js-test-driver-rails 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/Gemfile +2 -1
  2. data/README +40 -0
  3. data/Rakefile +1 -0
  4. data/VERSION +1 -1
  5. data/lib/js_test_driver.rb +5 -1
  6. data/lib/js_test_driver/config.rb +84 -7
  7. data/lib/js_test_driver/html_fixture.rb +40 -0
  8. data/lib/js_test_driver/runner.rb +21 -3
  9. data/test/fixtures/a.html +1 -0
  10. data/test/fixtures/b.html +1 -0
  11. data/test/fixtures/baz/a.html +1 -0
  12. data/test/fixtures/c.html +1 -0
  13. data/test/fixtures/foo/a.html +1 -0
  14. data/test/fixtures/foo/bar/a.html +1 -0
  15. data/test/fixtures/hello.txt +1 -0
  16. data/test/test_helper.rb +19 -0
  17. data/test/unit/config_test.rb +75 -2
  18. data/test/unit/html_fixture_test.rb +70 -0
  19. data/vendor/VERSIONS +3 -0
  20. data/vendor/jasmine-jstd-adapter/MIT.LICENSE +22 -0
  21. data/vendor/jasmine-jstd-adapter/README.md +25 -0
  22. data/vendor/jasmine-jstd-adapter/jsTestDriver.conf +6 -0
  23. data/vendor/jasmine-jstd-adapter/lib/jasmine/jasmine-0.11.1.js +2343 -0
  24. data/vendor/jasmine-jstd-adapter/lib/jstestdriver/JsTestDriver.jar +0 -0
  25. data/vendor/jasmine-jstd-adapter/server.sh +1 -0
  26. data/vendor/jasmine-jstd-adapter/src-test/tests.js +89 -0
  27. data/vendor/jasmine-jstd-adapter/src/JasmineAdapter.js +111 -0
  28. data/vendor/jasmine-jstd-adapter/test.sh +1 -0
  29. data/vendor/jasmine/Gemfile +6 -0
  30. data/vendor/jasmine/MIT.LICENSE +20 -0
  31. data/vendor/jasmine/README.markdown +28 -0
  32. data/vendor/jasmine/Rakefile +178 -0
  33. data/vendor/jasmine/cruise_config.rb +21 -0
  34. data/vendor/jasmine/example/SpecRunner.html +27 -0
  35. data/vendor/jasmine/example/spec/PlayerSpec.js +58 -0
  36. data/vendor/jasmine/example/spec/SpecHelper.js +9 -0
  37. data/vendor/jasmine/example/src/Player.js +22 -0
  38. data/vendor/jasmine/example/src/Song.js +7 -0
  39. data/vendor/jasmine/images/fail-16.png +0 -0
  40. data/vendor/jasmine/images/fail.png +0 -0
  41. data/vendor/jasmine/images/go-16.png +0 -0
  42. data/vendor/jasmine/images/go.png +0 -0
  43. data/vendor/jasmine/images/pending-16.png +0 -0
  44. data/vendor/jasmine/images/pending.png +0 -0
  45. data/vendor/jasmine/images/question-bk.png +0 -0
  46. data/vendor/jasmine/images/questionbk-16.png +0 -0
  47. data/vendor/jasmine/images/spinner.gif +0 -0
  48. data/vendor/jasmine/lib/jasmine-html.js +182 -0
  49. data/vendor/jasmine/lib/jasmine.css +166 -0
  50. data/vendor/jasmine/lib/jasmine.js +2421 -0
  51. data/vendor/jasmine/lib/json2.js +478 -0
  52. data/vendor/jasmine/spec/runner.html +80 -0
  53. data/vendor/jasmine/spec/suites/BaseSpec.js +27 -0
  54. data/vendor/jasmine/spec/suites/CustomMatchersSpec.js +97 -0
  55. data/vendor/jasmine/spec/suites/EnvSpec.js +158 -0
  56. data/vendor/jasmine/spec/suites/ExceptionsSpec.js +107 -0
  57. data/vendor/jasmine/spec/suites/JsApiReporterSpec.js +103 -0
  58. data/vendor/jasmine/spec/suites/MatchersSpec.js +795 -0
  59. data/vendor/jasmine/spec/suites/MockClockSpec.js +38 -0
  60. data/vendor/jasmine/spec/suites/MultiReporterSpec.js +45 -0
  61. data/vendor/jasmine/spec/suites/NestedResultsSpec.js +54 -0
  62. data/vendor/jasmine/spec/suites/PrettyPrintSpec.js +93 -0
  63. data/vendor/jasmine/spec/suites/QueueSpec.js +23 -0
  64. data/vendor/jasmine/spec/suites/ReporterSpec.js +56 -0
  65. data/vendor/jasmine/spec/suites/RunnerSpec.js +267 -0
  66. data/vendor/jasmine/spec/suites/SpecRunningSpec.js +1253 -0
  67. data/vendor/jasmine/spec/suites/SpecSpec.js +124 -0
  68. data/vendor/jasmine/spec/suites/SpySpec.js +201 -0
  69. data/vendor/jasmine/spec/suites/SuiteSpec.js +120 -0
  70. data/vendor/jasmine/spec/suites/TrivialReporterSpec.js +235 -0
  71. data/vendor/jasmine/spec/suites/UtilSpec.js +40 -0
  72. data/vendor/jasmine/spec/suites/WaitsForBlockSpec.js +87 -0
  73. data/vendor/jasmine/src/Block.js +22 -0
  74. data/vendor/jasmine/src/Env.js +264 -0
  75. data/vendor/jasmine/src/JsApiReporter.js +102 -0
  76. data/vendor/jasmine/src/Matchers.js +354 -0
  77. data/vendor/jasmine/src/MultiReporter.js +35 -0
  78. data/vendor/jasmine/src/NestedResults.js +80 -0
  79. data/vendor/jasmine/src/PrettyPrinter.js +122 -0
  80. data/vendor/jasmine/src/Queue.js +99 -0
  81. data/vendor/jasmine/src/Reporter.js +31 -0
  82. data/vendor/jasmine/src/Runner.js +77 -0
  83. data/vendor/jasmine/src/Spec.js +242 -0
  84. data/vendor/jasmine/src/Suite.js +82 -0
  85. data/vendor/jasmine/src/WaitsBlock.js +13 -0
  86. data/vendor/jasmine/src/WaitsForBlock.js +52 -0
  87. data/vendor/jasmine/src/base.js +589 -0
  88. data/vendor/jasmine/src/html/TrivialReporter.js +182 -0
  89. data/vendor/jasmine/src/html/jasmine.css +166 -0
  90. data/vendor/jasmine/src/mock-timeout.js +183 -0
  91. data/vendor/jasmine/src/util.js +67 -0
  92. data/vendor/jasmine/src/version.json +5 -0
  93. metadata +102 -5
  94. data/test/unit/jsTestDriver.conf +0 -2
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Internal representation of a Jasmine suite.
3
+ *
4
+ * @constructor
5
+ * @param {jasmine.Env} env
6
+ * @param {String} description
7
+ * @param {Function} specDefinitions
8
+ * @param {jasmine.Suite} parentSuite
9
+ */
10
+ jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
11
+ var self = this;
12
+ self.id = env.nextSuiteId ? env.nextSuiteId() : null;
13
+ self.description = description;
14
+ self.queue = new jasmine.Queue(env);
15
+ self.parentSuite = parentSuite;
16
+ self.env = env;
17
+ self.before_ = [];
18
+ self.after_ = [];
19
+ self.children_ = [];
20
+ self.suites_ = [];
21
+ self.specs_ = [];
22
+ };
23
+
24
+ jasmine.Suite.prototype.getFullName = function() {
25
+ var fullName = this.description;
26
+ for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
27
+ fullName = parentSuite.description + ' ' + fullName;
28
+ }
29
+ return fullName;
30
+ };
31
+
32
+ jasmine.Suite.prototype.finish = function(onComplete) {
33
+ this.env.reporter.reportSuiteResults(this);
34
+ this.finished = true;
35
+ if (typeof(onComplete) == 'function') {
36
+ onComplete();
37
+ }
38
+ };
39
+
40
+ jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
41
+ beforeEachFunction.typeName = 'beforeEach';
42
+ this.before_.unshift(beforeEachFunction);
43
+ };
44
+
45
+ jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
46
+ afterEachFunction.typeName = 'afterEach';
47
+ this.after_.unshift(afterEachFunction);
48
+ };
49
+
50
+ jasmine.Suite.prototype.results = function() {
51
+ return this.queue.results();
52
+ };
53
+
54
+ jasmine.Suite.prototype.add = function(suiteOrSpec) {
55
+ this.children_.push(suiteOrSpec);
56
+ if (suiteOrSpec instanceof jasmine.Suite) {
57
+ this.suites_.push(suiteOrSpec);
58
+ this.env.currentRunner().addSuite(suiteOrSpec);
59
+ } else {
60
+ this.specs_.push(suiteOrSpec);
61
+ }
62
+ this.queue.add(suiteOrSpec);
63
+ };
64
+
65
+ jasmine.Suite.prototype.specs = function() {
66
+ return this.specs_;
67
+ };
68
+
69
+ jasmine.Suite.prototype.suites = function() {
70
+ return this.suites_;
71
+ };
72
+
73
+ jasmine.Suite.prototype.children = function() {
74
+ return this.children_;
75
+ };
76
+
77
+ jasmine.Suite.prototype.execute = function(onComplete) {
78
+ var self = this;
79
+ this.queue.start(function () {
80
+ self.finish(onComplete);
81
+ });
82
+ };
@@ -0,0 +1,13 @@
1
+ jasmine.WaitsBlock = function(env, timeout, spec) {
2
+ this.timeout = timeout;
3
+ jasmine.Block.call(this, env, null, spec);
4
+ };
5
+
6
+ jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
7
+
8
+ jasmine.WaitsBlock.prototype.execute = function (onComplete) {
9
+ this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
10
+ this.env.setTimeout(function () {
11
+ onComplete();
12
+ }, this.timeout);
13
+ };
@@ -0,0 +1,52 @@
1
+ /**
2
+ * A block which waits for some condition to become true, with timeout.
3
+ *
4
+ * @constructor
5
+ * @extends jasmine.Block
6
+ * @param {jasmine.Env} env The Jasmine environment.
7
+ * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
8
+ * @param {Function} latchFunction A function which returns true when the desired condition has been met.
9
+ * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
10
+ * @param {jasmine.Spec} spec The Jasmine spec.
11
+ */
12
+ jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
13
+ this.timeout = timeout || env.defaultTimeoutInterval;
14
+ this.latchFunction = latchFunction;
15
+ this.message = message;
16
+ this.totalTimeSpentWaitingForLatch = 0;
17
+ jasmine.Block.call(this, env, null, spec);
18
+ };
19
+ jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
20
+
21
+ jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
22
+
23
+ jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
24
+ this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
25
+ var latchFunctionResult;
26
+ try {
27
+ latchFunctionResult = this.latchFunction.apply(this.spec);
28
+ } catch (e) {
29
+ this.spec.fail(e);
30
+ onComplete();
31
+ return;
32
+ }
33
+
34
+ if (latchFunctionResult) {
35
+ onComplete();
36
+ } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
37
+ var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
38
+ this.spec.fail({
39
+ name: 'timeout',
40
+ message: message
41
+ });
42
+
43
+ this.abort = true;
44
+ onComplete();
45
+ } else {
46
+ this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
47
+ var self = this;
48
+ this.env.setTimeout(function() {
49
+ self.execute(onComplete);
50
+ }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
51
+ }
52
+ };
@@ -0,0 +1,589 @@
1
+ /**
2
+ * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
3
+ *
4
+ * @namespace
5
+ */
6
+ var jasmine = {};
7
+
8
+ /**
9
+ * @private
10
+ */
11
+ jasmine.unimplementedMethod_ = function() {
12
+ throw new Error("unimplemented method");
13
+ };
14
+
15
+ /**
16
+ * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
17
+ * a plain old variable and may be redefined by somebody else.
18
+ *
19
+ * @private
20
+ */
21
+ jasmine.undefined = jasmine.___undefined___;
22
+
23
+ /**
24
+ * Default interval 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.
25
+ *
26
+ */
27
+ jasmine.DEFAULT_UPDATE_INTERVAL = 250;
28
+
29
+ /**
30
+ * Default timeout interval in milliseconds for waitsFor() blocks.
31
+ */
32
+ jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
33
+
34
+ jasmine.getGlobal = function() {
35
+ function getGlobal() {
36
+ return this;
37
+ }
38
+
39
+ return getGlobal();
40
+ };
41
+
42
+ /**
43
+ * Allows for bound functions to be compared. Internal use only.
44
+ *
45
+ * @ignore
46
+ * @private
47
+ * @param base {Object} bound 'this' for the function
48
+ * @param name {Function} function to find
49
+ */
50
+ jasmine.bindOriginal_ = function(base, name) {
51
+ var original = base[name];
52
+ if (original.apply) {
53
+ return function() {
54
+ return original.apply(base, arguments);
55
+ };
56
+ } else {
57
+ // IE support
58
+ return jasmine.getGlobal()[name];
59
+ }
60
+ };
61
+
62
+ jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
63
+ jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
64
+ jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
65
+ jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
66
+
67
+ jasmine.MessageResult = function(values) {
68
+ this.type = 'log';
69
+ this.values = values;
70
+ this.trace = new Error(); // todo: test better
71
+ };
72
+
73
+ jasmine.MessageResult.prototype.toString = function() {
74
+ var text = "";
75
+ for(var i = 0; i < this.values.length; i++) {
76
+ if (i > 0) text += " ";
77
+ if (jasmine.isString_(this.values[i])) {
78
+ text += this.values[i];
79
+ } else {
80
+ text += jasmine.pp(this.values[i]);
81
+ }
82
+ }
83
+ return text;
84
+ };
85
+
86
+ jasmine.ExpectationResult = function(params) {
87
+ this.type = 'expect';
88
+ this.matcherName = params.matcherName;
89
+ this.passed_ = params.passed;
90
+ this.expected = params.expected;
91
+ this.actual = params.actual;
92
+
93
+ this.message = this.passed_ ? 'Passed.' : params.message;
94
+ this.trace = this.passed_ ? '' : new Error(this.message);
95
+ };
96
+
97
+ jasmine.ExpectationResult.prototype.toString = function () {
98
+ return this.message;
99
+ };
100
+
101
+ jasmine.ExpectationResult.prototype.passed = function () {
102
+ return this.passed_;
103
+ };
104
+
105
+ /**
106
+ * Getter for the Jasmine environment. Ensures one gets created
107
+ */
108
+ jasmine.getEnv = function() {
109
+ return jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
110
+ };
111
+
112
+ /**
113
+ * @ignore
114
+ * @private
115
+ * @param value
116
+ * @returns {Boolean}
117
+ */
118
+ jasmine.isArray_ = function(value) {
119
+ return jasmine.isA_("Array", value);
120
+ };
121
+
122
+ /**
123
+ * @ignore
124
+ * @private
125
+ * @param value
126
+ * @returns {Boolean}
127
+ */
128
+ jasmine.isString_ = function(value) {
129
+ return jasmine.isA_("String", value);
130
+ };
131
+
132
+ /**
133
+ * @ignore
134
+ * @private
135
+ * @param value
136
+ * @returns {Boolean}
137
+ */
138
+ jasmine.isNumber_ = function(value) {
139
+ return jasmine.isA_("Number", value);
140
+ };
141
+
142
+ /**
143
+ * @ignore
144
+ * @private
145
+ * @param {String} typeName
146
+ * @param value
147
+ * @returns {Boolean}
148
+ */
149
+ jasmine.isA_ = function(typeName, value) {
150
+ return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
151
+ };
152
+
153
+ /**
154
+ * Pretty printer for expecations. Takes any object and turns it into a human-readable string.
155
+ *
156
+ * @param value {Object} an object to be outputted
157
+ * @returns {String}
158
+ */
159
+ jasmine.pp = function(value) {
160
+ var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
161
+ stringPrettyPrinter.format(value);
162
+ return stringPrettyPrinter.string;
163
+ };
164
+
165
+ /**
166
+ * Returns true if the object is a DOM Node.
167
+ *
168
+ * @param {Object} obj object to check
169
+ * @returns {Boolean}
170
+ */
171
+ jasmine.isDomNode = function(obj) {
172
+ return obj['nodeType'] > 0;
173
+ };
174
+
175
+ /**
176
+ * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter.
177
+ *
178
+ * @example
179
+ * // don't care about which function is passed in, as long as it's a function
180
+ * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));
181
+ *
182
+ * @param {Class} clazz
183
+ * @returns matchable object of the type clazz
184
+ */
185
+ jasmine.any = function(clazz) {
186
+ return new jasmine.Matchers.Any(clazz);
187
+ };
188
+
189
+ /**
190
+ * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
191
+ *
192
+ * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine
193
+ * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
194
+ *
195
+ * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).
196
+ *
197
+ * Spies are torn down at the end of every spec.
198
+ *
199
+ * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
200
+ *
201
+ * @example
202
+ * // a stub
203
+ * var myStub = jasmine.createSpy('myStub'); // can be used anywhere
204
+ *
205
+ * // spy example
206
+ * var foo = {
207
+ * not: function(bool) { return !bool; }
208
+ * }
209
+ *
210
+ * // actual foo.not will not be called, execution stops
211
+ * spyOn(foo, 'not');
212
+
213
+ // foo.not spied upon, execution will continue to implementation
214
+ * spyOn(foo, 'not').andCallThrough();
215
+ *
216
+ * // fake example
217
+ * var foo = {
218
+ * not: function(bool) { return !bool; }
219
+ * }
220
+ *
221
+ * // foo.not(val) will return val
222
+ * spyOn(foo, 'not').andCallFake(function(value) {return value;});
223
+ *
224
+ * // mock example
225
+ * foo.not(7 == 7);
226
+ * expect(foo.not).toHaveBeenCalled();
227
+ * expect(foo.not).toHaveBeenCalledWith(true);
228
+ *
229
+ * @constructor
230
+ * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
231
+ * @param {String} name
232
+ */
233
+ jasmine.Spy = function(name) {
234
+ /**
235
+ * The name of the spy, if provided.
236
+ */
237
+ this.identity = name || 'unknown';
238
+ /**
239
+ * Is this Object a spy?
240
+ */
241
+ this.isSpy = true;
242
+ /**
243
+ * The actual function this spy stubs.
244
+ */
245
+ this.plan = function() {
246
+ };
247
+ /**
248
+ * Tracking of the most recent call to the spy.
249
+ * @example
250
+ * var mySpy = jasmine.createSpy('foo');
251
+ * mySpy(1, 2);
252
+ * mySpy.mostRecentCall.args = [1, 2];
253
+ */
254
+ this.mostRecentCall = {};
255
+
256
+ /**
257
+ * Holds arguments for each call to the spy, indexed by call count
258
+ * @example
259
+ * var mySpy = jasmine.createSpy('foo');
260
+ * mySpy(1, 2);
261
+ * mySpy(7, 8);
262
+ * mySpy.mostRecentCall.args = [7, 8];
263
+ * mySpy.argsForCall[0] = [1, 2];
264
+ * mySpy.argsForCall[1] = [7, 8];
265
+ */
266
+ this.argsForCall = [];
267
+ this.calls = [];
268
+ };
269
+
270
+ /**
271
+ * Tells a spy to call through to the actual implemenatation.
272
+ *
273
+ * @example
274
+ * var foo = {
275
+ * bar: function() { // do some stuff }
276
+ * }
277
+ *
278
+ * // defining a spy on an existing property: foo.bar
279
+ * spyOn(foo, 'bar').andCallThrough();
280
+ */
281
+ jasmine.Spy.prototype.andCallThrough = function() {
282
+ this.plan = this.originalValue;
283
+ return this;
284
+ };
285
+
286
+ /**
287
+ * For setting the return value of a spy.
288
+ *
289
+ * @example
290
+ * // defining a spy from scratch: foo() returns 'baz'
291
+ * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
292
+ *
293
+ * // defining a spy on an existing property: foo.bar() returns 'baz'
294
+ * spyOn(foo, 'bar').andReturn('baz');
295
+ *
296
+ * @param {Object} value
297
+ */
298
+ jasmine.Spy.prototype.andReturn = function(value) {
299
+ this.plan = function() {
300
+ return value;
301
+ };
302
+ return this;
303
+ };
304
+
305
+ /**
306
+ * For throwing an exception when a spy is called.
307
+ *
308
+ * @example
309
+ * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
310
+ * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
311
+ *
312
+ * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
313
+ * spyOn(foo, 'bar').andThrow('baz');
314
+ *
315
+ * @param {String} exceptionMsg
316
+ */
317
+ jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
318
+ this.plan = function() {
319
+ throw exceptionMsg;
320
+ };
321
+ return this;
322
+ };
323
+
324
+ /**
325
+ * Calls an alternate implementation when a spy is called.
326
+ *
327
+ * @example
328
+ * var baz = function() {
329
+ * // do some stuff, return something
330
+ * }
331
+ * // defining a spy from scratch: foo() calls the function baz
332
+ * var foo = jasmine.createSpy('spy on foo').andCall(baz);
333
+ *
334
+ * // defining a spy on an existing property: foo.bar() calls an anonymnous function
335
+ * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
336
+ *
337
+ * @param {Function} fakeFunc
338
+ */
339
+ jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
340
+ this.plan = fakeFunc;
341
+ return this;
342
+ };
343
+
344
+ /**
345
+ * Resets all of a spy's the tracking variables so that it can be used again.
346
+ *
347
+ * @example
348
+ * spyOn(foo, 'bar');
349
+ *
350
+ * foo.bar();
351
+ *
352
+ * expect(foo.bar.callCount).toEqual(1);
353
+ *
354
+ * foo.bar.reset();
355
+ *
356
+ * expect(foo.bar.callCount).toEqual(0);
357
+ */
358
+ jasmine.Spy.prototype.reset = function() {
359
+ this.wasCalled = false;
360
+ this.callCount = 0;
361
+ this.argsForCall = [];
362
+ this.calls = [];
363
+ this.mostRecentCall = {};
364
+ };
365
+
366
+ jasmine.createSpy = function(name) {
367
+
368
+ var spyObj = function() {
369
+ spyObj.wasCalled = true;
370
+ spyObj.callCount++;
371
+ var args = jasmine.util.argsToArray(arguments);
372
+ spyObj.mostRecentCall.object = this;
373
+ spyObj.mostRecentCall.args = args;
374
+ spyObj.argsForCall.push(args);
375
+ spyObj.calls.push({object: this, args: args});
376
+ return spyObj.plan.apply(this, arguments);
377
+ };
378
+
379
+ var spy = new jasmine.Spy(name);
380
+
381
+ for (var prop in spy) {
382
+ spyObj[prop] = spy[prop];
383
+ }
384
+
385
+ spyObj.reset();
386
+
387
+ return spyObj;
388
+ };
389
+
390
+ /**
391
+ * Determines whether an object is a spy.
392
+ *
393
+ * @param {jasmine.Spy|Object} putativeSpy
394
+ * @returns {Boolean}
395
+ */
396
+ jasmine.isSpy = function(putativeSpy) {
397
+ return putativeSpy && putativeSpy.isSpy;
398
+ };
399
+
400
+ /**
401
+ * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something
402
+ * large in one call.
403
+ *
404
+ * @param {String} baseName name of spy class
405
+ * @param {Array} methodNames array of names of methods to make spies
406
+ */
407
+ jasmine.createSpyObj = function(baseName, methodNames) {
408
+ if (!jasmine.isArray_(methodNames) || methodNames.length == 0) {
409
+ throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
410
+ }
411
+ var obj = {};
412
+ for (var i = 0; i < methodNames.length; i++) {
413
+ obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
414
+ }
415
+ return obj;
416
+ };
417
+
418
+ /**
419
+ * All parameters are pretty-printed and concatenated together, then written to the current spec's output.
420
+ *
421
+ * Be careful not to leave calls to <code>jasmine.log</code> in production code.
422
+ */
423
+ jasmine.log = function() {
424
+ var spec = jasmine.getEnv().currentSpec;
425
+ spec.log.apply(spec, arguments);
426
+ };
427
+
428
+ /**
429
+ * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.
430
+ *
431
+ * @example
432
+ * // spy example
433
+ * var foo = {
434
+ * not: function(bool) { return !bool; }
435
+ * }
436
+ * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
437
+ *
438
+ * @see jasmine.createSpy
439
+ * @param obj
440
+ * @param methodName
441
+ * @returns a Jasmine spy that can be chained with all spy methods
442
+ */
443
+ var spyOn = function(obj, methodName) {
444
+ return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
445
+ };
446
+
447
+ /**
448
+ * Creates a Jasmine spec that will be added to the current suite.
449
+ *
450
+ * // TODO: pending tests
451
+ *
452
+ * @example
453
+ * it('should be true', function() {
454
+ * expect(true).toEqual(true);
455
+ * });
456
+ *
457
+ * @param {String} desc description of this specification
458
+ * @param {Function} func defines the preconditions and expectations of the spec
459
+ */
460
+ var it = function(desc, func) {
461
+ return jasmine.getEnv().it(desc, func);
462
+ };
463
+
464
+ /**
465
+ * Creates a <em>disabled</em> Jasmine spec.
466
+ *
467
+ * A convenience method that allows existing specs to be disabled temporarily during development.
468
+ *
469
+ * @param {String} desc description of this specification
470
+ * @param {Function} func defines the preconditions and expectations of the spec
471
+ */
472
+ var xit = function(desc, func) {
473
+ return jasmine.getEnv().xit(desc, func);
474
+ };
475
+
476
+ /**
477
+ * Starts a chain for a Jasmine expectation.
478
+ *
479
+ * It is passed an Object that is the actual value and should chain to one of the many
480
+ * jasmine.Matchers functions.
481
+ *
482
+ * @param {Object} actual Actual value to test against and expected value
483
+ */
484
+ var expect = function(actual) {
485
+ return jasmine.getEnv().currentSpec.expect(actual);
486
+ };
487
+
488
+ /**
489
+ * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
490
+ *
491
+ * @param {Function} func Function that defines part of a jasmine spec.
492
+ */
493
+ var runs = function(func) {
494
+ jasmine.getEnv().currentSpec.runs(func);
495
+ };
496
+
497
+ /**
498
+ * Waits a fixed time period before moving to the next block.
499
+ *
500
+ * @deprecated Use waitsFor() instead
501
+ * @param {Number} timeout milliseconds to wait
502
+ */
503
+ var waits = function(timeout) {
504
+ jasmine.getEnv().currentSpec.waits(timeout);
505
+ };
506
+
507
+ /**
508
+ * Waits for the latchFunction to return true before proceeding to the next block.
509
+ *
510
+ * @param {Function} latchFunction
511
+ * @param {String} optional_timeoutMessage
512
+ * @param {Number} optional_timeout
513
+ */
514
+ var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
515
+ jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
516
+ };
517
+
518
+ /**
519
+ * A function that is called before each spec in a suite.
520
+ *
521
+ * Used for spec setup, including validating assumptions.
522
+ *
523
+ * @param {Function} beforeEachFunction
524
+ */
525
+ var beforeEach = function(beforeEachFunction) {
526
+ jasmine.getEnv().beforeEach(beforeEachFunction);
527
+ };
528
+
529
+ /**
530
+ * A function that is called after each spec in a suite.
531
+ *
532
+ * Used for restoring any state that is hijacked during spec execution.
533
+ *
534
+ * @param {Function} afterEachFunction
535
+ */
536
+ var afterEach = function(afterEachFunction) {
537
+ jasmine.getEnv().afterEach(afterEachFunction);
538
+ };
539
+
540
+ /**
541
+ * Defines a suite of specifications.
542
+ *
543
+ * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
544
+ * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
545
+ * of setup in some tests.
546
+ *
547
+ * @example
548
+ * // TODO: a simple suite
549
+ *
550
+ * // TODO: a simple suite with a nested describe block
551
+ *
552
+ * @param {String} description A string, usually the class under test.
553
+ * @param {Function} specDefinitions function that defines several specs.
554
+ */
555
+ var describe = function(description, specDefinitions) {
556
+ return jasmine.getEnv().describe(description, specDefinitions);
557
+ };
558
+
559
+ /**
560
+ * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
561
+ *
562
+ * @param {String} description A string, usually the class under test.
563
+ * @param {Function} specDefinitions function that defines several specs.
564
+ */
565
+ var xdescribe = function(description, specDefinitions) {
566
+ return jasmine.getEnv().xdescribe(description, specDefinitions);
567
+ };
568
+
569
+
570
+ // Provide the XMLHttpRequest class for IE 5.x-6.x:
571
+ jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
572
+ try {
573
+ return new ActiveXObject("Msxml2.XMLHTTP.6.0");
574
+ } catch(e) {
575
+ }
576
+ try {
577
+ return new ActiveXObject("Msxml2.XMLHTTP.3.0");
578
+ } catch(e) {
579
+ }
580
+ try {
581
+ return new ActiveXObject("Msxml2.XMLHTTP");
582
+ } catch(e) {
583
+ }
584
+ try {
585
+ return new ActiveXObject("Microsoft.XMLHTTP");
586
+ } catch(e) {
587
+ }
588
+ throw new Error("This browser does not support XMLHttpRequest.");
589
+ } : XMLHttpRequest;