mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-09-16 18:00:09 +00:00
refactor(h3d-carve-1b): extract render-order, note-key, camera-bootstrap, fretMid to src/geometry.js
Move 9 symbols verbatim from screen.js factory scope to geometry.js:
- RENDER_ORDER_LAYER_STACK, RENDER_ORDER_LAYER_INDEX, RENDER_ORDER_AT_Z_ZERO,
RENDER_ORDER_FAR_CLAMP — compile-time constants, now exported from geometry.js
- renderOrderForLayerAtZ — pure fn; reads K + RENDER_ORDER_* from geometry scope
- _noteKey, lowerBoundT — hot-path helpers; no external deps
- hwyFirstRelevantFrettedTime — camera bootstrap scan; no external deps
- fretMid → geoFretMid(f, uniform) — same fretX delegator pattern as Cut 1;
screen.js keeps: const fretMid = f => geoFretMid(f, _h3dFretUniform); (1 beyond-subst)
screen.js import line updated to import all 9 new exports; tombstones replace
each original definition.
Source-scan retargets:
- highway_3d_render_order.test.js: layers()/zZeroRenderOrder() now read
GEOMETRY_JS; the 5 renderOrderForLayerAtZ-internals asserts in
chordFrameRenderOrder test retargeted to geo() (call-site assert stays on src()).
- highway_3d_camera_bootstrap.test.js: extractFn now reads geoSrc (GEOMETRY_JS);
sourceBetween wiring tests remain on SCREEN_JS.
- highway_3d_panel_controls.test.js: sandbox stubs extended with 9 new names.
Class-killer tests added to highway_3d_geometry.test.js (8 new tests, 180 total):
- RENDER_ORDER_LAYER_STACK length + first/last entries
- RENDER_ORDER_LAYER_INDEX spot-checks (CHORD_FILL=0, NOTE_CORE=10)
- renderOrderForLayerAtZ far-clamp (worldZ=-5 gives 50, not 33 without max)
- renderOrderForLayerAtZ unknown-layer throws
- _noteKey |0 truncation (1.5,3)=150003 not float-derived 150008
- lowerBoundT strict lower-bound (3 in [{t:1},{t:3},{t:5}] gives 1, not 2)
- hwyFirstRelevantFrettedTime smoke (empty → null)
- geoFretMid sentinel (f=0 gives -2K≈-0.015, not 0) + ratio invariant
Mutation analysis confirmed all 8 tests fail under their named mutation before
committing (per Toby r1 lesson).
Base run (a1f7ad5): 172/172 pass.
Post-cut run: 180/180 pass.
Command: node --test tests/js/highway_3d*.test.js plugins/highway_3d/tests/*.test.js
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014uZ169yfoFYArXz962g7KW
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
a1f7ad5e68
commit
5e401afe87
@@ -99,6 +99,67 @@ test('camLowFretPullbackU is clamped to zero — high fret gives 0 not negative'
|
||||
assert.strictEqual(camLowFretPullbackU(10), 0, 'fret 10: clamped to 0, not -20');
|
||||
});
|
||||
|
||||
// ── Cut 1b class-killers ───────────────────────────────────────────────────────
|
||||
|
||||
test('RENDER_ORDER_LAYER_STACK has 17 layers with CHORD_FILL first and CHORD_FRET_LABEL last', async () => {
|
||||
const { RENDER_ORDER_LAYER_STACK } = await import(GEOMETRY_JS);
|
||||
assert.strictEqual(RENDER_ORDER_LAYER_STACK.length, 17, 'stack must have exactly 17 layers');
|
||||
assert.strictEqual(RENDER_ORDER_LAYER_STACK[0], 'CHORD_FILL', 'first layer must be CHORD_FILL');
|
||||
assert.strictEqual(RENDER_ORDER_LAYER_STACK[RENDER_ORDER_LAYER_STACK.length - 1], 'CHORD_FRET_LABEL', 'last layer must be CHORD_FRET_LABEL');
|
||||
});
|
||||
|
||||
test('RENDER_ORDER_LAYER_INDEX maps CHORD_FILL to 0 and NOTE_CORE to 10', async () => {
|
||||
// Mutation: wrong layer order → NOTE_CORE would not map to 10.
|
||||
const { RENDER_ORDER_LAYER_INDEX } = await import(GEOMETRY_JS);
|
||||
assert.strictEqual(RENDER_ORDER_LAYER_INDEX['CHORD_FILL'], 0, 'CHORD_FILL must be index 0 (bottom of stack)');
|
||||
assert.strictEqual(RENDER_ORDER_LAYER_INDEX['NOTE_CORE'], 10, 'NOTE_CORE must be index 10');
|
||||
});
|
||||
|
||||
test('renderOrderForLayerAtZ applies the far clamp — worldZ=-5 gives 50 not 33', async () => {
|
||||
// Mutation: remove Math.max(RENDER_ORDER_FAR_CLAMP, ...) clamp.
|
||||
// K=2.25/300=0.0075; Math.round(700+(-5)/0.0075)=Math.round(33.33)=33; max(50,33)=50.
|
||||
// Without clamp: 33 + 0/17 ≈ 33. Test pins the clamped value.
|
||||
const { renderOrderForLayerAtZ } = await import(GEOMETRY_JS);
|
||||
assert.strictEqual(renderOrderForLayerAtZ(-5, 'CHORD_FILL'), 50, 'far objects must be clamped to RENDER_ORDER_FAR_CLAMP=50');
|
||||
});
|
||||
|
||||
test('renderOrderForLayerAtZ throws for unknown layer names', async () => {
|
||||
const { renderOrderForLayerAtZ } = await import(GEOMETRY_JS);
|
||||
assert.throws(() => renderOrderForLayerAtZ(0, 'NONEXISTENT'), /Unknown 3D highway depth layer/);
|
||||
});
|
||||
|
||||
test('_noteKey integer-truncates float times — _noteKey(1.5, 3) is 150003 not 150008', async () => {
|
||||
// Mutation: drop |0 → (15000.5)*10+3 = 150008.
|
||||
const { _noteKey } = await import(GEOMETRY_JS);
|
||||
assert.strictEqual(_noteKey(1.5, 3), 150003, '|0 truncation must give 150003, not float-derived 150008');
|
||||
assert.strictEqual(_noteKey(0, 0), 0);
|
||||
});
|
||||
|
||||
test('lowerBoundT returns first index where arr[i].t >= t (strict lower bound)', async () => {
|
||||
// Mutation: < → <= causes lowerBoundT([{t:1},{t:3},{t:5}], 3) → 2 instead of 1.
|
||||
const { lowerBoundT } = await import(GEOMETRY_JS);
|
||||
const arr = [{ t: 1 }, { t: 3 }, { t: 5 }];
|
||||
assert.strictEqual(lowerBoundT(arr, 3), 1, 'strict lower-bound: first index where .t >= 3 is 1 (not 2)');
|
||||
assert.strictEqual(lowerBoundT(arr, 0), 0, 'value before all: must return 0');
|
||||
assert.strictEqual(lowerBoundT(arr, 6), 3, 'value after all: must return length');
|
||||
});
|
||||
|
||||
test('hwyFirstRelevantFrettedTime returns null for empty/all-open input', async () => {
|
||||
const { hwyFirstRelevantFrettedTime } = await import(GEOMETRY_JS);
|
||||
assert.strictEqual(hwyFirstRelevantFrettedTime([], [], 0, 0.2, 6), null);
|
||||
});
|
||||
|
||||
test('geoFretMid returns -2K sentinel for f<=0, positive for f=1', async () => {
|
||||
// Mutation: drop f<=0 guard → geoFretMid(0, true) returns (0+0)/2=0, not -0.015.
|
||||
const { geoFretMid } = await import(GEOMETRY_JS);
|
||||
const K = 2.25 / 300;
|
||||
assert.ok(Math.abs(geoFretMid(0, true) - (-2 * K)) < 1e-10, 'f=0 must return -2K sentinel (≈-0.015)');
|
||||
assert.ok(geoFretMid(1, true) > 0, 'f=1 must return positive X');
|
||||
// In uniform mode: geoFretX(0,true)=0, geoFretX(1,true)=step, so mid=step/2.
|
||||
// geoFretMid(2,true) = (step+2step)/2 = 1.5step. Ratio 3 catches wrong f offset.
|
||||
assert.ok(Math.abs(geoFretMid(2, true) / geoFretMid(1, true) - 3) < 1e-9, 'uniform mid(2)/mid(1) must equal 3');
|
||||
});
|
||||
|
||||
test('_makeGaussTex peak alpha is 255 at the centre pixel', async () => {
|
||||
// Mutation: default sigma changed to 0 → (u-0.5)/0 = NaN chain → all Uint8Array writes
|
||||
// become 0 (TypedArray coerces NaN to 0). Test calls without explicit sigma so the
|
||||
|
||||
Reference in New Issue
Block a user