jasmine-core 2.5.2 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
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
  });