@holoscript/std 7.0.0 → 7.0.1

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 (132) hide show
  1. package/README.md +8 -0
  2. package/dist/chunk-DGUM43GV.js +11 -0
  3. package/dist/{chunk-PFX2JM4X.js → chunk-FAMOLKH3.js} +2 -1
  4. package/dist/{chunk-PFX2JM4X.js.map → chunk-FAMOLKH3.js.map} +1 -1
  5. package/dist/{chunk-DZHAVOCH.js → chunk-SOKH6FJ7.js} +31 -6
  6. package/dist/chunk-SOKH6FJ7.js.map +1 -0
  7. package/dist/collections.cjs +1 -0
  8. package/dist/collections.cjs.map +1 -1
  9. package/dist/collections.js +2 -2
  10. package/dist/fs/fs.d.ts.map +1 -1
  11. package/dist/fs/index.cjs +221 -8510
  12. package/dist/fs/index.cjs.map +1 -1
  13. package/dist/fs/index.js +832 -118
  14. package/dist/fs/index.js.map +1 -1
  15. package/dist/fs/sandbox.d.ts +49 -0
  16. package/dist/fs/sandbox.d.ts.map +1 -0
  17. package/dist/index.cjs +3494 -12672
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.ts +0 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +17 -7
  22. package/dist/index.js.map +1 -1
  23. package/dist/math.cjs +18 -3
  24. package/dist/math.cjs.map +1 -1
  25. package/dist/math.js +2 -2
  26. package/dist/string.js +1 -1
  27. package/dist/time.js +1 -1
  28. package/dist/traits/EconomicPrimitives.js +1 -1
  29. package/dist/traits/EconomicTraits.js +1 -1
  30. package/dist/types.d.ts.map +1 -1
  31. package/package.json +19 -9
  32. package/dist/__tests__/EconomicPrimitives.test.d.ts +0 -2
  33. package/dist/__tests__/EconomicPrimitives.test.d.ts.map +0 -1
  34. package/dist/__tests__/EconomicTraits.test.d.ts +0 -2
  35. package/dist/__tests__/EconomicTraits.test.d.ts.map +0 -1
  36. package/dist/__tests__/SimulationLabPrimitives.test.d.ts +0 -2
  37. package/dist/__tests__/SimulationLabPrimitives.test.d.ts.map +0 -1
  38. package/dist/__tests__/collections.test.d.ts +0 -2
  39. package/dist/__tests__/collections.test.d.ts.map +0 -1
  40. package/dist/__tests__/events.test.d.ts +0 -2
  41. package/dist/__tests__/events.test.d.ts.map +0 -1
  42. package/dist/__tests__/index.test.d.ts +0 -2
  43. package/dist/__tests__/index.test.d.ts.map +0 -1
  44. package/dist/__tests__/materials.test.d.ts +0 -2
  45. package/dist/__tests__/materials.test.d.ts.map +0 -1
  46. package/dist/__tests__/math.test.d.ts +0 -2
  47. package/dist/__tests__/math.test.d.ts.map +0 -1
  48. package/dist/__tests__/physics.test.d.ts +0 -2
  49. package/dist/__tests__/physics.test.d.ts.map +0 -1
  50. package/dist/__tests__/spatial.test.d.ts +0 -2
  51. package/dist/__tests__/spatial.test.d.ts.map +0 -1
  52. package/dist/__tests__/standard-library-fundamentals.test.d.ts +0 -2
  53. package/dist/__tests__/standard-library-fundamentals.test.d.ts.map +0 -1
  54. package/dist/__tests__/string-and-time-utilities.test.d.ts +0 -2
  55. package/dist/__tests__/string-and-time-utilities.test.d.ts.map +0 -1
  56. package/dist/__tests__/string-decoupled.test.d.ts +0 -2
  57. package/dist/__tests__/string-decoupled.test.d.ts.map +0 -1
  58. package/dist/__tests__/string.test.d.ts +0 -2
  59. package/dist/__tests__/string.test.d.ts.map +0 -1
  60. package/dist/__tests__/time.test.d.ts +0 -2
  61. package/dist/__tests__/time.test.d.ts.map +0 -1
  62. package/dist/chunk-DZHAVOCH.js.map +0 -1
  63. package/dist/chunk-PR4QN5HX.js +0 -43
  64. package/dist/chunk-XBA4ARST.js +0 -9313
  65. package/dist/chunk-XBA4ARST.js.map +0 -1
  66. package/dist/fs/__tests__/file-watch-system.test.d.ts +0 -2
  67. package/dist/fs/__tests__/file-watch-system.test.d.ts.map +0 -1
  68. package/dist/fs/__tests__/path-utilities.test.d.ts +0 -2
  69. package/dist/fs/__tests__/path-utilities.test.d.ts.map +0 -1
  70. package/dist/fs/__tests__/path.test.d.ts +0 -2
  71. package/dist/fs/__tests__/path.test.d.ts.map +0 -1
  72. package/dist/string.basic.test.d.ts +0 -5
  73. package/dist/string.basic.test.d.ts.map +0 -1
  74. package/dist/string.test.d.ts +0 -5
  75. package/dist/string.test.d.ts.map +0 -1
  76. package/dist/traits/__tests__/ARTraits.test.d.ts +0 -2
  77. package/dist/traits/__tests__/ARTraits.test.d.ts.map +0 -1
  78. package/dist/traits/__tests__/EconomicPrimitives.test.d.ts +0 -2
  79. package/dist/traits/__tests__/EconomicPrimitives.test.d.ts.map +0 -1
  80. package/dist/traits/__tests__/EconomicTraits.test.d.ts +0 -2
  81. package/dist/traits/__tests__/EconomicTraits.test.d.ts.map +0 -1
  82. package/error-utf8.log +0 -6
  83. package/error.log +0 -0
  84. package/src/__tests__/EconomicPrimitives.test.ts +0 -690
  85. package/src/__tests__/EconomicTraits.test.ts +0 -425
  86. package/src/__tests__/SimulationLabPrimitives.test.ts +0 -415
  87. package/src/__tests__/collections.test.ts +0 -182
  88. package/src/__tests__/events.test.ts +0 -135
  89. package/src/__tests__/index.test.ts +0 -14
  90. package/src/__tests__/materials.test.ts +0 -84
  91. package/src/__tests__/math.test.ts +0 -246
  92. package/src/__tests__/physics.test.ts +0 -83
  93. package/src/__tests__/spatial.test.ts +0 -333
  94. package/src/__tests__/standard-library-fundamentals.test.ts +0 -1318
  95. package/src/__tests__/string-and-time-utilities.test.ts +0 -1070
  96. package/src/__tests__/string-decoupled.test.ts +0 -13
  97. package/src/__tests__/string.test.ts +0 -164
  98. package/src/__tests__/time.test.ts +0 -110
  99. package/src/collections.ts +0 -850
  100. package/src/events.ts +0 -88
  101. package/src/fs/__tests__/file-watch-system.test.ts +0 -675
  102. package/src/fs/__tests__/path-utilities.test.ts +0 -375
  103. package/src/fs/__tests__/path.test.ts +0 -287
  104. package/src/fs/fs.ts +0 -692
  105. package/src/fs/index.ts +0 -194
  106. package/src/fs/path.ts +0 -310
  107. package/src/fs/watch.ts +0 -413
  108. package/src/index.ts +0 -476
  109. package/src/materials.ts +0 -109
  110. package/src/math.ts +0 -674
  111. package/src/physics.ts +0 -141
  112. package/src/spatial.ts +0 -320
  113. package/src/string.basic.test.ts +0 -14
  114. package/src/string.test.ts +0 -335
  115. package/src/string.ts +0 -531
  116. package/src/time.ts +0 -621
  117. package/src/traits/ARTraits.ts +0 -103
  118. package/src/traits/EconomicPrimitives.ts +0 -755
  119. package/src/traits/EconomicTraits.ts +0 -552
  120. package/src/traits/IoTTraits.ts +0 -102
  121. package/src/traits/SimulationLabPrimitives.ts +0 -650
  122. package/src/traits/SimulationLabTraits.ts +0 -191
  123. package/src/traits/VRRTraits.ts +0 -326
  124. package/src/traits/__tests__/ARTraits.test.ts +0 -8
  125. package/src/traits/__tests__/EconomicPrimitives.test.ts +0 -14
  126. package/src/traits/__tests__/EconomicTraits.test.ts +0 -16
  127. package/src/types.ts +0 -418
  128. package/std_error.log +0 -5
  129. package/tsconfig.json +0 -18
  130. package/tsup.config.ts +0 -20
  131. package/vitest.config.ts +0 -10
  132. /package/dist/{chunk-PR4QN5HX.js.map → chunk-DGUM43GV.js.map} +0 -0
@@ -1,415 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import {
3
- mean,
4
- variance,
5
- standardDeviation,
6
- standardError,
7
- cohensD,
8
- tTest,
9
- oneSampleTTest,
10
- mannWhitneyU,
11
- chiSquaredTest,
12
- expandSweep,
13
- generateSweepCombinations,
14
- extractMetric,
15
- groupByParameter,
16
- summarizeMetrics,
17
- isParameterRange,
18
- } from '../traits/SimulationLabPrimitives.js';
19
- import type {
20
- ParameterRange,
21
- ParameterSet,
22
- SimulationMetrics,
23
- } from '../traits/SimulationLabPrimitives.js';
24
- import {
25
- SimulationLabTraits,
26
- getSimulationTraitNames,
27
- getSimulationTrait,
28
- } from '../traits/SimulationLabTraits.js';
29
-
30
- // =============================================================================
31
- // BASIC STATISTICS
32
- // =============================================================================
33
-
34
- describe('Basic Statistics', () => {
35
- describe('mean', () => {
36
- it('should return 0 for empty array', () => {
37
- expect(mean([])).toBe(0);
38
- });
39
- it('should calculate correct mean', () => {
40
- expect(mean([1, 2, 3, 4, 5])).toBe(3);
41
- });
42
- it('should handle single element', () => {
43
- expect(mean([42])).toBe(42);
44
- });
45
- it('should handle negative numbers', () => {
46
- expect(mean([-10, 10])).toBe(0);
47
- });
48
- });
49
-
50
- describe('variance', () => {
51
- it('should return 0 for single element', () => {
52
- expect(variance([5])).toBe(0);
53
- });
54
- it('should return 0 for identical values', () => {
55
- expect(variance([3, 3, 3, 3])).toBe(0);
56
- });
57
- it('should calculate sample variance with Bessel correction', () => {
58
- // [1,2,3,4,5]: mean=3, sum of sq diffs=10, n-1=4 -> var=2.5
59
- expect(variance([1, 2, 3, 4, 5])).toBe(2.5);
60
- });
61
- });
62
-
63
- describe('standardDeviation', () => {
64
- it('should be sqrt of variance', () => {
65
- const data = [1, 2, 3, 4, 5];
66
- expect(standardDeviation(data)).toBeCloseTo(Math.sqrt(2.5), 10);
67
- });
68
- });
69
-
70
- describe('standardError', () => {
71
- it('should return 0 for empty array', () => {
72
- expect(standardError([])).toBe(0);
73
- });
74
- it('should equal sd / sqrt(n)', () => {
75
- const data = [1, 2, 3, 4, 5];
76
- const sd = standardDeviation(data);
77
- expect(standardError(data)).toBeCloseTo(sd / Math.sqrt(5), 10);
78
- });
79
- });
80
-
81
- describe('cohensD', () => {
82
- it('should return 0 for identical groups', () => {
83
- expect(cohensD([5, 5, 5], [5, 5, 5])).toBe(0);
84
- });
85
- it('should return positive d when group1 > group2', () => {
86
- const d = cohensD([10, 11, 12], [1, 2, 3]);
87
- expect(d).toBeGreaterThan(0);
88
- });
89
- it('should return large d for well-separated groups', () => {
90
- const d = cohensD([100, 101, 102], [1, 2, 3]);
91
- expect(Math.abs(d)).toBeGreaterThan(2); // Large effect
92
- });
93
- it('should handle insufficient data', () => {
94
- expect(cohensD([5], [3])).toBe(0);
95
- });
96
- });
97
- });
98
-
99
- // =============================================================================
100
- // PARAMETER SWEEP
101
- // =============================================================================
102
-
103
- describe('Parameter Sweep', () => {
104
- describe('isParameterRange', () => {
105
- it('should identify range', () => {
106
- const r: ParameterRange = { name: 'x', min: 0, max: 10, step: 1 };
107
- expect(isParameterRange(r)).toBe(true);
108
- });
109
- it('should reject set', () => {
110
- const s: ParameterSet = { name: 'x', values: [1, 2, 3] };
111
- expect(isParameterRange(s)).toBe(false);
112
- });
113
- });
114
-
115
- describe('expandSweep', () => {
116
- it('should expand range correctly', () => {
117
- const r: ParameterRange = { name: 'x', min: 0, max: 1, step: 0.5 };
118
- const values = expandSweep(r);
119
- expect(values).toEqual([0, 0.5, 1.0]);
120
- });
121
- it('should return values for discrete set', () => {
122
- const s: ParameterSet = { name: 'x', values: [1, 5, 10] };
123
- expect(expandSweep(s)).toEqual([1, 5, 10]);
124
- });
125
- it('should handle zero step', () => {
126
- const r: ParameterRange = { name: 'x', min: 5, max: 10, step: 0 };
127
- expect(expandSweep(r)).toEqual([5]);
128
- });
129
- it('should handle reversed range', () => {
130
- const r: ParameterRange = { name: 'x', min: 10, max: 5, step: 1 };
131
- expect(expandSweep(r)).toEqual([]);
132
- });
133
- it('should handle single-value range', () => {
134
- const r: ParameterRange = { name: 'x', min: 5, max: 5, step: 1 };
135
- expect(expandSweep(r)).toEqual([5]);
136
- });
137
- });
138
-
139
- describe('generateSweepCombinations', () => {
140
- it('should return [{}] for empty sweeps', () => {
141
- expect(generateSweepCombinations([])).toEqual([{}]);
142
- });
143
- it('should generate all values for single sweep', () => {
144
- const combos = generateSweepCombinations([{ name: 'x', values: [1, 2, 3] }]);
145
- expect(combos).toEqual([{ x: 1 }, { x: 2 }, { x: 3 }]);
146
- });
147
- it('should generate Cartesian product for two sweeps', () => {
148
- const combos = generateSweepCombinations([
149
- { name: 'x', values: [1, 2] },
150
- { name: 'y', values: [10, 20] },
151
- ]);
152
- expect(combos).toHaveLength(4);
153
- expect(combos).toContainEqual({ x: 1, y: 10 });
154
- expect(combos).toContainEqual({ x: 1, y: 20 });
155
- expect(combos).toContainEqual({ x: 2, y: 10 });
156
- expect(combos).toContainEqual({ x: 2, y: 20 });
157
- });
158
- it('should handle three sweeps', () => {
159
- const combos = generateSweepCombinations([
160
- { name: 'a', values: [1, 2] },
161
- { name: 'b', values: [3, 4] },
162
- { name: 'c', values: [5, 6] },
163
- ]);
164
- expect(combos).toHaveLength(8); // 2 * 2 * 2
165
- });
166
- });
167
- });
168
-
169
- // =============================================================================
170
- // STATISTICAL TESTS
171
- // =============================================================================
172
-
173
- describe('Statistical Tests', () => {
174
- describe('tTest (Welch)', () => {
175
- it('should detect significantly different means', () => {
176
- const group1 = Array.from({ length: 100 }, (_, i) => 100 + Math.sin(i));
177
- const group2 = Array.from({ length: 100 }, (_, i) => 50 + Math.sin(i));
178
- const result = tTest(group1, group2);
179
- expect(result.significant).toBe(true);
180
- expect(result.pValue).toBeLessThan(0.05);
181
- expect(result.testName).toBe('welch_t_test');
182
- });
183
-
184
- it('should NOT detect difference in identical groups', () => {
185
- const data = Array.from({ length: 50 }, (_, i) => Math.sin(i) * 10);
186
- const result = tTest(data, data);
187
- expect(result.significant).toBe(false);
188
- expect(result.pValue).toBeGreaterThan(0.05);
189
- });
190
-
191
- it('should handle small samples gracefully', () => {
192
- const result = tTest([1], [2]);
193
- expect(result.pValue).toBe(1);
194
- expect(result.significant).toBe(false);
195
- });
196
-
197
- it('should report positive effect size when group1 > group2', () => {
198
- const g1 = [100, 110, 120, 130, 140];
199
- const g2 = [10, 20, 30, 40, 50];
200
- const result = tTest(g1, g2);
201
- expect(result.effectSize).toBeGreaterThan(0);
202
- });
203
-
204
- it('should respect directional hypotheses', () => {
205
- const high = Array.from({ length: 50 }, () => 100 + Math.random() * 5);
206
- const low = Array.from({ length: 50 }, () => 50 + Math.random() * 5);
207
- const greater = tTest(high, low, 0.05, 'greater');
208
- const less = tTest(high, low, 0.05, 'less');
209
- expect(greater.pValue).toBeLessThan(less.pValue);
210
- });
211
- });
212
-
213
- describe('oneSampleTTest', () => {
214
- it('should detect mean different from population', () => {
215
- const data = Array.from({ length: 100 }, (_, i) => 50 + Math.sin(i));
216
- const result = oneSampleTTest(data, 0);
217
- expect(result.significant).toBe(true);
218
- expect(result.testName).toBe('one_sample_t_test');
219
- });
220
-
221
- it('should NOT reject when sample comes from population', () => {
222
- // Data centered around 100
223
- const data = Array.from({ length: 100 }, (_, i) => 100 + Math.sin(i) * 0.01);
224
- const result = oneSampleTTest(data, 100);
225
- expect(result.significant).toBe(false);
226
- });
227
- });
228
-
229
- describe('mannWhitneyU', () => {
230
- it('should detect difference in ranked groups', () => {
231
- const high = [90, 91, 92, 93, 94, 95, 96, 97, 98, 99];
232
- const low = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
233
- const result = mannWhitneyU(high, low);
234
- expect(result.significant).toBe(true);
235
- expect(result.testName).toBe('mann_whitney_u');
236
- });
237
-
238
- it('should handle empty groups', () => {
239
- const result = mannWhitneyU([], [1, 2, 3]);
240
- expect(result.significant).toBe(false);
241
- expect(result.pValue).toBe(1);
242
- });
243
-
244
- it('should report effect size', () => {
245
- const high = [90, 91, 92, 93, 94];
246
- const low = [1, 2, 3, 4, 5];
247
- const result = mannWhitneyU(high, low);
248
- expect(Math.abs(result.effectSize)).toBeGreaterThan(0.5);
249
- });
250
- });
251
-
252
- describe('chiSquaredTest', () => {
253
- it('should NOT reject when observed matches expected', () => {
254
- const observed = [50, 50, 50, 50];
255
- const expected = [50, 50, 50, 50];
256
- const result = chiSquaredTest(observed, expected);
257
- expect(result.significant).toBe(false);
258
- expect(result.statistic).toBe(0);
259
- });
260
-
261
- it('should reject when observed differs significantly from expected', () => {
262
- const observed = [100, 10, 10, 10];
263
- const expected = [32.5, 32.5, 32.5, 32.5];
264
- const result = chiSquaredTest(observed, expected);
265
- expect(result.significant).toBe(true);
266
- });
267
-
268
- it('should handle mismatched lengths', () => {
269
- const result = chiSquaredTest([1, 2], [1]);
270
- expect(result.significant).toBe(false);
271
- expect(result.sampleSize).toBe(0);
272
- });
273
-
274
- it('should calculate Cramers V effect size', () => {
275
- const observed = [100, 10, 10, 10];
276
- const expected = [32.5, 32.5, 32.5, 32.5];
277
- const result = chiSquaredTest(observed, expected);
278
- expect(result.effectSize).toBeGreaterThan(0);
279
- });
280
- });
281
- });
282
-
283
- // =============================================================================
284
- // METRIC AGGREGATION
285
- // =============================================================================
286
-
287
- describe('Metric Aggregation', () => {
288
- const mockMetrics: SimulationMetrics[] = [
289
- { values: { score: 100, time: 5 }, seed: 1, params: { difficulty: 1 }, durationMs: 10 },
290
- { values: { score: 120, time: 6 }, seed: 2, params: { difficulty: 1 }, durationMs: 12 },
291
- { values: { score: 80, time: 8 }, seed: 3, params: { difficulty: 2 }, durationMs: 15 },
292
- { values: { score: 70, time: 9 }, seed: 4, params: { difficulty: 2 }, durationMs: 14 },
293
- ];
294
-
295
- describe('extractMetric', () => {
296
- it('should extract named metric values', () => {
297
- expect(extractMetric(mockMetrics, 'score')).toEqual([100, 120, 80, 70]);
298
- });
299
- it('should return empty for unknown metric', () => {
300
- expect(extractMetric(mockMetrics, 'unknown')).toEqual([]);
301
- });
302
- });
303
-
304
- describe('groupByParameter', () => {
305
- it('should group by parameter value', () => {
306
- const groups = groupByParameter(mockMetrics, 'difficulty');
307
- expect(groups.size).toBe(2);
308
- expect(groups.get(1)!).toHaveLength(2);
309
- expect(groups.get(2)!).toHaveLength(2);
310
- });
311
- it('should handle missing parameter', () => {
312
- const groups = groupByParameter(mockMetrics, 'nonexistent');
313
- expect(groups.size).toBe(0);
314
- });
315
- });
316
-
317
- describe('summarizeMetrics', () => {
318
- it('should produce correct summary', () => {
319
- const summary = summarizeMetrics(mockMetrics, 'score');
320
- expect(summary.n).toBe(4);
321
- expect(summary.mean).toBeCloseTo(92.5, 1);
322
- expect(summary.min).toBe(70);
323
- expect(summary.max).toBe(120);
324
- expect(summary.std).toBeGreaterThan(0);
325
- });
326
- it('should handle missing metric', () => {
327
- const summary = summarizeMetrics(mockMetrics, 'nonexistent');
328
- expect(summary.n).toBe(0);
329
- });
330
- });
331
- });
332
-
333
- // =============================================================================
334
- // TRAIT DEFINITIONS
335
- // =============================================================================
336
-
337
- describe('SimulationLab Traits', () => {
338
- it('should define @simulation_lab trait', () => {
339
- expect(SimulationLabTraits.simulation_lab).toBeDefined();
340
- expect(SimulationLabTraits.simulation_lab.name).toBe('@simulation_lab');
341
- });
342
-
343
- it('should require hypothesis and metrics params', () => {
344
- const trait = SimulationLabTraits.simulation_lab;
345
- expect(trait.params!.hypothesis.required).toBe(true);
346
- expect(trait.params!.metrics.required).toBe(true);
347
- });
348
-
349
- it('should validate correct params', () => {
350
- const valid = SimulationLabTraits.simulation_lab.validator!({
351
- hypothesis: 'Test hypothesis',
352
- metrics: ['score'],
353
- epochs: 100,
354
- confidence_level: 0.95,
355
- direction: 'greater',
356
- });
357
- expect(valid).toBe(true);
358
- });
359
-
360
- it('should reject missing hypothesis', () => {
361
- const invalid = SimulationLabTraits.simulation_lab.validator!({
362
- metrics: ['score'],
363
- });
364
- expect(invalid).toBe(false);
365
- });
366
-
367
- it('should reject empty metrics', () => {
368
- const invalid = SimulationLabTraits.simulation_lab.validator!({
369
- hypothesis: 'Test',
370
- metrics: [],
371
- });
372
- expect(invalid).toBe(false);
373
- });
374
-
375
- it('should reject invalid direction', () => {
376
- const invalid = SimulationLabTraits.simulation_lab.validator!({
377
- hypothesis: 'Test',
378
- metrics: ['x'],
379
- direction: 'sideways',
380
- });
381
- expect(invalid).toBe(false);
382
- });
383
-
384
- it('should compose with all economic traits', () => {
385
- const trait = SimulationLabTraits.simulation_lab;
386
- expect(trait.composesWith).toContain('@tradeable');
387
- expect(trait.composesWith).toContain('@pid_controlled');
388
- expect(trait.composesWith).toContain('@bonding_curved');
389
- });
390
-
391
- it('should use worker thread for batch execution', () => {
392
- const hints = SimulationLabTraits.simulation_lab.compiler_hints;
393
- expect(hints?.thread_safety).toBe('worker_thread');
394
- expect(hints?.batch_mode).toBe(true);
395
- });
396
-
397
- describe('getSimulationTraitNames', () => {
398
- it('should return trait names', () => {
399
- const names = getSimulationTraitNames();
400
- expect(names).toContain('@simulation_lab');
401
- });
402
- });
403
-
404
- describe('getSimulationTrait', () => {
405
- it('should find by name with @', () => {
406
- expect(getSimulationTrait('@simulation_lab')).toBeDefined();
407
- });
408
- it('should find by name without @', () => {
409
- expect(getSimulationTrait('simulation_lab')).toBeDefined();
410
- });
411
- it('should return undefined for unknown', () => {
412
- expect(getSimulationTrait('@unknown')).toBeUndefined();
413
- });
414
- });
415
- });
@@ -1,182 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { List } from '../collections.js';
3
-
4
- describe('List', () => {
5
- describe('construction', () => {
6
- it('should create empty list', () => {
7
- const list = new List<number>();
8
- expect(list.length).toBe(0);
9
- expect(list.isEmpty).toBe(true);
10
- });
11
-
12
- it('should create from array', () => {
13
- const list = new List([1, 2, 3]);
14
- expect(list.length).toBe(3);
15
- });
16
-
17
- it('should create with List.of()', () => {
18
- const list = List.of(1, 2, 3);
19
- expect(list.length).toBe(3);
20
- });
21
-
22
- it('should create with List.from()', () => {
23
- const list = List.from([1, 2, 3]);
24
- expect(list.length).toBe(3);
25
- });
26
- });
27
-
28
- describe('List.range()', () => {
29
- it('should create range with positive step', () => {
30
- const list = List.range(0, 5, 1);
31
- expect(list.toArray()).toEqual([0, 1, 2, 3, 4]);
32
- });
33
-
34
- it('should create range with default step', () => {
35
- const list = List.range(0, 3);
36
- expect(list.toArray()).toEqual([0, 1, 2]);
37
- });
38
-
39
- it('should create range with custom step', () => {
40
- const list = List.range(0, 10, 2);
41
- expect(list.toArray()).toEqual([0, 2, 4, 6, 8]);
42
- });
43
-
44
- it('should create range with negative step', () => {
45
- const list = List.range(5, 0, -1);
46
- expect(list.toArray()).toEqual([5, 4, 3, 2, 1]);
47
- });
48
- });
49
-
50
- describe('List.repeat()', () => {
51
- it('should create list with repeated values', () => {
52
- const list = List.repeat('a', 3);
53
- expect(list.toArray()).toEqual(['a', 'a', 'a']);
54
- });
55
-
56
- it('should create empty list with count 0', () => {
57
- const list = List.repeat('a', 0);
58
- expect(list.isEmpty).toBe(true);
59
- });
60
- });
61
-
62
- describe('accessors', () => {
63
- const list = List.of(10, 20, 30, 40, 50);
64
-
65
- it('should get element by positive index', () => {
66
- expect(list.get(0)).toBe(10);
67
- expect(list.get(2)).toBe(30);
68
- });
69
-
70
- it('should get element by negative index', () => {
71
- expect(list.get(-1)).toBe(50);
72
- expect(list.get(-2)).toBe(40);
73
- });
74
-
75
- it('should return undefined for out of bounds', () => {
76
- expect(list.get(10)).toBeUndefined();
77
- });
78
-
79
- it('should get first element', () => {
80
- expect(list.first()).toBe(10);
81
- });
82
-
83
- it('should get last element', () => {
84
- expect(list.last()).toBe(50);
85
- });
86
-
87
- it('should return undefined for first/last on empty list', () => {
88
- const empty = new List<number>();
89
- expect(empty.first()).toBeUndefined();
90
- expect(empty.last()).toBeUndefined();
91
- });
92
- });
93
-
94
- describe('map', () => {
95
- it('should map over elements', () => {
96
- const list = List.of(1, 2, 3);
97
- const doubled = list.map((x) => x * 2);
98
- expect(doubled.toArray()).toEqual([2, 4, 6]);
99
- });
100
-
101
- it('should receive index in map callback', () => {
102
- const list = List.of('a', 'b', 'c');
103
- const indexed = list.map((_, i) => i);
104
- expect(indexed.toArray()).toEqual([0, 1, 2]);
105
- });
106
-
107
- it('should return new List instance', () => {
108
- const list = List.of(1, 2, 3);
109
- const mapped = list.map((x) => x);
110
- expect(mapped).not.toBe(list);
111
- });
112
- });
113
-
114
- describe('filter', () => {
115
- it('should filter elements', () => {
116
- const list = List.of(1, 2, 3, 4, 5);
117
- const evens = list.filter((x) => x % 2 === 0);
118
- expect(evens.toArray()).toEqual([2, 4]);
119
- });
120
-
121
- it('should return empty list when nothing matches', () => {
122
- const list = List.of(1, 3, 5);
123
- const evens = list.filter((x) => x % 2 === 0);
124
- expect(evens.isEmpty).toBe(true);
125
- });
126
- });
127
-
128
- describe('flatMap', () => {
129
- it('should flatMap with arrays', () => {
130
- const list = List.of(1, 2, 3);
131
- const result = list.flatMap((x) => [x, x * 10]);
132
- expect(result.toArray()).toEqual([1, 10, 2, 20, 3, 30]);
133
- });
134
-
135
- it('should flatMap with Lists', () => {
136
- const list = List.of(1, 2);
137
- const result = list.flatMap((x) => List.of(x, x + 1));
138
- expect(result.toArray()).toEqual([1, 2, 2, 3]);
139
- });
140
- });
141
-
142
- describe('reduce', () => {
143
- it('should reduce with initial value', () => {
144
- const list = List.of(1, 2, 3, 4);
145
- const sum = list.reduce((acc, x) => acc + x, 0);
146
- expect(sum).toBe(10);
147
- });
148
- });
149
-
150
- describe('immutability', () => {
151
- it('operations should return new List instances', () => {
152
- const original = List.of(1, 2, 3);
153
- const mapped = original.map((x) => x * 2);
154
- const filtered = original.filter((x) => x > 1);
155
-
156
- expect(original.toArray()).toEqual([1, 2, 3]);
157
- expect(mapped.toArray()).toEqual([2, 4, 6]);
158
- expect(filtered.toArray()).toEqual([2, 3]);
159
- });
160
- });
161
-
162
- describe('toArray', () => {
163
- it('should return array copy', () => {
164
- const list = List.of(1, 2, 3);
165
- const arr = list.toArray();
166
- expect(arr).toEqual([1, 2, 3]);
167
- arr.push(4);
168
- expect(list.length).toBe(3); // Original unchanged
169
- });
170
- });
171
-
172
- describe('iteration', () => {
173
- it('should be iterable', () => {
174
- const list = List.of(1, 2, 3);
175
- const result: number[] = [];
176
- for (const item of list) {
177
- result.push(item);
178
- }
179
- expect(result).toEqual([1, 2, 3]);
180
- });
181
- });
182
- });