Created
February 9, 2011 17:46
-
-
Save davemo/818879 to your computer and use it in GitHub Desktop.
A pattern for testing anonymous functions and asserting expected behaviour through nested calls using JasmineBDD.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Notes: This is a way @Searls and I came up with that lets you | |
// test deeply nested anonymous functions and callbacks. | |
// We don't recommend nesting things this deep but we _do_ like the closure scoping in the tests. | |
// Any suggestions or improvements would be welcome :) | |
// The Codez, A little modal window framework | |
(function($, _) { | |
$.cil = $.cil || {}; | |
$.cil.modals = {}; | |
var m = $.cil.modals; | |
m.MODAL_LINK_TEMPLATE = | |
'<a href="<%= url %>" class="modal" data-controller="<%= controller %>" title="<%= title %>">' + | |
'<%= label %>' + | |
'</a>'; | |
m.MODAL_TEMPLATE = '<div class="modal cil-template"></div>'; | |
m.bind = function() { | |
$("body").delegate("a.modal", "click", m.open); | |
}; | |
m.link = function(context) { | |
return _.template(m.MODAL_LINK_TEMPLATE, context); | |
}; | |
m.hide = function() { | |
$("div.modal").dialog("close"); | |
$('div.modal').remove(); | |
}; | |
m.open = function(e) { | |
var $modal = $(m.MODAL_TEMPLATE); | |
var $link = $(this); | |
var controller = m._extractController($link); | |
$modal.appendTo("body"); // level 1 specs test from here | |
$.cil.loadingIndicator.show(); | |
$modal.load($link.attr("href"), function() { // level 2 specs test from here | |
$.cil.loadingIndicator.hide(); | |
$modal.dialog({ | |
modal: true, | |
minWidth: 450, | |
title: controller.title, | |
buttons: controller.buttons, | |
open: function(ev, ui) { | |
controller.onLoaded({ // level 3 specs test from here | |
link: $link, | |
container: $modal | |
}); | |
} | |
}); | |
}); | |
e.preventDefault(); | |
}; | |
m._extractController = function($link) { | |
var ns = $link.attr("data-controller").split("."); | |
return $.cil[ns[0]][ns[1]]; | |
}; | |
$.subscribe('/cil/modals/action-complete', m.hide); | |
})(jQuery, _); | |
// The Tests | |
describe('Modal Window Generator', function() { | |
var sut = $.cil.modals, | |
support = $.jasmine, // requires https://github.com/searls/jasmine-fixture | |
$link, | |
linkMetaData; | |
beforeEach(function() { | |
// setup fixtures | |
linkMetaData = { | |
url: '/test/url', | |
controller: 'test.controller', | |
title: 'Test Link!', | |
label: 'Test Link Text' | |
}; | |
$link = $(sut.link(linkMetaData)); | |
}); | |
// Level 1 | |
describe('#open', function() { | |
var url, loadedCallback; | |
beforeEach(function() { | |
spyOn($.fn, 'load').andCallFake(function('/some/url', callback) { | |
loadedCallback = callback; | |
}); | |
sut.open.call($link, { preventDefault: function() {} }); | |
}); | |
// Level 1 Assertions | |
it('loads remote content into the modal', function() { | |
expect($.fn.load).toHaveBeenCalledWith(linkMetaData.url, loadedCallback); | |
}); | |
// ... *snip* | |
// Level 2 | |
describe('$.load anonymous handler', function() { | |
var dialogParams; | |
beforeEach(function() { | |
spyOn($.fn, 'dialog').andCallFake(function(options) { | |
dialogParams = options; | |
}); | |
// execute the callback passed in from our previous execution scope | |
loadedCallback(); | |
}); | |
// Level 2 Assertions | |
it('sets the modal flag to true', function() { | |
expect(dialogParams.modal).toBe(true); | |
}); | |
// ... *snip* | |
// Level 3, feeling like inception all of a sudden... | |
describe('controller.onLoaded arguments', function() { | |
var onLoadedParams; | |
beforeEach(function() { | |
$.cil.test.controller.onLoaded = function() {}; | |
spyOn($.cil.test.controller, 'onLoaded').andCallFake(function(options) { | |
onLoadedParams = options; | |
}); | |
dialogParams.open(); | |
}); | |
it('passes the link', function() { | |
expect(onLoadedParams.link).toBe('a.modal'); | |
}); | |
it('passes the modal as container', function() { | |
expect(onLoadedParams.container).toBe('div.modal'); | |
}); | |
}); | |
}); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment