At one point I had my entire Backbone.js application (plus some required, supporting HTML) all in a single web page. It was quite huge.
Having worked with the code quite a bit recently, the entire contents of the
<body>
tag is now:<h1> Funky Calendar <span class="year-and-month"></span> </h1> <div id="calendar"></div> <script> $(function() { window.calendar = new Cal($('#calendar')); }); </script>The actual Backbone code (
Cal
) is now defined entirely in a separate calendar.js
file. That source file is loaded via <script>
tag along with backbone.js
and other Javascript dependencies. What I hope this means in practice is that I can do away with some of the testing complexity that I have in place. Until now, I have needed to generate a testing fixture from the web page (since it defined so much of what was critical to running the app). For that, I had a very simple expresso test that ran my express.js server and dumped the homepage to the fixture directory. Then, in my jasmine test, I loaded that fixture into the DOM for testing with jasmine-jquery's
loadFixtures()
.Now, I need only a DOM element to which I can attach my application:
new Cal($('#calendar'));So, I replace my fixture loading:
beforeEach(function() {
// ...
loadFixtures('homepage.html');
// ...
});
Instead, I create a DOM element and inject it into my Backbone application: beforeEach(function() {
// ...
$('body').append('<div id="calendar"/>');
window.calendar = new Cal($('#calendar'));
// ...
});
I do have to remember to remove that element after each test: afterEach(function() {
$('#calendar').remove();
$('#calendar-navigation').remove();
});
Amazingly... it just works:Without my fixture data, I am tempted to remove jasmine-jquery. I think better of that idea because I really like the
toHaveText()
matchers: describe("appointments", function() {
it("populates the calendar with appointments", function() {
expect($('#' + fifteenth)).toHaveText(/Get Funky/);
});
});
That was unexpectedly easy. It kinda make me wonder why I did not avoid fixtures in the first place. Ah well, lesson learned.Day #208
why even give the calendar an element? Backbone will make one not on the dom if you don't provide one.
ReplyDeleteIf you need it for tests,
var cal = new Cal();
var el = cal.el
-Nick
Fair point. The DI was more important under the covers than it is for the application.
ReplyDeleteStill, from an API standpoint, I rather prefer:
var cal = new Cal($('#calendar'));
To:
var cal = new Cal();
$('#calendar').append(cal.el);
The former feels like clearer intent to me.