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