I continue working through vows.js testing for fab.js today. I am still working with my simple
player_from_querystring
unary (fab) app. At this point, I have two different "topics" (vows terminology for things to be tested) and several "vows" (unit tests in vows-speak). My goal today is to move beyond what I know about testing and into what vows is try to get me to do.I have two test batches so far, one for 'with a query string' and the other for 'POSTing data'. The things that I am testing, the topics, in both cases are very similar. The first:
'with a query string': {And the second:
topic: function() {
var response;
function downstream (obj) { response = obj; }
var upstream_listener = player_from_querystring.call(downstream);
upstream_listener({
url: { search : "?player=foo&x=1&y=2" },
headers: { cookie: null }
});
return response.body;
},
'POSTing data': {The first three lines of each are identical. The
topic: function() {
var response;
function downstream (obj) { response = obj; }
var upstream_listener = player_from_querystring.call(downstream);
upstream_listener({body: "foo"});
return [response];
},
return
statement for both would be the same if vows.js allowed undefined topics. The real difference between the two is what gets set by the downstream (e.g. the browser). When I am testing the query string, I send only HTTP header stuff. When I am testing what happens when POSTing the data, I only send a body.If I understood this better, then I would DRY up the code. Since I am learning, I think it makes more sense to try to get one of them right, apply what I know to the other and then DRY things up. This may blow up in my face, but that is what
git checkout
is for.I will start with the second of the two since there is only one vow/test written against it and because it was obviously awkward when I wrote it. What made it feel awkward was, as I mentioned earlier, that I was testing for an undefined response, but vows does not allow undefined topics. Actually, that is not entirely accurate, it allows for undefined responses, but they must be accompanied by the use of
this.callback
. The
this.callback
function seems well-named—vows.js uses it to keep track of asynchronous callback functions. It ensures that they do get called and then send the arguments that it receives onto the vows/tests. Let's see if I can replace the downstream
app with a this.callback
in my POSTing test like so:addBatch({Ooh... I like that. I like it a lot.
'POSTing data': {
topic: function() {
var upstream_listener = player_from_querystring.call(this.callback);
upstream_listener({body: "foo"});
},
'is null response': function (obj) {
assert.isUndefined (obj);
}
}
})
The topic section only has the code I wanted. Gone are the identical first three lines of code between my two topics as well as the weird
return
. Only the topic code that is important is left. Awesome!But... does it work?
cstrom@whitefall:~/repos/my_fab_game$ vows --specNice. There may just be something to this vows.js stuff.
♢ just_playing
with a query string
✓ is player
✓ has unique ID
✓ has X coordinate
✓ has Y coordinate
POSTing data
✓ is null response
✓ OK » 5 honored (0.096s)
So let's see if I can apply this to my more involved happy path:
addBatch({Oooh... that's equally nice. All that is left is the barebones topic—only what matters. Sadly, however, that does work for me:
'with a query string': {
topic: function() {
var upstream_listener = player_from_querystring.call(this.callback);
upstream_listener({
url: { search : "?player=foo&x=1&y=2" },
headers: { cookie: null }
});
},
'is player': function (obj) {
assert.equal (obj.body.id, "foo");
},
//...
}
})
cstrom@whitefall:~/repos/my_fab_game$ vows --specDang.
♢ just_playing
with a query string
✗ is player
» An unexpected error was caught: [object Object]
✗ has unique ID
» An unexpected error was caught: [object Object]
✗ has X coordinate
» An unexpected error was caught: [object Object]
✗ has Y coordinate
» An unexpected error was caught: [object Object]
POSTing data
✓ is null response
✗ Errored » 1 honored ∙ 4 errored (0.087s)
With the help of well-placed
puts
, I figure out that I am not even reaching my tests. A little more investigation tells me that I cannot pass just anything to this.callback
, I need to pass both an error object and a real object. Bah! That means a bit of an impedance match between vows.js and fab.js.Rather than sending
this.callback
directly to my (fab) app, I have to pass in a proxy:addBatch({The nice thing about this is that I can pass the
'with a query string': {
topic: function() {
var topic = this;
var upstream_listener = player_from_querystring.call(
function(obj) {
topic.callback(null, obj.body);
}
);
upstream_listener({
url: { search : "?player=foo&x=1&y=2" },
headers: { cookie: null }
});
},
'is player': function (player) {
assert.equal (player.id, "foo");
},
// ...
}
})
body
attribute from my (fab) app to my tests. The bad thing is the added code. That is a good stopping point for tonight. I am a bit better off than I was last night. Hopefully tomorrow will be even better.Day #154
No comments:
Post a Comment