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
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (c) 2008-2016 Pivotal Labs
2
+ Copyright (c) 2008-2017 Pivotal Labs
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining
5
5
  a copy of this software and associated documentation files (the
@@ -0,0 +1,67 @@
1
+ describe("ClearStack", function() {
2
+ it("works in an integrationy way", function(done) {
3
+ var clearStack = jasmineUnderTest.getClearStack(jasmineUnderTest.getGlobal());
4
+
5
+ clearStack(function() {
6
+ done();
7
+ });
8
+ });
9
+
10
+ it("uses nextTick when available", function() {
11
+ var nextTick = jasmine.createSpy('nextTick').and.callFake(function(fn) { fn() }),
12
+ global = { process: { nextTick: nextTick } },
13
+ clearStack = jasmineUnderTest.getClearStack(global),
14
+ called = false;
15
+
16
+ clearStack(function() {
17
+ called = true;
18
+ });
19
+
20
+ expect(called).toBe(true);
21
+ expect(nextTick).toHaveBeenCalled();
22
+ });
23
+
24
+ it("uses setImmediate when available", function() {
25
+ var setImmediate = jasmine.createSpy('setImmediate').and.callFake(function(fn) { fn() }),
26
+ global = { setImmediate: setImmediate },
27
+ clearStack = jasmineUnderTest.getClearStack(global),
28
+ called = false;
29
+
30
+ clearStack(function() {
31
+ called = true;
32
+ });
33
+
34
+ expect(called).toBe(true);
35
+ expect(setImmediate).toHaveBeenCalled();
36
+ });
37
+
38
+ it("uses MessageChannels when available", function() {
39
+ var fakeChannel = {
40
+ port1: {},
41
+ port2: { postMessage: function() { fakeChannel.port1.onmessage(); } }
42
+ },
43
+ global = { MessageChannel: function() { return fakeChannel; } },
44
+ clearStack = jasmineUnderTest.getClearStack(global),
45
+ called = false;
46
+
47
+ clearStack(function() {
48
+ called = true;
49
+ });
50
+
51
+ expect(called).toBe(true);
52
+ });
53
+
54
+ it("falls back to setTimeout", function() {
55
+ var setTimeout = jasmine.createSpy('setTimeout').and.callFake(function(fn) { fn() }),
56
+ global = { setTimeout: setTimeout },
57
+ clearStack = jasmineUnderTest.getClearStack(global),
58
+ called = false;
59
+
60
+ clearStack(function() {
61
+ called = true;
62
+ });
63
+
64
+ expect(called).toBe(true);
65
+ expect(setTimeout).toHaveBeenCalledWith(jasmine.any(Function), 0);
66
+ });
67
+ });
@@ -26,15 +26,6 @@ describe("Env", function() {
26
26
  });
27
27
  });
28
28
 
29
- describe('#describe', function () {
30
- var spec = function(done){};
31
- it("throws the error", function() {
32
- expect(function() {
33
- env.describe('done method', spec);
34
- }).toThrow(new Error('describe does not expect any arguments'));
35
- });
36
- });
37
-
38
29
  it('can configure specs to throw errors on expectation failures', function() {
39
30
  env.throwOnExpectationFailure(true);
40
31
 
@@ -55,14 +46,113 @@ describe("Env", function() {
55
46
  }));
56
47
  });
57
48
 
49
+ describe('#describe', function () {
50
+ it("throws an error when given arguments", function() {
51
+ expect(function() {
52
+ env.describe('done method', function(done) {});
53
+ }).toThrowError('describe does not expect any arguments');
54
+ });
55
+
56
+ it('throws an error when it receives a non-fn argument', function() {
57
+ // Some versions of PhantomJS return [object DOMWindow] when
58
+ // Object.prototype.toString.apply is called with `undefined` or `null`.
59
+ // In a similar fashion, IE8 gives [object Object] for both `undefined`
60
+ // and `null`. We mostly just want these tests to check that using
61
+ // anything other than a function throws an error.
62
+ expect(function() {
63
+ env.describe('undefined arg', undefined);
64
+ }).toThrowError(/describe expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
65
+ expect(function() {
66
+ env.describe('null arg', null);
67
+ }).toThrowError(/describe expects a function argument; received \[object (Null|DOMWindow|Object)\]/);
68
+
69
+ expect(function() {
70
+ env.describe('array arg', []);
71
+ }).toThrowError('describe expects a function argument; received [object Array]');
72
+ expect(function() {
73
+ env.describe('object arg', {});
74
+ }).toThrowError('describe expects a function argument; received [object Object]');
75
+
76
+ expect(function() {
77
+ env.describe('fn arg', function() {});
78
+ }).not.toThrowError('describe expects a function argument; received [object Function]');
79
+ });
80
+ });
81
+
82
+ describe('#it', function () {
83
+ it('throws an error when it receives a non-fn argument', function() {
84
+ expect(function() {
85
+ env.it('undefined arg', undefined);
86
+ }).toThrowError(/it expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
87
+ });
88
+
89
+ it('does not throw when it is not given a fn argument', function() {
90
+ expect(function() {
91
+ env.it('pending spec');
92
+ }).not.toThrow();
93
+ });
94
+ });
95
+
58
96
  describe('#xit', function() {
59
97
  it('calls spec.pend with "Temporarily disabled with xit"', function() {
60
98
  var pendSpy = jasmine.createSpy();
61
99
  spyOn(env, 'it').and.returnValue({
62
100
  pend: pendSpy
63
101
  });
64
- env.xit();
102
+ env.xit('foo', function() {});
65
103
  expect(pendSpy).toHaveBeenCalledWith('Temporarily disabled with xit');
66
104
  });
105
+
106
+ it('throws an error when it receives a non-fn argument', function() {
107
+ expect(function() {
108
+ env.xit('undefined arg', undefined);
109
+ }).toThrowError(/xit expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
110
+ });
111
+
112
+ it('does not throw when it is not given a fn argument', function() {
113
+ expect(function() {
114
+ env.xit('pending spec');
115
+ }).not.toThrow();
116
+ });
117
+ });
118
+
119
+ describe('#fit', function () {
120
+ it('throws an error when it receives a non-fn argument', function() {
121
+ expect(function() {
122
+ env.fit('undefined arg', undefined);
123
+ }).toThrowError(/fit expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
124
+ });
125
+ });
126
+
127
+ describe('#beforeEach', function () {
128
+ it('throws an error when it receives a non-fn argument', function() {
129
+ expect(function() {
130
+ env.beforeEach(undefined);
131
+ }).toThrowError(/beforeEach expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
132
+ });
133
+ });
134
+
135
+ describe('#beforeAll', function () {
136
+ it('throws an error when it receives a non-fn argument', function() {
137
+ expect(function() {
138
+ env.beforeAll(undefined);
139
+ }).toThrowError(/beforeAll expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
140
+ });
141
+ });
142
+
143
+ describe('#afterEach', function () {
144
+ it('throws an error when it receives a non-fn argument', function() {
145
+ expect(function() {
146
+ env.afterEach(undefined);
147
+ }).toThrowError(/afterEach expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
148
+ });
149
+ });
150
+
151
+ describe('#afterAll', function () {
152
+ it('throws an error when it receives a non-fn argument', function() {
153
+ expect(function() {
154
+ env.afterAll(undefined);
155
+ }).toThrowError(/afterAll expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/);
156
+ });
67
157
  });
68
158
  });
@@ -113,6 +113,7 @@ describe("Expectation", function() {
113
113
  matcherName: "toFoo",
114
114
  passed: true,
115
115
  message: "",
116
+ error: undefined,
116
117
  expected: "hello",
117
118
  actual: "an actual"
118
119
  });
@@ -146,7 +147,8 @@ describe("Expectation", function() {
146
147
  passed: false,
147
148
  expected: "hello",
148
149
  actual: "an actual",
149
- message: ""
150
+ message: "",
151
+ error: undefined
150
152
  });
151
153
  });
152
154
 
@@ -179,7 +181,8 @@ describe("Expectation", function() {
179
181
  passed: false,
180
182
  expected: "hello",
181
183
  actual: "an actual",
182
- message: "I am a custom message"
184
+ message: "I am a custom message",
185
+ error: undefined
183
186
  });
184
187
  });
185
188
 
@@ -212,7 +215,8 @@ describe("Expectation", function() {
212
215
  passed: false,
213
216
  expected: "hello",
214
217
  actual: "an actual",
215
- message: "I am a custom message"
218
+ message: "I am a custom message",
219
+ error: undefined
216
220
  });
217
221
  });
218
222
 
@@ -244,6 +248,7 @@ describe("Expectation", function() {
244
248
  matcherName: "toFoo",
245
249
  passed: true,
246
250
  message: "",
251
+ error: undefined,
247
252
  expected: "hello",
248
253
  actual: actual
249
254
  });
@@ -279,7 +284,8 @@ describe("Expectation", function() {
279
284
  passed: false,
280
285
  expected: "hello",
281
286
  actual: actual,
282
- message: "default message"
287
+ message: "default message",
288
+ error: undefined
283
289
  });
284
290
  });
285
291
 
@@ -314,7 +320,8 @@ describe("Expectation", function() {
314
320
  passed: false,
315
321
  expected: "hello",
316
322
  actual: actual,
317
- message: "I am a custom message"
323
+ message: "I am a custom message",
324
+ error: undefined
318
325
  });
319
326
  });
320
327
 
@@ -345,7 +352,8 @@ describe("Expectation", function() {
345
352
  passed: true,
346
353
  expected: "hello",
347
354
  actual: actual,
348
- message: ""
355
+ message: "",
356
+ error: undefined
349
357
  });
350
358
  });
351
359
 
@@ -381,7 +389,44 @@ describe("Expectation", function() {
381
389
  passed: false,
382
390
  expected: "hello",
383
391
  actual: actual,
384
- message: "I'm a custom message"
392
+ message: "I'm a custom message",
393
+ error: undefined
394
+ });
395
+ });
396
+
397
+ it("reports a custom error message to the spec", function() {
398
+ var customError = new Error("I am a custom error");
399
+ var matchers = {
400
+ toFoo: function() {
401
+ return {
402
+ compare: function() {
403
+ return {
404
+ pass: false,
405
+ message: "I am a custom message",
406
+ error: customError
407
+ };
408
+ }
409
+ };
410
+ }
411
+ },
412
+ addExpectationResult = jasmine.createSpy("addExpectationResult"),
413
+ expectation;
414
+
415
+ expectation = new jasmineUnderTest.Expectation({
416
+ actual: "an actual",
417
+ customMatchers: matchers,
418
+ addExpectationResult: addExpectationResult
419
+ });
420
+
421
+ expectation.toFoo("hello");
422
+
423
+ expect(addExpectationResult).toHaveBeenCalledWith(false, {
424
+ matcherName: "toFoo",
425
+ passed: false,
426
+ expected: "hello",
427
+ actual: "an actual",
428
+ message: "I am a custom message",
429
+ error: customError
385
430
  });
386
431
  });
387
432
 
@@ -0,0 +1,94 @@
1
+ describe("GlobalErrors", function() {
2
+ it("calls the added handler on error", function() {
3
+ var fakeGlobal = { onerror: null },
4
+ handler = jasmine.createSpy('errorHandler'),
5
+ errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
6
+
7
+ errors.install();
8
+ errors.pushListener(handler);
9
+
10
+ fakeGlobal.onerror('foo');
11
+
12
+ expect(handler).toHaveBeenCalledWith('foo');
13
+ });
14
+
15
+ it("only calls the most recent handler", function() {
16
+ var fakeGlobal = { onerror: null },
17
+ handler1 = jasmine.createSpy('errorHandler1'),
18
+ handler2 = jasmine.createSpy('errorHandler2'),
19
+ errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
20
+
21
+ errors.install();
22
+ errors.pushListener(handler1);
23
+ errors.pushListener(handler2);
24
+
25
+ fakeGlobal.onerror('foo');
26
+
27
+ expect(handler1).not.toHaveBeenCalled();
28
+ expect(handler2).toHaveBeenCalledWith('foo');
29
+ });
30
+
31
+ it("calls previous handlers when one is removed", function() {
32
+ var fakeGlobal = { onerror: null },
33
+ handler1 = jasmine.createSpy('errorHandler1'),
34
+ handler2 = jasmine.createSpy('errorHandler2'),
35
+ errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
36
+
37
+ errors.install();
38
+ errors.pushListener(handler1);
39
+ errors.pushListener(handler2);
40
+
41
+ errors.popListener();
42
+
43
+ fakeGlobal.onerror('foo');
44
+
45
+ expect(handler1).toHaveBeenCalledWith('foo');
46
+ expect(handler2).not.toHaveBeenCalled();
47
+ });
48
+
49
+ it("uninstalls itself, putting back a previous callback", function() {
50
+ var originalCallback = jasmine.createSpy('error'),
51
+ fakeGlobal = { onerror: originalCallback },
52
+ errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
53
+
54
+ expect(fakeGlobal.onerror).toBe(originalCallback);
55
+
56
+ errors.install();
57
+
58
+ expect(fakeGlobal.onerror).not.toBe(originalCallback);
59
+
60
+ errors.uninstall();
61
+
62
+ expect(fakeGlobal.onerror).toBe(originalCallback);
63
+ });
64
+
65
+ it("works in node.js", function() {
66
+ var fakeGlobal = {
67
+ process: {
68
+ on: jasmine.createSpy('process.on'),
69
+ removeListener: jasmine.createSpy('process.removeListener'),
70
+ listeners: jasmine.createSpy('process.listeners').and.returnValue(['foo']),
71
+ removeAllListeners: jasmine.createSpy('process.removeAllListeners')
72
+ }
73
+ },
74
+ handler = jasmine.createSpy('errorHandler'),
75
+ errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
76
+
77
+ errors.install();
78
+ expect(fakeGlobal.process.on).toHaveBeenCalledWith('uncaughtException', jasmine.any(Function));
79
+ expect(fakeGlobal.process.listeners).toHaveBeenCalledWith('uncaughtException');
80
+ expect(fakeGlobal.process.removeAllListeners).toHaveBeenCalledWith('uncaughtException');
81
+
82
+ errors.pushListener(handler);
83
+
84
+ var addedListener = fakeGlobal.process.on.calls.argsFor(0)[1];
85
+ addedListener(new Error('bar'));
86
+
87
+ expect(handler).toHaveBeenCalledWith(new Error('bar'));
88
+
89
+ errors.uninstall();
90
+
91
+ expect(fakeGlobal.process.removeListener).toHaveBeenCalledWith('uncaughtException', addedListener);
92
+ expect(fakeGlobal.process.on).toHaveBeenCalledWith('uncaughtException', 'foo');
93
+ });
94
+ });
@@ -14,6 +14,25 @@ describe("jasmineUnderTest.pp", function () {
14
14
  expect(jasmineUnderTest.pp(-0)).toEqual("-0");
15
15
  });
16
16
 
17
+ describe('stringify sets', function() {
18
+ it("should stringify sets properly", function() {
19
+ jasmine.getEnv().requireFunctioningSets();
20
+ expect(jasmineUnderTest.pp(new Set([1, 2]))).toEqual("Set( 1, 2 )");
21
+ });
22
+
23
+ it("should truncate sets with more elments than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
24
+ jasmine.getEnv().requireFunctioningSets();
25
+ var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
26
+
27
+ try {
28
+ jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
29
+ expect(jasmineUnderTest.pp(new Set(["a", "b", "c"]))).toEqual("Set( 'a', 'b', ... )");
30
+ } finally {
31
+ jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize;
32
+ }
33
+ })
34
+ });
35
+
17
36
  describe('stringify arrays', function() {
18
37
  it("should stringify arrays properly", function() {
19
38
  expect(jasmineUnderTest.pp([1, 2])).toEqual("[ 1, 2 ]");
@@ -80,6 +99,11 @@ describe("jasmineUnderTest.pp", function () {
80
99
  }, bar: [1, 2, 3]})).toEqual("Object({ foo: Function, bar: [ 1, 2, 3 ] })");
81
100
  });
82
101
 
102
+ it("should print 'null' as the constructor of an object with its own constructor property", function() {
103
+ expect(jasmineUnderTest.pp({constructor: function() {}})).toContain("null({");
104
+ expect(jasmineUnderTest.pp({constructor: 'foo'})).toContain("null({");
105
+ });
106
+
83
107
  it("should not include inherited properties when stringifying an object", function() {
84
108
  var SomeClass = function SomeClass() {};
85
109
  SomeClass.prototype.foo = "inherited foo";
@@ -145,7 +169,6 @@ describe("jasmineUnderTest.pp", function () {
145
169
  }
146
170
  });
147
171
 
148
-
149
172
  it('should not do HTML escaping of strings', function() {
150
173
  expect(jasmineUnderTest.pp('some <b>html string</b> &', false)).toEqual('\'some <b>html string</b> &\'');
151
174
  });
@@ -187,6 +210,19 @@ describe("jasmineUnderTest.pp", function () {
187
210
  };
188
211
 
189
212
  expect(jasmineUnderTest.pp(obj)).toEqual("my toString");
213
+
214
+ // Simulate object from another global context (e.g. an iframe or Web Worker) that does not actually have a custom
215
+ // toString despite obj.toString !== Object.prototype.toString
216
+ var objFromOtherContext = {
217
+ foo: 'bar',
218
+ toString: function () { return Object.prototype.toString.call(this); }
219
+ };
220
+
221
+ if (jasmine.getEnv().ieVersion < 9) {
222
+ expect(jasmineUnderTest.pp(objFromOtherContext)).toEqual("Object({ foo: 'bar' })");
223
+ } else {
224
+ expect(jasmineUnderTest.pp(objFromOtherContext)).toEqual("Object({ foo: 'bar', toString: Function })");
225
+ }
190
226
  });
191
227
 
192
228
  it("should stringify objects from anonymous constructors with custom toString", function () {
@@ -234,6 +234,43 @@ describe("QueueRunner", function() {
234
234
  queueRunner.execute();
235
235
  expect(doneReturn).toBe(null);
236
236
  });
237
+
238
+ it("continues running functions when an exception is thrown in async code without timing out", function() {
239
+ var queueableFn = { fn: function(done) { throwAsync(); }, timeout: function() { return 1; } },
240
+ nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
241
+ onException = jasmine.createSpy('onException'),
242
+ globalErrors = { pushListener: jasmine.createSpy('pushListener'), popListener: jasmine.createSpy('popListener') },
243
+ queueRunner = new jasmineUnderTest.QueueRunner({
244
+ queueableFns: [queueableFn, nextQueueableFn],
245
+ onException: onException,
246
+ globalErrors: globalErrors
247
+ }),
248
+ throwAsync = function() {
249
+ globalErrors.pushListener.calls.mostRecent().args[0](new Error('foo'));
250
+ jasmine.clock().tick(2);
251
+ };
252
+
253
+ nextQueueableFn.fn.and.callFake(function() {
254
+ // should remove the same function that was added
255
+ expect(globalErrors.popListener).toHaveBeenCalledWith(globalErrors.pushListener.calls.argsFor(0)[0]);
256
+ });
257
+
258
+ queueRunner.execute();
259
+
260
+ function errorWithMessage(message) {
261
+ return {
262
+ asymmetricMatch: function(other) {
263
+ return new RegExp(message).test(other.message);
264
+ },
265
+ toString: function() {
266
+ return '<Error with message like "' + message + '">';
267
+ }
268
+ };
269
+ }
270
+ expect(onException).not.toHaveBeenCalledWith(errorWithMessage(/DEFAULT_TIMEOUT_INTERVAL/));
271
+ expect(onException).toHaveBeenCalledWith(errorWithMessage(/^foo$/));
272
+ expect(nextQueueableFn.fn).toHaveBeenCalled();
273
+ });
237
274
  });
238
275
 
239
276
  it("calls exception handlers when an exception is thrown in a fn", function() {