jasmine-core 2.5.2 → 2.6.0

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/console/console.js +1 -1
  3. data/lib/jasmine-core/boot/boot.js +4 -1
  4. data/lib/jasmine-core/boot.js +5 -2
  5. data/lib/jasmine-core/jasmine-html.js +19 -1
  6. data/lib/jasmine-core/jasmine.js +2859 -1571
  7. data/lib/jasmine-core/node_boot.js +1 -1
  8. data/lib/jasmine-core/spec/core/ClearStackSpec.js +67 -0
  9. data/lib/jasmine-core/spec/core/EnvSpec.js +100 -10
  10. data/lib/jasmine-core/spec/core/ExpectationSpec.js +52 -7
  11. data/lib/jasmine-core/spec/core/GlobalErrorsSpec.js +94 -0
  12. data/lib/jasmine-core/spec/core/PrettyPrintSpec.js +37 -1
  13. data/lib/jasmine-core/spec/core/QueueRunnerSpec.js +37 -0
  14. data/lib/jasmine-core/spec/core/SpyRegistrySpec.js +183 -0
  15. data/lib/jasmine-core/spec/core/SpySpec.js +44 -2
  16. data/lib/jasmine-core/spec/core/SuiteSpec.js +3 -18
  17. data/lib/jasmine-core/spec/core/UtilSpec.js +71 -0
  18. data/lib/jasmine-core/spec/core/asymmetric_equality/ArrayContainingSpec.js +13 -0
  19. data/lib/jasmine-core/spec/core/asymmetric_equality/ObjectContainingSpec.js +13 -0
  20. data/lib/jasmine-core/spec/core/integration/CustomMatchersSpec.js +47 -0
  21. data/lib/jasmine-core/spec/core/integration/EnvSpec.js +85 -14
  22. data/lib/jasmine-core/spec/core/integration/SpecRunningSpec.js +45 -3
  23. data/lib/jasmine-core/spec/core/matchers/DiffBuilderSpec.js +47 -0
  24. data/lib/jasmine-core/spec/core/matchers/NullDiffBuilderSpec.js +13 -0
  25. data/lib/jasmine-core/spec/core/matchers/ObjectPathSpec.js +43 -0
  26. data/lib/jasmine-core/spec/core/matchers/matchersUtilSpec.js +57 -1
  27. data/lib/jasmine-core/spec/core/matchers/toBeNegativeInfinitySpec.js +31 -0
  28. data/lib/jasmine-core/spec/core/matchers/toBePositiveInfinitySpec.js +31 -0
  29. data/lib/jasmine-core/spec/core/matchers/toEqualSpec.js +492 -4
  30. data/lib/jasmine-core/spec/core/matchers/toHaveBeenCalledBeforeSpec.js +99 -0
  31. data/lib/jasmine-core/spec/core/matchers/toThrowErrorSpec.js +37 -0
  32. data/lib/jasmine-core/spec/helpers/BrowserFlags.js +4 -0
  33. data/lib/jasmine-core/spec/helpers/checkForSet.js +21 -0
  34. data/lib/jasmine-core/spec/html/HtmlReporterSpec.js +58 -0
  35. data/lib/jasmine-core/spec/npmPackage/npmPackageSpec.js +1 -1
  36. data/lib/jasmine-core/version.rb +1 -1
  37. metadata +11 -4
@@ -16,6 +16,22 @@ describe("SpyRegistry", function() {
16
16
  }).toThrowError(/No method name supplied/);
17
17
  });
18
18
 
19
+ it("checks that the object is not `null`", function() {
20
+ var spyRegistry = new jasmineUnderTest.SpyRegistry();
21
+ expect(function() {
22
+ spyRegistry.spyOn(null, 'pants');
23
+ }).toThrowError(/could not find an object/);
24
+ });
25
+
26
+ it("checks that the method name is not `null`", function() {
27
+ var spyRegistry = new jasmineUnderTest.SpyRegistry(),
28
+ subject = {};
29
+
30
+ expect(function() {
31
+ spyRegistry.spyOn(subject, null);
32
+ }).toThrowError(/No method name supplied/);
33
+ });
34
+
19
35
  it("checks for the existence of the method", function() {
20
36
  var spyRegistry = new jasmineUnderTest.SpyRegistry(),
21
37
  subject = {};
@@ -77,6 +93,126 @@ describe("SpyRegistry", function() {
77
93
  });
78
94
  });
79
95
 
96
+ describe("#spyOnProperty", function() {
97
+ // IE 8 doesn't support `definePropery` on non-DOM nodes
98
+ if (jasmine.getEnv().ieVersion < 9) { return; }
99
+
100
+ it("checks for the existence of the object", function() {
101
+ var spyRegistry = new jasmineUnderTest.SpyRegistry();
102
+ expect(function() {
103
+ spyRegistry.spyOnProperty(void 0, 'pants');
104
+ }).toThrowError(/could not find an object/);
105
+ });
106
+
107
+ it("checks that a property name was passed", function() {
108
+ var spyRegistry = new jasmineUnderTest.SpyRegistry(),
109
+ subject = {};
110
+
111
+ expect(function() {
112
+ spyRegistry.spyOnProperty(subject);
113
+ }).toThrowError(/No property name supplied/);
114
+ });
115
+
116
+ it("checks for the existence of the method", function() {
117
+ var spyRegistry = new jasmineUnderTest.SpyRegistry(),
118
+ subject = {};
119
+
120
+ expect(function() {
121
+ spyRegistry.spyOnProperty(subject, 'pants');
122
+ }).toThrowError(/property does not exist/);
123
+ });
124
+
125
+ it("checks for the existence of access type", function() {
126
+ var spyRegistry = new jasmineUnderTest.SpyRegistry(),
127
+ subject = {};
128
+
129
+ Object.defineProperty(subject, 'pants', {
130
+ get: function() { return 1; },
131
+ configurable: true
132
+ });
133
+
134
+ expect(function() {
135
+ spyRegistry.spyOnProperty(subject, 'pants', 'set');
136
+ }).toThrowError(/does not have access type/);
137
+ });
138
+
139
+ it("checks if it has already been spied upon", function() {
140
+ var spyRegistry = new jasmineUnderTest.SpyRegistry(),
141
+ subject = {};
142
+
143
+ Object.defineProperty(subject, 'spiedProp', {
144
+ get: function() { return 1; },
145
+ configurable: true
146
+ });
147
+
148
+ spyRegistry.spyOnProperty(subject, 'spiedProp');
149
+
150
+ expect(function() {
151
+ spyRegistry.spyOnProperty(subject, 'spiedProp');
152
+ }).toThrowError(/has already been spied upon/);
153
+ });
154
+
155
+ it("checks if it can be spied upon", function() {
156
+ var subject = {};
157
+
158
+ Object.defineProperty(subject, 'myProp', {
159
+ get: function() {}
160
+ });
161
+
162
+ Object.defineProperty(subject, 'spiedProp', {
163
+ get: function() {},
164
+ configurable: true
165
+ });
166
+
167
+ var spyRegistry = new jasmineUnderTest.SpyRegistry();
168
+
169
+ expect(function() {
170
+ spyRegistry.spyOnProperty(subject, 'myProp');
171
+ }).toThrowError(/is not declared configurable/);
172
+
173
+ expect(function() {
174
+ spyRegistry.spyOnProperty(subject, 'spiedProp');
175
+ }).not.toThrowError(/is not declared configurable/);
176
+ });
177
+
178
+ it("overrides the property getter on the object and returns the spy", function() {
179
+ var spyRegistry = new jasmineUnderTest.SpyRegistry(),
180
+ subject = {},
181
+ returnValue = 1;
182
+
183
+ Object.defineProperty(subject, 'spiedProperty', {
184
+ get: function() { return returnValue; },
185
+ configurable: true
186
+ });
187
+
188
+ expect(subject.spiedProperty).toEqual(returnValue);
189
+
190
+ var spy = spyRegistry.spyOnProperty(subject, 'spiedProperty');
191
+ var getter = Object.getOwnPropertyDescriptor(subject, 'spiedProperty').get;
192
+
193
+ expect(getter).toEqual(spy);
194
+ expect(subject.spiedProperty).toBeUndefined();
195
+ });
196
+
197
+ it("overrides the property setter on the object and returns the spy", function() {
198
+ var spyRegistry = new jasmineUnderTest.SpyRegistry(),
199
+ subject = {},
200
+ returnValue = 1;
201
+
202
+ Object.defineProperty(subject, 'spiedProperty', {
203
+ get: function() { return returnValue; },
204
+ set: function() {},
205
+ configurable: true
206
+ });
207
+
208
+ var spy = spyRegistry.spyOnProperty(subject, 'spiedProperty', 'set');
209
+ var setter = Object.getOwnPropertyDescriptor(subject, 'spiedProperty').set;
210
+
211
+ expect(subject.spiedProperty).toEqual(returnValue);
212
+ expect(setter).toEqual(spy);
213
+ });
214
+ });
215
+
80
216
  describe("#clearSpies", function() {
81
217
  it("restores the original functions on the spied-upon objects", function() {
82
218
  var spies = [],
@@ -152,4 +288,51 @@ describe("SpyRegistry", function() {
152
288
  expect(jasmineUnderTest.isSpy(subject.spiedFunc)).toBe(false);
153
289
  });
154
290
  });
291
+
292
+ describe('spying on properties', function() {
293
+ it("restores the original properties on the spied-upon objects", function() {
294
+ // IE 8 doesn't support `definePropery` on non-DOM nodes
295
+ if (jasmine.getEnv().ieVersion < 9) { return; }
296
+
297
+ var spies = [],
298
+ spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
299
+ originalReturn = 1,
300
+ subject = {};
301
+
302
+ Object.defineProperty(subject, 'spiedProp', {
303
+ get: function() { return originalReturn; },
304
+ configurable: true
305
+ });
306
+
307
+ spyRegistry.spyOnProperty(subject, 'spiedProp');
308
+ spyRegistry.clearSpies();
309
+
310
+ expect(subject.spiedProp).toBe(originalReturn);
311
+ });
312
+
313
+ it("does not add a property that the spied-upon object didn't originally have", function() {
314
+ // IE 8 doesn't support `Object.create`
315
+ if (jasmine.getEnv().ieVersion < 9) { return; }
316
+
317
+ var spies = [],
318
+ spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
319
+ originalReturn = 1,
320
+ subjectParent = {};
321
+
322
+ Object.defineProperty(subjectParent, 'spiedProp', {
323
+ get: function() { return originalReturn; },
324
+ configurable: true
325
+ });
326
+
327
+ var subject = Object.create(subjectParent);
328
+
329
+ expect(subject.hasOwnProperty('spiedProp')).toBe(false);
330
+
331
+ spyRegistry.spyOnProperty(subject, 'spiedProp');
332
+ spyRegistry.clearSpies();
333
+
334
+ expect(subject.hasOwnProperty('spiedProp')).toBe(false);
335
+ expect(subject.spiedProp).toBe(originalReturn);
336
+ });
337
+ });
155
338
  });
@@ -57,9 +57,39 @@ describe('Spies', function () {
57
57
 
58
58
  expect(trackSpy.calls.mostRecent().args[0].returnValue).toEqual("return value");
59
59
  });
60
+
61
+ it("preserves arity of original function", function () {
62
+ var functions = [
63
+ function nullary () {},
64
+ function unary (arg) {},
65
+ function binary (arg1, arg2) {},
66
+ function ternary (arg1, arg2, arg3) {},
67
+ function quaternary (arg1, arg2, arg3, arg4) {},
68
+ function quinary (arg1, arg2, arg3, arg4, arg5) {},
69
+ function senary (arg1, arg2, arg3, arg4, arg5, arg6) {}
70
+ ];
71
+
72
+ for (var arity = 0; arity < functions.length; arity++) {
73
+ var someFunction = functions[arity],
74
+ spy = jasmineUnderTest.createSpy(someFunction.name, someFunction);
75
+
76
+ expect(spy.length).toEqual(arity);
77
+ }
78
+ });
60
79
  });
61
80
 
62
81
  describe("createSpyObj", function() {
82
+ it("should create an object with spy methods and corresponding return values when you call jasmine.createSpyObj() with an object", function () {
83
+ var spyObj = jasmineUnderTest.createSpyObj('BaseName', {'method1': 42, 'method2': 'special sauce' });
84
+
85
+ expect(spyObj.method1()).toEqual(42);
86
+ expect(spyObj.method1.and.identity()).toEqual('BaseName.method1');
87
+
88
+ expect(spyObj.method2()).toEqual('special sauce');
89
+ expect(spyObj.method2.and.identity()).toEqual('BaseName.method2');
90
+ });
91
+
92
+
63
93
  it("should create an object with a bunch of spy methods when you call jasmine.createSpyObj()", function() {
64
94
  var spyObj = jasmineUnderTest.createSpyObj('BaseName', ['method1', 'method2']);
65
95
 
@@ -76,10 +106,22 @@ describe('Spies', function () {
76
106
  expect(spyObj.method2.and.identity()).toEqual('unknown.method2');
77
107
  });
78
108
 
79
- it("should throw if you do not pass an array argument", function() {
109
+ it("should throw if you do not pass an array or object argument", function() {
80
110
  expect(function() {
81
111
  jasmineUnderTest.createSpyObj('BaseName');
82
- }).toThrow("createSpyObj requires a non-empty array of method names to create spies for");
112
+ }).toThrow("createSpyObj requires a non-empty array or object of method names to create spies for");
113
+ });
114
+
115
+ it("should throw if you pass an empty array argument", function() {
116
+ expect(function() {
117
+ jasmineUnderTest.createSpyObj('BaseName', []);
118
+ }).toThrow("createSpyObj requires a non-empty array or object of method names to create spies for");
119
+ });
120
+
121
+ it("should throw if you pass an empty object argument", function() {
122
+ expect(function() {
123
+ jasmineUnderTest.createSpyObj('BaseName', {});
124
+ }).toThrow("createSpyObj requires a non-empty array or object of method names to create spies for");
83
125
  });
84
126
  });
85
127
  });
@@ -83,13 +83,6 @@ describe("Suite", function() {
83
83
  expect(suite.getResult().status).toBe('finished');
84
84
  });
85
85
 
86
- it("retrieves a result with disabled status", function() {
87
- var suite = new jasmineUnderTest.Suite({});
88
- suite.disable();
89
-
90
- expect(suite.getResult().status).toBe('disabled');
91
- });
92
-
93
86
  it("retrieves a result with pending status", function() {
94
87
  var suite = new jasmineUnderTest.Suite({});
95
88
  suite.pend();
@@ -97,23 +90,15 @@ describe("Suite", function() {
97
90
  expect(suite.getResult().status).toBe('pending');
98
91
  });
99
92
 
100
- it("priviledges a disabled status over pending status", function() {
101
- var suite = new jasmineUnderTest.Suite({});
102
- suite.disable();
103
- suite.pend();
104
-
105
- expect(suite.getResult().status).toBe('disabled');
106
- });
107
-
108
- it("is executable if not disabled", function() {
93
+ it("is executable if not pending", function() {
109
94
  var suite = new jasmineUnderTest.Suite({});
110
95
 
111
96
  expect(suite.isExecutable()).toBe(true);
112
97
  });
113
98
 
114
- it("is not executable if disabled", function() {
99
+ it("is not executable if pending", function() {
115
100
  var suite = new jasmineUnderTest.Suite({});
116
- suite.disable();
101
+ suite.pend();
117
102
 
118
103
  expect(suite.isExecutable()).toBe(false);
119
104
  });
@@ -15,6 +15,22 @@ describe("jasmineUnderTest.util", function() {
15
15
  });
16
16
  });
17
17
 
18
+ describe("isObject_", function() {
19
+ it("should return true if the argument is an object", function() {
20
+ expect(jasmineUnderTest.isObject_({})).toBe(true);
21
+ expect(jasmineUnderTest.isObject_({an: "object"})).toBe(true);
22
+ });
23
+
24
+ it("should return false if the argument is not an object", function() {
25
+ expect(jasmineUnderTest.isObject_(undefined)).toBe(false);
26
+ expect(jasmineUnderTest.isObject_([])).toBe(false);
27
+ expect(jasmineUnderTest.isObject_(function() {})).toBe(false);
28
+ expect(jasmineUnderTest.isObject_('foo')).toBe(false);
29
+ expect(jasmineUnderTest.isObject_(5)).toBe(false);
30
+ expect(jasmineUnderTest.isObject_(null)).toBe(false);
31
+ });
32
+ });
33
+
18
34
  describe("isUndefined", function() {
19
35
  it("reports if a variable is defined", function() {
20
36
  var a;
@@ -25,4 +41,59 @@ describe("jasmineUnderTest.util", function() {
25
41
  expect(jasmineUnderTest.util.isUndefined(undefined)).toBe(false);
26
42
  });
27
43
  });
44
+
45
+ describe("getPropertyDescriptor", function() {
46
+ // IE 8 doesn't support `definePropery` on non-DOM nodes
47
+ if (jasmine.getEnv().ieVersion < 9) { return; }
48
+
49
+ it("get property descriptor from object", function() {
50
+ var obj = {prop: 1},
51
+ actual = jasmineUnderTest.util.getPropertyDescriptor(obj, 'prop'),
52
+ expected = Object.getOwnPropertyDescriptor(obj, 'prop');
53
+
54
+ expect(actual).toEqual(expected);
55
+ });
56
+
57
+ it("get property descriptor from object property", function() {
58
+ var proto = {prop: 1},
59
+ obj = Object.create(proto),
60
+ actual = jasmineUnderTest.util.getPropertyDescriptor(proto, 'prop'),
61
+ expected = Object.getOwnPropertyDescriptor(proto, 'prop');
62
+
63
+ expect(actual).toEqual(expected);
64
+ });
65
+ });
66
+
67
+ describe("objectDifference", function() {
68
+ it("given two objects A and B, returns the properties in A not present in B", function() {
69
+ var a = {
70
+ foo: 3,
71
+ bar: 4,
72
+ baz: 5
73
+ };
74
+
75
+ var b = {
76
+ bar: 6,
77
+ quux: 7
78
+ };
79
+
80
+ expect(jasmineUnderTest.util.objectDifference(a, b)).toEqual({foo: 3, baz: 5})
81
+ });
82
+
83
+ it("only looks at own properties of both objects", function() {
84
+ function Foo() {}
85
+
86
+ Foo.prototype.x = 1;
87
+ Foo.prototype.y = 2;
88
+
89
+ var a = new Foo();
90
+ a.x = 1;
91
+
92
+ var b = new Foo();
93
+ b.y = 2;
94
+
95
+ expect(jasmineUnderTest.util.objectDifference(a, b)).toEqual({x: 1});
96
+ expect(jasmineUnderTest.util.objectDifference(b, a)).toEqual({y: 2});
97
+ })
98
+ })
28
99
  });
@@ -36,4 +36,17 @@ describe("ArrayContaining", function() {
36
36
 
37
37
  expect(containing.jasmineToString()).toMatch("<jasmine.arrayContaining");
38
38
  });
39
+
40
+ it("uses custom equality testers", function() {
41
+ var tester = function(a, b) {
42
+ // All "foo*" strings match each other.
43
+ if (typeof a == "string" && typeof b == "string" &&
44
+ a.substr(0, 3) == "foo" && b.substr(0, 3) == "foo") {
45
+ return true;
46
+ }
47
+ };
48
+ var containing = new jasmineUnderTest.ArrayContaining(["fooVal"]);
49
+
50
+ expect(containing.asymmetricMatch(["fooBar"], [tester])).toBe(true);
51
+ });
39
52
  });
@@ -86,4 +86,17 @@ describe("ObjectContaining", function() {
86
86
 
87
87
  expect(containing.asymmetricMatch(obj)).toBe(true);
88
88
  });
89
+
90
+ it("uses custom equality testers", function() {
91
+ var tester = function(a, b) {
92
+ // All "foo*" strings match each other.
93
+ if (typeof a == "string" && typeof b == "string" &&
94
+ a.substr(0, 3) == "foo" && b.substr(0, 3) == "foo") {
95
+ return true;
96
+ }
97
+ };
98
+ var containing = new jasmineUnderTest.ObjectContaining({foo: "fooVal"});
99
+
100
+ expect(containing.asymmetricMatch({foo: "fooBar"}, [tester])).toBe(true);
101
+ });
89
102
  });
@@ -56,6 +56,53 @@ describe("Custom Matchers (Integration)", function() {
56
56
  env.execute();
57
57
  });
58
58
 
59
+ it("passes the spec if the custom equality matcher passes for types nested inside asymmetric equality testers", function(done) {
60
+ env.it("spec using custom equality matcher", function() {
61
+ var customEqualityFn = function(a, b) {
62
+ // All "foo*" strings match each other.
63
+ if (typeof a == "string" && typeof b == "string" &&
64
+ a.substr(0, 3) == "foo" && b.substr(0, 3) == "foo") {
65
+ return true;
66
+ }
67
+ };
68
+
69
+ env.addCustomEqualityTester(customEqualityFn);
70
+ env.expect({foo: 'fooValue'}).toEqual(jasmine.objectContaining({foo: 'fooBar'}));
71
+ env.expect(['fooValue']).toEqual(jasmine.arrayContaining(['fooBar']));
72
+ });
73
+
74
+ var specExpectations = function(result) {
75
+ expect(result.status).toEqual('passed');
76
+ };
77
+
78
+ env.addReporter({ specDone: specExpectations, jasmineDone: done });
79
+ env.execute();
80
+ });
81
+
82
+ it("displays an appropriate failure message if a custom equality matcher fails", function(done) {
83
+ env.it("spec using custom equality matcher", function() {
84
+ var customEqualityFn = function(a, b) {
85
+ // "foo" is not equal to anything
86
+ if (a === 'foo' || b === 'foo') {
87
+ return false;
88
+ }
89
+ };
90
+
91
+ env.addCustomEqualityTester(customEqualityFn);
92
+ env.expect({foo: 'foo'}).toEqual({foo: 'foo'});
93
+ });
94
+
95
+ var specExpectations = function(result) {
96
+ expect(result.status).toEqual('failed');
97
+ expect(result.failedExpectations[0].message).toEqual(
98
+ "Expected $.foo = 'foo' to equal 'foo'."
99
+ );
100
+ };
101
+
102
+ env.addReporter({ specDone: specExpectations, jasmineDone: done });
103
+ env.execute();
104
+ });
105
+
59
106
  it("uses the negative compare function for a negative comparison, if provided", function(done) {
60
107
  env.it("spec with custom negative comparison matcher", function() {
61
108
  env.addMatchers({
@@ -181,6 +181,12 @@ describe("Env integration", function() {
181
181
  }
182
182
  })]
183
183
  }));
184
+ expect(specDone).toHaveBeenCalledWith(jasmine.objectContaining({
185
+ description: 'pretty prints objects',
186
+ failedExpectations: [jasmine.objectContaining({
187
+ message: 'Failed: Object({ prop: \'value\', arr: [ \'works\', true ] })'
188
+ })]
189
+ }));
184
190
  done();
185
191
  }
186
192
  });
@@ -197,6 +203,27 @@ describe("Env integration", function() {
197
203
  env.it('has a message and stack trace from an Error', function() {
198
204
  env.fail(new Error('error message'));
199
205
  });
206
+
207
+ env.it('pretty prints objects', function() {
208
+ env.fail({prop: 'value', arr: ['works', true]});
209
+ })
210
+ });
211
+
212
+ env.execute();
213
+ });
214
+
215
+ it("produces an understandable error message when 'fail' is used outside of a current spec", function(done) {
216
+ var env = new jasmineUnderTest.Env(),
217
+ reporter = jasmine.createSpyObj('fakeReporter', ['jasmineDone']);
218
+
219
+ reporter.jasmineDone.and.callFake(done);
220
+ env.addReporter(reporter);
221
+
222
+ env.describe("A Suite", function() {
223
+ env.it("an async spec that is actually synchronous", function(underTestCallback) {
224
+ underTestCallback();
225
+ });
226
+ expect(function() { env.fail(); }).toThrowError(/'fail' was used when there was no current spec/);
200
227
  });
201
228
 
202
229
  env.execute();
@@ -940,8 +967,8 @@ describe("Env integration", function() {
940
967
  env.addReporter(reporter);
941
968
  jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL = 1290;
942
969
 
943
- env.beforeAll(function(done) {
944
- jasmine.clock().tick(1290);
970
+ env.beforeAll(function(innerDone) {
971
+ jasmine.clock().tick(1291);
945
972
  });
946
973
 
947
974
  env.it("spec that will be failed", function() {
@@ -955,7 +982,7 @@ describe("Env integration", function() {
955
982
  env.execute();
956
983
  });
957
984
 
958
- it("should not use the mock clock for asynchronous timeouts", function(){
985
+ it("should not use the mock clock for asynchronous timeouts", function(done){
959
986
  var env = new jasmineUnderTest.Env(),
960
987
  reporter = jasmine.createSpyObj('fakeReporter', [ "specDone", "jasmineDone" ]),
961
988
  clock = env.clock;
@@ -963,6 +990,7 @@ describe("Env integration", function() {
963
990
  reporter.jasmineDone.and.callFake(function() {
964
991
  expect(reporter.specDone.calls.count()).toEqual(1);
965
992
  expect(reporter.specDone.calls.argsFor(0)[0]).toEqual(jasmine.objectContaining({status: 'passed'}));
993
+ done();
966
994
  });
967
995
 
968
996
  env.addReporter(reporter);
@@ -976,10 +1004,11 @@ describe("Env integration", function() {
976
1004
  clock.uninstall();
977
1005
  });
978
1006
 
979
- env.it("spec that should not time out", function(done) {
1007
+ env.it("spec that should not time out", function(innerDone) {
980
1008
  clock.tick(6);
981
1009
  expect(true).toEqual(true);
982
- done();
1010
+ innerDone();
1011
+ jasmine.clock().tick(1);
983
1012
  });
984
1013
 
985
1014
  env.execute();
@@ -1006,10 +1035,12 @@ describe("Env integration", function() {
1006
1035
  env.afterAll(function(innerDone) {
1007
1036
  jasmine.clock().tick(3001);
1008
1037
  innerDone();
1038
+ jasmine.clock().tick(1);
1009
1039
  });
1010
1040
  });
1011
1041
 
1012
1042
  env.execute();
1043
+ jasmine.clock().tick(1);
1013
1044
  });
1014
1045
 
1015
1046
  it('should wait a custom interval before reporting async functions that fail to call done', function(done) {
@@ -1130,6 +1161,8 @@ describe("Env integration", function() {
1130
1161
  env.fail();
1131
1162
  innerDone();
1132
1163
  }, 1);
1164
+ jasmine.clock().tick(1);
1165
+ jasmine.clock().tick(1);
1133
1166
  });
1134
1167
 
1135
1168
  env.it('specifies a message', function(innerDone) {
@@ -1137,12 +1170,16 @@ describe("Env integration", function() {
1137
1170
  env.fail('messy message');
1138
1171
  innerDone();
1139
1172
  }, 1);
1173
+ jasmine.clock().tick(1);
1174
+ jasmine.clock().tick(1);
1140
1175
  });
1141
1176
 
1142
1177
  env.it('fails via the done callback', function(innerDone) {
1143
1178
  setTimeout(function() {
1144
1179
  innerDone.fail('done failed');
1145
1180
  }, 1);
1181
+ jasmine.clock().tick(1);
1182
+ jasmine.clock().tick(1);
1146
1183
  });
1147
1184
 
1148
1185
  env.it('has a message from an Error', function(innerDone) {
@@ -1150,14 +1187,12 @@ describe("Env integration", function() {
1150
1187
  env.fail(new Error('error message'));
1151
1188
  innerDone();
1152
1189
  }, 1);
1190
+ jasmine.clock().tick(1);
1191
+ jasmine.clock().tick(1);
1153
1192
  });
1154
1193
  });
1155
1194
 
1156
1195
  env.execute();
1157
- jasmine.clock().tick(1);
1158
- jasmine.clock().tick(1);
1159
- jasmine.clock().tick(1);
1160
- jasmine.clock().tick(1);
1161
1196
  });
1162
1197
  });
1163
1198
 
@@ -1186,7 +1221,7 @@ describe("Env integration", function() {
1186
1221
  env.execute();
1187
1222
  });
1188
1223
 
1189
- it('should only run focused suites', function(){
1224
+ it('should only run focused suites', function(done){
1190
1225
  var env = new jasmineUnderTest.Env(),
1191
1226
  calls = [];
1192
1227
 
@@ -1417,7 +1452,7 @@ describe("Env integration", function() {
1417
1452
  totalSpecsDefined: 1
1418
1453
  });
1419
1454
 
1420
- expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({ status: 'pending' }));
1455
+ expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({ status: 'disabled' }));
1421
1456
  expect(reporter.suiteDone).toHaveBeenCalledWith(jasmine.objectContaining({ description: 'xd out', status: 'pending' }));
1422
1457
  expect(reporter.suiteDone.calls.count()).toBe(4);
1423
1458
 
@@ -1572,14 +1607,17 @@ describe("Env integration", function() {
1572
1607
  });
1573
1608
 
1574
1609
  it("produces an understandable error message when an 'expect' is used outside of a current spec", function(done) {
1575
- var env = new jasmineUnderTest.Env();
1610
+ var env = new jasmineUnderTest.Env(),
1611
+ reporter = jasmine.createSpyObj('fakeReporter', ['jasmineDone']);
1612
+
1613
+ reporter.jasmineDone.and.callFake(done);
1614
+ env.addReporter(reporter);
1576
1615
 
1577
1616
  env.describe("A Suite", function() {
1578
1617
  env.it("an async spec that is actually synchronous", function(underTestCallback) {
1579
1618
  underTestCallback();
1580
- expect(function() { env.expect('a').toEqual('a'); }).toThrowError(/'expect' was used when there was no current spec/);
1581
- done();
1582
1619
  });
1620
+ expect(function() { env.expect('a').toEqual('a'); }).toThrowError(/'expect' was used when there was no current spec/);
1583
1621
  });
1584
1622
 
1585
1623
  env.execute();
@@ -1746,4 +1784,37 @@ describe("Env integration", function() {
1746
1784
 
1747
1785
  env.execute();
1748
1786
  });
1787
+
1788
+ it("should associate errors thrown from async code with the correct runnable", function(done) {
1789
+ var env = new jasmineUnderTest.Env(),
1790
+ reporter = jasmine.createSpyObj('fakeReport', ['jasmineDone','suiteDone','specDone']);
1791
+
1792
+ reporter.jasmineDone.and.callFake(function() {
1793
+ expect(reporter.suiteDone).toHaveFailedExpecationsForRunnable('async suite', [
1794
+ /^(((Uncaught )?Error: suite( thrown)?)|(suite thrown))$/
1795
+ ]);
1796
+ expect(reporter.specDone).toHaveFailedExpecationsForRunnable('suite async spec', [
1797
+ /^(((Uncaught )?Error: spec( thrown)?)|(spec thrown))$/
1798
+ ]);
1799
+ done();
1800
+ });
1801
+
1802
+ env.addReporter(reporter);
1803
+
1804
+ env.describe('async suite', function() {
1805
+ env.afterAll(function(innerDone) {
1806
+ setTimeout(function() { throw new Error('suite'); }, 1);
1807
+ }, 10);
1808
+
1809
+ env.it('spec', function() {});
1810
+ });
1811
+
1812
+ env.describe('suite', function() {
1813
+ env.it('async spec', function(innerDone) {
1814
+ setTimeout(function() { throw new Error('spec'); }, 1);
1815
+ }, 10);
1816
+ });
1817
+
1818
+ env.execute();
1819
+ });
1749
1820
  });