From c1957ecd7c08d76dfb3c33ee6233a782cf18230f Mon Sep 17 00:00:00 2001 From: Michael Leaney Date: Wed, 11 Oct 2017 20:29:27 +0800 Subject: [PATCH 01/11] Add test --- spec/core/ClockSpec.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/spec/core/ClockSpec.js b/spec/core/ClockSpec.js index 6b3ed1d0..350dc85e 100644 --- a/spec/core/ClockSpec.js +++ b/spec/core/ClockSpec.js @@ -679,4 +679,25 @@ describe("Clock (acceptance)", function() { expect(actualTimes).toEqual([baseTime.getTime(), baseTime.getTime() + 1, baseTime.getTime() + 3]); }) + + it('should be able to clear a timeout', function () { + var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(), + global = {Date: Date, setTimeout: undefined}, + mockDate = new jasmineUnderTest.MockDate(global), + clock = new jasmineUnderTest.Clock(global, function () { return delayedFunctionScheduler; }, mockDate); + + clock.install(); + + var timerId2; + + global.setTimeout(function () { + global.clearTimeout(timerId2); + }, 100); + + timerId2 = global.setTimeout(() => { + fail(); + }, 100); + + clock.tick(100); + }); }); From 516e00d7ba9cd5f3397d6e506241e726acefef7c Mon Sep 17 00:00:00 2001 From: Michael Leaney Date: Wed, 11 Oct 2017 20:54:56 +0800 Subject: [PATCH 02/11] Fix #1426 clearTimeout not correctly clearing a timeout clearTimeout was not correctly handling the case of clearing a timeout that is also scheduled to run at the same tick. This fix adds a deletedKeys array that is checked whilst we are running the scheduled functions for the current clock tick. If a function exists in deletedKeys it will not be ran. deletedKeys is then reset to an empty array. --- spec/core/ClockSpec.js | 24 ++++++++++++++++++++---- src/core/DelayedFunctionScheduler.js | 13 ++++++++++++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/spec/core/ClockSpec.js b/spec/core/ClockSpec.js index 350dc85e..37c1bc33 100644 --- a/spec/core/ClockSpec.js +++ b/spec/core/ClockSpec.js @@ -680,7 +680,7 @@ describe("Clock (acceptance)", function() { expect(actualTimes).toEqual([baseTime.getTime(), baseTime.getTime() + 1, baseTime.getTime() + 3]); }) - it('should be able to clear a timeout', function () { + it('correctly clears a scheduled timeout while the Clock is advancing', function () { var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(), global = {Date: Date, setTimeout: undefined}, mockDate = new jasmineUnderTest.MockDate(global), @@ -694,10 +694,26 @@ describe("Clock (acceptance)", function() { global.clearTimeout(timerId2); }, 100); - timerId2 = global.setTimeout(() => { - fail(); - }, 100); + timerId2 = global.setTimeout(fail, 100); clock.tick(100); }); + + it('correctly clears a scheduled interval while the Clock is advancing', function () { + var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(), + global = {Date: Date, setTimeout: undefined}, + mockDate = new jasmineUnderTest.MockDate(global), + clock = new jasmineUnderTest.Clock(global, function () { return delayedFunctionScheduler; }, mockDate); + + clock.install(); + + var timerId2; + var timerId1 = global.setInterval(function () { + global.clearInterval(timerId2); + }, 100); + + timerId2 = global.setInterval(fail, 100); + + clock.tick(400); + }); }); diff --git a/src/core/DelayedFunctionScheduler.js b/src/core/DelayedFunctionScheduler.js index 4756b323..91557a37 100644 --- a/src/core/DelayedFunctionScheduler.js +++ b/src/core/DelayedFunctionScheduler.js @@ -5,6 +5,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() { var scheduledFunctions = {}; var currentTime = 0; var delayedFnCount = 0; + var deletedKeys = []; self.tick = function(millis, tickDate) { millis = millis || 0; @@ -51,6 +52,8 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() { }; self.removeFunctionWithId = function(timeoutKey) { + deletedKeys.push(timeoutKey); + for (var runAtMillis in scheduledFunctions) { var funcs = scheduledFunctions[runAtMillis]; var i = indexOfFirstToPass(funcs, function (func) { @@ -126,7 +129,10 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() { currentTime = newCurrentTime; - var funcsToRun = scheduledFunctions[currentTime]; + var funcsToRun = scheduledFunctions[currentTime].sort(function (a, b) { + return a.millis > b.millis; + }); + delete scheduledFunctions[currentTime]; forEachFunction(funcsToRun, function(funcToRun) { @@ -136,8 +142,13 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() { }); forEachFunction(funcsToRun, function(funcToRun) { + if (deletedKeys.indexOf(funcToRun.timeoutKey) !== -1) { + // skip a timeoutKey deleted whilst we were running + return; + } funcToRun.funcToCall.apply(null, funcToRun.params || []); }); + deletedKeys = []; } while (scheduledLookup.length > 0 && // checking first if we're out of time prevents setTimeout(0) // scheduled in a funcToRun from forcing an extra iteration From 1136fddcde1f327c8c895b65275f45704bbc0107 Mon Sep 17 00:00:00 2001 From: Michael Leaney Date: Tue, 2 Jan 2018 14:51:51 +0800 Subject: [PATCH 03/11] Remove .sort() and fix logic in test --- spec/core/DelayedFunctionSchedulerSpec.js | 18 ++++++++++-------- src/core/DelayedFunctionScheduler.js | 4 +--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/core/DelayedFunctionSchedulerSpec.js b/spec/core/DelayedFunctionSchedulerSpec.js index c26252ef..fa846d6f 100644 --- a/spec/core/DelayedFunctionSchedulerSpec.js +++ b/spec/core/DelayedFunctionSchedulerSpec.js @@ -216,21 +216,23 @@ describe("DelayedFunctionScheduler", function() { it("removes functions during a tick that runs the function", function() { var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(), - fn = jasmine.createSpy('fn'), + spy = jasmine.createSpy('fn'), + spyAndRemove = jasmine.createSpy('fn'), fnDelay = 10, timeoutKey; - timeoutKey = scheduler.scheduleFunction(fn, fnDelay, [], true); - scheduler.scheduleFunction(function () { + spyAndRemove.and.callFake(function() { scheduler.removeFunctionWithId(timeoutKey); - }, 2 * fnDelay); + }); - expect(fn).not.toHaveBeenCalled(); + scheduler.scheduleFunction(spyAndRemove, fnDelay); - scheduler.tick(3 * fnDelay); + timeoutKey = scheduler.scheduleFunction(spy, fnDelay, [], true); - expect(fn).toHaveBeenCalled(); - expect(fn.calls.count()).toBe(2); + scheduler.tick(2 * fnDelay); + + expect(spy).not.toHaveBeenCalled(); + expect(spyAndRemove).toHaveBeenCalled(); }); it("removes functions during the first tick that runs the function", function() { diff --git a/src/core/DelayedFunctionScheduler.js b/src/core/DelayedFunctionScheduler.js index 91557a37..73001cc3 100644 --- a/src/core/DelayedFunctionScheduler.js +++ b/src/core/DelayedFunctionScheduler.js @@ -129,9 +129,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() { currentTime = newCurrentTime; - var funcsToRun = scheduledFunctions[currentTime].sort(function (a, b) { - return a.millis > b.millis; - }); + var funcsToRun = scheduledFunctions[currentTime]; delete scheduledFunctions[currentTime]; From cb6de64e58ab08856e31f24cc33e556fc335f783 Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Tue, 2 Jan 2018 18:17:23 -0800 Subject: [PATCH 04/11] Fixed DelayedFunctionScheduler IE 8 compatibility issue --- lib/jasmine-core/jasmine.js | 6 +++--- src/core/DelayedFunctionScheduler.js | 4 ++-- src/core/requireCore.js | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 65ed7782..b737f831 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -54,7 +54,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) { j$.MockDate = jRequire.MockDate(); j$.getClearStack = jRequire.clearStack(j$); j$.Clock = jRequire.Clock(); - j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(); + j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$); j$.Env = jRequire.Env(j$); j$.ExceptionFormatter = jRequire.ExceptionFormatter(); j$.Expectation = jRequire.Expectation(); @@ -2059,7 +2059,7 @@ getJasmineRequireObj().Clock = function() { return Clock; }; -getJasmineRequireObj().DelayedFunctionScheduler = function() { +getJasmineRequireObj().DelayedFunctionScheduler = function(j$) { function DelayedFunctionScheduler() { var self = this; var scheduledLookup = []; @@ -2201,7 +2201,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() { }); forEachFunction(funcsToRun, function(funcToRun) { - if (deletedKeys.indexOf(funcToRun.timeoutKey) !== -1) { + if (j$.util.arrayContains(deletedKeys, funcToRun.timeoutKey)) { // skip a timeoutKey deleted whilst we were running return; } diff --git a/src/core/DelayedFunctionScheduler.js b/src/core/DelayedFunctionScheduler.js index 73001cc3..62cf5dc9 100644 --- a/src/core/DelayedFunctionScheduler.js +++ b/src/core/DelayedFunctionScheduler.js @@ -1,4 +1,4 @@ -getJasmineRequireObj().DelayedFunctionScheduler = function() { +getJasmineRequireObj().DelayedFunctionScheduler = function(j$) { function DelayedFunctionScheduler() { var self = this; var scheduledLookup = []; @@ -140,7 +140,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() { }); forEachFunction(funcsToRun, function(funcToRun) { - if (deletedKeys.indexOf(funcToRun.timeoutKey) !== -1) { + if (j$.util.arrayContains(deletedKeys, funcToRun.timeoutKey)) { // skip a timeoutKey deleted whilst we were running return; } diff --git a/src/core/requireCore.js b/src/core/requireCore.js index 159e75a8..a40bf768 100644 --- a/src/core/requireCore.js +++ b/src/core/requireCore.js @@ -32,7 +32,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) { j$.MockDate = jRequire.MockDate(); j$.getClearStack = jRequire.clearStack(j$); j$.Clock = jRequire.Clock(); - j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(); + j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$); j$.Env = jRequire.Env(j$); j$.ExceptionFormatter = jRequire.ExceptionFormatter(); j$.Expectation = jRequire.Expectation(); From aeeb5b7107058da2629b4250288451795d3c5e82 Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Wed, 10 Jan 2018 10:16:02 -0800 Subject: [PATCH 05/11] Bumped copyright dates --- lib/console/console.js | 2 +- lib/jasmine-core/boot.js | 2 +- lib/jasmine-core/jasmine-html.js | 2 +- lib/jasmine-core/node_boot.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/console/console.js b/lib/console/console.js index 38ad952d..43a82ac6 100644 --- a/lib/console/console.js +++ b/lib/console/console.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2008-2017 Pivotal Labs +Copyright (c) 2008-2018 Pivotal Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/lib/jasmine-core/boot.js b/lib/jasmine-core/boot.js index 85adb0d8..8d6e4217 100644 --- a/lib/jasmine-core/boot.js +++ b/lib/jasmine-core/boot.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2008-2017 Pivotal Labs +Copyright (c) 2008-2018 Pivotal Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/lib/jasmine-core/jasmine-html.js b/lib/jasmine-core/jasmine-html.js index 2ce54d1b..221a15d5 100644 --- a/lib/jasmine-core/jasmine-html.js +++ b/lib/jasmine-core/jasmine-html.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2008-2017 Pivotal Labs +Copyright (c) 2008-2018 Pivotal Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/lib/jasmine-core/node_boot.js b/lib/jasmine-core/node_boot.js index 7268ae9b..f23e2192 100644 --- a/lib/jasmine-core/node_boot.js +++ b/lib/jasmine-core/node_boot.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2008-2017 Pivotal Labs +Copyright (c) 2008-2018 Pivotal Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the From 085a1f8a16dd4318d58bb4882e4a5340c0e1f5e3 Mon Sep 17 00:00:00 2001 From: Volonterio Riccardo Date: Thu, 11 Jan 2018 18:13:24 +0100 Subject: [PATCH 06/11] Added complete support for Map also for IE11. Fixes 1472 --- spec/core/PrettyPrintSpec.js | 14 ++-- spec/core/matchers/matchersUtilSpec.js | 27 ++++++-- spec/core/matchers/toEqualSpec.js | 91 +++++++++++++++++--------- spec/helpers/checkForMap.js | 34 ++++++++-- src/core/PrettyPrinter.js | 19 ++++-- src/core/base.js | 4 ++ src/core/matchers/matchersUtil.js | 68 ++++++++++--------- 7 files changed, 173 insertions(+), 84 deletions(-) diff --git a/spec/core/PrettyPrintSpec.js b/spec/core/PrettyPrintSpec.js index 65578260..a484a8ad 100644 --- a/spec/core/PrettyPrintSpec.js +++ b/spec/core/PrettyPrintSpec.js @@ -35,8 +35,10 @@ describe("jasmineUnderTest.pp", function () { describe('stringify maps', function() { it("should stringify maps properly", function() { - jasmine.getEnv().requireFunctioningMaps(); - expect(jasmineUnderTest.pp(new Map([[1, 2]]))).toEqual("Map( [ 1, 2 ] )"); + jasmine.getEnv().requireFunctioningMaps(); + var map = new Map(); + map.set(1,2); + expect(jasmineUnderTest.pp(map)).toEqual("Map( [ 1, 2 ] )"); }); it("should truncate maps with more elments than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() { @@ -44,8 +46,12 @@ describe("jasmineUnderTest.pp", function () { var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH; try { - jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2; - expect(jasmineUnderTest.pp(new Map([["a", 1], ["b", 2], ["c", 3]]))).toEqual("Map( [ 'a', 1 ], [ 'b', 2 ], ... )"); + jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2; + var map = new Map(); + map.set("a",1); + map.set("b",2); + map.set("c",3); + expect(jasmineUnderTest.pp(map)).toEqual("Map( [ 'a', 1 ], [ 'b', 2 ], ... )"); } finally { jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize; } diff --git a/spec/core/matchers/matchersUtilSpec.js b/spec/core/matchers/matchersUtilSpec.js index 485d72b4..e9976f1e 100644 --- a/spec/core/matchers/matchersUtilSpec.js +++ b/spec/core/matchers/matchersUtilSpec.js @@ -445,7 +445,8 @@ describe("matchersUtil", function() { it("passes when comparing identical maps", function() { jasmine.getEnv().requireFunctioningMaps(); - var mapA = new Map([[6, 5]]); + var mapA = new Map(); + mapA.set(6, 5); var mapB = new Map(); mapB.set(6, 5); expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(true); @@ -453,22 +454,34 @@ describe("matchersUtil", function() { it("passes when comparing identical maps with different insertion order", function() { jasmine.getEnv().requireFunctioningMaps(); - var mapA = new Map([['a', 3], [6, 1]]); - var mapB = new Map([[6, 1], ['a', 3]]); + var mapA = new Map(); + mapA.set("a", 3); + mapA.set(6, 1); + var mapB = new Map(); + mapB.set(6, 1); + mapB.set("a", 3); expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(true); }); it("fails for maps with different elements", function() { jasmine.getEnv().requireFunctioningMaps(); - var mapA = new Map([[6, 3], [5, 1]]); - var mapB = new Map([[6, 4], [5, 1]]); + var mapA = new Map(); + mapA.set(6, 3); + mapA.set(5, 1); + var mapB = new Map(); + mapB.set(6, 4); + mapB.set(5, 1); + expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(false); }); it("fails for maps of different size", function() { jasmine.getEnv().requireFunctioningMaps(); - var mapA = new Map([[6, 3]]); - var mapB = new Map([[6, 4], [5, 1]]); + var mapA = new Map(); + mapA.set(6, 3); + var mapB = new Map(); + mapB.set(6, 4); + mapB.set(5, 1); expect(jasmineUnderTest.matchersUtil.equals(mapA, mapB)).toBe(false); }); diff --git a/spec/core/matchers/toEqualSpec.js b/spec/core/matchers/toEqualSpec.js index 2c4916bb..5ab468c1 100644 --- a/spec/core/matchers/toEqualSpec.js +++ b/spec/core/matchers/toEqualSpec.js @@ -436,11 +436,13 @@ describe("toEqual", function() { // == Maps == it("does not report mismatches between deep equal Maps", function() { - jasmine.getEnv().requireFunctioningSets(); + jasmine.getEnv().requireFunctioningMaps(); // values are the same but with different object identity - var actual = new Map([['a', {x: 1}]]), - expected = new Map([['a', {x: 1}]]); + var actual = new Map(); + actual.set('a',{x:1}); + var expected = new Map(); + expected.set('a',{x:1}); expect(compareEquals(actual, expected).pass).toBe(true); }); @@ -448,9 +450,11 @@ describe("toEqual", function() { it("reports deep mismatches within Maps", function() { jasmine.getEnv().requireFunctioningMaps(); - var actual = new Map([['a', {x: 1}]]), - expected = new Map([['a', {x: 2}]]), - message = "Expected Map( [ 'a', Object({ x: 1 }) ] ) to equal Map( [ 'a', Object({ x: 2 }) ] )."; + var actual = new Map(); + actual.set('a',{x:1}); + var expected = new Map(); + expected.set('a',{x:2}); + var message = "Expected Map( [ 'a', Object({ x: 1 }) ] ) to equal Map( [ 'a', Object({ x: 2 }) ] )."; expect(compareEquals(actual, expected).message).toEqual(message); }); @@ -458,9 +462,14 @@ describe("toEqual", function() { it("reports mismatches between Maps nested in objects", function() { jasmine.getEnv().requireFunctioningMaps(); - var actual = {Maps: [new Map([['a', 1]])]}, - expected = {Maps: [new Map([['a', 2]])]}, - message = "Expected $.Maps[0] = Map( [ 'a', 1 ] ) to equal Map( [ 'a', 2 ] )."; + var actual = {Maps:[new Map()]}; + actual.Maps[0].set('a',1); + var expected = {Maps:[new Map()]}; + expected.Maps[0].set('a',2); + + // var actual = {Maps: [new Map([['a', 1]])]}, + // expected = {Maps: [new Map([['a', 2]])]}, + var message = "Expected $.Maps[0] = Map( [ 'a', 1 ] ) to equal Map( [ 'a', 2 ] )."; expect(compareEquals(actual, expected).message).toEqual(message); }); @@ -468,9 +477,12 @@ describe("toEqual", function() { it("reports mismatches between Maps of different lengths", function() { jasmine.getEnv().requireFunctioningMaps(); - var actual = new Map([['a', 1]]), - expected = new Map([['a', 2], ['b', 1]]), - message = "Expected Map( [ 'a', 1 ] ) to equal Map( [ 'a', 2 ], [ 'b', 1 ] )."; + var actual = new Map(); + actual.set('a',1); + var expected = new Map(); + expected.set('a',2); + expected.set('b',1); + var message = "Expected Map( [ 'a', 1 ] ) to equal Map( [ 'a', 2 ], [ 'b', 1 ] )."; expect(compareEquals(actual, expected).message).toEqual(message); }); @@ -478,18 +490,22 @@ describe("toEqual", function() { it("reports mismatches between Maps with equal values but differing keys", function() { jasmine.getEnv().requireFunctioningMaps(); - var actual = new Map([['a', 1]]), - expected = new Map([['b', 1]]), - message = "Expected Map( [ 'a', 1 ] ) to equal Map( [ 'b', 1 ] )."; + var actual = new Map(); + actual.set('a',1); + var expected = new Map(); + expected.set('b',1); + var message = "Expected Map( [ 'a', 1 ] ) to equal Map( [ 'b', 1 ] )."; expect(compareEquals(actual, expected).message).toEqual(message); }); it("does not report mismatches between Maps with keys with same object identity", function() { jasmine.getEnv().requireFunctioningMaps(); - var key = {x: 1}, - actual = new Map([[key, 2]]), - expected = new Map([[key, 2]]); + var key = {x: 1}; + var actual = new Map(); + actual.set(key,2); + var expected = new Map(); + expected.set(key,2); expect(compareEquals(actual, expected).pass).toBe(true); }); @@ -497,9 +513,11 @@ describe("toEqual", function() { it("reports mismatches between Maps with identical keys with different object identity", function() { jasmine.getEnv().requireFunctioningMaps(); - var actual = new Map([[{x: 1}, 2]]), - expected = new Map([[{x: 1}, 2]]), - message = "Expected Map( [ Object({ x: 1 }), 2 ] ) to equal Map( [ Object({ x: 1 }), 2 ] )."; + var actual = new Map(); + actual.set({x:1},2); + var expected = new Map(); + expected.set({x:1},2); + var message = "Expected Map( [ Object({ x: 1 }), 2 ] ) to equal Map( [ Object({ x: 1 }), 2 ] )."; expect(compareEquals(actual, expected).message).toEqual(message); }); @@ -507,8 +525,11 @@ describe("toEqual", function() { it("does not report mismatches when comparing Map key to jasmine.anything()", function() { jasmine.getEnv().requireFunctioningMaps(); - var actual = new Map([['a', 1]]), - expected = new Map([[jasmineUnderTest.anything(), 1]]); + var actual = new Map(); + actual.set('a',1); + var expected = new Map(); + expected.set(jasmineUnderTest.anything(),1); + expect(compareEquals(actual, expected).pass).toBe(true); }); @@ -516,9 +537,12 @@ describe("toEqual", function() { jasmine.getEnv().requireFunctioningMaps(); jasmine.getEnv().requireFunctioningSymbols(); - var key = Symbol(), - actual = new Map([[key, 1]]), - expected = new Map([[key, 1]]); + var key = Symbol(); + var actual = new Map(); + actual.set(key,1); + var expected = new Map(); + expected.set(key,1); + expect(compareEquals(actual, expected).pass).toBe(true); }); @@ -526,9 +550,11 @@ describe("toEqual", function() { jasmine.getEnv().requireFunctioningMaps(); jasmine.getEnv().requireFunctioningSymbols(); - var actual = new Map([[Symbol(), 1]]), - expected = new Map([[Symbol(), 1]]), - message = "Expected Map( [ Symbol(), 1 ] ) to equal Map( [ Symbol(), 1 ] )."; + var actual = new Map(); + actual.set(Symbol(),1); + var expected = new Map(); + expected.set(Symbol(),1); + var message = "Expected Map( [ Symbol(), 1 ] ) to equal Map( [ Symbol(), 1 ] )."; expect(compareEquals(actual, expected).message).toBe(message); }); @@ -537,8 +563,11 @@ describe("toEqual", function() { jasmine.getEnv().requireFunctioningMaps(); jasmine.getEnv().requireFunctioningSymbols(); - var actual = new Map([[Symbol(), 1]]), - expected = new Map([[jasmineUnderTest.anything(), 1]]); + var actual = new Map(); + actual.set(Symbol(),1); + var expected = new Map(); + expected.set(jasmineUnderTest.anything(),1); + expect(compareEquals(actual, expected).pass).toBe(true); }); diff --git a/spec/helpers/checkForMap.js b/spec/helpers/checkForMap.js index b924e1a1..e0f9f2a3 100644 --- a/spec/helpers/checkForMap.js +++ b/spec/helpers/checkForMap.js @@ -3,10 +3,36 @@ if (typeof Map === 'undefined') { return false; } try { - var s = new Map([['a', 4]]); - if (s.size !== 1) { return false; } - if (s.keys().next().value !== 'a') { return false; } - if (s.values().next().value !== 4) { return false; } + var s = new Map(); + s.set('a',1); + s.set('b',2); + + // Check for `size` + if (s.size !== 2) { return false; } + + // Check for `has` + if (s.has('a') !== true) { return false; } + + // Check for `delete` + if (s.delete('b') !== true) { return false; } + + // Check for `forEach` + var iterations = 0; + var ifForEachWorking = true; + s.forEach( function( value, key, map ) { + ifForEachWorking = ifForEachWorking && map === s; + if( key==='a') { + ifForEachWorking = ifForEachWorking && value===1; + } + iterations++; + } ); + if (iterations !== 1) { return false; } + if (ifForEachWorking !== true) { return false; } + + // Check for `clear` + s.clear() + if (s.size !== 0) { return false; } + return true; } catch(e) { return false; diff --git a/src/core/PrettyPrinter.js b/src/core/PrettyPrinter.js index 88746102..09066dc1 100644 --- a/src/core/PrettyPrinter.js +++ b/src/core/PrettyPrinter.js @@ -40,7 +40,7 @@ getJasmineRequireObj().pp = function(j$) { this.emitScalar('Date(' + value + ')'); } else if (j$.getType_(value) == '[object Set]') { this.emitSet(value); - } else if (j$.getType_(value) == '[object Map]') { + } else if (j$.isMap(value)) { this.emitMap(value); } else if (j$.isTypedArray_(value)) { this.emitTypedArray(value); @@ -157,13 +157,18 @@ getJasmineRequireObj().pp = function(j$) { } this.append('Map( '); var size = Math.min(map.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH); - var iter = map.entries(); - for (var i = 0; i < size; i++) { - if (i > 0) { + var i = 0; + map.forEach( function( value, key ) { + if (i >= size) { + return; + } + if (i > 0) { this.append(', '); - } - this.format(iter.next().value); - } + } + this.format([key,value]); + + i++; + }, this ); if (map.size > size){ this.append(', ...'); } diff --git a/src/core/base.js b/src/core/base.js index da39f762..cf1d3848 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -93,6 +93,10 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { return obj.nodeType > 0; }; + j$.isMap = function(obj) { + return typeof jasmineGlobal.Map !== 'undefined' && obj.constructor === jasmineGlobal.Map; + }; + j$.isPromise = function(obj) { return typeof jasmineGlobal.Promise !== 'undefined' && obj.constructor === jasmineGlobal.Promise; }; diff --git a/src/core/matchers/matchersUtil.js b/src/core/matchers/matchersUtil.js index 235e5a05..c07463d1 100644 --- a/src/core/matchers/matchersUtil.js +++ b/src/core/matchers/matchersUtil.js @@ -253,42 +253,48 @@ getJasmineRequireObj().matchersUtil = function(j$) { if (!result) { return false; } - } else if (className == '[object Map]') { + } else if (j$.isMap(a) && j$.isMap(b)) { if (a.size != b.size) { diffBuilder.record(a, b); return false; - } + } + + var keysA = []; + var keysB = []; + a.forEach( function( valueA, keyA ) { + keysA.push( keyA ); + }); + b.forEach( function( valueB, keyB ) { + keysB.push( keyB ); + }); - // For both sets of keys, check they map to equal values in both maps. - // Keep track of corresponding keys (in insertion order) in order to handle asymmetric obj keys. - var mapKeys = [a.keys(), b.keys()]; - var cmpKeys = [b.keys(), a.keys()]; - var mapIter, mapKeyIt, mapKey, mapValueA, mapValueB; - var cmpIter, cmpKeyIt, cmpKey; - for (i = 0; result && i < mapKeys.length; i++) { - mapIter = mapKeys[i]; - cmpIter = cmpKeys[i]; - mapKeyIt = mapIter.next(); - cmpKeyIt = cmpIter.next(); - while (result && !mapKeyIt.done) { - mapKey = mapKeyIt.value; - cmpKey = cmpKeyIt.value; - mapValueA = a.get(mapKey); + // For both sets of keys, check they map to equal values in both maps. + // Keep track of corresponding keys (in insertion order) in order to handle asymmetric obj keys. + var mapKeys = [keysA, keysB]; + var cmpKeys = [keysB, keysA]; + var mapIter, mapKey, mapValueA, mapValueB; + var cmpIter, cmpKey; + for (i = 0; result && i < mapKeys.length; i++) { + mapIter = mapKeys[i]; + cmpIter = cmpKeys[i]; + + for (var j = 0; result && j < mapIter.length; j++) { + mapKey = mapIter[j]; + cmpKey = cmpIter[j]; + mapValueA = a.get(mapKey); - // Only use the cmpKey when one of the keys is asymmetric and the corresponding key matches, - // otherwise explicitly look up the mapKey in the other Map since we want keys with unique - // obj identity (that are otherwise equal) to not match. - if (isAsymmetric(mapKey) || isAsymmetric(cmpKey) && - eq(mapKey, cmpKey, aStack, bStack, customTesters, j$.NullDiffBuilder())) { - mapValueB = b.get(cmpKey); - } else { - mapValueB = b.get(mapKey); - } - result = eq(mapValueA, mapValueB, aStack, bStack, customTesters, j$.NullDiffBuilder()); - mapKeyIt = mapIter.next(); - cmpKeyIt = cmpIter.next(); - } - } + // Only use the cmpKey when one of the keys is asymmetric and the corresponding key matches, + // otherwise explicitly look up the mapKey in the other Map since we want keys with unique + // obj identity (that are otherwise equal) to not match. + if (isAsymmetric(mapKey) || isAsymmetric(cmpKey) && + eq(mapKey, cmpKey, aStack, bStack, customTesters, j$.NullDiffBuilder())) { + mapValueB = b.get(cmpKey); + } else { + mapValueB = b.get(mapKey); + } + result = eq(mapValueA, mapValueB, aStack, bStack, customTesters, j$.NullDiffBuilder()); + } + } if (!result) { diffBuilder.record(a, b); From 486a64658f17b8fca4798b3a2661b6cd6df88317 Mon Sep 17 00:00:00 2001 From: Volonterio Riccardo Date: Fri, 12 Jan 2018 12:18:35 +0100 Subject: [PATCH 07/11] Added complete support for Set also for IE11. Fixes 1355 --- spec/core/PrettyPrintSpec.js | 15 ++++-- spec/core/matchers/matchersUtilSpec.js | 75 +++++++++++++++++++++----- spec/core/matchers/toEqualSpec.js | 56 ++++++++++++------- spec/helpers/checkForSet.js | 26 +++++++-- src/core/PrettyPrinter.js | 15 ++++-- src/core/base.js | 4 ++ src/core/matchers/matchersUtil.js | 41 +++++++------- 7 files changed, 169 insertions(+), 63 deletions(-) diff --git a/spec/core/PrettyPrintSpec.js b/spec/core/PrettyPrintSpec.js index 2edb8894..32b9d99b 100644 --- a/spec/core/PrettyPrintSpec.js +++ b/spec/core/PrettyPrintSpec.js @@ -16,8 +16,11 @@ describe("jasmineUnderTest.pp", function () { describe('stringify sets', function() { it("should stringify sets properly", function() { - jasmine.getEnv().requireFunctioningSets(); - expect(jasmineUnderTest.pp(new Set([1, 2]))).toEqual("Set( 1, 2 )"); + jasmine.getEnv().requireFunctioningSets(); + var set = new Set(); + set.add(1); + set.add(2); + expect(jasmineUnderTest.pp(set)).toEqual("Set( 1, 2 )"); }); it("should truncate sets with more elments than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() { @@ -25,8 +28,12 @@ describe("jasmineUnderTest.pp", function () { var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH; try { - jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2; - expect(jasmineUnderTest.pp(new Set(["a", "b", "c"]))).toEqual("Set( 'a', 'b', ... )"); + jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2; + var set = new Set(); + set.add('a'); + set.add('b'); + set.add('c'); + expect(jasmineUnderTest.pp(set)).toEqual("Set( 'a', 'b', ... )"); } finally { jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize; } diff --git a/spec/core/matchers/matchersUtilSpec.js b/spec/core/matchers/matchersUtilSpec.js index b47f4772..5a40e665 100644 --- a/spec/core/matchers/matchersUtilSpec.js +++ b/spec/core/matchers/matchersUtilSpec.js @@ -396,45 +396,94 @@ describe("matchersUtil", function() { it("passes when comparing identical sets", function() { jasmine.getEnv().requireFunctioningSets(); - var setA = new Set([6, 5]); + + var setA = new Set(); + setA.add(6); + setA.add(5); var setB = new Set(); setB.add(6); setB.add(5); + expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true); }); it("passes when comparing identical sets with different insertion order and simple elements", function() { jasmine.getEnv().requireFunctioningSets(); - var setA = new Set([3, 6]); - var setB = new Set([6, 3]); + + var setA = new Set(); + setA.add(3); + setA.add(6); + var setB = new Set(); + setB.add(6); + setB.add(3); + expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true); }); it("passes when comparing identical sets with different insertion order and complex elements 1", function() { - jasmine.getEnv().requireFunctioningMaps(); - var setA = new Set([new Set([['a', 3], [6, 1]]), new Set([['y', 3], [6, 1]])]); - var setB = new Set([new Set([[6, 1], ['a', 3]]), new Set([[6, 1], ['y', 3]])]); + jasmine.getEnv().requireFunctioningSets(); + + var setA1 = new Set(); + setA1.add(['a',3]); + setA1.add([6,1]); + var setA2 = new Set(); + setA1.add(['y',3]); + setA1.add([6,1]); + var setA = new Set(); + setA.add(setA1); + setA.add(setA2); + + + var setB1 = new Set(); + setB1.add([6,1]); + setB1.add(['a',3]); + var setB2 = new Set(); + setB1.add([6,1]); + setB1.add(['y',3]); + var setB = new Set(); + setB.add(setB1); + setB.add(setB2); + expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true); }); it("passes when comparing identical sets with different insertion order and complex elements 2", function() { - jasmine.getEnv().requireFunctioningMaps(); - var setA = new Set([[[1,2], [3,4]], [[5,6], [7,8]]]); - var setB = new Set([[[5,6], [7,8]], [[1,2], [3,4]]]); + jasmine.getEnv().requireFunctioningSets(); + + var setA = new Set(); + setA.add([[1,2], [3,4]]); + setA.add([[5,6], [7,8]]); + var setB = new Set(); + setB.add([[5,6], [7,8]]); + setB.add([[1,2], [3,4]]); + expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true); }); it("fails for sets with different elements", function() { jasmine.getEnv().requireFunctioningSets(); - var setA = new Set([6, 3, 5]); - var setB = new Set([6, 4, 5]); + var setA = new Set(); + setA.add(6); + setA.add(3); + setA.add(5); + var setB = new Set(); + setB.add(6); + setB.add(4); + setB.add(5); + expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(false); }); it("fails for sets of different size", function() { jasmine.getEnv().requireFunctioningSets(); - var setA = new Set([6, 3]); - var setB = new Set([6, 4, 5]); + var setA = new Set(); + setA.add(6); + setA.add(3); + var setB = new Set(); + setB.add(6); + setB.add(4); + setB.add(5); + expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(false); }); diff --git a/spec/core/matchers/toEqualSpec.js b/spec/core/matchers/toEqualSpec.js index 0dc50dd8..d186025b 100644 --- a/spec/core/matchers/toEqualSpec.js +++ b/spec/core/matchers/toEqualSpec.js @@ -374,9 +374,11 @@ describe("toEqual", function() { it("reports mismatches between Sets", function() { jasmine.getEnv().requireFunctioningSets(); - var actual = new Set([1]), - expected = new Set([2]), - message = 'Expected Set( 1 ) to equal Set( 2 ).'; + var actual = new Set(); + actual.add(1); + var expected = new Set(); + expected.add(2); + var message = 'Expected Set( 1 ) to equal Set( 2 ).'; expect(compareEquals(actual, expected).message).toEqual(message); }); @@ -384,9 +386,11 @@ describe("toEqual", function() { it("reports deep mismatches within Sets", function() { jasmine.getEnv().requireFunctioningSets(); - var actual = new Set([{x: 1}]), - expected = new Set([{x: 2}]), - message = 'Expected Set( Object({ x: 1 }) ) to equal Set( Object({ x: 2 }) ).'; + var actual = new Set(); + actual.add({x: 1}); + var expected = new Set(); + expected.add({x: 2}); + var message = 'Expected Set( Object({ x: 1 }) ) to equal Set( Object({ x: 2 }) ).'; expect(compareEquals(actual, expected).message).toEqual(message); }); @@ -394,9 +398,14 @@ describe("toEqual", function() { it("reports mismatches between Sets nested in objects", function() { jasmine.getEnv().requireFunctioningSets(); - var actual = {sets: [new Set([1])]}, - expected = {sets: [new Set([2])]}, - message = "Expected $.sets[0] = Set( 1 ) to equal Set( 2 )."; + var actualSet = new Set(); + actualSet.add(1); + var expectedSet = new Set(); + expectedSet.add(2); + + var actual = { sets: [actualSet] }; + var expected = { sets: [expectedSet] }; + var message = "Expected $.sets[0] = Set( 1 ) to equal Set( 2 )."; expect(compareEquals(actual, expected).message).toEqual(message); }); @@ -404,9 +413,12 @@ describe("toEqual", function() { it("reports mismatches between Sets of different lengths", function() { jasmine.getEnv().requireFunctioningSets(); - var actual = new Set([1, 2]), - expected = new Set([2]), - message = 'Expected Set( 1, 2 ) to equal Set( 2 ).'; + var actual = new Set(); + actual.add(1); + actual.add(2); + var expected = new Set(); + expected.add(2); + var message = 'Expected Set( 1, 2 ) to equal Set( 2 ).'; expect(compareEquals(actual, expected).message).toEqual(message); }); @@ -415,9 +427,13 @@ describe("toEqual", function() { jasmine.getEnv().requireFunctioningSets(); // Use 'duplicate' object in actual so sizes match - var actual = new Set([{x: 1}, {x: 1}]), - expected = new Set([{x: 1}, {x: 2}]), - message = 'Expected Set( Object({ x: 1 }), Object({ x: 1 }) ) to equal Set( Object({ x: 1 }), Object({ x: 2 }) ).'; + var actual = new Set(); + actual.add({x: 1}); + actual.add({x: 1}); + var expected = new Set(); + expected.add({x: 1}); + expected.add({x: 2}); + var message = 'Expected Set( Object({ x: 1 }), Object({ x: 1 }) ) to equal Set( Object({ x: 1 }), Object({ x: 2 }) ).'; expect(compareEquals(actual, expected).message).toEqual(message); }); @@ -426,9 +442,13 @@ describe("toEqual", function() { jasmine.getEnv().requireFunctioningSets(); // Use 'duplicate' object in expected so sizes match - var actual = new Set([{x: 1}, {x: 2}]), - expected = new Set([{x: 1}, {x: 1}]), - message = 'Expected Set( Object({ x: 1 }), Object({ x: 2 }) ) to equal Set( Object({ x: 1 }), Object({ x: 1 }) ).'; + var actual = new Set(); + actual.add({x: 1}); + actual.add({x: 2}); + var expected = new Set(); + expected.add({x: 1}); + expected.add({x: 1}); + var message = 'Expected Set( Object({ x: 1 }), Object({ x: 2 }) ) to equal Set( Object({ x: 1 }), Object({ x: 1 }) ).'; expect(compareEquals(actual, expected).message).toEqual(message); }); diff --git a/spec/helpers/checkForSet.js b/spec/helpers/checkForSet.js index eb31aed7..4ba13edd 100644 --- a/spec/helpers/checkForSet.js +++ b/spec/helpers/checkForSet.js @@ -3,9 +3,29 @@ if (typeof Set === 'undefined') { return false; } try { - var s = new Set([4]); - if (s.size !== 1) { return false; } - if (s.values().next().value !== 4) { return false; } + var s = new Set(); + s.add(1); + s.add(2); + + if (s.size !== 2) { return false; } + if (s.has(1) !== true) { return false; } + + var iterations = 0; + var isForEachWorking = true; + s.forEach(function(value, key, set) { + isForEachWorking = isForEachWorking && set === s; + + if (iterations===0) { + isForEachWorking = isForEachWorking && (key===value) && value===1; + } else if (iterations===1) { + isForEachWorking = isForEachWorking && (key===value) && value===2; + } + + iterations++; + }); + if (iterations !== 2) { return false; } + if (isForEachWorking !== true) { return false; } + return true; } catch(e) { return false; diff --git a/src/core/PrettyPrinter.js b/src/core/PrettyPrinter.js index 5f2ffbe4..ab680130 100644 --- a/src/core/PrettyPrinter.js +++ b/src/core/PrettyPrinter.js @@ -38,7 +38,7 @@ getJasmineRequireObj().pp = function(j$) { this.emitScalar('HTMLNode'); } else if (value instanceof Date) { this.emitScalar('Date(' + value + ')'); - } else if (j$.getType_(value) == '[object Set]') { + } else if (j$.isSet(value)) { this.emitSet(value); } else if (j$.isMap(value)) { this.emitMap(value); @@ -137,13 +137,18 @@ getJasmineRequireObj().pp = function(j$) { } this.append('Set( '); var size = Math.min(set.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH); - var iter = set.values(); - for (var i = 0; i < size; i++) { + var i = 0; + set.forEach( function( value, key ) { + if (i >= size) { + return; + } if (i > 0) { this.append(', '); } - this.format(iter.next().value); - } + this.format(value); + + i++; + }, this ); if (set.size > size){ this.append(', ...'); } diff --git a/src/core/base.js b/src/core/base.js index 13d1504b..9781fa20 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -95,6 +95,10 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { j$.isMap = function(obj) { return typeof jasmineGlobal.Map !== 'undefined' && obj.constructor === jasmineGlobal.Map; + }; + + j$.isSet = function(obj) { + return typeof jasmineGlobal.Set !== 'undefined' && obj.constructor === jasmineGlobal.Set; }; j$.isPromise = function(obj) { diff --git a/src/core/matchers/matchersUtil.js b/src/core/matchers/matchersUtil.js index 7b9cb4b3..c91609f4 100644 --- a/src/core/matchers/matchersUtil.js +++ b/src/core/matchers/matchersUtil.js @@ -300,48 +300,49 @@ getJasmineRequireObj().matchersUtil = function(j$) { diffBuilder.record(a, b); return false; } - } else if (className == '[object Set]') { + } else if (j$.isSet(a) && j$.isSet(b)) { if (a.size != b.size) { diffBuilder.record(a, b); return false; } + var valuesA = []; + a.forEach( function( valueA ) { + valuesA.push( valueA ); + }); + var valuesB = []; + b.forEach( function( valueB ) { + valuesB.push( valueB ); + }); + // For both sets, check they are all contained in the other set - var setPairs = [[a, b], [b, a]]; + var setPairs = [[valuesA, valuesB], [valuesB, valuesA]]; var stackPairs = [[aStack, bStack], [bStack, aStack]]; - var baseIter, baseValueIt, baseValue, baseStack; - var otherSet, otherIter, otherValueIt, otherValue, otherStack; + var baseIter, baseValue, baseStack; + var otherSet, otherIter, otherValue, otherStack; var found; var prevStackSize; for (i = 0; result && i < setPairs.length; i++) { - baseIter = setPairs[i][0].values(); - otherSet = setPairs[i][1]; + baseIter = setPairs[i][0]; + otherIter = setPairs[i][1]; baseStack = stackPairs[i][0]; otherStack = stackPairs[i][1]; // For each value in the base set... - baseValueIt = baseIter.next(); - while (result && !baseValueIt.done) { - baseValue = baseValueIt.value; + for (var k = 0; result && k < baseIter.length; k++) { + baseValue = baseIter[k]; + found = false; // ... test that it is present in the other set - // Optimisation: start looking for value by object identity - found = otherSet.has(baseValue); - if (!found) { - otherIter = otherSet.values(); - otherValueIt = otherIter.next(); - } - // If not found, compare by value equality - while (!found && !otherValueIt.done) { - otherValue = otherValueIt.value; + for (var l = 0; !found && l < otherIter.length; l++) { + otherValue = otherIter[l]; prevStackSize = baseStack.length; + // compare by value equality found = eq(baseValue, otherValue, baseStack, otherStack, customTesters, j$.NullDiffBuilder()); if (!found && prevStackSize !== baseStack.length) { baseStack.splice(prevStackSize); otherStack.splice(prevStackSize); } - otherValueIt = otherIter.next(); } result = result && found; - baseValueIt = baseIter.next(); } } From f76b45281656b76ff979dc5410ccd08c9ef482e1 Mon Sep 17 00:00:00 2001 From: Gregg Van Hove Date: Fri, 12 Jan 2018 17:45:00 -0800 Subject: [PATCH 08/11] Correctly check for Symbols, not Sets in AnythingSpec --- spec/core/asymmetric_equality/AnythingSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/core/asymmetric_equality/AnythingSpec.js b/spec/core/asymmetric_equality/AnythingSpec.js index 76900993..216757eb 100644 --- a/spec/core/asymmetric_equality/AnythingSpec.js +++ b/spec/core/asymmetric_equality/AnythingSpec.js @@ -48,7 +48,7 @@ describe("Anything", function() { }); it("matches a Symbol", function() { - jasmine.getEnv().requireFunctioningSets(); + jasmine.getEnv().requireFunctioningSymbols(); var anything = new jasmineUnderTest.Anything(); From c82e5947f56d6f93a02a111fd004efb1924edbe1 Mon Sep 17 00:00:00 2001 From: Gregg Van Hove Date: Tue, 16 Jan 2018 17:29:34 -0800 Subject: [PATCH 09/11] Version bump to 2.9.0 --- RELEASE.md | 4 +- lib/jasmine-core/jasmine.js | 2 +- lib/jasmine-core/version.rb | 2 +- package.json | 2 +- release_notes/2.9.0.md | 99 +++++++++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 release_notes/2.9.0.md diff --git a/RELEASE.md b/RELEASE.md index caae7ddd..20790a52 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -7,9 +7,7 @@ Follow the instructions in `CONTRIBUTING.md` during development. ### Git Rules -Please work on feature branches. - -Please attempt to keep commits to `master` small, but cohesive. If a feature is contained in a bunch of small commits (e.g., it has several wip commits or small work), please squash them when merging back to `master`. +Please attempt to keep commits to `master` small, but cohesive. If a feature is contained in a bunch of small commits (e.g., it has several wip commits or small work), please squash them when pushing to `master`. ### Version diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 8db6151d..dbb71e2d 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -5538,5 +5538,5 @@ getJasmineRequireObj().UserContext = function(j$) { }; getJasmineRequireObj().version = function() { - return '2.8.0'; + return '2.9.0'; }; diff --git a/lib/jasmine-core/version.rb b/lib/jasmine-core/version.rb index b91a9e70..964fb68c 100644 --- a/lib/jasmine-core/version.rb +++ b/lib/jasmine-core/version.rb @@ -4,6 +4,6 @@ # module Jasmine module Core - VERSION = "2.8.0" + VERSION = "2.9.0" end end diff --git a/package.json b/package.json index 8fb199c9..d6505c54 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jasmine-core", "license": "MIT", - "version": "2.8.0", + "version": "2.9.0", "repository": { "type": "git", "url": "https://github.com/jasmine/jasmine.git" diff --git a/release_notes/2.9.0.md b/release_notes/2.9.0.md new file mode 100644 index 00000000..cebf13ec --- /dev/null +++ b/release_notes/2.9.0.md @@ -0,0 +1,99 @@ +# Jasmine 2.9 Release Notes + +## Summary + +This release contains a number of fixes and pull requests. + +## Changes + +* Fixed DelayedFunctionScheduler IE 8 compatibility issue +* Fixed SPEC HAS NO EXPECTATIONS warning in HTML reporter +* Correctly remove spies of window.onerror on IE +* Truncate pretty printer output that is more than j$.MAX_PRETTY_PRINT_CHARS long +* Reduced pretty printer limits to much smaller values +* Update contributing for new naming of `jasmineUnderTest` +* Allowed async functions to be passed into spy#callFake + +## Pull Requests & Issues + +* Added complete support for Set also for IE11. + - Merges [#1478](https://github.com/jasmine/jasmine/issues/1478) from @Volox + - Fixes [#1355](https://github.com/jasmine/jasmine/issues/1355) + + +* Added complete support for Map also for IE11. + - Merges [#1477](https://github.com/jasmine/jasmine/issues/1477) from @Volox + - Fixes [#1472](https://github.com/jasmine/jasmine/issues/1472) + + +* Use timeout objects when in node + - Merges [#1470](https://github.com/jasmine/jasmine/issues/1470) from @chris--young + - Fixes [#1469](https://github.com/jasmine/jasmine/issues/1469) + + +* Fixed `pending()` for `async`/promise-returning specs + - Fixes [#1449](https://github.com/jasmine/jasmine/issues/1449) + - Fixes [#1450](https://github.com/jasmine/jasmine/issues/1450) + + +* Added test steps for other major node versions + - Merges [#1448](https://github.com/jasmine/jasmine/issues/1448) from @mrlannigan + + +* Fix equality computation for ES6 Sets. + - Merges [#1445](https://github.com/jasmine/jasmine/issues/1445) from @b-3-n + - Fixes [#1444](https://github.com/jasmine/jasmine/issues/1444) + + +* Add instruction to sync local master with upstream + - Merges [#1440](https://github.com/jasmine/jasmine/issues/1440) from aaronang + + +* Add some unit tests that exercise jasmine.anything() and Map matching. + - Merges [#1437](https://github.com/jasmine/jasmine/issues/1437) from @voithos + + +* Add special handling of asymmetric matcher objects as keys in Maps. + - Merges [#1436](https://github.com/jasmine/jasmine/issues/1436) from @voithos + - Fixes [#1432](https://github.com/jasmine/jasmine/issues/1432) + + +* Add support for jasmine.any(Symbol). + - Merge [#1435](https://github.com/jasmine/jasmine/issues/1435) from @voithos + - Fixes [#1431](https://github.com/jasmine/jasmine/issues/1431) + + +* Throw an error for invalid nesting of a suite functions + - Merges [#1411](https://github.com/jasmine/jasmine/issues/1411) from @ksvitkovsky + - Fixes [#1295](https://github.com/jasmine/jasmine/issues/1295) + + +* Deep clone args before passing them to reporters + - Merges [#1424](https://github.com/jasmine/jasmine/issues/1424) from @aj-dev + + +* Fix "Before Committing" section of CONTRIBUTING.md. + - Merges [#1429](https://github.com/jasmine/jasmine/issues/1429) from @voithos + + +* Fix lint warning in CallTracker. + - Merges [#1428](https://github.com/jasmine/jasmine/issues/1428) from @voithos + + +* clearTimeout should now correctly clear a timeout that is also scheduled to run at the same tick. + - Merges [#1427](https://github.com/jasmine/jasmine/issues/1427) from @leahciMic + - Fixes [#1426](https://github.com/jasmine/jasmine/issues/1426) + + +* Add a note about `defineProperty` for `spyOnProperty` + - Fixes [#1415](https://github.com/jasmine/jasmine/issues/1415) + + +* Add Promise checking to eq + - Merges [#1386](https://github.com/jasmine/jasmine/issues/1386) from @sderickson + - Fixes [#1314](https://github.com/jasmine/jasmine/issues/1314) + + +------ + +_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_ From 53529bdc9a6c911cd6545c6cc1e9297ef3388cb2 Mon Sep 17 00:00:00 2001 From: Gregg Van Hove Date: Fri, 19 Jan 2018 17:47:28 -0800 Subject: [PATCH 10/11] Clear timeouts when starting to process a milli instead of at the end - Fixes #1482 --- spec/core/DelayedFunctionSchedulerSpec.js | 16 ++++++++++++++++ src/core/DelayedFunctionScheduler.js | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/spec/core/DelayedFunctionSchedulerSpec.js b/spec/core/DelayedFunctionSchedulerSpec.js index fa846d6f..f04d8f39 100644 --- a/spec/core/DelayedFunctionSchedulerSpec.js +++ b/spec/core/DelayedFunctionSchedulerSpec.js @@ -254,6 +254,22 @@ describe("DelayedFunctionScheduler", function() { expect(fn.calls.count()).toBe(1); }); + it("does not remove a function that hasn't been added yet", function() { + var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(), + fn = jasmine.createSpy('fn'), + fnDelay = 10, + timeoutKey; + + scheduler.removeFunctionWithId('foo'); + scheduler.scheduleFunction(fn, fnDelay, [], false, 'foo'); + + expect(fn).not.toHaveBeenCalled(); + + scheduler.tick(fnDelay + 1); + + expect(fn).toHaveBeenCalled(); + }); + it("updates the mockDate per scheduled time", function () { var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(), tickDate = jasmine.createSpy('tickDate'); diff --git a/src/core/DelayedFunctionScheduler.js b/src/core/DelayedFunctionScheduler.js index 62cf5dc9..5bceb48e 100644 --- a/src/core/DelayedFunctionScheduler.js +++ b/src/core/DelayedFunctionScheduler.js @@ -124,6 +124,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) { } do { + deletedKeys = []; var newCurrentTime = scheduledLookup.shift(); tickDate(newCurrentTime - currentTime); @@ -146,7 +147,6 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) { } funcToRun.funcToCall.apply(null, funcToRun.params || []); }); - deletedKeys = []; } while (scheduledLookup.length > 0 && // checking first if we're out of time prevents setTimeout(0) // scheduled in a funcToRun from forcing an extra iteration From 70bce5572190047980480ce3940f6253142691cd Mon Sep 17 00:00:00 2001 From: Gregg Van Hove Date: Fri, 19 Jan 2018 17:51:18 -0800 Subject: [PATCH 11/11] Bump version to 2.9.1 --- lib/jasmine-core/jasmine.js | 4 ++-- lib/jasmine-core/version.rb | 2 +- package.json | 2 +- release_notes/2.9.1.md | 15 +++++++++++++++ 4 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 release_notes/2.9.1.md diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index dbb71e2d..23d1441d 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -2193,6 +2193,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) { } do { + deletedKeys = []; var newCurrentTime = scheduledLookup.shift(); tickDate(newCurrentTime - currentTime); @@ -2215,7 +2216,6 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) { } funcToRun.funcToCall.apply(null, funcToRun.params || []); }); - deletedKeys = []; } while (scheduledLookup.length > 0 && // checking first if we're out of time prevents setTimeout(0) // scheduled in a funcToRun from forcing an extra iteration @@ -5538,5 +5538,5 @@ getJasmineRequireObj().UserContext = function(j$) { }; getJasmineRequireObj().version = function() { - return '2.9.0'; + return '2.9.1'; }; diff --git a/lib/jasmine-core/version.rb b/lib/jasmine-core/version.rb index 964fb68c..26125ac0 100644 --- a/lib/jasmine-core/version.rb +++ b/lib/jasmine-core/version.rb @@ -4,6 +4,6 @@ # module Jasmine module Core - VERSION = "2.9.0" + VERSION = "2.9.1" end end diff --git a/package.json b/package.json index d6505c54..d1fb37f3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jasmine-core", "license": "MIT", - "version": "2.9.0", + "version": "2.9.1", "repository": { "type": "git", "url": "https://github.com/jasmine/jasmine.git" diff --git a/release_notes/2.9.1.md b/release_notes/2.9.1.md new file mode 100644 index 00000000..e6b56a8b --- /dev/null +++ b/release_notes/2.9.1.md @@ -0,0 +1,15 @@ +# Jasmine Core 2.9.1 Release Notes + +## Summary + +This is a hotfix release to fix a breaking change from the 2.9.0 release + +## Changes + +* Clear timeouts when starting to process a milli instead of at the end + - Fixes #1482 + + +------ + +_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_