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
@@ -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() {