I am fairly confident that I have made a mess out of adding and editing appointments in my Backbone.js calendar. The UI for adding appointments is somehow split between two Backbone views. The "application" view adds handlers to a jQuery UI dialog for creating new appointments. But a "day" view, attached to each day in the calendar, is responsible for opening that jQuery UI dialog. And don't even get me started on what I did to the edit dialog.
Yup, it's a fantastic mess, but... I have a secret weapon to help me fix said mess: Jasmine tests. And not just any jasmine tests—end-to-end jasmine tests. Click this button, the dialog opens, fill in that text, hit submit and voilĂ a new appointment shows up in the UI. Best of all, since none of that relies on the underlying implementation, I ought to be able to fix everything without changing the test. The test will serve as a sanity check as I refactor.
Yup, that'll be nice. But first I actually need tests for the add dialog (I have tests for delete and the overall calendar only):
Now to add some tests for the add dialog itself:
describe("adding an appointment", function() {
it("sends clicks on day to an add dialog", function() {
$('#2011-09-14').click();
var dialog = $('#dialog').parent();
expect(dialog).toBeVisible();
expect(dialog).toHaveText(/Add/);
});
it("displays the date clicked in the add dialog", function() {
$('#2011-09-14').click();
expect($('#dialog')).toHaveText(/2011-09-14/);
});
});Aside from some funkiness due to the title of a jQuery UI dialog being in the parent of the "#dialog" element, both of those two specs are straight forward and they pass.Last up, I need to verify the round trip, stubbing out the XHR request with sinon.js:
describe("adding an appointment", function() {
it("sends clicks on day to an add dialog", function() { /* ... */ });
it("displays the date clicked in the add dialog", function() { /* ... */ });
it("adds a new appointment to the UI when saved", function() {
$('#2011-09-14').click();
$('.ok').click();
var appointment = {
"id": "42",
"rev": "1-2345",
"startDate": "2011-09-14",
"title": "Groovy meeting",
"description": "asdf"
};
server.respondWith('POST', '/appointments', JSON.stringify(appointment));
server.respond();
expect($('#2011-09-14')).toHaveText(/Groovy/);
});
});Wow. I have a hard time I got that newest test right. As a quick sanity check, I intentionally break it: it("adds a new appointment to the UI when saved", function() {
// ...
expect($('#2011-09-14')).toHaveText(/Grooy/);
});And yup, it does break:Cool. Safe in the knowledge that I finally have my add dialog accurately described by jasmine, I call it a night. Up tomorrow: I hack together a pretty ugly edit implementation.
Day #133




0 comments:
Post a Comment