Friday 10 December 2010

Funky Stuff

It occurs to me that I'm missing a basic test here. I've not used the Func object to return values before now. So maybe I should start by testing that.

The ideal way to do TDD is with one test module per class. I'm kind of sloppy about that, but I think I'll start a new one for this object

package.path = package.path .. ";../Scripts/?.lua"

require "Func"
require "xml"
require "lunit"

module( "func_tests", lunit.testcase, package.seeall )

function test_func()
        --
        -- UML to describe the scene
        --
        local xml_src = [[
        <func>
                return 27.3 -- pick a value unlikely to just be on the stack...
        </func>
        ]]

        --
        -- parse the xml
        --
        local xml_root = xml.collect(xml_src)[1]

        --
        -- create the Func
        --
        local f = Func:new(xml_root)
        local rc = f:exec()
        assert_equal(27.3, rc)
end


The "package" line at the top just tells Lua where the modules I'm testing are to be found. "require" pulls in the modules so we can use them, and the "module" line is a bit of magic for the test harness. Apart from that, nothing new here.

Oh, and the test fails:

1 Assertions checked.

  1) Failure (func_tests.test_func):
test_func.lua:30: expected 27.3 but was nil

Testsuite finished (0 passed, 1 failed, 0 errors).


But that's a good thing in this case. Because now we get to fix it.

This turns out to be very easy. We change this line from Func.lua

        self.chunk()

to look like this

        return self.chunk()

And the test passes.

How about checking the userdata while we're in there? New test case:

function test_userdata()
        --
        -- UML to describe the scene
        --
        local xml_src = [[
        <func>
                userdata.name = "Aldus P. Mickletwaite, Esquire"
                return userdata.retval
        </func>
        ]]
        local xml_root = xml.collect(xml_src)[1]
        local f = Func:new(xml_root)

        --
        -- we'll need a table to hold the userdata
        --
        local ud = {}

        --
        -- make sure name is null when we go in
        -- make sure retval is set
        --
        assert_nil(ud.name)
        ud.retval = true

        --
        -- call the func and check the results
        --
        local rc = f:exec(ud)
        assert_true(rc)
        assert_equal(
                "Aldus P. Mickletwaite, Esquire",
                ud.name
        )


Which passes.  Not a great surprise, since this is already working in the narrator tests, but nice to have a test for it anyway. While I'm at it, let's make sure that return value changes if we change the value in retval

        --
        -- let's do that again with a different retval
        --
        ud = {}
        ud.retval = false
        rc = f:exec(ud)
        assert_false(rc)

        -- once more for luck - let's return a different type
        ud = {}
        local s = "ying tong iddle i po"
        ud.retval = s
        rc = f:exec(ud)
        assert_equal(s, rc)


OK. That's Func well and truly tested. Pop the stack and back to conditional options

No comments: