@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.
- package/README.md +8 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/{chunk-PFX2JM4X.js → chunk-FAMOLKH3.js} +2 -1
- package/dist/{chunk-PFX2JM4X.js.map → chunk-FAMOLKH3.js.map} +1 -1
- package/dist/{chunk-DZHAVOCH.js → chunk-SOKH6FJ7.js} +31 -6
- package/dist/chunk-SOKH6FJ7.js.map +1 -0
- package/dist/collections.cjs +1 -0
- package/dist/collections.cjs.map +1 -1
- package/dist/collections.js +2 -2
- package/dist/fs/fs.d.ts.map +1 -1
- package/dist/fs/index.cjs +221 -8510
- package/dist/fs/index.cjs.map +1 -1
- package/dist/fs/index.js +832 -118
- package/dist/fs/index.js.map +1 -1
- package/dist/fs/sandbox.d.ts +49 -0
- package/dist/fs/sandbox.d.ts.map +1 -0
- package/dist/index.cjs +3494 -12672
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/dist/math.cjs +18 -3
- package/dist/math.cjs.map +1 -1
- package/dist/math.js +2 -2
- package/dist/string.js +1 -1
- package/dist/time.js +1 -1
- package/dist/traits/EconomicPrimitives.js +1 -1
- package/dist/traits/EconomicTraits.js +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +19 -9
- package/dist/__tests__/EconomicPrimitives.test.d.ts +0 -2
- package/dist/__tests__/EconomicPrimitives.test.d.ts.map +0 -1
- package/dist/__tests__/EconomicTraits.test.d.ts +0 -2
- package/dist/__tests__/EconomicTraits.test.d.ts.map +0 -1
- package/dist/__tests__/SimulationLabPrimitives.test.d.ts +0 -2
- package/dist/__tests__/SimulationLabPrimitives.test.d.ts.map +0 -1
- package/dist/__tests__/collections.test.d.ts +0 -2
- package/dist/__tests__/collections.test.d.ts.map +0 -1
- package/dist/__tests__/events.test.d.ts +0 -2
- package/dist/__tests__/events.test.d.ts.map +0 -1
- package/dist/__tests__/index.test.d.ts +0 -2
- package/dist/__tests__/index.test.d.ts.map +0 -1
- package/dist/__tests__/materials.test.d.ts +0 -2
- package/dist/__tests__/materials.test.d.ts.map +0 -1
- package/dist/__tests__/math.test.d.ts +0 -2
- package/dist/__tests__/math.test.d.ts.map +0 -1
- package/dist/__tests__/physics.test.d.ts +0 -2
- package/dist/__tests__/physics.test.d.ts.map +0 -1
- package/dist/__tests__/spatial.test.d.ts +0 -2
- package/dist/__tests__/spatial.test.d.ts.map +0 -1
- package/dist/__tests__/standard-library-fundamentals.test.d.ts +0 -2
- package/dist/__tests__/standard-library-fundamentals.test.d.ts.map +0 -1
- package/dist/__tests__/string-and-time-utilities.test.d.ts +0 -2
- package/dist/__tests__/string-and-time-utilities.test.d.ts.map +0 -1
- package/dist/__tests__/string-decoupled.test.d.ts +0 -2
- package/dist/__tests__/string-decoupled.test.d.ts.map +0 -1
- package/dist/__tests__/string.test.d.ts +0 -2
- package/dist/__tests__/string.test.d.ts.map +0 -1
- package/dist/__tests__/time.test.d.ts +0 -2
- package/dist/__tests__/time.test.d.ts.map +0 -1
- package/dist/chunk-DZHAVOCH.js.map +0 -1
- package/dist/chunk-PR4QN5HX.js +0 -43
- package/dist/chunk-XBA4ARST.js +0 -9313
- package/dist/chunk-XBA4ARST.js.map +0 -1
- package/dist/fs/__tests__/file-watch-system.test.d.ts +0 -2
- package/dist/fs/__tests__/file-watch-system.test.d.ts.map +0 -1
- package/dist/fs/__tests__/path-utilities.test.d.ts +0 -2
- package/dist/fs/__tests__/path-utilities.test.d.ts.map +0 -1
- package/dist/fs/__tests__/path.test.d.ts +0 -2
- package/dist/fs/__tests__/path.test.d.ts.map +0 -1
- package/dist/string.basic.test.d.ts +0 -5
- package/dist/string.basic.test.d.ts.map +0 -1
- package/dist/string.test.d.ts +0 -5
- package/dist/string.test.d.ts.map +0 -1
- package/dist/traits/__tests__/ARTraits.test.d.ts +0 -2
- package/dist/traits/__tests__/ARTraits.test.d.ts.map +0 -1
- package/dist/traits/__tests__/EconomicPrimitives.test.d.ts +0 -2
- package/dist/traits/__tests__/EconomicPrimitives.test.d.ts.map +0 -1
- package/dist/traits/__tests__/EconomicTraits.test.d.ts +0 -2
- package/dist/traits/__tests__/EconomicTraits.test.d.ts.map +0 -1
- package/error-utf8.log +0 -6
- package/error.log +0 -0
- package/src/__tests__/EconomicPrimitives.test.ts +0 -690
- package/src/__tests__/EconomicTraits.test.ts +0 -425
- package/src/__tests__/SimulationLabPrimitives.test.ts +0 -415
- package/src/__tests__/collections.test.ts +0 -182
- package/src/__tests__/events.test.ts +0 -135
- package/src/__tests__/index.test.ts +0 -14
- package/src/__tests__/materials.test.ts +0 -84
- package/src/__tests__/math.test.ts +0 -246
- package/src/__tests__/physics.test.ts +0 -83
- package/src/__tests__/spatial.test.ts +0 -333
- package/src/__tests__/standard-library-fundamentals.test.ts +0 -1318
- package/src/__tests__/string-and-time-utilities.test.ts +0 -1070
- package/src/__tests__/string-decoupled.test.ts +0 -13
- package/src/__tests__/string.test.ts +0 -164
- package/src/__tests__/time.test.ts +0 -110
- package/src/collections.ts +0 -850
- package/src/events.ts +0 -88
- package/src/fs/__tests__/file-watch-system.test.ts +0 -675
- package/src/fs/__tests__/path-utilities.test.ts +0 -375
- package/src/fs/__tests__/path.test.ts +0 -287
- package/src/fs/fs.ts +0 -692
- package/src/fs/index.ts +0 -194
- package/src/fs/path.ts +0 -310
- package/src/fs/watch.ts +0 -413
- package/src/index.ts +0 -476
- package/src/materials.ts +0 -109
- package/src/math.ts +0 -674
- package/src/physics.ts +0 -141
- package/src/spatial.ts +0 -320
- package/src/string.basic.test.ts +0 -14
- package/src/string.test.ts +0 -335
- package/src/string.ts +0 -531
- package/src/time.ts +0 -621
- package/src/traits/ARTraits.ts +0 -103
- package/src/traits/EconomicPrimitives.ts +0 -755
- package/src/traits/EconomicTraits.ts +0 -552
- package/src/traits/IoTTraits.ts +0 -102
- package/src/traits/SimulationLabPrimitives.ts +0 -650
- package/src/traits/SimulationLabTraits.ts +0 -191
- package/src/traits/VRRTraits.ts +0 -326
- package/src/traits/__tests__/ARTraits.test.ts +0 -8
- package/src/traits/__tests__/EconomicPrimitives.test.ts +0 -14
- package/src/traits/__tests__/EconomicTraits.test.ts +0 -16
- package/src/types.ts +0 -418
- package/std_error.log +0 -5
- package/tsconfig.json +0 -18
- package/tsup.config.ts +0 -20
- package/vitest.config.ts +0 -10
- /package/dist/{chunk-PR4QN5HX.js.map → chunk-DGUM43GV.js.map} +0 -0
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { EventBus } from '../events.js';
|
|
3
|
-
|
|
4
|
-
describe('EventBus', () => {
|
|
5
|
-
describe('on / emit', () => {
|
|
6
|
-
it('calls handler on emit', () => {
|
|
7
|
-
const bus = new EventBus();
|
|
8
|
-
const fn = vi.fn();
|
|
9
|
-
bus.on('test', fn);
|
|
10
|
-
bus.emit('test', 42);
|
|
11
|
-
expect(fn).toHaveBeenCalledWith(42);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('calls handler multiple times', () => {
|
|
15
|
-
const bus = new EventBus();
|
|
16
|
-
const fn = vi.fn();
|
|
17
|
-
bus.on('x', fn);
|
|
18
|
-
bus.emit('x');
|
|
19
|
-
bus.emit('x');
|
|
20
|
-
bus.emit('x');
|
|
21
|
-
expect(fn).toHaveBeenCalledTimes(3);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('handles multiple listeners on same event', () => {
|
|
25
|
-
const bus = new EventBus();
|
|
26
|
-
const fn1 = vi.fn();
|
|
27
|
-
const fn2 = vi.fn();
|
|
28
|
-
bus.on('e', fn1);
|
|
29
|
-
bus.on('e', fn2);
|
|
30
|
-
bus.emit('e', 'data');
|
|
31
|
-
expect(fn1).toHaveBeenCalledWith('data');
|
|
32
|
-
expect(fn2).toHaveBeenCalledWith('data');
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('does not call unrelated listeners', () => {
|
|
36
|
-
const bus = new EventBus();
|
|
37
|
-
const fn = vi.fn();
|
|
38
|
-
bus.on('a', fn);
|
|
39
|
-
bus.emit('b');
|
|
40
|
-
expect(fn).not.toHaveBeenCalled();
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe('once', () => {
|
|
45
|
-
it('calls handler only once', () => {
|
|
46
|
-
const bus = new EventBus();
|
|
47
|
-
const fn = vi.fn();
|
|
48
|
-
bus.once('x', fn);
|
|
49
|
-
bus.emit('x', 1);
|
|
50
|
-
bus.emit('x', 2);
|
|
51
|
-
expect(fn).toHaveBeenCalledTimes(1);
|
|
52
|
-
expect(fn).toHaveBeenCalledWith(1);
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
describe('off', () => {
|
|
57
|
-
it('removes a listener', () => {
|
|
58
|
-
const bus = new EventBus();
|
|
59
|
-
const fn = vi.fn();
|
|
60
|
-
bus.on('x', fn);
|
|
61
|
-
bus.off('x', fn);
|
|
62
|
-
bus.emit('x');
|
|
63
|
-
expect(fn).not.toHaveBeenCalled();
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('returns unsubscribe function', () => {
|
|
67
|
-
const bus = new EventBus();
|
|
68
|
-
const fn = vi.fn();
|
|
69
|
-
const unsub = bus.on('x', fn);
|
|
70
|
-
unsub();
|
|
71
|
-
bus.emit('x');
|
|
72
|
-
expect(fn).not.toHaveBeenCalled();
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
describe('onAny', () => {
|
|
77
|
-
it('receives all events', () => {
|
|
78
|
-
const bus = new EventBus();
|
|
79
|
-
const fn = vi.fn();
|
|
80
|
-
bus.onAny(fn);
|
|
81
|
-
bus.emit('a', 1);
|
|
82
|
-
bus.emit('b', 2);
|
|
83
|
-
expect(fn).toHaveBeenCalledTimes(2);
|
|
84
|
-
expect(fn).toHaveBeenCalledWith({ event: 'a', data: 1 });
|
|
85
|
-
expect(fn).toHaveBeenCalledWith({ event: 'b', data: 2 });
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('returns unsubscribe function', () => {
|
|
89
|
-
const bus = new EventBus();
|
|
90
|
-
const fn = vi.fn();
|
|
91
|
-
const unsub = bus.onAny(fn);
|
|
92
|
-
unsub();
|
|
93
|
-
bus.emit('x');
|
|
94
|
-
expect(fn).not.toHaveBeenCalled();
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
describe('clear', () => {
|
|
99
|
-
it('removes all listeners', () => {
|
|
100
|
-
const bus = new EventBus();
|
|
101
|
-
const fn1 = vi.fn();
|
|
102
|
-
const fn2 = vi.fn();
|
|
103
|
-
bus.on('a', fn1);
|
|
104
|
-
bus.onAny(fn2);
|
|
105
|
-
bus.clear();
|
|
106
|
-
bus.emit('a');
|
|
107
|
-
expect(fn1).not.toHaveBeenCalled();
|
|
108
|
-
expect(fn2).not.toHaveBeenCalled();
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe('listenerCount', () => {
|
|
113
|
-
it('counts specific event listeners', () => {
|
|
114
|
-
const bus = new EventBus();
|
|
115
|
-
bus.on('a', () => {});
|
|
116
|
-
bus.on('a', () => {});
|
|
117
|
-
bus.on('b', () => {});
|
|
118
|
-
expect(bus.listenerCount('a')).toBe(2);
|
|
119
|
-
expect(bus.listenerCount('b')).toBe(1);
|
|
120
|
-
expect(bus.listenerCount('c')).toBe(0);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('counts all listeners', () => {
|
|
124
|
-
const bus = new EventBus();
|
|
125
|
-
bus.on('a', () => {});
|
|
126
|
-
bus.on('b', () => {});
|
|
127
|
-
bus.onAny(() => {});
|
|
128
|
-
expect(bus.listenerCount()).toBe(3);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it('empty bus has 0 listeners', () => {
|
|
132
|
-
expect(new EventBus().listenerCount()).toBe(0);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
});
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import * as std from '../index.js';
|
|
3
|
-
|
|
4
|
-
describe('std/index', () => {
|
|
5
|
-
it('should export standard types and math', () => {
|
|
6
|
-
expect(std).toBeDefined();
|
|
7
|
-
expect(std.PI).toBeGreaterThan(3.14);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('should export string utilities', () => {
|
|
11
|
-
expect(std.capitalize('holo')).toBe('Holo');
|
|
12
|
-
expect(typeof std.lerp).toBe('function');
|
|
13
|
-
});
|
|
14
|
-
});
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { MATERIAL_PRESETS, createPBRMaterial } from '../materials.js';
|
|
3
|
-
import type { PBRMaterial } from '../materials.js';
|
|
4
|
-
|
|
5
|
-
describe('MATERIAL_PRESETS', () => {
|
|
6
|
-
it('should have at least 10 presets', () => {
|
|
7
|
-
expect(Object.keys(MATERIAL_PRESETS).length).toBeGreaterThanOrEqual(10);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('metal preset should be highly metallic', () => {
|
|
11
|
-
expect(MATERIAL_PRESETS.metal.metallic).toBe(1.0);
|
|
12
|
-
expect(MATERIAL_PRESETS.metal.roughness).toBeLessThan(0.5);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('wood preset should not be metallic', () => {
|
|
16
|
-
expect(MATERIAL_PRESETS.wood.metallic).toBe(0.0);
|
|
17
|
-
expect(MATERIAL_PRESETS.wood.roughness).toBeGreaterThan(0.7);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('glass preset should have low roughness and ior', () => {
|
|
21
|
-
expect(MATERIAL_PRESETS.glass.roughness).toBeLessThan(0.2);
|
|
22
|
-
expect(MATERIAL_PRESETS.glass.ior).toBeCloseTo(1.5);
|
|
23
|
-
expect(MATERIAL_PRESETS.glass.opacity).toBeLessThan(1.0);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('water preset should have correct ior', () => {
|
|
27
|
-
expect(MATERIAL_PRESETS.water.ior).toBeCloseTo(1.33);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('chrome preset should be fully metallic with low roughness', () => {
|
|
31
|
-
expect(MATERIAL_PRESETS.chrome.metallic).toBe(1.0);
|
|
32
|
-
expect(MATERIAL_PRESETS.chrome.roughness).toBeLessThan(0.1);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('skin preset should have subsurface scattering', () => {
|
|
36
|
-
expect(MATERIAL_PRESETS.skin.subsurface).toBeGreaterThan(0);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('all presets should have roughness defined', () => {
|
|
40
|
-
for (const [name, preset] of Object.entries(MATERIAL_PRESETS)) {
|
|
41
|
-
expect(preset.roughness, `${name} missing roughness`).toBeDefined();
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('all presets should have metallic defined', () => {
|
|
46
|
-
for (const [name, preset] of Object.entries(MATERIAL_PRESETS)) {
|
|
47
|
-
expect(preset.metallic, `${name} missing metallic`).toBeDefined();
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe('createPBRMaterial', () => {
|
|
53
|
-
it('creates material with defaults', () => {
|
|
54
|
-
const mat = createPBRMaterial('Test');
|
|
55
|
-
expect(mat.name).toBe('Test');
|
|
56
|
-
expect(mat.baseColor).toBe('#ffffff');
|
|
57
|
-
expect(mat.roughness).toBe(0.5);
|
|
58
|
-
expect(mat.metallic).toBe(0.0);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('applies preset', () => {
|
|
62
|
-
const mat = createPBRMaterial('Steel', 'metal');
|
|
63
|
-
expect(mat.metallic).toBe(1.0);
|
|
64
|
-
expect(mat.roughness).toBe(0.2);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('overrides preset values', () => {
|
|
68
|
-
const mat = createPBRMaterial('CustomMetal', 'metal', { roughness: 0.8 });
|
|
69
|
-
expect(mat.metallic).toBe(1.0);
|
|
70
|
-
expect(mat.roughness).toBe(0.8);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('creates material without preset', () => {
|
|
74
|
-
const mat = createPBRMaterial('Plain', undefined, { baseColor: '#ff0000' });
|
|
75
|
-
expect(mat.baseColor).toBe('#ff0000');
|
|
76
|
-
expect(mat.roughness).toBe(0.5);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('preserves name through preset', () => {
|
|
80
|
-
const mat = createPBRMaterial('Gold', 'gold');
|
|
81
|
-
expect(mat.name).toBe('Gold');
|
|
82
|
-
expect(mat.baseColor).toBe('#ffd700');
|
|
83
|
-
});
|
|
84
|
-
});
|
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
PI,
|
|
4
|
-
TAU,
|
|
5
|
-
HALF_PI,
|
|
6
|
-
DEG_TO_RAD,
|
|
7
|
-
RAD_TO_DEG,
|
|
8
|
-
EPSILON,
|
|
9
|
-
clamp,
|
|
10
|
-
lerp,
|
|
11
|
-
inverseLerp,
|
|
12
|
-
remap,
|
|
13
|
-
smoothstep,
|
|
14
|
-
smootherstep,
|
|
15
|
-
degToRad,
|
|
16
|
-
radToDeg,
|
|
17
|
-
mod,
|
|
18
|
-
fract,
|
|
19
|
-
sign,
|
|
20
|
-
step,
|
|
21
|
-
} from '../math.js';
|
|
22
|
-
|
|
23
|
-
describe('Math Constants', () => {
|
|
24
|
-
it('PI should be Math.PI', () => {
|
|
25
|
-
expect(PI).toBe(Math.PI);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('TAU should be 2 * PI', () => {
|
|
29
|
-
expect(TAU).toBe(Math.PI * 2);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('HALF_PI should be PI / 2', () => {
|
|
33
|
-
expect(HALF_PI).toBe(Math.PI / 2);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('DEG_TO_RAD should convert degrees to radians', () => {
|
|
37
|
-
expect(DEG_TO_RAD).toBe(Math.PI / 180);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('RAD_TO_DEG should convert radians to degrees', () => {
|
|
41
|
-
expect(RAD_TO_DEG).toBe(180 / Math.PI);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('EPSILON should be a small value for float comparison', () => {
|
|
45
|
-
expect(EPSILON).toBe(1e-6);
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
describe('clamp', () => {
|
|
50
|
-
it('should return min when value is below min', () => {
|
|
51
|
-
expect(clamp(-5, 0, 10)).toBe(0);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('should return max when value is above max', () => {
|
|
55
|
-
expect(clamp(15, 0, 10)).toBe(10);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('should return value when within range', () => {
|
|
59
|
-
expect(clamp(5, 0, 10)).toBe(5);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('should handle edge cases at boundaries', () => {
|
|
63
|
-
expect(clamp(0, 0, 10)).toBe(0);
|
|
64
|
-
expect(clamp(10, 0, 10)).toBe(10);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('should work with negative ranges', () => {
|
|
68
|
-
expect(clamp(-5, -10, -1)).toBe(-5);
|
|
69
|
-
expect(clamp(-15, -10, -1)).toBe(-10);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
describe('lerp', () => {
|
|
74
|
-
it('should return a when t is 0', () => {
|
|
75
|
-
expect(lerp(0, 10, 0)).toBe(0);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('should return b when t is 1', () => {
|
|
79
|
-
expect(lerp(0, 10, 1)).toBe(10);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('should return midpoint when t is 0.5', () => {
|
|
83
|
-
expect(lerp(0, 10, 0.5)).toBe(5);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('should extrapolate when t > 1', () => {
|
|
87
|
-
expect(lerp(0, 10, 2)).toBe(20);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('should work with negative values', () => {
|
|
91
|
-
expect(lerp(-10, 10, 0.5)).toBe(0);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
describe('inverseLerp', () => {
|
|
96
|
-
it('should return 0 when value equals a', () => {
|
|
97
|
-
expect(inverseLerp(0, 10, 0)).toBe(0);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('should return 1 when value equals b', () => {
|
|
101
|
-
expect(inverseLerp(0, 10, 10)).toBe(1);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('should return 0.5 when value is midpoint', () => {
|
|
105
|
-
expect(inverseLerp(0, 10, 5)).toBe(0.5);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('should work with negative ranges', () => {
|
|
109
|
-
expect(inverseLerp(-10, 10, 0)).toBe(0.5);
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
describe('remap', () => {
|
|
114
|
-
it('should remap 0-1 to 0-100', () => {
|
|
115
|
-
expect(remap(0.5, 0, 1, 0, 100)).toBe(50);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it('should remap between different ranges', () => {
|
|
119
|
-
expect(remap(5, 0, 10, 100, 200)).toBe(150);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('should handle inverted output ranges', () => {
|
|
123
|
-
expect(remap(0, 0, 10, 100, 0)).toBe(100);
|
|
124
|
-
expect(remap(10, 0, 10, 100, 0)).toBe(0);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
describe('smoothstep', () => {
|
|
129
|
-
it('should return 0 when x <= edge0', () => {
|
|
130
|
-
expect(smoothstep(0, 1, -0.5)).toBe(0);
|
|
131
|
-
expect(smoothstep(0, 1, 0)).toBe(0);
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('should return 1 when x >= edge1', () => {
|
|
135
|
-
expect(smoothstep(0, 1, 1)).toBe(1);
|
|
136
|
-
expect(smoothstep(0, 1, 1.5)).toBe(1);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('should return smooth interpolation in between', () => {
|
|
140
|
-
const mid = smoothstep(0, 1, 0.5);
|
|
141
|
-
expect(mid).toBe(0.5);
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
describe('smootherstep', () => {
|
|
146
|
-
it('should return 0 when x <= edge0', () => {
|
|
147
|
-
expect(smootherstep(0, 1, 0)).toBe(0);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it('should return 1 when x >= edge1', () => {
|
|
151
|
-
expect(smootherstep(0, 1, 1)).toBe(1);
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it('should return smooth interpolation at midpoint', () => {
|
|
155
|
-
const mid = smootherstep(0, 1, 0.5);
|
|
156
|
-
expect(mid).toBe(0.5);
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
describe('degToRad', () => {
|
|
161
|
-
it('should convert 0 degrees to 0 radians', () => {
|
|
162
|
-
expect(degToRad(0)).toBe(0);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it('should convert 180 degrees to PI radians', () => {
|
|
166
|
-
expect(degToRad(180)).toBeCloseTo(Math.PI);
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it('should convert 360 degrees to 2*PI radians', () => {
|
|
170
|
-
expect(degToRad(360)).toBeCloseTo(2 * Math.PI);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
it('should convert 90 degrees to PI/2 radians', () => {
|
|
174
|
-
expect(degToRad(90)).toBeCloseTo(Math.PI / 2);
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
describe('radToDeg', () => {
|
|
179
|
-
it('should convert 0 radians to 0 degrees', () => {
|
|
180
|
-
expect(radToDeg(0)).toBe(0);
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
it('should convert PI radians to 180 degrees', () => {
|
|
184
|
-
expect(radToDeg(Math.PI)).toBeCloseTo(180);
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
it('should convert 2*PI radians to 360 degrees', () => {
|
|
188
|
-
expect(radToDeg(2 * Math.PI)).toBeCloseTo(360);
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
describe('mod', () => {
|
|
193
|
-
it('should handle positive modulo', () => {
|
|
194
|
-
expect(mod(7, 3)).toBe(1);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
it('should handle negative values correctly (always positive result)', () => {
|
|
198
|
-
expect(mod(-1, 3)).toBe(2);
|
|
199
|
-
expect(mod(-4, 3)).toBe(2);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
it('should return 0 for exact multiples', () => {
|
|
203
|
-
expect(mod(6, 3)).toBe(0);
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
describe('fract', () => {
|
|
208
|
-
it('should return fractional part of positive numbers', () => {
|
|
209
|
-
expect(fract(3.7)).toBeCloseTo(0.7);
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it('should return 0 for integers', () => {
|
|
213
|
-
expect(fract(5)).toBe(0);
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
it('should handle negative numbers', () => {
|
|
217
|
-
expect(fract(-3.3)).toBeCloseTo(0.7);
|
|
218
|
-
});
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
describe('sign', () => {
|
|
222
|
-
it('should return 1 for positive numbers', () => {
|
|
223
|
-
expect(sign(5)).toBe(1);
|
|
224
|
-
expect(sign(0.001)).toBe(1);
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it('should return -1 for negative numbers', () => {
|
|
228
|
-
expect(sign(-5)).toBe(-1);
|
|
229
|
-
expect(sign(-0.001)).toBe(-1);
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it('should return 0 for zero', () => {
|
|
233
|
-
expect(sign(0)).toBe(0);
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
describe('step', () => {
|
|
238
|
-
it('should return 0 when x < edge', () => {
|
|
239
|
-
expect(step(0.5, 0.3)).toBe(0);
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
it('should return 1 when x >= edge', () => {
|
|
243
|
-
expect(step(0.5, 0.5)).toBe(1);
|
|
244
|
-
expect(step(0.5, 0.7)).toBe(1);
|
|
245
|
-
});
|
|
246
|
-
});
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
createBoxCollider,
|
|
4
|
-
createSphereCollider,
|
|
5
|
-
createCapsuleCollider,
|
|
6
|
-
createRigidbody,
|
|
7
|
-
} from '../physics.js';
|
|
8
|
-
import { Vec3 } from '../spatial.js';
|
|
9
|
-
|
|
10
|
-
describe('createBoxCollider', () => {
|
|
11
|
-
it('creates a box collider with defaults', () => {
|
|
12
|
-
const c = createBoxCollider(new Vec3(1, 1, 1));
|
|
13
|
-
expect(c.shape).toBe('box');
|
|
14
|
-
expect(c.isTrigger).toBe(false);
|
|
15
|
-
expect(c.friction).toBe(0.5);
|
|
16
|
-
expect(c.restitution).toBe(0.0);
|
|
17
|
-
expect(c.halfExtents).toBeDefined();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('accepts option overrides', () => {
|
|
21
|
-
const c = createBoxCollider(new Vec3(2, 2, 2), { friction: 0.9, isTrigger: true });
|
|
22
|
-
expect(c.friction).toBe(0.9);
|
|
23
|
-
expect(c.isTrigger).toBe(true);
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
describe('createSphereCollider', () => {
|
|
28
|
-
it('creates a sphere collider', () => {
|
|
29
|
-
const c = createSphereCollider(0.5);
|
|
30
|
-
expect(c.shape).toBe('sphere');
|
|
31
|
-
expect(c.radius).toBe(0.5);
|
|
32
|
-
expect(c.friction).toBe(0.5);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('overrides restitution', () => {
|
|
36
|
-
const c = createSphereCollider(1.0, { restitution: 0.8 });
|
|
37
|
-
expect(c.restitution).toBe(0.8);
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
describe('createCapsuleCollider', () => {
|
|
42
|
-
it('creates a capsule collider', () => {
|
|
43
|
-
const c = createCapsuleCollider(0.3, 1.8);
|
|
44
|
-
expect(c.shape).toBe('capsule');
|
|
45
|
-
expect(c.radius).toBe(0.3);
|
|
46
|
-
expect(c.height).toBe(1.8);
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
describe('createRigidbody', () => {
|
|
51
|
-
it('creates a rigidbody with defaults', () => {
|
|
52
|
-
const rb = createRigidbody(10);
|
|
53
|
-
expect(rb.mass).toBe(10);
|
|
54
|
-
expect(rb.useGravity).toBe(true);
|
|
55
|
-
expect(rb.linearDamping).toBe(0.0);
|
|
56
|
-
expect(rb.angularDamping).toBe(0.05);
|
|
57
|
-
expect(rb.isKinematic).toBe(false);
|
|
58
|
-
expect(rb.freezePosition).toEqual([false, false, false]);
|
|
59
|
-
expect(rb.freezeRotation).toEqual([false, false, false]);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('overrides gravity', () => {
|
|
63
|
-
const rb = createRigidbody(5, { useGravity: false });
|
|
64
|
-
expect(rb.useGravity).toBe(false);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('overrides kinematic', () => {
|
|
68
|
-
const rb = createRigidbody(1, { isKinematic: true });
|
|
69
|
-
expect(rb.isKinematic).toBe(true);
|
|
70
|
-
expect(rb.mass).toBe(1);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('overrides damping', () => {
|
|
74
|
-
const rb = createRigidbody(50, { linearDamping: 0.5, angularDamping: 0.8 });
|
|
75
|
-
expect(rb.linearDamping).toBe(0.5);
|
|
76
|
-
expect(rb.angularDamping).toBe(0.8);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('overrides freeze axes', () => {
|
|
80
|
-
const rb = createRigidbody(1, { freezePosition: [true, false, true] });
|
|
81
|
-
expect(rb.freezePosition).toEqual([true, false, true]);
|
|
82
|
-
});
|
|
83
|
-
});
|