@graphty/layout 1.2.3 → 1.2.5
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/dist/src/algorithms/index.d.ts +5 -0
- package/dist/src/algorithms/index.js +6 -0
- package/dist/src/algorithms/index.js.map +1 -0
- package/dist/src/algorithms/optimization/index.d.ts +7 -0
- package/dist/src/algorithms/optimization/index.js +7 -0
- package/dist/src/algorithms/optimization/index.js.map +1 -0
- package/dist/src/algorithms/optimization/kamada-kawai-solver.d.ts +32 -0
- package/dist/src/algorithms/optimization/kamada-kawai-solver.js +176 -0
- package/dist/src/algorithms/optimization/kamada-kawai-solver.js.map +1 -0
- package/dist/src/algorithms/optimization/lbfgs.d.ts +13 -0
- package/dist/src/algorithms/optimization/lbfgs.js +56 -0
- package/dist/src/algorithms/optimization/lbfgs.js.map +1 -0
- package/dist/src/algorithms/optimization/line-search.d.ts +15 -0
- package/dist/src/algorithms/optimization/line-search.js +37 -0
- package/dist/src/algorithms/optimization/line-search.js.map +1 -0
- package/dist/src/algorithms/optimization/types.d.ts +5 -0
- package/dist/src/algorithms/optimization/types.js +5 -0
- package/dist/src/algorithms/optimization/types.js.map +1 -0
- package/dist/src/algorithms/planarity/check.d.ts +17 -0
- package/dist/src/algorithms/planarity/check.js +30 -0
- package/dist/src/algorithms/planarity/check.js.map +1 -0
- package/dist/src/algorithms/planarity/embedding.d.ts +29 -0
- package/dist/src/algorithms/planarity/embedding.js +179 -0
- package/dist/src/algorithms/planarity/embedding.js.map +1 -0
- package/dist/src/algorithms/planarity/index.d.ts +7 -0
- package/dist/src/algorithms/planarity/index.js +8 -0
- package/dist/src/algorithms/planarity/index.js.map +1 -0
- package/dist/src/algorithms/planarity/lr-test.d.ts +15 -0
- package/dist/src/algorithms/planarity/lr-test.js +54 -0
- package/dist/src/algorithms/planarity/lr-test.js.map +1 -0
- package/dist/src/algorithms/planarity/special-graphs.d.ts +28 -0
- package/dist/src/algorithms/planarity/special-graphs.js +108 -0
- package/dist/src/algorithms/planarity/special-graphs.js.map +1 -0
- package/dist/src/generators/basic.d.ts +28 -0
- package/dist/src/generators/basic.js +79 -0
- package/dist/src/generators/basic.js.map +1 -0
- package/dist/src/generators/bipartite.d.ts +16 -0
- package/dist/src/generators/bipartite.js +40 -0
- package/dist/src/generators/bipartite.js.map +1 -0
- package/dist/src/generators/grid.d.ts +11 -0
- package/dist/src/generators/grid.js +37 -0
- package/dist/src/generators/grid.js.map +1 -0
- package/dist/src/generators/index.d.ts +8 -0
- package/dist/src/generators/index.js +9 -0
- package/dist/src/generators/index.js.map +1 -0
- package/dist/src/generators/random.d.ts +12 -0
- package/dist/src/generators/random.js +34 -0
- package/dist/src/generators/random.js.map +1 -0
- package/dist/src/generators/scale-free.d.ts +12 -0
- package/dist/src/generators/scale-free.js +62 -0
- package/dist/src/generators/scale-free.js.map +1 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.js +15 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/layouts/basic/index.d.ts +4 -0
- package/dist/src/layouts/basic/index.js +5 -0
- package/dist/src/layouts/basic/index.js.map +1 -0
- package/dist/src/layouts/basic/random.d.ts +14 -0
- package/dist/src/layouts/basic/random.js +27 -0
- package/dist/src/layouts/basic/random.js.map +1 -0
- package/dist/src/layouts/force-directed/arf.d.ts +13 -0
- package/dist/src/layouts/force-directed/arf.js +103 -0
- package/dist/src/layouts/force-directed/arf.js.map +1 -0
- package/dist/src/layouts/force-directed/forceatlas2.d.ts +22 -0
- package/dist/src/layouts/force-directed/forceatlas2.js +340 -0
- package/dist/src/layouts/force-directed/forceatlas2.js.map +1 -0
- package/dist/src/layouts/force-directed/fruchterman-reingold.d.ts +19 -0
- package/dist/src/layouts/force-directed/fruchterman-reingold.js +131 -0
- package/dist/src/layouts/force-directed/fruchterman-reingold.js.map +1 -0
- package/dist/src/layouts/force-directed/index.d.ts +8 -0
- package/dist/src/layouts/force-directed/index.js +9 -0
- package/dist/src/layouts/force-directed/index.js.map +1 -0
- package/dist/src/layouts/force-directed/kamada-kawai.d.ts +15 -0
- package/dist/src/layouts/force-directed/kamada-kawai.js +87 -0
- package/dist/src/layouts/force-directed/kamada-kawai.js.map +1 -0
- package/dist/src/layouts/force-directed/spring.d.ts +19 -0
- package/dist/src/layouts/force-directed/spring.js +23 -0
- package/dist/src/layouts/force-directed/spring.js.map +1 -0
- package/dist/src/layouts/geometric/circular.d.ts +14 -0
- package/dist/src/layouts/geometric/circular.js +67 -0
- package/dist/src/layouts/geometric/circular.js.map +1 -0
- package/dist/src/layouts/geometric/index.d.ts +6 -0
- package/dist/src/layouts/geometric/index.js +7 -0
- package/dist/src/layouts/geometric/index.js.map +1 -0
- package/dist/src/layouts/geometric/shell.d.ts +15 -0
- package/dist/src/layouts/geometric/shell.js +67 -0
- package/dist/src/layouts/geometric/shell.js.map +1 -0
- package/dist/src/layouts/geometric/spiral.d.ts +16 -0
- package/dist/src/layouts/geometric/spiral.js +73 -0
- package/dist/src/layouts/geometric/spiral.js.map +1 -0
- package/dist/src/layouts/hierarchical/bfs.d.ts +12 -0
- package/dist/src/layouts/hierarchical/bfs.js +62 -0
- package/dist/src/layouts/hierarchical/bfs.js.map +1 -0
- package/dist/src/layouts/hierarchical/bipartite.d.ts +16 -0
- package/dist/src/layouts/hierarchical/bipartite.js +72 -0
- package/dist/src/layouts/hierarchical/bipartite.js.map +1 -0
- package/dist/src/layouts/hierarchical/index.d.ts +6 -0
- package/dist/src/layouts/hierarchical/index.js +7 -0
- package/dist/src/layouts/hierarchical/index.js.map +1 -0
- package/dist/src/layouts/hierarchical/multipartite.d.ts +12 -0
- package/dist/src/layouts/hierarchical/multipartite.js +73 -0
- package/dist/src/layouts/hierarchical/multipartite.js.map +1 -0
- package/dist/src/layouts/index.d.ts +8 -0
- package/dist/src/layouts/index.js +9 -0
- package/dist/src/layouts/index.js.map +1 -0
- package/dist/src/layouts/specialized/index.d.ts +5 -0
- package/dist/src/layouts/specialized/index.js +6 -0
- package/dist/src/layouts/specialized/index.js.map +1 -0
- package/dist/src/layouts/specialized/planar.d.ts +14 -0
- package/dist/src/layouts/specialized/planar.js +47 -0
- package/dist/src/layouts/specialized/planar.js.map +1 -0
- package/dist/src/layouts/specialized/spectral.d.ts +14 -0
- package/dist/src/layouts/specialized/spectral.js +106 -0
- package/dist/src/layouts/specialized/spectral.js.map +1 -0
- package/dist/src/types/embedding.d.ts +9 -0
- package/dist/src/types/embedding.js +5 -0
- package/dist/src/types/embedding.js.map +1 -0
- package/dist/src/types/graph.d.ts +10 -0
- package/dist/src/types/graph.js +5 -0
- package/dist/src/types/graph.js.map +1 -0
- package/dist/src/types/index.d.ts +6 -0
- package/dist/src/types/index.js +7 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/layout.d.ts +6 -0
- package/dist/src/types/layout.js +5 -0
- package/dist/src/types/layout.js.map +1 -0
- package/dist/src/utils/graph.d.ts +34 -0
- package/dist/src/utils/graph.js +69 -0
- package/dist/src/utils/graph.js.map +1 -0
- package/dist/src/utils/index.d.ts +8 -0
- package/dist/src/utils/index.js +9 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/numpy.d.ts +17 -0
- package/dist/src/utils/numpy.js +101 -0
- package/dist/src/utils/numpy.js.map +1 -0
- package/dist/src/utils/params.d.ts +17 -0
- package/dist/src/utils/params.js +22 -0
- package/dist/src/utils/params.js.map +1 -0
- package/dist/src/utils/random.d.ts +14 -0
- package/dist/src/utils/random.js +42 -0
- package/dist/src/utils/random.js.map +1 -0
- package/dist/src/utils/rescale.d.ts +21 -0
- package/dist/src/utils/rescale.js +194 -0
- package/dist/src/utils/rescale.js.map +1 -0
- package/dist/vitest.config.js +1 -1
- package/dist/vitest.config.js.map +1 -1
- package/package.json +19 -4
- package/src/layouts/force-directed/forceatlas2.ts +23 -4
- package/src/utils/rescale.ts +90 -15
- package/.env.example +0 -11
- package/.github/workflows/ci.yml +0 -101
- package/.releaserc.json +0 -22
- package/CHANGELOG.md +0 -52
- package/CLAUDE.md +0 -104
- package/CONTRIBUTING.md +0 -1
- package/DEPLOYMENT.md +0 -59
- package/build-examples-script.js +0 -26
- package/commitlint.config.js +0 -37
- package/examples/3d-force-directed.html +0 -611
- package/examples/3d-kamada-kawai.html +0 -379
- package/examples/3d-layout-comparison.html +0 -448
- package/examples/3d-spherical-layout.html +0 -319
- package/examples/arf-layout.html +0 -524
- package/examples/bfs-layout.html +0 -487
- package/examples/bipartite-layout.html +0 -382
- package/examples/circular-layout.html +0 -292
- package/examples/forceatlas2-layout.html +0 -588
- package/examples/index.html +0 -241
- package/examples/kamada-kawai-layout.html +0 -425
- package/examples/layout-helpers.js +0 -23
- package/examples/layout.js +0 -2304
- package/examples/multipartite-layout.html +0 -410
- package/examples/planar-layout.html +0 -388
- package/examples/random-layout.html +0 -328
- package/examples/shell-layout.html +0 -323
- package/examples/spectral-layout.html +0 -335
- package/examples/spiral-layout.html +0 -447
- package/examples/spring-layout.html +0 -313
- package/test/arf-layout.test.ts +0 -443
- package/test/bfs-layout.test.ts +0 -427
- package/test/bipartite-layout.test.ts +0 -344
- package/test/circular-layout.test.ts +0 -442
- package/test/forceatlas2-layout.test.ts +0 -405
- package/test/fruchterman-reingold-layout.test.ts +0 -477
- package/test/graph-generators.test.ts +0 -450
- package/test/kamada-kawai-layout.test.ts +0 -623
- package/test/multipartite-layout.test.ts +0 -404
- package/test/planar-layout.test.ts +0 -266
- package/test/random-layout.test.ts +0 -254
- package/test/rescale-layout.test.ts +0 -373
- package/test/shell-layout.test.ts +0 -347
- package/test/spectral-layout.test.ts +0 -378
- package/test/spiral-layout.test.ts +0 -338
- package/test/spring-layout.test.ts +0 -241
- package/test/test-utils.ts +0 -34
- package/test/utils-graph.test.ts +0 -155
- package/test/utils-index.test.ts +0 -77
- package/test/utils-numpy.test.ts +0 -272
- package/test/utils-params.test.ts +0 -99
- package/test/utils-random.test.ts +0 -229
- package/tsconfig.json +0 -16
- package/vite.config.js +0 -36
- package/vitest.config.ts +0 -30
package/test/utils-graph.test.ts
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for graph utility functions
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, it, expect } from 'vitest';
|
|
6
|
-
import {
|
|
7
|
-
getNodesFromGraph,
|
|
8
|
-
getEdgesFromGraph,
|
|
9
|
-
getNodeDegree,
|
|
10
|
-
getNeighbors
|
|
11
|
-
} from '../src/utils/graph';
|
|
12
|
-
import { createTestGraph } from './test-utils';
|
|
13
|
-
|
|
14
|
-
describe('Graph Utils', () => {
|
|
15
|
-
describe('getNodesFromGraph', () => {
|
|
16
|
-
it('should return array as-is when given array of nodes', () => {
|
|
17
|
-
const nodes = [1, 2, 3, 'a', 'b'];
|
|
18
|
-
const result = getNodesFromGraph(nodes);
|
|
19
|
-
expect(result).toEqual(nodes);
|
|
20
|
-
expect(result).toBe(nodes); // same reference
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('should call nodes() method when given graph object', () => {
|
|
24
|
-
const graph = createTestGraph([1, 2, 3], [[1, 2], [2, 3]]);
|
|
25
|
-
const result = getNodesFromGraph(graph);
|
|
26
|
-
expect(result).toEqual([1, 2, 3]);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('should handle empty array', () => {
|
|
30
|
-
const result = getNodesFromGraph([]);
|
|
31
|
-
expect(result).toEqual([]);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('should handle empty graph', () => {
|
|
35
|
-
const graph = createTestGraph([], []);
|
|
36
|
-
const result = getNodesFromGraph(graph);
|
|
37
|
-
expect(result).toEqual([]);
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
describe('getEdgesFromGraph', () => {
|
|
42
|
-
it('should return empty array when given array of nodes', () => {
|
|
43
|
-
const nodes = [1, 2, 3, 'a', 'b'];
|
|
44
|
-
const result = getEdgesFromGraph(nodes);
|
|
45
|
-
expect(result).toEqual([]);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('should call edges() method when given graph object', () => {
|
|
49
|
-
const edges = [[1, 2], [2, 3], [3, 1]];
|
|
50
|
-
const graph = createTestGraph([1, 2, 3], edges);
|
|
51
|
-
const result = getEdgesFromGraph(graph);
|
|
52
|
-
expect(result).toEqual(edges);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('should handle empty array', () => {
|
|
56
|
-
const result = getEdgesFromGraph([]);
|
|
57
|
-
expect(result).toEqual([]);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should handle graph with no edges', () => {
|
|
61
|
-
const graph = createTestGraph([1, 2, 3], []);
|
|
62
|
-
const result = getEdgesFromGraph(graph);
|
|
63
|
-
expect(result).toEqual([]);
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
describe('getNodeDegree', () => {
|
|
68
|
-
it('should return 0 for graph without edges method', () => {
|
|
69
|
-
const graph = { nodes: () => [1, 2, 3] } as any;
|
|
70
|
-
const result = getNodeDegree(graph, 1);
|
|
71
|
-
expect(result).toBe(0);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it('should calculate degree correctly for connected node', () => {
|
|
75
|
-
const graph = createTestGraph([1, 2, 3, 4], [[1, 2], [1, 3], [1, 4], [2, 3]]);
|
|
76
|
-
expect(getNodeDegree(graph, 1)).toBe(3); // connected to 2, 3, 4
|
|
77
|
-
expect(getNodeDegree(graph, 2)).toBe(2); // connected to 1, 3
|
|
78
|
-
expect(getNodeDegree(graph, 3)).toBe(2); // connected to 1, 2
|
|
79
|
-
expect(getNodeDegree(graph, 4)).toBe(1); // connected to 1
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('should return 0 for isolated node', () => {
|
|
83
|
-
const graph = createTestGraph([1, 2, 3], [[1, 2]]);
|
|
84
|
-
expect(getNodeDegree(graph, 3)).toBe(0);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should handle self-loops correctly', () => {
|
|
88
|
-
const graph = createTestGraph([1, 2], [[1, 1], [1, 2]]);
|
|
89
|
-
expect(getNodeDegree(graph, 1)).toBe(2); // self-loop + edge to 2
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('should handle node not in graph', () => {
|
|
93
|
-
const graph = createTestGraph([1, 2, 3], [[1, 2]]);
|
|
94
|
-
expect(getNodeDegree(graph, 999)).toBe(0);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('should handle empty graph', () => {
|
|
98
|
-
const graph = createTestGraph([], []);
|
|
99
|
-
expect(getNodeDegree(graph, 1)).toBe(0);
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
describe('getNeighbors', () => {
|
|
104
|
-
it('should return empty array for graph without edges method', () => {
|
|
105
|
-
const graph = { nodes: () => [1, 2, 3] } as any;
|
|
106
|
-
const result = getNeighbors(graph, 1);
|
|
107
|
-
expect(result).toEqual([]);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('should return neighbors correctly', () => {
|
|
111
|
-
const graph = createTestGraph([1, 2, 3, 4], [[1, 2], [1, 3], [2, 4], [3, 4]]);
|
|
112
|
-
|
|
113
|
-
const neighbors1 = getNeighbors(graph, 1);
|
|
114
|
-
expect(neighbors1.sort()).toEqual([2, 3]);
|
|
115
|
-
|
|
116
|
-
const neighbors2 = getNeighbors(graph, 2);
|
|
117
|
-
expect(neighbors2.sort()).toEqual([1, 4]);
|
|
118
|
-
|
|
119
|
-
const neighbors4 = getNeighbors(graph, 4);
|
|
120
|
-
expect(neighbors4.sort()).toEqual([2, 3]);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('should return empty array for isolated node', () => {
|
|
124
|
-
const graph = createTestGraph([1, 2, 3], [[1, 2]]);
|
|
125
|
-
expect(getNeighbors(graph, 3)).toEqual([]);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('should handle self-loops correctly', () => {
|
|
129
|
-
const graph = createTestGraph([1, 2], [[1, 1], [1, 2]]);
|
|
130
|
-
const neighbors = getNeighbors(graph, 1);
|
|
131
|
-
expect(neighbors.sort()).toEqual([1, 2]); // includes self and neighbor
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('should not duplicate neighbors in undirected edges', () => {
|
|
135
|
-
const graph = createTestGraph([1, 2, 3], [[1, 2], [2, 1], [1, 3]]); // bidirectional edge
|
|
136
|
-
const neighbors = getNeighbors(graph, 1);
|
|
137
|
-
expect(neighbors.sort()).toEqual([2, 3]); // should not duplicate node 2
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('should handle node not in graph', () => {
|
|
141
|
-
const graph = createTestGraph([1, 2, 3], [[1, 2]]);
|
|
142
|
-
expect(getNeighbors(graph, 999)).toEqual([]);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it('should handle empty graph', () => {
|
|
146
|
-
const graph = createTestGraph([], []);
|
|
147
|
-
expect(getNeighbors(graph, 1)).toEqual([]);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it('should work with string node IDs', () => {
|
|
151
|
-
const graph = createTestGraph(['a', 'b', 'c'], [['a', 'b'], ['b', 'c']]);
|
|
152
|
-
expect(getNeighbors(graph, 'b').sort()).toEqual(['a', 'c']);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
});
|
package/test/utils-index.test.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for utils index exports
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, it, expect } from 'vitest';
|
|
6
|
-
|
|
7
|
-
describe('Utils Index', () => {
|
|
8
|
-
it('should export all utility functions from numpy', async () => {
|
|
9
|
-
const { np } = await import('../src/utils/index');
|
|
10
|
-
expect(np).toBeDefined();
|
|
11
|
-
expect(typeof np.zeros).toBe('function');
|
|
12
|
-
expect(typeof np.ones).toBe('function');
|
|
13
|
-
expect(typeof np.linspace).toBe('function');
|
|
14
|
-
expect(typeof np.array).toBe('function');
|
|
15
|
-
expect(typeof np.repeat).toBe('function');
|
|
16
|
-
expect(typeof np.mean).toBe('function');
|
|
17
|
-
expect(typeof np.add).toBe('function');
|
|
18
|
-
expect(typeof np.subtract).toBe('function');
|
|
19
|
-
expect(typeof np.max).toBe('function');
|
|
20
|
-
expect(typeof np.min).toBe('function');
|
|
21
|
-
expect(typeof np.norm).toBe('function');
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('should export RandomNumberGenerator class', async () => {
|
|
25
|
-
const { RandomNumberGenerator } = await import('../src/utils/index');
|
|
26
|
-
expect(RandomNumberGenerator).toBeDefined();
|
|
27
|
-
expect(typeof RandomNumberGenerator).toBe('function');
|
|
28
|
-
|
|
29
|
-
const rng = new RandomNumberGenerator(123);
|
|
30
|
-
expect(typeof rng.rand).toBe('function');
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('should export graph utility functions', async () => {
|
|
34
|
-
const { getNodesFromGraph, getEdgesFromGraph, getNodeDegree, getNeighbors } = await import('../src/utils/index');
|
|
35
|
-
expect(typeof getNodesFromGraph).toBe('function');
|
|
36
|
-
expect(typeof getEdgesFromGraph).toBe('function');
|
|
37
|
-
expect(typeof getNodeDegree).toBe('function');
|
|
38
|
-
expect(typeof getNeighbors).toBe('function');
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('should export parameter processing functions', async () => {
|
|
42
|
-
const { _processParams } = await import('../src/utils/index');
|
|
43
|
-
expect(typeof _processParams).toBe('function');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should export rescale functions', async () => {
|
|
47
|
-
const { rescaleLayout, rescaleLayoutDict } = await import('../src/utils/index');
|
|
48
|
-
expect(typeof rescaleLayout).toBe('function');
|
|
49
|
-
expect(typeof rescaleLayoutDict).toBe('function');
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('should allow importing everything with wildcard', async () => {
|
|
53
|
-
const utils = await import('../src/utils/index');
|
|
54
|
-
|
|
55
|
-
// Check that key exports are available
|
|
56
|
-
expect(utils.np).toBeDefined();
|
|
57
|
-
expect(utils.RandomNumberGenerator).toBeDefined();
|
|
58
|
-
expect(utils.getNodesFromGraph).toBeDefined();
|
|
59
|
-
expect(utils._processParams).toBeDefined();
|
|
60
|
-
expect(utils.rescaleLayout).toBeDefined();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should work with destructured imports', async () => {
|
|
64
|
-
// Test that the typical usage patterns work
|
|
65
|
-
const { np, RandomNumberGenerator, getNodesFromGraph } = await import('../src/utils/index');
|
|
66
|
-
|
|
67
|
-
// Quick functional test
|
|
68
|
-
expect(np.zeros(3)).toEqual([0, 0, 0]);
|
|
69
|
-
|
|
70
|
-
const rng = new RandomNumberGenerator(42);
|
|
71
|
-
const value = rng.rand() as number;
|
|
72
|
-
expect(typeof value).toBe('number');
|
|
73
|
-
|
|
74
|
-
const nodes = getNodesFromGraph([1, 2, 3]);
|
|
75
|
-
expect(nodes).toEqual([1, 2, 3]);
|
|
76
|
-
});
|
|
77
|
-
});
|
package/test/utils-numpy.test.ts
DELETED
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for NumPy-like utility functions
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, it, expect } from 'vitest';
|
|
6
|
-
import { np } from '../src/utils/numpy';
|
|
7
|
-
|
|
8
|
-
describe('NumPy Utils', () => {
|
|
9
|
-
describe('zeros', () => {
|
|
10
|
-
it('should create 1D array of zeros', () => {
|
|
11
|
-
expect(np.zeros(3)).toEqual([0, 0, 0]);
|
|
12
|
-
expect(np.zeros(0)).toEqual([]);
|
|
13
|
-
expect(np.zeros(1)).toEqual([0]);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('should create 1D array from single-element array shape', () => {
|
|
17
|
-
expect(np.zeros([3])).toEqual([0, 0, 0]);
|
|
18
|
-
expect(np.zeros([0])).toEqual([]);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('should create 2D array of zeros', () => {
|
|
22
|
-
expect(np.zeros([2, 3])).toEqual([[0, 0, 0], [0, 0, 0]]);
|
|
23
|
-
expect(np.zeros([3, 2])).toEqual([[0, 0], [0, 0], [0, 0]]);
|
|
24
|
-
expect(np.zeros([1, 1])).toEqual([[0]]);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('should create 3D array of zeros', () => {
|
|
28
|
-
const result = np.zeros([2, 2, 2]) as number[][][];
|
|
29
|
-
expect(result).toEqual([
|
|
30
|
-
[[0, 0], [0, 0]],
|
|
31
|
-
[[0, 0], [0, 0]]
|
|
32
|
-
]);
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
describe('ones', () => {
|
|
37
|
-
it('should create 1D array of ones', () => {
|
|
38
|
-
expect(np.ones(3)).toEqual([1, 1, 1]);
|
|
39
|
-
expect(np.ones(0)).toEqual([]);
|
|
40
|
-
expect(np.ones(1)).toEqual([1]);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('should create 1D array from single-element array shape', () => {
|
|
44
|
-
expect(np.ones([3])).toEqual([1, 1, 1]);
|
|
45
|
-
expect(np.ones([0])).toEqual([]);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('should create 2D array of ones', () => {
|
|
49
|
-
expect(np.ones([2, 3])).toEqual([[1, 1, 1], [1, 1, 1]]);
|
|
50
|
-
expect(np.ones([3, 2])).toEqual([[1, 1], [1, 1], [1, 1]]);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('should create 3D array of ones', () => {
|
|
54
|
-
const result = np.ones([2, 1, 2]) as number[][][];
|
|
55
|
-
expect(result).toEqual([
|
|
56
|
-
[[1, 1]],
|
|
57
|
-
[[1, 1]]
|
|
58
|
-
]);
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
describe('linspace', () => {
|
|
63
|
-
it('should create linearly spaced array', () => {
|
|
64
|
-
const result = np.linspace(0, 1, 5);
|
|
65
|
-
expect(result).toHaveLength(5);
|
|
66
|
-
expect(result[0]).toBe(0);
|
|
67
|
-
expect(result[4]).toBe(1);
|
|
68
|
-
expect(result[2]).toBeCloseTo(0.5);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('should handle single point', () => {
|
|
72
|
-
expect(np.linspace(5, 5, 1)).toEqual([5]);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('should handle reverse range', () => {
|
|
76
|
-
const result = np.linspace(10, 0, 3);
|
|
77
|
-
expect(result).toEqual([10, 5, 0]);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should handle negative numbers', () => {
|
|
81
|
-
const result = np.linspace(-1, 1, 3);
|
|
82
|
-
expect(result).toEqual([-1, 0, 1]);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
describe('array', () => {
|
|
87
|
-
it('should copy arrays', () => {
|
|
88
|
-
const input = [1, 2, 3];
|
|
89
|
-
const result = np.array(input);
|
|
90
|
-
expect(result).toEqual(input);
|
|
91
|
-
expect(result).not.toBe(input); // different reference
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('should wrap non-arrays', () => {
|
|
95
|
-
expect(np.array(5)).toEqual([5]);
|
|
96
|
-
expect(np.array('hello')).toEqual(['hello']);
|
|
97
|
-
expect(np.array(null)).toEqual([null]);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('should handle nested arrays', () => {
|
|
101
|
-
const input = [[1, 2], [3, 4]];
|
|
102
|
-
const result = np.array(input);
|
|
103
|
-
expect(result).toEqual(input);
|
|
104
|
-
expect(result).not.toBe(input);
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
describe('repeat', () => {
|
|
109
|
-
it('should repeat single values', () => {
|
|
110
|
-
expect(np.repeat(5, 3)).toEqual([5, 5, 5]);
|
|
111
|
-
expect(np.repeat('a', 2)).toEqual(['a', 'a']);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should repeat arrays', () => {
|
|
115
|
-
expect(np.repeat([1, 2], 2)).toEqual([1, 2, 1, 2]);
|
|
116
|
-
expect(np.repeat([1, 2, 3], 3)).toEqual([1, 2, 3, 1, 2, 3, 1, 2, 3]);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it('should handle zero repeats', () => {
|
|
120
|
-
expect(np.repeat(5, 0)).toEqual([]);
|
|
121
|
-
expect(np.repeat([1, 2], 0)).toEqual([]);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it('should handle single repeat', () => {
|
|
125
|
-
expect(np.repeat([1, 2, 3], 1)).toEqual([1, 2, 3]);
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
describe('mean', () => {
|
|
130
|
-
it('should calculate mean of 1D array', () => {
|
|
131
|
-
expect(np.mean([1, 2, 3, 4, 5])).toBe(3);
|
|
132
|
-
expect(np.mean([2, 4, 6])).toBe(4);
|
|
133
|
-
expect(np.mean([10])).toBe(10);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('should calculate mean of 2D array (flatten)', () => {
|
|
137
|
-
expect(np.mean([[1, 2], [3, 4]])).toBe(2.5);
|
|
138
|
-
expect(np.mean([[1, 1], [1, 1]])).toBe(1);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it('should calculate mean along axis 0 (columns)', () => {
|
|
142
|
-
const result = np.mean([[1, 2, 3], [4, 5, 6]], 0) as number[];
|
|
143
|
-
expect(result).toEqual([2.5, 3.5, 4.5]);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('should calculate mean along axis 1 (rows)', () => {
|
|
147
|
-
const result = np.mean([[1, 2, 3], [4, 5, 6]], 1) as number[];
|
|
148
|
-
expect(result).toEqual([2, 5]);
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it('should handle empty arrays', () => {
|
|
152
|
-
expect(np.mean([])).toBeNaN();
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it('should handle nested empty arrays', () => {
|
|
156
|
-
expect(np.mean([[], []])).toBeNaN();
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
describe('add', () => {
|
|
161
|
-
it('should add two numbers', () => {
|
|
162
|
-
expect(np.add(5, 3)).toBe(8);
|
|
163
|
-
expect(np.add(-2, 7)).toBe(5);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it('should add number to array', () => {
|
|
167
|
-
expect(np.add(2, [1, 2, 3])).toEqual([3, 4, 5]);
|
|
168
|
-
expect(np.add([1, 2, 3], 10)).toEqual([11, 12, 13]);
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it('should add two arrays element-wise', () => {
|
|
172
|
-
expect(np.add([1, 2, 3], [4, 5, 6])).toEqual([5, 7, 9]);
|
|
173
|
-
expect(np.add([10, 20], [1, 2])).toEqual([11, 22]);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it('should handle negative numbers', () => {
|
|
177
|
-
expect(np.add([-1, -2], [1, 2])).toEqual([0, 0]);
|
|
178
|
-
expect(np.add(5, [-3, -7])).toEqual([2, -2]);
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
describe('subtract', () => {
|
|
183
|
-
it('should subtract two numbers', () => {
|
|
184
|
-
expect(np.subtract(8, 3)).toBe(5);
|
|
185
|
-
expect(np.subtract(-2, 7)).toBe(-9);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('should subtract number from array', () => {
|
|
189
|
-
expect(np.subtract(10, [1, 2, 3])).toEqual([9, 8, 7]);
|
|
190
|
-
expect(np.subtract([5, 6, 7], 2)).toEqual([3, 4, 5]);
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
it('should subtract two arrays element-wise', () => {
|
|
194
|
-
expect(np.subtract([5, 7, 9], [1, 2, 3])).toEqual([4, 5, 6]);
|
|
195
|
-
expect(np.subtract([10, 20], [3, 5])).toEqual([7, 15]);
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
it('should handle negative results', () => {
|
|
199
|
-
expect(np.subtract([1, 2], [5, 7])).toEqual([-4, -5]);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
describe('max', () => {
|
|
204
|
-
it('should return single number as-is', () => {
|
|
205
|
-
expect(np.max(42)).toBe(42);
|
|
206
|
-
expect(np.max(-5)).toBe(-5);
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
it('should find max in 1D array', () => {
|
|
210
|
-
expect(np.max([1, 5, 3, 9, 2])).toBe(9);
|
|
211
|
-
expect(np.max([-10, -5, -20])).toBe(-5);
|
|
212
|
-
expect(np.max([7])).toBe(7);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
it('should find max in nested arrays', () => {
|
|
216
|
-
expect(np.max([[1, 2], [3, 4]])).toBe(4);
|
|
217
|
-
expect(np.max([[10, 5], [2, 8], [1, 12]])).toBe(12);
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
it('should handle deeply nested arrays', () => {
|
|
221
|
-
expect(np.max([[[1, 2]], [[3, 4]]])).toBe(4);
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
describe('min', () => {
|
|
226
|
-
it('should return single number as-is', () => {
|
|
227
|
-
expect(np.min(42)).toBe(42);
|
|
228
|
-
expect(np.min(-5)).toBe(-5);
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
it('should find min in 1D array', () => {
|
|
232
|
-
expect(np.min([1, 5, 3, 9, 2])).toBe(1);
|
|
233
|
-
expect(np.min([-10, -5, -20])).toBe(-20);
|
|
234
|
-
expect(np.min([7])).toBe(7);
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
it('should find min in nested arrays', () => {
|
|
238
|
-
expect(np.min([[1, 2], [3, 4]])).toBe(1);
|
|
239
|
-
expect(np.min([[10, 5], [2, 8], [1, 12]])).toBe(1);
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
it('should handle deeply nested arrays', () => {
|
|
243
|
-
expect(np.min([[[1, 2]], [[3, 4]]])).toBe(1);
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
describe('norm', () => {
|
|
248
|
-
it('should calculate Euclidean norm', () => {
|
|
249
|
-
expect(np.norm([3, 4])).toBe(5); // 3-4-5 triangle
|
|
250
|
-
expect(np.norm([1, 0])).toBe(1);
|
|
251
|
-
expect(np.norm([0, 0])).toBe(0);
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
it('should handle negative values', () => {
|
|
255
|
-
expect(np.norm([-3, 4])).toBe(5);
|
|
256
|
-
expect(np.norm([-3, -4])).toBe(5);
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
it('should handle single element', () => {
|
|
260
|
-
expect(np.norm([5])).toBe(5);
|
|
261
|
-
expect(np.norm([-7])).toBe(7);
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
it('should handle higher dimensions', () => {
|
|
265
|
-
expect(np.norm([1, 2, 2])).toBeCloseTo(3); // sqrt(1 + 4 + 4) = 3
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
it('should handle empty array', () => {
|
|
269
|
-
expect(np.norm([])).toBe(0);
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
});
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for parameter processing utilities
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, it, expect } from 'vitest';
|
|
6
|
-
import { _processParams } from '../src/utils/params';
|
|
7
|
-
import { createTestGraph } from './test-utils';
|
|
8
|
-
|
|
9
|
-
describe('Parameter Utils', () => {
|
|
10
|
-
describe('_processParams', () => {
|
|
11
|
-
it('should use default center when null', () => {
|
|
12
|
-
const graph = createTestGraph([1, 2], [[1, 2]]);
|
|
13
|
-
const result = _processParams(graph, null, 2);
|
|
14
|
-
|
|
15
|
-
expect(result.G).toBe(graph);
|
|
16
|
-
expect(result.center).toEqual([0, 0]);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('should use default center when undefined', () => {
|
|
20
|
-
const nodes = [1, 2, 3];
|
|
21
|
-
const result = _processParams(nodes, null, 3);
|
|
22
|
-
|
|
23
|
-
expect(result.G).toBe(nodes);
|
|
24
|
-
expect(result.center).toEqual([0, 0, 0]);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('should preserve provided center', () => {
|
|
28
|
-
const graph = createTestGraph([1, 2], [[1, 2]]);
|
|
29
|
-
const center = [5, 10];
|
|
30
|
-
const result = _processParams(graph, center, 2);
|
|
31
|
-
|
|
32
|
-
expect(result.G).toBe(graph);
|
|
33
|
-
expect(result.center).toBe(center);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should work with array of nodes', () => {
|
|
37
|
-
const nodes = ['a', 'b', 'c'];
|
|
38
|
-
const center = [1, 2, 3];
|
|
39
|
-
const result = _processParams(nodes, center, 3);
|
|
40
|
-
|
|
41
|
-
expect(result.G).toBe(nodes);
|
|
42
|
-
expect(result.center).toBe(center);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('should throw error when center length does not match dimension', () => {
|
|
46
|
-
const graph = createTestGraph([1, 2], [[1, 2]]);
|
|
47
|
-
|
|
48
|
-
expect(() => {
|
|
49
|
-
_processParams(graph, [1, 2], 3); // center has 2 elements, dim is 3
|
|
50
|
-
}).toThrow('length of center coordinates must match dimension of layout');
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('should throw error when center is too long', () => {
|
|
54
|
-
const nodes = [1, 2, 3];
|
|
55
|
-
|
|
56
|
-
expect(() => {
|
|
57
|
-
_processParams(nodes, [1, 2, 3, 4], 2); // center has 4 elements, dim is 2
|
|
58
|
-
}).toThrow('length of center coordinates must match dimension of layout');
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should throw error when center is too short', () => {
|
|
62
|
-
const graph = createTestGraph([1], []);
|
|
63
|
-
|
|
64
|
-
expect(() => {
|
|
65
|
-
_processParams(graph, [1], 3); // center has 1 element, dim is 3
|
|
66
|
-
}).toThrow('length of center coordinates must match dimension of layout');
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('should work with 1D layouts', () => {
|
|
70
|
-
const graph = createTestGraph([1, 2], [[1, 2]]);
|
|
71
|
-
const result = _processParams(graph, [5], 1);
|
|
72
|
-
|
|
73
|
-
expect(result.center).toEqual([5]);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should work with high-dimensional layouts', () => {
|
|
77
|
-
const nodes = [1, 2, 3];
|
|
78
|
-
const center = [1, 2, 3, 4, 5];
|
|
79
|
-
const result = _processParams(nodes, center, 5);
|
|
80
|
-
|
|
81
|
-
expect(result.center).toBe(center);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('should handle empty center array for 0D (edge case)', () => {
|
|
85
|
-
const graph = createTestGraph([1], []);
|
|
86
|
-
const result = _processParams(graph, [], 0);
|
|
87
|
-
|
|
88
|
-
expect(result.center).toEqual([]);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('should create correct default center for various dimensions', () => {
|
|
92
|
-
const graph = createTestGraph([1], []);
|
|
93
|
-
|
|
94
|
-
expect(_processParams(graph, null, 1).center).toEqual([0]);
|
|
95
|
-
expect(_processParams(graph, null, 4).center).toEqual([0, 0, 0, 0]);
|
|
96
|
-
expect(_processParams(graph, null, 0).center).toEqual([]);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
});
|