zff 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in zff.gemspec
4
+ gemspec
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,5 @@
1
+ require "zff/version"
2
+
3
+ module Zff
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,3 @@
1
+ module Zff
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ //= require jasmine/jasmine
2
+ //= require jasmine/jasmine-html
3
+ //= require jasmine/mock-ajax
4
+ //= require jasmine/spec-helper
@@ -0,0 +1,190 @@
1
+ jasmine.TrivialReporter = function(doc) {
2
+ this.document = doc || document;
3
+ this.suiteDivs = {};
4
+ this.logRunningSpecs = false;
5
+ };
6
+
7
+ jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
8
+ var el = document.createElement(type);
9
+
10
+ for (var i = 2; i < arguments.length; i++) {
11
+ var child = arguments[i];
12
+
13
+ if (typeof child === 'string') {
14
+ el.appendChild(document.createTextNode(child));
15
+ } else {
16
+ if (child) { el.appendChild(child); }
17
+ }
18
+ }
19
+
20
+ for (var attr in attrs) {
21
+ if (attr == "className") {
22
+ el[attr] = attrs[attr];
23
+ } else {
24
+ el.setAttribute(attr, attrs[attr]);
25
+ }
26
+ }
27
+
28
+ return el;
29
+ };
30
+
31
+ jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
32
+ var showPassed, showSkipped;
33
+
34
+ this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
35
+ this.createDom('div', { className: 'banner' },
36
+ this.createDom('div', { className: 'logo' },
37
+ this.createDom('a', { href: 'http://pivotal.github.com/jasmine/', target: "_blank" }, "Jasmine"),
38
+ this.createDom('span', { className: 'version' }, runner.env.versionString())),
39
+ this.createDom('div', { className: 'options' },
40
+ "Show ",
41
+ showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
42
+ this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
43
+ showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
44
+ this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
45
+ )
46
+ ),
47
+
48
+ this.runnerDiv = this.createDom('div', { className: 'runner running' },
49
+ this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
50
+ this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
51
+ this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
52
+ );
53
+
54
+ this.document.body.appendChild(this.outerDiv);
55
+
56
+ var suites = runner.suites();
57
+ for (var i = 0; i < suites.length; i++) {
58
+ var suite = suites[i];
59
+ var suiteDiv = this.createDom('div', { className: 'suite' },
60
+ this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
61
+ this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
62
+ this.suiteDivs[suite.id] = suiteDiv;
63
+ var parentDiv = this.outerDiv;
64
+ if (suite.parentSuite) {
65
+ parentDiv = this.suiteDivs[suite.parentSuite.id];
66
+ }
67
+ parentDiv.appendChild(suiteDiv);
68
+ }
69
+
70
+ this.startedAt = new Date();
71
+
72
+ var self = this;
73
+ showPassed.onclick = function(evt) {
74
+ if (showPassed.checked) {
75
+ self.outerDiv.className += ' show-passed';
76
+ } else {
77
+ self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
78
+ }
79
+ };
80
+
81
+ showSkipped.onclick = function(evt) {
82
+ if (showSkipped.checked) {
83
+ self.outerDiv.className += ' show-skipped';
84
+ } else {
85
+ self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
86
+ }
87
+ };
88
+ };
89
+
90
+ jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
91
+ var results = runner.results();
92
+ var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
93
+ this.runnerDiv.setAttribute("class", className);
94
+ //do it twice for IE
95
+ this.runnerDiv.setAttribute("className", className);
96
+ var specs = runner.specs();
97
+ var specCount = 0;
98
+ for (var i = 0; i < specs.length; i++) {
99
+ if (this.specFilter(specs[i])) {
100
+ specCount++;
101
+ }
102
+ }
103
+ var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
104
+ message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
105
+ this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
106
+
107
+ this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
108
+ };
109
+
110
+ jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
111
+ var results = suite.results();
112
+ var status = results.passed() ? 'passed' : 'failed';
113
+ if (results.totalCount === 0) { // todo: change this to check results.skipped
114
+ status = 'skipped';
115
+ }
116
+ this.suiteDivs[suite.id].className += " " + status;
117
+ };
118
+
119
+ jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
120
+ if (this.logRunningSpecs) {
121
+ this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
122
+ }
123
+ };
124
+
125
+ jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
126
+ var results = spec.results();
127
+ var status = results.passed() ? 'passed' : 'failed';
128
+ if (results.skipped) {
129
+ status = 'skipped';
130
+ }
131
+ var specDiv = this.createDom('div', { className: 'spec ' + status },
132
+ this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
133
+ this.createDom('a', {
134
+ className: 'description',
135
+ href: '?spec=' + encodeURIComponent(spec.getFullName()),
136
+ title: spec.getFullName()
137
+ }, spec.description));
138
+
139
+
140
+ var resultItems = results.getItems();
141
+ var messagesDiv = this.createDom('div', { className: 'messages' });
142
+ for (var i = 0; i < resultItems.length; i++) {
143
+ var result = resultItems[i];
144
+
145
+ if (result.type == 'log') {
146
+ messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
147
+ } else if (result.type == 'expect' && result.passed && !result.passed()) {
148
+ messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
149
+
150
+ if (result.trace.stack) {
151
+ messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
152
+ }
153
+ }
154
+ }
155
+
156
+ if (messagesDiv.childNodes.length > 0) {
157
+ specDiv.appendChild(messagesDiv);
158
+ }
159
+
160
+ this.suiteDivs[spec.suite.id].appendChild(specDiv);
161
+ };
162
+
163
+ jasmine.TrivialReporter.prototype.log = function() {
164
+ var console = jasmine.getGlobal().console;
165
+ if (console && console.log) {
166
+ if (console.log.apply) {
167
+ console.log.apply(console, arguments);
168
+ } else {
169
+ console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
170
+ }
171
+ }
172
+ };
173
+
174
+ jasmine.TrivialReporter.prototype.getLocation = function() {
175
+ return this.document.location;
176
+ };
177
+
178
+ jasmine.TrivialReporter.prototype.specFilter = function(spec) {
179
+ var paramMap = {};
180
+ var params = this.getLocation().search.substring(1).split('&');
181
+ for (var i = 0; i < params.length; i++) {
182
+ var p = params[i].split('=');
183
+ paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
184
+ }
185
+
186
+ if (!paramMap.spec) {
187
+ return true;
188
+ }
189
+ return spec.getFullName().indexOf(paramMap.spec) === 0;
190
+ };
@@ -0,0 +1,2445 @@
1
+ var isCommonJS = typeof window == "undefined";
2
+
3
+ /**
4
+ * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
5
+ *
6
+ * @namespace
7
+ */
8
+ var jasmine = {};
9
+ if (isCommonJS) exports.jasmine = jasmine;
10
+ /**
11
+ * @private
12
+ */
13
+ jasmine.unimplementedMethod_ = function() {
14
+ throw new Error("unimplemented method");
15
+ };
16
+
17
+ /**
18
+ * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
19
+ * a plain old variable and may be redefined by somebody else.
20
+ *
21
+ * @private
22
+ */
23
+ jasmine.undefined = jasmine.___undefined___;
24
+
25
+ /**
26
+ * Show diagnostic messages in the console if set to true
27
+ *
28
+ */
29
+ jasmine.VERBOSE = false;
30
+
31
+ /**
32
+ * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
33
+ *
34
+ */
35
+ jasmine.DEFAULT_UPDATE_INTERVAL = 250;
36
+
37
+ /**
38
+ * Default timeout interval in milliseconds for waitsFor() blocks.
39
+ */
40
+ jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
41
+
42
+ jasmine.getGlobal = function() {
43
+ function getGlobal() {
44
+ return this;
45
+ }
46
+
47
+ return getGlobal();
48
+ };
49
+
50
+ /**
51
+ * Allows for bound functions to be compared. Internal use only.
52
+ *
53
+ * @ignore
54
+ * @private
55
+ * @param base {Object} bound 'this' for the function
56
+ * @param name {Function} function to find
57
+ */
58
+ jasmine.bindOriginal_ = function(base, name) {
59
+ var original = base[name];
60
+ if (original.apply) {
61
+ return function() {
62
+ return original.apply(base, arguments);
63
+ };
64
+ } else {
65
+ // IE support
66
+ return jasmine.getGlobal()[name];
67
+ }
68
+ };
69
+
70
+ jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
71
+ jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
72
+ jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
73
+ jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
74
+
75
+ jasmine.MessageResult = function(values) {
76
+ this.type = 'log';
77
+ this.values = values;
78
+ this.trace = new Error(); // todo: test better
79
+ };
80
+
81
+ jasmine.MessageResult.prototype.toString = function() {
82
+ var text = "";
83
+ for(var i = 0; i < this.values.length; i++) {
84
+ if (i > 0) text += " ";
85
+ if (jasmine.isString_(this.values[i])) {
86
+ text += this.values[i];
87
+ } else {
88
+ text += jasmine.pp(this.values[i]);
89
+ }
90
+ }
91
+ return text;
92
+ };
93
+
94
+ jasmine.ExpectationResult = function(params) {
95
+ this.type = 'expect';
96
+ this.matcherName = params.matcherName;
97
+ this.passed_ = params.passed;
98
+ this.expected = params.expected;
99
+ this.actual = params.actual;
100
+
101
+ this.message = this.passed_ ? 'Passed.' : params.message;
102
+ this.trace = this.passed_ ? '' : new Error(this.message);
103
+ };
104
+
105
+ jasmine.ExpectationResult.prototype.toString = function () {
106
+ return this.message;
107
+ };
108
+
109
+ jasmine.ExpectationResult.prototype.passed = function () {
110
+ return this.passed_;
111
+ };
112
+
113
+ /**
114
+ * Getter for the Jasmine environment. Ensures one gets created
115
+ */
116
+ jasmine.getEnv = function() {
117
+ var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
118
+ return env;
119
+ };
120
+
121
+ /**
122
+ * @ignore
123
+ * @private
124
+ * @param value
125
+ * @returns {Boolean}
126
+ */
127
+ jasmine.isArray_ = function(value) {
128
+ return jasmine.isA_("Array", value);
129
+ };
130
+
131
+ /**
132
+ * @ignore
133
+ * @private
134
+ * @param value
135
+ * @returns {Boolean}
136
+ */
137
+ jasmine.isString_ = function(value) {
138
+ return jasmine.isA_("String", value);
139
+ };
140
+
141
+ /**
142
+ * @ignore
143
+ * @private
144
+ * @param value
145
+ * @returns {Boolean}
146
+ */
147
+ jasmine.isNumber_ = function(value) {
148
+ return jasmine.isA_("Number", value);
149
+ };
150
+
151
+ /**
152
+ * @ignore
153
+ * @private
154
+ * @param {String} typeName
155
+ * @param value
156
+ * @returns {Boolean}
157
+ */
158
+ jasmine.isA_ = function(typeName, value) {
159
+ return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
160
+ };
161
+
162
+ /**
163
+ * Pretty printer for expecations. Takes any object and turns it into a human-readable string.
164
+ *
165
+ * @param value {Object} an object to be outputted
166
+ * @returns {String}
167
+ */
168
+ jasmine.pp = function(value) {
169
+ var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
170
+ stringPrettyPrinter.format(value);
171
+ return stringPrettyPrinter.string;
172
+ };
173
+
174
+ /**
175
+ * Returns true if the object is a DOM Node.
176
+ *
177
+ * @param {Object} obj object to check
178
+ * @returns {Boolean}
179
+ */
180
+ jasmine.isDomNode = function(obj) {
181
+ return obj.nodeType > 0;
182
+ };
183
+
184
+ /**
185
+ * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter.
186
+ *
187
+ * @example
188
+ * // don't care about which function is passed in, as long as it's a function
189
+ * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));
190
+ *
191
+ * @param {Class} clazz
192
+ * @returns matchable object of the type clazz
193
+ */
194
+ jasmine.any = function(clazz) {
195
+ return new jasmine.Matchers.Any(clazz);
196
+ };
197
+
198
+ /**
199
+ * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
200
+ *
201
+ * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine
202
+ * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
203
+ *
204
+ * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).
205
+ *
206
+ * Spies are torn down at the end of every spec.
207
+ *
208
+ * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
209
+ *
210
+ * @example
211
+ * // a stub
212
+ * var myStub = jasmine.createSpy('myStub'); // can be used anywhere
213
+ *
214
+ * // spy example
215
+ * var foo = {
216
+ * not: function(bool) { return !bool; }
217
+ * }
218
+ *
219
+ * // actual foo.not will not be called, execution stops
220
+ * spyOn(foo, 'not');
221
+
222
+ // foo.not spied upon, execution will continue to implementation
223
+ * spyOn(foo, 'not').andCallThrough();
224
+ *
225
+ * // fake example
226
+ * var foo = {
227
+ * not: function(bool) { return !bool; }
228
+ * }
229
+ *
230
+ * // foo.not(val) will return val
231
+ * spyOn(foo, 'not').andCallFake(function(value) {return value;});
232
+ *
233
+ * // mock example
234
+ * foo.not(7 == 7);
235
+ * expect(foo.not).toHaveBeenCalled();
236
+ * expect(foo.not).toHaveBeenCalledWith(true);
237
+ *
238
+ * @constructor
239
+ * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
240
+ * @param {String} name
241
+ */
242
+ jasmine.Spy = function(name) {
243
+ /**
244
+ * The name of the spy, if provided.
245
+ */
246
+ this.identity = name || 'unknown';
247
+ /**
248
+ * Is this Object a spy?
249
+ */
250
+ this.isSpy = true;
251
+ /**
252
+ * The actual function this spy stubs.
253
+ */
254
+ this.plan = function() {
255
+ };
256
+ /**
257
+ * Tracking of the most recent call to the spy.
258
+ * @example
259
+ * var mySpy = jasmine.createSpy('foo');
260
+ * mySpy(1, 2);
261
+ * mySpy.mostRecentCall.args = [1, 2];
262
+ */
263
+ this.mostRecentCall = {};
264
+
265
+ /**
266
+ * Holds arguments for each call to the spy, indexed by call count
267
+ * @example
268
+ * var mySpy = jasmine.createSpy('foo');
269
+ * mySpy(1, 2);
270
+ * mySpy(7, 8);
271
+ * mySpy.mostRecentCall.args = [7, 8];
272
+ * mySpy.argsForCall[0] = [1, 2];
273
+ * mySpy.argsForCall[1] = [7, 8];
274
+ */
275
+ this.argsForCall = [];
276
+ this.calls = [];
277
+ };
278
+
279
+ /**
280
+ * Tells a spy to call through to the actual implemenatation.
281
+ *
282
+ * @example
283
+ * var foo = {
284
+ * bar: function() { // do some stuff }
285
+ * }
286
+ *
287
+ * // defining a spy on an existing property: foo.bar
288
+ * spyOn(foo, 'bar').andCallThrough();
289
+ */
290
+ jasmine.Spy.prototype.andCallThrough = function() {
291
+ this.plan = this.originalValue;
292
+ return this;
293
+ };
294
+
295
+ /**
296
+ * For setting the return value of a spy.
297
+ *
298
+ * @example
299
+ * // defining a spy from scratch: foo() returns 'baz'
300
+ * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
301
+ *
302
+ * // defining a spy on an existing property: foo.bar() returns 'baz'
303
+ * spyOn(foo, 'bar').andReturn('baz');
304
+ *
305
+ * @param {Object} value
306
+ */
307
+ jasmine.Spy.prototype.andReturn = function(value) {
308
+ this.plan = function() {
309
+ return value;
310
+ };
311
+ return this;
312
+ };
313
+
314
+ /**
315
+ * For throwing an exception when a spy is called.
316
+ *
317
+ * @example
318
+ * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
319
+ * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
320
+ *
321
+ * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
322
+ * spyOn(foo, 'bar').andThrow('baz');
323
+ *
324
+ * @param {String} exceptionMsg
325
+ */
326
+ jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
327
+ this.plan = function() {
328
+ throw exceptionMsg;
329
+ };
330
+ return this;
331
+ };
332
+
333
+ /**
334
+ * Calls an alternate implementation when a spy is called.
335
+ *
336
+ * @example
337
+ * var baz = function() {
338
+ * // do some stuff, return something
339
+ * }
340
+ * // defining a spy from scratch: foo() calls the function baz
341
+ * var foo = jasmine.createSpy('spy on foo').andCall(baz);
342
+ *
343
+ * // defining a spy on an existing property: foo.bar() calls an anonymnous function
344
+ * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
345
+ *
346
+ * @param {Function} fakeFunc
347
+ */
348
+ jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
349
+ this.plan = fakeFunc;
350
+ return this;
351
+ };
352
+
353
+ /**
354
+ * Resets all of a spy's the tracking variables so that it can be used again.
355
+ *
356
+ * @example
357
+ * spyOn(foo, 'bar');
358
+ *
359
+ * foo.bar();
360
+ *
361
+ * expect(foo.bar.callCount).toEqual(1);
362
+ *
363
+ * foo.bar.reset();
364
+ *
365
+ * expect(foo.bar.callCount).toEqual(0);
366
+ */
367
+ jasmine.Spy.prototype.reset = function() {
368
+ this.wasCalled = false;
369
+ this.callCount = 0;
370
+ this.argsForCall = [];
371
+ this.calls = [];
372
+ this.mostRecentCall = {};
373
+ };
374
+
375
+ jasmine.createSpy = function(name) {
376
+
377
+ var spyObj = function() {
378
+ spyObj.wasCalled = true;
379
+ spyObj.callCount++;
380
+ var args = jasmine.util.argsToArray(arguments);
381
+ spyObj.mostRecentCall.object = this;
382
+ spyObj.mostRecentCall.args = args;
383
+ spyObj.argsForCall.push(args);
384
+ spyObj.calls.push({object: this, args: args});
385
+ return spyObj.plan.apply(this, arguments);
386
+ };
387
+
388
+ var spy = new jasmine.Spy(name);
389
+
390
+ for (var prop in spy) {
391
+ spyObj[prop] = spy[prop];
392
+ }
393
+
394
+ spyObj.reset();
395
+
396
+ return spyObj;
397
+ };
398
+
399
+ /**
400
+ * Determines whether an object is a spy.
401
+ *
402
+ * @param {jasmine.Spy|Object} putativeSpy
403
+ * @returns {Boolean}
404
+ */
405
+ jasmine.isSpy = function(putativeSpy) {
406
+ return putativeSpy && putativeSpy.isSpy;
407
+ };
408
+
409
+ /**
410
+ * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something
411
+ * large in one call.
412
+ *
413
+ * @param {String} baseName name of spy class
414
+ * @param {Array} methodNames array of names of methods to make spies
415
+ */
416
+ jasmine.createSpyObj = function(baseName, methodNames) {
417
+ if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
418
+ throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
419
+ }
420
+ var obj = {};
421
+ for (var i = 0; i < methodNames.length; i++) {
422
+ obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
423
+ }
424
+ return obj;
425
+ };
426
+
427
+ /**
428
+ * All parameters are pretty-printed and concatenated together, then written to the current spec's output.
429
+ *
430
+ * Be careful not to leave calls to <code>jasmine.log</code> in production code.
431
+ */
432
+ jasmine.log = function() {
433
+ var spec = jasmine.getEnv().currentSpec;
434
+ spec.log.apply(spec, arguments);
435
+ };
436
+
437
+ /**
438
+ * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.
439
+ *
440
+ * @example
441
+ * // spy example
442
+ * var foo = {
443
+ * not: function(bool) { return !bool; }
444
+ * }
445
+ * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
446
+ *
447
+ * @see jasmine.createSpy
448
+ * @param obj
449
+ * @param methodName
450
+ * @returns a Jasmine spy that can be chained with all spy methods
451
+ */
452
+ var spyOn = function(obj, methodName) {
453
+ return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
454
+ };
455
+ if (isCommonJS) exports.spyOn = spyOn;
456
+
457
+ /**
458
+ * Creates a Jasmine spec that will be added to the current suite.
459
+ *
460
+ * // TODO: pending tests
461
+ *
462
+ * @example
463
+ * it('should be true', function() {
464
+ * expect(true).toEqual(true);
465
+ * });
466
+ *
467
+ * @param {String} desc description of this specification
468
+ * @param {Function} func defines the preconditions and expectations of the spec
469
+ */
470
+ var it = function(desc, func) {
471
+ return jasmine.getEnv().it(desc, func);
472
+ };
473
+ if (isCommonJS) exports.it = it;
474
+
475
+ /**
476
+ * Creates a <em>disabled</em> Jasmine spec.
477
+ *
478
+ * A convenience method that allows existing specs to be disabled temporarily during development.
479
+ *
480
+ * @param {String} desc description of this specification
481
+ * @param {Function} func defines the preconditions and expectations of the spec
482
+ */
483
+ var xit = function(desc, func) {
484
+ return jasmine.getEnv().xit(desc, func);
485
+ };
486
+ if (isCommonJS) exports.xit = xit;
487
+
488
+ /**
489
+ * Starts a chain for a Jasmine expectation.
490
+ *
491
+ * It is passed an Object that is the actual value and should chain to one of the many
492
+ * jasmine.Matchers functions.
493
+ *
494
+ * @param {Object} actual Actual value to test against and expected value
495
+ */
496
+ var expect = function(actual) {
497
+ return jasmine.getEnv().currentSpec.expect(actual);
498
+ };
499
+ if (isCommonJS) exports.expect = expect;
500
+
501
+ /**
502
+ * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
503
+ *
504
+ * @param {Function} func Function that defines part of a jasmine spec.
505
+ */
506
+ var runs = function(func) {
507
+ jasmine.getEnv().currentSpec.runs(func);
508
+ };
509
+ if (isCommonJS) exports.runs = runs;
510
+
511
+ /**
512
+ * Waits a fixed time period before moving to the next block.
513
+ *
514
+ * @deprecated Use waitsFor() instead
515
+ * @param {Number} timeout milliseconds to wait
516
+ */
517
+ var waits = function(timeout) {
518
+ jasmine.getEnv().currentSpec.waits(timeout);
519
+ };
520
+ if (isCommonJS) exports.waits = waits;
521
+
522
+ /**
523
+ * Waits for the latchFunction to return true before proceeding to the next block.
524
+ *
525
+ * @param {Function} latchFunction
526
+ * @param {String} optional_timeoutMessage
527
+ * @param {Number} optional_timeout
528
+ */
529
+ var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
530
+ jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
531
+ };
532
+ if (isCommonJS) exports.waitsFor = waitsFor;
533
+
534
+ /**
535
+ * A function that is called before each spec in a suite.
536
+ *
537
+ * Used for spec setup, including validating assumptions.
538
+ *
539
+ * @param {Function} beforeEachFunction
540
+ */
541
+ var beforeEach = function(beforeEachFunction) {
542
+ jasmine.getEnv().beforeEach(beforeEachFunction);
543
+ };
544
+ if (isCommonJS) exports.beforeEach = beforeEach;
545
+
546
+ /**
547
+ * A function that is called after each spec in a suite.
548
+ *
549
+ * Used for restoring any state that is hijacked during spec execution.
550
+ *
551
+ * @param {Function} afterEachFunction
552
+ */
553
+ var afterEach = function(afterEachFunction) {
554
+ jasmine.getEnv().afterEach(afterEachFunction);
555
+ };
556
+ if (isCommonJS) exports.afterEach = afterEach;
557
+
558
+ /**
559
+ * Defines a suite of specifications.
560
+ *
561
+ * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
562
+ * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
563
+ * of setup in some tests.
564
+ *
565
+ * @example
566
+ * // TODO: a simple suite
567
+ *
568
+ * // TODO: a simple suite with a nested describe block
569
+ *
570
+ * @param {String} description A string, usually the class under test.
571
+ * @param {Function} specDefinitions function that defines several specs.
572
+ */
573
+ var describe = function(description, specDefinitions) {
574
+ return jasmine.getEnv().describe(description, specDefinitions);
575
+ };
576
+ if (isCommonJS) exports.describe = describe;
577
+
578
+ /**
579
+ * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
580
+ *
581
+ * @param {String} description A string, usually the class under test.
582
+ * @param {Function} specDefinitions function that defines several specs.
583
+ */
584
+ var xdescribe = function(description, specDefinitions) {
585
+ return jasmine.getEnv().xdescribe(description, specDefinitions);
586
+ };
587
+ if (isCommonJS) exports.xdescribe = xdescribe;
588
+
589
+
590
+ // Provide the XMLHttpRequest class for IE 5.x-6.x:
591
+ jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
592
+ function tryIt(f) {
593
+ try {
594
+ return f();
595
+ } catch(e) {
596
+ }
597
+ return null;
598
+ }
599
+
600
+ var xhr = tryIt(function(){return new ActiveXObject("Msxml2.XMLHTTP.6.0");}) ||
601
+ tryIt(function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0");}) ||
602
+ tryIt(function(){return new ActiveXObject("Msxml2.XMLHTTP");}) ||
603
+ tryIt(function(){return new ActiveXObject("Microsoft.XMLHTTP");});
604
+
605
+ if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
606
+
607
+ return xhr;
608
+ } : XMLHttpRequest;
609
+ /**
610
+ * @namespace
611
+ */
612
+ jasmine.util = {};
613
+
614
+ /**
615
+ * Declare that a child class inherit it's prototype from the parent class.
616
+ *
617
+ * @private
618
+ * @param {Function} childClass
619
+ * @param {Function} parentClass
620
+ */
621
+ jasmine.util.inherit = function(childClass, parentClass) {
622
+ /**
623
+ * @private
624
+ */
625
+ var subclass = function() {
626
+ };
627
+ subclass.prototype = parentClass.prototype;
628
+ childClass.prototype = new subclass();
629
+ };
630
+
631
+ jasmine.util.formatException = function(e) {
632
+ var lineNumber;
633
+ if (e.line) {
634
+ lineNumber = e.line;
635
+ }
636
+ else if (e.lineNumber) {
637
+ lineNumber = e.lineNumber;
638
+ }
639
+
640
+ var file;
641
+
642
+ if (e.sourceURL) {
643
+ file = e.sourceURL;
644
+ }
645
+ else if (e.fileName) {
646
+ file = e.fileName;
647
+ }
648
+
649
+ var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
650
+
651
+ if (file && lineNumber) {
652
+ message += ' in ' + file + ' (line ' + lineNumber + ')';
653
+ }
654
+
655
+ return message;
656
+ };
657
+
658
+ jasmine.util.htmlEscape = function(str) {
659
+ if (!str) return str;
660
+ return str.replace(/&/g, '&amp;')
661
+ .replace(/</g, '&lt;')
662
+ .replace(/>/g, '&gt;');
663
+ };
664
+
665
+ jasmine.util.argsToArray = function(args) {
666
+ var arrayOfArgs = [];
667
+ for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
668
+ return arrayOfArgs;
669
+ };
670
+
671
+ jasmine.util.extend = function(destination, source) {
672
+ for (var property in source) destination[property] = source[property];
673
+ return destination;
674
+ };
675
+
676
+ /**
677
+ * Environment for Jasmine
678
+ *
679
+ * @constructor
680
+ */
681
+ jasmine.Env = function() {
682
+ this.currentSpec = null;
683
+ this.currentSuite = null;
684
+ this.currentRunner_ = new jasmine.Runner(this);
685
+
686
+ this.reporter = new jasmine.MultiReporter();
687
+
688
+ this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
689
+ this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
690
+ this.lastUpdate = 0;
691
+ this.specFilter = function() {
692
+ return true;
693
+ };
694
+
695
+ this.nextSpecId_ = 0;
696
+ this.nextSuiteId_ = 0;
697
+ this.equalityTesters_ = [];
698
+
699
+ // wrap matchers
700
+ this.matchersClass = function() {
701
+ jasmine.Matchers.apply(this, arguments);
702
+ };
703
+ jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
704
+
705
+ jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
706
+ };
707
+
708
+
709
+ jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
710
+ jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
711
+ jasmine.Env.prototype.setInterval = jasmine.setInterval;
712
+ jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
713
+
714
+ /**
715
+ * @returns an object containing jasmine version build info, if set.
716
+ */
717
+ jasmine.Env.prototype.version = function () {
718
+ if (jasmine.version_) {
719
+ return jasmine.version_;
720
+ } else {
721
+ throw new Error('Version not set');
722
+ }
723
+ };
724
+
725
+ /**
726
+ * @returns string containing jasmine version build info, if set.
727
+ */
728
+ jasmine.Env.prototype.versionString = function() {
729
+ if (jasmine.version_) {
730
+ var version = this.version();
731
+ return version.major + "." + version.minor + "." + version.build + " revision " + version.revision;
732
+ } else {
733
+ return "version unknown";
734
+ }
735
+ };
736
+
737
+ /**
738
+ * @returns a sequential integer starting at 0
739
+ */
740
+ jasmine.Env.prototype.nextSpecId = function () {
741
+ return this.nextSpecId_++;
742
+ };
743
+
744
+ /**
745
+ * @returns a sequential integer starting at 0
746
+ */
747
+ jasmine.Env.prototype.nextSuiteId = function () {
748
+ return this.nextSuiteId_++;
749
+ };
750
+
751
+ /**
752
+ * Register a reporter to receive status updates from Jasmine.
753
+ * @param {jasmine.Reporter} reporter An object which will receive status updates.
754
+ */
755
+ jasmine.Env.prototype.addReporter = function(reporter) {
756
+ this.reporter.addReporter(reporter);
757
+ };
758
+
759
+ jasmine.Env.prototype.execute = function() {
760
+ this.currentRunner_.execute();
761
+ };
762
+
763
+ jasmine.Env.prototype.describe = function(description, specDefinitions) {
764
+ var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
765
+
766
+ var parentSuite = this.currentSuite;
767
+ if (parentSuite) {
768
+ parentSuite.add(suite);
769
+ } else {
770
+ this.currentRunner_.add(suite);
771
+ }
772
+
773
+ this.currentSuite = suite;
774
+
775
+ var declarationError = null;
776
+ try {
777
+ specDefinitions.call(suite);
778
+ } catch(e) {
779
+ declarationError = e;
780
+ }
781
+
782
+ this.currentSuite = parentSuite;
783
+
784
+ if (declarationError) {
785
+ this.it("encountered a declaration exception", function() {
786
+ throw declarationError;
787
+ });
788
+ }
789
+
790
+ return suite;
791
+ };
792
+
793
+ jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
794
+ if (this.currentSuite) {
795
+ this.currentSuite.beforeEach(beforeEachFunction);
796
+ } else {
797
+ this.currentRunner_.beforeEach(beforeEachFunction);
798
+ }
799
+ };
800
+
801
+ jasmine.Env.prototype.currentRunner = function () {
802
+ return this.currentRunner_;
803
+ };
804
+
805
+ jasmine.Env.prototype.afterEach = function(afterEachFunction) {
806
+ if (this.currentSuite) {
807
+ this.currentSuite.afterEach(afterEachFunction);
808
+ } else {
809
+ this.currentRunner_.afterEach(afterEachFunction);
810
+ }
811
+
812
+ };
813
+
814
+ jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
815
+ return {
816
+ execute: function() {
817
+ }
818
+ };
819
+ };
820
+
821
+ jasmine.Env.prototype.it = function(description, func) {
822
+ var spec = new jasmine.Spec(this, this.currentSuite, description);
823
+ this.currentSuite.add(spec);
824
+ this.currentSpec = spec;
825
+
826
+ if (func) {
827
+ spec.runs(func);
828
+ }
829
+
830
+ return spec;
831
+ };
832
+
833
+ jasmine.Env.prototype.xit = function(desc, func) {
834
+ return {
835
+ id: this.nextSpecId(),
836
+ runs: function() {
837
+ }
838
+ };
839
+ };
840
+
841
+ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
842
+ if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
843
+ return true;
844
+ }
845
+
846
+ a.__Jasmine_been_here_before__ = b;
847
+ b.__Jasmine_been_here_before__ = a;
848
+
849
+ var hasKey = function(obj, keyName) {
850
+ return obj !== null && obj[keyName] !== jasmine.undefined;
851
+ };
852
+
853
+ for (var property in b) {
854
+ if (!hasKey(a, property) && hasKey(b, property)) {
855
+ mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
856
+ }
857
+ }
858
+ for (property in a) {
859
+ if (!hasKey(b, property) && hasKey(a, property)) {
860
+ mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
861
+ }
862
+ }
863
+ for (property in b) {
864
+ if (property == '__Jasmine_been_here_before__') continue;
865
+ if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
866
+ mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
867
+ }
868
+ }
869
+
870
+ if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
871
+ mismatchValues.push("arrays were not the same length");
872
+ }
873
+
874
+ delete a.__Jasmine_been_here_before__;
875
+ delete b.__Jasmine_been_here_before__;
876
+ return (mismatchKeys.length === 0 && mismatchValues.length === 0);
877
+ };
878
+
879
+ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
880
+ mismatchKeys = mismatchKeys || [];
881
+ mismatchValues = mismatchValues || [];
882
+
883
+ for (var i = 0; i < this.equalityTesters_.length; i++) {
884
+ var equalityTester = this.equalityTesters_[i];
885
+ var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
886
+ if (result !== jasmine.undefined) return result;
887
+ }
888
+
889
+ if (a === b) return true;
890
+
891
+ if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
892
+ return (a == jasmine.undefined && b == jasmine.undefined);
893
+ }
894
+
895
+ if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
896
+ return a === b;
897
+ }
898
+
899
+ if (a instanceof Date && b instanceof Date) {
900
+ return a.getTime() == b.getTime();
901
+ }
902
+
903
+ if (a instanceof jasmine.Matchers.Any) {
904
+ return a.matches(b);
905
+ }
906
+
907
+ if (b instanceof jasmine.Matchers.Any) {
908
+ return b.matches(a);
909
+ }
910
+
911
+ if (jasmine.isString_(a) && jasmine.isString_(b)) {
912
+ return (a == b);
913
+ }
914
+
915
+ if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
916
+ return (a == b);
917
+ }
918
+
919
+ if (typeof a === "object" && typeof b === "object") {
920
+ return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
921
+ }
922
+
923
+ //Straight check
924
+ return (a === b);
925
+ };
926
+
927
+ jasmine.Env.prototype.contains_ = function(haystack, needle) {
928
+ if (jasmine.isArray_(haystack)) {
929
+ for (var i = 0; i < haystack.length; i++) {
930
+ if (this.equals_(haystack[i], needle)) return true;
931
+ }
932
+ return false;
933
+ }
934
+ return haystack.indexOf(needle) >= 0;
935
+ };
936
+
937
+ jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
938
+ this.equalityTesters_.push(equalityTester);
939
+ };
940
+ /** No-op base class for Jasmine reporters.
941
+ *
942
+ * @constructor
943
+ */
944
+ jasmine.Reporter = function() {
945
+ };
946
+
947
+ //noinspection JSUnusedLocalSymbols
948
+ jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
949
+ };
950
+
951
+ //noinspection JSUnusedLocalSymbols
952
+ jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
953
+ };
954
+
955
+ //noinspection JSUnusedLocalSymbols
956
+ jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
957
+ };
958
+
959
+ //noinspection JSUnusedLocalSymbols
960
+ jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
961
+ };
962
+
963
+ //noinspection JSUnusedLocalSymbols
964
+ jasmine.Reporter.prototype.reportSpecResults = function(spec) {
965
+ };
966
+
967
+ //noinspection JSUnusedLocalSymbols
968
+ jasmine.Reporter.prototype.log = function(str) {
969
+ };
970
+
971
+ /**
972
+ * Blocks are functions with executable code that make up a spec.
973
+ *
974
+ * @constructor
975
+ * @param {jasmine.Env} env
976
+ * @param {Function} func
977
+ * @param {jasmine.Spec} spec
978
+ */
979
+ jasmine.Block = function(env, func, spec) {
980
+ this.env = env;
981
+ this.func = func;
982
+ this.spec = spec;
983
+ };
984
+
985
+ jasmine.Block.prototype.execute = function(onComplete) {
986
+ try {
987
+ this.func.apply(this.spec);
988
+ } catch (e) {
989
+ this.spec.fail(e);
990
+ }
991
+ onComplete();
992
+ };
993
+ /** JavaScript API reporter.
994
+ *
995
+ * @constructor
996
+ */
997
+ jasmine.JsApiReporter = function() {
998
+ this.started = false;
999
+ this.finished = false;
1000
+ this.suites_ = [];
1001
+ this.results_ = {};
1002
+ };
1003
+
1004
+ jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
1005
+ this.started = true;
1006
+ var suites = runner.topLevelSuites();
1007
+ for (var i = 0; i < suites.length; i++) {
1008
+ var suite = suites[i];
1009
+ this.suites_.push(this.summarize_(suite));
1010
+ }
1011
+ };
1012
+
1013
+ jasmine.JsApiReporter.prototype.suites = function() {
1014
+ return this.suites_;
1015
+ };
1016
+
1017
+ jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
1018
+ var isSuite = suiteOrSpec instanceof jasmine.Suite;
1019
+ var summary = {
1020
+ id: suiteOrSpec.id,
1021
+ name: suiteOrSpec.description,
1022
+ type: isSuite ? 'suite' : 'spec',
1023
+ children: []
1024
+ };
1025
+
1026
+ if (isSuite) {
1027
+ var children = suiteOrSpec.children();
1028
+ for (var i = 0; i < children.length; i++) {
1029
+ summary.children.push(this.summarize_(children[i]));
1030
+ }
1031
+ }
1032
+ return summary;
1033
+ };
1034
+
1035
+ jasmine.JsApiReporter.prototype.results = function() {
1036
+ return this.results_;
1037
+ };
1038
+
1039
+ jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
1040
+ return this.results_[specId];
1041
+ };
1042
+
1043
+ //noinspection JSUnusedLocalSymbols
1044
+ jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
1045
+ this.finished = true;
1046
+ };
1047
+
1048
+ //noinspection JSUnusedLocalSymbols
1049
+ jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
1050
+ };
1051
+
1052
+ //noinspection JSUnusedLocalSymbols
1053
+ jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
1054
+ this.results_[spec.id] = {
1055
+ messages: spec.results().getItems(),
1056
+ result: spec.results().failedCount > 0 ? "failed" : "passed"
1057
+ };
1058
+ };
1059
+
1060
+ //noinspection JSUnusedLocalSymbols
1061
+ jasmine.JsApiReporter.prototype.log = function(str) {
1062
+ };
1063
+
1064
+ jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
1065
+ var results = {};
1066
+ for (var i = 0; i < specIds.length; i++) {
1067
+ var specId = specIds[i];
1068
+ results[specId] = this.summarizeResult_(this.results_[specId]);
1069
+ }
1070
+ return results;
1071
+ };
1072
+
1073
+ jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
1074
+ var summaryMessages = [];
1075
+ var messagesLength = result.messages.length;
1076
+ for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
1077
+ var resultMessage = result.messages[messageIndex];
1078
+ summaryMessages.push({
1079
+ text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
1080
+ passed: resultMessage.passed ? resultMessage.passed() : true,
1081
+ type: resultMessage.type,
1082
+ message: resultMessage.message,
1083
+ trace: {
1084
+ stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
1085
+ }
1086
+ });
1087
+ }
1088
+
1089
+ return {
1090
+ result : result.result,
1091
+ messages : summaryMessages
1092
+ };
1093
+ };
1094
+
1095
+ /**
1096
+ * @constructor
1097
+ * @param {jasmine.Env} env
1098
+ * @param actual
1099
+ * @param {jasmine.Spec} spec
1100
+ */
1101
+ jasmine.Matchers = function(env, actual, spec, opt_isNot) {
1102
+ this.env = env;
1103
+ this.actual = actual;
1104
+ this.spec = spec;
1105
+ this.isNot = opt_isNot || false;
1106
+ this.reportWasCalled_ = false;
1107
+ };
1108
+
1109
+ // todo: @deprecated as of Jasmine 0.11, remove soon [xw]
1110
+ jasmine.Matchers.pp = function(str) {
1111
+ throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
1112
+ };
1113
+
1114
+ // todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
1115
+ jasmine.Matchers.prototype.report = function(result, failing_message, details) {
1116
+ throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
1117
+ };
1118
+
1119
+ jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
1120
+ for (var methodName in prototype) {
1121
+ if (methodName == 'report') continue;
1122
+ var orig = prototype[methodName];
1123
+ matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
1124
+ }
1125
+ };
1126
+
1127
+ jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
1128
+ return function() {
1129
+ var matcherArgs = jasmine.util.argsToArray(arguments);
1130
+ var result = matcherFunction.apply(this, arguments);
1131
+
1132
+ if (this.isNot) {
1133
+ result = !result;
1134
+ }
1135
+
1136
+ if (this.reportWasCalled_) return result;
1137
+
1138
+ var message;
1139
+ if (!result) {
1140
+ if (this.message) {
1141
+ message = this.message.apply(this, arguments);
1142
+ if (jasmine.isArray_(message)) {
1143
+ message = message[this.isNot ? 1 : 0];
1144
+ }
1145
+ } else {
1146
+ var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
1147
+ message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate;
1148
+ if (matcherArgs.length > 0) {
1149
+ for (var i = 0; i < matcherArgs.length; i++) {
1150
+ if (i > 0) message += ",";
1151
+ message += " " + jasmine.pp(matcherArgs[i]);
1152
+ }
1153
+ }
1154
+ message += ".";
1155
+ }
1156
+ }
1157
+ var expectationResult = new jasmine.ExpectationResult({
1158
+ matcherName: matcherName,
1159
+ passed: result,
1160
+ expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
1161
+ actual: this.actual,
1162
+ message: message
1163
+ });
1164
+ this.spec.addMatcherResult(expectationResult);
1165
+ return jasmine.undefined;
1166
+ };
1167
+ };
1168
+
1169
+
1170
+
1171
+
1172
+ /**
1173
+ * toBe: compares the actual to the expected using ===
1174
+ * @param expected
1175
+ */
1176
+ jasmine.Matchers.prototype.toBe = function(expected) {
1177
+ return this.actual === expected;
1178
+ };
1179
+
1180
+ /**
1181
+ * toNotBe: compares the actual to the expected using !==
1182
+ * @param expected
1183
+ * @deprecated as of 1.0. Use not.toBe() instead.
1184
+ */
1185
+ jasmine.Matchers.prototype.toNotBe = function(expected) {
1186
+ return this.actual !== expected;
1187
+ };
1188
+
1189
+ /**
1190
+ * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
1191
+ *
1192
+ * @param expected
1193
+ */
1194
+ jasmine.Matchers.prototype.toEqual = function(expected) {
1195
+ return this.env.equals_(this.actual, expected);
1196
+ };
1197
+
1198
+ /**
1199
+ * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
1200
+ * @param expected
1201
+ * @deprecated as of 1.0. Use not.toNotEqual() instead.
1202
+ */
1203
+ jasmine.Matchers.prototype.toNotEqual = function(expected) {
1204
+ return !this.env.equals_(this.actual, expected);
1205
+ };
1206
+
1207
+ /**
1208
+ * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes
1209
+ * a pattern or a String.
1210
+ *
1211
+ * @param expected
1212
+ */
1213
+ jasmine.Matchers.prototype.toMatch = function(expected) {
1214
+ return new RegExp(expected).test(this.actual);
1215
+ };
1216
+
1217
+ /**
1218
+ * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
1219
+ * @param expected
1220
+ * @deprecated as of 1.0. Use not.toMatch() instead.
1221
+ */
1222
+ jasmine.Matchers.prototype.toNotMatch = function(expected) {
1223
+ return !(new RegExp(expected).test(this.actual));
1224
+ };
1225
+
1226
+ /**
1227
+ * Matcher that compares the actual to jasmine.undefined.
1228
+ */
1229
+ jasmine.Matchers.prototype.toBeDefined = function() {
1230
+ return (this.actual !== jasmine.undefined);
1231
+ };
1232
+
1233
+ /**
1234
+ * Matcher that compares the actual to jasmine.undefined.
1235
+ */
1236
+ jasmine.Matchers.prototype.toBeUndefined = function() {
1237
+ return (this.actual === jasmine.undefined);
1238
+ };
1239
+
1240
+ /**
1241
+ * Matcher that compares the actual to null.
1242
+ */
1243
+ jasmine.Matchers.prototype.toBeNull = function() {
1244
+ return (this.actual === null);
1245
+ };
1246
+
1247
+ /**
1248
+ * Matcher that boolean not-nots the actual.
1249
+ */
1250
+ jasmine.Matchers.prototype.toBeTruthy = function() {
1251
+ return !!this.actual;
1252
+ };
1253
+
1254
+
1255
+ /**
1256
+ * Matcher that boolean nots the actual.
1257
+ */
1258
+ jasmine.Matchers.prototype.toBeFalsy = function() {
1259
+ return !this.actual;
1260
+ };
1261
+
1262
+
1263
+ /**
1264
+ * Matcher that checks to see if the actual, a Jasmine spy, was called.
1265
+ */
1266
+ jasmine.Matchers.prototype.toHaveBeenCalled = function() {
1267
+ if (arguments.length > 0) {
1268
+ throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
1269
+ }
1270
+
1271
+ if (!jasmine.isSpy(this.actual)) {
1272
+ throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1273
+ }
1274
+
1275
+ this.message = function() {
1276
+ return [
1277
+ "Expected spy " + this.actual.identity + " to have been called.",
1278
+ "Expected spy " + this.actual.identity + " not to have been called."
1279
+ ];
1280
+ };
1281
+
1282
+ return this.actual.wasCalled;
1283
+ };
1284
+
1285
+ /** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
1286
+ jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
1287
+
1288
+ /**
1289
+ * Matcher that checks to see if the actual, a Jasmine spy, was not called.
1290
+ *
1291
+ * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead
1292
+ */
1293
+ jasmine.Matchers.prototype.wasNotCalled = function() {
1294
+ if (arguments.length > 0) {
1295
+ throw new Error('wasNotCalled does not take arguments');
1296
+ }
1297
+
1298
+ if (!jasmine.isSpy(this.actual)) {
1299
+ throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1300
+ }
1301
+
1302
+ this.message = function() {
1303
+ return [
1304
+ "Expected spy " + this.actual.identity + " to not have been called.",
1305
+ "Expected spy " + this.actual.identity + " to have been called."
1306
+ ];
1307
+ };
1308
+
1309
+ return !this.actual.wasCalled;
1310
+ };
1311
+
1312
+ /**
1313
+ * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
1314
+ *
1315
+ * @example
1316
+ *
1317
+ */
1318
+ jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
1319
+ var expectedArgs = jasmine.util.argsToArray(arguments);
1320
+ if (!jasmine.isSpy(this.actual)) {
1321
+ throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1322
+ }
1323
+ this.message = function() {
1324
+ if (this.actual.callCount === 0) {
1325
+ // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw]
1326
+ return [
1327
+ "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.",
1328
+ "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was."
1329
+ ];
1330
+ } else {
1331
+ return [
1332
+ "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall),
1333
+ "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall)
1334
+ ];
1335
+ }
1336
+ };
1337
+
1338
+ return this.env.contains_(this.actual.argsForCall, expectedArgs);
1339
+ };
1340
+
1341
+ /** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
1342
+ jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
1343
+
1344
+ /** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
1345
+ jasmine.Matchers.prototype.wasNotCalledWith = function() {
1346
+ var expectedArgs = jasmine.util.argsToArray(arguments);
1347
+ if (!jasmine.isSpy(this.actual)) {
1348
+ throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1349
+ }
1350
+
1351
+ this.message = function() {
1352
+ return [
1353
+ "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
1354
+ "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
1355
+ ];
1356
+ };
1357
+
1358
+ return !this.env.contains_(this.actual.argsForCall, expectedArgs);
1359
+ };
1360
+
1361
+ /**
1362
+ * Matcher that checks that the expected item is an element in the actual Array.
1363
+ *
1364
+ * @param {Object} expected
1365
+ */
1366
+ jasmine.Matchers.prototype.toContain = function(expected) {
1367
+ return this.env.contains_(this.actual, expected);
1368
+ };
1369
+
1370
+ /**
1371
+ * Matcher that checks that the expected item is NOT an element in the actual Array.
1372
+ *
1373
+ * @param {Object} expected
1374
+ * @deprecated as of 1.0. Use not.toNotContain() instead.
1375
+ */
1376
+ jasmine.Matchers.prototype.toNotContain = function(expected) {
1377
+ return !this.env.contains_(this.actual, expected);
1378
+ };
1379
+
1380
+ jasmine.Matchers.prototype.toBeLessThan = function(expected) {
1381
+ return this.actual < expected;
1382
+ };
1383
+
1384
+ jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
1385
+ return this.actual > expected;
1386
+ };
1387
+
1388
+ /**
1389
+ * Matcher that checks that the expected exception was thrown by the actual.
1390
+ *
1391
+ * @param {String} expected
1392
+ */
1393
+ jasmine.Matchers.prototype.toThrow = function(expected) {
1394
+ var result = false;
1395
+ var exception;
1396
+ if (typeof this.actual != 'function') {
1397
+ throw new Error('Actual is not a function');
1398
+ }
1399
+ try {
1400
+ this.actual();
1401
+ } catch (e) {
1402
+ exception = e;
1403
+ }
1404
+ if (exception) {
1405
+ result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
1406
+ }
1407
+
1408
+ var not = this.isNot ? "not " : "";
1409
+
1410
+ this.message = function() {
1411
+ if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
1412
+ return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
1413
+ } else {
1414
+ return "Expected function to throw an exception.";
1415
+ }
1416
+ };
1417
+
1418
+ return result;
1419
+ };
1420
+
1421
+ jasmine.Matchers.Any = function(expectedClass) {
1422
+ this.expectedClass = expectedClass;
1423
+ };
1424
+
1425
+ jasmine.Matchers.Any.prototype.matches = function(other) {
1426
+ if (this.expectedClass == String) {
1427
+ return typeof other == 'string' || other instanceof String;
1428
+ }
1429
+
1430
+ if (this.expectedClass == Number) {
1431
+ return typeof other == 'number' || other instanceof Number;
1432
+ }
1433
+
1434
+ if (this.expectedClass == Function) {
1435
+ return typeof other == 'function' || other instanceof Function;
1436
+ }
1437
+
1438
+ if (this.expectedClass == Object) {
1439
+ return typeof other == 'object';
1440
+ }
1441
+
1442
+ return other instanceof this.expectedClass;
1443
+ };
1444
+
1445
+ jasmine.Matchers.Any.prototype.toString = function() {
1446
+ return '<jasmine.any(' + this.expectedClass + ')>';
1447
+ };
1448
+
1449
+ /**
1450
+ * @constructor
1451
+ */
1452
+ jasmine.MultiReporter = function() {
1453
+ this.subReporters_ = [];
1454
+ };
1455
+ jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
1456
+
1457
+ jasmine.MultiReporter.prototype.addReporter = function(reporter) {
1458
+ this.subReporters_.push(reporter);
1459
+ };
1460
+
1461
+ (function() {
1462
+ var functionNames = [
1463
+ "reportRunnerStarting",
1464
+ "reportRunnerResults",
1465
+ "reportSuiteResults",
1466
+ "reportSpecStarting",
1467
+ "reportSpecResults",
1468
+ "log"
1469
+ ];
1470
+ for (var i = 0; i < functionNames.length; i++) {
1471
+ var functionName = functionNames[i];
1472
+ jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
1473
+ return function() {
1474
+ for (var j = 0; j < this.subReporters_.length; j++) {
1475
+ var subReporter = this.subReporters_[j];
1476
+ if (subReporter[functionName]) {
1477
+ subReporter[functionName].apply(subReporter, arguments);
1478
+ }
1479
+ }
1480
+ };
1481
+ })(functionName);
1482
+ }
1483
+ })();
1484
+ /**
1485
+ * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
1486
+ *
1487
+ * @constructor
1488
+ */
1489
+ jasmine.NestedResults = function() {
1490
+ /**
1491
+ * The total count of results
1492
+ */
1493
+ this.totalCount = 0;
1494
+ /**
1495
+ * Number of passed results
1496
+ */
1497
+ this.passedCount = 0;
1498
+ /**
1499
+ * Number of failed results
1500
+ */
1501
+ this.failedCount = 0;
1502
+ /**
1503
+ * Was this suite/spec skipped?
1504
+ */
1505
+ this.skipped = false;
1506
+ /**
1507
+ * @ignore
1508
+ */
1509
+ this.items_ = [];
1510
+ };
1511
+
1512
+ /**
1513
+ * Roll up the result counts.
1514
+ *
1515
+ * @param result
1516
+ */
1517
+ jasmine.NestedResults.prototype.rollupCounts = function(result) {
1518
+ this.totalCount += result.totalCount;
1519
+ this.passedCount += result.passedCount;
1520
+ this.failedCount += result.failedCount;
1521
+ };
1522
+
1523
+ /**
1524
+ * Adds a log message.
1525
+ * @param values Array of message parts which will be concatenated later.
1526
+ */
1527
+ jasmine.NestedResults.prototype.log = function(values) {
1528
+ this.items_.push(new jasmine.MessageResult(values));
1529
+ };
1530
+
1531
+ /**
1532
+ * Getter for the results: message & results.
1533
+ */
1534
+ jasmine.NestedResults.prototype.getItems = function() {
1535
+ return this.items_;
1536
+ };
1537
+
1538
+ /**
1539
+ * Adds a result, tracking counts (total, passed, & failed)
1540
+ * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
1541
+ */
1542
+ jasmine.NestedResults.prototype.addResult = function(result) {
1543
+ if (result.type != 'log') {
1544
+ if (result.items_) {
1545
+ this.rollupCounts(result);
1546
+ } else {
1547
+ this.totalCount++;
1548
+ if (result.passed()) {
1549
+ this.passedCount++;
1550
+ } else {
1551
+ this.failedCount++;
1552
+ }
1553
+ }
1554
+ }
1555
+ this.items_.push(result);
1556
+ };
1557
+
1558
+ /**
1559
+ * @returns {Boolean} True if <b>everything</b> below passed
1560
+ */
1561
+ jasmine.NestedResults.prototype.passed = function() {
1562
+ return this.passedCount === this.totalCount;
1563
+ };
1564
+ /**
1565
+ * Base class for pretty printing for expectation results.
1566
+ */
1567
+ jasmine.PrettyPrinter = function() {
1568
+ this.ppNestLevel_ = 0;
1569
+ };
1570
+
1571
+ /**
1572
+ * Formats a value in a nice, human-readable string.
1573
+ *
1574
+ * @param value
1575
+ */
1576
+ jasmine.PrettyPrinter.prototype.format = function(value) {
1577
+ if (this.ppNestLevel_ > 40) {
1578
+ throw new Error('jasmine.PrettyPrinter: format() nested too deeply!');
1579
+ }
1580
+
1581
+ this.ppNestLevel_++;
1582
+ try {
1583
+ if (value === jasmine.undefined) {
1584
+ this.emitScalar('undefined');
1585
+ } else if (value === null) {
1586
+ this.emitScalar('null');
1587
+ } else if (value === jasmine.getGlobal()) {
1588
+ this.emitScalar('<global>');
1589
+ } else if (value instanceof jasmine.Matchers.Any) {
1590
+ this.emitScalar(value.toString());
1591
+ } else if (typeof value === 'string') {
1592
+ this.emitString(value);
1593
+ } else if (jasmine.isSpy(value)) {
1594
+ this.emitScalar("spy on " + value.identity);
1595
+ } else if (value instanceof RegExp) {
1596
+ this.emitScalar(value.toString());
1597
+ } else if (typeof value === 'function') {
1598
+ this.emitScalar('Function');
1599
+ } else if (typeof value.nodeType === 'number') {
1600
+ this.emitScalar('HTMLNode');
1601
+ } else if (value instanceof Date) {
1602
+ this.emitScalar('Date(' + value + ')');
1603
+ } else if (value.__Jasmine_been_here_before__) {
1604
+ this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');
1605
+ } else if (jasmine.isArray_(value) || typeof value == 'object') {
1606
+ value.__Jasmine_been_here_before__ = true;
1607
+ if (jasmine.isArray_(value)) {
1608
+ this.emitArray(value);
1609
+ } else {
1610
+ this.emitObject(value);
1611
+ }
1612
+ delete value.__Jasmine_been_here_before__;
1613
+ } else {
1614
+ this.emitScalar(value.toString());
1615
+ }
1616
+ } finally {
1617
+ this.ppNestLevel_--;
1618
+ }
1619
+ };
1620
+
1621
+ jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
1622
+ for (var property in obj) {
1623
+ if (property == '__Jasmine_been_here_before__') continue;
1624
+ fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
1625
+ obj.__lookupGetter__(property) !== null) : false);
1626
+ }
1627
+ };
1628
+
1629
+ jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
1630
+ jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
1631
+ jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
1632
+ jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
1633
+
1634
+ jasmine.StringPrettyPrinter = function() {
1635
+ jasmine.PrettyPrinter.call(this);
1636
+
1637
+ this.string = '';
1638
+ };
1639
+ jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
1640
+
1641
+ jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
1642
+ this.append(value);
1643
+ };
1644
+
1645
+ jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
1646
+ this.append("'" + value + "'");
1647
+ };
1648
+
1649
+ jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
1650
+ this.append('[ ');
1651
+ for (var i = 0; i < array.length; i++) {
1652
+ if (i > 0) {
1653
+ this.append(', ');
1654
+ }
1655
+ this.format(array[i]);
1656
+ }
1657
+ this.append(' ]');
1658
+ };
1659
+
1660
+ jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
1661
+ var self = this;
1662
+ this.append('{ ');
1663
+ var first = true;
1664
+
1665
+ this.iterateObject(obj, function(property, isGetter) {
1666
+ if (first) {
1667
+ first = false;
1668
+ } else {
1669
+ self.append(', ');
1670
+ }
1671
+
1672
+ self.append(property);
1673
+ self.append(' : ');
1674
+ if (isGetter) {
1675
+ self.append('<getter>');
1676
+ } else {
1677
+ self.format(obj[property]);
1678
+ }
1679
+ });
1680
+
1681
+ this.append(' }');
1682
+ };
1683
+
1684
+ jasmine.StringPrettyPrinter.prototype.append = function(value) {
1685
+ this.string += value;
1686
+ };
1687
+ jasmine.Queue = function(env) {
1688
+ this.env = env;
1689
+ this.blocks = [];
1690
+ this.running = false;
1691
+ this.index = 0;
1692
+ this.offset = 0;
1693
+ this.abort = false;
1694
+ };
1695
+
1696
+ jasmine.Queue.prototype.addBefore = function(block) {
1697
+ this.blocks.unshift(block);
1698
+ };
1699
+
1700
+ jasmine.Queue.prototype.add = function(block) {
1701
+ this.blocks.push(block);
1702
+ };
1703
+
1704
+ jasmine.Queue.prototype.insertNext = function(block) {
1705
+ this.blocks.splice((this.index + this.offset + 1), 0, block);
1706
+ this.offset++;
1707
+ };
1708
+
1709
+ jasmine.Queue.prototype.start = function(onComplete) {
1710
+ this.running = true;
1711
+ this.onComplete = onComplete;
1712
+ this.next_();
1713
+ };
1714
+
1715
+ jasmine.Queue.prototype.isRunning = function() {
1716
+ return this.running;
1717
+ };
1718
+
1719
+ jasmine.Queue.LOOP_DONT_RECURSE = true;
1720
+
1721
+ jasmine.Queue.prototype.next_ = function() {
1722
+ var self = this;
1723
+ var goAgain = true;
1724
+
1725
+ while (goAgain) {
1726
+ goAgain = false;
1727
+
1728
+ if (self.index < self.blocks.length && !this.abort) {
1729
+ var calledSynchronously = true;
1730
+ var completedSynchronously = false;
1731
+
1732
+ var onComplete = function () {
1733
+ if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
1734
+ completedSynchronously = true;
1735
+ return;
1736
+ }
1737
+
1738
+ if (self.blocks[self.index].abort) {
1739
+ self.abort = true;
1740
+ }
1741
+
1742
+ self.offset = 0;
1743
+ self.index++;
1744
+
1745
+ var now = new Date().getTime();
1746
+ if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
1747
+ self.env.lastUpdate = now;
1748
+ self.env.setTimeout(function() {
1749
+ self.next_();
1750
+ }, 0);
1751
+ } else {
1752
+ if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
1753
+ goAgain = true;
1754
+ } else {
1755
+ self.next_();
1756
+ }
1757
+ }
1758
+ };
1759
+ self.blocks[self.index].execute(onComplete);
1760
+
1761
+ calledSynchronously = false;
1762
+ if (completedSynchronously) {
1763
+ onComplete();
1764
+ }
1765
+
1766
+ } else {
1767
+ self.running = false;
1768
+ if (self.onComplete) {
1769
+ self.onComplete();
1770
+ }
1771
+ }
1772
+ }
1773
+ };
1774
+
1775
+ jasmine.Queue.prototype.results = function() {
1776
+ var results = new jasmine.NestedResults();
1777
+ for (var i = 0; i < this.blocks.length; i++) {
1778
+ if (this.blocks[i].results) {
1779
+ results.addResult(this.blocks[i].results());
1780
+ }
1781
+ }
1782
+ return results;
1783
+ };
1784
+
1785
+
1786
+ /**
1787
+ * Runner
1788
+ *
1789
+ * @constructor
1790
+ * @param {jasmine.Env} env
1791
+ */
1792
+ jasmine.Runner = function(env) {
1793
+ var self = this;
1794
+ self.env = env;
1795
+ self.queue = new jasmine.Queue(env);
1796
+ self.before_ = [];
1797
+ self.after_ = [];
1798
+ self.suites_ = [];
1799
+ };
1800
+
1801
+ jasmine.Runner.prototype.execute = function() {
1802
+ var self = this;
1803
+ if (self.env.reporter.reportRunnerStarting) {
1804
+ self.env.reporter.reportRunnerStarting(this);
1805
+ }
1806
+ self.queue.start(function () {
1807
+ self.finishCallback();
1808
+ });
1809
+ };
1810
+
1811
+ jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
1812
+ beforeEachFunction.typeName = 'beforeEach';
1813
+ this.before_.splice(0,0,beforeEachFunction);
1814
+ };
1815
+
1816
+ jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
1817
+ afterEachFunction.typeName = 'afterEach';
1818
+ this.after_.splice(0,0,afterEachFunction);
1819
+ };
1820
+
1821
+
1822
+ jasmine.Runner.prototype.finishCallback = function() {
1823
+ this.env.reporter.reportRunnerResults(this);
1824
+ };
1825
+
1826
+ jasmine.Runner.prototype.addSuite = function(suite) {
1827
+ this.suites_.push(suite);
1828
+ };
1829
+
1830
+ jasmine.Runner.prototype.add = function(block) {
1831
+ if (block instanceof jasmine.Suite) {
1832
+ this.addSuite(block);
1833
+ }
1834
+ this.queue.add(block);
1835
+ };
1836
+
1837
+ jasmine.Runner.prototype.specs = function () {
1838
+ var suites = this.suites();
1839
+ var specs = [];
1840
+ for (var i = 0; i < suites.length; i++) {
1841
+ specs = specs.concat(suites[i].specs());
1842
+ }
1843
+ return specs;
1844
+ };
1845
+
1846
+ jasmine.Runner.prototype.suites = function() {
1847
+ return this.suites_;
1848
+ };
1849
+
1850
+ jasmine.Runner.prototype.topLevelSuites = function() {
1851
+ var topLevelSuites = [];
1852
+ for (var i = 0; i < this.suites_.length; i++) {
1853
+ if (!this.suites_[i].parentSuite) {
1854
+ topLevelSuites.push(this.suites_[i]);
1855
+ }
1856
+ }
1857
+ return topLevelSuites;
1858
+ };
1859
+
1860
+ jasmine.Runner.prototype.results = function() {
1861
+ return this.queue.results();
1862
+ };
1863
+ /**
1864
+ * Internal representation of a Jasmine specification, or test.
1865
+ *
1866
+ * @constructor
1867
+ * @param {jasmine.Env} env
1868
+ * @param {jasmine.Suite} suite
1869
+ * @param {String} description
1870
+ */
1871
+ jasmine.Spec = function(env, suite, description) {
1872
+ if (!env) {
1873
+ throw new Error('jasmine.Env() required');
1874
+ }
1875
+ if (!suite) {
1876
+ throw new Error('jasmine.Suite() required');
1877
+ }
1878
+ var spec = this;
1879
+ spec.id = env.nextSpecId ? env.nextSpecId() : null;
1880
+ spec.env = env;
1881
+ spec.suite = suite;
1882
+ spec.description = description;
1883
+ spec.queue = new jasmine.Queue(env);
1884
+
1885
+ spec.afterCallbacks = [];
1886
+ spec.spies_ = [];
1887
+
1888
+ spec.results_ = new jasmine.NestedResults();
1889
+ spec.results_.description = description;
1890
+ spec.matchersClass = null;
1891
+ };
1892
+
1893
+ jasmine.Spec.prototype.getFullName = function() {
1894
+ return this.suite.getFullName() + ' ' + this.description + '.';
1895
+ };
1896
+
1897
+
1898
+ jasmine.Spec.prototype.results = function() {
1899
+ return this.results_;
1900
+ };
1901
+
1902
+ /**
1903
+ * All parameters are pretty-printed and concatenated together, then written to the spec's output.
1904
+ *
1905
+ * Be careful not to leave calls to <code>jasmine.log</code> in production code.
1906
+ */
1907
+ jasmine.Spec.prototype.log = function() {
1908
+ return this.results_.log(arguments);
1909
+ };
1910
+
1911
+ jasmine.Spec.prototype.runs = function (func) {
1912
+ var block = new jasmine.Block(this.env, func, this);
1913
+ this.addToQueue(block);
1914
+ return this;
1915
+ };
1916
+
1917
+ jasmine.Spec.prototype.addToQueue = function (block) {
1918
+ if (this.queue.isRunning()) {
1919
+ this.queue.insertNext(block);
1920
+ } else {
1921
+ this.queue.add(block);
1922
+ }
1923
+ };
1924
+
1925
+ /**
1926
+ * @param {jasmine.ExpectationResult} result
1927
+ */
1928
+ jasmine.Spec.prototype.addMatcherResult = function(result) {
1929
+ this.results_.addResult(result);
1930
+ };
1931
+
1932
+ jasmine.Spec.prototype.expect = function(actual) {
1933
+ var positive = new (this.getMatchersClass_())(this.env, actual, this);
1934
+ positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
1935
+ return positive;
1936
+ };
1937
+
1938
+ /**
1939
+ * Waits a fixed time period before moving to the next block.
1940
+ *
1941
+ * @deprecated Use waitsFor() instead
1942
+ * @param {Number} timeout milliseconds to wait
1943
+ */
1944
+ jasmine.Spec.prototype.waits = function(timeout) {
1945
+ var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
1946
+ this.addToQueue(waitsFunc);
1947
+ return this;
1948
+ };
1949
+
1950
+ /**
1951
+ * Waits for the latchFunction to return true before proceeding to the next block.
1952
+ *
1953
+ * @param {Function} latchFunction
1954
+ * @param {String} optional_timeoutMessage
1955
+ * @param {Number} optional_timeout
1956
+ */
1957
+ jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
1958
+ var latchFunction_ = null;
1959
+ var optional_timeoutMessage_ = null;
1960
+ var optional_timeout_ = null;
1961
+
1962
+ for (var i = 0; i < arguments.length; i++) {
1963
+ var arg = arguments[i];
1964
+ switch (typeof arg) {
1965
+ case 'function':
1966
+ latchFunction_ = arg;
1967
+ break;
1968
+ case 'string':
1969
+ optional_timeoutMessage_ = arg;
1970
+ break;
1971
+ case 'number':
1972
+ optional_timeout_ = arg;
1973
+ break;
1974
+ }
1975
+ }
1976
+
1977
+ var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
1978
+ this.addToQueue(waitsForFunc);
1979
+ return this;
1980
+ };
1981
+
1982
+ jasmine.Spec.prototype.fail = function (e) {
1983
+ var expectationResult = new jasmine.ExpectationResult({
1984
+ passed: false,
1985
+ message: e ? jasmine.util.formatException(e) : 'Exception'
1986
+ });
1987
+ this.results_.addResult(expectationResult);
1988
+ };
1989
+
1990
+ jasmine.Spec.prototype.getMatchersClass_ = function() {
1991
+ return this.matchersClass || this.env.matchersClass;
1992
+ };
1993
+
1994
+ jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
1995
+ var parent = this.getMatchersClass_();
1996
+ var newMatchersClass = function() {
1997
+ parent.apply(this, arguments);
1998
+ };
1999
+ jasmine.util.inherit(newMatchersClass, parent);
2000
+ jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
2001
+ this.matchersClass = newMatchersClass;
2002
+ };
2003
+
2004
+ jasmine.Spec.prototype.finishCallback = function() {
2005
+ this.env.reporter.reportSpecResults(this);
2006
+ };
2007
+
2008
+ jasmine.Spec.prototype.finish = function(onComplete) {
2009
+ this.removeAllSpies();
2010
+ this.finishCallback();
2011
+ if (onComplete) {
2012
+ onComplete();
2013
+ }
2014
+ };
2015
+
2016
+ jasmine.Spec.prototype.after = function(doAfter) {
2017
+ if (this.queue.isRunning()) {
2018
+ this.queue.add(new jasmine.Block(this.env, doAfter, this));
2019
+ } else {
2020
+ this.afterCallbacks.unshift(doAfter);
2021
+ }
2022
+ };
2023
+
2024
+ jasmine.Spec.prototype.execute = function(onComplete) {
2025
+ var spec = this;
2026
+ if (!spec.env.specFilter(spec)) {
2027
+ spec.results_.skipped = true;
2028
+ spec.finish(onComplete);
2029
+ return;
2030
+ }
2031
+
2032
+ this.env.reporter.reportSpecStarting(this);
2033
+
2034
+ spec.env.currentSpec = spec;
2035
+
2036
+ spec.addBeforesAndAftersToQueue();
2037
+
2038
+ spec.queue.start(function () {
2039
+ spec.finish(onComplete);
2040
+ });
2041
+ };
2042
+
2043
+ jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
2044
+ var runner = this.env.currentRunner();
2045
+ var i;
2046
+
2047
+ for (var suite = this.suite; suite; suite = suite.parentSuite) {
2048
+ for (i = 0; i < suite.before_.length; i++) {
2049
+ this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
2050
+ }
2051
+ }
2052
+ for (i = 0; i < runner.before_.length; i++) {
2053
+ this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
2054
+ }
2055
+ for (i = 0; i < this.afterCallbacks.length; i++) {
2056
+ this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this));
2057
+ }
2058
+ for (suite = this.suite; suite; suite = suite.parentSuite) {
2059
+ for (i = 0; i < suite.after_.length; i++) {
2060
+ this.queue.add(new jasmine.Block(this.env, suite.after_[i], this));
2061
+ }
2062
+ }
2063
+ for (i = 0; i < runner.after_.length; i++) {
2064
+ this.queue.add(new jasmine.Block(this.env, runner.after_[i], this));
2065
+ }
2066
+ };
2067
+
2068
+ jasmine.Spec.prototype.explodes = function() {
2069
+ throw 'explodes function should not have been called';
2070
+ };
2071
+
2072
+ jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
2073
+ if (obj == jasmine.undefined) {
2074
+ throw "spyOn could not find an object to spy upon for " + methodName + "()";
2075
+ }
2076
+
2077
+ if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
2078
+ throw methodName + '() method does not exist';
2079
+ }
2080
+
2081
+ if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
2082
+ throw new Error(methodName + ' has already been spied upon');
2083
+ }
2084
+
2085
+ var spyObj = jasmine.createSpy(methodName);
2086
+
2087
+ this.spies_.push(spyObj);
2088
+ spyObj.baseObj = obj;
2089
+ spyObj.methodName = methodName;
2090
+ spyObj.originalValue = obj[methodName];
2091
+
2092
+ obj[methodName] = spyObj;
2093
+
2094
+ return spyObj;
2095
+ };
2096
+
2097
+ jasmine.Spec.prototype.removeAllSpies = function() {
2098
+ for (var i = 0; i < this.spies_.length; i++) {
2099
+ var spy = this.spies_[i];
2100
+ spy.baseObj[spy.methodName] = spy.originalValue;
2101
+ }
2102
+ this.spies_ = [];
2103
+ };
2104
+
2105
+ /**
2106
+ * Internal representation of a Jasmine suite.
2107
+ *
2108
+ * @constructor
2109
+ * @param {jasmine.Env} env
2110
+ * @param {String} description
2111
+ * @param {Function} specDefinitions
2112
+ * @param {jasmine.Suite} parentSuite
2113
+ */
2114
+ jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
2115
+ var self = this;
2116
+ self.id = env.nextSuiteId ? env.nextSuiteId() : null;
2117
+ self.description = description;
2118
+ self.queue = new jasmine.Queue(env);
2119
+ self.parentSuite = parentSuite;
2120
+ self.env = env;
2121
+ self.before_ = [];
2122
+ self.after_ = [];
2123
+ self.children_ = [];
2124
+ self.suites_ = [];
2125
+ self.specs_ = [];
2126
+ };
2127
+
2128
+ jasmine.Suite.prototype.getFullName = function() {
2129
+ var fullName = this.description;
2130
+ for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
2131
+ fullName = parentSuite.description + ' ' + fullName;
2132
+ }
2133
+ return fullName;
2134
+ };
2135
+
2136
+ jasmine.Suite.prototype.finish = function(onComplete) {
2137
+ this.env.reporter.reportSuiteResults(this);
2138
+ this.finished = true;
2139
+ if (typeof(onComplete) == 'function') {
2140
+ onComplete();
2141
+ }
2142
+ };
2143
+
2144
+ jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
2145
+ beforeEachFunction.typeName = 'beforeEach';
2146
+ this.before_.unshift(beforeEachFunction);
2147
+ };
2148
+
2149
+ jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
2150
+ afterEachFunction.typeName = 'afterEach';
2151
+ this.after_.unshift(afterEachFunction);
2152
+ };
2153
+
2154
+ jasmine.Suite.prototype.results = function() {
2155
+ return this.queue.results();
2156
+ };
2157
+
2158
+ jasmine.Suite.prototype.add = function(suiteOrSpec) {
2159
+ this.children_.push(suiteOrSpec);
2160
+ if (suiteOrSpec instanceof jasmine.Suite) {
2161
+ this.suites_.push(suiteOrSpec);
2162
+ this.env.currentRunner().addSuite(suiteOrSpec);
2163
+ } else {
2164
+ this.specs_.push(suiteOrSpec);
2165
+ }
2166
+ this.queue.add(suiteOrSpec);
2167
+ };
2168
+
2169
+ jasmine.Suite.prototype.specs = function() {
2170
+ return this.specs_;
2171
+ };
2172
+
2173
+ jasmine.Suite.prototype.suites = function() {
2174
+ return this.suites_;
2175
+ };
2176
+
2177
+ jasmine.Suite.prototype.children = function() {
2178
+ return this.children_;
2179
+ };
2180
+
2181
+ jasmine.Suite.prototype.execute = function(onComplete) {
2182
+ var self = this;
2183
+ this.queue.start(function () {
2184
+ self.finish(onComplete);
2185
+ });
2186
+ };
2187
+ jasmine.WaitsBlock = function(env, timeout, spec) {
2188
+ this.timeout = timeout;
2189
+ jasmine.Block.call(this, env, null, spec);
2190
+ };
2191
+
2192
+ jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
2193
+
2194
+ jasmine.WaitsBlock.prototype.execute = function (onComplete) {
2195
+ if (jasmine.VERBOSE) {
2196
+ this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
2197
+ }
2198
+ this.env.setTimeout(function () {
2199
+ onComplete();
2200
+ }, this.timeout);
2201
+ };
2202
+ /**
2203
+ * A block which waits for some condition to become true, with timeout.
2204
+ *
2205
+ * @constructor
2206
+ * @extends jasmine.Block
2207
+ * @param {jasmine.Env} env The Jasmine environment.
2208
+ * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
2209
+ * @param {Function} latchFunction A function which returns true when the desired condition has been met.
2210
+ * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
2211
+ * @param {jasmine.Spec} spec The Jasmine spec.
2212
+ */
2213
+ jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
2214
+ this.timeout = timeout || env.defaultTimeoutInterval;
2215
+ this.latchFunction = latchFunction;
2216
+ this.message = message;
2217
+ this.totalTimeSpentWaitingForLatch = 0;
2218
+ jasmine.Block.call(this, env, null, spec);
2219
+ };
2220
+ jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
2221
+
2222
+ jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
2223
+
2224
+ jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
2225
+ if (jasmine.VERBOSE) {
2226
+ this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
2227
+ }
2228
+ var latchFunctionResult;
2229
+ try {
2230
+ latchFunctionResult = this.latchFunction.apply(this.spec);
2231
+ } catch (e) {
2232
+ this.spec.fail(e);
2233
+ onComplete();
2234
+ return;
2235
+ }
2236
+
2237
+ if (latchFunctionResult) {
2238
+ onComplete();
2239
+ } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
2240
+ var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
2241
+ this.spec.fail({
2242
+ name: 'timeout',
2243
+ message: message
2244
+ });
2245
+
2246
+ this.abort = true;
2247
+ onComplete();
2248
+ } else {
2249
+ this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
2250
+ var self = this;
2251
+ this.env.setTimeout(function() {
2252
+ self.execute(onComplete);
2253
+ }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
2254
+ }
2255
+ };
2256
+ // Mock setTimeout, clearTimeout
2257
+ // Contributed by Pivotal Computer Systems, www.pivotalsf.com
2258
+
2259
+ jasmine.FakeTimer = function() {
2260
+ this.reset();
2261
+
2262
+ var self = this;
2263
+ self.setTimeout = function(funcToCall, millis) {
2264
+ self.timeoutsMade++;
2265
+ self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
2266
+ return self.timeoutsMade;
2267
+ };
2268
+
2269
+ self.setInterval = function(funcToCall, millis) {
2270
+ self.timeoutsMade++;
2271
+ self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
2272
+ return self.timeoutsMade;
2273
+ };
2274
+
2275
+ self.clearTimeout = function(timeoutKey) {
2276
+ self.scheduledFunctions[timeoutKey] = jasmine.undefined;
2277
+ };
2278
+
2279
+ self.clearInterval = function(timeoutKey) {
2280
+ self.scheduledFunctions[timeoutKey] = jasmine.undefined;
2281
+ };
2282
+
2283
+ };
2284
+
2285
+ jasmine.FakeTimer.prototype.reset = function() {
2286
+ this.timeoutsMade = 0;
2287
+ this.scheduledFunctions = {};
2288
+ this.nowMillis = 0;
2289
+ };
2290
+
2291
+ jasmine.FakeTimer.prototype.tick = function(millis) {
2292
+ var oldMillis = this.nowMillis;
2293
+ var newMillis = oldMillis + millis;
2294
+ this.runFunctionsWithinRange(oldMillis, newMillis);
2295
+ this.nowMillis = newMillis;
2296
+ };
2297
+
2298
+ jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
2299
+ var scheduledFunc;
2300
+ var funcsToRun = [];
2301
+ for (var timeoutKey in this.scheduledFunctions) {
2302
+ scheduledFunc = this.scheduledFunctions[timeoutKey];
2303
+ if (scheduledFunc != jasmine.undefined &&
2304
+ scheduledFunc.runAtMillis >= oldMillis &&
2305
+ scheduledFunc.runAtMillis <= nowMillis) {
2306
+ funcsToRun.push(scheduledFunc);
2307
+ this.scheduledFunctions[timeoutKey] = jasmine.undefined;
2308
+ }
2309
+ }
2310
+
2311
+ if (funcsToRun.length > 0) {
2312
+ funcsToRun.sort(function(a, b) {
2313
+ return a.runAtMillis - b.runAtMillis;
2314
+ });
2315
+ for (var i = 0; i < funcsToRun.length; ++i) {
2316
+ try {
2317
+ var funcToRun = funcsToRun[i];
2318
+ this.nowMillis = funcToRun.runAtMillis;
2319
+ funcToRun.funcToCall();
2320
+ if (funcToRun.recurring) {
2321
+ this.scheduleFunction(funcToRun.timeoutKey,
2322
+ funcToRun.funcToCall,
2323
+ funcToRun.millis,
2324
+ true);
2325
+ }
2326
+ } catch(e) {
2327
+ }
2328
+ }
2329
+ this.runFunctionsWithinRange(oldMillis, nowMillis);
2330
+ }
2331
+ };
2332
+
2333
+ jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
2334
+ this.scheduledFunctions[timeoutKey] = {
2335
+ runAtMillis: this.nowMillis + millis,
2336
+ funcToCall: funcToCall,
2337
+ recurring: recurring,
2338
+ timeoutKey: timeoutKey,
2339
+ millis: millis
2340
+ };
2341
+ };
2342
+
2343
+ /**
2344
+ * @namespace
2345
+ */
2346
+ jasmine.Clock = {
2347
+ defaultFakeTimer: new jasmine.FakeTimer(),
2348
+
2349
+ reset: function() {
2350
+ jasmine.Clock.assertInstalled();
2351
+ jasmine.Clock.defaultFakeTimer.reset();
2352
+ },
2353
+
2354
+ tick: function(millis) {
2355
+ jasmine.Clock.assertInstalled();
2356
+ jasmine.Clock.defaultFakeTimer.tick(millis);
2357
+ },
2358
+
2359
+ runFunctionsWithinRange: function(oldMillis, nowMillis) {
2360
+ jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
2361
+ },
2362
+
2363
+ scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
2364
+ jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
2365
+ },
2366
+
2367
+ useMock: function() {
2368
+ if (!jasmine.Clock.isInstalled()) {
2369
+ var spec = jasmine.getEnv().currentSpec;
2370
+ spec.after(jasmine.Clock.uninstallMock);
2371
+
2372
+ jasmine.Clock.installMock();
2373
+ }
2374
+ },
2375
+
2376
+ installMock: function() {
2377
+ jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
2378
+ },
2379
+
2380
+ uninstallMock: function() {
2381
+ jasmine.Clock.assertInstalled();
2382
+ jasmine.Clock.installed = jasmine.Clock.real;
2383
+ },
2384
+
2385
+ real: {
2386
+ setTimeout: jasmine.getGlobal().setTimeout,
2387
+ clearTimeout: jasmine.getGlobal().clearTimeout,
2388
+ setInterval: jasmine.getGlobal().setInterval,
2389
+ clearInterval: jasmine.getGlobal().clearInterval
2390
+ },
2391
+
2392
+ assertInstalled: function() {
2393
+ if (!jasmine.Clock.isInstalled()) {
2394
+ throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
2395
+ }
2396
+ },
2397
+
2398
+ isInstalled: function() {
2399
+ return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
2400
+ },
2401
+
2402
+ installed: null
2403
+ };
2404
+ jasmine.Clock.installed = jasmine.Clock.real;
2405
+
2406
+ //else for IE support
2407
+ jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
2408
+ if (jasmine.Clock.installed.setTimeout.apply) {
2409
+ return jasmine.Clock.installed.setTimeout.apply(this, arguments);
2410
+ } else {
2411
+ return jasmine.Clock.installed.setTimeout(funcToCall, millis);
2412
+ }
2413
+ };
2414
+
2415
+ jasmine.getGlobal().setInterval = function(funcToCall, millis) {
2416
+ if (jasmine.Clock.installed.setInterval.apply) {
2417
+ return jasmine.Clock.installed.setInterval.apply(this, arguments);
2418
+ } else {
2419
+ return jasmine.Clock.installed.setInterval(funcToCall, millis);
2420
+ }
2421
+ };
2422
+
2423
+ jasmine.getGlobal().clearTimeout = function(timeoutKey) {
2424
+ if (jasmine.Clock.installed.clearTimeout.apply) {
2425
+ return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
2426
+ } else {
2427
+ return jasmine.Clock.installed.clearTimeout(timeoutKey);
2428
+ }
2429
+ };
2430
+
2431
+ jasmine.getGlobal().clearInterval = function(timeoutKey) {
2432
+ if (jasmine.Clock.installed.clearTimeout.apply) {
2433
+ return jasmine.Clock.installed.clearInterval.apply(this, arguments);
2434
+ } else {
2435
+ return jasmine.Clock.installed.clearInterval(timeoutKey);
2436
+ }
2437
+ };
2438
+
2439
+
2440
+ jasmine.version_= {
2441
+ "major": 1,
2442
+ "minor": 1,
2443
+ "build": 0,
2444
+ "revision": 1304737707
2445
+ };