From b502ae98e110303457fc87b79dec8f7b8920fa15 Mon Sep 17 00:00:00 2001 From: kpreisser Date: Fri, 4 Jan 2019 18:02:43 +0100 Subject: [PATCH] Add a unit test for the shimMap (currently failing). This will test that iteration is in insertion order, new entries added during iteration will be visited by the iterator, and values can be deleted while an iterator is running. --- src/testRunner/tsconfig.json | 1 + src/testRunner/unittests/shimMap.ts | 103 ++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 src/testRunner/unittests/shimMap.ts diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index 849906e24c..7e75c0105a 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -58,6 +58,7 @@ "unittests/publicApi.ts", "unittests/reuseProgramStructure.ts", "unittests/semver.ts", + "unittests/shimMap.ts", "unittests/transform.ts", "unittests/tsbuild.ts", "unittests/tsbuildWatchMode.ts", diff --git a/src/testRunner/unittests/shimMap.ts b/src/testRunner/unittests/shimMap.ts new file mode 100644 index 0000000000..e169f1963c --- /dev/null +++ b/src/testRunner/unittests/shimMap.ts @@ -0,0 +1,103 @@ +namespace ts { + describe("unittests:: shimMap", () => { + + function testMapIterationAddedValues(map: Map, useForEach: boolean): string { + let resultString = ""; + + map.set("1", "1"); + map.set("3", "3"); + map.set("2", "2"); + map.set("4", "4"); + + let addedThree = false; + const doForEach = (value: string, key: string) => { + resultString += `${key}:${value};`; + + // Add a new key ("0") - the map should provide this + // one in the next iteration. + if (key === "1") { + map.set("1", "X1"); + map.set("0", "X0"); + map.set("4", "X4"); + } + else if (key === "3") { + if (!addedThree) { + addedThree = true; + + // Remove and re-add key "3"; the map should + // visit it after "0". + map.delete("3"); + map.set("3", "Y3"); + + // Change the value of "2"; the map should provide + // it when visiting the key. + map.set("2", "Y2"); + } + else { + // Check that an entry added when we visit the + // currently last entry will still be visited. + map.set("999", "999"); + } + } + else if (key === "999") { + // Ensure that clear() behaves correctly same as removing all keys. + map.set("A", "A"); + map.set("B", "B"); + map.set("C", "C"); + } + else if (key === "A") { + map.clear(); + map.set("Z", "Z"); + } + else if (key === "Z") { + // Check that the map behaves correctly when an item is + // added and removed immediately. + map.set("X", "X"); + map.delete("X"); + map.set("Y", "Y"); + } + }; + + if (useForEach) { + map.forEach(doForEach); + } + else { + // Use an iterator. + const iterator = map.entries(); + while (true) { + const { value: tuple, done } = iterator.next(); + if (done) { + break; + } + + doForEach(tuple[1], tuple[0]); + } + } + + return resultString; + } + + it("iterates values in insertion order and handles changes", () => { + const expectedResult = "1:1;3:3;2:Y2;4:X4;0:X0;3:Y3;999:999;A:A;Z:Z;Y:Y;"; + + // First, ensure the test actually has the same behavior as a native Map. + let nativeMap = createMap(); + const nativeMapForEachResult = testMapIterationAddedValues(nativeMap, /* useForEach */ true); + assert.equal(nativeMapForEachResult, expectedResult, "nativeMap-forEach"); + + nativeMap = createMap(); + const nativeMapIteratorResult = testMapIterationAddedValues(nativeMap, /* useForEach */ false); + assert.equal(nativeMapIteratorResult, expectedResult, "nativeMap-iterator"); + + // Then, test the shimMap. + let localShimMap = new (shimMap())(); + const shimMapForEachResult = testMapIterationAddedValues(localShimMap, /* useForEach */ true); + assert.equal(shimMapForEachResult, expectedResult, "shimMap-forEach"); + + localShimMap = new (shimMap())(); + const shimMapIteratorResult = testMapIterationAddedValues(localShimMap, /* useForEach */ false); + assert.equal(shimMapIteratorResult, expectedResult, "shimMap-iterator"); + + }); + }); +}