1namespace ts { 2 describe("unittests:: compilerCore", () => { 3 describe("equalOwnProperties", () => { 4 it("correctly equates objects", () => { 5 assert.isTrue(equalOwnProperties({}, {})); 6 assert.isTrue(equalOwnProperties({ a: 1 }, { a: 1 })); 7 assert.isTrue(equalOwnProperties({ a: 1, b: 2 }, { b: 2, a: 1 })); 8 }); 9 it("correctly identifies unmatched objects", () => { 10 assert.isFalse(equalOwnProperties({}, { a: 1 }), "missing left property"); 11 assert.isFalse(equalOwnProperties({ a: 1 }, {}), "missing right property"); 12 assert.isFalse(equalOwnProperties({ a: 1 }, { a: 2 }), "differing property"); 13 }); 14 it("correctly identifies undefined vs hasOwnProperty", () => { 15 assert.isFalse(equalOwnProperties({}, { a: undefined }), "missing left property"); 16 assert.isFalse(equalOwnProperties({ a: undefined }, {}), "missing right property"); 17 }); 18 it("truthiness", () => { 19 const trythyTest = (l: any, r: any) => !!l === !!r; 20 assert.isFalse(equalOwnProperties({}, { a: 1 }, trythyTest), "missing left truthy property"); 21 assert.isFalse(equalOwnProperties({}, { a: 0 }, trythyTest), "missing left falsey property"); 22 assert.isFalse(equalOwnProperties({ a: 1 }, {}, trythyTest), "missing right truthy property"); 23 assert.isFalse(equalOwnProperties({ a: 0 }, {}, trythyTest), "missing right falsey property"); 24 assert.isTrue(equalOwnProperties({ a: 1 }, { a: "foo" }, trythyTest), "valid equality"); 25 }); 26 it("all equal", () => { 27 assert.isFalse(equalOwnProperties({}, { a: 1 }, () => true), "missing left property"); 28 assert.isFalse(equalOwnProperties({ a: 1 }, {}, () => true), "missing right property"); 29 assert.isTrue(equalOwnProperties({ a: 1 }, { a: 2 }, () => true), "valid equality"); 30 }); 31 }); 32 describe("customSet", () => { 33 it("mutation", () => { 34 const set = createSet<number, number>(x => x % 2, (x, y) => (x % 4) === (y % 4)); 35 assert.equal(set.size, 0); 36 37 const newSet = set.add(0); 38 assert.strictEqual(newSet, set); 39 assert.equal(set.size, 1); 40 41 set.add(1); 42 assert.equal(set.size, 2); 43 44 set.add(2); // Collision with 0 45 assert.equal(set.size, 3); 46 47 set.add(3); // Collision with 1 48 assert.equal(set.size, 4); 49 50 set.add(4); // Already present as 0 51 assert.equal(set.size, 4); 52 53 set.add(5); // Already present as 1 54 assert.equal(set.size, 4); 55 56 assert.isTrue(set.has(6)); 57 assert.isTrue(set.has(7)); 58 59 assert.isTrue(set.delete(8)); 60 assert.equal(set.size, 3); 61 assert.isFalse(set.has(8)); 62 assert.isFalse(set.delete(8)); 63 64 assert.isTrue(set.delete(9)); 65 assert.equal(set.size, 2); 66 67 assert.isTrue(set.delete(10)); 68 assert.equal(set.size, 1); 69 70 assert.isTrue(set.delete(11)); 71 assert.equal(set.size, 0); 72 }); 73 it("resizing", () => { 74 const set = createSet<number, number>(x => x % 2, (x, y) => x === y); 75 const elementCount = 100; 76 77 for (let i = 0; i < elementCount; i++) { 78 assert.isFalse(set.has(i)); 79 set.add(i); 80 assert.isTrue(set.has(i)); 81 assert.equal(set.size, i + 1); 82 } 83 84 for (let i = 0; i < elementCount; i++) { 85 assert.isTrue(set.has(i)); 86 set.delete(i); 87 assert.isFalse(set.has(i)); 88 assert.equal(set.size, elementCount - (i + 1)); 89 } 90 }); 91 it("clear", () => { 92 const set = createSet<number, number>(x => x % 2, (x, y) => (x % 4) === (y % 4)); 93 for (let j = 0; j < 2; j++) { 94 for (let i = 0; i < 100; i++) { 95 set.add(i); 96 } 97 assert.equal(set.size, 4); 98 99 set.clear(); 100 assert.equal(set.size, 0); 101 assert.isFalse(set.has(0)); 102 } 103 }); 104 it("forEach", () => { 105 const set = createSet<number, number>(x => x % 2, (x, y) => (x % 4) === (y % 4)); 106 for (let i = 0; i < 100; i++) { 107 set.add(i); 108 } 109 110 const values: number[] = []; 111 const keys: number[] = []; 112 set.forEach((value, key) => { 113 values.push(value); 114 keys.push(key); 115 }); 116 117 assert.equal(values.length, 4); 118 119 values.sort(); 120 keys.sort(); 121 122 // NB: first equal value wins (i.e. not [96, 97, 98, 99]) 123 const expected = [0, 1, 2, 3]; 124 assert.deepEqual(values, expected); 125 assert.deepEqual(keys, expected); 126 }); 127 it("iteration", () => { 128 const set = createSet<number, number>(x => x % 2, (x, y) => (x % 4) === (y % 4)); 129 for (let i = 0; i < 4; i++) { 130 set.add(i); 131 } 132 133 const expected = [0, 1, 2, 3]; 134 let actual: number[]; 135 136 actual = arrayFrom(set.keys()); 137 actual.sort(); 138 assert.deepEqual(actual, expected); 139 140 actual = arrayFrom(set.values()); 141 actual.sort(); 142 assert.deepEqual(actual, expected); 143 144 const actualTuple = arrayFrom(set.entries()); 145 assert.isFalse(actualTuple.some(([v, k]) => v !== k)); 146 actual = actualTuple.map(([v, _]) => v); 147 actual.sort(); 148 assert.deepEqual(actual, expected); 149 }); 150 it("string hash code", () => { 151 interface Thing { 152 x: number; 153 y: string; 154 } 155 156 const set = createSet<Thing, string>(t => t.y, (t, u) => t.x === u.x && t.y === u.y); 157 158 const thing1: Thing = { 159 x: 1, 160 y: "a", 161 }; 162 163 const thing2: Thing = { 164 x: 2, 165 y: "b", 166 }; 167 168 const thing3: Thing = { 169 x: 3, 170 y: "a", // Collides with thing1 171 }; 172 173 set.add(thing1); 174 set.add(thing2); 175 set.add(thing3); 176 177 assert.equal(set.size, 3); 178 179 assert.isTrue(set.has(thing1)); 180 assert.isTrue(set.has(thing2)); 181 assert.isTrue(set.has(thing3)); 182 183 assert.isFalse(set.has({ 184 x: 4, 185 y: "a", // Collides with thing1 186 })); 187 188 assert.isFalse(set.has({ 189 x: 5, 190 y: "c", // No collision 191 })); 192 }); 193 }); 194 }); 195} 196