1 var readFixtures = function() {
2 return jasmine.getFixtures().proxyCallTo_('read', arguments);
5 var preloadFixtures = function() {
6 jasmine.getFixtures().proxyCallTo_('preload', arguments);
9 var loadFixtures = function() {
10 jasmine.getFixtures().proxyCallTo_('load', arguments);
13 var setFixtures = function(html) {
14 jasmine.getFixtures().set(html);
17 var sandbox = function(attributes) {
18 return jasmine.getFixtures().sandbox(attributes);
21 var spyOnEvent = function(selector, eventName) {
22 jasmine.JQuery.events.spyOn(selector, eventName);
25 jasmine.getFixtures = function() {
26 return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures();
29 jasmine.Fixtures = function() {
30 this.containerId = 'jasmine-fixtures';
31 this.fixturesCache_ = {};
32 this.fixturesPath = 'spec/javascripts/fixtures';
35 jasmine.Fixtures.prototype.set = function(html) {
37 this.createContainer_(html);
40 jasmine.Fixtures.prototype.preload = function() {
41 this.read.apply(this, arguments);
44 jasmine.Fixtures.prototype.load = function() {
46 this.createContainer_(this.read.apply(this, arguments));
49 jasmine.Fixtures.prototype.read = function() {
52 var fixtureUrls = arguments;
53 for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
54 htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex]));
57 return htmlChunks.join('');
60 jasmine.Fixtures.prototype.clearCache = function() {
61 this.fixturesCache_ = {};
64 jasmine.Fixtures.prototype.cleanUp = function() {
65 jQuery('#' + this.containerId).remove();
68 jasmine.Fixtures.prototype.sandbox = function(attributes) {
69 var attributesToSet = attributes || {};
70 return jQuery('<div id="sandbox" />').attr(attributesToSet);
73 jasmine.Fixtures.prototype.createContainer_ = function(html) {
75 if(html instanceof jQuery) {
76 container = jQuery('<div id="' + this.containerId + '" />');
79 container = '<div id="' + this.containerId + '">' + html + '</div>'
81 jQuery('body').append(container);
84 jasmine.Fixtures.prototype.getFixtureHtml_ = function(url) {
85 if (typeof this.fixturesCache_[url] == 'undefined') {
86 this.loadFixtureIntoCache_(url);
88 return this.fixturesCache_[url];
91 jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function(relativeUrl) {
93 var url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl;
95 async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
99 success: function(data) {
100 self.fixturesCache_[relativeUrl] = data;
102 error: function(jqXHR, status, errorThrown) {
103 throw Error('Fixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + errorThrown.message + ')');
108 jasmine.Fixtures.prototype.proxyCallTo_ = function(methodName, passedArguments) {
109 return this[methodName].apply(this, passedArguments);
113 jasmine.JQuery = function() {};
115 jasmine.JQuery.browserTagCaseIndependentHtml = function(html) {
116 return jQuery('<div/>').append(html).html();
119 jasmine.JQuery.elementToString = function(element) {
120 return jQuery('<div />').append(element.clone()).html();
123 jasmine.JQuery.matchersClass = {};
125 (function(namespace) {
132 spyOn: function(selector, eventName) {
133 var handler = function(e) {
134 data.spiedEvents[[selector, eventName]] = e;
136 jQuery(selector).bind(eventName, handler);
137 data.handlers.push(handler);
140 wasTriggered: function(selector, eventName) {
141 return !!(data.spiedEvents[[selector, eventName]]);
144 cleanUp: function() {
145 data.spiedEvents = {};
152 var jQueryMatchers = {
153 toHaveClass: function(className) {
154 return this.actual.hasClass(className);
157 toBeVisible: function() {
158 return this.actual.is(':visible');
161 toBeHidden: function() {
162 return this.actual.is(':hidden');
165 toBeSelected: function() {
166 return this.actual.is(':selected');
169 toBeChecked: function() {
170 return this.actual.is(':checked');
173 toBeEmpty: function() {
174 return this.actual.is(':empty');
177 toExist: function() {
178 return this.actual.size() > 0;
181 toHaveAttr: function(attributeName, expectedAttributeValue) {
182 return hasProperty(this.actual.attr(attributeName), expectedAttributeValue);
185 toHaveId: function(id) {
186 return this.actual.attr('id') == id;
189 toHaveHtml: function(html) {
190 return this.actual.html() == jasmine.JQuery.browserTagCaseIndependentHtml(html);
193 toHaveText: function(text) {
194 if (text && jQuery.isFunction(text.test)) {
195 return text.test(this.actual.text());
197 return this.actual.text() == text;
201 toHaveValue: function(value) {
202 return this.actual.val() == value;
205 toHaveData: function(key, expectedValue) {
206 return hasProperty(this.actual.data(key), expectedValue);
209 toBe: function(selector) {
210 return this.actual.is(selector);
213 toContain: function(selector) {
214 return this.actual.find(selector).size() > 0;
217 toBeDisabled: function(selector){
218 return this.actual.is(':disabled');
221 // tests the existence of a specific event binding
222 toHandle: function(eventName) {
223 var events = this.actual.data("events");
224 return events && events[eventName].length > 0;
227 // tests the existence of a specific event binding + handler
228 toHandleWith: function(eventName, eventHandler) {
229 var stack = this.actual.data("events")[eventName];
231 for (i = 0; i < stack.length; i++) {
232 if (stack[i].handler == eventHandler) {
240 var hasProperty = function(actualValue, expectedValue) {
241 if (expectedValue === undefined) {
242 return actualValue !== undefined;
244 return actualValue == expectedValue;
247 var bindMatcher = function(methodName) {
248 var builtInMatcher = jasmine.Matchers.prototype[methodName];
250 jasmine.JQuery.matchersClass[methodName] = function() {
251 if (this.actual instanceof jQuery) {
252 var result = jQueryMatchers[methodName].apply(this, arguments);
253 this.actual = jasmine.JQuery.elementToString(this.actual);
257 if (builtInMatcher) {
258 return builtInMatcher.apply(this, arguments);
265 for(var methodName in jQueryMatchers) {
266 bindMatcher(methodName);
270 beforeEach(function() {
271 this.addMatchers(jasmine.JQuery.matchersClass);
273 toHaveBeenTriggeredOn: function(selector) {
274 this.message = function() {
276 "Expected event " + this.actual + " to have been triggered on" + selector,
277 "Expected event " + this.actual + " not to have been triggered on" + selector
280 return jasmine.JQuery.events.wasTriggered(selector, this.actual);
285 afterEach(function() {
286 jasmine.getFixtures().cleanUp();
287 jasmine.JQuery.events.cleanUp();