smparkes-jazrb 0.0.3

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