test(h3d): catch const-shadow mutation in T=mod assertion (Toby r1)

Toby r1 finding on 8ea123d: the count-based check /T\s*=\s*mod\s*;/g
matches even when the .then bodies declare 'const T = mod' — a local
shadow that leaves the module-level live-binding T permanently null.
Fix: add doesNotMatch(/(?:const|let|var)\s+T\s*=\s*mod/) to reject
any declaration form.

Mutation-verified: 7/8 RED under const-shadow, 188/188 GREEN on original.
Suite: 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:
byrongamatos
2026-09-05 07:42:18 +02:00
co-authored by Claude Sonnet 4.6
parent 8ea123deaf
commit f75e91088f
+6 -2
View File
@@ -38,11 +38,15 @@ test('T is exported as a live let-binding from three-loader.js', () => {
});
test('loadThree assigns T = mod in both the primary and CDN .then handlers', () => {
// Mutation: remove all T = mod assignments — T stays null forever; all Three.js
// calls throw. Two assignments exist: primary load and CDN fallback.
// Mutation 1: remove all T = mod — T stays null forever; T.WebGLRenderer throws.
// Two assignments exist: primary .then and CDN fallback .then.
// Mutation 2 (Toby r1): `const T = mod` inside .then bodies — count=2 still
// matches, but shadows the module-level export; live-binding T stays null forever.
const matches = loader().match(/T\s*=\s*mod\s*;/g) || [];
assert.ok(matches.length >= 2,
'T = mod must appear in both the primary and CDN .then handlers (found ' + matches.length + ')');
assert.doesNotMatch(loader(), /(?:const|let|var)\s+T\s*=\s*mod/,
'T = mod must be a bare assignment, not a declaration that shadows the live-binding export');
});
test('loadThree memoises the promise — returns existing promise on repeated calls', () => {