evergreen 0.1

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