getBlob
, as the mocked version returns the blob regardless of arguments. I had messed up the url variable in the BookStorageManager
object, and was passing in book_object.url
(undefined) instead of book_object.fullBookUrl
(...url), but my tests were still succeeding, which is bad. I set up a spy for my mocked getBlob
method so I could check what arguments it was being called with. One problem with this specific approach is that it relies really heavily on the ordering of arguments, which could be subject to change.Given the object
{ 'progress_callback': req_progress_callback, 'test_var':42 };being passed into another object's function, and then logging the variables on both ends, I got:
LOG: 'args passed to object: ' LOG: Object{progress_callback: function (event) { ... }, test_var: 42} LOG: 'args recieved by object:' LOG: Object{progress_callback: undefined, test_var: 42}This is really strange, and I guess the function goes out of scope when the object changes. I also changed the
progress_callback
to 'progress_callback': req_progress_callback ? 'true' : 'false'
and got
LOG: 'args passed to object: ' LOG: Object{progress_callback: 'true', test_var: 42} LOG: 'args recieved by object:' LOG: Object{progress_callback: 'false', test_var: 42}which is even stranger, because that means the ternary statement is being evaluated twice rather than just setting the value.
On the other hand, setting
'progress_callback': function () {}
passes the function in correctly, so it looks like in javascript you just have to encapsulate any functions passed in arguments in functions defined within the object. Hopefully JavaScript: The Good Parts will talk about this. I don't like the idea of just encapsulating it with 'progress_callback': function (e) {callback(e)}
and assuming there will only be 1 argument, because I don't necessarily want this function to depend on the interface of my HttpRequestHandler
. StackOverflow says that you can get around this by doing function () {callback.apply(this, arguments)}
which calls the function but allows you to set the two implicit variables declared in all javascript functions, this
and arguments
I was getting some more weird test behavior, and was trying to debug it with no success, when I finally realized that my test for the progress callback were both using
blobSpy.getCall(0)
, which refers to the first time the blob had been called. However, there was nothing clearing the list, so all tests would be looking at the results of whatever test happened to be run first. To fix this, I did
beforeEach(function () { blobSpy.reset(); });In the future, I'll always check this when dealing with weird issues.
Here are my finished tests. Also, notice the comment here, which is a question for anyone who knows more about this than I do.
Do I need to test that the progress callback correctly updates the scrollbar as the file downloads? I think it's definitely possible to write a test that does this, but I feel like I'm 'wasting' a ton of time fighting with the DOM to be able to test my user interface, when maybe I would be more productive just leaving that part of it untested. For example, setting up the tests I talk about in this post took around 4 hours, just because I was fighting javascript the whole way to get it to do what I wanted. That being said, in writing these tests I found a bunch of bugs that I wouldn't have noticed otherwise, so it was definitely worth it in this case.
For broad questions of overall approach, such as, "maybe I would be more productive just leaving that part of it untested?", please ask Kevin. Our quest for a friendly JavaScript guru remains unfulfilled, so we'll muddle forward without one for now. Reading JavaScript The Good Parts will be a great way to start. Douglas Crockford also has a series of videos, the first of which can be found here:
ReplyDeletehttp://yui.zenfs.com/theater/crockford-tjpl-1.m4v
In the longer term, I'm hoping we can earn the attention and support we seek from Mozilla. If you can make steady progress with LibreFox, and perhaps contribute to FoxMap this Summer, your contribution will be significant enough to warrant more love and attention from the Firefox OS folks, who are undoubtedly over extended and trying to do a lot with limited resources.