@calcit/ternary-tree 0.0.23 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/test-map.mjs CHANGED
@@ -1,215 +1,208 @@
1
1
  import { hashGenerator } from "./types.mjs";
2
2
  import { cmp, deepEqual } from "./utils.mjs";
3
- import { test, check, justDisplay } from "./test-utils.mjs";
3
+ import { describe, test, check, justDisplay } from "./test-utils.mjs";
4
4
  import { initTernaryTreeMap, initTernaryTreeMapFromArray, toHashSortedPairs, merge, mergeSkip, formatMapInline, assocMap, dissocMap, contains, toPairs, initEmptyTernaryTreeMap, sameMapShape, checkMapStructure, mapLen, mapEqual, toKeys, toPairsArray, mapMapValues, mapGetDefault, } from "./map.mjs";
5
5
  export let runMapTests = () => {
6
- test("init map", () => {
7
- var dict = new Map();
8
- var inList = [];
9
- for (let idx = 0; idx < 10; idx++) {
10
- dict.set(`${idx}`, idx + 10);
11
- inList.push([`${idx}`, idx + 10]);
12
- }
13
- // TODO
14
- inList.sort((x, y) => {
15
- let hx = hashGenerator(x[0]);
16
- let hy = hashGenerator(y[0]);
17
- return cmp(hx, hy);
6
+ describe("TernaryTreeMap Tests", () => {
7
+ test("should initialize map correctly", () => {
8
+ var dict = new Map();
9
+ var inList = [];
10
+ for (let idx = 0; idx < 10; idx++) {
11
+ dict.set(`${idx}`, idx + 10);
12
+ inList.push([`${idx}`, idx + 10]);
13
+ }
14
+ inList.sort((x, y) => {
15
+ let hx = hashGenerator(x[0]);
16
+ let hy = hashGenerator(y[0]);
17
+ return cmp(hx, hy);
18
+ });
19
+ let data10 = initTernaryTreeMap(dict);
20
+ let data11 = initTernaryTreeMapFromArray(inList);
21
+ check(checkMapStructure(data10));
22
+ check(checkMapStructure(data11));
23
+ justDisplay(formatMapInline(data10, true), " ((0:10 1:11 2:12) (3:13 (4:14 5:15 _) 6:16) (7:17 8:18 9:19))");
24
+ check(deepEqual(toHashSortedPairs(data10), inList));
25
+ check(deepEqual(toHashSortedPairs(data11), inList));
26
+ check(contains(data10, "1") === true);
27
+ check(contains(data10, "11") === false);
28
+ check(deepEqual(mapGetDefault(data10, "1", null), 11));
29
+ check(deepEqual(mapGetDefault(data10, "111", 0), 0));
30
+ let emptyData = new Map();
31
+ check(mapEqual(initEmptyTernaryTreeMap(), initTernaryTreeMap(emptyData)));
32
+ });
33
+ test("should handle assoc and contains correctly", () => {
34
+ var dict = new Map();
35
+ for (let idx = 0; idx < 100; idx++) {
36
+ dict.set(`${idx * 2}`, idx);
37
+ }
38
+ let data = initTernaryTreeMap(dict);
39
+ for (let idx = 0; idx < 100; idx++) {
40
+ dict.set(`${idx * 2 + 1}`, idx);
41
+ let data2 = assocMap(data, `${idx * 2 + 1}`, idx);
42
+ check(contains(data2, `${idx * 2 + 1}`));
43
+ }
44
+ var dict2 = new Map();
45
+ data = initTernaryTreeMap(dict2);
46
+ for (let idx = 0; idx < 1000; idx++) {
47
+ let p = 100 - idx / 10;
48
+ data = assocMap(data, `${p}`, idx);
49
+ check(contains(data, `${p}`));
50
+ }
51
+ });
52
+ test("should maintain structure integrity", () => {
53
+ var dict = new Map();
54
+ for (let idx = 0; idx < 100; idx++) {
55
+ dict.set(`${idx}`, idx + 10);
56
+ }
57
+ let data = initTernaryTreeMap(dict);
58
+ check(checkMapStructure(data));
59
+ });
60
+ test("should handle map association correctly", () => {
61
+ var dict = new Map();
62
+ for (let idx = 0; idx < 10; idx++) {
63
+ dict.set(`${idx}`, idx + 10);
64
+ }
65
+ let data = initTernaryTreeMap(dict);
66
+ check(contains(data, "1") === true);
67
+ check(contains(data, "12") === false);
68
+ check(checkMapStructure(data));
69
+ justDisplay(formatMapInline(assocMap(data, "1", 2222), true), "((0:10 1:2222 2:12) (3:13 (4:14 5:15 _) 6:16) (7:17 8:18 9:19))");
70
+ justDisplay(formatMapInline(assocMap(data, "23", 2222), true), "(((0:10 1:11 2:12) (3:13 (4:14 5:15 _) 6:16) (7:17 8:18 9:19)) 23:2222 _)");
71
+ });
72
+ test("should handle dissociation correctly", () => {
73
+ var dict = new Map();
74
+ for (let idx = 0; idx < 10; idx++) {
75
+ dict.set(`${idx}`, idx + 10);
76
+ }
77
+ let data = initTernaryTreeMap(dict);
78
+ check(checkMapStructure(data));
79
+ for (let idx = 0; idx < 10; idx++) {
80
+ let v = dissocMap(data, `${idx}`);
81
+ check(contains(v, `${idx}`) === false);
82
+ check(contains(data, `${idx}`) === true);
83
+ check(mapLen(v) === mapLen(data) - 1);
84
+ }
85
+ for (let idx = 10; idx < 12; idx++) {
86
+ let v = dissocMap(data, `${idx}`);
87
+ check(contains(v, `${idx}`) === false);
88
+ check(mapLen(v) === mapLen(data));
89
+ }
90
+ });
91
+ test("should convert to array correctly", () => {
92
+ var dict = new Map();
93
+ for (let idx = 0; idx < 10; idx++) {
94
+ dict.set(`${idx}`, idx + 10);
95
+ }
96
+ let data = initTernaryTreeMap(dict);
97
+ check(checkMapStructure(data));
98
+ justDisplay([...toKeys(data)], ["2", "3", "7", "9", "6", "5", "1", "8", "0", "4"]);
99
+ check(deepEqual(toPairsArray(data), [...toPairs(data)]));
100
+ });
101
+ test("should check equality correctly", () => {
102
+ var dict = new Map();
103
+ for (let idx = 0; idx < 10; idx++) {
104
+ dict.set(`${idx}`, idx + 10);
105
+ }
106
+ let data = initTernaryTreeMap(dict);
107
+ let b = dissocMap(data, "3");
108
+ check(checkMapStructure(data));
109
+ check(checkMapStructure(b));
110
+ check(mapEqual(data, data));
111
+ check(!mapEqual(data, b));
112
+ let c = assocMap(data, "3", 15);
113
+ check(sameMapShape(data, data));
114
+ check(sameMapShape(data, b) === false);
115
+ check(sameMapShape(data, c) === false);
116
+ let d = assocMap(c, "3", 13);
117
+ check(mapEqual(data, d));
118
+ check(data !== d); // not identical
119
+ });
120
+ test("should merge maps correctly", () => {
121
+ var dict = new Map();
122
+ var dictBoth = new Map();
123
+ for (let idx = 0; idx < 4; idx++) {
124
+ dict.set(`${idx}`, idx + 10);
125
+ dictBoth.set(`${idx}`, idx + 10);
126
+ }
127
+ let data = initTernaryTreeMap(dict);
128
+ check(checkMapStructure(data));
129
+ var dictB = new Map();
130
+ for (let idx = 10; idx < 14; idx++) {
131
+ dictB.set(`${idx}`, idx + 23);
132
+ dictBoth.set(`${idx}`, idx + 23);
133
+ }
134
+ let b = initTernaryTreeMap(dictB);
135
+ let merged = merge(data, b);
136
+ let both = initTernaryTreeMap(dictBoth);
137
+ check(mapEqual(merged, both));
138
+ });
139
+ test("should merge with skip correctly", () => {
140
+ var dict = new Map();
141
+ for (let idx = 0; idx < 4; idx++) {
142
+ dict.set(`${idx}`, idx + 10);
143
+ }
144
+ let a = initTernaryTreeMap(dict);
145
+ check(checkMapStructure(a));
146
+ var dict2 = new Map();
147
+ for (let idx = 0; idx < 4; idx++) {
148
+ dict2.set(`${idx}`, idx + 11);
149
+ }
150
+ let b = initTernaryTreeMap(dict2);
151
+ check(checkMapStructure(b));
152
+ let c = mergeSkip(a, b, 11);
153
+ check(deepEqual(mapGetDefault(c, "0", null), 10));
154
+ check(deepEqual(mapGetDefault(c, "1", null), 12));
155
+ check(deepEqual(mapGetDefault(c, "2", null), 13));
156
+ check(deepEqual(mapGetDefault(c, "3", null), 14));
157
+ });
158
+ test("should handle iteration correctly", () => {
159
+ var dict = new Map();
160
+ var dictBoth = new Map();
161
+ for (let idx = 0; idx < 4; idx++) {
162
+ dict.set(`${idx}`, idx + 10);
163
+ dictBoth.set(`${idx}`, idx + 10);
164
+ }
165
+ let data = initTernaryTreeMap(dict);
166
+ check(checkMapStructure(data));
167
+ var count = 0;
168
+ for (let [k, v] of toPairs(data)) {
169
+ count = count + 1;
170
+ }
171
+ check(count === 4);
172
+ count = 0;
173
+ for (let key of toPairs(data)) {
174
+ count = count + 1;
175
+ }
176
+ check(count === 4);
177
+ });
178
+ test("should iterate through large maps", () => {
179
+ var dict = new Map();
180
+ for (let idx = 0; idx < 100; idx++) {
181
+ dict.set(`${idx}`, idx + 10);
182
+ }
183
+ let data = initTernaryTreeMap(dict);
184
+ check(checkMapStructure(data));
185
+ var count = 0;
186
+ for (let [k, v] of toPairs(data)) {
187
+ count = count + 1;
188
+ }
189
+ check(count === 100);
190
+ });
191
+ test("should map values correctly", () => {
192
+ var dict = new Map();
193
+ for (let idx = 0; idx < 4; idx++) {
194
+ dict.set(`${idx}`, idx + 10);
195
+ }
196
+ let data = initTernaryTreeMap(dict);
197
+ var dict2 = new Map();
198
+ for (let idx = 0; idx < 4; idx++) {
199
+ dict2.set(`${idx}`, idx + 20);
200
+ }
201
+ let data2 = initTernaryTreeMap(dict2);
202
+ let data3 = mapMapValues(data, (x) => x + 10);
203
+ check(checkMapStructure(data3));
204
+ check(mapEqual(data2, data3));
205
+ check(formatMapInline(data2) === formatMapInline(data3));
18
206
  });
19
- let data10 = initTernaryTreeMap(dict);
20
- let data11 = initTernaryTreeMapFromArray(inList);
21
- checkMapStructure(data10);
22
- checkMapStructure(data11);
23
- // echo data10
24
- justDisplay(formatMapInline(data10, true), " ((0:10 1:11 2:12) (3:13 (4:14 5:15 _) 6:16) (7:17 8:18 9:19))");
25
- check(deepEqual(toHashSortedPairs(data10), inList));
26
- check(deepEqual(toHashSortedPairs(data11), inList));
27
- check(contains(data10, "1") === true);
28
- check(contains(data10, "11") === false);
29
- check(deepEqual(mapGetDefault(data10, "1", null), 11));
30
- check(deepEqual(mapGetDefault(data10, "111", 0), 0));
31
- // check(deepEqual(mapGetDefault(data10, "11", {} as any), null)); // should throws error
32
- let emptyData = new Map();
33
- check(mapEqual(initEmptyTernaryTreeMap(), initTernaryTreeMap(emptyData)));
34
- });
35
- test("assoc and contains", () => {
36
- var dict = new Map();
37
- for (let idx = 0; idx < 100; idx++) {
38
- dict.set(`${idx * 2}`, idx);
39
- }
40
- let data = initTernaryTreeMap(dict);
41
- for (let idx = 0; idx < 100; idx++) {
42
- dict.set(`${idx * 2 + 1}`, idx);
43
- let data2 = assocMap(data, `${idx * 2 + 1}`, idx);
44
- check(contains(data2, `${idx * 2 + 1}`));
45
- }
46
- var dict = new Map();
47
- data = initTernaryTreeMap(dict);
48
- for (let idx = 0; idx < 1000; idx++) {
49
- let p = 100 - idx / 10;
50
- data = assocMap(data, `${p}`, idx);
51
- check(contains(data, `${p}`));
52
- }
53
- });
54
- test("check structure", () => {
55
- var dict = new Map();
56
- for (let idx = 0; idx < 100; idx++) {
57
- dict.set(`${idx}`, idx + 10);
58
- }
59
- let data = initTernaryTreeMap(dict);
60
- check(checkMapStructure(data));
61
- });
62
- test("assoc map", () => {
63
- var dict = new Map();
64
- for (let idx = 0; idx < 10; idx++) {
65
- dict.set(`${idx}`, idx + 10);
66
- }
67
- let data = initTernaryTreeMap(dict);
68
- // echo data.formatInline
69
- check(contains(data, "1") === true);
70
- check(contains(data, "12") === false);
71
- checkMapStructure(data);
72
- justDisplay(formatMapInline(assocMap(data, "1", 2222), true), "((0:10 1:2222 2:12) (3:13 (4:14 5:15 _) 6:16) (7:17 8:18 9:19))");
73
- justDisplay(formatMapInline(assocMap(data, "23", 2222), true), "(((0:10 1:11 2:12) (3:13 (4:14 5:15 _) 6:16) (7:17 8:18 9:19)) 23:2222 _)");
74
- });
75
- test("dissoc", () => {
76
- var dict = new Map();
77
- for (let idx = 0; idx < 10; idx++) {
78
- dict.set(`${idx}`, idx + 10);
79
- }
80
- let data = initTernaryTreeMap(dict);
81
- checkMapStructure(data);
82
- // echo data.formatInline
83
- for (let idx = 0; idx < 10; idx++) {
84
- let v = dissocMap(data, `${idx}`);
85
- check(contains(v, `${idx}`) === false);
86
- check(contains(data, `${idx}`) === true);
87
- check(mapLen(v) === mapLen(data) - 1);
88
- }
89
- for (let idx = 10; idx < 12; idx++) {
90
- let v = dissocMap(data, `${idx}`);
91
- check(contains(v, `${idx}`) === false);
92
- check(mapLen(v) === mapLen(data));
93
- }
94
- });
95
- test("to array", () => {
96
- var dict = new Map();
97
- for (let idx = 0; idx < 10; idx++) {
98
- dict.set(`${idx}`, idx + 10);
99
- }
100
- let data = initTernaryTreeMap(dict);
101
- checkMapStructure(data);
102
- // TODO
103
- // justDisplay((mapToString(toPairs(data))) , "@[2:12, 3:13, 7:17, 9:19, 6:16, 5:15, 1:11, 8:18, 0:10, 4:14]")
104
- justDisplay([...toKeys(data)], ["2", "3", "7", "9", "6", "5", "1", "8", "0", "4"]);
105
- check(deepEqual(toPairsArray(data), [...toPairs(data)]));
106
- });
107
- test("Equality", () => {
108
- var dict = new Map();
109
- for (let idx = 0; idx < 10; idx++) {
110
- dict.set(`${idx}`, idx + 10);
111
- }
112
- let data = initTernaryTreeMap(dict);
113
- let b = dissocMap(data, "3");
114
- checkMapStructure(data);
115
- checkMapStructure(b);
116
- check(mapEqual(data, data));
117
- check(!mapEqual(data, b));
118
- let c = assocMap(data, "3", 15);
119
- check(sameMapShape(data, data));
120
- check(sameMapShape(data, b) === false);
121
- check(sameMapShape(data, c) === false);
122
- let d = assocMap(c, "3", 13);
123
- check(mapEqual(data, d));
124
- check(data !== d); // not identical
125
- });
126
- test("Merge", () => {
127
- var dict = new Map();
128
- var dictBoth = new Map();
129
- for (let idx = 0; idx < 4; idx++) {
130
- dict.set(`${idx}`, idx + 10);
131
- dictBoth.set(`${idx}`, idx + 10);
132
- }
133
- let data = initTernaryTreeMap(dict);
134
- checkMapStructure(data);
135
- var dictB = new Map();
136
- for (let idx = 10; idx < 14; idx++) {
137
- dictB.set(`${idx}`, idx + 23);
138
- dictBoth.set(`${idx}`, idx + 23);
139
- }
140
- let b = initTernaryTreeMap(dictB);
141
- let merged = merge(data, b);
142
- let both = initTernaryTreeMap(dictBoth);
143
- check(mapEqual(merged, both));
144
- });
145
- test("Merge skip", () => {
146
- var dict = new Map();
147
- for (let idx = 0; idx < 4; idx++) {
148
- dict.set(`${idx}`, idx + 10);
149
- }
150
- let a = initTernaryTreeMap(dict);
151
- checkMapStructure(a);
152
- var dict2 = new Map();
153
- for (let idx = 0; idx < 4; idx++) {
154
- dict2.set(`${idx}`, idx + 11);
155
- }
156
- let b = initTernaryTreeMap(dict2);
157
- checkMapStructure(b);
158
- let c = mergeSkip(a, b, 11);
159
- check(deepEqual(mapGetDefault(c, "0", null), 10));
160
- check(deepEqual(mapGetDefault(c, "1", null), 12));
161
- check(deepEqual(mapGetDefault(c, "2", null), 13));
162
- check(deepEqual(mapGetDefault(c, "3", null), 14));
163
- });
164
- test("iterator", () => {
165
- var dict = new Map();
166
- var dictBoth = new Map();
167
- for (let idx = 0; idx < 4; idx++) {
168
- dict.set(`${idx}`, idx + 10);
169
- dictBoth.set(`${idx}`, idx + 10);
170
- }
171
- let data = initTernaryTreeMap(dict);
172
- checkMapStructure(data);
173
- var i = 0;
174
- for (let [k, v] of toPairs(data)) {
175
- i = i + 1;
176
- }
177
- check(i === 4);
178
- i = 0;
179
- for (let key of toPairs(data)) {
180
- i = i + 1;
181
- }
182
- check(i === 4);
183
- });
184
- test("each map", () => {
185
- var dict = new Map();
186
- for (let idx = 0; idx < 100; idx++) {
187
- dict.set(`${idx}`, idx + 10);
188
- }
189
- let data = initTernaryTreeMap(dict);
190
- checkMapStructure(data);
191
- var i = 0;
192
- for (let [k, v] of toPairs(data)) {
193
- // echo "..{k}-{v}.."
194
- i = i + 1;
195
- }
196
- check(i === 100);
197
- });
198
- test("map values", () => {
199
- var dict = new Map();
200
- for (let idx = 0; idx < 4; idx++) {
201
- dict.set(`${idx}`, idx + 10);
202
- }
203
- let data = initTernaryTreeMap(dict);
204
- var dict2 = new Map();
205
- for (let idx = 0; idx < 4; idx++) {
206
- dict2.set(`${idx}`, idx + 20);
207
- }
208
- let data2 = initTernaryTreeMap(dict2);
209
- let data3 = mapMapValues(data, (x) => x + 10);
210
- checkMapStructure(data3);
211
- checkMapStructure(data3);
212
- check(mapEqual(data2, data3));
213
- check(formatMapInline(data2) === formatMapInline(data3));
214
207
  });
215
208
  };
@@ -1,6 +1,10 @@
1
- export declare let test: (name: string, cb: () => void) => void;
2
- export declare let check: (x: boolean) => void;
3
- /** compare by reference */
4
- export declare let checkEqual: (x: any, y: any) => void;
1
+ export declare function describe(suiteName: string, cb: () => void): void;
2
+ export declare function test(testName: string, cb: () => void): void;
3
+ export declare function check(condition: boolean, message?: string): void;
4
+ export declare function checkEqual<T>(actual: T, expected: T, message?: string): void;
5
+ export declare function checkDeepEqual<T>(actual: T, expected: T, message?: string): void;
6
+ export declare function checkThrows(fn: () => void, message?: string): void;
5
7
  export declare function arrayEqual<T>(xs: Array<T>, ys: Array<T>): boolean;
6
- export declare let justDisplay: (x: any, y: any) => void;
8
+ export declare function checkArrayEqual<T>(actual: Array<T>, expected: Array<T>, message?: string): void;
9
+ export declare function justDisplay(x: any, y: any): void;
10
+ export declare function printTestSummary(): void;
@@ -1,23 +1,87 @@
1
- export let test = (name, cb) => {
2
- let target = process === null || process === void 0 ? void 0 : process.env["target"];
3
- if (target == null || name.includes(target)) {
4
- console.log("Test:", name);
1
+ const stats = { total: 0, passed: 0, failed: 0, suites: 0 };
2
+ const suites = [];
3
+ let currentSuite = null;
4
+ const colors = {
5
+ reset: "\x1b[0m",
6
+ bright: "\x1b[1m",
7
+ red: "\x1b[31m",
8
+ green: "\x1b[32m",
9
+ yellow: "\x1b[33m",
10
+ blue: "\x1b[34m",
11
+ magenta: "\x1b[35m",
12
+ cyan: "\x1b[36m",
13
+ };
14
+ export function describe(suiteName, cb) {
15
+ const target = process === null || process === void 0 ? void 0 : process.env["target"];
16
+ if (target != null && !suiteName.includes(target)) {
17
+ return;
18
+ }
19
+ console.log(`\n${colors.cyan}${colors.bright}○ ${suiteName}${colors.reset}`);
20
+ const suite = { name: suiteName, tests: [] };
21
+ suites.push(suite);
22
+ currentSuite = suite;
23
+ stats.suites++;
24
+ try {
5
25
  cb();
6
26
  }
7
- };
8
- export let check = (x) => {
9
- if (!x) {
10
- throw new Error("Test failed");
27
+ catch (error) {
28
+ console.log(`${colors.red}Suite "${suiteName}" failed to execute: ${error}${colors.reset}`);
11
29
  }
12
- };
13
- /** compare by reference */
14
- export let checkEqual = (x, y) => {
15
- if (x !== y) {
16
- console.log("Left: ", x);
17
- console.log("Right: ", y);
18
- throw new Error("Test failed");
30
+ currentSuite = null;
31
+ }
32
+ export function test(testName, cb) {
33
+ const target = process === null || process === void 0 ? void 0 : process.env["target"];
34
+ if (target != null && !testName.includes(target)) {
35
+ return;
19
36
  }
20
- };
37
+ const testCase = { name: testName, passed: false };
38
+ if (currentSuite) {
39
+ currentSuite.tests.push(testCase);
40
+ }
41
+ stats.total++;
42
+ const startTime = Date.now();
43
+ try {
44
+ cb();
45
+ testCase.passed = true;
46
+ testCase.duration = Date.now() - startTime;
47
+ stats.passed++;
48
+ console.log(` ${colors.green}✓${colors.reset} ${testName} ${colors.cyan}(${testCase.duration}ms)${colors.reset}`);
49
+ }
50
+ catch (error) {
51
+ testCase.passed = false;
52
+ testCase.error = error;
53
+ testCase.duration = Date.now() - startTime;
54
+ stats.failed++;
55
+ console.log(` ${colors.red}✗${colors.reset} ${testName} ${colors.cyan}(${testCase.duration}ms)${colors.reset}`);
56
+ console.log(` ${colors.red}${error.message}${colors.reset}`);
57
+ }
58
+ }
59
+ export function check(condition, message) {
60
+ if (!condition) {
61
+ throw new Error(message || "Assertion failed");
62
+ }
63
+ }
64
+ export function checkEqual(actual, expected, message) {
65
+ if (actual !== expected) {
66
+ const errorMessage = message || `Expected ${expected}, but got ${actual}`;
67
+ throw new Error(errorMessage);
68
+ }
69
+ }
70
+ export function checkDeepEqual(actual, expected, message) {
71
+ if (!deepEqual(actual, expected)) {
72
+ const errorMessage = message || `Deep equality check failed:\nActual: ${JSON.stringify(actual)}\nExpected: ${JSON.stringify(expected)}`;
73
+ throw new Error(errorMessage);
74
+ }
75
+ }
76
+ export function checkThrows(fn, message) {
77
+ try {
78
+ fn();
79
+ throw new Error(message || "Expected function to throw, but it didn't");
80
+ }
81
+ catch (error) {
82
+ // Success - function threw as expected
83
+ }
84
+ }
21
85
  export function arrayEqual(xs, ys) {
22
86
  if (xs.length != ys.length) {
23
87
  return false;
@@ -29,9 +93,58 @@ export function arrayEqual(xs, ys) {
29
93
  }
30
94
  return true;
31
95
  }
32
- export let justDisplay = (x, y) => {
96
+ export function checkArrayEqual(actual, expected, message) {
97
+ if (!arrayEqual(actual, expected)) {
98
+ const errorMessage = message || `Arrays are not equal:\nActual: [${actual.join(", ")}]\nExpected: [${expected.join(", ")}]`;
99
+ throw new Error(errorMessage);
100
+ }
101
+ }
102
+ export function justDisplay(x, y) {
33
103
  console.group("Compare:");
34
104
  console.log(x);
35
105
  console.log(y);
36
106
  console.groupEnd();
37
- };
107
+ }
108
+ function deepEqual(a, b) {
109
+ if (a === b)
110
+ return true;
111
+ if (a == null || b == null)
112
+ return false;
113
+ if (typeof a !== typeof b)
114
+ return false;
115
+ if (Array.isArray(a) && Array.isArray(b)) {
116
+ if (a.length !== b.length)
117
+ return false;
118
+ for (let i = 0; i < a.length; i++) {
119
+ if (!deepEqual(a[i], b[i]))
120
+ return false;
121
+ }
122
+ return true;
123
+ }
124
+ if (typeof a === "object" && typeof b === "object") {
125
+ const keysA = Object.keys(a);
126
+ const keysB = Object.keys(b);
127
+ if (keysA.length !== keysB.length)
128
+ return false;
129
+ for (const key of keysA) {
130
+ if (!keysB.includes(key) || !deepEqual(a[key], b[key]))
131
+ return false;
132
+ }
133
+ return true;
134
+ }
135
+ return false;
136
+ }
137
+ export function printTestSummary() {
138
+ console.log(`\n${colors.bright}Test Summary:${colors.reset}`);
139
+ console.log(`${colors.cyan}Suites: ${stats.suites}${colors.reset}`);
140
+ console.log(`${colors.cyan}Tests: ${stats.total}${colors.reset}`);
141
+ console.log(`${colors.green}Passed: ${stats.passed}${colors.reset}`);
142
+ if (stats.failed > 0) {
143
+ console.log(`${colors.red}Failed: ${stats.failed}${colors.reset}`);
144
+ console.log(`\n${colors.red}${colors.bright}❌ ${stats.failed} test(s) failed${colors.reset}`);
145
+ process.exit(1);
146
+ }
147
+ else {
148
+ console.log(`\n${colors.green}${colors.bright}✅ All tests passed!${colors.reset}`);
149
+ }
150
+ }
@@ -4,6 +4,9 @@ import "./test-map.mjs";
4
4
  import { runListTests } from "./test-list.mjs";
5
5
  import { runMapTests } from "./test-map.mjs";
6
6
  import { mergeValueHash, overwriteHashGenerator, valueHash } from "./types.mjs";
7
+ import { printTestSummary } from "./test-utils.mjs";
8
+ // import { disableListStructureCheck } from "./list.mjs";
9
+ // disableListStructureCheck();
7
10
  overwriteComparator((x, y) => {
8
11
  // console.log("comparing", x, y);
9
12
  return deepEqual(x, y);
@@ -13,5 +16,7 @@ overwriteHashGenerator((x) => {
13
16
  // console.log("hashing", x, ret);
14
17
  return ret;
15
18
  });
19
+ console.log("🧪 Running TernaryTree Tests...\n");
16
20
  runListTests();
17
21
  runMapTests();
22
+ printTestSummary();
package/package.json CHANGED
@@ -1,11 +1,19 @@
1
1
  {
2
2
  "name": "@calcit/ternary-tree",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "main": "./lib/index.mjs",
5
- "scripts": {},
5
+ "scripts": {
6
+ "build": "tsc",
7
+ "test": "yarn build && node lib/test.mjs",
8
+ "test:watch": "yarn build && node lib/test.mjs",
9
+ "test:list": "TARGET=list yarn test",
10
+ "test:map": "TARGET=map yarn test",
11
+ "test:list-perf": "yarn build && node lib/test-list-perf.mjs",
12
+ "test:list-detailed-perf": "yarn build && node lib/test-list-detailed-perf.mjs"
13
+ },
6
14
  "devDependencies": {
7
- "@types/node": "^20.4.8",
8
- "prettier": "^3.0.0",
9
- "typescript": "^5.1.6"
15
+ "@types/node": "^20.12.5",
16
+ "prettier": "^3.2.5",
17
+ "typescript": "^5.4.4"
10
18
  }
11
19
  }
File without changes