smparkes-jazrb 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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
+