jasmine-core 2.99.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jasmine-core/boot.js +7 -6
  3. data/lib/jasmine-core/boot/boot.js +7 -6
  4. data/lib/jasmine-core/boot/node_boot.js +0 -3
  5. data/lib/jasmine-core/jasmine-html.js +228 -137
  6. data/lib/jasmine-core/jasmine.css +11 -5
  7. data/lib/jasmine-core/jasmine.js +1046 -608
  8. data/lib/jasmine-core/node_boot.js +0 -3
  9. data/lib/jasmine-core/spec/core/CallTrackerSpec.js +130 -0
  10. data/lib/jasmine-core/spec/core/ClearStackSpec.js +137 -0
  11. data/lib/jasmine-core/spec/core/ClockSpec.js +710 -0
  12. data/lib/jasmine-core/spec/core/DelayedFunctionSchedulerSpec.js +286 -0
  13. data/lib/jasmine-core/spec/core/EnvSpec.js +200 -0
  14. data/lib/jasmine-core/spec/core/ExceptionFormatterSpec.js +120 -0
  15. data/lib/jasmine-core/spec/core/ExceptionsSpec.js +46 -0
  16. data/lib/jasmine-core/spec/core/ExpectationResultSpec.js +61 -0
  17. data/lib/jasmine-core/spec/core/ExpectationSpec.js +434 -0
  18. data/lib/jasmine-core/spec/core/GlobalErrorsSpec.js +110 -0
  19. data/lib/jasmine-core/spec/core/JsApiReporterSpec.js +259 -0
  20. data/lib/jasmine-core/spec/core/MockDateSpec.js +200 -0
  21. data/lib/jasmine-core/spec/core/PrettyPrintSpec.js +332 -0
  22. data/lib/jasmine-core/spec/core/QueueRunnerSpec.js +670 -0
  23. data/lib/jasmine-core/spec/core/ReportDispatcherSpec.js +140 -0
  24. data/lib/jasmine-core/spec/core/SpecSpec.js +407 -0
  25. data/lib/jasmine-core/spec/core/SpyRegistrySpec.js +364 -0
  26. data/lib/jasmine-core/spec/core/SpySpec.js +177 -0
  27. data/lib/jasmine-core/spec/core/SpyStrategySpec.js +202 -0
  28. data/lib/jasmine-core/spec/core/StackTraceSpec.js +166 -0
  29. data/lib/jasmine-core/spec/core/SuiteSpec.js +123 -0
  30. data/lib/jasmine-core/spec/core/TimerSpec.js +31 -0
  31. data/lib/jasmine-core/spec/core/TreeProcessorSpec.js +794 -0
  32. data/lib/jasmine-core/spec/core/UserContextSpec.js +54 -0
  33. data/lib/jasmine-core/spec/core/UtilSpec.js +105 -0
  34. data/lib/jasmine-core/spec/core/asymmetric_equality/AnySpec.js +91 -0
  35. data/lib/jasmine-core/spec/core/asymmetric_equality/AnythingSpec.js +76 -0
  36. data/lib/jasmine-core/spec/core/asymmetric_equality/ArrayContainingSpec.js +52 -0
  37. data/lib/jasmine-core/spec/core/asymmetric_equality/ArrayWithExactContentsSpec.js +47 -0
  38. data/lib/jasmine-core/spec/core/asymmetric_equality/ObjectContainingSpec.js +99 -0
  39. data/lib/jasmine-core/spec/core/asymmetric_equality/StringMatchingSpec.js +27 -0
  40. data/lib/jasmine-core/spec/core/formatErrorMsgSpec.js +13 -0
  41. data/lib/jasmine-core/spec/core/integration/CustomMatchersSpec.js +200 -0
  42. data/lib/jasmine-core/spec/core/integration/CustomSpyStrategiesSpec.js +138 -0
  43. data/lib/jasmine-core/spec/core/integration/EnvSpec.js +2344 -0
  44. data/lib/jasmine-core/spec/core/integration/SpecRunningSpec.js +976 -0
  45. data/lib/jasmine-core/spec/core/matchers/DiffBuilderSpec.js +47 -0
  46. data/lib/jasmine-core/spec/core/matchers/NullDiffBuilderSpec.js +13 -0
  47. data/lib/jasmine-core/spec/core/matchers/ObjectPathSpec.js +43 -0
  48. data/lib/jasmine-core/spec/core/matchers/matchersUtilSpec.js +645 -0
  49. data/lib/jasmine-core/spec/core/matchers/nothingSpec.js +8 -0
  50. data/lib/jasmine-core/spec/core/matchers/toBeCloseToSpec.js +93 -0
  51. data/lib/jasmine-core/spec/core/matchers/toBeDefinedSpec.js +18 -0
  52. data/lib/jasmine-core/spec/core/matchers/toBeFalsySpec.js +38 -0
  53. data/lib/jasmine-core/spec/core/matchers/toBeGreaterThanOrEqualSpec.js +29 -0
  54. data/lib/jasmine-core/spec/core/matchers/toBeGreaterThanSpec.js +20 -0
  55. data/lib/jasmine-core/spec/core/matchers/toBeLessThanOrEqualSpec.js +29 -0
  56. data/lib/jasmine-core/spec/core/matchers/toBeLessThanSpec.js +20 -0
  57. data/lib/jasmine-core/spec/core/matchers/toBeNaNSpec.js +37 -0
  58. data/lib/jasmine-core/spec/core/matchers/toBeNegativeInfinitySpec.js +31 -0
  59. data/lib/jasmine-core/spec/core/matchers/toBeNullSpec.js +17 -0
  60. data/lib/jasmine-core/spec/core/matchers/toBePositiveInfinitySpec.js +31 -0
  61. data/lib/jasmine-core/spec/core/matchers/toBeSpec.js +17 -0
  62. data/lib/jasmine-core/spec/core/matchers/toBeTruthySpec.js +38 -0
  63. data/lib/jasmine-core/spec/core/matchers/toBeUndefinedSpec.js +18 -0
  64. data/lib/jasmine-core/spec/core/matchers/toContainSpec.js +26 -0
  65. data/lib/jasmine-core/spec/core/matchers/toEqualSpec.js +785 -0
  66. data/lib/jasmine-core/spec/core/matchers/toHaveBeenCalledBeforeSpec.js +99 -0
  67. data/lib/jasmine-core/spec/core/matchers/toHaveBeenCalledSpec.js +47 -0
  68. data/lib/jasmine-core/spec/core/matchers/toHaveBeenCalledTimesSpec.js +86 -0
  69. data/lib/jasmine-core/spec/core/matchers/toHaveBeenCalledWithSpec.js +67 -0
  70. data/lib/jasmine-core/spec/core/matchers/toMatchSpec.js +43 -0
  71. data/lib/jasmine-core/spec/core/matchers/toThrowErrorSpec.js +315 -0
  72. data/lib/jasmine-core/spec/core/matchers/toThrowMatchingSpec.js +73 -0
  73. data/lib/jasmine-core/spec/core/matchers/toThrowSpec.js +100 -0
  74. data/lib/jasmine-core/spec/helpers/BrowserFlags.js +15 -0
  75. data/lib/jasmine-core/spec/helpers/asyncAwait.js +27 -0
  76. data/lib/jasmine-core/spec/helpers/checkForMap.js +37 -0
  77. data/lib/jasmine-core/spec/helpers/checkForSet.js +41 -0
  78. data/lib/jasmine-core/spec/helpers/checkForSymbol.js +28 -0
  79. data/lib/jasmine-core/spec/helpers/checkForTypedArrays.js +20 -0
  80. data/lib/jasmine-core/spec/helpers/defineJasmineUnderTest.js +6 -0
  81. data/lib/jasmine-core/spec/helpers/integrationMatchers.js +43 -0
  82. data/lib/jasmine-core/spec/helpers/nodeDefineJasmineUnderTest.js +30 -0
  83. data/lib/jasmine-core/spec/html/HtmlReporterSpec.js +1261 -0
  84. data/lib/jasmine-core/spec/html/HtmlSpecFilterSpec.js +18 -0
  85. data/lib/jasmine-core/spec/html/MatchersHtmlSpec.js +37 -0
  86. data/lib/jasmine-core/spec/html/PrettyPrintHtmlSpec.js +27 -0
  87. data/lib/jasmine-core/spec/html/QueryStringSpec.js +72 -0
  88. data/lib/jasmine-core/spec/html/ResultsNodeSpec.js +62 -0
  89. data/lib/jasmine-core/spec/html/SpyRegistryHtmlSpec.js +39 -0
  90. data/lib/jasmine-core/spec/html/matchers/toHaveClassSpec.js +48 -0
  91. data/lib/jasmine-core/spec/npmPackage/npmPackageSpec.js +101 -0
  92. data/lib/jasmine-core/spec/performance/large_object_test.js +36 -0
  93. data/lib/jasmine-core/spec/performance/performance_test.js +10 -0
  94. data/lib/jasmine-core/version.rb +1 -1
  95. metadata +88 -4
  96. data/lib/console/console.js +0 -190
@@ -0,0 +1,332 @@
1
+ describe("jasmineUnderTest.pp", function () {
2
+ it("should wrap strings in single quotes", function() {
3
+ expect(jasmineUnderTest.pp("some string")).toEqual("'some string'");
4
+ expect(jasmineUnderTest.pp("som' string")).toEqual("'som' string'");
5
+ });
6
+
7
+ it("should stringify primitives properly", function() {
8
+ expect(jasmineUnderTest.pp(true)).toEqual("true");
9
+ expect(jasmineUnderTest.pp(false)).toEqual("false");
10
+ expect(jasmineUnderTest.pp(null)).toEqual("null");
11
+ expect(jasmineUnderTest.pp(jasmine.undefined)).toEqual("undefined");
12
+ expect(jasmineUnderTest.pp(3)).toEqual("3");
13
+ expect(jasmineUnderTest.pp(-3.14)).toEqual("-3.14");
14
+ expect(jasmineUnderTest.pp(-0)).toEqual("-0");
15
+ });
16
+
17
+ describe('stringify sets', function() {
18
+ it("should stringify sets properly", function() {
19
+ jasmine.getEnv().requireFunctioningSets();
20
+ var set = new Set();
21
+ set.add(1);
22
+ set.add(2);
23
+ expect(jasmineUnderTest.pp(set)).toEqual("Set( 1, 2 )");
24
+ });
25
+
26
+ it("should truncate sets with more elments than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
27
+ jasmine.getEnv().requireFunctioningSets();
28
+ var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
29
+
30
+ try {
31
+ jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
32
+ var set = new Set();
33
+ set.add('a');
34
+ set.add('b');
35
+ set.add('c');
36
+ expect(jasmineUnderTest.pp(set)).toEqual("Set( 'a', 'b', ... )");
37
+ } finally {
38
+ jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize;
39
+ }
40
+ })
41
+ });
42
+
43
+ describe('stringify maps', function() {
44
+ it("should stringify maps properly", function() {
45
+ jasmine.getEnv().requireFunctioningMaps();
46
+ var map = new Map();
47
+ map.set(1,2);
48
+ expect(jasmineUnderTest.pp(map)).toEqual("Map( [ 1, 2 ] )");
49
+ });
50
+
51
+ it("should truncate maps with more elments than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
52
+ jasmine.getEnv().requireFunctioningMaps();
53
+ var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
54
+
55
+ try {
56
+ jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
57
+ var map = new Map();
58
+ map.set("a",1);
59
+ map.set("b",2);
60
+ map.set("c",3);
61
+ expect(jasmineUnderTest.pp(map)).toEqual("Map( [ 'a', 1 ], [ 'b', 2 ], ... )");
62
+ } finally {
63
+ jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize;
64
+ }
65
+ })
66
+ });
67
+
68
+
69
+ describe('stringify arrays', function() {
70
+ it("should stringify arrays properly", function() {
71
+ expect(jasmineUnderTest.pp([1, 2])).toEqual("[ 1, 2 ]");
72
+ expect(jasmineUnderTest.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', Object({ }), undefined, null ]");
73
+ });
74
+
75
+ it("should truncate arrays that are longer than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
76
+ var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
77
+ var array = [1, 2, 3];
78
+
79
+ try {
80
+ jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
81
+ expect(jasmineUnderTest.pp(array)).toEqual("[ 1, 2, ... ]");
82
+ } finally {
83
+ jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
84
+ }
85
+ });
86
+
87
+ it("should stringify arrays with properties properly", function() {
88
+ var arr = [1, 2];
89
+ arr.foo = 'bar';
90
+ arr.baz = {};
91
+ expect(jasmineUnderTest.pp(arr)).toEqual("[ 1, 2, foo: 'bar', baz: Object({ }) ]");
92
+ });
93
+
94
+ it("should stringify empty arrays with properties properly", function() {
95
+ var empty = [];
96
+ empty.foo = 'bar';
97
+ empty.baz = {};
98
+ expect(jasmineUnderTest.pp(empty)).toEqual("[ foo: 'bar', baz: Object({ }) ]");
99
+ });
100
+
101
+ it("should stringify long arrays with properties properly", function() {
102
+ var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
103
+ var long = [1,2,3];
104
+ long.foo = 'bar';
105
+ long.baz = {};
106
+
107
+ try {
108
+ jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
109
+ expect(jasmineUnderTest.pp(long)).toEqual("[ 1, 2, ..., foo: 'bar', baz: Object({ }) ]");
110
+ } finally {
111
+ jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
112
+ }
113
+ });
114
+
115
+ it("should indicate circular array references", function() {
116
+ var array1 = [1, 2];
117
+ var array2 = [array1];
118
+ array1.push(array2);
119
+ expect(jasmineUnderTest.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
120
+ });
121
+
122
+ it("should not indicate circular references incorrectly", function() {
123
+ var array = [ [1] ];
124
+ expect(jasmineUnderTest.pp(array)).toEqual("[ [ 1 ] ]");
125
+ });
126
+ });
127
+
128
+ it("should stringify objects properly", function() {
129
+ expect(jasmineUnderTest.pp({foo: 'bar'})).toEqual("Object({ foo: 'bar' })");
130
+ expect(jasmineUnderTest.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("Object({ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined })");
131
+ expect(jasmineUnderTest.pp({foo: function () {
132
+ }, bar: [1, 2, 3]})).toEqual("Object({ foo: Function, bar: [ 1, 2, 3 ] })");
133
+ });
134
+
135
+ it("should truncate objects with too many keys", function () {
136
+ var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
137
+ var long = {a: 1, b: 2, c: 3};
138
+
139
+ try {
140
+ jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
141
+ expect(jasmineUnderTest.pp(long)).toEqual("Object({ a: 1, b: 2, ... })");
142
+ } finally {
143
+ jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
144
+ }
145
+ });
146
+
147
+ function withMaxChars(maxChars, fn) {
148
+ var originalMaxChars = jasmineUnderTest.MAX_PRETTY_PRINT_CHARS;
149
+
150
+ try {
151
+ jasmineUnderTest.MAX_PRETTY_PRINT_CHARS = maxChars;
152
+ fn();
153
+ } finally {
154
+ jasmineUnderTest.MAX_PRETTY_PRINT_CHARS = originalMaxChars;
155
+ }
156
+ }
157
+
158
+ it("should truncate outputs that are too long", function() {
159
+ var big = [
160
+ { a: 1, b: "a long string" },
161
+ {}
162
+ ];
163
+
164
+ withMaxChars(34, function() {
165
+ expect(jasmineUnderTest.pp(big)).toEqual("[ Object({ a: 1, b: 'a long st ...");
166
+ });
167
+ });
168
+
169
+ it("should not serialize more objects after hitting MAX_PRETTY_PRINT_CHARS", function() {
170
+ var a = { jasmineToString: function() { return 'object a'; } },
171
+ b = { jasmineToString: function() { return 'object b'; } },
172
+ c = { jasmineToString: jasmine.createSpy('c jasmineToString').and.returnValue('') },
173
+ d = { jasmineToString: jasmine.createSpy('d jasmineToString').and.returnValue('') };
174
+
175
+ withMaxChars(30, function() {
176
+ jasmineUnderTest.pp([{a: a, b: b, c: c}, d]);
177
+ expect(c.jasmineToString).not.toHaveBeenCalled();
178
+ expect(d.jasmineToString).not.toHaveBeenCalled();
179
+ });
180
+ });
181
+
182
+ it("should print 'null' as the constructor of an object with its own constructor property", function() {
183
+ expect(jasmineUnderTest.pp({constructor: function() {}})).toContain("null({");
184
+ expect(jasmineUnderTest.pp({constructor: 'foo'})).toContain("null({");
185
+ });
186
+
187
+ it("should not include inherited properties when stringifying an object", function() {
188
+ var SomeClass = function SomeClass() {};
189
+ SomeClass.prototype.foo = "inherited foo";
190
+ var instance = new SomeClass();
191
+ instance.bar = "my own bar";
192
+ expect(jasmineUnderTest.pp(instance)).toEqual("SomeClass({ bar: 'my own bar' })");
193
+ });
194
+
195
+ it("should not recurse objects and arrays more deeply than jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH", function() {
196
+ var originalMaxDepth = jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH;
197
+ var nestedObject = { level1: { level2: { level3: { level4: "leaf" } } } };
198
+ var nestedArray = [1, [2, [3, [4, "leaf"]]]];
199
+
200
+ try {
201
+ jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 2;
202
+ expect(jasmineUnderTest.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object }) })");
203
+ expect(jasmineUnderTest.pp(nestedArray)).toEqual("[ 1, [ 2, Array ] ]");
204
+
205
+ jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 3;
206
+ expect(jasmineUnderTest.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object({ level3: Object }) }) })");
207
+ expect(jasmineUnderTest.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, Array ] ] ]");
208
+
209
+ jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 4;
210
+ expect(jasmineUnderTest.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object({ level3: Object({ level4: 'leaf' }) }) }) })");
211
+ expect(jasmineUnderTest.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
212
+ } finally {
213
+ jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
214
+ }
215
+ });
216
+
217
+ it("should stringify immutable circular objects", function(){
218
+ if(Object.freeze){
219
+ var frozenObject = {foo: {bar: 'baz'}};
220
+ frozenObject.circular = frozenObject;
221
+ frozenObject = Object.freeze(frozenObject);
222
+ expect(jasmineUnderTest.pp(frozenObject)).toEqual("Object({ foo: Object({ bar: 'baz' }), circular: <circular reference: Object> })");
223
+ }
224
+ });
225
+
226
+ it("should stringify RegExp objects properly", function() {
227
+ expect(jasmineUnderTest.pp(/x|y|z/)).toEqual("/x|y|z/");
228
+ });
229
+
230
+ it("should indicate circular object references", function() {
231
+ var sampleValue = {foo: 'hello'};
232
+ sampleValue.nested = sampleValue;
233
+ expect(jasmineUnderTest.pp(sampleValue)).toEqual("Object({ foo: 'hello', nested: <circular reference: Object> })");
234
+ });
235
+
236
+ it("should indicate getters on objects as such", function() {
237
+ var sampleValue = {id: 1};
238
+ if (sampleValue.__defineGetter__) {
239
+ //not supported in IE!
240
+ sampleValue.__defineGetter__('calculatedValue', function() {
241
+ throw new Error("don't call me!");
242
+ });
243
+ }
244
+ if (sampleValue.__defineGetter__) {
245
+ expect(jasmineUnderTest.pp(sampleValue)).toEqual("Object({ id: 1, calculatedValue: <getter> })");
246
+ }
247
+ else {
248
+ expect(jasmineUnderTest.pp(sampleValue)).toEqual("Object({ id: 1 })");
249
+ }
250
+ });
251
+
252
+ it('should not do HTML escaping of strings', function() {
253
+ expect(jasmineUnderTest.pp('some <b>html string</b> &', false)).toEqual('\'some <b>html string</b> &\'');
254
+ });
255
+
256
+ it("should abbreviate the global (usually window) object", function() {
257
+ expect(jasmineUnderTest.pp(jasmine.getGlobal())).toEqual("<global>");
258
+ });
259
+
260
+ it("should stringify Date objects properly", function() {
261
+ var now = new Date();
262
+ expect(jasmineUnderTest.pp(now)).toEqual("Date(" + now.toString() + ")");
263
+ });
264
+
265
+ it("should stringify spy objects properly", function() {
266
+ var TestObject = {
267
+ someFunction: function() {}
268
+ },
269
+ env = new jasmineUnderTest.Env();
270
+
271
+ var spyRegistry = new jasmineUnderTest.SpyRegistry({
272
+ currentSpies: function() {return [];},
273
+ createSpy: function(name, originalFn) {
274
+ return jasmineUnderTest.Spy(name, originalFn);
275
+ }
276
+ });
277
+
278
+ spyRegistry.spyOn(TestObject, 'someFunction');
279
+ expect(jasmineUnderTest.pp(TestObject.someFunction)).toEqual("spy on someFunction");
280
+
281
+ expect(jasmineUnderTest.pp(env.createSpy("something"))).toEqual("spy on something");
282
+ });
283
+
284
+ it("should stringify objects that implement jasmineToString", function () {
285
+ var obj = {
286
+ jasmineToString: function () { return "strung"; }
287
+ };
288
+
289
+ expect(jasmineUnderTest.pp(obj)).toEqual("strung");
290
+ });
291
+
292
+ it("should stringify objects that implement custom toString", function () {
293
+ var obj = {
294
+ toString: function () { return "my toString"; }
295
+ };
296
+
297
+ expect(jasmineUnderTest.pp(obj)).toEqual("my toString");
298
+
299
+ // Simulate object from another global context (e.g. an iframe or Web Worker) that does not actually have a custom
300
+ // toString despite obj.toString !== Object.prototype.toString
301
+ var objFromOtherContext = {
302
+ foo: 'bar',
303
+ toString: function () { return Object.prototype.toString.call(this); }
304
+ };
305
+
306
+ expect(jasmineUnderTest.pp(objFromOtherContext)).toEqual("Object({ foo: 'bar', toString: Function })");
307
+ });
308
+
309
+ it("should stringify objects have have a toString that isn't a function", function() {
310
+ var obj = {
311
+ toString: "foo"
312
+ };
313
+
314
+ expect(jasmineUnderTest.pp(obj)).toEqual("Object({ toString: 'foo' })");
315
+ });
316
+
317
+ it("should stringify objects from anonymous constructors with custom toString", function () {
318
+ var MyAnonymousConstructor = (function() { return function () {}; })();
319
+ MyAnonymousConstructor.toString = function () { return ''; };
320
+
321
+ var a = new MyAnonymousConstructor();
322
+
323
+ expect(jasmineUnderTest.pp(a)).toEqual("<anonymous>({ })");
324
+ });
325
+
326
+ it("should handle objects with null prototype", function() {
327
+ var obj = Object.create(null);
328
+ obj.foo = 'bar';
329
+
330
+ expect(jasmineUnderTest.pp(obj)).toEqual("null({ foo: 'bar' })");
331
+ });
332
+ });
@@ -0,0 +1,670 @@
1
+ describe("QueueRunner", function() {
2
+
3
+ it("runs all the functions it's passed", function() {
4
+ var calls = [],
5
+ queueableFn1 = { fn: jasmine.createSpy('fn1') },
6
+ queueableFn2 = { fn: jasmine.createSpy('fn2') },
7
+ queueRunner = new jasmineUnderTest.QueueRunner({
8
+ queueableFns: [queueableFn1, queueableFn2]
9
+ });
10
+ queueableFn1.fn.and.callFake(function() {
11
+ calls.push('fn1');
12
+ });
13
+ queueableFn2.fn.and.callFake(function() {
14
+ calls.push('fn2');
15
+ });
16
+
17
+ queueRunner.execute();
18
+
19
+ expect(calls).toEqual(['fn1', 'fn2']);
20
+ });
21
+
22
+ it("runs cleanup functions after the others", function() {
23
+ var calls = [],
24
+ queueableFn1 = { fn: jasmine.createSpy('fn1') },
25
+ queueableFn2 = { fn: jasmine.createSpy('fn2') },
26
+ queueRunner = new jasmineUnderTest.QueueRunner({
27
+ queueableFns: [queueableFn1],
28
+ cleanupFns: [queueableFn2]
29
+ });
30
+ queueableFn1.fn.and.callFake(function() {
31
+ calls.push('fn1');
32
+ });
33
+ queueableFn2.fn.and.callFake(function() {
34
+ calls.push('fn2');
35
+ });
36
+
37
+ queueRunner.execute();
38
+
39
+ expect(calls).toEqual(['fn1', 'fn2']);
40
+ });
41
+
42
+ it("calls each function with a consistent 'this'-- an empty object", function() {
43
+ var queueableFn1 = { fn: jasmine.createSpy('fn1') },
44
+ queueableFn2 = { fn: jasmine.createSpy('fn2') },
45
+ queueableFn3 = { fn: function(done) { asyncContext = this; done(); } },
46
+ queueRunner = new jasmineUnderTest.QueueRunner({
47
+ queueableFns: [queueableFn1, queueableFn2, queueableFn3]
48
+ }),
49
+ asyncContext;
50
+
51
+ queueRunner.execute();
52
+
53
+ var context = queueableFn1.fn.calls.first().object;
54
+ expect(context).toEqual(new jasmineUnderTest.UserContext());
55
+ expect(queueableFn2.fn.calls.first().object).toBe(context);
56
+ expect(asyncContext).toBe(context);
57
+ });
58
+
59
+ describe("with an asynchronous function", function() {
60
+ beforeEach(function() {
61
+ jasmine.clock().install();
62
+ });
63
+
64
+ afterEach(function() {
65
+ jasmine.clock().uninstall();
66
+ });
67
+
68
+ it("supports asynchronous functions, only advancing to next function after a done() callback", function() {
69
+ //TODO: it would be nice if spy arity could match the fake, so we could do something like:
70
+ //createSpy('asyncfn').and.callFake(function(done) {});
71
+
72
+ var onComplete = jasmine.createSpy('onComplete'),
73
+ beforeCallback = jasmine.createSpy('beforeCallback'),
74
+ fnCallback = jasmine.createSpy('fnCallback'),
75
+ afterCallback = jasmine.createSpy('afterCallback'),
76
+ queueableFn1 = { fn: function(done) {
77
+ beforeCallback();
78
+ setTimeout(done, 100);
79
+ } },
80
+ queueableFn2 = { fn: function(done) {
81
+ fnCallback();
82
+ setTimeout(done, 100);
83
+ } },
84
+ queueableFn3 = { fn: function(done) {
85
+ afterCallback();
86
+ setTimeout(done, 100);
87
+ } },
88
+ queueRunner = new jasmineUnderTest.QueueRunner({
89
+ queueableFns: [queueableFn1, queueableFn2, queueableFn3],
90
+ onComplete: onComplete
91
+ });
92
+
93
+ queueRunner.execute();
94
+
95
+ expect(beforeCallback).toHaveBeenCalled();
96
+ expect(fnCallback).not.toHaveBeenCalled();
97
+ expect(afterCallback).not.toHaveBeenCalled();
98
+ expect(onComplete).not.toHaveBeenCalled();
99
+
100
+ jasmine.clock().tick(100);
101
+
102
+ expect(fnCallback).toHaveBeenCalled();
103
+ expect(afterCallback).not.toHaveBeenCalled();
104
+ expect(onComplete).not.toHaveBeenCalled();
105
+
106
+ jasmine.clock().tick(100);
107
+
108
+ expect(afterCallback).toHaveBeenCalled();
109
+ expect(onComplete).not.toHaveBeenCalled();
110
+
111
+ jasmine.clock().tick(100);
112
+
113
+ expect(onComplete).toHaveBeenCalled();
114
+ });
115
+
116
+ it("explicitly fails an async function with a provided fail function and moves to the next function", function() {
117
+ var queueableFn1 = { fn: function(done) {
118
+ setTimeout(function() { done.fail('foo'); }, 100);
119
+ } },
120
+ queueableFn2 = { fn: jasmine.createSpy('fn2') },
121
+ failFn = jasmine.createSpy('fail'),
122
+ queueRunner = new jasmineUnderTest.QueueRunner({
123
+ queueableFns: [queueableFn1, queueableFn2],
124
+ fail: failFn
125
+ });
126
+
127
+ queueRunner.execute();
128
+
129
+ expect(failFn).not.toHaveBeenCalled();
130
+ expect(queueableFn2.fn).not.toHaveBeenCalled();
131
+
132
+ jasmine.clock().tick(100);
133
+
134
+ expect(failFn).toHaveBeenCalledWith('foo');
135
+ expect(queueableFn2.fn).toHaveBeenCalled();
136
+ });
137
+
138
+ it("explicitly fails an async function when next is called with an Error and moves to the next function", function() {
139
+ var err = new Error('foo'),
140
+ queueableFn1 = { fn: function(done) {
141
+ setTimeout(function() { done(err); }, 100);
142
+ } },
143
+ queueableFn2 = { fn: jasmine.createSpy('fn2') },
144
+ failFn = jasmine.createSpy('fail'),
145
+ queueRunner = new jasmineUnderTest.QueueRunner({
146
+ queueableFns: [queueableFn1, queueableFn2],
147
+ fail: failFn
148
+ });
149
+
150
+ queueRunner.execute();
151
+
152
+ expect(failFn).not.toHaveBeenCalled();
153
+ expect(queueableFn2.fn).not.toHaveBeenCalled();
154
+
155
+ jasmine.clock().tick(100);
156
+
157
+ expect(failFn).toHaveBeenCalledWith(err);
158
+ expect(queueableFn2.fn).toHaveBeenCalled();
159
+ });
160
+
161
+ it("does not cause an explicit fail if execution is being stopped", function() {
162
+ var err = new jasmineUnderTest.StopExecutionError('foo'),
163
+ queueableFn1 = { fn: function(done) {
164
+ setTimeout(function() { done(err); }, 100);
165
+ } },
166
+ queueableFn2 = { fn: jasmine.createSpy('fn2') },
167
+ failFn = jasmine.createSpy('fail'),
168
+ queueRunner = new jasmineUnderTest.QueueRunner({
169
+ queueableFns: [queueableFn1, queueableFn2],
170
+ fail: failFn
171
+ });
172
+
173
+ queueRunner.execute();
174
+
175
+ expect(failFn).not.toHaveBeenCalled();
176
+ expect(queueableFn2.fn).not.toHaveBeenCalled();
177
+
178
+ jasmine.clock().tick(100);
179
+
180
+ expect(failFn).not.toHaveBeenCalled();
181
+ expect(queueableFn2.fn).toHaveBeenCalled();
182
+ });
183
+
184
+ it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() {
185
+ var timeout = 3,
186
+ beforeFn = { fn: function(done) { }, type: 'before', timeout: function() { return timeout; } },
187
+ queueableFn = { fn: jasmine.createSpy('fn'), type: 'queueable' },
188
+ onComplete = jasmine.createSpy('onComplete'),
189
+ onException = jasmine.createSpy('onException'),
190
+ queueRunner = new jasmineUnderTest.QueueRunner({
191
+ queueableFns: [beforeFn, queueableFn],
192
+ onComplete: onComplete,
193
+ onException: onException
194
+ });
195
+
196
+ queueRunner.execute();
197
+ expect(queueableFn.fn).not.toHaveBeenCalled();
198
+
199
+ jasmine.clock().tick(timeout);
200
+
201
+ expect(onException).toHaveBeenCalledWith(jasmine.any(Error));
202
+ expect(queueableFn.fn).toHaveBeenCalled();
203
+ expect(onComplete).toHaveBeenCalled();
204
+ });
205
+
206
+ it("by default does not set a timeout for asynchronous functions", function() {
207
+ var beforeFn = { fn: function(done) { } },
208
+ queueableFn = { fn: jasmine.createSpy('fn') },
209
+ onComplete = jasmine.createSpy('onComplete'),
210
+ onException = jasmine.createSpy('onException'),
211
+ queueRunner = new jasmineUnderTest.QueueRunner({
212
+ queueableFns: [beforeFn, queueableFn],
213
+ onComplete: onComplete,
214
+ onException: onException,
215
+ });
216
+
217
+ queueRunner.execute();
218
+ expect(queueableFn.fn).not.toHaveBeenCalled();
219
+
220
+ jasmine.clock().tick(jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL);
221
+
222
+ expect(onException).not.toHaveBeenCalled();
223
+ expect(queueableFn.fn).not.toHaveBeenCalled();
224
+ expect(onComplete).not.toHaveBeenCalled();
225
+ });
226
+
227
+ it("clears the timeout when an async function throws an exception, to prevent additional exception reporting", function() {
228
+ var queueableFn = { fn: function(done) { throw new Error("error!"); } },
229
+ onComplete = jasmine.createSpy('onComplete'),
230
+ onException = jasmine.createSpy('onException'),
231
+ queueRunner = new jasmineUnderTest.QueueRunner({
232
+ queueableFns: [queueableFn],
233
+ onComplete: onComplete,
234
+ onException: onException
235
+ });
236
+
237
+ queueRunner.execute();
238
+
239
+ expect(onComplete).toHaveBeenCalled();
240
+ expect(onException).toHaveBeenCalled();
241
+
242
+ jasmine.clock().tick(jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL);
243
+ expect(onException.calls.count()).toEqual(1);
244
+ });
245
+
246
+ it("clears the timeout when the done callback is called", function() {
247
+ var queueableFn = { fn: function(done) { done(); } },
248
+ onComplete = jasmine.createSpy('onComplete'),
249
+ onException = jasmine.createSpy('onException'),
250
+ queueRunner = new jasmineUnderTest.QueueRunner({
251
+ queueableFns: [queueableFn],
252
+ onComplete: onComplete,
253
+ onException: onException
254
+ });
255
+
256
+ queueRunner.execute();
257
+
258
+ jasmine.clock().tick(1);
259
+ expect(onComplete).toHaveBeenCalled();
260
+
261
+ jasmine.clock().tick(jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL);
262
+ expect(onException).not.toHaveBeenCalled();
263
+ });
264
+
265
+ it("only moves to the next spec the first time you call done", function() {
266
+ var queueableFn = { fn: function(done) {done(); done();} },
267
+ nextQueueableFn = { fn: jasmine.createSpy('nextFn') },
268
+ queueRunner = new jasmineUnderTest.QueueRunner({
269
+ queueableFns: [queueableFn, nextQueueableFn]
270
+ });
271
+
272
+ queueRunner.execute();
273
+ jasmine.clock().tick(1);
274
+ expect(nextQueueableFn.fn.calls.count()).toEqual(1);
275
+ });
276
+
277
+ it("does not move to the next spec if done is called after an exception has ended the spec", function() {
278
+ var queueableFn = { fn: function(done) {
279
+ setTimeout(done, 1);
280
+ throw new Error('error!');
281
+ } },
282
+ nextQueueableFn = { fn: jasmine.createSpy('nextFn') },
283
+ queueRunner = new jasmineUnderTest.QueueRunner({
284
+ queueableFns: [queueableFn, nextQueueableFn]
285
+ });
286
+
287
+ queueRunner.execute();
288
+ jasmine.clock().tick(1);
289
+ expect(nextQueueableFn.fn.calls.count()).toEqual(1);
290
+ });
291
+
292
+ it("should return a null when you call done", function () {
293
+ // Some promises want handlers to return anything but undefined to help catch "forgotten returns".
294
+ var doneReturn,
295
+ queueableFn = { fn: function(done) {
296
+ doneReturn = done();
297
+ } },
298
+ queueRunner = new jasmineUnderTest.QueueRunner({
299
+ queueableFns: [queueableFn]
300
+ });
301
+
302
+ queueRunner.execute();
303
+ expect(doneReturn).toBe(null);
304
+ });
305
+
306
+ it("continues running functions when an exception is thrown in async code without timing out", function() {
307
+ var queueableFn = { fn: function(done) { throwAsync(); }, timeout: function() { return 1; } },
308
+ nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
309
+ onException = jasmine.createSpy('onException'),
310
+ globalErrors = { pushListener: jasmine.createSpy('pushListener'), popListener: jasmine.createSpy('popListener') },
311
+ queueRunner = new jasmineUnderTest.QueueRunner({
312
+ queueableFns: [queueableFn, nextQueueableFn],
313
+ onException: onException,
314
+ globalErrors: globalErrors
315
+ }),
316
+ throwAsync = function() {
317
+ globalErrors.pushListener.calls.mostRecent().args[0](new Error('foo'));
318
+ jasmine.clock().tick(2);
319
+ };
320
+
321
+ nextQueueableFn.fn.and.callFake(function() {
322
+ // should remove the same function that was added
323
+ expect(globalErrors.popListener).toHaveBeenCalledWith(globalErrors.pushListener.calls.argsFor(1)[0]);
324
+ });
325
+
326
+ queueRunner.execute();
327
+
328
+ function errorWithMessage(message) {
329
+ return {
330
+ asymmetricMatch: function(other) {
331
+ return new RegExp(message).test(other.message);
332
+ },
333
+ toString: function() {
334
+ return '<Error with message like "' + message + '">';
335
+ }
336
+ };
337
+ }
338
+ expect(onException).not.toHaveBeenCalledWith(errorWithMessage(/DEFAULT_TIMEOUT_INTERVAL/));
339
+ expect(onException).toHaveBeenCalledWith(errorWithMessage(/^foo$/));
340
+ expect(nextQueueableFn.fn).toHaveBeenCalled();
341
+ });
342
+
343
+ it("handles exceptions thrown while waiting for the stack to clear", function() {
344
+ var queueableFn = { fn: function(done) { done() } },
345
+ global = {},
346
+ errorListeners = [],
347
+ globalErrors = {
348
+ pushListener: function(f) { errorListeners.push(f); },
349
+ popListener: function() { errorListeners.pop(); }
350
+ },
351
+ clearStack = jasmine.createSpy('clearStack'),
352
+ onException = jasmine.createSpy('onException'),
353
+ queueRunner = new jasmineUnderTest.QueueRunner({
354
+ queueableFns: [queueableFn],
355
+ globalErrors: globalErrors,
356
+ clearStack: clearStack,
357
+ onException: onException
358
+ }),
359
+ error = new Error('nope');
360
+
361
+ queueRunner.execute();
362
+ jasmine.clock().tick();
363
+ expect(clearStack).toHaveBeenCalled();
364
+ expect(errorListeners.length).toEqual(1);
365
+ errorListeners[0](error);
366
+ clearStack.calls.argsFor(0)[0]();
367
+ expect(onException).toHaveBeenCalledWith(error);
368
+ });
369
+ });
370
+
371
+ describe("with a function that returns a promise", function() {
372
+ function StubPromise() {}
373
+
374
+ StubPromise.prototype.then = function(resolve, reject) {
375
+ this.resolveHandler = resolve;
376
+ this.rejectHandler = reject;
377
+ };
378
+
379
+ beforeEach(function() {
380
+ jasmine.clock().install();
381
+ });
382
+
383
+ afterEach(function() {
384
+ jasmine.clock().uninstall();
385
+ });
386
+
387
+ it("runs the function asynchronously, advancing once the promise is settled", function() {
388
+ var onComplete = jasmine.createSpy('onComplete'),
389
+ fnCallback = jasmine.createSpy('fnCallback'),
390
+ p1 = new StubPromise(),
391
+ p2 = new StubPromise(),
392
+ queueableFn1 = { fn: function() {
393
+ setTimeout(function() {
394
+ p1.resolveHandler();
395
+ }, 100);
396
+ return p1;
397
+ } };
398
+ queueableFn2 = { fn: function() {
399
+ fnCallback();
400
+ setTimeout(function() {
401
+ p2.resolveHandler();
402
+ }, 100);
403
+ return p2;
404
+ } },
405
+ queueRunner = new jasmineUnderTest.QueueRunner({
406
+ queueableFns: [queueableFn1, queueableFn2],
407
+ onComplete: onComplete
408
+ });
409
+
410
+ queueRunner.execute();
411
+ expect(fnCallback).not.toHaveBeenCalled();
412
+ expect(onComplete).not.toHaveBeenCalled();
413
+
414
+ jasmine.clock().tick(100);
415
+
416
+ expect(fnCallback).toHaveBeenCalled();
417
+ expect(onComplete).not.toHaveBeenCalled();
418
+
419
+ jasmine.clock().tick(100);
420
+
421
+ expect(onComplete).toHaveBeenCalled();
422
+ });
423
+
424
+ it("handles a rejected promise like an unhandled exception", function() {
425
+ var promise = new StubPromise(),
426
+ queueableFn1 = { fn: function() {
427
+ setTimeout(function() {
428
+ promise.rejectHandler('foo')
429
+ }, 100);
430
+ return promise;
431
+ } },
432
+ queueableFn2 = { fn: jasmine.createSpy('fn2') },
433
+ failFn = jasmine.createSpy('fail'),
434
+ onExceptionCallback = jasmine.createSpy('on exception callback'),
435
+ queueRunner = new jasmineUnderTest.QueueRunner({
436
+ queueableFns: [queueableFn1, queueableFn2],
437
+ onException: onExceptionCallback
438
+ });
439
+
440
+ queueRunner.execute();
441
+
442
+ expect(onExceptionCallback).not.toHaveBeenCalled();
443
+ expect(queueableFn2.fn).not.toHaveBeenCalled();
444
+
445
+ jasmine.clock().tick(100);
446
+
447
+ expect(onExceptionCallback).toHaveBeenCalledWith('foo');
448
+ expect(queueableFn2.fn).toHaveBeenCalled();
449
+ });
450
+ });
451
+
452
+ it("calls exception handlers when an exception is thrown in a fn", function() {
453
+ var queueableFn = { type: 'queueable',
454
+ fn: function() {
455
+ throw new Error('fake error');
456
+ } },
457
+ onExceptionCallback = jasmine.createSpy('on exception callback'),
458
+ queueRunner = new jasmineUnderTest.QueueRunner({
459
+ queueableFns: [queueableFn],
460
+ onException: onExceptionCallback
461
+ });
462
+
463
+ queueRunner.execute();
464
+
465
+ expect(onExceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
466
+ });
467
+
468
+ it("continues running the functions even after an exception is thrown in an async spec", function() {
469
+ var queueableFn = { fn: function(done) { throw new Error("error"); } },
470
+ nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
471
+ queueRunner = new jasmineUnderTest.QueueRunner({
472
+ queueableFns: [queueableFn, nextQueueableFn]
473
+ });
474
+
475
+ queueRunner.execute();
476
+ expect(nextQueueableFn.fn).toHaveBeenCalled();
477
+ });
478
+
479
+ describe("When configured to complete on first error", function() {
480
+ it("skips to cleanup functions on the first exception", function() {
481
+ var queueableFn = { fn: function() { throw new Error("error"); } },
482
+ nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
483
+ cleanupFn = { fn: jasmine.createSpy("cleanup") },
484
+ queueRunner = new jasmineUnderTest.QueueRunner({
485
+ queueableFns: [queueableFn, nextQueueableFn],
486
+ cleanupFns: [cleanupFn],
487
+ completeOnFirstError: true
488
+ });
489
+
490
+ queueRunner.execute();
491
+ expect(nextQueueableFn.fn).not.toHaveBeenCalled();
492
+ expect(cleanupFn.fn).toHaveBeenCalled();
493
+ });
494
+
495
+ it("does not skip when a cleanup function throws", function() {
496
+ var queueableFn = { fn: function() { } },
497
+ cleanupFn1 = { fn: function() { throw new Error("error"); } },
498
+ cleanupFn2 = { fn: jasmine.createSpy("cleanupFn2") },
499
+ queueRunner = new jasmineUnderTest.QueueRunner({
500
+ queueableFns: [queueableFn],
501
+ cleanupFns: [cleanupFn1, cleanupFn2],
502
+ completeOnFirstError: true
503
+ });
504
+
505
+ queueRunner.execute();
506
+ expect(cleanupFn2.fn).toHaveBeenCalled();
507
+ });
508
+
509
+ describe("with an asynchronous function", function() {
510
+ beforeEach(function() {
511
+ jasmine.clock().install();
512
+ });
513
+
514
+ afterEach(function() {
515
+ jasmine.clock().uninstall();
516
+ });
517
+
518
+
519
+ it("skips to cleanup functions on the first exception", function() {
520
+ var errorListeners = [],
521
+ queueableFn = { fn: function(done) {} },
522
+ nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
523
+ cleanupFn = { fn: jasmine.createSpy('cleanup') },
524
+ queueRunner = new jasmineUnderTest.QueueRunner({
525
+ globalErrors: {
526
+ pushListener: function(f) { errorListeners.push(f); },
527
+ popListener: function() { errorListeners.pop(); },
528
+ },
529
+ queueableFns: [queueableFn, nextQueueableFn],
530
+ cleanupFns: [cleanupFn],
531
+ completeOnFirstError: true,
532
+ });
533
+
534
+ queueRunner.execute();
535
+ errorListeners[errorListeners.length - 1](new Error('error'));
536
+ expect(nextQueueableFn.fn).not.toHaveBeenCalled();
537
+ expect(cleanupFn.fn).toHaveBeenCalled();
538
+ });
539
+
540
+ it("skips to cleanup functions when next.fail is called", function() {
541
+ var queueableFn = { fn: function(done) {
542
+ done.fail('nope');
543
+ } },
544
+ nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
545
+ cleanupFn = { fn: jasmine.createSpy('cleanup') },
546
+ queueRunner = new jasmineUnderTest.QueueRunner({
547
+ queueableFns: [queueableFn, nextQueueableFn],
548
+ cleanupFns: [cleanupFn],
549
+ completeOnFirstError: true,
550
+ });
551
+
552
+ queueRunner.execute();
553
+ jasmine.clock().tick();
554
+ expect(nextQueueableFn.fn).not.toHaveBeenCalled();
555
+ expect(cleanupFn.fn).toHaveBeenCalled();
556
+ });
557
+
558
+ it("skips to cleanup functions when next is called with an Error", function() {
559
+ var queueableFn = { fn: function(done) {
560
+ done(new Error('nope'));
561
+ } },
562
+ nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
563
+ cleanupFn = { fn: jasmine.createSpy('cleanup') },
564
+ queueRunner = new jasmineUnderTest.QueueRunner({
565
+ queueableFns: [queueableFn, nextQueueableFn],
566
+ cleanupFns: [cleanupFn],
567
+ completeOnFirstError: true,
568
+ });
569
+
570
+ queueRunner.execute();
571
+ jasmine.clock().tick();
572
+ expect(nextQueueableFn.fn).not.toHaveBeenCalled();
573
+ expect(cleanupFn.fn).toHaveBeenCalled();
574
+ });
575
+ });
576
+ });
577
+
578
+ it("calls a provided complete callback when done", function() {
579
+ var queueableFn = { fn: jasmine.createSpy('fn') },
580
+ completeCallback = jasmine.createSpy('completeCallback'),
581
+ queueRunner = new jasmineUnderTest.QueueRunner({
582
+ queueableFns: [queueableFn],
583
+ onComplete: completeCallback
584
+ });
585
+
586
+ queueRunner.execute();
587
+
588
+ expect(completeCallback).toHaveBeenCalled();
589
+ });
590
+
591
+ describe("clearing the stack", function() {
592
+ beforeEach(function() {
593
+ jasmine.clock().install();
594
+ });
595
+
596
+ afterEach(function() {
597
+ jasmine.clock().uninstall();
598
+ });
599
+
600
+ it("calls a provided stack clearing function when done", function() {
601
+ var asyncFn = { fn: function(done) { done() } },
602
+ afterFn = { fn: jasmine.createSpy('afterFn') },
603
+ completeCallback = jasmine.createSpy('completeCallback'),
604
+ clearStack = jasmine.createSpy('clearStack'),
605
+ queueRunner = new jasmineUnderTest.QueueRunner({
606
+ queueableFns: [asyncFn, afterFn],
607
+ clearStack: clearStack,
608
+ onComplete: completeCallback
609
+ });
610
+
611
+ clearStack.and.callFake(function(fn) { fn(); });
612
+
613
+ queueRunner.execute();
614
+ jasmine.clock().tick();
615
+ expect(afterFn.fn).toHaveBeenCalled();
616
+ expect(clearStack).toHaveBeenCalled();
617
+ clearStack.calls.argsFor(0)[0]();
618
+ expect(completeCallback).toHaveBeenCalled();
619
+ });
620
+ });
621
+
622
+ describe('when user context has not been defined', function() {
623
+ beforeEach(function() {
624
+ var fn;
625
+
626
+ this.fn = fn = jasmine.createSpy('fn1');
627
+ this.queueRunner = new jasmineUnderTest.QueueRunner({
628
+ queueableFns: [{ fn: fn }]
629
+ });
630
+ });
631
+
632
+ it('runs the functions on the scope of a UserContext', function() {
633
+ var calls = [],
634
+ context;
635
+
636
+ this.fn.and.callFake(function() {
637
+ context = this;
638
+ });
639
+
640
+ this.queueRunner.execute();
641
+
642
+ expect(context.constructor).toBe(jasmineUnderTest.UserContext);
643
+ });
644
+ });
645
+
646
+ describe('when user context has been defined', function() {
647
+ beforeEach(function() {
648
+ var fn, context;
649
+
650
+ this.fn = fn = jasmine.createSpy('fn1');
651
+ this.context = context = new jasmineUnderTest.UserContext();
652
+ this.queueRunner = new jasmineUnderTest.QueueRunner({
653
+ queueableFns: [{ fn: fn }],
654
+ userContext: context
655
+ });
656
+ });
657
+
658
+ it('runs the functions on the scope of a UserContext', function() {
659
+ var calls = [],
660
+ context;
661
+ this.fn.and.callFake(function() {
662
+ context = this;
663
+ });
664
+
665
+ this.queueRunner.execute();
666
+
667
+ expect(context).toBe(this.context);
668
+ });
669
+ });
670
+ });