1
+import DisjointSet from "../Utils/DisjointSet";
2
+
3
+type TestIdentifier = {
4
+ id: number;
5
+ name: string;
6
+};
7
+
8
+describe("DisjointSet", () => {
9
+ let identifierId = 0;
10
+ function makeIdentifier(name: string): TestIdentifier {
11
+ return {
12
+ id: identifierId++,
13
+ name,
14
+ };
15
+ }
16
+
17
+ function makeIdentifiers(...names: string[]): TestIdentifier[] {
18
+ return names.map((name) => makeIdentifier(name));
19
+ }
20
+
21
+ beforeEach(() => {
22
+ identifierId = 0;
23
+ });
24
+
25
+ it(".find - finds the correct group which the item is associated with", () => {
26
+ const identifiers = new DisjointSet<TestIdentifier>();
27
+ const [x, y, z] = makeIdentifiers("x", "y", "z");
28
+
29
+ identifiers.union([x]);
30
+ identifiers.union([y, x]);
31
+
32
+ expect(identifiers.find(x)).toBe(y);
33
+ expect(identifiers.find(y)).toBe(y);
34
+ expect(identifiers.find(z)).toBe(null);
35
+ });
36
+
37
+ it(".size - returns 0 when empty", () => {
38
+ const identifiers = new DisjointSet<TestIdentifier>();
39
+
40
+ expect(identifiers.size).toBe(0);
41
+ });
42
+
43
+ it(".size - returns the correct size when non-empty", () => {
44
+ const identifiers = new DisjointSet<TestIdentifier>();
45
+ const [x, y] = makeIdentifiers("x", "y", "z");
46
+
47
+ identifiers.union([x]);
48
+ identifiers.union([y, x]);
49
+
50
+ expect(identifiers.size).toBe(2);
51
+ });
52
+
53
+ it(".buildSets - returns non-overlapping sets", () => {
54
+ const identifiers = new DisjointSet<TestIdentifier>();
55
+ const [a, b, c, x, y, z] = makeIdentifiers("a", "b", "c", "x", "y", "z");
56
+
57
+ identifiers.union([a]);
58
+ identifiers.union([b, a]);
59
+ identifiers.union([c, b]);
60
+
61
+ identifiers.union([x]);
62
+ identifiers.union([y, x]);
63
+ identifiers.union([z, y]);
64
+ identifiers.union([x, z]);
65
+
66
+ expect(identifiers.buildSets()).toMatchInlineSnapshot(`
67
+ [
68
+ Set {
69
+ {
70
+ "id": 0,
71
+ "name": "a",
72
+ },
73
+ {
74
+ "id": 1,
75
+ "name": "b",
76
+ },
77
+ {
78
+ "id": 2,
79
+ "name": "c",
80
+ },
81
+ },
82
+ Set {
83
+ {
84
+ "id": 3,
85
+ "name": "x",
86
+ },
87
+ {
88
+ "id": 4,
89
+ "name": "y",
90
+ },
91
+ {
92
+ "id": 5,
93
+ "name": "z",
94
+ },
95
+ },
96
+ ]
97
+ `);
98
+ });
99
+
100
+ // Regression test for issue #933
101
+ it("`forEach` doesn't infinite loop when there are cycles", () => {
102
+ const identifiers = new DisjointSet<TestIdentifier>();
103
+ const [x, y, z] = makeIdentifiers("x", "y", "z");
104
+
105
+ identifiers.union([x]);
106
+ identifiers.union([y, x]);
107
+ identifiers.union([z, y]);
108
+ identifiers.union([x, z]);
109
+
110
+ identifiers.forEach((_, group) => expect(group).toBe(z));
111
+ });
112
+});