teaspoon 0.7.9 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +382 -260
  3. data/app/assets/javascripts/teaspoon-angular.js +108 -26241
  4. data/app/assets/javascripts/teaspoon-jasmine.js +103 -2642
  5. data/app/assets/javascripts/teaspoon-mocha.js +109 -5416
  6. data/app/assets/javascripts/teaspoon-qunit.js +107 -2255
  7. data/app/assets/javascripts/teaspoon-teaspoon.js +0 -1
  8. data/app/assets/javascripts/teaspoon/angular.coffee +3 -1
  9. data/app/assets/javascripts/teaspoon/base/hook.coffee +21 -0
  10. data/app/assets/javascripts/teaspoon/base/reporters/html.coffee +26 -14
  11. data/app/assets/javascripts/teaspoon/base/reporters/html/progress_view.coffee +1 -1
  12. data/app/assets/javascripts/teaspoon/base/reporters/html/template.coffee +3 -3
  13. data/app/assets/javascripts/teaspoon/base/teaspoon.coffee +10 -1
  14. data/app/assets/javascripts/teaspoon/jasmine.coffee +3 -1
  15. data/app/assets/javascripts/teaspoon/mocha.coffee +3 -1
  16. data/app/assets/javascripts/teaspoon/mocha/reporters/html.coffee +1 -1
  17. data/app/assets/javascripts/teaspoon/qunit.coffee +3 -1
  18. data/app/assets/javascripts/teaspoon/qunit/reporters/html.coffee +1 -1
  19. data/app/assets/javascripts/teaspoon/teaspoon.coffee +0 -1
  20. data/app/assets/stylesheets/teaspoon.css +12 -8
  21. data/app/controllers/teaspoon/suite_controller.rb +32 -0
  22. data/app/views/teaspoon/suite/_body.html.erb +0 -0
  23. data/app/views/teaspoon/suite/_boot.html.erb +4 -0
  24. data/app/views/teaspoon/suite/_boot_require_js.html.erb +19 -0
  25. data/app/views/teaspoon/{spec/suites.html.erb → suite/index.html.erb} +6 -7
  26. data/app/views/teaspoon/suite/show.html.erb +19 -0
  27. data/bin/teaspoon +1 -1
  28. data/config/routes.rb +14 -4
  29. data/lib/generators/teaspoon/install/POST_INSTALL +2 -2
  30. data/lib/generators/teaspoon/install/install_generator.rb +22 -11
  31. data/lib/generators/teaspoon/install/templates/_body.html.erb +0 -0
  32. data/lib/generators/teaspoon/install/templates/_boot.html.erb +4 -0
  33. data/lib/generators/teaspoon/install/templates/jasmine/env.rb +11 -0
  34. data/lib/generators/teaspoon/install/templates/jasmine/env_comments.rb +182 -0
  35. data/lib/generators/teaspoon/install/templates/jasmine/spec_helper.coffee +8 -6
  36. data/lib/generators/teaspoon/install/templates/jasmine/spec_helper.js +8 -7
  37. data/lib/generators/teaspoon/install/templates/mocha/env.rb +11 -0
  38. data/lib/generators/teaspoon/install/templates/mocha/env_comments.rb +182 -0
  39. data/lib/generators/teaspoon/install/templates/mocha/spec_helper.coffee +13 -13
  40. data/lib/generators/teaspoon/install/templates/mocha/spec_helper.js +13 -13
  41. data/lib/generators/teaspoon/install/templates/qunit/env.rb +11 -0
  42. data/lib/generators/teaspoon/install/templates/qunit/env_comments.rb +182 -0
  43. data/lib/generators/teaspoon/install/templates/qunit/test_helper.coffee +6 -5
  44. data/lib/generators/teaspoon/install/templates/qunit/test_helper.js +6 -5
  45. data/lib/tasks/teaspoon.rake +9 -2
  46. data/lib/teaspoon.rb +4 -6
  47. data/lib/teaspoon/command_line.rb +116 -134
  48. data/lib/teaspoon/configuration.rb +144 -66
  49. data/lib/teaspoon/console.rb +70 -37
  50. data/lib/teaspoon/coverage.rb +42 -15
  51. data/lib/teaspoon/deprecated.rb +65 -0
  52. data/lib/teaspoon/drivers/base.rb +10 -0
  53. data/lib/teaspoon/drivers/phantomjs/runner.js +9 -11
  54. data/lib/teaspoon/drivers/phantomjs_driver.rb +21 -21
  55. data/lib/teaspoon/drivers/selenium_driver.rb +32 -13
  56. data/lib/teaspoon/engine.rb +32 -12
  57. data/lib/teaspoon/environment.rb +16 -12
  58. data/lib/teaspoon/exceptions.rb +41 -5
  59. data/lib/teaspoon/exporter.rb +52 -0
  60. data/lib/teaspoon/formatters/base.rb +171 -0
  61. data/lib/teaspoon/formatters/clean_formatter.rb +2 -4
  62. data/lib/teaspoon/formatters/documentation_formatter.rb +60 -0
  63. data/lib/teaspoon/formatters/dot_formatter.rb +12 -90
  64. data/lib/teaspoon/formatters/json_formatter.rb +36 -0
  65. data/lib/teaspoon/formatters/junit_formatter.rb +51 -32
  66. data/lib/teaspoon/formatters/modules/report_module.rb +76 -0
  67. data/lib/teaspoon/formatters/pride_formatter.rb +23 -27
  68. data/lib/teaspoon/formatters/snowday_formatter.rb +7 -11
  69. data/lib/teaspoon/formatters/swayze_or_oprah_formatter.rb +88 -64
  70. data/lib/teaspoon/formatters/tap_formatter.rb +18 -27
  71. data/lib/teaspoon/formatters/tap_y_formatter.rb +35 -45
  72. data/lib/teaspoon/formatters/teamcity_formatter.rb +69 -31
  73. data/lib/teaspoon/instrumentation.rb +33 -33
  74. data/lib/teaspoon/result.rb +2 -1
  75. data/lib/teaspoon/runner.rb +40 -28
  76. data/lib/teaspoon/server.rb +23 -25
  77. data/lib/teaspoon/suite.rb +52 -72
  78. data/lib/teaspoon/utility.rb +3 -14
  79. data/lib/teaspoon/version.rb +1 -1
  80. data/spec/dummy/app/assets/javascripts/integration/integration_spec.coffee +3 -0
  81. data/spec/dummy/app/assets/javascripts/integration/spec_helper.coffee +2 -0
  82. data/spec/dummy/config/application.rb +3 -0
  83. data/spec/features/console_reporter_spec.rb +48 -18
  84. data/spec/features/hooks_spec.rb +23 -41
  85. data/spec/features/html_reporter_spec.rb +38 -21
  86. data/spec/features/install_generator_spec.rb +34 -20
  87. data/spec/features/instrumentation_spec.rb +3 -2
  88. data/spec/fixtures/coverage.json +243 -0
  89. data/spec/javascripts/fixtures/_body.html.erb +1 -0
  90. data/spec/javascripts/jasmine_helper.coffee +1 -1
  91. data/spec/javascripts/teaspoon/base/fixture_spec.coffee +4 -4
  92. data/spec/javascripts/teaspoon/base/reporters/html_spec.coffee +9 -10
  93. data/spec/javascripts/teaspoon/mocha/reporters/html_mspec.coffee +0 -6
  94. data/spec/javascripts/teaspoon/phantomjs/runner_spec.coffee +5 -6
  95. data/spec/javascripts/turbolinks_helper.coffee +1 -1
  96. data/spec/spec_helper.rb +3 -4
  97. data/spec/teaspoon/command_line_spec.rb +139 -23
  98. data/spec/teaspoon/configuration_spec.rb +164 -46
  99. data/spec/teaspoon/console_spec.rb +142 -47
  100. data/spec/teaspoon/coverage_spec.rb +98 -28
  101. data/spec/teaspoon/drivers/base_spec.rb +5 -0
  102. data/spec/teaspoon/drivers/phantomjs_driver_spec.rb +32 -14
  103. data/spec/teaspoon/drivers/selenium_driver_spec.rb +32 -24
  104. data/spec/teaspoon/engine_spec.rb +8 -5
  105. data/spec/teaspoon/environment_spec.rb +56 -33
  106. data/spec/teaspoon/exceptions_spec.rb +57 -0
  107. data/spec/teaspoon/exporter_spec.rb +96 -0
  108. data/spec/teaspoon/formatters/base_spec.rb +259 -0
  109. data/spec/teaspoon/formatters/clean_formatter_spec.rb +37 -0
  110. data/spec/teaspoon/formatters/documentation_formatter_spec.rb +127 -0
  111. data/spec/teaspoon/formatters/dot_formatter_spec.rb +52 -56
  112. data/spec/teaspoon/formatters/json_formatter_spec.rb +77 -0
  113. data/spec/teaspoon/formatters/junit_formatter_spec.rb +72 -35
  114. data/spec/teaspoon/formatters/pride_formatter_spec.rb +37 -0
  115. data/spec/teaspoon/formatters/snowday_formatter_spec.rb +35 -0
  116. data/spec/teaspoon/formatters/tap_formatter_spec.rb +29 -81
  117. data/spec/teaspoon/formatters/tap_y_formatter_spec.rb +31 -141
  118. data/spec/teaspoon/formatters/teamcity_formatter_spec.rb +99 -42
  119. data/spec/teaspoon/instrumentation_spec.rb +44 -44
  120. data/spec/teaspoon/result_spec.rb +37 -0
  121. data/spec/teaspoon/runner_spec.rb +70 -59
  122. data/spec/teaspoon/server_spec.rb +34 -52
  123. data/spec/teaspoon/suite_spec.rb +42 -188
  124. data/spec/teaspoon_env.rb +39 -28
  125. data/vendor/assets/javascripts/{angular-scenario-1.0.5.js → angular/1.0.5.js} +0 -0
  126. data/vendor/assets/javascripts/{angular-scenario-1.0.5.MIT-LICENSE → angular/MIT-LICENSE} +0 -0
  127. data/vendor/assets/javascripts/{jasmine-1.3.1.js → jasmine/1.3.1.js} +0 -0
  128. data/vendor/assets/javascripts/jasmine/2.0.0.js +2412 -0
  129. data/vendor/assets/javascripts/{jasmine-1.3.1.MIT.LICENSE → jasmine/MIT.LICENSE} +0 -0
  130. data/vendor/assets/javascripts/{mocha-1.10.0.js → mocha/1.10.0.js} +1 -0
  131. data/vendor/assets/javascripts/mocha/1.17.1.js +5813 -0
  132. data/vendor/assets/javascripts/{mocha-1.10.1.MIT.LICENSE → mocha/MIT.LICENSE} +0 -0
  133. data/vendor/assets/javascripts/{qunit-1.12.0.js → qunit/1.12.0.js} +1 -1
  134. data/vendor/assets/javascripts/qunit/1.14.0.js +2288 -0
  135. data/vendor/assets/javascripts/{qunit-1.12.0.MIT.LICENSE → qunit/MIT.LICENSE} +0 -0
  136. data/vendor/assets/javascripts/support/chai.js +827 -385
  137. data/vendor/assets/javascripts/support/jasmine-jquery-1.7.0.js +720 -0
  138. data/vendor/assets/javascripts/support/jasmine-jquery-2.0.0.js +812 -0
  139. data/vendor/assets/javascripts/support/sinon-chai.js +17 -0
  140. data/vendor/assets/javascripts/support/sinon.js +1138 -643
  141. metadata +57 -36
  142. data/app/controllers/teaspoon/spec_controller.rb +0 -38
  143. data/app/helpers/teaspoon/spec_helper.rb +0 -36
  144. data/app/views/teaspoon/spec/_require_js.html.erb +0 -21
  145. data/app/views/teaspoon/spec/_standard.html.erb +0 -4
  146. data/app/views/teaspoon/spec/runner.html.erb +0 -19
  147. data/lib/generators/teaspoon/install/templates/env.rb +0 -38
  148. data/lib/generators/teaspoon/install/templates/jasmine/initializer.rb +0 -64
  149. data/lib/generators/teaspoon/install/templates/mocha/initializer.rb +0 -64
  150. data/lib/generators/teaspoon/install/templates/qunit/initializer.rb +0 -64
  151. data/lib/teaspoon/check_coverage.rb +0 -33
  152. data/lib/teaspoon/drivers/base_driver.rb +0 -10
  153. data/lib/teaspoon/exception_handling.rb +0 -18
  154. data/lib/teaspoon/formatters/base_formatter.rb +0 -63
  155. data/spec/dummy/config/initializers/teaspoon.rb +0 -41
  156. data/spec/teaspoon/check_coverage_spec.rb +0 -50
  157. data/spec/teaspoon/formatters/base_formatter_spec.rb +0 -45
  158. data/vendor/assets/javascripts/support/chai.MIT.LICENSE +0 -22
  159. data/vendor/assets/javascripts/support/expect.MIT.LICENSE +0 -22
  160. data/vendor/assets/javascripts/support/jasmine-jquery.MIT.LICENSE +0 -20
  161. data/vendor/assets/javascripts/support/jasmine-jquery.js +0 -659
  162. data/vendor/assets/javascripts/support/sinon-chai.MIT-ISH.LICENSE +0 -13
  163. data/vendor/assets/javascripts/support/sinon.BSD.LICENSE +0 -27
@@ -1,2606 +1,7 @@
1
- var isCommonJS = typeof window == "undefined" && typeof exports == "object";
2
-
3
- /**
4
- * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
5
- *
6
- * @namespace
7
- */
8
- var jasmine = {};
9
- if (isCommonJS) exports.jasmine = jasmine;
10
- /**
11
- * @private
12
- */
13
- jasmine.unimplementedMethod_ = function() {
14
- throw new Error("unimplemented method");
15
- };
16
-
17
- /**
18
- * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
19
- * a plain old variable and may be redefined by somebody else.
20
- *
21
- * @private
22
- */
23
- jasmine.undefined = jasmine.___undefined___;
24
-
25
- /**
26
- * Show diagnostic messages in the console if set to true
27
- *
28
- */
29
- jasmine.VERBOSE = false;
30
-
31
- /**
32
- * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
33
- *
34
- */
35
- jasmine.DEFAULT_UPDATE_INTERVAL = 250;
36
-
37
- /**
38
- * Maximum levels of nesting that will be included when an object is pretty-printed
39
- */
40
- jasmine.MAX_PRETTY_PRINT_DEPTH = 40;
41
-
42
- /**
43
- * Default timeout interval in milliseconds for waitsFor() blocks.
44
- */
45
- jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
46
-
47
- /**
48
- * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite.
49
- * Set to false to let the exception bubble up in the browser.
50
- *
51
- */
52
- jasmine.CATCH_EXCEPTIONS = true;
53
-
54
- jasmine.getGlobal = function() {
55
- function getGlobal() {
56
- return this;
57
- }
58
-
59
- return getGlobal();
60
- };
61
-
62
- /**
63
- * Allows for bound functions to be compared. Internal use only.
64
- *
65
- * @ignore
66
- * @private
67
- * @param base {Object} bound 'this' for the function
68
- * @param name {Function} function to find
69
- */
70
- jasmine.bindOriginal_ = function(base, name) {
71
- var original = base[name];
72
- if (original.apply) {
73
- return function() {
74
- return original.apply(base, arguments);
75
- };
76
- } else {
77
- // IE support
78
- return jasmine.getGlobal()[name];
79
- }
80
- };
81
-
82
- jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
83
- jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
84
- jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
85
- jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
86
-
87
- jasmine.MessageResult = function(values) {
88
- this.type = 'log';
89
- this.values = values;
90
- this.trace = new Error(); // todo: test better
91
- };
92
-
93
- jasmine.MessageResult.prototype.toString = function() {
94
- var text = "";
95
- for (var i = 0; i < this.values.length; i++) {
96
- if (i > 0) text += " ";
97
- if (jasmine.isString_(this.values[i])) {
98
- text += this.values[i];
99
- } else {
100
- text += jasmine.pp(this.values[i]);
101
- }
102
- }
103
- return text;
104
- };
105
-
106
- jasmine.ExpectationResult = function(params) {
107
- this.type = 'expect';
108
- this.matcherName = params.matcherName;
109
- this.passed_ = params.passed;
110
- this.expected = params.expected;
111
- this.actual = params.actual;
112
- this.message = this.passed_ ? 'Passed.' : params.message;
113
-
114
- var trace = (params.trace || new Error(this.message));
115
- this.trace = this.passed_ ? '' : trace;
116
- };
117
-
118
- jasmine.ExpectationResult.prototype.toString = function () {
119
- return this.message;
120
- };
121
-
122
- jasmine.ExpectationResult.prototype.passed = function () {
123
- return this.passed_;
124
- };
125
-
126
- /**
127
- * Getter for the Jasmine environment. Ensures one gets created
128
- */
129
- jasmine.getEnv = function() {
130
- var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
131
- return env;
132
- };
133
-
134
- /**
135
- * @ignore
136
- * @private
137
- * @param value
138
- * @returns {Boolean}
139
- */
140
- jasmine.isArray_ = function(value) {
141
- return jasmine.isA_("Array", value);
142
- };
143
-
144
- /**
145
- * @ignore
146
- * @private
147
- * @param value
148
- * @returns {Boolean}
149
- */
150
- jasmine.isString_ = function(value) {
151
- return jasmine.isA_("String", value);
152
- };
153
-
154
- /**
155
- * @ignore
156
- * @private
157
- * @param value
158
- * @returns {Boolean}
159
- */
160
- jasmine.isNumber_ = function(value) {
161
- return jasmine.isA_("Number", value);
162
- };
163
-
164
- /**
165
- * @ignore
166
- * @private
167
- * @param {String} typeName
168
- * @param value
169
- * @returns {Boolean}
170
- */
171
- jasmine.isA_ = function(typeName, value) {
172
- return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
173
- };
174
-
175
- /**
176
- * Pretty printer for expecations. Takes any object and turns it into a human-readable string.
177
- *
178
- * @param value {Object} an object to be outputted
179
- * @returns {String}
180
- */
181
- jasmine.pp = function(value) {
182
- var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
183
- stringPrettyPrinter.format(value);
184
- return stringPrettyPrinter.string;
185
- };
186
-
187
- /**
188
- * Returns true if the object is a DOM Node.
189
- *
190
- * @param {Object} obj object to check
191
- * @returns {Boolean}
192
- */
193
- jasmine.isDomNode = function(obj) {
194
- return obj.nodeType > 0;
195
- };
196
-
197
- /**
198
- * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter.
199
- *
200
- * @example
201
- * // don't care about which function is passed in, as long as it's a function
202
- * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));
203
- *
204
- * @param {Class} clazz
205
- * @returns matchable object of the type clazz
206
- */
207
- jasmine.any = function(clazz) {
208
- return new jasmine.Matchers.Any(clazz);
209
- };
210
-
211
- /**
212
- * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
213
- * attributes on the object.
214
- *
215
- * @example
216
- * // don't care about any other attributes than foo.
217
- * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
218
- *
219
- * @param sample {Object} sample
220
- * @returns matchable object for the sample
221
- */
222
- jasmine.objectContaining = function (sample) {
223
- return new jasmine.Matchers.ObjectContaining(sample);
224
- };
225
-
226
- /**
227
- * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
228
- *
229
- * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine
230
- * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
231
- *
232
- * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).
233
- *
234
- * Spies are torn down at the end of every spec.
235
- *
236
- * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
237
- *
238
- * @example
239
- * // a stub
240
- * var myStub = jasmine.createSpy('myStub'); // can be used anywhere
241
- *
242
- * // spy example
243
- * var foo = {
244
- * not: function(bool) { return !bool; }
245
- * }
246
- *
247
- * // actual foo.not will not be called, execution stops
248
- * spyOn(foo, 'not');
249
-
250
- // foo.not spied upon, execution will continue to implementation
251
- * spyOn(foo, 'not').andCallThrough();
252
- *
253
- * // fake example
254
- * var foo = {
255
- * not: function(bool) { return !bool; }
256
- * }
257
- *
258
- * // foo.not(val) will return val
259
- * spyOn(foo, 'not').andCallFake(function(value) {return value;});
260
- *
261
- * // mock example
262
- * foo.not(7 == 7);
263
- * expect(foo.not).toHaveBeenCalled();
264
- * expect(foo.not).toHaveBeenCalledWith(true);
265
- *
266
- * @constructor
267
- * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
268
- * @param {String} name
269
- */
270
- jasmine.Spy = function(name) {
271
- /**
272
- * The name of the spy, if provided.
273
- */
274
- this.identity = name || 'unknown';
275
- /**
276
- * Is this Object a spy?
277
- */
278
- this.isSpy = true;
279
- /**
280
- * The actual function this spy stubs.
281
- */
282
- this.plan = function() {
283
- };
284
- /**
285
- * Tracking of the most recent call to the spy.
286
- * @example
287
- * var mySpy = jasmine.createSpy('foo');
288
- * mySpy(1, 2);
289
- * mySpy.mostRecentCall.args = [1, 2];
290
- */
291
- this.mostRecentCall = {};
292
-
293
- /**
294
- * Holds arguments for each call to the spy, indexed by call count
295
- * @example
296
- * var mySpy = jasmine.createSpy('foo');
297
- * mySpy(1, 2);
298
- * mySpy(7, 8);
299
- * mySpy.mostRecentCall.args = [7, 8];
300
- * mySpy.argsForCall[0] = [1, 2];
301
- * mySpy.argsForCall[1] = [7, 8];
302
- */
303
- this.argsForCall = [];
304
- this.calls = [];
305
- };
306
-
307
- /**
308
- * Tells a spy to call through to the actual implemenatation.
309
- *
310
- * @example
311
- * var foo = {
312
- * bar: function() { // do some stuff }
313
- * }
314
- *
315
- * // defining a spy on an existing property: foo.bar
316
- * spyOn(foo, 'bar').andCallThrough();
317
- */
318
- jasmine.Spy.prototype.andCallThrough = function() {
319
- this.plan = this.originalValue;
320
- return this;
321
- };
322
-
323
- /**
324
- * For setting the return value of a spy.
325
- *
326
- * @example
327
- * // defining a spy from scratch: foo() returns 'baz'
328
- * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
329
- *
330
- * // defining a spy on an existing property: foo.bar() returns 'baz'
331
- * spyOn(foo, 'bar').andReturn('baz');
332
- *
333
- * @param {Object} value
334
- */
335
- jasmine.Spy.prototype.andReturn = function(value) {
336
- this.plan = function() {
337
- return value;
338
- };
339
- return this;
340
- };
341
-
342
- /**
343
- * For throwing an exception when a spy is called.
344
- *
345
- * @example
346
- * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
347
- * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
348
- *
349
- * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
350
- * spyOn(foo, 'bar').andThrow('baz');
351
- *
352
- * @param {String} exceptionMsg
353
- */
354
- jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
355
- this.plan = function() {
356
- throw exceptionMsg;
357
- };
358
- return this;
359
- };
360
-
361
- /**
362
- * Calls an alternate implementation when a spy is called.
363
- *
364
- * @example
365
- * var baz = function() {
366
- * // do some stuff, return something
367
- * }
368
- * // defining a spy from scratch: foo() calls the function baz
369
- * var foo = jasmine.createSpy('spy on foo').andCall(baz);
370
- *
371
- * // defining a spy on an existing property: foo.bar() calls an anonymnous function
372
- * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
373
- *
374
- * @param {Function} fakeFunc
375
- */
376
- jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
377
- this.plan = fakeFunc;
378
- return this;
379
- };
380
-
381
- /**
382
- * Resets all of a spy's the tracking variables so that it can be used again.
383
- *
384
- * @example
385
- * spyOn(foo, 'bar');
386
- *
387
- * foo.bar();
388
- *
389
- * expect(foo.bar.callCount).toEqual(1);
390
- *
391
- * foo.bar.reset();
392
- *
393
- * expect(foo.bar.callCount).toEqual(0);
394
- */
395
- jasmine.Spy.prototype.reset = function() {
396
- this.wasCalled = false;
397
- this.callCount = 0;
398
- this.argsForCall = [];
399
- this.calls = [];
400
- this.mostRecentCall = {};
401
- };
402
-
403
- jasmine.createSpy = function(name) {
404
-
405
- var spyObj = function() {
406
- spyObj.wasCalled = true;
407
- spyObj.callCount++;
408
- var args = jasmine.util.argsToArray(arguments);
409
- spyObj.mostRecentCall.object = this;
410
- spyObj.mostRecentCall.args = args;
411
- spyObj.argsForCall.push(args);
412
- spyObj.calls.push({object: this, args: args});
413
- return spyObj.plan.apply(this, arguments);
414
- };
415
-
416
- var spy = new jasmine.Spy(name);
417
-
418
- for (var prop in spy) {
419
- spyObj[prop] = spy[prop];
420
- }
421
-
422
- spyObj.reset();
423
-
424
- return spyObj;
425
- };
426
-
427
- /**
428
- * Determines whether an object is a spy.
429
- *
430
- * @param {jasmine.Spy|Object} putativeSpy
431
- * @returns {Boolean}
432
- */
433
- jasmine.isSpy = function(putativeSpy) {
434
- return putativeSpy && putativeSpy.isSpy;
435
- };
436
-
437
- /**
438
- * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something
439
- * large in one call.
440
- *
441
- * @param {String} baseName name of spy class
442
- * @param {Array} methodNames array of names of methods to make spies
443
- */
444
- jasmine.createSpyObj = function(baseName, methodNames) {
445
- if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
446
- throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
447
- }
448
- var obj = {};
449
- for (var i = 0; i < methodNames.length; i++) {
450
- obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
451
- }
452
- return obj;
453
- };
454
-
455
- /**
456
- * All parameters are pretty-printed and concatenated together, then written to the current spec's output.
457
- *
458
- * Be careful not to leave calls to <code>jasmine.log</code> in production code.
459
- */
460
- jasmine.log = function() {
461
- var spec = jasmine.getEnv().currentSpec;
462
- spec.log.apply(spec, arguments);
463
- };
464
-
465
- /**
466
- * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.
467
- *
468
- * @example
469
- * // spy example
470
- * var foo = {
471
- * not: function(bool) { return !bool; }
472
- * }
473
- * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
474
- *
475
- * @see jasmine.createSpy
476
- * @param obj
477
- * @param methodName
478
- * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods
479
- */
480
- var spyOn = function(obj, methodName) {
481
- return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
482
- };
483
- if (isCommonJS) exports.spyOn = spyOn;
484
-
485
- /**
486
- * Creates a Jasmine spec that will be added to the current suite.
487
- *
488
- * // TODO: pending tests
489
- *
490
- * @example
491
- * it('should be true', function() {
492
- * expect(true).toEqual(true);
493
- * });
494
- *
495
- * @param {String} desc description of this specification
496
- * @param {Function} func defines the preconditions and expectations of the spec
497
- */
498
- var it = function(desc, func) {
499
- return jasmine.getEnv().it(desc, func);
500
- };
501
- if (isCommonJS) exports.it = it;
502
-
503
- /**
504
- * Creates a <em>disabled</em> Jasmine spec.
505
- *
506
- * A convenience method that allows existing specs to be disabled temporarily during development.
507
- *
508
- * @param {String} desc description of this specification
509
- * @param {Function} func defines the preconditions and expectations of the spec
510
- */
511
- var xit = function(desc, func) {
512
- return jasmine.getEnv().xit(desc, func);
513
- };
514
- if (isCommonJS) exports.xit = xit;
515
-
516
- /**
517
- * Starts a chain for a Jasmine expectation.
518
- *
519
- * It is passed an Object that is the actual value and should chain to one of the many
520
- * jasmine.Matchers functions.
521
- *
522
- * @param {Object} actual Actual value to test against and expected value
523
- * @return {jasmine.Matchers}
524
- */
525
- var expect = function(actual) {
526
- return jasmine.getEnv().currentSpec.expect(actual);
527
- };
528
- if (isCommonJS) exports.expect = expect;
529
-
530
- /**
531
- * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
532
- *
533
- * @param {Function} func Function that defines part of a jasmine spec.
534
- */
535
- var runs = function(func) {
536
- jasmine.getEnv().currentSpec.runs(func);
537
- };
538
- if (isCommonJS) exports.runs = runs;
539
-
540
- /**
541
- * Waits a fixed time period before moving to the next block.
542
- *
543
- * @deprecated Use waitsFor() instead
544
- * @param {Number} timeout milliseconds to wait
545
- */
546
- var waits = function(timeout) {
547
- jasmine.getEnv().currentSpec.waits(timeout);
548
- };
549
- if (isCommonJS) exports.waits = waits;
550
-
551
- /**
552
- * Waits for the latchFunction to return true before proceeding to the next block.
553
- *
554
- * @param {Function} latchFunction
555
- * @param {String} optional_timeoutMessage
556
- * @param {Number} optional_timeout
557
- */
558
- var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
559
- jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
560
- };
561
- if (isCommonJS) exports.waitsFor = waitsFor;
562
-
563
- /**
564
- * A function that is called before each spec in a suite.
565
- *
566
- * Used for spec setup, including validating assumptions.
567
- *
568
- * @param {Function} beforeEachFunction
569
- */
570
- var beforeEach = function(beforeEachFunction) {
571
- jasmine.getEnv().beforeEach(beforeEachFunction);
572
- };
573
- if (isCommonJS) exports.beforeEach = beforeEach;
574
-
575
- /**
576
- * A function that is called after each spec in a suite.
577
- *
578
- * Used for restoring any state that is hijacked during spec execution.
579
- *
580
- * @param {Function} afterEachFunction
581
- */
582
- var afterEach = function(afterEachFunction) {
583
- jasmine.getEnv().afterEach(afterEachFunction);
584
- };
585
- if (isCommonJS) exports.afterEach = afterEach;
586
-
587
- /**
588
- * Defines a suite of specifications.
589
- *
590
- * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
591
- * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
592
- * of setup in some tests.
593
- *
594
- * @example
595
- * // TODO: a simple suite
596
- *
597
- * // TODO: a simple suite with a nested describe block
598
- *
599
- * @param {String} description A string, usually the class under test.
600
- * @param {Function} specDefinitions function that defines several specs.
601
- */
602
- var describe = function(description, specDefinitions) {
603
- return jasmine.getEnv().describe(description, specDefinitions);
604
- };
605
- if (isCommonJS) exports.describe = describe;
606
-
607
- /**
608
- * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
609
- *
610
- * @param {String} description A string, usually the class under test.
611
- * @param {Function} specDefinitions function that defines several specs.
612
- */
613
- var xdescribe = function(description, specDefinitions) {
614
- return jasmine.getEnv().xdescribe(description, specDefinitions);
615
- };
616
- if (isCommonJS) exports.xdescribe = xdescribe;
617
-
618
-
619
- // Provide the XMLHttpRequest class for IE 5.x-6.x:
620
- jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
621
- function tryIt(f) {
622
- try {
623
- return f();
624
- } catch(e) {
625
- }
626
- return null;
627
- }
628
-
629
- var xhr = tryIt(function() {
630
- return new ActiveXObject("Msxml2.XMLHTTP.6.0");
631
- }) ||
632
- tryIt(function() {
633
- return new ActiveXObject("Msxml2.XMLHTTP.3.0");
634
- }) ||
635
- tryIt(function() {
636
- return new ActiveXObject("Msxml2.XMLHTTP");
637
- }) ||
638
- tryIt(function() {
639
- return new ActiveXObject("Microsoft.XMLHTTP");
640
- });
641
-
642
- if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
643
-
644
- return xhr;
645
- } : XMLHttpRequest;
646
- /**
647
- * @namespace
648
- */
649
- jasmine.util = {};
650
-
651
- /**
652
- * Declare that a child class inherit it's prototype from the parent class.
653
- *
654
- * @private
655
- * @param {Function} childClass
656
- * @param {Function} parentClass
657
- */
658
- jasmine.util.inherit = function(childClass, parentClass) {
659
- /**
660
- * @private
661
- */
662
- var subclass = function() {
663
- };
664
- subclass.prototype = parentClass.prototype;
665
- childClass.prototype = new subclass();
666
- };
667
-
668
- jasmine.util.formatException = function(e) {
669
- var lineNumber;
670
- if (e.line) {
671
- lineNumber = e.line;
672
- }
673
- else if (e.lineNumber) {
674
- lineNumber = e.lineNumber;
675
- }
676
-
677
- var file;
678
-
679
- if (e.sourceURL) {
680
- file = e.sourceURL;
681
- }
682
- else if (e.fileName) {
683
- file = e.fileName;
684
- }
685
-
686
- var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
687
-
688
- if (file && lineNumber) {
689
- message += ' in ' + file + ' (line ' + lineNumber + ')';
690
- }
691
-
692
- return message;
693
- };
694
-
695
- jasmine.util.htmlEscape = function(str) {
696
- if (!str) return str;
697
- return str.replace(/&/g, '&amp;')
698
- .replace(/</g, '&lt;')
699
- .replace(/>/g, '&gt;');
700
- };
701
-
702
- jasmine.util.argsToArray = function(args) {
703
- var arrayOfArgs = [];
704
- for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
705
- return arrayOfArgs;
706
- };
707
-
708
- jasmine.util.extend = function(destination, source) {
709
- for (var property in source) destination[property] = source[property];
710
- return destination;
711
- };
712
-
713
- /**
714
- * Environment for Jasmine
715
- *
716
- * @constructor
717
- */
718
- jasmine.Env = function() {
719
- this.currentSpec = null;
720
- this.currentSuite = null;
721
- this.currentRunner_ = new jasmine.Runner(this);
722
-
723
- this.reporter = new jasmine.MultiReporter();
724
-
725
- this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
726
- this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
727
- this.lastUpdate = 0;
728
- this.specFilter = function() {
729
- return true;
730
- };
731
-
732
- this.nextSpecId_ = 0;
733
- this.nextSuiteId_ = 0;
734
- this.equalityTesters_ = [];
735
-
736
- // wrap matchers
737
- this.matchersClass = function() {
738
- jasmine.Matchers.apply(this, arguments);
739
- };
740
- jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
741
-
742
- jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
743
- };
744
-
745
-
746
- jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
747
- jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
748
- jasmine.Env.prototype.setInterval = jasmine.setInterval;
749
- jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
750
-
751
- /**
752
- * @returns an object containing jasmine version build info, if set.
753
- */
754
- jasmine.Env.prototype.version = function () {
755
- if (jasmine.version_) {
756
- return jasmine.version_;
757
- } else {
758
- throw new Error('Version not set');
759
- }
760
- };
761
-
762
- /**
763
- * @returns string containing jasmine version build info, if set.
764
- */
765
- jasmine.Env.prototype.versionString = function() {
766
- if (!jasmine.version_) {
767
- return "version unknown";
768
- }
769
-
770
- var version = this.version();
771
- var versionString = version.major + "." + version.minor + "." + version.build;
772
- if (version.release_candidate) {
773
- versionString += ".rc" + version.release_candidate;
774
- }
775
- versionString += " revision " + version.revision;
776
- return versionString;
777
- };
778
-
779
- /**
780
- * @returns a sequential integer starting at 0
781
- */
782
- jasmine.Env.prototype.nextSpecId = function () {
783
- return this.nextSpecId_++;
784
- };
785
-
786
- /**
787
- * @returns a sequential integer starting at 0
788
- */
789
- jasmine.Env.prototype.nextSuiteId = function () {
790
- return this.nextSuiteId_++;
791
- };
792
-
793
- /**
794
- * Register a reporter to receive status updates from Jasmine.
795
- * @param {jasmine.Reporter} reporter An object which will receive status updates.
796
- */
797
- jasmine.Env.prototype.addReporter = function(reporter) {
798
- this.reporter.addReporter(reporter);
799
- };
800
-
801
- jasmine.Env.prototype.execute = function() {
802
- this.currentRunner_.execute();
803
- };
804
-
805
- jasmine.Env.prototype.describe = function(description, specDefinitions) {
806
- var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
807
-
808
- var parentSuite = this.currentSuite;
809
- if (parentSuite) {
810
- parentSuite.add(suite);
811
- } else {
812
- this.currentRunner_.add(suite);
813
- }
814
-
815
- this.currentSuite = suite;
816
-
817
- var declarationError = null;
818
- try {
819
- specDefinitions.call(suite);
820
- } catch(e) {
821
- declarationError = e;
822
- }
823
-
824
- if (declarationError) {
825
- this.it("encountered a declaration exception", function() {
826
- throw declarationError;
827
- });
828
- }
829
-
830
- this.currentSuite = parentSuite;
831
-
832
- return suite;
833
- };
834
-
835
- jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
836
- if (this.currentSuite) {
837
- this.currentSuite.beforeEach(beforeEachFunction);
838
- } else {
839
- this.currentRunner_.beforeEach(beforeEachFunction);
840
- }
841
- };
842
-
843
- jasmine.Env.prototype.currentRunner = function () {
844
- return this.currentRunner_;
845
- };
846
-
847
- jasmine.Env.prototype.afterEach = function(afterEachFunction) {
848
- if (this.currentSuite) {
849
- this.currentSuite.afterEach(afterEachFunction);
850
- } else {
851
- this.currentRunner_.afterEach(afterEachFunction);
852
- }
853
-
854
- };
855
-
856
- jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
857
- return {
858
- execute: function() {
859
- }
860
- };
861
- };
862
-
863
- jasmine.Env.prototype.it = function(description, func) {
864
- var spec = new jasmine.Spec(this, this.currentSuite, description);
865
- this.currentSuite.add(spec);
866
- this.currentSpec = spec;
867
-
868
- if (func) {
869
- spec.runs(func);
870
- } else {
871
- spec.pending = true
872
- }
873
-
874
- return spec;
875
- };
876
-
877
- jasmine.Env.prototype.xit = function(desc, func) {
878
- return {
879
- id: this.nextSpecId(),
880
- runs: function() {
881
- }
882
- };
883
- };
884
-
885
- jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {
886
- if (a.source != b.source)
887
- mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/");
888
-
889
- if (a.ignoreCase != b.ignoreCase)
890
- mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier");
891
-
892
- if (a.global != b.global)
893
- mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier");
894
-
895
- if (a.multiline != b.multiline)
896
- mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier");
897
-
898
- if (a.sticky != b.sticky)
899
- mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier");
900
-
901
- return (mismatchValues.length === 0);
902
- };
903
-
904
- jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
905
- if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
906
- return true;
907
- }
908
-
909
- a.__Jasmine_been_here_before__ = b;
910
- b.__Jasmine_been_here_before__ = a;
911
-
912
- var hasKey = function(obj, keyName) {
913
- return obj !== null && obj[keyName] !== jasmine.undefined;
914
- };
915
-
916
- for (var property in b) {
917
- if (!hasKey(a, property) && hasKey(b, property)) {
918
- mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
919
- }
920
- }
921
- for (property in a) {
922
- if (!hasKey(b, property) && hasKey(a, property)) {
923
- mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
924
- }
925
- }
926
- for (property in b) {
927
- if (property == '__Jasmine_been_here_before__') continue;
928
- if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
929
- 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.");
930
- }
931
- }
932
-
933
- if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
934
- mismatchValues.push("arrays were not the same length");
935
- }
936
-
937
- delete a.__Jasmine_been_here_before__;
938
- delete b.__Jasmine_been_here_before__;
939
- return (mismatchKeys.length === 0 && mismatchValues.length === 0);
940
- };
941
-
942
- jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
943
- mismatchKeys = mismatchKeys || [];
944
- mismatchValues = mismatchValues || [];
945
-
946
- for (var i = 0; i < this.equalityTesters_.length; i++) {
947
- var equalityTester = this.equalityTesters_[i];
948
- var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
949
- if (result !== jasmine.undefined) return result;
950
- }
951
-
952
- if (a === b) return true;
953
-
954
- if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
955
- return (a == jasmine.undefined && b == jasmine.undefined);
956
- }
957
-
958
- if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
959
- return a === b;
960
- }
961
-
962
- if (a instanceof Date && b instanceof Date) {
963
- return a.getTime() == b.getTime();
964
- }
965
-
966
- if (a.jasmineMatches) {
967
- return a.jasmineMatches(b);
968
- }
969
-
970
- if (b.jasmineMatches) {
971
- return b.jasmineMatches(a);
972
- }
973
-
974
- if (a instanceof jasmine.Matchers.ObjectContaining) {
975
- return a.matches(b);
976
- }
977
-
978
- if (b instanceof jasmine.Matchers.ObjectContaining) {
979
- return b.matches(a);
980
- }
981
-
982
- if (jasmine.isString_(a) && jasmine.isString_(b)) {
983
- return (a == b);
984
- }
985
-
986
- if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
987
- return (a == b);
988
- }
989
-
990
- if (a instanceof RegExp && b instanceof RegExp) {
991
- return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);
992
- }
993
-
994
- if (typeof a === "object" && typeof b === "object") {
995
- return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
996
- }
997
-
998
- //Straight check
999
- return (a === b);
1000
- };
1001
-
1002
- jasmine.Env.prototype.contains_ = function(haystack, needle) {
1003
- if (jasmine.isArray_(haystack)) {
1004
- for (var i = 0; i < haystack.length; i++) {
1005
- if (this.equals_(haystack[i], needle)) return true;
1006
- }
1007
- return false;
1008
- }
1009
- return haystack.indexOf(needle) >= 0;
1010
- };
1011
-
1012
- jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
1013
- this.equalityTesters_.push(equalityTester);
1014
- };
1015
- /** No-op base class for Jasmine reporters.
1016
- *
1017
- * @constructor
1018
- */
1019
- jasmine.Reporter = function() {
1020
- };
1021
-
1022
- //noinspection JSUnusedLocalSymbols
1023
- jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
1024
- };
1025
-
1026
- //noinspection JSUnusedLocalSymbols
1027
- jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
1028
- };
1029
-
1030
- //noinspection JSUnusedLocalSymbols
1031
- jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
1032
- };
1033
-
1034
- //noinspection JSUnusedLocalSymbols
1035
- jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
1036
- };
1037
-
1038
- //noinspection JSUnusedLocalSymbols
1039
- jasmine.Reporter.prototype.reportSpecResults = function(spec) {
1040
- };
1041
-
1042
- //noinspection JSUnusedLocalSymbols
1043
- jasmine.Reporter.prototype.log = function(str) {
1044
- };
1045
-
1046
- /**
1047
- * Blocks are functions with executable code that make up a spec.
1048
- *
1049
- * @constructor
1050
- * @param {jasmine.Env} env
1051
- * @param {Function} func
1052
- * @param {jasmine.Spec} spec
1053
- */
1054
- jasmine.Block = function(env, func, spec) {
1055
- this.env = env;
1056
- this.func = func;
1057
- this.spec = spec;
1058
- };
1059
-
1060
- jasmine.Block.prototype.execute = function(onComplete) {
1061
- if (!jasmine.CATCH_EXCEPTIONS) {
1062
- this.func.apply(this.spec);
1063
- }
1064
- else {
1065
- try {
1066
- this.func.apply(this.spec);
1067
- } catch (e) {
1068
- this.spec.fail(e);
1069
- }
1070
- }
1071
- onComplete();
1072
- };
1073
- /** JavaScript API reporter.
1074
- *
1075
- * @constructor
1076
- */
1077
- jasmine.JsApiReporter = function() {
1078
- this.started = false;
1079
- this.finished = false;
1080
- this.suites_ = [];
1081
- this.results_ = {};
1082
- };
1083
-
1084
- jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
1085
- this.started = true;
1086
- var suites = runner.topLevelSuites();
1087
- for (var i = 0; i < suites.length; i++) {
1088
- var suite = suites[i];
1089
- this.suites_.push(this.summarize_(suite));
1090
- }
1091
- };
1092
-
1093
- jasmine.JsApiReporter.prototype.suites = function() {
1094
- return this.suites_;
1095
- };
1096
-
1097
- jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
1098
- var isSuite = suiteOrSpec instanceof jasmine.Suite;
1099
- var summary = {
1100
- id: suiteOrSpec.id,
1101
- name: suiteOrSpec.description,
1102
- type: isSuite ? 'suite' : 'spec',
1103
- children: []
1104
- };
1105
-
1106
- if (isSuite) {
1107
- var children = suiteOrSpec.children();
1108
- for (var i = 0; i < children.length; i++) {
1109
- summary.children.push(this.summarize_(children[i]));
1110
- }
1111
- }
1112
- return summary;
1113
- };
1114
-
1115
- jasmine.JsApiReporter.prototype.results = function() {
1116
- return this.results_;
1117
- };
1118
-
1119
- jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
1120
- return this.results_[specId];
1121
- };
1122
-
1123
- //noinspection JSUnusedLocalSymbols
1124
- jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
1125
- this.finished = true;
1126
- };
1127
-
1128
- //noinspection JSUnusedLocalSymbols
1129
- jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
1130
- };
1131
-
1132
- //noinspection JSUnusedLocalSymbols
1133
- jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
1134
- this.results_[spec.id] = {
1135
- messages: spec.results().getItems(),
1136
- result: spec.results().failedCount > 0 ? "failed" : "passed"
1137
- };
1138
- };
1139
-
1140
- //noinspection JSUnusedLocalSymbols
1141
- jasmine.JsApiReporter.prototype.log = function(str) {
1142
- };
1143
-
1144
- jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
1145
- var results = {};
1146
- for (var i = 0; i < specIds.length; i++) {
1147
- var specId = specIds[i];
1148
- results[specId] = this.summarizeResult_(this.results_[specId]);
1149
- }
1150
- return results;
1151
- };
1152
-
1153
- jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
1154
- var summaryMessages = [];
1155
- var messagesLength = result.messages.length;
1156
- for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
1157
- var resultMessage = result.messages[messageIndex];
1158
- summaryMessages.push({
1159
- text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
1160
- passed: resultMessage.passed ? resultMessage.passed() : true,
1161
- type: resultMessage.type,
1162
- message: resultMessage.message,
1163
- trace: {
1164
- stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
1165
- }
1166
- });
1167
- }
1168
-
1169
- return {
1170
- result : result.result,
1171
- messages : summaryMessages
1172
- };
1173
- };
1174
-
1175
- /**
1176
- * @constructor
1177
- * @param {jasmine.Env} env
1178
- * @param actual
1179
- * @param {jasmine.Spec} spec
1180
- */
1181
- jasmine.Matchers = function(env, actual, spec, opt_isNot) {
1182
- this.env = env;
1183
- this.actual = actual;
1184
- this.spec = spec;
1185
- this.isNot = opt_isNot || false;
1186
- this.reportWasCalled_ = false;
1187
- };
1188
-
1189
- // todo: @deprecated as of Jasmine 0.11, remove soon [xw]
1190
- jasmine.Matchers.pp = function(str) {
1191
- throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
1192
- };
1193
-
1194
- // todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
1195
- jasmine.Matchers.prototype.report = function(result, failing_message, details) {
1196
- throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
1197
- };
1198
-
1199
- jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
1200
- for (var methodName in prototype) {
1201
- if (methodName == 'report') continue;
1202
- var orig = prototype[methodName];
1203
- matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
1204
- }
1205
- };
1206
-
1207
- jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
1208
- return function() {
1209
- var matcherArgs = jasmine.util.argsToArray(arguments);
1210
- var result = matcherFunction.apply(this, arguments);
1211
-
1212
- if (this.isNot) {
1213
- result = !result;
1214
- }
1215
-
1216
- if (this.reportWasCalled_) return result;
1217
-
1218
- var message;
1219
- if (!result) {
1220
- if (this.message) {
1221
- message = this.message.apply(this, arguments);
1222
- if (jasmine.isArray_(message)) {
1223
- message = message[this.isNot ? 1 : 0];
1224
- }
1225
- } else {
1226
- var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
1227
- message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate;
1228
- if (matcherArgs.length > 0) {
1229
- for (var i = 0; i < matcherArgs.length; i++) {
1230
- if (i > 0) message += ",";
1231
- message += " " + jasmine.pp(matcherArgs[i]);
1232
- }
1233
- }
1234
- message += ".";
1235
- }
1236
- }
1237
- var expectationResult = new jasmine.ExpectationResult({
1238
- matcherName: matcherName,
1239
- passed: result,
1240
- expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
1241
- actual: this.actual,
1242
- message: message
1243
- });
1244
- this.spec.addMatcherResult(expectationResult);
1245
- return jasmine.undefined;
1246
- };
1247
- };
1248
-
1249
-
1250
-
1251
-
1252
- /**
1253
- * toBe: compares the actual to the expected using ===
1254
- * @param expected
1255
- */
1256
- jasmine.Matchers.prototype.toBe = function(expected) {
1257
- return this.actual === expected;
1258
- };
1259
-
1260
- /**
1261
- * toNotBe: compares the actual to the expected using !==
1262
- * @param expected
1263
- * @deprecated as of 1.0. Use not.toBe() instead.
1264
- */
1265
- jasmine.Matchers.prototype.toNotBe = function(expected) {
1266
- return this.actual !== expected;
1267
- };
1268
-
1269
- /**
1270
- * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
1271
- *
1272
- * @param expected
1273
- */
1274
- jasmine.Matchers.prototype.toEqual = function(expected) {
1275
- return this.env.equals_(this.actual, expected);
1276
- };
1277
-
1278
- /**
1279
- * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
1280
- * @param expected
1281
- * @deprecated as of 1.0. Use not.toEqual() instead.
1282
- */
1283
- jasmine.Matchers.prototype.toNotEqual = function(expected) {
1284
- return !this.env.equals_(this.actual, expected);
1285
- };
1286
-
1287
- /**
1288
- * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes
1289
- * a pattern or a String.
1290
- *
1291
- * @param expected
1292
- */
1293
- jasmine.Matchers.prototype.toMatch = function(expected) {
1294
- return new RegExp(expected).test(this.actual);
1295
- };
1296
-
1297
- /**
1298
- * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
1299
- * @param expected
1300
- * @deprecated as of 1.0. Use not.toMatch() instead.
1301
- */
1302
- jasmine.Matchers.prototype.toNotMatch = function(expected) {
1303
- return !(new RegExp(expected).test(this.actual));
1304
- };
1305
-
1306
- /**
1307
- * Matcher that compares the actual to jasmine.undefined.
1308
- */
1309
- jasmine.Matchers.prototype.toBeDefined = function() {
1310
- return (this.actual !== jasmine.undefined);
1311
- };
1312
-
1313
- /**
1314
- * Matcher that compares the actual to jasmine.undefined.
1315
- */
1316
- jasmine.Matchers.prototype.toBeUndefined = function() {
1317
- return (this.actual === jasmine.undefined);
1318
- };
1319
-
1320
- /**
1321
- * Matcher that compares the actual to null.
1322
- */
1323
- jasmine.Matchers.prototype.toBeNull = function() {
1324
- return (this.actual === null);
1325
- };
1326
-
1327
- /**
1328
- * Matcher that compares the actual to NaN.
1329
- */
1330
- jasmine.Matchers.prototype.toBeNaN = function() {
1331
- this.message = function() {
1332
- return [ "Expected " + jasmine.pp(this.actual) + " to be NaN." ];
1333
- };
1334
-
1335
- return (this.actual !== this.actual);
1336
- };
1337
-
1338
- /**
1339
- * Matcher that boolean not-nots the actual.
1340
- */
1341
- jasmine.Matchers.prototype.toBeTruthy = function() {
1342
- return !!this.actual;
1343
- };
1344
-
1345
-
1346
- /**
1347
- * Matcher that boolean nots the actual.
1348
- */
1349
- jasmine.Matchers.prototype.toBeFalsy = function() {
1350
- return !this.actual;
1351
- };
1352
-
1353
-
1354
- /**
1355
- * Matcher that checks to see if the actual, a Jasmine spy, was called.
1356
- */
1357
- jasmine.Matchers.prototype.toHaveBeenCalled = function() {
1358
- if (arguments.length > 0) {
1359
- throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
1360
- }
1361
-
1362
- if (!jasmine.isSpy(this.actual)) {
1363
- throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1364
- }
1365
-
1366
- this.message = function() {
1367
- return [
1368
- "Expected spy " + this.actual.identity + " to have been called.",
1369
- "Expected spy " + this.actual.identity + " not to have been called."
1370
- ];
1371
- };
1372
-
1373
- return this.actual.wasCalled;
1374
- };
1375
-
1376
- /** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
1377
- jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
1378
-
1379
- /**
1380
- * Matcher that checks to see if the actual, a Jasmine spy, was not called.
1381
- *
1382
- * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead
1383
- */
1384
- jasmine.Matchers.prototype.wasNotCalled = function() {
1385
- if (arguments.length > 0) {
1386
- throw new Error('wasNotCalled does not take arguments');
1387
- }
1388
-
1389
- if (!jasmine.isSpy(this.actual)) {
1390
- throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1391
- }
1392
-
1393
- this.message = function() {
1394
- return [
1395
- "Expected spy " + this.actual.identity + " to not have been called.",
1396
- "Expected spy " + this.actual.identity + " to have been called."
1397
- ];
1398
- };
1399
-
1400
- return !this.actual.wasCalled;
1401
- };
1402
-
1403
- /**
1404
- * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
1405
- *
1406
- * @example
1407
- *
1408
- */
1409
- jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
1410
- var expectedArgs = jasmine.util.argsToArray(arguments);
1411
- if (!jasmine.isSpy(this.actual)) {
1412
- throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1413
- }
1414
- this.message = function() {
1415
- var invertedMessage = "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was.";
1416
- var positiveMessage = "";
1417
- if (this.actual.callCount === 0) {
1418
- positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.";
1419
- } else {
1420
- positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '')
1421
- }
1422
- return [positiveMessage, invertedMessage];
1423
- };
1424
-
1425
- return this.env.contains_(this.actual.argsForCall, expectedArgs);
1426
- };
1427
-
1428
- /** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
1429
- jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
1430
-
1431
- /** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
1432
- jasmine.Matchers.prototype.wasNotCalledWith = function() {
1433
- var expectedArgs = jasmine.util.argsToArray(arguments);
1434
- if (!jasmine.isSpy(this.actual)) {
1435
- throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1436
- }
1437
-
1438
- this.message = function() {
1439
- return [
1440
- "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
1441
- "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
1442
- ];
1443
- };
1444
-
1445
- return !this.env.contains_(this.actual.argsForCall, expectedArgs);
1446
- };
1447
-
1448
- /**
1449
- * Matcher that checks that the expected item is an element in the actual Array.
1450
- *
1451
- * @param {Object} expected
1452
- */
1453
- jasmine.Matchers.prototype.toContain = function(expected) {
1454
- return this.env.contains_(this.actual, expected);
1455
- };
1456
-
1457
- /**
1458
- * Matcher that checks that the expected item is NOT an element in the actual Array.
1459
- *
1460
- * @param {Object} expected
1461
- * @deprecated as of 1.0. Use not.toContain() instead.
1462
- */
1463
- jasmine.Matchers.prototype.toNotContain = function(expected) {
1464
- return !this.env.contains_(this.actual, expected);
1465
- };
1466
-
1467
- jasmine.Matchers.prototype.toBeLessThan = function(expected) {
1468
- return this.actual < expected;
1469
- };
1470
-
1471
- jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
1472
- return this.actual > expected;
1473
- };
1474
-
1475
- /**
1476
- * Matcher that checks that the expected item is equal to the actual item
1477
- * up to a given level of decimal precision (default 2).
1478
- *
1479
- * @param {Number} expected
1480
- * @param {Number} precision, as number of decimal places
1481
- */
1482
- jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
1483
- if (!(precision === 0)) {
1484
- precision = precision || 2;
1485
- }
1486
- return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2);
1487
- };
1488
-
1489
- /**
1490
- * Matcher that checks that the expected exception was thrown by the actual.
1491
- *
1492
- * @param {String} [expected]
1493
- */
1494
- jasmine.Matchers.prototype.toThrow = function(expected) {
1495
- var result = false;
1496
- var exception;
1497
- if (typeof this.actual != 'function') {
1498
- throw new Error('Actual is not a function');
1499
- }
1500
- try {
1501
- this.actual();
1502
- } catch (e) {
1503
- exception = e;
1504
- }
1505
- if (exception) {
1506
- result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
1507
- }
1508
-
1509
- var not = this.isNot ? "not " : "";
1510
-
1511
- this.message = function() {
1512
- if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
1513
- return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
1514
- } else {
1515
- return "Expected function to throw an exception.";
1516
- }
1517
- };
1518
-
1519
- return result;
1520
- };
1521
-
1522
- jasmine.Matchers.Any = function(expectedClass) {
1523
- this.expectedClass = expectedClass;
1524
- };
1525
-
1526
- jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
1527
- if (this.expectedClass == String) {
1528
- return typeof other == 'string' || other instanceof String;
1529
- }
1530
-
1531
- if (this.expectedClass == Number) {
1532
- return typeof other == 'number' || other instanceof Number;
1533
- }
1534
-
1535
- if (this.expectedClass == Function) {
1536
- return typeof other == 'function' || other instanceof Function;
1537
- }
1538
-
1539
- if (this.expectedClass == Object) {
1540
- return typeof other == 'object';
1541
- }
1542
-
1543
- return other instanceof this.expectedClass;
1544
- };
1545
-
1546
- jasmine.Matchers.Any.prototype.jasmineToString = function() {
1547
- return '<jasmine.any(' + this.expectedClass + ')>';
1548
- };
1549
-
1550
- jasmine.Matchers.ObjectContaining = function (sample) {
1551
- this.sample = sample;
1552
- };
1553
-
1554
- jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
1555
- mismatchKeys = mismatchKeys || [];
1556
- mismatchValues = mismatchValues || [];
1557
-
1558
- var env = jasmine.getEnv();
1559
-
1560
- var hasKey = function(obj, keyName) {
1561
- return obj != null && obj[keyName] !== jasmine.undefined;
1562
- };
1563
-
1564
- for (var property in this.sample) {
1565
- if (!hasKey(other, property) && hasKey(this.sample, property)) {
1566
- mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
1567
- }
1568
- else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
1569
- mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual.");
1570
- }
1571
- }
1572
-
1573
- return (mismatchKeys.length === 0 && mismatchValues.length === 0);
1574
- };
1575
-
1576
- jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
1577
- return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>";
1578
- };
1579
- // Mock setTimeout, clearTimeout
1580
- // Contributed by Pivotal Computer Systems, www.pivotalsf.com
1581
-
1582
- jasmine.FakeTimer = function() {
1583
- this.reset();
1584
-
1585
- var self = this;
1586
- self.setTimeout = function(funcToCall, millis) {
1587
- self.timeoutsMade++;
1588
- self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
1589
- return self.timeoutsMade;
1590
- };
1591
-
1592
- self.setInterval = function(funcToCall, millis) {
1593
- self.timeoutsMade++;
1594
- self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
1595
- return self.timeoutsMade;
1596
- };
1597
-
1598
- self.clearTimeout = function(timeoutKey) {
1599
- self.scheduledFunctions[timeoutKey] = jasmine.undefined;
1600
- };
1601
-
1602
- self.clearInterval = function(timeoutKey) {
1603
- self.scheduledFunctions[timeoutKey] = jasmine.undefined;
1604
- };
1605
-
1606
- };
1607
-
1608
- jasmine.FakeTimer.prototype.reset = function() {
1609
- this.timeoutsMade = 0;
1610
- this.scheduledFunctions = {};
1611
- this.nowMillis = 0;
1612
- };
1613
-
1614
- jasmine.FakeTimer.prototype.tick = function(millis) {
1615
- var oldMillis = this.nowMillis;
1616
- var newMillis = oldMillis + millis;
1617
- this.runFunctionsWithinRange(oldMillis, newMillis);
1618
- this.nowMillis = newMillis;
1619
- };
1620
-
1621
- jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
1622
- var scheduledFunc;
1623
- var funcsToRun = [];
1624
- for (var timeoutKey in this.scheduledFunctions) {
1625
- scheduledFunc = this.scheduledFunctions[timeoutKey];
1626
- if (scheduledFunc != jasmine.undefined &&
1627
- scheduledFunc.runAtMillis >= oldMillis &&
1628
- scheduledFunc.runAtMillis <= nowMillis) {
1629
- funcsToRun.push(scheduledFunc);
1630
- this.scheduledFunctions[timeoutKey] = jasmine.undefined;
1631
- }
1632
- }
1633
-
1634
- if (funcsToRun.length > 0) {
1635
- funcsToRun.sort(function(a, b) {
1636
- return a.runAtMillis - b.runAtMillis;
1637
- });
1638
- for (var i = 0; i < funcsToRun.length; ++i) {
1639
- try {
1640
- var funcToRun = funcsToRun[i];
1641
- this.nowMillis = funcToRun.runAtMillis;
1642
- funcToRun.funcToCall();
1643
- if (funcToRun.recurring) {
1644
- this.scheduleFunction(funcToRun.timeoutKey,
1645
- funcToRun.funcToCall,
1646
- funcToRun.millis,
1647
- true);
1648
- }
1649
- } catch(e) {
1650
- }
1651
- }
1652
- this.runFunctionsWithinRange(oldMillis, nowMillis);
1653
- }
1654
- };
1655
-
1656
- jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
1657
- this.scheduledFunctions[timeoutKey] = {
1658
- runAtMillis: this.nowMillis + millis,
1659
- funcToCall: funcToCall,
1660
- recurring: recurring,
1661
- timeoutKey: timeoutKey,
1662
- millis: millis
1663
- };
1664
- };
1665
-
1666
- /**
1667
- * @namespace
1668
- */
1669
- jasmine.Clock = {
1670
- defaultFakeTimer: new jasmine.FakeTimer(),
1671
-
1672
- reset: function() {
1673
- jasmine.Clock.assertInstalled();
1674
- jasmine.Clock.defaultFakeTimer.reset();
1675
- },
1676
-
1677
- tick: function(millis) {
1678
- jasmine.Clock.assertInstalled();
1679
- jasmine.Clock.defaultFakeTimer.tick(millis);
1680
- },
1681
-
1682
- runFunctionsWithinRange: function(oldMillis, nowMillis) {
1683
- jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
1684
- },
1685
-
1686
- scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
1687
- jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
1688
- },
1689
-
1690
- useMock: function() {
1691
- if (!jasmine.Clock.isInstalled()) {
1692
- var spec = jasmine.getEnv().currentSpec;
1693
- spec.after(jasmine.Clock.uninstallMock);
1694
-
1695
- jasmine.Clock.installMock();
1696
- }
1697
- },
1698
-
1699
- installMock: function() {
1700
- jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
1701
- },
1702
-
1703
- uninstallMock: function() {
1704
- jasmine.Clock.assertInstalled();
1705
- jasmine.Clock.installed = jasmine.Clock.real;
1706
- },
1707
-
1708
- real: {
1709
- setTimeout: jasmine.getGlobal().setTimeout,
1710
- clearTimeout: jasmine.getGlobal().clearTimeout,
1711
- setInterval: jasmine.getGlobal().setInterval,
1712
- clearInterval: jasmine.getGlobal().clearInterval
1713
- },
1714
-
1715
- assertInstalled: function() {
1716
- if (!jasmine.Clock.isInstalled()) {
1717
- throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
1718
- }
1719
- },
1720
-
1721
- isInstalled: function() {
1722
- return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
1723
- },
1724
-
1725
- installed: null
1726
- };
1727
- jasmine.Clock.installed = jasmine.Clock.real;
1728
-
1729
- //else for IE support
1730
- jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
1731
- if (jasmine.Clock.installed.setTimeout.apply) {
1732
- return jasmine.Clock.installed.setTimeout.apply(this, arguments);
1733
- } else {
1734
- return jasmine.Clock.installed.setTimeout(funcToCall, millis);
1735
- }
1736
- };
1737
-
1738
- jasmine.getGlobal().setInterval = function(funcToCall, millis) {
1739
- if (jasmine.Clock.installed.setInterval.apply) {
1740
- return jasmine.Clock.installed.setInterval.apply(this, arguments);
1741
- } else {
1742
- return jasmine.Clock.installed.setInterval(funcToCall, millis);
1743
- }
1744
- };
1745
-
1746
- jasmine.getGlobal().clearTimeout = function(timeoutKey) {
1747
- if (jasmine.Clock.installed.clearTimeout.apply) {
1748
- return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
1749
- } else {
1750
- return jasmine.Clock.installed.clearTimeout(timeoutKey);
1751
- }
1752
- };
1753
-
1754
- jasmine.getGlobal().clearInterval = function(timeoutKey) {
1755
- if (jasmine.Clock.installed.clearTimeout.apply) {
1756
- return jasmine.Clock.installed.clearInterval.apply(this, arguments);
1757
- } else {
1758
- return jasmine.Clock.installed.clearInterval(timeoutKey);
1759
- }
1760
- };
1761
-
1762
- /**
1763
- * @constructor
1764
- */
1765
- jasmine.MultiReporter = function() {
1766
- this.subReporters_ = [];
1767
- };
1768
- jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
1769
-
1770
- jasmine.MultiReporter.prototype.addReporter = function(reporter) {
1771
- this.subReporters_.push(reporter);
1772
- };
1773
-
1774
1
  (function() {
1775
- var functionNames = [
1776
- "reportRunnerStarting",
1777
- "reportRunnerResults",
1778
- "reportSuiteResults",
1779
- "reportSpecStarting",
1780
- "reportSpecResults",
1781
- "log"
1782
- ];
1783
- for (var i = 0; i < functionNames.length; i++) {
1784
- var functionName = functionNames[i];
1785
- jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
1786
- return function() {
1787
- for (var j = 0; j < this.subReporters_.length; j++) {
1788
- var subReporter = this.subReporters_[j];
1789
- if (subReporter[functionName]) {
1790
- subReporter[functionName].apply(subReporter, arguments);
1791
- }
1792
- }
1793
- };
1794
- })(functionName);
1795
- }
1796
- })();
1797
- /**
1798
- * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
1799
- *
1800
- * @constructor
1801
- */
1802
- jasmine.NestedResults = function() {
1803
- /**
1804
- * The total count of results
1805
- */
1806
- this.totalCount = 0;
1807
- /**
1808
- * Number of passed results
1809
- */
1810
- this.passedCount = 0;
1811
- /**
1812
- * Number of failed results
1813
- */
1814
- this.failedCount = 0;
1815
- /**
1816
- * Was this suite/spec skipped?
1817
- */
1818
- this.skipped = false;
1819
- /**
1820
- * @ignore
1821
- */
1822
- this.items_ = [];
1823
- };
1824
-
1825
- /**
1826
- * Roll up the result counts.
1827
- *
1828
- * @param result
1829
- */
1830
- jasmine.NestedResults.prototype.rollupCounts = function(result) {
1831
- this.totalCount += result.totalCount;
1832
- this.passedCount += result.passedCount;
1833
- this.failedCount += result.failedCount;
1834
- };
1835
-
1836
- /**
1837
- * Adds a log message.
1838
- * @param values Array of message parts which will be concatenated later.
1839
- */
1840
- jasmine.NestedResults.prototype.log = function(values) {
1841
- this.items_.push(new jasmine.MessageResult(values));
1842
- };
1843
-
1844
- /**
1845
- * Getter for the results: message & results.
1846
- */
1847
- jasmine.NestedResults.prototype.getItems = function() {
1848
- return this.items_;
1849
- };
1850
-
1851
- /**
1852
- * Adds a result, tracking counts (total, passed, & failed)
1853
- * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
1854
- */
1855
- jasmine.NestedResults.prototype.addResult = function(result) {
1856
- if (result.type != 'log') {
1857
- if (result.items_) {
1858
- this.rollupCounts(result);
1859
- } else {
1860
- this.totalCount++;
1861
- if (result.passed()) {
1862
- this.passedCount++;
1863
- } else {
1864
- this.failedCount++;
1865
- }
1866
- }
1867
- }
1868
- this.items_.push(result);
1869
- };
1870
-
1871
- /**
1872
- * @returns {Boolean} True if <b>everything</b> below passed
1873
- */
1874
- jasmine.NestedResults.prototype.passed = function() {
1875
- return this.passedCount === this.totalCount;
1876
- };
1877
- /**
1878
- * Base class for pretty printing for expectation results.
1879
- */
1880
- jasmine.PrettyPrinter = function() {
1881
- this.ppNestLevel_ = 0;
1882
- };
1883
-
1884
- /**
1885
- * Formats a value in a nice, human-readable string.
1886
- *
1887
- * @param value
1888
- */
1889
- jasmine.PrettyPrinter.prototype.format = function(value) {
1890
- this.ppNestLevel_++;
1891
- try {
1892
- if (value === jasmine.undefined) {
1893
- this.emitScalar('undefined');
1894
- } else if (value === null) {
1895
- this.emitScalar('null');
1896
- } else if (value === jasmine.getGlobal()) {
1897
- this.emitScalar('<global>');
1898
- } else if (value.jasmineToString) {
1899
- this.emitScalar(value.jasmineToString());
1900
- } else if (typeof value === 'string') {
1901
- this.emitString(value);
1902
- } else if (jasmine.isSpy(value)) {
1903
- this.emitScalar("spy on " + value.identity);
1904
- } else if (value instanceof RegExp) {
1905
- this.emitScalar(value.toString());
1906
- } else if (typeof value === 'function') {
1907
- this.emitScalar('Function');
1908
- } else if (typeof value.nodeType === 'number') {
1909
- this.emitScalar('HTMLNode');
1910
- } else if (value instanceof Date) {
1911
- this.emitScalar('Date(' + value + ')');
1912
- } else if (value.__Jasmine_been_here_before__) {
1913
- this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');
1914
- } else if (jasmine.isArray_(value) || typeof value == 'object') {
1915
- value.__Jasmine_been_here_before__ = true;
1916
- if (jasmine.isArray_(value)) {
1917
- this.emitArray(value);
1918
- } else {
1919
- this.emitObject(value);
1920
- }
1921
- delete value.__Jasmine_been_here_before__;
1922
- } else {
1923
- this.emitScalar(value.toString());
1924
- }
1925
- } finally {
1926
- this.ppNestLevel_--;
1927
- }
1928
- };
1929
-
1930
- jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
1931
- for (var property in obj) {
1932
- if (!obj.hasOwnProperty(property)) continue;
1933
- if (property == '__Jasmine_been_here_before__') continue;
1934
- fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
1935
- obj.__lookupGetter__(property) !== null) : false);
1936
- }
1937
- };
1938
-
1939
- jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
1940
- jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
1941
- jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
1942
- jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
1943
-
1944
- jasmine.StringPrettyPrinter = function() {
1945
- jasmine.PrettyPrinter.call(this);
1946
-
1947
- this.string = '';
1948
- };
1949
- jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
1950
-
1951
- jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
1952
- this.append(value);
1953
- };
1954
-
1955
- jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
1956
- this.append("'" + value + "'");
1957
- };
1958
-
1959
- jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
1960
- if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
1961
- this.append("Array");
1962
- return;
1963
- }
1964
-
1965
- this.append('[ ');
1966
- for (var i = 0; i < array.length; i++) {
1967
- if (i > 0) {
1968
- this.append(', ');
1969
- }
1970
- this.format(array[i]);
1971
- }
1972
- this.append(' ]');
1973
- };
1974
-
1975
- jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
1976
- if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
1977
- this.append("Object");
1978
- return;
1979
- }
1980
-
1981
- var self = this;
1982
- this.append('{ ');
1983
- var first = true;
1984
-
1985
- this.iterateObject(obj, function(property, isGetter) {
1986
- if (first) {
1987
- first = false;
1988
- } else {
1989
- self.append(', ');
1990
- }
1991
-
1992
- self.append(property);
1993
- self.append(' : ');
1994
- if (isGetter) {
1995
- self.append('<getter>');
1996
- } else {
1997
- self.format(obj[property]);
1998
- }
1999
- });
2000
-
2001
- this.append(' }');
2002
- };
2003
-
2004
- jasmine.StringPrettyPrinter.prototype.append = function(value) {
2005
- this.string += value;
2006
- };
2007
- jasmine.Queue = function(env) {
2008
- this.env = env;
2009
-
2010
- // parallel to blocks. each true value in this array means the block will
2011
- // get executed even if we abort
2012
- this.ensured = [];
2013
- this.blocks = [];
2014
- this.running = false;
2015
- this.index = 0;
2016
- this.offset = 0;
2017
- this.abort = false;
2018
- };
2019
-
2020
- jasmine.Queue.prototype.addBefore = function(block, ensure) {
2021
- if (ensure === jasmine.undefined) {
2022
- ensure = false;
2023
- }
2024
-
2025
- this.blocks.unshift(block);
2026
- this.ensured.unshift(ensure);
2027
- };
2028
-
2029
- jasmine.Queue.prototype.add = function(block, ensure) {
2030
- if (ensure === jasmine.undefined) {
2031
- ensure = false;
2032
- }
2033
-
2034
- this.blocks.push(block);
2035
- this.ensured.push(ensure);
2036
- };
2037
-
2038
- jasmine.Queue.prototype.insertNext = function(block, ensure) {
2039
- if (ensure === jasmine.undefined) {
2040
- ensure = false;
2041
- }
2042
-
2043
- this.ensured.splice((this.index + this.offset + 1), 0, ensure);
2044
- this.blocks.splice((this.index + this.offset + 1), 0, block);
2045
- this.offset++;
2046
- };
2047
-
2048
- jasmine.Queue.prototype.start = function(onComplete) {
2049
- this.running = true;
2050
- this.onComplete = onComplete;
2051
- this.next_();
2052
- };
2053
-
2054
- jasmine.Queue.prototype.isRunning = function() {
2055
- return this.running;
2056
- };
2057
-
2058
- jasmine.Queue.LOOP_DONT_RECURSE = true;
2059
-
2060
- jasmine.Queue.prototype.next_ = function() {
2061
- var self = this;
2062
- var goAgain = true;
2063
-
2064
- while (goAgain) {
2065
- goAgain = false;
2066
-
2067
- if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) {
2068
- var calledSynchronously = true;
2069
- var completedSynchronously = false;
2070
-
2071
- var onComplete = function () {
2072
- if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
2073
- completedSynchronously = true;
2074
- return;
2075
- }
2076
-
2077
- if (self.blocks[self.index].abort) {
2078
- self.abort = true;
2079
- }
2080
-
2081
- self.offset = 0;
2082
- self.index++;
2083
-
2084
- var now = new Date().getTime();
2085
- if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
2086
- self.env.lastUpdate = now;
2087
- self.env.setTimeout(function() {
2088
- self.next_();
2089
- }, 0);
2090
- } else {
2091
- if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
2092
- goAgain = true;
2093
- } else {
2094
- self.next_();
2095
- }
2096
- }
2097
- };
2098
- self.blocks[self.index].execute(onComplete);
2099
-
2100
- calledSynchronously = false;
2101
- if (completedSynchronously) {
2102
- onComplete();
2103
- }
2104
-
2105
- } else {
2106
- self.running = false;
2107
- if (self.onComplete) {
2108
- self.onComplete();
2109
- }
2110
- }
2111
- }
2112
- };
2113
-
2114
- jasmine.Queue.prototype.results = function() {
2115
- var results = new jasmine.NestedResults();
2116
- for (var i = 0; i < this.blocks.length; i++) {
2117
- if (this.blocks[i].results) {
2118
- results.addResult(this.blocks[i].results());
2119
- }
2120
- }
2121
- return results;
2122
- };
2123
-
2124
-
2125
- /**
2126
- * Runner
2127
- *
2128
- * @constructor
2129
- * @param {jasmine.Env} env
2130
- */
2131
- jasmine.Runner = function(env) {
2132
- var self = this;
2133
- self.env = env;
2134
- self.queue = new jasmine.Queue(env);
2135
- self.before_ = [];
2136
- self.after_ = [];
2137
- self.suites_ = [];
2138
- };
2139
-
2140
- jasmine.Runner.prototype.execute = function() {
2141
- var self = this;
2142
- if (self.env.reporter.reportRunnerStarting) {
2143
- self.env.reporter.reportRunnerStarting(this);
2144
- }
2145
- self.queue.start(function () {
2146
- self.finishCallback();
2147
- });
2148
- };
2149
-
2150
- jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
2151
- beforeEachFunction.typeName = 'beforeEach';
2152
- this.before_.splice(0,0,beforeEachFunction);
2153
- };
2154
-
2155
- jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
2156
- afterEachFunction.typeName = 'afterEach';
2157
- this.after_.splice(0,0,afterEachFunction);
2158
- };
2159
-
2160
-
2161
- jasmine.Runner.prototype.finishCallback = function() {
2162
- this.env.reporter.reportRunnerResults(this);
2163
- };
2164
-
2165
- jasmine.Runner.prototype.addSuite = function(suite) {
2166
- this.suites_.push(suite);
2167
- };
2168
-
2169
- jasmine.Runner.prototype.add = function(block) {
2170
- if (block instanceof jasmine.Suite) {
2171
- this.addSuite(block);
2172
- }
2173
- this.queue.add(block);
2174
- };
2175
-
2176
- jasmine.Runner.prototype.specs = function () {
2177
- var suites = this.suites();
2178
- var specs = [];
2179
- for (var i = 0; i < suites.length; i++) {
2180
- specs = specs.concat(suites[i].specs());
2181
- }
2182
- return specs;
2183
- };
2184
-
2185
- jasmine.Runner.prototype.suites = function() {
2186
- return this.suites_;
2187
- };
2188
-
2189
- jasmine.Runner.prototype.topLevelSuites = function() {
2190
- var topLevelSuites = [];
2191
- for (var i = 0; i < this.suites_.length; i++) {
2192
- if (!this.suites_[i].parentSuite) {
2193
- topLevelSuites.push(this.suites_[i]);
2194
- }
2195
- }
2196
- return topLevelSuites;
2197
- };
2198
-
2199
- jasmine.Runner.prototype.results = function() {
2200
- return this.queue.results();
2201
- };
2202
- /**
2203
- * Internal representation of a Jasmine specification, or test.
2204
- *
2205
- * @constructor
2206
- * @param {jasmine.Env} env
2207
- * @param {jasmine.Suite} suite
2208
- * @param {String} description
2209
- */
2210
- jasmine.Spec = function(env, suite, description) {
2211
- if (!env) {
2212
- throw new Error('jasmine.Env() required');
2213
- }
2214
- if (!suite) {
2215
- throw new Error('jasmine.Suite() required');
2216
- }
2217
- var spec = this;
2218
- spec.id = env.nextSpecId ? env.nextSpecId() : null;
2219
- spec.env = env;
2220
- spec.suite = suite;
2221
- spec.description = description;
2222
- spec.queue = new jasmine.Queue(env);
2223
-
2224
- spec.afterCallbacks = [];
2225
- spec.spies_ = [];
2226
-
2227
- spec.results_ = new jasmine.NestedResults();
2228
- spec.results_.description = description;
2229
- spec.matchersClass = null;
2230
- };
2231
-
2232
- jasmine.Spec.prototype.getFullName = function() {
2233
- return this.suite.getFullName() + ' ' + this.description + '.';
2234
- };
2235
-
2236
-
2237
- jasmine.Spec.prototype.results = function() {
2238
- return this.results_;
2239
- };
2240
-
2241
- /**
2242
- * All parameters are pretty-printed and concatenated together, then written to the spec's output.
2243
- *
2244
- * Be careful not to leave calls to <code>jasmine.log</code> in production code.
2245
- */
2246
- jasmine.Spec.prototype.log = function() {
2247
- return this.results_.log(arguments);
2248
- };
2249
-
2250
- jasmine.Spec.prototype.runs = function (func) {
2251
- var block = new jasmine.Block(this.env, func, this);
2252
- this.addToQueue(block);
2253
- return this;
2254
- };
2255
-
2256
- jasmine.Spec.prototype.addToQueue = function (block) {
2257
- if (this.queue.isRunning()) {
2258
- this.queue.insertNext(block);
2259
- } else {
2260
- this.queue.add(block);
2261
- }
2262
- };
2263
-
2264
- /**
2265
- * @param {jasmine.ExpectationResult} result
2266
- */
2267
- jasmine.Spec.prototype.addMatcherResult = function(result) {
2268
- this.results_.addResult(result);
2269
- };
2270
-
2271
- jasmine.Spec.prototype.expect = function(actual) {
2272
- var positive = new (this.getMatchersClass_())(this.env, actual, this);
2273
- positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
2274
- return positive;
2275
- };
2276
-
2277
- /**
2278
- * Waits a fixed time period before moving to the next block.
2279
- *
2280
- * @deprecated Use waitsFor() instead
2281
- * @param {Number} timeout milliseconds to wait
2282
- */
2283
- jasmine.Spec.prototype.waits = function(timeout) {
2284
- var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
2285
- this.addToQueue(waitsFunc);
2286
- return this;
2287
- };
2288
-
2289
- /**
2290
- * Waits for the latchFunction to return true before proceeding to the next block.
2291
- *
2292
- * @param {Function} latchFunction
2293
- * @param {String} optional_timeoutMessage
2294
- * @param {Number} optional_timeout
2295
- */
2296
- jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
2297
- var latchFunction_ = null;
2298
- var optional_timeoutMessage_ = null;
2299
- var optional_timeout_ = null;
2300
-
2301
- for (var i = 0; i < arguments.length; i++) {
2302
- var arg = arguments[i];
2303
- switch (typeof arg) {
2304
- case 'function':
2305
- latchFunction_ = arg;
2306
- break;
2307
- case 'string':
2308
- optional_timeoutMessage_ = arg;
2309
- break;
2310
- case 'number':
2311
- optional_timeout_ = arg;
2312
- break;
2313
- }
2314
- }
2315
-
2316
- var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
2317
- this.addToQueue(waitsForFunc);
2318
- return this;
2319
- };
2320
-
2321
- jasmine.Spec.prototype.fail = function (e) {
2322
- var expectationResult = new jasmine.ExpectationResult({
2323
- passed: false,
2324
- message: e ? jasmine.util.formatException(e) : 'Exception',
2325
- trace: { stack: e.stack }
2326
- });
2327
- this.results_.addResult(expectationResult);
2328
- };
2329
-
2330
- jasmine.Spec.prototype.getMatchersClass_ = function() {
2331
- return this.matchersClass || this.env.matchersClass;
2332
- };
2333
-
2334
- jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
2335
- var parent = this.getMatchersClass_();
2336
- var newMatchersClass = function() {
2337
- parent.apply(this, arguments);
2338
- };
2339
- jasmine.util.inherit(newMatchersClass, parent);
2340
- jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
2341
- this.matchersClass = newMatchersClass;
2342
- };
2343
-
2344
- jasmine.Spec.prototype.finishCallback = function() {
2345
- this.env.reporter.reportSpecResults(this);
2346
- };
2347
-
2348
- jasmine.Spec.prototype.finish = function(onComplete) {
2349
- this.removeAllSpies();
2350
- this.finishCallback();
2351
- if (onComplete) {
2352
- onComplete();
2353
- }
2354
- };
2355
-
2356
- jasmine.Spec.prototype.after = function(doAfter) {
2357
- if (this.queue.isRunning()) {
2358
- this.queue.add(new jasmine.Block(this.env, doAfter, this), true);
2359
- } else {
2360
- this.afterCallbacks.unshift(doAfter);
2361
- }
2362
- };
2363
-
2364
- jasmine.Spec.prototype.execute = function(onComplete) {
2365
- var spec = this;
2366
- if (!spec.env.specFilter(spec)) {
2367
- spec.results_.skipped = true;
2368
- spec.finish(onComplete);
2369
- return;
2370
- }
2371
-
2372
- this.env.reporter.reportSpecStarting(this);
2373
-
2374
- spec.env.currentSpec = spec;
2375
-
2376
- spec.addBeforesAndAftersToQueue();
2377
-
2378
- spec.queue.start(function () {
2379
- spec.finish(onComplete);
2380
- });
2381
- };
2382
-
2383
- jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
2384
- var runner = this.env.currentRunner();
2385
- var i;
2386
-
2387
- for (var suite = this.suite; suite; suite = suite.parentSuite) {
2388
- for (i = 0; i < suite.before_.length; i++) {
2389
- this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
2390
- }
2391
- }
2392
- for (i = 0; i < runner.before_.length; i++) {
2393
- this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
2394
- }
2395
- for (i = 0; i < this.afterCallbacks.length; i++) {
2396
- this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true);
2397
- }
2398
- for (suite = this.suite; suite; suite = suite.parentSuite) {
2399
- for (i = 0; i < suite.after_.length; i++) {
2400
- this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true);
2401
- }
2402
- }
2403
- for (i = 0; i < runner.after_.length; i++) {
2404
- this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true);
2405
- }
2406
- };
2407
-
2408
- jasmine.Spec.prototype.explodes = function() {
2409
- throw 'explodes function should not have been called';
2410
- };
2411
-
2412
- jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
2413
- if (obj == jasmine.undefined) {
2414
- throw "spyOn could not find an object to spy upon for " + methodName + "()";
2415
- }
2416
-
2417
- if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
2418
- throw methodName + '() method does not exist';
2419
- }
2420
-
2421
- if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
2422
- throw new Error(methodName + ' has already been spied upon');
2423
- }
2424
-
2425
- var spyObj = jasmine.createSpy(methodName);
2426
-
2427
- this.spies_.push(spyObj);
2428
- spyObj.baseObj = obj;
2429
- spyObj.methodName = methodName;
2430
- spyObj.originalValue = obj[methodName];
2431
-
2432
- obj[methodName] = spyObj;
2433
-
2434
- return spyObj;
2435
- };
2436
-
2437
- jasmine.Spec.prototype.removeAllSpies = function() {
2438
- for (var i = 0; i < this.spies_.length; i++) {
2439
- var spy = this.spies_[i];
2440
- spy.baseObj[spy.methodName] = spy.originalValue;
2441
- }
2442
- this.spies_ = [];
2443
- };
2444
-
2445
- /**
2446
- * Internal representation of a Jasmine suite.
2447
- *
2448
- * @constructor
2449
- * @param {jasmine.Env} env
2450
- * @param {String} description
2451
- * @param {Function} specDefinitions
2452
- * @param {jasmine.Suite} parentSuite
2453
- */
2454
- jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
2455
- var self = this;
2456
- self.id = env.nextSuiteId ? env.nextSuiteId() : null;
2457
- self.description = description;
2458
- self.queue = new jasmine.Queue(env);
2459
- self.parentSuite = parentSuite;
2460
- self.env = env;
2461
- self.before_ = [];
2462
- self.after_ = [];
2463
- self.children_ = [];
2464
- self.suites_ = [];
2465
- self.specs_ = [];
2466
- };
2467
-
2468
- jasmine.Suite.prototype.getFullName = function() {
2469
- var fullName = this.description;
2470
- for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
2471
- fullName = parentSuite.description + ' ' + fullName;
2472
- }
2473
- return fullName;
2474
- };
2475
-
2476
- jasmine.Suite.prototype.finish = function(onComplete) {
2477
- this.env.reporter.reportSuiteResults(this);
2478
- this.finished = true;
2479
- if (typeof(onComplete) == 'function') {
2480
- onComplete();
2481
- }
2482
- };
2483
-
2484
- jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
2485
- beforeEachFunction.typeName = 'beforeEach';
2486
- this.before_.unshift(beforeEachFunction);
2487
- };
2488
-
2489
- jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
2490
- afterEachFunction.typeName = 'afterEach';
2491
- this.after_.unshift(afterEachFunction);
2492
- };
2493
-
2494
- jasmine.Suite.prototype.results = function() {
2495
- return this.queue.results();
2496
- };
2497
-
2498
- jasmine.Suite.prototype.add = function(suiteOrSpec) {
2499
- this.children_.push(suiteOrSpec);
2500
- if (suiteOrSpec instanceof jasmine.Suite) {
2501
- this.suites_.push(suiteOrSpec);
2502
- this.env.currentRunner().addSuite(suiteOrSpec);
2503
- } else {
2504
- this.specs_.push(suiteOrSpec);
2505
- }
2506
- this.queue.add(suiteOrSpec);
2507
- };
2508
-
2509
- jasmine.Suite.prototype.specs = function() {
2510
- return this.specs_;
2511
- };
2512
-
2513
- jasmine.Suite.prototype.suites = function() {
2514
- return this.suites_;
2515
- };
2516
-
2517
- jasmine.Suite.prototype.children = function() {
2518
- return this.children_;
2519
- };
2520
-
2521
- jasmine.Suite.prototype.execute = function(onComplete) {
2522
- var self = this;
2523
- this.queue.start(function () {
2524
- self.finish(onComplete);
2525
- });
2526
- };
2527
- jasmine.WaitsBlock = function(env, timeout, spec) {
2528
- this.timeout = timeout;
2529
- jasmine.Block.call(this, env, null, spec);
2530
- };
2531
-
2532
- jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
2533
-
2534
- jasmine.WaitsBlock.prototype.execute = function (onComplete) {
2535
- if (jasmine.VERBOSE) {
2536
- this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
2537
- }
2538
- this.env.setTimeout(function () {
2539
- onComplete();
2540
- }, this.timeout);
2541
- };
2542
- /**
2543
- * A block which waits for some condition to become true, with timeout.
2544
- *
2545
- * @constructor
2546
- * @extends jasmine.Block
2547
- * @param {jasmine.Env} env The Jasmine environment.
2548
- * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
2549
- * @param {Function} latchFunction A function which returns true when the desired condition has been met.
2550
- * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
2551
- * @param {jasmine.Spec} spec The Jasmine spec.
2552
- */
2553
- jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
2554
- this.timeout = timeout || env.defaultTimeoutInterval;
2555
- this.latchFunction = latchFunction;
2556
- this.message = message;
2557
- this.totalTimeSpentWaitingForLatch = 0;
2558
- jasmine.Block.call(this, env, null, spec);
2559
- };
2560
- jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
2561
-
2562
- jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
2563
-
2564
- jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
2565
- if (jasmine.VERBOSE) {
2566
- this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
2567
- }
2568
- var latchFunctionResult;
2569
- try {
2570
- latchFunctionResult = this.latchFunction.apply(this.spec);
2571
- } catch (e) {
2572
- this.spec.fail(e);
2573
- onComplete();
2574
- return;
2575
- }
2576
-
2577
- if (latchFunctionResult) {
2578
- onComplete();
2579
- } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
2580
- var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
2581
- this.spec.fail({
2582
- name: 'timeout',
2583
- message: message
2584
- });
2
+ var __hasProp = {}.hasOwnProperty,
3
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
2585
4
 
2586
- this.abort = true;
2587
- onComplete();
2588
- } else {
2589
- this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
2590
- var self = this;
2591
- this.env.setTimeout(function() {
2592
- self.execute(onComplete);
2593
- }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
2594
- }
2595
- };
2596
-
2597
- jasmine.version_= {
2598
- "major": 1,
2599
- "minor": 3,
2600
- "build": 1,
2601
- "revision": 1354556913
2602
- };
2603
- (function() {
2604
5
  this.Teaspoon = (function() {
2605
6
  function Teaspoon() {}
2606
7
 
@@ -2608,7 +9,7 @@ jasmine.version_= {
2608
9
 
2609
10
  Teaspoon.slow = 75;
2610
11
 
2611
- Teaspoon.root = null;
12
+ Teaspoon.root = window.location.pathname.replace(/\/+(index\.html)?$/, "").replace(/\/[^\/]*$/, "");
2612
13
 
2613
14
  Teaspoon.started = false;
2614
15
 
@@ -2697,6 +98,18 @@ jasmine.version_= {
2697
98
 
2698
99
  })();
2699
100
 
101
+ Teaspoon.Error = (function(_super) {
102
+ __extends(Error, _super);
103
+
104
+ function Error(message) {
105
+ this.name = "TeaspoonError";
106
+ this.message = message || "";
107
+ }
108
+
109
+ return Error;
110
+
111
+ })(Error);
112
+
2700
113
  }).call(this);
2701
114
  (function() {
2702
115
  Teaspoon.Runner = (function() {
@@ -2714,7 +127,6 @@ jasmine.version_= {
2714
127
 
2715
128
  Runner.prototype.getParams = function() {
2716
129
  var name, param, params, value, _i, _len, _ref, _ref1;
2717
-
2718
130
  params = {};
2719
131
  _ref = Teaspoon.location.search.substring(1).split("&");
2720
132
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -2761,7 +173,6 @@ jasmine.version_= {
2761
173
 
2762
174
  fixture.preload = function() {
2763
175
  var url, urls, _i, _len, _results;
2764
-
2765
176
  urls = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
2766
177
  _results = [];
2767
178
  for (_i = 0, _len = urls.length; _i < _len; _i++) {
@@ -2773,7 +184,6 @@ jasmine.version_= {
2773
184
 
2774
185
  fixture.load = function() {
2775
186
  var append, index, url, urls, _i, _j, _len, _results;
2776
-
2777
187
  urls = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), append = arguments[_i++];
2778
188
  if (append == null) {
2779
189
  append = false;
@@ -2792,7 +202,6 @@ jasmine.version_= {
2792
202
 
2793
203
  fixture.set = function() {
2794
204
  var append, html, htmls, index, _i, _j, _len, _results;
2795
-
2796
205
  htmls = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), append = arguments[_i++];
2797
206
  if (append == null) {
2798
207
  append = false;
@@ -2825,7 +234,6 @@ jasmine.version_= {
2825
234
 
2826
235
  load = function(url, append, preload) {
2827
236
  var cached, value;
2828
-
2829
237
  if (preload == null) {
2830
238
  preload = false;
2831
239
  }
@@ -2887,7 +295,6 @@ jasmine.version_= {
2887
295
 
2888
296
  create = function() {
2889
297
  var _ref;
2890
-
2891
298
  Teaspoon.fixture.el = document.createElement("div");
2892
299
  if (typeof window.$ === 'function') {
2893
300
  Teaspoon.fixture.$el = $(Teaspoon.fixture.el);
@@ -2898,7 +305,6 @@ jasmine.version_= {
2898
305
 
2899
306
  cleanup = function() {
2900
307
  var _base, _ref, _ref1;
2901
-
2902
308
  (_base = Teaspoon.fixture).el || (_base.el = document.getElementById("teaspoon-fixtures"));
2903
309
  if ((_ref = Teaspoon.fixture.el) != null) {
2904
310
  if ((_ref1 = _ref.parentNode) != null) {
@@ -2910,7 +316,6 @@ jasmine.version_= {
2910
316
 
2911
317
  xhrRequest = function(url, callback) {
2912
318
  var e;
2913
-
2914
319
  if (window.XMLHttpRequest) {
2915
320
  xhr = new XMLHttpRequest();
2916
321
  } else if (window.ActiveXObject) {
@@ -2937,6 +342,47 @@ jasmine.version_= {
2937
342
 
2938
343
  }).call(this);
2939
344
 
345
+ }).call(this);
346
+ (function() {
347
+ Teaspoon.hook = function(name, options) {
348
+ var xhr, xhrRequest;
349
+ if (options == null) {
350
+ options = {};
351
+ }
352
+ xhr = null;
353
+ xhrRequest = function(url, options, callback) {
354
+ var e;
355
+ if (window.XMLHttpRequest) {
356
+ xhr = new XMLHttpRequest();
357
+ } else if (window.ActiveXObject) {
358
+ try {
359
+ xhr = new ActiveXObject("Msxml2.XMLHTTP");
360
+ } catch (_error) {
361
+ e = _error;
362
+ try {
363
+ xhr = new ActiveXObject("Microsoft.XMLHTTP");
364
+ } catch (_error) {
365
+ e = _error;
366
+ }
367
+ }
368
+ }
369
+ if (!xhr) {
370
+ throw "Unable to make Ajax Request";
371
+ }
372
+ xhr.onreadystatechange = callback;
373
+ xhr.open(options['method'] || "GET", "" + Teaspoon.root + "/" + url, false);
374
+ return xhr.send(options['payload']);
375
+ };
376
+ return xhrRequest("" + Teaspoon.suites.active + "/" + name, options, function() {
377
+ if (xhr.readyState !== 4) {
378
+ return;
379
+ }
380
+ if (xhr.status !== 200) {
381
+ throw "Unable to call hook \"" + url + "\".";
382
+ }
383
+ });
384
+ };
385
+
2940
386
  }).call(this);
2941
387
  (function() {
2942
388
  Teaspoon.Reporters.BaseView = (function() {
@@ -2959,7 +405,6 @@ jasmine.version_= {
2959
405
 
2960
406
  BaseView.prototype.createEl = function(type, className) {
2961
407
  var el;
2962
-
2963
408
  if (className == null) {
2964
409
  className = "";
2965
410
  }
@@ -2970,21 +415,18 @@ jasmine.version_= {
2970
415
 
2971
416
  BaseView.prototype.findEl = function(id) {
2972
417
  var _base;
2973
-
2974
418
  this.elements || (this.elements = {});
2975
419
  return (_base = this.elements)[id] || (_base[id] = document.getElementById("teaspoon-" + id));
2976
420
  };
2977
421
 
2978
422
  BaseView.prototype.setText = function(id, value) {
2979
423
  var el;
2980
-
2981
424
  el = this.findEl(id);
2982
425
  return el.innerHTML = value;
2983
426
  };
2984
427
 
2985
428
  BaseView.prototype.setHtml = function(id, value, add) {
2986
429
  var el;
2987
-
2988
430
  if (add == null) {
2989
431
  add = false;
2990
432
  }
@@ -2998,14 +440,12 @@ jasmine.version_= {
2998
440
 
2999
441
  BaseView.prototype.setClass = function(id, value) {
3000
442
  var el;
3001
-
3002
443
  el = this.findEl(id);
3003
444
  return el.className = value;
3004
445
  };
3005
446
 
3006
447
  BaseView.prototype.htmlSafe = function(str) {
3007
448
  var el;
3008
-
3009
449
  el = document.createElement("div");
3010
450
  el.appendChild(document.createTextNode(str));
3011
451
  return el.innerHTML;
@@ -3025,6 +465,7 @@ jasmine.version_= {
3025
465
  __extends(HTML, _super);
3026
466
 
3027
467
  function HTML() {
468
+ this.changeSuite = __bind(this.changeSuite, this);
3028
469
  this.toggleConfig = __bind(this.toggleConfig, this);
3029
470
  this.reportRunnerResults = __bind(this.reportRunnerResults, this);
3030
471
  this.start = new Teaspoon.Date().getTime();
@@ -3060,7 +501,6 @@ jasmine.version_= {
3060
501
  if ((_ref = this.findEl("suite-select")) != null) {
3061
502
  _ref.onchange = this.changeSuite;
3062
503
  }
3063
- this.findEl("root-link").href = Teaspoon.root;
3064
504
  this.el = this.findEl("report-all");
3065
505
  this.showConfiguration();
3066
506
  this.buildProgress();
@@ -3071,20 +511,26 @@ jasmine.version_= {
3071
511
  var el;
3072
512
  el = this.createEl("div");
3073
513
  el.id = "teaspoon-interface";
3074
- el.innerHTML = Teaspoon.Reporters.HTML.template;
514
+ el.innerHTML = Teaspoon.Reporters.HTML.template();
3075
515
  return document.body.appendChild(el);
3076
516
  };
3077
517
 
3078
518
  HTML.prototype.buildSuiteSelect = function() {
3079
- var options, suite, _i, _len, _ref;
519
+ var filename, options, path, selected, suite, _i, _len, _ref;
3080
520
  if (Teaspoon.suites.all.length === 1) {
3081
521
  return "";
3082
522
  }
523
+ filename = "";
524
+ if (/index\.html$/.test(window.location.pathname)) {
525
+ filename = "/index.html";
526
+ }
3083
527
  options = [];
3084
528
  _ref = Teaspoon.suites.all;
3085
529
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3086
530
  suite = _ref[_i];
3087
- options.push("<option" + (Teaspoon.suites.active === suite ? " selected='selected'" : "") + " value=\"" + suite + "\">" + suite + "</option>");
531
+ path = [Teaspoon.root, suite].join("/");
532
+ selected = Teaspoon.suites.active === suite ? " selected" : "";
533
+ options.push("<option" + selected + " value=\"" + path + filename + "\">" + suite + "</option>");
3088
534
  }
3089
535
  return "<select id=\"teaspoon-suite-select\">" + (options.join("")) + "</select>";
3090
536
  };
@@ -3195,19 +641,17 @@ jasmine.version_= {
3195
641
  };
3196
642
 
3197
643
  HTML.prototype.setFilters = function() {
3198
- var link;
3199
- link = [Teaspoon.root, Teaspoon.suites.active].join('/');
3200
644
  if (Teaspoon.params["file"]) {
3201
- this.filters.push("by file: " + Teaspoon.params["file"] + " <a href='" + link + "'>remove</a>");
645
+ this.filters.push("by file: " + Teaspoon.params["file"]);
3202
646
  }
3203
647
  if (Teaspoon.params["grep"]) {
3204
- return this.filters.push("by match: " + Teaspoon.params["grep"] + " <a href='" + link + "'>remove</a>");
648
+ return this.filters.push("by match: " + Teaspoon.params["grep"]);
3205
649
  }
3206
650
  };
3207
651
 
3208
652
  HTML.prototype.readConfig = function() {
3209
653
  var config;
3210
- if (config = this.cookie("teaspoon")) {
654
+ if (config = this.store("teaspoon")) {
3211
655
  return this.config = config;
3212
656
  }
3213
657
  };
@@ -3220,16 +664,23 @@ jasmine.version_= {
3220
664
  }
3221
665
  name = button.getAttribute("id").replace(/^teaspoon-/, "");
3222
666
  this.config[name] = !this.config[name];
3223
- this.cookie("teaspoon", this.config);
3224
- return this.refresh();
667
+ this.store("teaspoon", this.config);
668
+ return Teaspoon.reload();
3225
669
  };
3226
670
 
3227
- HTML.prototype.changeSuite = function() {
3228
- return window.location.href = [Teaspoon.root, this.options[this.options.selectedIndex].value].join('/');
671
+ HTML.prototype.changeSuite = function(e) {
672
+ var options;
673
+ options = e.target.options;
674
+ return window.location.href = options[options.selectedIndex].value;
3229
675
  };
3230
676
 
3231
- HTML.prototype.refresh = function() {
3232
- return window.location.href = window.location.href;
677
+ HTML.prototype.store = function(name, value) {
678
+ var _ref;
679
+ if (((_ref = window.localStorage) != null ? _ref.setItem : void 0) != null) {
680
+ return this.localstore(name, value);
681
+ } else {
682
+ return this.cookie(name, value);
683
+ }
3233
684
  };
3234
685
 
3235
686
  HTML.prototype.cookie = function(name, value) {
@@ -3248,6 +699,17 @@ jasmine.version_= {
3248
699
  }
3249
700
  };
3250
701
 
702
+ HTML.prototype.localstore = function(name, value) {
703
+ if (value == null) {
704
+ value = void 0;
705
+ }
706
+ if (value === void 0) {
707
+ return JSON.parse(unescape(localStorage.getItem(name)));
708
+ } else {
709
+ return localStorage.setItem(name, escape(JSON.stringify(value)));
710
+ }
711
+ };
712
+
3251
713
  return HTML;
3252
714
 
3253
715
  })(Teaspoon.Reporters.BaseView);
@@ -3281,7 +743,7 @@ jasmine.version_= {
3281
743
  };
3282
744
 
3283
745
  ProgressView.prototype.build = function() {
3284
- return this.el = this.createEl("div", "teaspoon-indicator modeset-logo");
746
+ return this.el = this.createEl("div", "teaspoon-indicator teaspoon-logo");
3285
747
  };
3286
748
 
3287
749
  ProgressView.prototype.update = function() {};
@@ -3305,7 +767,6 @@ jasmine.version_= {
3305
767
 
3306
768
  SimpleProgressView.prototype.update = function(total, run) {
3307
769
  var percent;
3308
-
3309
770
  percent = total ? Math.ceil((run * 100) / total) : 0;
3310
771
  return this.setHtml("progress-percent", "" + percent + "%");
3311
772
  };
@@ -3331,7 +792,6 @@ jasmine.version_= {
3331
792
 
3332
793
  RadialProgressView.prototype.appendTo = function() {
3333
794
  var canvas, e;
3334
-
3335
795
  RadialProgressView.__super__.appendTo.apply(this, arguments);
3336
796
  this.size = 80;
3337
797
  try {
@@ -3347,7 +807,6 @@ jasmine.version_= {
3347
807
 
3348
808
  RadialProgressView.prototype.update = function(total, run) {
3349
809
  var half, percent;
3350
-
3351
810
  percent = total ? Math.ceil((run * 100) / total) : 0;
3352
811
  this.setHtml("progress-percent", "" + percent + "%");
3353
812
  if (!this.ctx) {
@@ -3539,7 +998,9 @@ jasmine.version_= {
3539
998
 
3540
999
  }).call(this);
3541
1000
  (function() {
3542
- Teaspoon.Reporters.HTML.template = "<div class=\"teaspoon-clearfix\">\n <div id=\"teaspoon-title\">\n <h1><a href=\"\" id=\"teaspoon-root-link\">Teaspoon</a></h1>\n <ul>\n <li>version: <b id=\"teaspoon-version\"></b></li>\n <li id=\"teaspoon-env-info\"></li>\n </ul>\n </div>\n <div id=\"teaspoon-progress\"></div>\n <ul id=\"teaspoon-stats\">\n <li>passes: <b id=\"teaspoon-stats-passes\">0</b></li>\n <li>failures: <b id=\"teaspoon-stats-failures\">0</b></li>\n <li>skipped: <b id=\"teaspoon-stats-skipped\">0</b></li>\n <li>duration: <b id=\"teaspoon-stats-duration\">&infin;</b></li>\n </ul>\n</div>\n\n<div id=\"teaspoon-controls\" class=\"teaspoon-clearfix\">\n <div id=\"teaspoon-toggles\">\n <button id=\"teaspoon-use-catch\" title=\"Toggle using try/catch wrappers when possible\">Try/Catch</button>\n <button id=\"teaspoon-build-full-report\" title=\"Toggle building the full report\">Full Report</button>\n <button id=\"teaspoon-display-progress\" title=\"Toggle displaying progress as tests run\">Progress</button>\n </div>\n <div id=\"teaspoon-suites\"></div>\n</div>\n\n<hr/>\n\n<div id=\"teaspoon-filter\">\n <h1>Filtering</h1>\n <ul id=\"teaspoon-filter-list\"></ul>\n</div>\n\n<div id=\"teaspoon-report\">\n <ol id=\"teaspoon-report-failures\"></ol>\n <ol id=\"teaspoon-report-all\"></ol>\n</div>";
1001
+ Teaspoon.Reporters.HTML.template = function() {
1002
+ return "<div class=\"teaspoon-clearfix\">\n <div id=\"teaspoon-title\">\n <h1><a href=\"" + Teaspoon.root + "\" id=\"teaspoon-root-link\">Teaspoon</a></h1>\n <ul>\n <li>version: <b id=\"teaspoon-version\"></b></li>\n <li id=\"teaspoon-env-info\"></li>\n </ul>\n </div>\n <div id=\"teaspoon-progress\"></div>\n <ul id=\"teaspoon-stats\">\n <li>passes: <b id=\"teaspoon-stats-passes\">0</b></li>\n <li>failures: <b id=\"teaspoon-stats-failures\">0</b></li>\n <li>skipped: <b id=\"teaspoon-stats-skipped\">0</b></li>\n <li>duration: <b id=\"teaspoon-stats-duration\">&infin;</b></li>\n </ul>\n</div>\n\n<div id=\"teaspoon-controls\" class=\"teaspoon-clearfix\">\n <div id=\"teaspoon-toggles\">\n <button id=\"teaspoon-use-catch\" title=\"Toggle using try/catch wrappers when possible\">Try/Catch</button>\n <button id=\"teaspoon-build-full-report\" title=\"Toggle building the full report\">Full Report</button>\n <button id=\"teaspoon-display-progress\" title=\"Toggle displaying progress as tests run\">Progress</button>\n </div>\n <div id=\"teaspoon-suites\"></div>\n</div>\n\n<hr/>\n\n<div id=\"teaspoon-filter\">\n <h1>Applied Filters [<a href=\"" + window.location.pathname + "\" id=\"teaspoon-filter-clear\">remove</a>]</h1>\n <ul id=\"teaspoon-filter-list\"></ul>\n</div>\n\n<div id=\"teaspoon-report\">\n <ol id=\"teaspoon-report-failures\"></ol>\n <ol id=\"teaspoon-report-all\"></ol>\n</div>";
1003
+ };
3543
1004
 
3544
1005
  }).call(this);
3545
1006
  (function() {
@@ -3547,7 +1008,8 @@ jasmine.version_= {
3547
1008
 
3548
1009
  Teaspoon.Reporters.Console = (function() {
3549
1010
  function Console() {
3550
- this.reportRunnerResults = __bind(this.reportRunnerResults, this); this.start = new Teaspoon.Date();
1011
+ this.reportRunnerResults = __bind(this.reportRunnerResults, this);
1012
+ this.start = new Teaspoon.Date();
3551
1013
  this.suites = {};
3552
1014
  }
3553
1015
 
@@ -3561,7 +1023,6 @@ jasmine.version_= {
3561
1023
 
3562
1024
  Console.prototype.reportSuites = function() {
3563
1025
  var index, suite, _i, _len, _ref, _results;
3564
-
3565
1026
  _ref = this.spec.getParents();
3566
1027
  _results = [];
3567
1028
  for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
@@ -3581,7 +1042,6 @@ jasmine.version_= {
3581
1042
 
3582
1043
  Console.prototype.reportSpecResults = function(spec) {
3583
1044
  var result;
3584
-
3585
1045
  this.spec = new Teaspoon.Spec(spec);
3586
1046
  result = this.spec.result();
3587
1047
  if (result.skipped) {
@@ -3606,7 +1066,6 @@ jasmine.version_= {
3606
1066
 
3607
1067
  Console.prototype.trackPending = function() {
3608
1068
  var result;
3609
-
3610
1069
  result = this.spec.result();
3611
1070
  return this.log({
3612
1071
  type: "spec",
@@ -3619,7 +1078,6 @@ jasmine.version_= {
3619
1078
 
3620
1079
  Console.prototype.trackFailure = function() {
3621
1080
  var error, result, _i, _len, _ref, _results;
3622
-
3623
1081
  result = this.spec.result();
3624
1082
  _ref = this.spec.errors();
3625
1083
  _results = [];
@@ -3681,7 +1139,6 @@ jasmine.version_= {
3681
1139
 
3682
1140
  HTML.prototype.envInfo = function() {
3683
1141
  var ver, verString;
3684
-
3685
1142
  ver = jasmine.getEnv().version();
3686
1143
  verString = [ver.major, ver.minor, ver.build].join(".");
3687
1144
  return "jasmine " + verString + " revision " + ver.revision;
@@ -3697,6 +1154,10 @@ jasmine.version_= {
3697
1154
  __hasProp = {}.hasOwnProperty,
3698
1155
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
3699
1156
 
1157
+ if (typeof jasmine === "undefined" || jasmine === null) {
1158
+ throw new Teaspoon.Error('Jasmine not found -- use `suite.use_framework :jasmine` and adjust or remove the `suite.javascripts` directive.');
1159
+ }
1160
+
3700
1161
  Teaspoon.Runner = (function(_super) {
3701
1162
  __extends(Runner, _super);
3702
1163