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.