jasmine-core 2.0.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/lib/console/console.js +54 -24
  3. data/lib/jasmine-core/__init__.py +1 -0
  4. data/lib/jasmine-core/boot/boot.js +2 -63
  5. data/lib/jasmine-core/boot/node_boot.js +19 -0
  6. data/lib/jasmine-core/boot.js +3 -64
  7. data/lib/jasmine-core/core.py +60 -0
  8. data/lib/jasmine-core/example/node_example/spec/PlayerSpec.js +60 -0
  9. data/lib/jasmine-core/example/node_example/spec/SpecHelper.js +15 -0
  10. data/lib/jasmine-core/example/node_example/src/Player.js +24 -0
  11. data/lib/jasmine-core/example/node_example/src/Song.js +9 -0
  12. data/lib/jasmine-core/jasmine-html.js +119 -74
  13. data/lib/jasmine-core/jasmine.css +61 -54
  14. data/lib/jasmine-core/jasmine.js +964 -456
  15. data/lib/jasmine-core/json2.js +73 -62
  16. data/lib/jasmine-core/node_boot.js +41 -0
  17. data/lib/jasmine-core/spec/console/ConsoleReporterSpec.js +52 -8
  18. data/lib/jasmine-core/spec/core/AnySpec.js +1 -0
  19. data/lib/jasmine-core/spec/core/ClockSpec.js +122 -18
  20. data/lib/jasmine-core/spec/core/DelayedFunctionSchedulerSpec.js +14 -1
  21. data/lib/jasmine-core/spec/core/EnvSpec.js +0 -63
  22. data/lib/jasmine-core/spec/core/ExceptionFormatterSpec.js +7 -0
  23. data/lib/jasmine-core/spec/core/ExceptionsSpec.js +2 -2
  24. data/lib/jasmine-core/spec/core/ExpectationSpec.js +46 -50
  25. data/lib/jasmine-core/spec/core/JsApiReporterSpec.js +37 -0
  26. data/lib/jasmine-core/spec/core/MockDateSpec.js +200 -0
  27. data/lib/jasmine-core/spec/core/ObjectContainingSpec.js +6 -0
  28. data/lib/jasmine-core/spec/core/PrettyPrintSpec.js +49 -12
  29. data/lib/jasmine-core/spec/core/QueueRunnerSpec.js +184 -60
  30. data/lib/jasmine-core/spec/core/SpecSpec.js +46 -108
  31. data/lib/jasmine-core/spec/core/SpyRegistrySpec.js +55 -0
  32. data/lib/jasmine-core/spec/core/SpySpec.js +10 -0
  33. data/lib/jasmine-core/spec/core/SpyStrategySpec.js +13 -0
  34. data/lib/jasmine-core/spec/core/SuiteSpec.js +143 -11
  35. data/lib/jasmine-core/spec/core/TimerSpec.js +18 -0
  36. data/lib/jasmine-core/spec/core/integration/CustomMatchersSpec.js +34 -32
  37. data/lib/jasmine-core/spec/core/integration/EnvSpec.js +998 -50
  38. data/lib/jasmine-core/spec/core/integration/SpecRunningSpec.js +279 -3
  39. data/lib/jasmine-core/spec/core/matchers/matchersUtilSpec.js +18 -1
  40. data/lib/jasmine-core/spec/core/matchers/toBeGreaterThanSpec.js +2 -1
  41. data/lib/jasmine-core/spec/core/matchers/toBeNaNSpec.js +3 -2
  42. data/lib/jasmine-core/spec/core/matchers/toBeUndefinedSpec.js +2 -1
  43. data/lib/jasmine-core/spec/core/matchers/toContainSpec.js +4 -2
  44. data/lib/jasmine-core/spec/core/matchers/toHaveBeenCalledSpec.js +2 -1
  45. data/lib/jasmine-core/spec/core/matchers/toHaveBeenCalledWithSpec.js +17 -3
  46. data/lib/jasmine-core/spec/core/matchers/toThrowErrorSpec.js +14 -14
  47. data/lib/jasmine-core/spec/core/matchers/toThrowSpec.js +5 -5
  48. data/lib/jasmine-core/spec/helpers/defineJasmineUnderTest.js +7 -0
  49. data/lib/jasmine-core/spec/helpers/nodeDefineJasmineUnderTest.js +33 -0
  50. data/lib/jasmine-core/spec/html/HtmlReporterSpec.js +183 -35
  51. data/lib/jasmine-core/spec/html/PrettyPrintHtmlSpec.js +1 -1
  52. data/lib/jasmine-core/spec/node_suite.js +9 -1
  53. data/lib/jasmine-core/spec/npmPackage/npmPackageSpec.js +104 -0
  54. data/lib/jasmine-core/spec/performance/large_object_test.js +36 -0
  55. data/lib/jasmine-core/version.rb +1 -1
  56. data/lib/jasmine-core.js +37 -0
  57. data/lib/jasmine-core.rb +6 -2
  58. metadata +23 -9
  59. data/lib/jasmine-core/spec/support/dev_boot.js +0 -124
@@ -0,0 +1,200 @@
1
+ describe("FakeDate", function() {
2
+ it("does not fail if no global date is found", function() {
3
+ var fakeGlobal = {},
4
+ mockDate = new j$.MockDate(fakeGlobal);
5
+
6
+ expect(function() {
7
+ mockDate.install();
8
+ mockDate.tick(0);
9
+ mockDate.uninstall();
10
+ }).not.toThrow();
11
+ });
12
+
13
+ it("replaces the global Date when it is installed", function() {
14
+ var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
15
+ return {
16
+ getTime: function() {}
17
+ }
18
+ }),
19
+ fakeGlobal = { Date: globalDate },
20
+ mockDate = new j$.MockDate(fakeGlobal);
21
+
22
+ expect(fakeGlobal.Date).toEqual(globalDate);
23
+ mockDate.install();
24
+
25
+ expect(fakeGlobal.Date).not.toEqual(globalDate);
26
+ });
27
+
28
+ it("replaces the global Date on uninstall", function() {
29
+ var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
30
+ return {
31
+ getTime: function() {}
32
+ }
33
+ }),
34
+ fakeGlobal = { Date: globalDate },
35
+ mockDate = new j$.MockDate(fakeGlobal);
36
+
37
+ mockDate.install();
38
+ mockDate.uninstall();
39
+
40
+ expect(fakeGlobal.Date).toEqual(globalDate);
41
+ });
42
+
43
+ it("takes the current time as the base when installing without parameters", function() {
44
+ var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
45
+ return {
46
+ getTime: function() {
47
+ return 1000;
48
+ }
49
+ }
50
+ }),
51
+ fakeGlobal = { Date: globalDate },
52
+ mockDate = new j$.MockDate(fakeGlobal);
53
+
54
+ mockDate.install();
55
+
56
+ globalDate.calls.reset();
57
+ new fakeGlobal.Date();
58
+ expect(globalDate).toHaveBeenCalledWith(1000);
59
+ });
60
+
61
+ it("can accept a date as time base when installing", function() {
62
+ var fakeGlobal = { Date: Date },
63
+ mockDate = new j$.MockDate(fakeGlobal),
64
+ baseDate = new Date();
65
+
66
+ spyOn(baseDate, 'getTime').and.returnValue(123);
67
+ mockDate.install(baseDate);
68
+
69
+ expect(new fakeGlobal.Date().getTime()).toEqual(123);
70
+ });
71
+
72
+ it("makes real dates", function() {
73
+ var fakeGlobal = { Date: Date },
74
+ mockDate = new j$.MockDate(fakeGlobal);
75
+
76
+ mockDate.install();
77
+ expect(new fakeGlobal.Date()).toEqual(jasmine.any(Date));
78
+ expect(new fakeGlobal.Date() instanceof fakeGlobal.Date).toBe(true);
79
+ });
80
+
81
+ it("fakes current time when using Date.now()", function() {
82
+ var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
83
+ return {
84
+ getTime: function() {
85
+ return 1000;
86
+ }
87
+ }
88
+ }),
89
+ fakeGlobal = { Date: globalDate };
90
+
91
+ globalDate.now = function() {};
92
+ var mockDate = new j$.MockDate(fakeGlobal);
93
+
94
+ mockDate.install();
95
+
96
+ expect(fakeGlobal.Date.now()).toEqual(1000);
97
+ });
98
+
99
+ it("does not stub Date.now() if it doesn't already exist", function() {
100
+ var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
101
+ return {
102
+ getTime: function() {
103
+ return 1000;
104
+ }
105
+ }
106
+ }),
107
+ fakeGlobal = { Date: globalDate },
108
+ mockDate = new j$.MockDate(fakeGlobal);
109
+
110
+ mockDate.install();
111
+
112
+ expect(fakeGlobal.Date.now).toThrowError("Browser does not support Date.now()");
113
+ });
114
+
115
+ it("makes time passes using tick", function() {
116
+ var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
117
+ return {
118
+ getTime: function() {
119
+ return 1000;
120
+ }
121
+ }
122
+ }),
123
+ fakeGlobal = { Date: globalDate };
124
+
125
+ globalDate.now = function() {};
126
+ var mockDate = new j$.MockDate(fakeGlobal);
127
+
128
+ mockDate.install();
129
+
130
+ mockDate.tick(100);
131
+
132
+ expect(fakeGlobal.Date.now()).toEqual(1100);
133
+
134
+ mockDate.tick(1000);
135
+
136
+ expect(fakeGlobal.Date.now()).toEqual(2100);
137
+ });
138
+
139
+ it("allows to increase 0 milliseconds using tick", function() {
140
+ var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
141
+ return {
142
+ getTime: function() {
143
+ return 1000;
144
+ }
145
+ }
146
+ }),
147
+ fakeGlobal = { Date: globalDate };
148
+
149
+ globalDate.now = function() {};
150
+ var mockDate = new j$.MockDate(fakeGlobal);
151
+
152
+ mockDate.install();
153
+
154
+ mockDate.tick(0);
155
+ expect(fakeGlobal.Date.now()).toEqual(1000);
156
+
157
+ mockDate.tick();
158
+ expect(fakeGlobal.Date.now()).toEqual(1000);
159
+ });
160
+
161
+ it("allows creation of a Date in a different time than the mocked time", function() {
162
+ var fakeGlobal = { Date: Date },
163
+ mockDate = new j$.MockDate(fakeGlobal);
164
+
165
+ mockDate.install();
166
+
167
+ var otherDate = new fakeGlobal.Date(2013, 9, 23, 0, 0, 1, 0);
168
+ expect(otherDate.getTime()).toEqual(new Date(2013, 9, 23, 0, 0, 1, 0).getTime());
169
+ });
170
+
171
+ it("allows creation of a Date that isn't fully specified", function() {
172
+ var fakeGlobal = { Date: Date },
173
+ mockDate = new j$.MockDate(fakeGlobal);
174
+
175
+ mockDate.install();
176
+
177
+ var otherDate = new fakeGlobal.Date(2013, 9, 23);
178
+ expect(otherDate.getTime()).toEqual(new Date(2013, 9, 23).getTime());
179
+ });
180
+
181
+ it('allows creation of a Date with millis', function() {
182
+ var fakeGlobal = { Date: Date },
183
+ mockDate = new j$.MockDate(fakeGlobal),
184
+ now = new Date(2014, 3, 15).getTime();
185
+
186
+ mockDate.install();
187
+
188
+ var otherDate = new fakeGlobal.Date(now);
189
+ expect(otherDate.getTime()).toEqual(now);
190
+ });
191
+
192
+ it("copies all Date properties to the mocked date", function() {
193
+ var fakeGlobal = { Date: Date },
194
+ mockDate = new j$.MockDate(fakeGlobal);
195
+
196
+ mockDate.install();
197
+
198
+ expect(fakeGlobal.Date.UTC(2013, 9, 23)).toEqual(Date.UTC(2013, 9, 23));
199
+ });
200
+ });
@@ -61,4 +61,10 @@ describe("ObjectContaining", function() {
61
61
 
62
62
  expect(containing.jasmineToString()).toMatch("<jasmine.objectContaining");
63
63
  });
64
+
65
+ it("matches recursively", function() {
66
+ var containing = new j$.ObjectContaining({one: new j$.ObjectContaining({two: {}})});
67
+
68
+ expect(containing.jasmineMatches({one: {two: {}}})).toBe(true);
69
+ });
64
70
  });
@@ -11,6 +11,7 @@ describe("j$.pp", function () {
11
11
  expect(j$.pp(jasmine.undefined)).toEqual("undefined");
12
12
  expect(j$.pp(3)).toEqual("3");
13
13
  expect(j$.pp(-3.14)).toEqual("-3.14");
14
+ expect(j$.pp(-0)).toEqual("-0");
14
15
  });
15
16
 
16
17
  it("should stringify arrays properly", function() {
@@ -25,11 +26,16 @@ describe("j$.pp", function () {
25
26
  expect(j$.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
26
27
  });
27
28
 
29
+ it("should not indicate circular references incorrectly", function() {
30
+ var array = [ [1] ];
31
+ expect(j$.pp(array)).toEqual("[ [ 1 ] ]");
32
+ });
33
+
28
34
  it("should stringify objects properly", function() {
29
- expect(j$.pp({foo: 'bar'})).toEqual("{ foo : 'bar' }");
30
- expect(j$.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("{ foo : 'bar', baz : 3, nullValue : null, undefinedValue : undefined }");
35
+ expect(j$.pp({foo: 'bar'})).toEqual("{ foo: 'bar' }");
36
+ expect(j$.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("{ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined }");
31
37
  expect(j$.pp({foo: function () {
32
- }, bar: [1, 2, 3]})).toEqual("{ foo : Function, bar : [ 1, 2, 3 ] }");
38
+ }, bar: [1, 2, 3]})).toEqual("{ foo: Function, bar: [ 1, 2, 3 ] }");
33
39
  });
34
40
 
35
41
  it("should not include inherited properties when stringifying an object", function() {
@@ -37,7 +43,7 @@ describe("j$.pp", function () {
37
43
  SomeClass.prototype.foo = "inherited foo";
38
44
  var instance = new SomeClass();
39
45
  instance.bar = "my own bar";
40
- expect(j$.pp(instance)).toEqual("{ bar : 'my own bar' }");
46
+ expect(j$.pp(instance)).toEqual("{ bar: 'my own bar' }");
41
47
  });
42
48
 
43
49
  it("should not recurse objects and arrays more deeply than j$.MAX_PRETTY_PRINT_DEPTH", function() {
@@ -47,21 +53,42 @@ describe("j$.pp", function () {
47
53
 
48
54
  try {
49
55
  j$.MAX_PRETTY_PRINT_DEPTH = 2;
50
- expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : Object } }");
56
+ expect(j$.pp(nestedObject)).toEqual("{ level1: { level2: Object } }");
51
57
  expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, Array ] ]");
52
58
 
53
59
  j$.MAX_PRETTY_PRINT_DEPTH = 3;
54
- expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : { level3 : Object } } }");
60
+ expect(j$.pp(nestedObject)).toEqual("{ level1: { level2: { level3: Object } } }");
55
61
  expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, Array ] ] ]");
56
62
 
57
63
  j$.MAX_PRETTY_PRINT_DEPTH = 4;
58
- expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : { level3 : { level4 : 'leaf' } } } }");
64
+ expect(j$.pp(nestedObject)).toEqual("{ level1: { level2: { level3: { level4: 'leaf' } } } }");
59
65
  expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
60
66
  } finally {
61
67
  j$.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
62
68
  }
63
69
  });
64
70
 
71
+ it("should stringify immutable circular objects", function(){
72
+ if(Object.freeze){
73
+ var frozenObject = {foo: {bar: 'baz'}};
74
+ frozenObject.circular = frozenObject;
75
+ frozenObject = Object.freeze(frozenObject);
76
+ expect(j$.pp(frozenObject)).toEqual("{ foo: { bar: 'baz' }, circular: <circular reference: Object> }");
77
+ }
78
+ });
79
+
80
+ it("should truncate arrays that are longer than j$.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
81
+ var originalMaxLength = j$.MAX_PRETTY_PRINT_ARRAY_LENGTH;
82
+ var array = [1, 2, 3];
83
+
84
+ try {
85
+ j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
86
+ expect(j$.pp(array)).toEqual("[ 1, 2, ... ]");
87
+ } finally {
88
+ j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
89
+ }
90
+ });
91
+
65
92
  it("should stringify RegExp objects properly", function() {
66
93
  expect(j$.pp(/x|y|z/)).toEqual("/x|y|z/");
67
94
  });
@@ -69,7 +96,7 @@ describe("j$.pp", function () {
69
96
  it("should indicate circular object references", function() {
70
97
  var sampleValue = {foo: 'hello'};
71
98
  sampleValue.nested = sampleValue;
72
- expect(j$.pp(sampleValue)).toEqual("{ foo : 'hello', nested : <circular reference: Object> }");
99
+ expect(j$.pp(sampleValue)).toEqual("{ foo: 'hello', nested: <circular reference: Object> }");
73
100
  });
74
101
 
75
102
  it("should indicate getters on objects as such", function() {
@@ -81,10 +108,10 @@ describe("j$.pp", function () {
81
108
  });
82
109
  }
83
110
  if (sampleValue.__defineGetter__) {
84
- expect(j$.pp(sampleValue)).toEqual("{ id : 1, calculatedValue : <getter> }");
111
+ expect(j$.pp(sampleValue)).toEqual("{ id: 1, calculatedValue: <getter> }");
85
112
  }
86
113
  else {
87
- expect(j$.pp(sampleValue)).toEqual("{ id : 1 }");
114
+ expect(j$.pp(sampleValue)).toEqual("{ id: 1 }");
88
115
  }
89
116
  });
90
117
 
@@ -108,7 +135,9 @@ describe("j$.pp", function () {
108
135
  },
109
136
  env = new j$.Env();
110
137
 
111
- env.spyOn(TestObject, 'someFunction');
138
+ var spyRegistry = new j$.SpyRegistry({currentSpies: function() {return [];}});
139
+
140
+ spyRegistry.spyOn(TestObject, 'someFunction');
112
141
  expect(j$.pp(TestObject.someFunction)).toEqual("spy on someFunction");
113
142
 
114
143
  expect(j$.pp(j$.createSpy("something"))).toEqual("spy on something");
@@ -121,5 +150,13 @@ describe("j$.pp", function () {
121
150
 
122
151
  expect(j$.pp(obj)).toEqual("strung");
123
152
  });
124
- });
125
153
 
154
+ it("should handle objects with null prototype", function() {
155
+ if (jasmine.getEnv().ieVersion < 9) { return; }
156
+
157
+ var obj = Object.create(null);
158
+ obj.foo = 'bar';
159
+
160
+ expect(j$.pp(obj)).toEqual("{ foo: 'bar' }");
161
+ });
162
+ });
@@ -2,15 +2,15 @@ describe("QueueRunner", function() {
2
2
 
3
3
  it("runs all the functions it's passed", function() {
4
4
  var calls = [],
5
- fn1 = jasmine.createSpy('fn1'),
6
- fn2 = jasmine.createSpy('fn2'),
5
+ queueableFn1 = { fn: jasmine.createSpy('fn1') },
6
+ queueableFn2 = { fn: jasmine.createSpy('fn2') },
7
7
  queueRunner = new j$.QueueRunner({
8
- fns: [fn1, fn2]
8
+ queueableFns: [queueableFn1, queueableFn2]
9
9
  });
10
- fn1.and.callFake(function() {
10
+ queueableFn1.fn.and.callFake(function() {
11
11
  calls.push('fn1');
12
12
  });
13
- fn2.and.callFake(function() {
13
+ queueableFn2.fn.and.callFake(function() {
14
14
  calls.push('fn2');
15
15
  });
16
16
 
@@ -20,19 +20,19 @@ describe("QueueRunner", function() {
20
20
  });
21
21
 
22
22
  it("calls each function with a consistent 'this'-- an empty object", function() {
23
- var fn1 = jasmine.createSpy('fn1'),
24
- fn2 = jasmine.createSpy('fn2'),
25
- fn3 = function(done) { asyncContext = this; done(); },
23
+ var queueableFn1 = { fn: jasmine.createSpy('fn1') },
24
+ queueableFn2 = { fn: jasmine.createSpy('fn2') },
25
+ queueableFn3 = { fn: function(done) { asyncContext = this; done(); } },
26
26
  queueRunner = new j$.QueueRunner({
27
- fns: [fn1, fn2, fn3]
27
+ queueableFns: [queueableFn1, queueableFn2, queueableFn3]
28
28
  }),
29
29
  asyncContext;
30
30
 
31
31
  queueRunner.execute();
32
32
 
33
- var context = fn1.calls.first().object;
33
+ var context = queueableFn1.fn.calls.first().object;
34
34
  expect(context).toEqual({});
35
- expect(fn2.calls.first().object).toBe(context);
35
+ expect(queueableFn2.fn.calls.first().object).toBe(context);
36
36
  expect(asyncContext).toBe(context);
37
37
  });
38
38
 
@@ -50,31 +50,25 @@ describe("QueueRunner", function() {
50
50
  //createSpy('asyncfn').and.callFake(function(done) {});
51
51
 
52
52
  var onComplete = jasmine.createSpy('onComplete'),
53
- beforeCallback = jasmine.createSpy('beforeCallback'),
54
- fnCallback = jasmine.createSpy('fnCallback'),
55
- afterCallback = jasmine.createSpy('afterCallback'),
56
- fn1 = function(done) {
57
- beforeCallback();
58
- setTimeout(function() {
59
- done()
60
- }, 100);
61
- },
62
- fn2 = function(done) {
63
- fnCallback();
64
- setTimeout(function() {
65
- done()
66
- }, 100);
67
- },
68
- fn3 = function(done) {
69
- afterCallback();
70
- setTimeout(function() {
71
- done()
72
- }, 100);
73
- },
74
- queueRunner = new j$.QueueRunner({
75
- fns: [fn1, fn2, fn3],
76
- onComplete: onComplete
77
- });
53
+ beforeCallback = jasmine.createSpy('beforeCallback'),
54
+ fnCallback = jasmine.createSpy('fnCallback'),
55
+ afterCallback = jasmine.createSpy('afterCallback'),
56
+ queueableFn1 = { fn: function(done) {
57
+ beforeCallback();
58
+ setTimeout(done, 100);
59
+ } },
60
+ queueableFn2 = { fn: function(done) {
61
+ fnCallback();
62
+ setTimeout(done, 100);
63
+ } },
64
+ queueableFn3 = { fn: function(done) {
65
+ afterCallback();
66
+ setTimeout(done, 100);
67
+ } },
68
+ queueRunner = new j$.QueueRunner({
69
+ queueableFns: [queueableFn1, queueableFn2, queueableFn3],
70
+ onComplete: onComplete
71
+ });
78
72
 
79
73
  queueRunner.execute();
80
74
 
@@ -98,52 +92,182 @@ describe("QueueRunner", function() {
98
92
 
99
93
  expect(onComplete).toHaveBeenCalled();
100
94
  });
95
+
96
+ it("explicitly fails an async function with a provided fail function and moves to the next function", function() {
97
+ var queueableFn1 = { fn: function(done) {
98
+ setTimeout(function() { done.fail('foo'); }, 100);
99
+ } },
100
+ queueableFn2 = { fn: jasmine.createSpy('fn2') },
101
+ failFn = jasmine.createSpy('fail'),
102
+ queueRunner = new j$.QueueRunner({
103
+ queueableFns: [queueableFn1, queueableFn2],
104
+ fail: failFn
105
+ });
106
+
107
+ queueRunner.execute();
108
+
109
+ expect(failFn).not.toHaveBeenCalled();
110
+ expect(queueableFn2.fn).not.toHaveBeenCalled();
111
+
112
+ jasmine.clock().tick(100);
113
+
114
+ expect(failFn).toHaveBeenCalledWith('foo');
115
+ expect(queueableFn2.fn).toHaveBeenCalled();
116
+ });
117
+
118
+ it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() {
119
+ var timeout = 3,
120
+ beforeFn = { fn: function(done) { }, type: 'before', timeout: function() { return timeout; } },
121
+ queueableFn = { fn: jasmine.createSpy('fn'), type: 'queueable' },
122
+ onComplete = jasmine.createSpy('onComplete'),
123
+ onException = jasmine.createSpy('onException'),
124
+ queueRunner = new j$.QueueRunner({
125
+ queueableFns: [beforeFn, queueableFn],
126
+ onComplete: onComplete,
127
+ onException: onException
128
+ });
129
+
130
+ queueRunner.execute();
131
+ expect(queueableFn.fn).not.toHaveBeenCalled();
132
+
133
+ jasmine.clock().tick(timeout);
134
+
135
+ expect(onException).toHaveBeenCalledWith(jasmine.any(Error));
136
+ expect(queueableFn.fn).toHaveBeenCalled();
137
+ expect(onComplete).toHaveBeenCalled();
138
+ });
139
+
140
+ it("by default does not set a timeout for asynchronous functions", function() {
141
+ var beforeFn = { fn: function(done) { } },
142
+ queueableFn = { fn: jasmine.createSpy('fn') },
143
+ onComplete = jasmine.createSpy('onComplete'),
144
+ onException = jasmine.createSpy('onException'),
145
+ queueRunner = new j$.QueueRunner({
146
+ queueableFns: [beforeFn, queueableFn],
147
+ onComplete: onComplete,
148
+ onException: onException,
149
+ });
150
+
151
+ queueRunner.execute();
152
+ expect(queueableFn.fn).not.toHaveBeenCalled();
153
+
154
+ jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
155
+
156
+ expect(onException).not.toHaveBeenCalled();
157
+ expect(queueableFn.fn).not.toHaveBeenCalled();
158
+ expect(onComplete).not.toHaveBeenCalled();
159
+ });
160
+
161
+ it("clears the timeout when an async function throws an exception, to prevent additional exception reporting", function() {
162
+ var queueableFn = { fn: function(done) { throw new Error("error!"); } },
163
+ onComplete = jasmine.createSpy('onComplete'),
164
+ onException = jasmine.createSpy('onException'),
165
+ queueRunner = new j$.QueueRunner({
166
+ queueableFns: [queueableFn],
167
+ onComplete: onComplete,
168
+ onException: onException
169
+ });
170
+
171
+ queueRunner.execute();
172
+
173
+ expect(onComplete).toHaveBeenCalled();
174
+ expect(onException).toHaveBeenCalled();
175
+
176
+ jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
177
+ expect(onException.calls.count()).toEqual(1);
178
+ });
179
+
180
+ it("clears the timeout when the done callback is called", function() {
181
+ var queueableFn = { fn: function(done) { done(); } },
182
+ onComplete = jasmine.createSpy('onComplete'),
183
+ onException = jasmine.createSpy('onException'),
184
+ queueRunner = new j$.QueueRunner({
185
+ queueableFns: [queueableFn],
186
+ onComplete: onComplete,
187
+ onException: onException
188
+ });
189
+
190
+ queueRunner.execute();
191
+
192
+ expect(onComplete).toHaveBeenCalled();
193
+
194
+ jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
195
+ expect(onException).not.toHaveBeenCalled();
196
+ });
197
+
198
+ it("only moves to the next spec the first time you call done", function() {
199
+ var queueableFn = { fn: function(done) {done(); done();} },
200
+ nextQueueableFn = { fn: jasmine.createSpy('nextFn') };
201
+ queueRunner = new j$.QueueRunner({
202
+ queueableFns: [queueableFn, nextQueueableFn]
203
+ });
204
+
205
+ queueRunner.execute();
206
+ expect(nextQueueableFn.fn.calls.count()).toEqual(1);
207
+ });
208
+
209
+ it("does not move to the next spec if done is called after an exception has ended the spec", function() {
210
+ var queueableFn = { fn: function(done) {
211
+ setTimeout(done, 1);
212
+ throw new Error('error!');
213
+ } },
214
+ nextQueueableFn = { fn: jasmine.createSpy('nextFn') };
215
+ queueRunner = new j$.QueueRunner({
216
+ queueableFns: [queueableFn, nextQueueableFn]
217
+ });
218
+
219
+ queueRunner.execute();
220
+ jasmine.clock().tick(1);
221
+ expect(nextQueueableFn.fn.calls.count()).toEqual(1);
222
+ });
101
223
  });
102
224
 
103
- it("calls an exception handler when an exception is thrown in a fn", function() {
104
- var fn = function() {
225
+ it("calls exception handlers when an exception is thrown in a fn", function() {
226
+ var queueableFn = { type: 'queueable',
227
+ fn: function() {
105
228
  throw new Error('fake error');
106
- },
107
- exceptionCallback = jasmine.createSpy('exception callback'),
229
+ } },
230
+ onExceptionCallback = jasmine.createSpy('on exception callback'),
108
231
  queueRunner = new j$.QueueRunner({
109
- fns: [fn],
110
- onException: exceptionCallback
232
+ queueableFns: [queueableFn],
233
+ onException: onExceptionCallback
111
234
  });
112
235
 
113
236
  queueRunner.execute();
114
237
 
115
- expect(exceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
238
+ expect(onExceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
116
239
  });
117
240
 
118
241
  it("rethrows an exception if told to", function() {
119
- var fn = function() {
242
+ var queueableFn = { fn: function() {
120
243
  throw new Error('fake error');
121
- },
244
+ } },
122
245
  queueRunner = new j$.QueueRunner({
123
- fns: [fn],
246
+ queueableFns: [queueableFn],
124
247
  catchException: function(e) { return false; }
125
248
  });
126
249
 
127
- expect(function() { queueRunner.execute(); }).toThrow();
250
+ expect(function() {
251
+ queueRunner.execute();
252
+ }).toThrowError('fake error');
128
253
  });
129
254
 
130
255
  it("continues running the functions even after an exception is thrown in an async spec", function() {
131
- var fn = function(done) { throw new Error("error"); },
132
- nextFn = jasmine.createSpy("nextFunction");
133
-
134
- queueRunner = new j$.QueueRunner({
135
- fns: [fn, nextFn]
136
- });
256
+ var queueableFn = { fn: function(done) { throw new Error("error"); } },
257
+ nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
258
+ queueRunner = new j$.QueueRunner({
259
+ queueableFns: [queueableFn, nextQueueableFn]
260
+ });
137
261
 
138
262
  queueRunner.execute();
139
- expect(nextFn).toHaveBeenCalled();
263
+ expect(nextQueueableFn.fn).toHaveBeenCalled();
140
264
  });
141
265
 
142
266
  it("calls a provided complete callback when done", function() {
143
- var fn = jasmine.createSpy('fn'),
267
+ var queueableFn = { fn: jasmine.createSpy('fn') },
144
268
  completeCallback = jasmine.createSpy('completeCallback'),
145
269
  queueRunner = new j$.QueueRunner({
146
- fns: [fn],
270
+ queueableFns: [queueableFn],
147
271
  onComplete: completeCallback
148
272
  });
149
273
 
@@ -153,12 +277,12 @@ describe("QueueRunner", function() {
153
277
  });
154
278
 
155
279
  it("calls a provided stack clearing function when done", function() {
156
- var asyncFn = function(done) { done() },
157
- afterFn = jasmine.createSpy('afterFn'),
280
+ var asyncFn = { fn: function(done) { done() } },
281
+ afterFn = { fn: jasmine.createSpy('afterFn') },
158
282
  completeCallback = jasmine.createSpy('completeCallback'),
159
283
  clearStack = jasmine.createSpy('clearStack'),
160
284
  queueRunner = new j$.QueueRunner({
161
- fns: [asyncFn, afterFn],
285
+ queueableFns: [asyncFn, afterFn],
162
286
  clearStack: clearStack,
163
287
  onComplete: completeCallback
164
288
  });
@@ -166,7 +290,7 @@ describe("QueueRunner", function() {
166
290
  clearStack.and.callFake(function(fn) { fn(); });
167
291
 
168
292
  queueRunner.execute();
169
- expect(afterFn).toHaveBeenCalled();
293
+ expect(afterFn.fn).toHaveBeenCalled();
170
294
  expect(clearStack).toHaveBeenCalledWith(completeCallback);
171
295
  });
172
296
  });