|
1 | | -import { describe, it, expect } from "vitest"; |
| 1 | +import { describe, test, expect } from "vitest"; |
2 | 2 |
|
3 | 3 | import { BiMap } from "./BiMap.ts"; |
4 | 4 |
|
5 | 5 | describe("BiMap", () => { |
6 | 6 | describe("constructor", () => { |
7 | | - it("creates an empty BiMap when no entries are provided", () => { |
| 7 | + test("creates an empty BiMap when no entries are provided", () => { |
8 | 8 | const map = new BiMap<string, number>(); |
9 | 9 |
|
10 | 10 | expect(map.size).toBe(0); |
11 | 11 | expect(map.inverse.size).toBe(0); |
12 | 12 | }); |
13 | 13 |
|
14 | | - it("initializes with entries", () => { |
15 | | - const map = new BiMap<string, number>([ |
| 14 | + test("initializes with array entries", () => { |
| 15 | + const biMap = new BiMap([ |
16 | 16 | ["a", 1], |
17 | 17 | ["b", 2], |
18 | 18 | ]); |
19 | 19 |
|
20 | | - expect(map.size).toBe(2); |
21 | | - expect(map.get("a")).toBe(1); |
22 | | - expect(map.get("b")).toBe(2); |
23 | | - expect(map.inverse).not.toBe(undefined); |
| 20 | + expect(biMap).toHaveProperty("size", 2); |
| 21 | + expect(biMap.get("a")).toBe(1); |
| 22 | + expect(biMap.get("b")).toBe(2); |
24 | 23 |
|
25 | | - expect(map.getKey(1)).toBe("a"); |
26 | | - expect(map.getKey(2)).toBe("b"); |
| 24 | + expect(biMap.getKey(1)).toBe("a"); |
| 25 | + expect(biMap.getKey(2)).toBe("b"); |
27 | 26 | }); |
28 | 27 |
|
29 | | - it("handles null or undefined entries", () => { |
30 | | - const map1 = new BiMap<string, number>(null); |
31 | | - const map2 = new BiMap<string, number>(undefined); |
| 28 | + test("initializes with iterable", () => { |
| 29 | + const biMap = new BiMap( |
| 30 | + (function* () { |
| 31 | + yield ["a", 1]; |
| 32 | + yield ["b", 2]; |
| 33 | + })(), |
| 34 | + ); |
| 35 | + expect(biMap).toHaveProperty("size", 2); |
| 36 | + expect(biMap.get("a")).toBe(1); |
| 37 | + expect(biMap.get("b")).toBe(2); |
32 | 38 |
|
33 | | - expect(map1.size).toBe(0); |
34 | | - expect(map2.size).toBe(0); |
| 39 | + expect(biMap.getKey(1)).toBe("a"); |
| 40 | + expect(biMap.getKey(2)).toBe("b"); |
| 41 | + }); |
| 42 | + |
| 43 | + test("handles null or undefined entries", () => { |
| 44 | + const biMap1 = new BiMap<string, number>(null); |
| 45 | + const biMap2 = new BiMap<string, number>(undefined); |
| 46 | + |
| 47 | + expect(biMap1).toHaveProperty("size", 0); |
| 48 | + expect(biMap2).toHaveProperty("size", 0); |
| 49 | + }); |
| 50 | + |
| 51 | + test("throws on non-iterable entries", () => { |
| 52 | + // @ts-expect-error -- testing non-iterable entries |
| 53 | + expect(() => new BiMap({})).toThrow(TypeError); |
35 | 54 | }); |
36 | 55 | }); |
37 | 56 |
|
38 | 57 | describe("set", () => { |
39 | | - it("sets key → value and value → key", () => { |
40 | | - const map = new BiMap<string, number>(); |
| 58 | + test("sets key → value and value → key", () => { |
| 59 | + const biMap = new BiMap<string, number>(); |
41 | 60 |
|
42 | | - map.set("a", 1); |
| 61 | + biMap.set("a", 1); |
43 | 62 |
|
44 | | - expect(map.get("a")).toBe(1); |
45 | | - expect(map.getKey(1)).toBe("a"); |
| 63 | + expect(biMap.get("a")).toBe(1); |
| 64 | + expect(biMap.getKey(1)).toBe("a"); |
46 | 65 | }); |
47 | 66 |
|
48 | | - it("overwrites existing key", () => { |
49 | | - const map = new BiMap<string, number>(); |
| 67 | + test("overwrites existing key", () => { |
| 68 | + const biMap = new BiMap<string, number>(); |
50 | 69 |
|
51 | | - map.set("a", 1); |
52 | | - map.set("a", 2); |
| 70 | + biMap.set("a", 1); |
| 71 | + biMap.set("a", 2); |
53 | 72 |
|
54 | | - expect(map.get("a")).toBe(2); |
55 | | - expect(map.getKey(1)).toBeUndefined(); |
56 | | - expect(map.getKey(2)).toBe("a"); |
| 73 | + expect(biMap.get("a")).toBe(2); |
| 74 | + expect(biMap.getKey(1)).toBeUndefined(); |
| 75 | + expect(biMap.getKey(2)).toBe("a"); |
57 | 76 | }); |
58 | 77 |
|
59 | | - it("removes previous key when value is reused", () => { |
60 | | - const map = new BiMap<string, number>(); |
| 78 | + test("removes previous key when value is reused", () => { |
| 79 | + const biMap = new BiMap<string, number>(); |
61 | 80 |
|
62 | | - map.set("a", 1); |
63 | | - map.set("b", 1); |
| 81 | + biMap.set("a", 1); |
| 82 | + biMap.set("b", 1); |
64 | 83 |
|
65 | | - expect(map.get("a")).toBeUndefined(); |
66 | | - expect(map.get("b")).toBe(1); |
67 | | - expect(map.getKey(1)).toBe("b"); |
| 84 | + expect(biMap.get("a")).toBeUndefined(); |
| 85 | + expect(biMap.get("b")).toBe(1); |
| 86 | + expect(biMap.getKey(1)).toBe("b"); |
68 | 87 | }); |
69 | 88 | }); |
70 | 89 |
|
71 | | - describe("get / getKey", () => { |
72 | | - it("retrieves values by key", () => { |
73 | | - const map = new BiMap<string, number>([["a", 1]]); |
74 | | - expect(map.inverse).not.toBe(undefined); |
| 90 | + describe("get, getKey, getValue", () => { |
| 91 | + test("retrieves values by key", () => { |
| 92 | + const biMap = new BiMap<string, number>([["a", 1]]); |
75 | 93 |
|
76 | | - expect(map.getValue("a")).toBe(1); |
| 94 | + expect(biMap.get("a")).toBe(1); |
| 95 | + expect(biMap.getValue("a")).toBe(1); |
77 | 96 | }); |
78 | 97 |
|
79 | | - it("retrieves keys by value", () => { |
80 | | - const map = new BiMap<string, number>([["a", 1]]); |
| 98 | + test("retrieves keys by value", () => { |
| 99 | + const biMap = new BiMap<string, number>([["a", 1]]); |
81 | 100 |
|
82 | | - expect(map.getKey(1)).toBe("a"); |
| 101 | + expect(biMap.getKey(1)).toBe("a"); |
83 | 102 | }); |
84 | 103 |
|
85 | | - it("returns undefined for missing entries", () => { |
86 | | - const map = new BiMap<string, number>(); |
| 104 | + test("returns undefined for missing entries", () => { |
| 105 | + const biMap = new BiMap<string, number>(); |
87 | 106 |
|
88 | | - expect(map.get("missing")).toBeUndefined(); |
89 | | - expect(map.getKey(999)).toBeUndefined(); |
| 107 | + expect(biMap.get("missing")).toBeUndefined(); |
| 108 | + expect(biMap.getValue("missing")).toBeUndefined(); |
| 109 | + expect(biMap.getKey(999)).toBeUndefined(); |
90 | 110 | }); |
91 | 111 | }); |
92 | 112 |
|
93 | | - describe("hasKey / hasValue", () => { |
94 | | - it("checks existence of keys", () => { |
95 | | - const map = new BiMap<string, number>([["a", 1]]); |
| 113 | + describe("has, hasKey, hasValue", () => { |
| 114 | + test("checks existence of keys", () => { |
| 115 | + const biMap = new BiMap<string, number>([["a", 1]]); |
96 | 116 |
|
97 | | - expect(map.hasKey("a")).toBe(true); |
98 | | - expect(map.hasKey("b")).toBe(false); |
| 117 | + expect(biMap.has("a")).toBe(true); |
| 118 | + expect(biMap.has("b")).toBe(false); |
| 119 | + expect(biMap.hasKey("a")).toBe(true); |
| 120 | + expect(biMap.hasKey("b")).toBe(false); |
99 | 121 | }); |
100 | 122 |
|
101 | | - it("checks existence of values", () => { |
102 | | - const map = new BiMap<string, number>([["a", 1]]); |
| 123 | + test("checks existence of values", () => { |
| 124 | + const biMap = new BiMap<string, number>([["a", 1]]); |
103 | 125 |
|
104 | | - expect(map.hasValue(1)).toBe(true); |
105 | | - expect(map.hasValue(2)).toBe(false); |
| 126 | + expect(biMap.hasValue(1)).toBe(true); |
| 127 | + expect(biMap.hasValue(2)).toBe(false); |
106 | 128 | }); |
107 | 129 | }); |
108 | 130 |
|
109 | 131 | describe("delete (by key)", () => { |
110 | | - it("deletes key and corresponding value", () => { |
111 | | - const map = new BiMap<string, number>([["a", 1]]); |
| 132 | + test("deletes key and corresponding value", () => { |
| 133 | + const biMap = new BiMap<string, number>([["a", 1]]); |
112 | 134 |
|
113 | | - const result = map.delete("a"); |
114 | | - |
115 | | - expect(result).toBe(true); |
116 | | - expect(map.get("a")).toBeUndefined(); |
117 | | - expect(map.getKey(1)).toBeUndefined(); |
118 | | - expect(map.size).toBe(0); |
| 135 | + expect(biMap.delete("a")).toBe(true); |
| 136 | + expect(biMap.get("a")).toBeUndefined(); |
| 137 | + expect(biMap.getKey(1)).toBeUndefined(); |
| 138 | + expect(biMap).toHaveProperty("size", 0); |
119 | 139 | }); |
120 | 140 |
|
121 | | - it("returns false if key does not exist", () => { |
122 | | - const map = new BiMap<string, number>(); |
| 141 | + test("returns false if key does not exist", () => { |
| 142 | + const biMap = new BiMap<string, number>(); |
123 | 143 |
|
124 | | - expect(map.delete("missing")).toBe(false); |
| 144 | + expect(biMap.delete("missing")).toBe(false); |
125 | 145 | }); |
126 | 146 | }); |
127 | 147 |
|
128 | 148 | describe("deleteValue", () => { |
129 | | - it("deletes value and corresponding key", () => { |
130 | | - const map = new BiMap<string, number>([["a", 1]]); |
131 | | - |
132 | | - const result = map.deleteValue(1); |
| 149 | + test("deletes value and corresponding key", () => { |
| 150 | + const biMap = new BiMap<string, number>([["a", 1]]); |
133 | 151 |
|
134 | | - expect(result).toBe(true); |
135 | | - expect(map.get("a")).toBeUndefined(); |
136 | | - expect(map.getKey(1)).toBeUndefined(); |
137 | | - expect(map.size).toBe(0); |
| 152 | + expect(biMap.deleteValue(1)).toBe(true); |
| 153 | + expect(biMap.get("a")).toBeUndefined(); |
| 154 | + expect(biMap.getKey(1)).toBeUndefined(); |
| 155 | + expect(biMap).toHaveProperty("size", 0); |
138 | 156 | }); |
139 | 157 |
|
140 | | - it("returns false if value does not exist", () => { |
141 | | - const map = new BiMap<string, number>(); |
| 158 | + test("returns false if value does not exist", () => { |
| 159 | + const biMap = new BiMap<string, number>(); |
142 | 160 |
|
143 | | - expect(map.deleteValue(123)).toBe(false); |
| 161 | + expect(biMap.deleteValue(123)).toBe(false); |
144 | 162 | }); |
145 | 163 | }); |
146 | 164 |
|
147 | 165 | describe("clear", () => { |
148 | | - it("removes all entries", () => { |
149 | | - const map = new BiMap<string, number>([ |
| 166 | + test("removes all entries", () => { |
| 167 | + const biMap = new BiMap<string, number>([ |
150 | 168 | ["a", 1], |
151 | 169 | ["b", 2], |
152 | 170 | ]); |
153 | 171 |
|
154 | | - map.clear(); |
| 172 | + biMap.clear(); |
155 | 173 |
|
156 | | - expect(map.size).toBe(0); |
157 | | - expect(map.get("a")).toBeUndefined(); |
158 | | - expect(map.getKey(1)).toBeUndefined(); |
| 174 | + expect(biMap.size).toBe(0); |
| 175 | + expect(biMap.get("a")).toBeUndefined(); |
| 176 | + expect(biMap.getKey(1)).toBeUndefined(); |
159 | 177 | }); |
160 | 178 | }); |
161 | 179 |
|
162 | 180 | describe("consistency", () => { |
163 | | - it("maintains bidirectional integrity across multiple operations", () => { |
164 | | - const map = new BiMap<string, number>(); |
| 181 | + test("maintains bidirectional integrity across multiple operations", () => { |
| 182 | + const biMap = new BiMap<string, number>(); |
165 | 183 |
|
166 | | - map.set("a", 1); |
167 | | - map.set("b", 2); |
168 | | - map.set("c", 3); |
| 184 | + biMap.set("a", 1); |
| 185 | + biMap.set("b", 2); |
| 186 | + biMap.set("c", 3); |
169 | 187 |
|
170 | | - map.delete("b"); |
171 | | - map.set("d", 1); // should evict "a" |
| 188 | + biMap.delete("b"); |
| 189 | + biMap.set("d", 1); // should evict "a" |
172 | 190 |
|
173 | | - expect(map.get("a")).toBeUndefined(); |
174 | | - expect(map.getKey(1)).toBe("d"); |
| 191 | + expect(biMap.get("a")).toBeUndefined(); |
| 192 | + expect(biMap.getKey(1)).toBe("d"); |
175 | 193 |
|
176 | | - expect(map.get("c")).toBe(3); |
177 | | - expect(map.getKey(3)).toBe("c"); |
| 194 | + expect(biMap.get("c")).toBe(3); |
| 195 | + expect(biMap.getKey(3)).toBe("c"); |
178 | 196 |
|
179 | | - expect(map.hasKey("b")).toBe(false); |
180 | | - expect(map.hasValue(2)).toBe(false); |
| 197 | + expect(biMap.hasKey("b")).toBe(false); |
| 198 | + expect(biMap.hasValue(2)).toBe(false); |
181 | 199 | }); |
182 | 200 | }); |
183 | 201 | }); |
0 commit comments