mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-10-03 11:37:54 +00:00
- Consume host adaptive-quality bundle.renderScale; fold into DPR like highway_3d (splitscreen proxy: >1 instance caps baseDPR at 1.25) - Bloom: port _bloomEnsure/_bloomDispose (UnrealBloomPass 0.65/0.5/0.82, MSAA HalfFloat target, ACES<->None tone-mapping switch); rebuilt across the kit-change renderer recreation; direct render is the degrade path - FX settings scaffold: FX_DEFAULTS + readFxSettings + drumH3dSetFx (drum_h3d_bg_* keys), Graphics section in settings.html (bloom toggle, default ON, live-applies) - _applyLaneFlashes dead-code comment updated (visual consumer lands in the hit-FX PR) - __test export + tests/data_layer.test.js (vm harness, 8 tests) — picked up by the CI glob from the bundling PR; README refreshed Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
95 lines
4.2 KiB
JavaScript
95 lines
4.2 KiB
JavaScript
// Pure data-layer tests: load screen.js in a bare vm window and exercise the
|
|
// __test exports (no DOM, no WebGL, no network). Doubles as a lint that no
|
|
// module-scope code touches document/localStorage outside a try/catch —
|
|
// the vm window deliberately provides neither.
|
|
const { test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const vm = require('node:vm');
|
|
|
|
function load() {
|
|
const window = {
|
|
console,
|
|
location: { protocol: 'http:', host: 'localhost' },
|
|
slopsmith: {},
|
|
};
|
|
window.window = window;
|
|
window.globalThis = window;
|
|
const context = vm.createContext(window);
|
|
const src = fs.readFileSync(path.join(__dirname, '..', 'screen.js'), 'utf8');
|
|
vm.runInContext(src, context, { filename: 'screen.js' });
|
|
return window.slopsmithViz_drum_highway_3d;
|
|
}
|
|
|
|
test('module loads in a bare vm (no DOM / localStorage at module scope)', () => {
|
|
const factory = load();
|
|
assert.equal(typeof factory, 'function');
|
|
assert.equal(factory.contextType, 'webgl2');
|
|
});
|
|
|
|
test('_variantForHit: ghost > flam > bell > accent > normal precedence', () => {
|
|
const { _variantForHit } = load().__test;
|
|
assert.equal(_variantForHit({ g: true, f: true, v: 120 }), 'ghost');
|
|
assert.equal(_variantForHit({ f: true, v: 120 }), 'flam');
|
|
assert.equal(_variantForHit({ p: 'ride_bell' }), 'bell');
|
|
assert.equal(_variantForHit({ v: 100 }), 'accent');
|
|
assert.equal(_variantForHit({ v: 127 }), 'accent');
|
|
assert.equal(_variantForHit({ v: 99 }), 'normal');
|
|
// Missing velocity defaults to 100 → accent.
|
|
assert.equal(_variantForHit({}), 'accent');
|
|
});
|
|
|
|
test('matchesArrangement: claims drum arrangements', () => {
|
|
const matches = load().matchesArrangement;
|
|
assert.equal(matches({ has_drum_tab: true, arrangement: 'Drums' }), true);
|
|
assert.equal(matches({ has_drum_tab: true, arrangement: 'Drum Kit' }), true);
|
|
assert.equal(matches({ has_drum_tab: true, arrangement: 'Percussion' }), true);
|
|
});
|
|
|
|
test('matchesArrangement: never claims without a drum tab', () => {
|
|
const matches = load().matchesArrangement;
|
|
assert.equal(matches(null), false);
|
|
assert.equal(matches({}), false);
|
|
assert.equal(matches({ arrangement: 'Drums' }), false);
|
|
});
|
|
|
|
test('matchesArrangement: steal-guard — guitar arrangements stay with highway_3d', () => {
|
|
const matches = load().matchesArrangement;
|
|
// Full-band pack (drum_tab present) playing a guitar-family part:
|
|
// first-match-wins Auto order must not hand these to the drum highway.
|
|
for (const arr of ['Lead', 'Rhythm', 'Bass', 'Combo', 'Guitar 22', 'Alt. Lead']) {
|
|
assert.equal(matches({ has_drum_tab: true, arrangement: arr }), false, arr);
|
|
}
|
|
// Keys notation present → the keys/staff viz take it.
|
|
assert.equal(matches({ has_drum_tab: true, has_notation: true, arrangement: 'Piano' }), false);
|
|
});
|
|
|
|
test('matchesArrangement: claims packs nothing more specific can render', () => {
|
|
const matches = load().matchesArrangement;
|
|
// Drum tab + nondescript arrangement, no notation → drummable, claim it.
|
|
assert.equal(matches({ has_drum_tab: true, arrangement: '' }), true);
|
|
assert.equal(matches({ has_drum_tab: true }), true);
|
|
// Word-boundary check: "BasslineKeys"-style names don't contain a
|
|
// guitar-family word as a whole word.
|
|
assert.equal(matches({ has_drum_tab: true, arrangement: 'Bassline' }), true);
|
|
});
|
|
|
|
test('readFxSettings: defaults survive a localStorage-less environment', () => {
|
|
const { readFxSettings, FX_DEFAULTS } = load().__test;
|
|
// The vm window has no localStorage — the try/catch must eat the
|
|
// ReferenceError and hand back pure defaults (everything ON).
|
|
assert.deepEqual(readFxSettings(), FX_DEFAULTS);
|
|
assert.equal(FX_DEFAULTS.bloom, true);
|
|
});
|
|
|
|
test('MIDI map: open hi-hat is a first-class piece (46 → hh_open)', () => {
|
|
const { MIDI_TO_PIECE, HIT_TOLERANCE_S } = load().__test;
|
|
assert.equal(MIDI_TO_PIECE[46], 'hh_open');
|
|
assert.equal(MIDI_TO_PIECE[42], 'hh_closed');
|
|
assert.equal(MIDI_TO_PIECE[35], 'kick');
|
|
assert.equal(MIDI_TO_PIECE[36], 'kick');
|
|
// ±50 ms window matches the 2D drums plugin.
|
|
assert.equal(HIT_TOLERANCE_S, 0.05);
|
|
});
|