gaffo-jasmine_webos 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2034 @@
1
+ /**
2
+ * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
3
+ *
4
+ * @namespace
5
+ */
6
+ var jasmine = {};
7
+
8
+ /**
9
+ * @private
10
+ */
11
+ jasmine.unimplementedMethod_ = function() {
12
+ throw new Error("unimplemented method");
13
+ };
14
+
15
+ /**
16
+ * Allows for bound functions to be comapred. Internal use only.
17
+ *
18
+ * @ignore
19
+ * @private
20
+ * @param base {Object} bound 'this' for the function
21
+ * @param name {Function} function to find
22
+ */
23
+ jasmine.bindOriginal_ = function(base, name) {
24
+ var original = base[name];
25
+ return function() {
26
+ return original.apply(base, arguments);
27
+ };
28
+ };
29
+
30
+ jasmine.setTimeout = jasmine.bindOriginal_(window, 'setTimeout');
31
+ jasmine.clearTimeout = jasmine.bindOriginal_(window, 'clearTimeout');
32
+ jasmine.setInterval = jasmine.bindOriginal_(window, 'setInterval');
33
+ jasmine.clearInterval = jasmine.bindOriginal_(window, 'clearInterval');
34
+
35
+ jasmine.MessageResult = function(text) {
36
+ this.type = 'MessageResult';
37
+ this.text = text;
38
+ this.trace = new Error(); // todo: test better
39
+ };
40
+
41
+ jasmine.ExpectationResult = function(passed, message, details) {
42
+ this.type = 'ExpectationResult';
43
+ this.passed_ = passed;
44
+ this.message = message;
45
+ this.details = details;
46
+ this.trace = new Error(message); // todo: test better
47
+ };
48
+
49
+ jasmine.ExpectationResult.prototype.passed = function () {
50
+ return this.passed_;
51
+ };
52
+
53
+ /**
54
+ * Getter for the Jasmine environment. Ensures one gets created
55
+ */
56
+ jasmine.getEnv = function() {
57
+ return jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
58
+ };
59
+
60
+ /**
61
+ * @ignore
62
+ * @private
63
+ * @param value
64
+ * @returns {Boolean}
65
+ */
66
+ jasmine.isArray_ = function(value) {
67
+ return value &&
68
+ typeof value === 'object' &&
69
+ typeof value.length === 'number' &&
70
+ typeof value.splice === 'function' &&
71
+ !(value.propertyIsEnumerable('length'));
72
+ };
73
+
74
+ /**
75
+ * Pretty printer for expecations. Takes any object and turns it into a human-readable string.
76
+ *
77
+ * @param value {Object} an object to be outputted
78
+ * @returns {String}
79
+ */
80
+ jasmine.pp = function(value) {
81
+ var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
82
+ stringPrettyPrinter.format(value);
83
+ return stringPrettyPrinter.string;
84
+ };
85
+
86
+ /**
87
+ * Returns true if the object is a DOM Node.
88
+ *
89
+ * @param {Object} obj object to check
90
+ * @returns {Boolean}
91
+ */
92
+ jasmine.isDomNode = function(obj) {
93
+ return obj['nodeType'] > 0;
94
+ };
95
+
96
+ /**
97
+ * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter.
98
+ *
99
+ * @example
100
+ * // don't care about which function is passed in, as long as it's a function
101
+ * expect(mySpy).wasCalledWith(jasmine.any(Function));
102
+ *
103
+ * @param {Class} clazz
104
+ * @returns matchable object of the type clazz
105
+ */
106
+ jasmine.any = function(clazz) {
107
+ return new jasmine.Matchers.Any(clazz);
108
+ };
109
+
110
+ /**
111
+ * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
112
+ *
113
+ * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine
114
+ * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
115
+ *
116
+ * A Spy has the following mehtod: wasCalled, callCount, mostRecentCall, and argsForCall (see docs)
117
+ * Spies are torn down at the end of every spec.
118
+ *
119
+ * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
120
+ *
121
+ * @example
122
+ * // a stub
123
+ * var myStub = jasmine.createSpy('myStub'); // can be used anywhere
124
+ *
125
+ * // spy example
126
+ * var foo = {
127
+ * not: function(bool) { return !bool; }
128
+ * }
129
+ *
130
+ * // actual foo.not will not be called, execution stops
131
+ * spyOn(foo, 'not');
132
+
133
+ // foo.not spied upon, execution will continue to implementation
134
+ * spyOn(foo, 'not').andCallThrough();
135
+ *
136
+ * // fake example
137
+ * var foo = {
138
+ * not: function(bool) { return !bool; }
139
+ * }
140
+ *
141
+ * // foo.not(val) will return val
142
+ * spyOn(foo, 'not').andCallFake(function(value) {return value;});
143
+ *
144
+ * // mock example
145
+ * foo.not(7 == 7);
146
+ * expect(foo.not).wasCalled();
147
+ * expect(foo.not).wasCalledWith(true);
148
+ *
149
+ * @constructor
150
+ * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
151
+ * @param {String} name
152
+ */
153
+ jasmine.Spy = function(name) {
154
+ /**
155
+ * The name of the spy, if provided.
156
+ */
157
+ this.identity = name || 'unknown';
158
+ /**
159
+ * Is this Object a spy?
160
+ */
161
+ this.isSpy = true;
162
+ /**
163
+ * The acutal function this spy stubs.
164
+ */
165
+ this.plan = function() {};
166
+ /**
167
+ * Tracking of the most recent call to the spy.
168
+ * @example
169
+ * var mySpy = jasmine.createSpy('foo');
170
+ * mySpy(1, 2);
171
+ * mySpy.mostRecentCall.args = [1, 2];
172
+ */
173
+ this.mostRecentCall = {};
174
+
175
+ /**
176
+ * Holds arguments for each call to the spy, indexed by call count
177
+ * @example
178
+ * var mySpy = jasmine.createSpy('foo');
179
+ * mySpy(1, 2);
180
+ * mySpy(7, 8);
181
+ * mySpy.mostRecentCall.args = [7, 8];
182
+ * mySpy.argsForCall[0] = [1, 2];
183
+ * mySpy.argsForCall[1] = [7, 8];
184
+ */
185
+ this.argsForCall = [];
186
+ };
187
+
188
+ /**
189
+ * Tells a spy to call through to the actual implemenatation.
190
+ *
191
+ * @example
192
+ * var foo = {
193
+ * bar: function() { // do some stuff }
194
+ * }
195
+ *
196
+ * // defining a spy on an existing property: foo.bar
197
+ * spyOn(foo, 'bar').andCallThrough();
198
+ */
199
+ jasmine.Spy.prototype.andCallThrough = function() {
200
+ this.plan = this.originalValue;
201
+ return this;
202
+ };
203
+
204
+ /**
205
+ * For setting the return value of a spy.
206
+ *
207
+ * @example
208
+ * // defining a spy from scratch: foo() returns 'baz'
209
+ * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
210
+ *
211
+ * // defining a spy on an existing property: foo.bar() returns 'baz'
212
+ * spyOn(foo, 'bar').andReturn('baz');
213
+ *
214
+ * @param {Object} value
215
+ */
216
+ jasmine.Spy.prototype.andReturn = function(value) {
217
+ this.plan = function() {
218
+ return value;
219
+ };
220
+ return this;
221
+ };
222
+
223
+ /**
224
+ * For throwing an exception when a spy is called.
225
+ *
226
+ * @example
227
+ * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
228
+ * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
229
+ *
230
+ * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
231
+ * spyOn(foo, 'bar').andThrow('baz');
232
+ *
233
+ * @param {String} exceptionMsg
234
+ */
235
+ jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
236
+ this.plan = function() {
237
+ throw exceptionMsg;
238
+ };
239
+ return this;
240
+ };
241
+
242
+ /**
243
+ * Calls an alternate implementation when a spy is called.
244
+ *
245
+ * @example
246
+ * var baz = function() {
247
+ * // do some stuff, return something
248
+ * }
249
+ * // defining a spy from scratch: foo() calls the function baz
250
+ * var foo = jasmine.createSpy('spy on foo').andCall(baz);
251
+ *
252
+ * // defining a spy on an existing property: foo.bar() calls an anonymnous function
253
+ * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
254
+ *
255
+ * @param {Function} fakeFunc
256
+ */
257
+ jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
258
+ this.plan = fakeFunc;
259
+ return this;
260
+ };
261
+
262
+ /**
263
+ * Resets all of a spy's the tracking variables so that it can be used again.
264
+ *
265
+ * @example
266
+ * spyOn(foo, 'bar');
267
+ *
268
+ * foo.bar();
269
+ *
270
+ * expect(foo.bar.callCount).toEqual(1);
271
+ *
272
+ * foo.bar.reset();
273
+ *
274
+ * expect(foo.bar.callCount).toEqual(0);
275
+ */
276
+ jasmine.Spy.prototype.reset = function() {
277
+ this.wasCalled = false;
278
+ this.callCount = 0;
279
+ this.argsForCall = [];
280
+ this.mostRecentCall = {};
281
+ };
282
+
283
+ jasmine.createSpy = function(name) {
284
+
285
+ var spyObj = function() {
286
+ spyObj.wasCalled = true;
287
+ spyObj.callCount++;
288
+ var args = jasmine.util.argsToArray(arguments);
289
+ //spyObj.mostRecentCall = {
290
+ // object: this,
291
+ // args: args
292
+ //};
293
+ spyObj.mostRecentCall.object = this;
294
+ spyObj.mostRecentCall.args = args;
295
+ spyObj.argsForCall.push(args);
296
+ return spyObj.plan.apply(this, arguments);
297
+ };
298
+
299
+ var spy = new jasmine.Spy(name);
300
+
301
+ for(var prop in spy) {
302
+ spyObj[prop] = spy[prop];
303
+ }
304
+
305
+ spyObj.reset();
306
+
307
+ return spyObj;
308
+ };
309
+
310
+ /**
311
+ * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something
312
+ * large in one call.
313
+ *
314
+ * @param {String} baseName name of spy class
315
+ * @param {Array} methodNames array of names of methods to make spies
316
+ */
317
+ jasmine.createSpyObj = function(baseName, methodNames) {
318
+ var obj = {};
319
+ for (var i = 0; i < methodNames.length; i++) {
320
+ obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
321
+ }
322
+ return obj;
323
+ };
324
+
325
+ jasmine.log = function(message) {
326
+ jasmine.getEnv().currentSpec.getResults().log(message);
327
+ };
328
+
329
+ /**
330
+ * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.
331
+ *
332
+ * @example
333
+ * // spy example
334
+ * var foo = {
335
+ * not: function(bool) { return !bool; }
336
+ * }
337
+ * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
338
+ *
339
+ * @see jasmine.createSpy
340
+ * @param obj
341
+ * @param methodName
342
+ * @returns a Jasmine spy that can be chained with all spy methods
343
+ */
344
+ var spyOn = function(obj, methodName) {
345
+ return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
346
+ };
347
+
348
+ /**
349
+ * Creates a Jasmine spec that will be added to the current suite.
350
+ *
351
+ * // TODO: pending tests
352
+ *
353
+ * @example
354
+ * it('should be true', function() {
355
+ * expect(true).toEqual(true);
356
+ * });
357
+ *
358
+ * @param {String} desc description of this specification
359
+ * @param {Function} func defines the preconditions and expectations of the spec
360
+ */
361
+ var it = function(desc, func) {
362
+ return jasmine.getEnv().it(desc, func);
363
+ };
364
+
365
+ /**
366
+ * Creates a <em>disabled</em> Jasmine spec.
367
+ *
368
+ * A convenience method that allows existing specs to be disabled temporarily during development.
369
+ *
370
+ * @param {String} desc description of this specification
371
+ * @param {Function} func defines the preconditions and expectations of the spec
372
+ */
373
+ var xit = function(desc, func) {
374
+ return jasmine.getEnv().xit(desc, func);
375
+ };
376
+
377
+ /**
378
+ * Starts a chain for a Jasmine expectation.
379
+ *
380
+ * It is passed an Object that is the actual value and should chain to one of the many
381
+ * jasmine.Matchers functions.
382
+ *
383
+ * @param {Object} actual Actual value to test against and expected value
384
+ */
385
+ var expect = function(actual) {
386
+ return jasmine.getEnv().currentSpec.expect(actual);
387
+ };
388
+
389
+ /**
390
+ * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
391
+ *
392
+ * @param {Function} func Function that defines part of a jasmine spec.
393
+ */
394
+ var runs = function(func) {
395
+ jasmine.getEnv().currentSpec.runs(func);
396
+ };
397
+
398
+ /**
399
+ * Waits for a timeout before moving to the next runs()-defined block.
400
+ * @param {Number} timeout
401
+ */
402
+ var waits = function(timeout) {
403
+ jasmine.getEnv().currentSpec.waits(timeout);
404
+ };
405
+
406
+ /**
407
+ * Waits for the latchFunction to return true before proceeding to the next runs()-defined block.
408
+ *
409
+ * @param {Number} timeout
410
+ * @param {Function} latchFunction
411
+ * @param {String} message
412
+ */
413
+ var waitsFor = function(timeout, latchFunction, message) {
414
+ jasmine.getEnv().currentSpec.waitsFor(timeout, latchFunction, message);
415
+ };
416
+
417
+ /**
418
+ * A function that is called before each spec in a suite.
419
+ *
420
+ * Used for spec setup, including validating assumptions.
421
+ *
422
+ * @param {Function} beforeEachFunction
423
+ */
424
+ var beforeEach = function(beforeEachFunction) {
425
+ jasmine.getEnv().beforeEach(beforeEachFunction);
426
+ };
427
+
428
+ /**
429
+ * A function that is called after each spec in a suite.
430
+ *
431
+ * Used for restoring any state that is hijacked during spec execution.
432
+ *
433
+ * @param {Function} afterEachFunction
434
+ */
435
+ var afterEach = function(afterEachFunction) {
436
+ jasmine.getEnv().afterEach(afterEachFunction);
437
+ };
438
+
439
+ /**
440
+ * Defines a suite of specifications.
441
+ *
442
+ * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
443
+ * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
444
+ * of setup in some tests.
445
+ *
446
+ * @example
447
+ * // TODO: a simple suite
448
+ *
449
+ * // TODO: a simple suite with a nested describe block
450
+ *
451
+ * @param {String} description A string, usually the class under test.
452
+ * @param {Function} specDefinitions function that defines several specs.
453
+ */
454
+ var describe = function(description, specDefinitions) {
455
+ return jasmine.getEnv().describe(description, specDefinitions);
456
+ };
457
+
458
+ /**
459
+ * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
460
+ *
461
+ * @param {String} description A string, usually the class under test.
462
+ * @param {Function} specDefinitions function that defines several specs.
463
+ */
464
+ var xdescribe = function(description, specDefinitions) {
465
+ return jasmine.getEnv().xdescribe(description, specDefinitions);
466
+ };
467
+
468
+
469
+ jasmine.XmlHttpRequest = XMLHttpRequest;
470
+
471
+ // Provide the XMLHttpRequest class for IE 5.x-6.x:
472
+ if (typeof XMLHttpRequest == "undefined") jasmine.XmlHttpRequest = function() {
473
+ try {
474
+ return new ActiveXObject("Msxml2.XMLHTTP.6.0");
475
+ } catch(e) {
476
+ }
477
+ try {
478
+ return new ActiveXObject("Msxml2.XMLHTTP.3.0");
479
+ } catch(e) {
480
+ }
481
+ try {
482
+ return new ActiveXObject("Msxml2.XMLHTTP");
483
+ } catch(e) {
484
+ }
485
+ try {
486
+ return new ActiveXObject("Microsoft.XMLHTTP");
487
+ } catch(e) {
488
+ }
489
+ throw new Error("This browser does not support XMLHttpRequest.");
490
+ };
491
+
492
+ /**
493
+ * Adds suite files to an HTML document so that they are executed, thus adding them to the current
494
+ * Jasmine environment.
495
+ *
496
+ * @param {String} url path to the file to include
497
+ * @param {Boolean} opt_global
498
+ */
499
+ jasmine.include = function(url, opt_global) {
500
+ if (opt_global) {
501
+ document.write('<script type="text/javascript" src="' + url + '"></' + 'script>');
502
+ } else {
503
+ var xhr;
504
+ try {
505
+ xhr = new jasmine.XmlHttpRequest();
506
+ xhr.open("GET", url, false);
507
+ xhr.send(null);
508
+ } catch(e) {
509
+ throw new Error("couldn't fetch " + url + ": " + e);
510
+ }
511
+
512
+ return eval(xhr.responseText);
513
+ }
514
+ };
515
+
516
+ jasmine.version_= {
517
+ "major": 0,
518
+ "minor": 9,
519
+ "build": 0,
520
+ "revision": 1252545255
521
+ };
522
+ /**
523
+ * @namespace
524
+ */
525
+ jasmine.util = {};
526
+
527
+ /**
528
+ * Declare that a child class inherite it's prototype from the parent class.
529
+ *
530
+ * @private
531
+ * @param {Function} childClass
532
+ * @param {Function} parentClass
533
+ */
534
+ jasmine.util.inherit = function(childClass, parentClass) {
535
+ var subclass = function() {
536
+ };
537
+ subclass.prototype = parentClass.prototype;
538
+ childClass.prototype = new subclass;
539
+ };
540
+
541
+ jasmine.util.formatException = function(e) {
542
+ var lineNumber;
543
+ if (e.line) {
544
+ lineNumber = e.line;
545
+ }
546
+ else if (e.lineNumber) {
547
+ lineNumber = e.lineNumber;
548
+ }
549
+
550
+ var file;
551
+
552
+ if (e.sourceURL) {
553
+ file = e.sourceURL;
554
+ }
555
+ else if (e.fileName) {
556
+ file = e.fileName;
557
+ }
558
+
559
+ var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
560
+
561
+ if (file && lineNumber) {
562
+ message += ' in ' + file + ' (line ' + lineNumber + ')';
563
+ }
564
+
565
+ return message;
566
+ };
567
+
568
+ jasmine.util.htmlEscape = function(str) {
569
+ if (!str) return str;
570
+ return str.replace(/&/g, '&amp;')
571
+ .replace(/</g, '&lt;')
572
+ .replace(/>/g, '&gt;');
573
+ };
574
+
575
+ jasmine.util.argsToArray = function(args) {
576
+ var arrayOfArgs = [];
577
+ for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
578
+ return arrayOfArgs;
579
+ };
580
+
581
+ /**
582
+ * Environment for Jasmine
583
+ *
584
+ * @constructor
585
+ */
586
+ jasmine.Env = function() {
587
+ this.currentSpec = null;
588
+ this.currentSuite = null;
589
+ this.currentRunner = new jasmine.Runner(this);
590
+ this.currentlyRunningTests = false;
591
+
592
+ this.reporter = new jasmine.MultiReporter();
593
+
594
+ this.updateInterval = 0;
595
+
596
+ this.updateInterval = 0;
597
+ this.lastUpdate = 0;
598
+ this.specFilter = function() {
599
+ return true;
600
+ };
601
+
602
+ this.nextSpecId_ = 0;
603
+ this.nextSuiteId_ = 0;
604
+ this.equalityTesters_ = [];
605
+ };
606
+
607
+
608
+ jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
609
+ jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
610
+ jasmine.Env.prototype.setInterval = jasmine.setInterval;
611
+ jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
612
+
613
+ jasmine.Env.prototype.version = function () {
614
+ if (jasmine.version_) {
615
+ return jasmine.version_;
616
+ } else {
617
+ throw new Error('Version not set');
618
+ }
619
+ };
620
+
621
+ /**
622
+ * Register a reporter to receive status updates from Jasmine.
623
+ * @param {jasmine.Reporter} reporter An object which will receive status updates.
624
+ */
625
+ jasmine.Env.prototype.addReporter = function(reporter) {
626
+ this.reporter.addReporter(reporter);
627
+ };
628
+
629
+ jasmine.Env.prototype.execute = function() {
630
+ this.currentRunner.execute();
631
+ };
632
+
633
+ jasmine.Env.prototype.describe = function(description, specDefinitions) {
634
+ var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
635
+
636
+ var parentSuite = this.currentSuite;
637
+ if (parentSuite) {
638
+ parentSuite.add(suite);
639
+ } else {
640
+ this.currentRunner.add(suite);
641
+ }
642
+
643
+ this.currentSuite = suite;
644
+
645
+ specDefinitions.call(suite);
646
+
647
+ this.currentSuite = parentSuite;
648
+
649
+ return suite;
650
+ };
651
+
652
+ jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
653
+ this.currentSuite.beforeEach(beforeEachFunction);
654
+ };
655
+
656
+ jasmine.Env.prototype.afterEach = function(afterEachFunction) {
657
+ this.currentSuite.afterEach(afterEachFunction);
658
+ };
659
+
660
+ jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
661
+ return {
662
+ execute: function() {
663
+ }
664
+ };
665
+ };
666
+
667
+ jasmine.Env.prototype.it = function(description, func) {
668
+ var spec = new jasmine.Spec(this, this.currentSuite, description);
669
+ this.currentSuite.add(spec);
670
+ this.currentSpec = spec;
671
+
672
+ if (func) {
673
+ spec.runs(func);
674
+ }
675
+
676
+ return spec;
677
+ };
678
+
679
+ jasmine.Env.prototype.xit = function(desc, func) {
680
+ return {
681
+ id: this.nextSpecId_++,
682
+ runs: function() {
683
+ }
684
+ };
685
+ };
686
+
687
+ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
688
+ if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
689
+ return true;
690
+ }
691
+
692
+ a.__Jasmine_been_here_before__ = b;
693
+ b.__Jasmine_been_here_before__ = a;
694
+
695
+ var hasKey = function(obj, keyName) {
696
+ return obj != null && obj[keyName] !== undefined;
697
+ };
698
+
699
+ for (var property in b) {
700
+ if (!hasKey(a, property) && hasKey(b, property)) {
701
+ mismatchKeys.push("expected has key '" + property + "', but missing from <b>actual</b>.");
702
+ }
703
+ }
704
+ for (property in a) {
705
+ if (!hasKey(b, property) && hasKey(a, property)) {
706
+ mismatchKeys.push("<b>expected</b> missing key '" + property + "', but present in actual.");
707
+ }
708
+ }
709
+ for (property in b) {
710
+ if (property == '__Jasmine_been_here_before__') continue;
711
+ if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
712
+ mismatchValues.push("'" + property + "' was<br /><br />'" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "'<br /><br />in expected, but was<br /><br />'" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "'<br /><br />in actual.<br />");
713
+ }
714
+ }
715
+
716
+ if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
717
+ mismatchValues.push("arrays were not the same length");
718
+ }
719
+
720
+ delete a.__Jasmine_been_here_before__;
721
+ delete b.__Jasmine_been_here_before__;
722
+ return (mismatchKeys.length == 0 && mismatchValues.length == 0);
723
+ };
724
+
725
+ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
726
+ mismatchKeys = mismatchKeys || [];
727
+ mismatchValues = mismatchValues || [];
728
+
729
+ if (a === b) return true;
730
+
731
+ if (a === undefined || a === null || b === undefined || b === null) {
732
+ return (a == undefined && b == undefined);
733
+ }
734
+
735
+ if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
736
+ return a === b;
737
+ }
738
+
739
+ if (a instanceof Date && b instanceof Date) {
740
+ return a.getTime() == b.getTime();
741
+ }
742
+
743
+ if (a instanceof jasmine.Matchers.Any) {
744
+ return a.matches(b);
745
+ }
746
+
747
+ if (b instanceof jasmine.Matchers.Any) {
748
+ return b.matches(a);
749
+ }
750
+
751
+ if (typeof a === "object" && typeof b === "object") {
752
+ return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
753
+ }
754
+
755
+ for (var i = 0; i < this.equalityTesters_.length; i++) {
756
+ var equalityTester = this.equalityTesters_[i];
757
+ var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
758
+ if (result !== undefined) return result;
759
+ }
760
+
761
+ //Straight check
762
+ return (a === b);
763
+ };
764
+
765
+ jasmine.Env.prototype.contains_ = function(haystack, needle) {
766
+ if (jasmine.isArray_(haystack)) {
767
+ for (var i = 0; i < haystack.length; i++) {
768
+ if (this.equals_(haystack[i], needle)) return true;
769
+ }
770
+ return false;
771
+ }
772
+ return haystack.indexOf(needle) >= 0;
773
+ };
774
+
775
+ jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
776
+ this.equalityTesters_.push(equalityTester);
777
+ };
778
+ /** No-op base class for Jasmine reporters.
779
+ *
780
+ * @constructor
781
+ */
782
+ jasmine.Reporter = function() {
783
+ };
784
+
785
+ //noinspection JSUnusedLocalSymbols
786
+ jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
787
+ };
788
+
789
+ //noinspection JSUnusedLocalSymbols
790
+ jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
791
+ };
792
+
793
+ //noinspection JSUnusedLocalSymbols
794
+ jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
795
+ };
796
+
797
+ //noinspection JSUnusedLocalSymbols
798
+ jasmine.Reporter.prototype.reportSpecResults = function(spec) {
799
+ };
800
+
801
+ //noinspection JSUnusedLocalSymbols
802
+ jasmine.Reporter.prototype.log = function(str) {
803
+ };
804
+
805
+ /**
806
+ * Blocks are functions with executable code that make up a spec.
807
+ *
808
+ * @constructor
809
+ * @param {jasmine.Env} env
810
+ * @param {Function} func
811
+ * @param {jasmine.Spec} spec
812
+ */
813
+ jasmine.Block = function(env, func, spec) {
814
+ this.env = env;
815
+ this.func = func;
816
+ this.spec = spec;
817
+ };
818
+
819
+ jasmine.Block.prototype.execute = function(onComplete) {
820
+ try {
821
+ this.func.apply(this.spec);
822
+ } catch (e) {
823
+ this.fail(e);
824
+ }
825
+ onComplete();
826
+ };
827
+
828
+ jasmine.Block.prototype.fail = function(e) {
829
+ this.spec.results.addResult(new jasmine.ExpectationResult(false, jasmine.util.formatException(e), null));
830
+ };
831
+ /** JavaScript API reporter.
832
+ *
833
+ * @constructor
834
+ */
835
+ jasmine.JsApiReporter = function() {
836
+ this.started = false;
837
+ this.finished = false;
838
+ this.suites = [];
839
+ this.results = {};
840
+ };
841
+
842
+ jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
843
+ this.started = true;
844
+ var suites = runner.suites();
845
+ for (var i = 0; i < suites.length; i++) {
846
+ var suite = suites[i];
847
+ this.suites.push(this.summarize_(suite));
848
+ }
849
+ };
850
+
851
+ jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
852
+ var isSuite = suiteOrSpec instanceof jasmine.Suite
853
+ var summary = {
854
+ id: suiteOrSpec.id,
855
+ name: suiteOrSpec.description,
856
+ type: isSuite ? 'suite' : 'spec',
857
+ children: []
858
+ };
859
+ if (isSuite) {
860
+ var specs = suiteOrSpec.specs();
861
+ for (var i = 0; i < specs.length; i++) {
862
+ summary.children.push(this.summarize_(specs[i]));
863
+ }
864
+ }
865
+ return summary;
866
+ };
867
+
868
+ //noinspection JSUnusedLocalSymbols
869
+ jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
870
+ this.finished = true;
871
+ };
872
+
873
+ //noinspection JSUnusedLocalSymbols
874
+ jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
875
+ };
876
+
877
+ //noinspection JSUnusedLocalSymbols
878
+ jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
879
+ this.results[spec.id] = {
880
+ messages: spec.results.getItems(),
881
+ result: spec.results.failedCount > 0 ? "failed" : "passed"
882
+ };
883
+ };
884
+
885
+ //noinspection JSUnusedLocalSymbols
886
+ jasmine.JsApiReporter.prototype.log = function(str) {
887
+ };
888
+
889
+ jasmine.Matchers = function(env, actual, results) {
890
+ this.env = env;
891
+ this.actual = actual;
892
+ this.passing_message = 'Passed.';
893
+ this.results = results || new jasmine.NestedResults();
894
+ };
895
+
896
+ jasmine.Matchers.pp = function(str) {
897
+ return jasmine.util.htmlEscape(jasmine.pp(str));
898
+ };
899
+
900
+ jasmine.Matchers.prototype.getResults = function() {
901
+ return this.results;
902
+ };
903
+
904
+ jasmine.Matchers.prototype.report = function(result, failing_message, details) {
905
+ this.results.addResult(new jasmine.ExpectationResult(result, result ? this.passing_message : failing_message, details));
906
+ return result;
907
+ };
908
+
909
+ /**
910
+ * Matcher that compares the actual to the expected using ===.
911
+ *
912
+ * @param expected
913
+ */
914
+ jasmine.Matchers.prototype.toBe = function(expected) {
915
+ return this.report(this.actual === expected, 'Expected<br /><br />' + jasmine.Matchers.pp(expected)
916
+ + '<br /><br />to be the same object as<br /><br />' + jasmine.Matchers.pp(this.actual)
917
+ + '<br />');
918
+ };
919
+
920
+ /**
921
+ * Matcher that compares the actual to the expected using !==
922
+ * @param expected
923
+ */
924
+ jasmine.Matchers.prototype.toNotBe = function(expected) {
925
+ return this.report(this.actual !== expected, 'Expected<br /><br />' + jasmine.Matchers.pp(expected)
926
+ + '<br /><br />to be a different object from actual, but they were the same.');
927
+ };
928
+
929
+ /**
930
+ * Matcher that compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
931
+ *
932
+ * @param expected
933
+ */
934
+ jasmine.Matchers.prototype.toEqual = function(expected) {
935
+ var mismatchKeys = [];
936
+ var mismatchValues = [];
937
+
938
+ var formatMismatches = function(name, array) {
939
+ if (array.length == 0) return '';
940
+ var errorOutput = '<br /><br />Different ' + name + ':<br />';
941
+ for (var i = 0; i < array.length; i++) {
942
+ errorOutput += array[i] + '<br />';
943
+ }
944
+ return errorOutput;
945
+ };
946
+
947
+ return this.report(this.env.equals_(this.actual, expected, mismatchKeys, mismatchValues),
948
+ 'Expected<br /><br />' + jasmine.Matchers.pp(expected)
949
+ + '<br /><br />but got<br /><br />' + jasmine.Matchers.pp(this.actual)
950
+ + '<br />'
951
+ + formatMismatches('Keys', mismatchKeys)
952
+ + formatMismatches('Values', mismatchValues), {
953
+ matcherName: 'toEqual', expected: expected, actual: this.actual
954
+ });
955
+ };
956
+ /** @deprecated */
957
+ jasmine.Matchers.prototype.should_equal = jasmine.Matchers.prototype.toEqual;
958
+
959
+ /**
960
+ * Matcher that compares the actual to the expected using the ! of jasmine.Matchers.toEqual
961
+ * @param expected
962
+ */
963
+ jasmine.Matchers.prototype.toNotEqual = function(expected) {
964
+ return this.report(!this.env.equals_(this.actual, expected),
965
+ 'Expected ' + jasmine.Matchers.pp(expected) + ' to not equal ' + jasmine.Matchers.pp(this.actual) + ', but it does.');
966
+ };
967
+ /** @deprecated */
968
+ jasmine.Matchers.prototype.should_not_equal = jasmine.Matchers.prototype.toNotEqual;
969
+
970
+ /**
971
+ * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes
972
+ * a pattern or a String.
973
+ *
974
+ * @param reg_exp
975
+ */
976
+ jasmine.Matchers.prototype.toMatch = function(reg_exp) {
977
+ return this.report((new RegExp(reg_exp).test(this.actual)),
978
+ 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to match ' + reg_exp + '.');
979
+ };
980
+ /** @deprecated */
981
+ jasmine.Matchers.prototype.should_match = jasmine.Matchers.prototype.toMatch;
982
+
983
+ /**
984
+ * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
985
+ * @param reg_exp
986
+ */
987
+ jasmine.Matchers.prototype.toNotMatch = function(reg_exp) {
988
+ return this.report((!new RegExp(reg_exp).test(this.actual)),
989
+ 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to not match ' + reg_exp + '.');
990
+ };
991
+ /** @deprecated */
992
+ jasmine.Matchers.prototype.should_not_match = jasmine.Matchers.prototype.toNotMatch;
993
+
994
+ /**
995
+ * Matcher that compares the acutal to undefined.
996
+ */
997
+ jasmine.Matchers.prototype.toBeDefined = function() {
998
+ return this.report((this.actual !== undefined),
999
+ 'Expected a value to be defined but it was undefined.');
1000
+ };
1001
+ /** @deprecated */
1002
+ jasmine.Matchers.prototype.should_be_defined = jasmine.Matchers.prototype.toBeDefined;
1003
+
1004
+ /**
1005
+ * Matcher that compares the actual to null.
1006
+ *
1007
+ */
1008
+ jasmine.Matchers.prototype.toBeNull = function() {
1009
+ return this.report((this.actual === null),
1010
+ 'Expected a value to be null but it was ' + jasmine.Matchers.pp(this.actual) + '.');
1011
+ };
1012
+ /** @deprecated */
1013
+ jasmine.Matchers.prototype.should_be_null = jasmine.Matchers.prototype.toBeNull;
1014
+
1015
+ /**
1016
+ * Matcher that boolean not-nots the actual.
1017
+ */
1018
+ jasmine.Matchers.prototype.toBeTruthy = function() {
1019
+ return this.report(!!this.actual,
1020
+ 'Expected a value to be truthy but it was ' + jasmine.Matchers.pp(this.actual) + '.');
1021
+ };
1022
+ /** @deprecated */
1023
+ jasmine.Matchers.prototype.should_be_truthy = jasmine.Matchers.prototype.toBeTruthy;
1024
+
1025
+ /**
1026
+ * Matcher that boolean nots the actual.
1027
+ */
1028
+ jasmine.Matchers.prototype.toBeFalsy = function() {
1029
+ return this.report(!this.actual,
1030
+ 'Expected a value to be falsy but it was ' + jasmine.Matchers.pp(this.actual) + '.');
1031
+ };
1032
+ /** @deprecated */
1033
+ jasmine.Matchers.prototype.should_be_falsy = jasmine.Matchers.prototype.toBeFalsy;
1034
+
1035
+ /**
1036
+ * Matcher that checks to see if the acutal, a Jasmine spy, was called.
1037
+ */
1038
+ jasmine.Matchers.prototype.wasCalled = function() {
1039
+ if (!this.actual || !this.actual.isSpy) {
1040
+ return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.');
1041
+ }
1042
+ if (arguments.length > 0) {
1043
+ return this.report(false, 'wasCalled matcher does not take arguments');
1044
+ }
1045
+ return this.report((this.actual.wasCalled),
1046
+ 'Expected spy "' + this.actual.identity + '" to have been called, but it was not.');
1047
+ };
1048
+ /** @deprecated */
1049
+ jasmine.Matchers.prototype.was_called = jasmine.Matchers.prototype.wasCalled;
1050
+
1051
+ /**
1052
+ * Matcher that checks to see if the acutal, a Jasmine spy, was not called.
1053
+ */
1054
+ jasmine.Matchers.prototype.wasNotCalled = function() {
1055
+ if (!this.actual || !this.actual.isSpy) {
1056
+ return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.');
1057
+ }
1058
+ return this.report((!this.actual.wasCalled),
1059
+ 'Expected spy "' + this.actual.identity + '" to not have been called, but it was.');
1060
+ };
1061
+ /** @deprecated */
1062
+ jasmine.Matchers.prototype.was_not_called = jasmine.Matchers.prototype.wasNotCalled;
1063
+
1064
+ /**
1065
+ * Matcher that checks to see if the acutal, a Jasmine spy, was called with a set of parameters.
1066
+ *
1067
+ * @example
1068
+ *
1069
+ */
1070
+ jasmine.Matchers.prototype.wasCalledWith = function() {
1071
+ if (!this.actual || !this.actual.isSpy) {
1072
+ return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.', {
1073
+ matcherName: 'wasCalledWith'
1074
+ });
1075
+ }
1076
+
1077
+ var args = jasmine.util.argsToArray(arguments);
1078
+
1079
+ return this.report(this.env.contains_(this.actual.argsForCall, args),
1080
+ 'Expected ' + jasmine.Matchers.pp(this.actual.argsForCall) + ' to contain ' + jasmine.Matchers.pp(args) + ', but it does not.', {
1081
+ matcherName: 'wasCalledWith', expected: args, actual: this.actual.argsForCall
1082
+ });
1083
+ };
1084
+
1085
+ /**
1086
+ * Matcher that checks that the expected item is an element in the actual Array.
1087
+ *
1088
+ * @param {Object} item
1089
+ */
1090
+ jasmine.Matchers.prototype.toContain = function(item) {
1091
+ return this.report(this.env.contains_(this.actual, item),
1092
+ 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to contain ' + jasmine.Matchers.pp(item) + ', but it does not.', {
1093
+ matcherName: 'toContain', expected: item, actual: this.actual
1094
+ });
1095
+ };
1096
+
1097
+ /**
1098
+ * Matcher that checks that the expected item is NOT an element in the actual Array.
1099
+ *
1100
+ * @param {Object} item
1101
+ */
1102
+ jasmine.Matchers.prototype.toNotContain = function(item) {
1103
+ return this.report(!this.env.contains_(this.actual, item),
1104
+ 'Expected ' + jasmine.Matchers.pp(this.actual) + ' not to contain ' + jasmine.Matchers.pp(item) + ', but it does.');
1105
+ };
1106
+
1107
+ jasmine.Matchers.prototype.toBeLessThan = function(expected) {
1108
+ return this.report(this.actual < expected,
1109
+ 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be less than ' + jasmine.Matchers.pp(expected) + ', but it was not.');
1110
+ };
1111
+
1112
+ jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
1113
+ return this.report(this.actual > expected,
1114
+ 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be greater than ' + jasmine.Matchers.pp(expected) + ', but it was not.');
1115
+ };
1116
+
1117
+ /**
1118
+ * Matcher that checks that the expected exception was thrown by the actual.
1119
+ *
1120
+ * @param {String} expectedException
1121
+ */
1122
+ jasmine.Matchers.prototype.toThrow = function(expectedException) {
1123
+ var exception = null;
1124
+ try {
1125
+ this.actual();
1126
+ } catch (e) {
1127
+ exception = e;
1128
+ }
1129
+ if (expectedException !== undefined) {
1130
+ if (exception == null) {
1131
+ return this.report(false, "Expected function to throw " + jasmine.Matchers.pp(expectedException) + ", but it did not.");
1132
+ }
1133
+ return this.report(
1134
+ this.env.equals_(
1135
+ exception.message || exception,
1136
+ expectedException.message || expectedException),
1137
+ "Expected function to throw " + jasmine.Matchers.pp(expectedException) + ", but it threw " + jasmine.Matchers.pp(exception) + ".");
1138
+ } else {
1139
+ return this.report(exception != null, "Expected function to throw an exception, but it did not.");
1140
+ }
1141
+ };
1142
+
1143
+ jasmine.Matchers.Any = function(expectedClass) {
1144
+ this.expectedClass = expectedClass;
1145
+ };
1146
+
1147
+ jasmine.Matchers.Any.prototype.matches = function(other) {
1148
+ if (this.expectedClass == String) {
1149
+ return typeof other == 'string' || other instanceof String;
1150
+ }
1151
+
1152
+ if (this.expectedClass == Number) {
1153
+ return typeof other == 'number' || other instanceof Number;
1154
+ }
1155
+
1156
+ if (this.expectedClass == Function) {
1157
+ return typeof other == 'function' || other instanceof Function;
1158
+ }
1159
+
1160
+ if (this.expectedClass == Object) {
1161
+ return typeof other == 'object';
1162
+ }
1163
+
1164
+ return other instanceof this.expectedClass;
1165
+ };
1166
+
1167
+ jasmine.Matchers.Any.prototype.toString = function() {
1168
+ return '<jasmine.any(' + this.expectedClass + ')>';
1169
+ };
1170
+
1171
+ /**
1172
+ * @constructor
1173
+ */
1174
+ jasmine.MultiReporter = function() {
1175
+ this.subReporters_ = [];
1176
+ };
1177
+ jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
1178
+
1179
+ jasmine.MultiReporter.prototype.addReporter = function(reporter) {
1180
+ this.subReporters_.push(reporter);
1181
+ };
1182
+
1183
+ (function() {
1184
+ var functionNames = ["reportRunnerStarting", "reportRunnerResults", "reportSuiteResults", "reportSpecResults", "log"];
1185
+ for (var i = 0; i < functionNames.length; i++) {
1186
+ var functionName = functionNames[i];
1187
+ jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
1188
+ return function() {
1189
+ for (var j = 0; j < this.subReporters_.length; j++) {
1190
+ var subReporter = this.subReporters_[j];
1191
+ if (subReporter[functionName]) {
1192
+ subReporter[functionName].apply(subReporter, arguments);
1193
+ }
1194
+ }
1195
+ };
1196
+ })(functionName);
1197
+ }
1198
+ })();
1199
+ /**
1200
+ * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
1201
+ *
1202
+ * @constructor
1203
+ */
1204
+ jasmine.NestedResults = function() {
1205
+ /**
1206
+ * The total count of results
1207
+ */
1208
+ this.totalCount = 0;
1209
+ /**
1210
+ * Number of passed results
1211
+ */
1212
+ this.passedCount = 0;
1213
+ /**
1214
+ * Number of failed results
1215
+ */
1216
+ this.failedCount = 0;
1217
+ /**
1218
+ * Was this suite/spec skipped?
1219
+ */
1220
+ this.skipped = false;
1221
+ /**
1222
+ * @ignore
1223
+ */
1224
+ this.items_ = [];
1225
+ };
1226
+
1227
+ /**
1228
+ * Roll up the result counts.
1229
+ *
1230
+ * @param result
1231
+ */
1232
+ jasmine.NestedResults.prototype.rollupCounts = function(result) {
1233
+ this.totalCount += result.totalCount;
1234
+ this.passedCount += result.passedCount;
1235
+ this.failedCount += result.failedCount;
1236
+ };
1237
+
1238
+ /**
1239
+ * Tracks a result's message.
1240
+ * @param message
1241
+ */
1242
+ jasmine.NestedResults.prototype.log = function(message) {
1243
+ this.items_.push(new jasmine.MessageResult(message));
1244
+ };
1245
+
1246
+ /**
1247
+ * Getter for the results: message & results.
1248
+ */
1249
+ jasmine.NestedResults.prototype.getItems = function() {
1250
+ return this.items_;
1251
+ };
1252
+
1253
+ /**
1254
+ * Adds a result, tracking counts (total, passed, & failed)
1255
+ * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
1256
+ */
1257
+ jasmine.NestedResults.prototype.addResult = function(result) {
1258
+ if (result.type != 'MessageResult') {
1259
+ if (result.items_) {
1260
+ this.rollupCounts(result);
1261
+ } else {
1262
+ this.totalCount++;
1263
+ if (result.passed()) {
1264
+ this.passedCount++;
1265
+ } else {
1266
+ this.failedCount++;
1267
+ }
1268
+ }
1269
+ }
1270
+ this.items_.push(result);
1271
+ };
1272
+
1273
+ /**
1274
+ * @returns {Boolean} True if <b>everything</b> below passed
1275
+ */
1276
+ jasmine.NestedResults.prototype.passed = function() {
1277
+ return this.passedCount === this.totalCount;
1278
+ };
1279
+ /**
1280
+ * Base class for pretty printing for expectation results.
1281
+ */
1282
+ jasmine.PrettyPrinter = function() {
1283
+ this.ppNestLevel_ = 0;
1284
+ };
1285
+
1286
+ /**
1287
+ * Formats a value in a nice, human-readable string.
1288
+ *
1289
+ * @param value
1290
+ * @returns {String}
1291
+ */
1292
+ jasmine.PrettyPrinter.prototype.format = function(value) {
1293
+ if (this.ppNestLevel_ > 40) {
1294
+ // return '(jasmine.pp nested too deeply!)';
1295
+ throw new Error('jasmine.PrettyPrinter: format() nested too deeply!');
1296
+ }
1297
+
1298
+ this.ppNestLevel_++;
1299
+ try {
1300
+ if (value === undefined) {
1301
+ this.emitScalar('undefined');
1302
+ } else if (value === null) {
1303
+ this.emitScalar('null');
1304
+ } else if (value.navigator && value.frames && value.setTimeout) {
1305
+ this.emitScalar('<window>');
1306
+ } else if (value instanceof jasmine.Matchers.Any) {
1307
+ this.emitScalar(value.toString());
1308
+ } else if (typeof value === 'string') {
1309
+ this.emitString(value);
1310
+ } else if (typeof value === 'function') {
1311
+ this.emitScalar('Function');
1312
+ } else if (typeof value.nodeType === 'number') {
1313
+ this.emitScalar('HTMLNode');
1314
+ } else if (value instanceof Date) {
1315
+ this.emitScalar('Date(' + value + ')');
1316
+ } else if (value.__Jasmine_been_here_before__) {
1317
+ this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');
1318
+ } else if (jasmine.isArray_(value) || typeof value == 'object') {
1319
+ value.__Jasmine_been_here_before__ = true;
1320
+ if (jasmine.isArray_(value)) {
1321
+ this.emitArray(value);
1322
+ } else {
1323
+ this.emitObject(value);
1324
+ }
1325
+ delete value.__Jasmine_been_here_before__;
1326
+ } else {
1327
+ this.emitScalar(value.toString());
1328
+ }
1329
+ } finally {
1330
+ this.ppNestLevel_--;
1331
+ }
1332
+ };
1333
+
1334
+ jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
1335
+ for (var property in obj) {
1336
+ if (property == '__Jasmine_been_here_before__') continue;
1337
+ fn(property, obj.__lookupGetter__(property) != null);
1338
+ }
1339
+ };
1340
+
1341
+ jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
1342
+ jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
1343
+ jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
1344
+ jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
1345
+
1346
+ jasmine.StringPrettyPrinter = function() {
1347
+ jasmine.PrettyPrinter.call(this);
1348
+
1349
+ this.string = '';
1350
+ };
1351
+ jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
1352
+
1353
+ jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
1354
+ this.append(value);
1355
+ };
1356
+
1357
+ jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
1358
+ this.append("'" + value + "'");
1359
+ };
1360
+
1361
+ jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
1362
+ this.append('[ ');
1363
+ for (var i = 0; i < array.length; i++) {
1364
+ if (i > 0) {
1365
+ this.append(', ');
1366
+ }
1367
+ this.format(array[i]);
1368
+ }
1369
+ this.append(' ]');
1370
+ };
1371
+
1372
+ jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
1373
+ var self = this;
1374
+ this.append('{ ');
1375
+ var first = true;
1376
+
1377
+ this.iterateObject(obj, function(property, isGetter) {
1378
+ if (first) {
1379
+ first = false;
1380
+ } else {
1381
+ self.append(', ');
1382
+ }
1383
+
1384
+ self.append(property);
1385
+ self.append(' : ');
1386
+ if (isGetter) {
1387
+ self.append('<getter>');
1388
+ } else {
1389
+ self.format(obj[property]);
1390
+ }
1391
+ });
1392
+
1393
+ this.append(' }');
1394
+ };
1395
+
1396
+ jasmine.StringPrettyPrinter.prototype.append = function(value) {
1397
+ this.string += value;
1398
+ };
1399
+ jasmine.Queue = function(env) {
1400
+ this.env = env;
1401
+ this.blocks = [];
1402
+ this.running = false;
1403
+ this.index = 0;
1404
+ this.offset = 0;
1405
+ };
1406
+
1407
+ jasmine.Queue.prototype.addBefore = function (block) {
1408
+ this.blocks.unshift(block);
1409
+ };
1410
+
1411
+ jasmine.Queue.prototype.add = function(block) {
1412
+ this.blocks.push(block);
1413
+ };
1414
+
1415
+ jasmine.Queue.prototype.insertNext = function (block) {
1416
+ this.blocks.splice((this.index + this.offset + 1), 0, block);
1417
+ this.offset++;
1418
+ };
1419
+
1420
+ jasmine.Queue.prototype.start = function(onComplete) {
1421
+ var self = this;
1422
+ self.running = true;
1423
+ self.onComplete = onComplete;
1424
+ if (self.blocks[0]) {
1425
+ self.blocks[0].execute(function () {
1426
+ self._next();
1427
+ });
1428
+ } else {
1429
+ self.finish();
1430
+ }
1431
+ };
1432
+
1433
+ jasmine.Queue.prototype.isRunning = function () {
1434
+ return this.running;
1435
+ };
1436
+
1437
+ jasmine.Queue.prototype._next = function () {
1438
+ var self = this;
1439
+ var doNext = function () {
1440
+ self.offset = 0;
1441
+ self.index++;
1442
+ if (self.index < self.blocks.length) {
1443
+ self.blocks[self.index].execute(function () {
1444
+ self._next();
1445
+ });
1446
+ } else {
1447
+ self.finish();
1448
+ }
1449
+ };
1450
+ var now = new Date().getTime();
1451
+ if (this.env.updateInterval && now - this.env.lastUpdate > this.env.updateInterval) {
1452
+ this.env.lastUpdate = now;
1453
+ this.env.setTimeout(doNext, 0);
1454
+ } else {
1455
+ doNext();
1456
+ }
1457
+
1458
+ };
1459
+
1460
+ jasmine.Queue.prototype.finish = function () {
1461
+ this.running = false;
1462
+ if (this.onComplete) {
1463
+ this.onComplete();
1464
+ }
1465
+ };
1466
+
1467
+ jasmine.Queue.prototype.getResults = function () {
1468
+ var results = new jasmine.NestedResults();
1469
+ for (var i = 0; i < this.blocks.length; i++) {
1470
+ if (this.blocks[i].getResults) {
1471
+ results.addResult(this.blocks[i].getResults());
1472
+ }
1473
+ }
1474
+ return results;
1475
+ };
1476
+
1477
+
1478
+ /* JasmineReporters.reporter
1479
+ * Base object that will get called whenever a Spec, Suite, or Runner is done. It is up to
1480
+ * descendants of this object to do something with the results (see json_reporter.js)
1481
+ */
1482
+ jasmine.Reporters = {};
1483
+
1484
+ jasmine.Reporters.reporter = function(callbacks) {
1485
+ var that = {
1486
+ callbacks: callbacks || {},
1487
+
1488
+ doCallback: function(callback, results) {
1489
+ if (callback) {
1490
+ callback(results);
1491
+ }
1492
+ },
1493
+
1494
+ reportRunnerResults: function(runner) {
1495
+ that.doCallback(that.callbacks.runnerCallback, runner);
1496
+ },
1497
+ reportSuiteResults: function(suite) {
1498
+ that.doCallback(that.callbacks.suiteCallback, suite);
1499
+ },
1500
+ reportSpecResults: function(spec) {
1501
+ that.doCallback(that.callbacks.specCallback, spec);
1502
+ },
1503
+ log: function (str) {
1504
+ if (console && console.log) console.log(str);
1505
+ }
1506
+ };
1507
+
1508
+ return that;
1509
+ };
1510
+
1511
+ /**
1512
+ * Runner
1513
+ *
1514
+ * @constructor
1515
+ * @param {jasmine.Env} env
1516
+ */
1517
+ jasmine.Runner = function(env) {
1518
+ var self = this;
1519
+ self.env = env;
1520
+ self.queue = new jasmine.Queue(env);
1521
+ self.suites_ = [];
1522
+ };
1523
+
1524
+ jasmine.Runner.prototype.execute = function() {
1525
+ var self = this;
1526
+ if (self.env.reporter.reportRunnerStarting) {
1527
+ self.env.reporter.reportRunnerStarting(this);
1528
+ }
1529
+ self.queue.start(function () {
1530
+ self.finishCallback();
1531
+ });
1532
+ };
1533
+
1534
+ jasmine.Runner.prototype.finishCallback = function() {
1535
+ this.env.reporter.reportRunnerResults(this);
1536
+ };
1537
+
1538
+ jasmine.Runner.prototype.addSuite = function(suite) {
1539
+ this.suites_.push(suite);
1540
+ };
1541
+
1542
+ jasmine.Runner.prototype.add = function(block) {
1543
+ if (block instanceof jasmine.Suite) {
1544
+ this.addSuite(block);
1545
+ }
1546
+ this.queue.add(block);
1547
+ };
1548
+
1549
+ /** @deprecated */
1550
+ jasmine.Runner.prototype.getAllSuites = function() {
1551
+ return this.suites_;
1552
+ };
1553
+
1554
+
1555
+ jasmine.Runner.prototype.suites = function() {
1556
+ return this.suites_;
1557
+ };
1558
+
1559
+ jasmine.Runner.prototype.getResults = function() {
1560
+ return this.queue.getResults();
1561
+ };
1562
+ /**
1563
+ * Internal representation of a Jasmine specification, or test.
1564
+ *
1565
+ * @constructor
1566
+ * @param {jasmine.Env} env
1567
+ * @param {jasmine.Suite} suite
1568
+ * @param {String} description
1569
+ */
1570
+ jasmine.Spec = function(env, suite, description) {
1571
+ var spec = this;
1572
+ spec.id = env.nextSpecId_++;
1573
+ spec.env = env;
1574
+ spec.suite = suite;
1575
+ spec.description = description;
1576
+ spec.queue = new jasmine.Queue(env);
1577
+
1578
+ spec.afterCallbacks = [];
1579
+ spec.spies_ = [];
1580
+
1581
+ spec.results = new jasmine.NestedResults();
1582
+ spec.results.description = description;
1583
+ spec.matchersClass = null;
1584
+ };
1585
+
1586
+ jasmine.Spec.prototype.getFullName = function() {
1587
+ return this.suite.getFullName() + ' ' + this.description + '.';
1588
+ };
1589
+
1590
+ jasmine.Spec.prototype.getResults = function() {
1591
+ return this.results;
1592
+ };
1593
+
1594
+ jasmine.Spec.prototype.runs = function (func) {
1595
+ var block = new jasmine.Block(this.env, func, this);
1596
+ this.addToQueue(block);
1597
+ return this;
1598
+ };
1599
+
1600
+ jasmine.Spec.prototype.addToQueue = function (block) {
1601
+ if (this.queue.isRunning()) {
1602
+ this.queue.insertNext(block);
1603
+ } else {
1604
+ this.queue.add(block);
1605
+ }
1606
+ };
1607
+
1608
+ /**
1609
+ * @private
1610
+ * @deprecated
1611
+ */
1612
+ jasmine.Spec.prototype.expects_that = function(actual) {
1613
+ return this.expect(actual);
1614
+ };
1615
+
1616
+ /**
1617
+ * @private
1618
+ */
1619
+ jasmine.Spec.prototype.expect = function(actual) {
1620
+ return new (this.getMatchersClass_())(this.env, actual, this.results);
1621
+ };
1622
+
1623
+ jasmine.Spec.prototype.waits = function(timeout) {
1624
+ var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
1625
+ this.addToQueue(waitsFunc);
1626
+ return this;
1627
+ };
1628
+
1629
+ jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessage) {
1630
+ var waitsForFunc = new jasmine.WaitsForBlock(this.env, timeout, latchFunction, timeoutMessage, this);
1631
+ this.addToQueue(waitsForFunc);
1632
+ return this;
1633
+ };
1634
+
1635
+ jasmine.Spec.prototype.failWithException = function (e) {
1636
+ this.results.addResult(new jasmine.ExpectationResult(false, jasmine.util.formatException(e), null));
1637
+ };
1638
+
1639
+ jasmine.Spec.prototype.getMatchersClass_ = function() {
1640
+ return this.matchersClass || jasmine.Matchers;
1641
+ };
1642
+
1643
+ jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
1644
+ var parent = this.getMatchersClass_();
1645
+ var newMatchersClass = function() {
1646
+ parent.apply(this, arguments);
1647
+ };
1648
+ jasmine.util.inherit(newMatchersClass, parent);
1649
+ for (var method in matchersPrototype) {
1650
+ newMatchersClass.prototype[method] = matchersPrototype[method];
1651
+ }
1652
+ this.matchersClass = newMatchersClass;
1653
+ };
1654
+
1655
+ jasmine.Spec.prototype.finishCallback = function() {
1656
+ this.env.reporter.reportSpecResults(this);
1657
+ };
1658
+
1659
+ jasmine.Spec.prototype.finish = function(onComplete) {
1660
+ this.removeAllSpies();
1661
+ this.finishCallback();
1662
+ if (onComplete) {
1663
+ onComplete();
1664
+ }
1665
+ };
1666
+
1667
+ jasmine.Spec.prototype.after = function(doAfter, test) {
1668
+
1669
+ if (this.queue.isRunning()) {
1670
+ this.queue.add(new jasmine.Block(this.env, doAfter, this));
1671
+ } else {
1672
+ this.afterCallbacks.unshift(doAfter);
1673
+ }
1674
+ };
1675
+
1676
+ jasmine.Spec.prototype.execute = function(onComplete) {
1677
+ var spec = this;
1678
+ if (!spec.env.specFilter(spec)) {
1679
+ spec.results.skipped = true;
1680
+ spec.finish(onComplete);
1681
+ return;
1682
+ }
1683
+ this.env.reporter.log('>> Jasmine Running ' + this.suite.description + ' ' + this.description + '...');
1684
+
1685
+ spec.env.currentSpec = spec;
1686
+ spec.env.currentlyRunningTests = true;
1687
+
1688
+ spec.addBeforesAndAftersToQueue();
1689
+
1690
+ spec.queue.start(function () {
1691
+ spec.finish(onComplete);
1692
+ });
1693
+ spec.env.currentlyRunningTests = false;
1694
+ };
1695
+
1696
+ jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
1697
+ for (var suite = this.suite; suite; suite = suite.parentSuite) {
1698
+ if (suite.beforeQueue) {
1699
+ for (var i = 0; i < suite.beforeQueue.length; i++)
1700
+ this.queue.addBefore(new jasmine.Block(this.env, suite.beforeQueue[i], this));
1701
+ }
1702
+ }
1703
+ for (i = 0; i < this.afterCallbacks.length; i++) {
1704
+ this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this));
1705
+ }
1706
+ for (suite = this.suite; suite; suite = suite.parentSuite) {
1707
+ if (suite.afterQueue) {
1708
+ for (var j = 0; j < suite.afterQueue.length; j++)
1709
+ this.queue.add(new jasmine.Block(this.env, suite.afterQueue[j], this));
1710
+ }
1711
+ }
1712
+ };
1713
+
1714
+ jasmine.Spec.prototype.explodes = function() {
1715
+ throw 'explodes function should not have been called';
1716
+ };
1717
+
1718
+ jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
1719
+ if (obj == undefined) {
1720
+ throw "spyOn could not find an object to spy upon for " + methodName + "()";
1721
+ }
1722
+
1723
+ if (!ignoreMethodDoesntExist && obj[methodName] === undefined) {
1724
+ throw methodName + '() method does not exist';
1725
+ }
1726
+
1727
+ if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
1728
+ throw new Error(methodName + ' has already been spied upon');
1729
+ }
1730
+
1731
+ var spyObj = jasmine.createSpy(methodName);
1732
+
1733
+ this.spies_.push(spyObj);
1734
+ spyObj.baseObj = obj;
1735
+ spyObj.methodName = methodName;
1736
+ spyObj.originalValue = obj[methodName];
1737
+
1738
+ obj[methodName] = spyObj;
1739
+
1740
+ return spyObj;
1741
+ };
1742
+
1743
+ jasmine.Spec.prototype.removeAllSpies = function() {
1744
+ for (var i = 0; i < this.spies_.length; i++) {
1745
+ var spy = this.spies_[i];
1746
+ spy.baseObj[spy.methodName] = spy.originalValue;
1747
+ }
1748
+ this.spies_ = [];
1749
+ };
1750
+
1751
+ /**
1752
+ * Internal representation of a Jasmine suite.
1753
+ *
1754
+ * @constructor
1755
+ * @param {jasmine.Env} env
1756
+ * @param {String} description
1757
+ * @param {Function} specDefinitions
1758
+ * @param {jasmine.Suite} parentSuite
1759
+ */
1760
+ jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
1761
+ var self = this;
1762
+ self.id = env.nextSuiteId_++;
1763
+ self.description = description;
1764
+ self.queue = new jasmine.Queue(env);
1765
+ self.parentSuite = parentSuite;
1766
+ self.env = env;
1767
+ self.beforeQueue = [];
1768
+ self.afterQueue = [];
1769
+ self.specs_ = [];
1770
+ };
1771
+
1772
+ jasmine.Suite.prototype.getFullName = function() {
1773
+ var fullName = this.description;
1774
+ for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
1775
+ fullName = parentSuite.description + ' ' + fullName;
1776
+ }
1777
+ return fullName;
1778
+ };
1779
+
1780
+ jasmine.Suite.prototype.finish = function(onComplete) {
1781
+ this.env.reporter.reportSuiteResults(this);
1782
+ this.finished = true;
1783
+ if (typeof(onComplete) == 'function') {
1784
+ onComplete();
1785
+ }
1786
+ };
1787
+
1788
+ jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
1789
+ beforeEachFunction.typeName = 'beforeEach';
1790
+ this.beforeQueue.push(beforeEachFunction);
1791
+ };
1792
+
1793
+ jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
1794
+ afterEachFunction.typeName = 'afterEach';
1795
+ this.afterQueue.push(afterEachFunction);
1796
+ };
1797
+
1798
+ jasmine.Suite.prototype.getResults = function() {
1799
+ return this.queue.getResults();
1800
+ };
1801
+
1802
+ jasmine.Suite.prototype.add = function(block) {
1803
+ if (block instanceof jasmine.Suite) {
1804
+ this.env.currentRunner.addSuite(block);
1805
+ } else {
1806
+ this.specs_.push(block);
1807
+ }
1808
+ this.queue.add(block);
1809
+ };
1810
+
1811
+ /** @deprecated */
1812
+ jasmine.Suite.prototype.specCount = function() {
1813
+ return this.specs_.length;
1814
+ };
1815
+
1816
+ jasmine.Suite.prototype.specs = function() {
1817
+ return this.specs_;
1818
+ };
1819
+
1820
+ jasmine.Suite.prototype.execute = function(onComplete) {
1821
+ var self = this;
1822
+ this.queue.start(function () {
1823
+ self.finish(onComplete);
1824
+ });
1825
+ };
1826
+ jasmine.WaitsBlock = function(env, timeout, spec) {
1827
+ this.timeout = timeout;
1828
+ jasmine.Block.call(this, env, null, spec);
1829
+ };
1830
+
1831
+ jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
1832
+
1833
+ jasmine.WaitsBlock.prototype.execute = function (onComplete) {
1834
+ this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
1835
+ this.env.setTimeout(function () {
1836
+ onComplete();
1837
+ }, this.timeout);
1838
+ };
1839
+ jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
1840
+ this.timeout = timeout;
1841
+ this.latchFunction = latchFunction;
1842
+ this.message = message;
1843
+ this.totalTimeSpentWaitingForLatch = 0;
1844
+ jasmine.Block.call(this, env, null, spec);
1845
+ };
1846
+
1847
+ jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
1848
+
1849
+ jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 100;
1850
+
1851
+ jasmine.WaitsForBlock.prototype.execute = function (onComplete) {
1852
+ var self = this;
1853
+ self.env.reporter.log('>> Jasmine waiting for ' + (self.message || 'something to happen'));
1854
+ var latchFunctionResult;
1855
+ try {
1856
+ latchFunctionResult = self.latchFunction.apply(self.spec);
1857
+ } catch (e) {
1858
+ self.fail(e);
1859
+ onComplete();
1860
+ return;
1861
+ }
1862
+
1863
+ if (latchFunctionResult) {
1864
+ onComplete();
1865
+ } else if (self.totalTimeSpentWaitingForLatch >= self.timeout) {
1866
+ var message = 'timed out after ' + self.timeout + ' msec waiting for ' + (self.message || 'something to happen');
1867
+ self.fail({
1868
+ name: 'timeout',
1869
+ message: message
1870
+ });
1871
+ self.spec._next();
1872
+ } else {
1873
+ self.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
1874
+ self.env.setTimeout(function () { self.execute(onComplete); }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
1875
+ }
1876
+ };
1877
+ // Mock setTimeout, clearTimeout
1878
+ // Contributed by Pivotal Computer Systems, www.pivotalsf.com
1879
+
1880
+ jasmine.FakeTimer = function() {
1881
+ this.reset();
1882
+
1883
+ var self = this;
1884
+ self.setTimeout = function(funcToCall, millis) {
1885
+ self.timeoutsMade++;
1886
+ self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
1887
+ return self.timeoutsMade;
1888
+ };
1889
+
1890
+ self.setInterval = function(funcToCall, millis) {
1891
+ self.timeoutsMade++;
1892
+ self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
1893
+ return self.timeoutsMade;
1894
+ };
1895
+
1896
+ self.clearTimeout = function(timeoutKey) {
1897
+ self.scheduledFunctions[timeoutKey] = undefined;
1898
+ };
1899
+
1900
+ self.clearInterval = function(timeoutKey) {
1901
+ self.scheduledFunctions[timeoutKey] = undefined;
1902
+ };
1903
+
1904
+ };
1905
+
1906
+ jasmine.FakeTimer.prototype.reset = function() {
1907
+ this.timeoutsMade = 0;
1908
+ this.scheduledFunctions = {};
1909
+ this.nowMillis = 0;
1910
+ };
1911
+
1912
+ jasmine.FakeTimer.prototype.tick = function(millis) {
1913
+ var oldMillis = this.nowMillis;
1914
+ var newMillis = oldMillis + millis;
1915
+ this.runFunctionsWithinRange(oldMillis, newMillis);
1916
+ this.nowMillis = newMillis;
1917
+ };
1918
+
1919
+ jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
1920
+ var scheduledFunc;
1921
+ var funcsToRun = [];
1922
+ for (var timeoutKey in this.scheduledFunctions) {
1923
+ scheduledFunc = this.scheduledFunctions[timeoutKey];
1924
+ if (scheduledFunc != undefined &&
1925
+ scheduledFunc.runAtMillis >= oldMillis &&
1926
+ scheduledFunc.runAtMillis <= nowMillis) {
1927
+ funcsToRun.push(scheduledFunc);
1928
+ this.scheduledFunctions[timeoutKey] = undefined;
1929
+ }
1930
+ }
1931
+
1932
+ if (funcsToRun.length > 0) {
1933
+ funcsToRun.sort(function(a, b) {
1934
+ return a.runAtMillis - b.runAtMillis;
1935
+ });
1936
+ for (var i = 0; i < funcsToRun.length; ++i) {
1937
+ try {
1938
+ var funcToRun = funcsToRun[i];
1939
+ this.nowMillis = funcToRun.runAtMillis;
1940
+ funcToRun.funcToCall();
1941
+ if (funcToRun.recurring) {
1942
+ this.scheduleFunction(funcToRun.timeoutKey,
1943
+ funcToRun.funcToCall,
1944
+ funcToRun.millis,
1945
+ true);
1946
+ }
1947
+ } catch(e) {
1948
+ }
1949
+ }
1950
+ this.runFunctionsWithinRange(oldMillis, nowMillis);
1951
+ }
1952
+ };
1953
+
1954
+ jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
1955
+ this.scheduledFunctions[timeoutKey] = {
1956
+ runAtMillis: this.nowMillis + millis,
1957
+ funcToCall: funcToCall,
1958
+ recurring: recurring,
1959
+ timeoutKey: timeoutKey,
1960
+ millis: millis
1961
+ };
1962
+ };
1963
+
1964
+
1965
+ jasmine.Clock = {
1966
+ defaultFakeTimer: new jasmine.FakeTimer(),
1967
+
1968
+ reset: function() {
1969
+ jasmine.Clock.assertInstalled();
1970
+ jasmine.Clock.defaultFakeTimer.reset();
1971
+ },
1972
+
1973
+ tick: function(millis) {
1974
+ jasmine.Clock.assertInstalled();
1975
+ jasmine.Clock.defaultFakeTimer.tick(millis);
1976
+ },
1977
+
1978
+ runFunctionsWithinRange: function(oldMillis, nowMillis) {
1979
+ jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
1980
+ },
1981
+
1982
+ scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
1983
+ jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
1984
+ },
1985
+
1986
+ useMock: function() {
1987
+ var spec = jasmine.getEnv().currentSpec;
1988
+ spec.after(jasmine.Clock.uninstallMock);
1989
+
1990
+ jasmine.Clock.installMock();
1991
+ },
1992
+
1993
+ installMock: function() {
1994
+ jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
1995
+ },
1996
+
1997
+ uninstallMock: function() {
1998
+ jasmine.Clock.assertInstalled();
1999
+ jasmine.Clock.installed = jasmine.Clock.real;
2000
+ },
2001
+
2002
+ real: {
2003
+ setTimeout: window.setTimeout,
2004
+ clearTimeout: window.clearTimeout,
2005
+ setInterval: window.setInterval,
2006
+ clearInterval: window.clearInterval
2007
+ },
2008
+
2009
+ assertInstalled: function() {
2010
+ if (jasmine.Clock.installed != jasmine.Clock.defaultFakeTimer) {
2011
+ throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
2012
+ }
2013
+ },
2014
+
2015
+ installed: null
2016
+ };
2017
+ jasmine.Clock.installed = jasmine.Clock.real;
2018
+
2019
+ window.setTimeout = function(funcToCall, millis) {
2020
+ return jasmine.Clock.installed.setTimeout.apply(this, arguments);
2021
+ };
2022
+
2023
+ window.setInterval = function(funcToCall, millis) {
2024
+ return jasmine.Clock.installed.setInterval.apply(this, arguments);
2025
+ };
2026
+
2027
+ window.clearTimeout = function(timeoutKey) {
2028
+ return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
2029
+ };
2030
+
2031
+ window.clearInterval = function(timeoutKey) {
2032
+ return jasmine.Clock.installed.clearInterval.apply(this, arguments);
2033
+ };
2034
+