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();