@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.
Files changed (203) hide show
  1. package/dist/src/algorithms/index.d.ts +5 -0
  2. package/dist/src/algorithms/index.js +6 -0
  3. package/dist/src/algorithms/index.js.map +1 -0
  4. package/dist/src/algorithms/optimization/index.d.ts +7 -0
  5. package/dist/src/algorithms/optimization/index.js +7 -0
  6. package/dist/src/algorithms/optimization/index.js.map +1 -0
  7. package/dist/src/algorithms/optimization/kamada-kawai-solver.d.ts +32 -0
  8. package/dist/src/algorithms/optimization/kamada-kawai-solver.js +176 -0
  9. package/dist/src/algorithms/optimization/kamada-kawai-solver.js.map +1 -0
  10. package/dist/src/algorithms/optimization/lbfgs.d.ts +13 -0
  11. package/dist/src/algorithms/optimization/lbfgs.js +56 -0
  12. package/dist/src/algorithms/optimization/lbfgs.js.map +1 -0
  13. package/dist/src/algorithms/optimization/line-search.d.ts +15 -0
  14. package/dist/src/algorithms/optimization/line-search.js +37 -0
  15. package/dist/src/algorithms/optimization/line-search.js.map +1 -0
  16. package/dist/src/algorithms/optimization/types.d.ts +5 -0
  17. package/dist/src/algorithms/optimization/types.js +5 -0
  18. package/dist/src/algorithms/optimization/types.js.map +1 -0
  19. package/dist/src/algorithms/planarity/check.d.ts +17 -0
  20. package/dist/src/algorithms/planarity/check.js +30 -0
  21. package/dist/src/algorithms/planarity/check.js.map +1 -0
  22. package/dist/src/algorithms/planarity/embedding.d.ts +29 -0
  23. package/dist/src/algorithms/planarity/embedding.js +179 -0
  24. package/dist/src/algorithms/planarity/embedding.js.map +1 -0
  25. package/dist/src/algorithms/planarity/index.d.ts +7 -0
  26. package/dist/src/algorithms/planarity/index.js +8 -0
  27. package/dist/src/algorithms/planarity/index.js.map +1 -0
  28. package/dist/src/algorithms/planarity/lr-test.d.ts +15 -0
  29. package/dist/src/algorithms/planarity/lr-test.js +54 -0
  30. package/dist/src/algorithms/planarity/lr-test.js.map +1 -0
  31. package/dist/src/algorithms/planarity/special-graphs.d.ts +28 -0
  32. package/dist/src/algorithms/planarity/special-graphs.js +108 -0
  33. package/dist/src/algorithms/planarity/special-graphs.js.map +1 -0
  34. package/dist/src/generators/basic.d.ts +28 -0
  35. package/dist/src/generators/basic.js +79 -0
  36. package/dist/src/generators/basic.js.map +1 -0
  37. package/dist/src/generators/bipartite.d.ts +16 -0
  38. package/dist/src/generators/bipartite.js +40 -0
  39. package/dist/src/generators/bipartite.js.map +1 -0
  40. package/dist/src/generators/grid.d.ts +11 -0
  41. package/dist/src/generators/grid.js +37 -0
  42. package/dist/src/generators/grid.js.map +1 -0
  43. package/dist/src/generators/index.d.ts +8 -0
  44. package/dist/src/generators/index.js +9 -0
  45. package/dist/src/generators/index.js.map +1 -0
  46. package/dist/src/generators/random.d.ts +12 -0
  47. package/dist/src/generators/random.js +34 -0
  48. package/dist/src/generators/random.js.map +1 -0
  49. package/dist/src/generators/scale-free.d.ts +12 -0
  50. package/dist/src/generators/scale-free.js +62 -0
  51. package/dist/src/generators/scale-free.js.map +1 -0
  52. package/dist/src/index.d.ts +10 -0
  53. package/dist/src/index.js +15 -0
  54. package/dist/src/index.js.map +1 -0
  55. package/dist/src/layouts/basic/index.d.ts +4 -0
  56. package/dist/src/layouts/basic/index.js +5 -0
  57. package/dist/src/layouts/basic/index.js.map +1 -0
  58. package/dist/src/layouts/basic/random.d.ts +14 -0
  59. package/dist/src/layouts/basic/random.js +27 -0
  60. package/dist/src/layouts/basic/random.js.map +1 -0
  61. package/dist/src/layouts/force-directed/arf.d.ts +13 -0
  62. package/dist/src/layouts/force-directed/arf.js +103 -0
  63. package/dist/src/layouts/force-directed/arf.js.map +1 -0
  64. package/dist/src/layouts/force-directed/forceatlas2.d.ts +22 -0
  65. package/dist/src/layouts/force-directed/forceatlas2.js +340 -0
  66. package/dist/src/layouts/force-directed/forceatlas2.js.map +1 -0
  67. package/dist/src/layouts/force-directed/fruchterman-reingold.d.ts +19 -0
  68. package/dist/src/layouts/force-directed/fruchterman-reingold.js +131 -0
  69. package/dist/src/layouts/force-directed/fruchterman-reingold.js.map +1 -0
  70. package/dist/src/layouts/force-directed/index.d.ts +8 -0
  71. package/dist/src/layouts/force-directed/index.js +9 -0
  72. package/dist/src/layouts/force-directed/index.js.map +1 -0
  73. package/dist/src/layouts/force-directed/kamada-kawai.d.ts +15 -0
  74. package/dist/src/layouts/force-directed/kamada-kawai.js +87 -0
  75. package/dist/src/layouts/force-directed/kamada-kawai.js.map +1 -0
  76. package/dist/src/layouts/force-directed/spring.d.ts +19 -0
  77. package/dist/src/layouts/force-directed/spring.js +23 -0
  78. package/dist/src/layouts/force-directed/spring.js.map +1 -0
  79. package/dist/src/layouts/geometric/circular.d.ts +14 -0
  80. package/dist/src/layouts/geometric/circular.js +67 -0
  81. package/dist/src/layouts/geometric/circular.js.map +1 -0
  82. package/dist/src/layouts/geometric/index.d.ts +6 -0
  83. package/dist/src/layouts/geometric/index.js +7 -0
  84. package/dist/src/layouts/geometric/index.js.map +1 -0
  85. package/dist/src/layouts/geometric/shell.d.ts +15 -0
  86. package/dist/src/layouts/geometric/shell.js +67 -0
  87. package/dist/src/layouts/geometric/shell.js.map +1 -0
  88. package/dist/src/layouts/geometric/spiral.d.ts +16 -0
  89. package/dist/src/layouts/geometric/spiral.js +73 -0
  90. package/dist/src/layouts/geometric/spiral.js.map +1 -0
  91. package/dist/src/layouts/hierarchical/bfs.d.ts +12 -0
  92. package/dist/src/layouts/hierarchical/bfs.js +62 -0
  93. package/dist/src/layouts/hierarchical/bfs.js.map +1 -0
  94. package/dist/src/layouts/hierarchical/bipartite.d.ts +16 -0
  95. package/dist/src/layouts/hierarchical/bipartite.js +72 -0
  96. package/dist/src/layouts/hierarchical/bipartite.js.map +1 -0
  97. package/dist/src/layouts/hierarchical/index.d.ts +6 -0
  98. package/dist/src/layouts/hierarchical/index.js +7 -0
  99. package/dist/src/layouts/hierarchical/index.js.map +1 -0
  100. package/dist/src/layouts/hierarchical/multipartite.d.ts +12 -0
  101. package/dist/src/layouts/hierarchical/multipartite.js +73 -0
  102. package/dist/src/layouts/hierarchical/multipartite.js.map +1 -0
  103. package/dist/src/layouts/index.d.ts +8 -0
  104. package/dist/src/layouts/index.js +9 -0
  105. package/dist/src/layouts/index.js.map +1 -0
  106. package/dist/src/layouts/specialized/index.d.ts +5 -0
  107. package/dist/src/layouts/specialized/index.js +6 -0
  108. package/dist/src/layouts/specialized/index.js.map +1 -0
  109. package/dist/src/layouts/specialized/planar.d.ts +14 -0
  110. package/dist/src/layouts/specialized/planar.js +47 -0
  111. package/dist/src/layouts/specialized/planar.js.map +1 -0
  112. package/dist/src/layouts/specialized/spectral.d.ts +14 -0
  113. package/dist/src/layouts/specialized/spectral.js +106 -0
  114. package/dist/src/layouts/specialized/spectral.js.map +1 -0
  115. package/dist/src/types/embedding.d.ts +9 -0
  116. package/dist/src/types/embedding.js +5 -0
  117. package/dist/src/types/embedding.js.map +1 -0
  118. package/dist/src/types/graph.d.ts +10 -0
  119. package/dist/src/types/graph.js +5 -0
  120. package/dist/src/types/graph.js.map +1 -0
  121. package/dist/src/types/index.d.ts +6 -0
  122. package/dist/src/types/index.js +7 -0
  123. package/dist/src/types/index.js.map +1 -0
  124. package/dist/src/types/layout.d.ts +6 -0
  125. package/dist/src/types/layout.js +5 -0
  126. package/dist/src/types/layout.js.map +1 -0
  127. package/dist/src/utils/graph.d.ts +34 -0
  128. package/dist/src/utils/graph.js +69 -0
  129. package/dist/src/utils/graph.js.map +1 -0
  130. package/dist/src/utils/index.d.ts +8 -0
  131. package/dist/src/utils/index.js +9 -0
  132. package/dist/src/utils/index.js.map +1 -0
  133. package/dist/src/utils/numpy.d.ts +17 -0
  134. package/dist/src/utils/numpy.js +101 -0
  135. package/dist/src/utils/numpy.js.map +1 -0
  136. package/dist/src/utils/params.d.ts +17 -0
  137. package/dist/src/utils/params.js +22 -0
  138. package/dist/src/utils/params.js.map +1 -0
  139. package/dist/src/utils/random.d.ts +14 -0
  140. package/dist/src/utils/random.js +42 -0
  141. package/dist/src/utils/random.js.map +1 -0
  142. package/dist/src/utils/rescale.d.ts +21 -0
  143. package/dist/src/utils/rescale.js +194 -0
  144. package/dist/src/utils/rescale.js.map +1 -0
  145. package/dist/vitest.config.js +1 -1
  146. package/dist/vitest.config.js.map +1 -1
  147. package/package.json +19 -4
  148. package/src/layouts/force-directed/forceatlas2.ts +23 -4
  149. package/src/utils/rescale.ts +90 -15
  150. package/.env.example +0 -11
  151. package/.github/workflows/ci.yml +0 -101
  152. package/.releaserc.json +0 -22
  153. package/CHANGELOG.md +0 -52
  154. package/CLAUDE.md +0 -104
  155. package/CONTRIBUTING.md +0 -1
  156. package/DEPLOYMENT.md +0 -59
  157. package/build-examples-script.js +0 -26
  158. package/commitlint.config.js +0 -37
  159. package/examples/3d-force-directed.html +0 -611
  160. package/examples/3d-kamada-kawai.html +0 -379
  161. package/examples/3d-layout-comparison.html +0 -448
  162. package/examples/3d-spherical-layout.html +0 -319
  163. package/examples/arf-layout.html +0 -524
  164. package/examples/bfs-layout.html +0 -487
  165. package/examples/bipartite-layout.html +0 -382
  166. package/examples/circular-layout.html +0 -292
  167. package/examples/forceatlas2-layout.html +0 -588
  168. package/examples/index.html +0 -241
  169. package/examples/kamada-kawai-layout.html +0 -425
  170. package/examples/layout-helpers.js +0 -23
  171. package/examples/layout.js +0 -2304
  172. package/examples/multipartite-layout.html +0 -410
  173. package/examples/planar-layout.html +0 -388
  174. package/examples/random-layout.html +0 -328
  175. package/examples/shell-layout.html +0 -323
  176. package/examples/spectral-layout.html +0 -335
  177. package/examples/spiral-layout.html +0 -447
  178. package/examples/spring-layout.html +0 -313
  179. package/test/arf-layout.test.ts +0 -443
  180. package/test/bfs-layout.test.ts +0 -427
  181. package/test/bipartite-layout.test.ts +0 -344
  182. package/test/circular-layout.test.ts +0 -442
  183. package/test/forceatlas2-layout.test.ts +0 -405
  184. package/test/fruchterman-reingold-layout.test.ts +0 -477
  185. package/test/graph-generators.test.ts +0 -450
  186. package/test/kamada-kawai-layout.test.ts +0 -623
  187. package/test/multipartite-layout.test.ts +0 -404
  188. package/test/planar-layout.test.ts +0 -266
  189. package/test/random-layout.test.ts +0 -254
  190. package/test/rescale-layout.test.ts +0 -373
  191. package/test/shell-layout.test.ts +0 -347
  192. package/test/spectral-layout.test.ts +0 -378
  193. package/test/spiral-layout.test.ts +0 -338
  194. package/test/spring-layout.test.ts +0 -241
  195. package/test/test-utils.ts +0 -34
  196. package/test/utils-graph.test.ts +0 -155
  197. package/test/utils-index.test.ts +0 -77
  198. package/test/utils-numpy.test.ts +0 -272
  199. package/test/utils-params.test.ts +0 -99
  200. package/test/utils-random.test.ts +0 -229
  201. package/tsconfig.json +0 -16
  202. package/vite.config.js +0 -36
  203. package/vitest.config.ts +0 -30
@@ -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
- });
@@ -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
- });
@@ -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
- });