@calcit/ternary-tree 0.0.24 → 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/README.md +24 -4
- package/TESTING.md +155 -0
- package/lib/benchmark.d.mts +1 -0
- package/lib/benchmark.mjs +67 -0
- package/lib/list.mjs +170 -124
- package/lib/map.mjs +124 -101
- package/lib/test-list-detailed-perf.d.mts +1 -0
- package/lib/test-list-detailed-perf.mjs +165 -0
- package/lib/test-list-perf.d.mts +1 -0
- package/lib/test-list-perf.mjs +153 -0
- package/lib/test-list.mjs +202 -203
- package/lib/test-map-perf.d.mts +1 -0
- package/lib/test-map-perf.mjs +70 -0
- package/lib/test-map.mjs +201 -208
- package/lib/test-utils.d.mts +9 -5
- package/lib/test-utils.mjs +131 -18
- package/lib/{main.mjs → test.mjs} +3 -0
- package/package.json +10 -2
- /package/lib/{main.d.mts → test.d.mts} +0 -0
package/README.md
CHANGED
@@ -40,7 +40,7 @@ function sameMapShape<K, T>(xs: TernaryTreeMap<K, T>, ys: TernaryTreeMap<K, T>):
|
|
40
40
|
|
41
41
|
List functions:
|
42
42
|
|
43
|
-
|
43
|
+
````ts
|
44
44
|
function makeTernaryTreeList<T>(size: number, offset: number, xs: /* var */ Array<TernaryTreeList<T>>): TernaryTreeList<T>;
|
45
45
|
function initTernaryTreeList<T>(xs: Array<T>): TernaryTreeList<T>;
|
46
46
|
function initEmptyTernaryTreeList<T>(): TernaryTreeList<T>;
|
@@ -75,9 +75,29 @@ function sameListShape<T>(xs: TernaryTreeList<T>, ys: TernaryTreeList<T>): boole
|
|
75
75
|
function getDepth<T>(tree: TernaryTreeList<T>): number;
|
76
76
|
function listToString<T>(tree: TernaryTreeList<T>): string;
|
77
77
|
function formatListInline<T>(tree: TernaryTreeList<T>): string;
|
78
|
-
function
|
78
|
+
function checkList
|
79
|
+
|
80
|
+
### Development
|
81
|
+
|
82
|
+
```bash
|
83
|
+
# Install dependencies
|
84
|
+
yarn install
|
85
|
+
|
86
|
+
# Build TypeScript
|
87
|
+
yarn build
|
88
|
+
|
89
|
+
# Run all tests
|
90
|
+
yarn test
|
91
|
+
|
92
|
+
# Run specific test suites
|
93
|
+
yarn test:list # List-related tests only
|
94
|
+
yarn test:map # Map-related tests only
|
95
|
+
````
|
96
|
+
|
97
|
+
For detailed testing information, see [TESTING.md](./TESTING.md).Structure<T>(tree: TernaryTreeList<T>): boolean;
|
79
98
|
function forceListInplaceBalancing<T>(tree: TernaryTreeList<T>): void;
|
80
|
-
|
99
|
+
|
100
|
+
````
|
81
101
|
|
82
102
|
To overwrite internals behaviors:
|
83
103
|
|
@@ -85,7 +105,7 @@ To overwrite internals behaviors:
|
|
85
105
|
overwriteHashGenerator(f);
|
86
106
|
|
87
107
|
overwriteComparator(f);
|
88
|
-
|
108
|
+
````
|
89
109
|
|
90
110
|
### License
|
91
111
|
|
package/TESTING.md
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
# Testing Guide
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
This project uses a custom lightweight testing framework that provides colored output, test organization, and detailed error reporting.
|
6
|
+
|
7
|
+
## Running Tests
|
8
|
+
|
9
|
+
### Basic Commands
|
10
|
+
|
11
|
+
```bash
|
12
|
+
# Build and run all tests
|
13
|
+
yarn test
|
14
|
+
|
15
|
+
# Only compile (useful for checking TypeScript errors)
|
16
|
+
yarn build
|
17
|
+
|
18
|
+
# Run tests manually after building
|
19
|
+
node lib/test.mjs
|
20
|
+
```
|
21
|
+
|
22
|
+
### Selective Testing
|
23
|
+
|
24
|
+
```bash
|
25
|
+
# Run only list tests (any test with "list" in the name)
|
26
|
+
yarn test:list
|
27
|
+
|
28
|
+
# Run only map tests (any test with "map" in the name)
|
29
|
+
yarn test:map
|
30
|
+
|
31
|
+
# Use environment variable for custom filtering
|
32
|
+
TARGET=specific-test-name yarn test
|
33
|
+
```
|
34
|
+
|
35
|
+
## Test Framework Features
|
36
|
+
|
37
|
+
### Test Organization
|
38
|
+
|
39
|
+
- **Test Suites**: Use `describe()` to group related tests
|
40
|
+
- **Individual Tests**: Use `test()` for specific test cases
|
41
|
+
- **Colored Output**: Green ✓ for passing tests, red ✗ for failing tests
|
42
|
+
- **Timing**: Shows execution time for each test
|
43
|
+
|
44
|
+
### Assertion Functions
|
45
|
+
|
46
|
+
#### Basic Assertions
|
47
|
+
|
48
|
+
```typescript
|
49
|
+
check(condition: boolean, message?: string)
|
50
|
+
```
|
51
|
+
|
52
|
+
#### Equality Checks
|
53
|
+
|
54
|
+
```typescript
|
55
|
+
checkEqual<T>(actual: T, expected: T, message?: string)
|
56
|
+
checkDeepEqual<T>(actual: T, expected: T, message?: string)
|
57
|
+
```
|
58
|
+
|
59
|
+
#### Array Comparisons
|
60
|
+
|
61
|
+
```typescript
|
62
|
+
checkArrayEqual<T>(actual: Array<T>, expected: Array<T>, message?: string)
|
63
|
+
arrayEqual<T>(xs: Array<T>, ys: Array<T>): boolean
|
64
|
+
```
|
65
|
+
|
66
|
+
#### Exception Testing
|
67
|
+
|
68
|
+
```typescript
|
69
|
+
checkThrows(fn: () => void, message?: string)
|
70
|
+
```
|
71
|
+
|
72
|
+
#### Debug Utilities
|
73
|
+
|
74
|
+
```typescript
|
75
|
+
justDisplay(actual: any, expected: any) // For comparing values visually
|
76
|
+
```
|
77
|
+
|
78
|
+
### Example Test Structure
|
79
|
+
|
80
|
+
```typescript
|
81
|
+
import { describe, test, check, checkEqual, checkArrayEqual } from "./test-utils.mjs";
|
82
|
+
|
83
|
+
export function runMyTests() {
|
84
|
+
describe("My Component Tests", () => {
|
85
|
+
test("should do something basic", () => {
|
86
|
+
const result = myFunction();
|
87
|
+
check(result !== null, "Result should not be null");
|
88
|
+
checkEqual(result.status, "success");
|
89
|
+
});
|
90
|
+
|
91
|
+
test("should handle arrays correctly", () => {
|
92
|
+
const actual = [1, 2, 3];
|
93
|
+
const expected = [1, 2, 3];
|
94
|
+
checkArrayEqual(actual, expected);
|
95
|
+
});
|
96
|
+
|
97
|
+
test("should throw on invalid input", () => {
|
98
|
+
checkThrows(() => {
|
99
|
+
myFunction(null);
|
100
|
+
}, "Should throw on null input");
|
101
|
+
});
|
102
|
+
});
|
103
|
+
}
|
104
|
+
```
|
105
|
+
|
106
|
+
## Test Output
|
107
|
+
|
108
|
+
The framework provides:
|
109
|
+
|
110
|
+
- **Suite Organization**: Clear grouping with cyan headers
|
111
|
+
- **Individual Results**: Green checkmarks for passing tests
|
112
|
+
- **Timing Information**: Execution time for each test
|
113
|
+
- **Error Details**: Clear error messages with stack traces
|
114
|
+
- **Summary Statistics**: Total tests, passed, failed counts
|
115
|
+
- **Exit Codes**: Non-zero exit code on test failures
|
116
|
+
|
117
|
+
## Current Test Coverage
|
118
|
+
|
119
|
+
### TernaryTreeList Tests (15 tests)
|
120
|
+
|
121
|
+
- Initialization and basic operations
|
122
|
+
- List insertions and modifications
|
123
|
+
- Concatenation and merging
|
124
|
+
- Equality checking and comparison
|
125
|
+
- Balancing and structure integrity
|
126
|
+
- Iteration and traversal
|
127
|
+
- Slicing and reversal
|
128
|
+
- Index finding and mapping
|
129
|
+
- Stress testing
|
130
|
+
|
131
|
+
### TernaryTreeMap Tests (12 tests)
|
132
|
+
|
133
|
+
- Map initialization and creation
|
134
|
+
- Association and containment checking
|
135
|
+
- Structure integrity validation
|
136
|
+
- Dissociation operations
|
137
|
+
- Array conversion and iteration
|
138
|
+
- Equality and shape comparison
|
139
|
+
- Map merging with various strategies
|
140
|
+
- Value mapping transformations
|
141
|
+
- Large dataset handling
|
142
|
+
|
143
|
+
## Adding New Tests
|
144
|
+
|
145
|
+
1. Create test functions in existing or new test files
|
146
|
+
2. Use the `describe()` and `test()` structure
|
147
|
+
3. Import and call your test function in `test.mts`
|
148
|
+
4. Use appropriate assertion functions for validation
|
149
|
+
5. Run `yarn test` to verify everything works
|
150
|
+
|
151
|
+
## Performance Considerations
|
152
|
+
|
153
|
+
- Tests include timing information to identify slow operations
|
154
|
+
- Stress tests (like concat loop test) help identify performance regressions
|
155
|
+
- Structure integrity checks validate the internal tree consistency
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,67 @@
|
|
1
|
+
// Performance comparison script
|
2
|
+
import { initTernaryTreeMap, initTernaryTreeMapFromArray, contains, mapGetDefault, toPairsArray, } from "./map.mjs";
|
3
|
+
function createTestData(size) {
|
4
|
+
const data = [];
|
5
|
+
for (let i = 0; i < size; i++) {
|
6
|
+
data.push([i, `value_${i}`]);
|
7
|
+
}
|
8
|
+
return data;
|
9
|
+
}
|
10
|
+
function measureTime(fn, iterations = 1) {
|
11
|
+
const start = performance.now();
|
12
|
+
for (let i = 0; i < iterations; i++) {
|
13
|
+
fn();
|
14
|
+
}
|
15
|
+
const end = performance.now();
|
16
|
+
return (end - start) / iterations;
|
17
|
+
}
|
18
|
+
function runComparison() {
|
19
|
+
console.log("=== Performance Optimization Results ===\n");
|
20
|
+
const sizes = [1000, 5000, 10000];
|
21
|
+
const iterations = 5; // Run multiple times for more accurate results
|
22
|
+
for (const size of sizes) {
|
23
|
+
console.log(`--- ${size} elements (averaged over ${iterations} runs) ---`);
|
24
|
+
const testData = createTestData(size);
|
25
|
+
const mapData = new Map(testData);
|
26
|
+
// Test initTernaryTreeMapFromArray performance
|
27
|
+
const arrayTime = measureTime(() => {
|
28
|
+
return initTernaryTreeMapFromArray(testData);
|
29
|
+
}, iterations);
|
30
|
+
const mapTime = measureTime(() => {
|
31
|
+
return initTernaryTreeMap(mapData);
|
32
|
+
}, iterations);
|
33
|
+
console.log(`initTernaryTreeMapFromArray: ${arrayTime.toFixed(2)}ms`);
|
34
|
+
console.log(`initTernaryTreeMap: ${mapTime.toFixed(2)}ms`);
|
35
|
+
// Create tree for lookup tests
|
36
|
+
const tree = initTernaryTreeMapFromArray(testData);
|
37
|
+
// Test lookup performance
|
38
|
+
const lookupKeys = testData.slice(0, 100).map(([k]) => k);
|
39
|
+
const lookupTime = measureTime(() => {
|
40
|
+
for (const key of lookupKeys) {
|
41
|
+
contains(tree, key);
|
42
|
+
mapGetDefault(tree, key, "default");
|
43
|
+
}
|
44
|
+
}, iterations);
|
45
|
+
console.log(`Lookups (100 operations): ${lookupTime.toFixed(2)}ms`);
|
46
|
+
// Test toPairsArray performance
|
47
|
+
const toPairsTime = measureTime(() => {
|
48
|
+
return toPairsArray(tree);
|
49
|
+
}, iterations);
|
50
|
+
console.log(`toPairsArray: ${toPairsTime.toFixed(2)}ms`);
|
51
|
+
console.log(`Array/Map init ratio: ${(arrayTime / mapTime).toFixed(2)}x`);
|
52
|
+
console.log("");
|
53
|
+
}
|
54
|
+
// Stress test
|
55
|
+
console.log("=== Stress Test ===");
|
56
|
+
const largeData = createTestData(50000);
|
57
|
+
const stressTime = measureTime(() => {
|
58
|
+
const tree = initTernaryTreeMapFromArray(largeData);
|
59
|
+
// Test some operations
|
60
|
+
for (let i = 0; i < 1000; i++) {
|
61
|
+
contains(tree, i);
|
62
|
+
}
|
63
|
+
return tree;
|
64
|
+
});
|
65
|
+
console.log(`Stress test (50k elements + 1k lookups): ${stressTime.toFixed(2)}ms`);
|
66
|
+
}
|
67
|
+
runComparison();
|