Spacewar! 17 - Using CodeaUnit all the way.
Braved Snowmageddon again to come to the bookstore. Nearly the only person here, certainly the only one at my table. I think I’ll move the rest of the tests to CodeaUnit. Let’s look at the concerns from last time: I think I might want to work directly in the Spacewar app, now that I’m confident enough to go ahead with CodeaUnit. The concerns were:
- Working in a separate project means too much switching about. We’ll just not do that.
- Syntax isn’t natural to me yet. We’ll just practice more.
- The
_:before
may not be very helpful. We’ll work through that, and we certainly don’t have it at all in our hand-woven tests.
Nothing to worry about there. I’ll require CodeaUnit into Spacewar, and see what happens. I already have a button for the home-grown tests, and it is possible that my class name may confuse CodeaUnit, but we’re in the process of moving tests from the old to the new anyway. Here goes. Hold my chai.
OK, the first thing that happens, of course, is that CodeaUnit is looking for all functions whose names start with “test” so it breaks horribly when they aren’t intended for it. I’ll just quickly rename those …
Yes. A little judicious renaming and we’re good to go. I have the old tests and the new CodeaUnit ones running, each on its own button. I won’t trouble you with the details of the code: I’ll just go ahead and move all the testing to CodeaUnit and report back then.
OK, I lied. This stage is worth talking about:
function testSpacewarButton()
CodeaUnit.detailed = false
local insideEndTouch = { id=1, state=ENDED, x=100, y=100 }
local insideBeganTouch = { id=3, state=BEGAN, x=100, y=100 }
local outsideBeganTouch = { id=4, state=BEGAN, x=151, y=100 }
local closeThree = { id=3, state=ENDED, x=200, y=200 }
local movingFinger = { id=5, state=BEGAN, x = 100, y=100}
_:describe("Spacewar Button Test", function()
_:test("Inside Circle", function()
local button = Button(nil, 100, 100, "nothing")
_:expect(button:insideCircle(insideEndTouch)).is(true)
end)
_:test("Initial Button Capture", function()
local button = Button(nil, 100, 100, "nothing")
button:touched(insideBeganTouch)
_:expect(button.capturedID).is(3)
button:touched(outsideBeganTouch)
_:expect(button.capturedID).is(3)
_:expect(button.pressed).is(false)
end)
end)
end
I copied over all the constant fake touches, and put them at the top of the testSpacewarButton file. That seems to make sense. Their names are a bit troubling, as they reflect what we were thinking when we did them but maybe they can be better. We’ll see. Now we notice more readily that there is the duplication of the button in each test, and feel more strongly that it should be moved to a _:before
function. I’m tempted to wait a bit but in fact I think it’s better to do it now, since I’ve never done a before before.
My first cut looks like this:
_:describe("Spacewar Button Test", function()
_:before(function()
button = Button(nil, 100, 100, "nothing")
end)
...
This works, with the two local buttons removed from the tests. But … now the variable button
is a global. We’d like it to be local to our test only. I think if I just declare it up in the locals up above that should fix it. The tests still run, but now I want to be sure there is no global named “button”. So I write a test:
function testSpacewarButton()
CodeaUnit.detailed = false
local insideEndTouch = { id=1, state=ENDED, x=100, y=100 }
local insideBeganTouch = { id=3, state=BEGAN, x=100, y=100 }
local outsideBeganTouch = { id=4, state=BEGAN, x=151, y=100 }
local closeThree = { id=3, state=ENDED, x=200, y=200 }
local movingFinger = { id=5, state=BEGAN, x = 100, y=100}
local button
_:describe("Spacewar Button Test", function()
_:before(function()
button = Button(nil, 100, 100, "nothing")
end)
_:test("No global button", function()
_:expect(_G["button"]).is(nil)
end)
_:test("Inside Circle", function()
_:expect(button:insideCircle(insideEndTouch)).is(true)
_:expect(button:insideCircle(outsideBeganTouch)).is(false)
end)
_:test("Initial Button Capture", function()
button:touched(insideBeganTouch)
_:expect(button.capturedID).is(3)
button:touched(outsideBeganTouch)
_:expect(button.capturedID).is(3)
_:expect(button.pressed).is(false)
end)
end)
end
Sure enough the “No global button” test passes. (And, if I comment out the local button
, it fails, so it’s really working. You’ll notice I also added another _:expect
for the “Inside Circle” test, and that runs as well. I think I’m getting the hang of this andI am starting to like it. I’ll move over some more of the old tests now.
function testSpacewarButton()
CodeaUnit.detailed = false
local insideEndTouch = { id=1, state=ENDED, x=100, y=100 }
local insideBeganTouch = { id=3, state=BEGAN, x=100, y=100 }
local outsideBeganTouch = { id=4, state=BEGAN, x=151, y=100 }
local closeThree = { id=3, state=ENDED, x=200, y=200 }
local movingFinger = { id=5, state=BEGAN, x = 100, y=100}
local button
_:describe("Spacewar Button Test", function()
_:before(function()
button = Button(nil, 100, 100, "nothing")
end)
_:test("No global button", function()
_:expect(_G["button"]).is(nil)
end)
_:test("Inside Circle", function()
_:expect(button:insideCircle(insideEndTouch)).is(true)
_:expect(button:insideCircle(outsideBeganTouch)).is(false)
end)
_:test("Initial Button Capture", function()
button:touched(insideBeganTouch)
_:expect(button.capturedID).is(3)
button:touched(outsideBeganTouch)
_:expect(button.capturedID).is(3)
_:expect(button.pressed).is(false)
end)
_:test("Sequence Test", function()
button:touched(closeThree)
_:expect(button.capturedID).is(nil)
button:touched(movingFinger)
_:expect(button.capturedID).is(5)
_:expect(button.pressed).is(true)
movingFinger.state=MOVING
button:touched(movingFinger)
_:expect(button.pressed).is(true)
movingFinger.x = 200
button:touched(movingFinger)
_:expect(button.pressed).is(false) -- no longer pressed
_:expect(button.capturedID).is(5) -- but retains capture
end)
end)
end
That’s all the tests moved over. Note that in the Sequence Test, I didn’t feel it told the story as well as it might, so added a couple of comments. It might be nice if those could be put inside the “expect” somehow, perhaps as an additional argument like
`_:expect(“Button should be no longer pressed”, button.pressed).is(false)1st
It’d be easier to make it the second parameter to expect, or maybe even to is, like:
`_:expect(button.pressed).is(false, “Button should not be pressed now”)1st
I think I like that, and it’s possibly an “easy” change to CodeaUnit. We’ll look at that later, perhaps. For now, a good morning’s work. I’ll remove the old test tab and be on my way. Thanks!