build: discover owned runtime modules in the formatter gate

This commit is contained in:
Sameh Khamis committed 2026-09-15 07:26:32 -07:00
1 parent 76c20be277
commit ae99843c14
13 files changed
+193 -36

No files matched your search

+11 -10
View File
@@ -31,7 +31,8 @@ function body(source, pattern, label) {
function ordered(source, needles, label) {
let previous = -1;
for (const needle of needles) {
const index = source.indexOf(needle, previous + 1);
const match = needle instanceof RegExp ? needle.exec(source.slice(previous + 1)) : null;
const index = needle instanceof RegExp ? (match ? previous + 1 + match.index : -1) : source.indexOf(needle, previous + 1);
assert.ok(index >= 0, `${label}: missing ${needle}`);
assert.ok(index > previous, `${label}: ${needle} is out of order`);
previous = index;
@@ -104,7 +105,7 @@ test('voice Cockpit entry reaches the camera only through stamping seams', () =>
'Cockpit entry transaction',
);
ordered(transaction, [
'if (!selectedLayer.trackById?.(selectedTarget.id, { origin: selectionOrigin })) {',
/if \(\s*!selectedLayer\.trackById\?\.\(selectedTarget\.id, \{\s*origin: selectionOrigin,?\s*\}\)\s*\) \{/,
'if (!entryError) entered = Boolean(cockpitView.enter());',
], 'Cockpit entry transaction');
// No direct camera control: every mutation goes through a layer tracker or
@@ -200,11 +201,11 @@ test('accepted navigation releases through PR15-aware ownership before flight',
test('validated voice camera destinations share the UI navigation authority facade', () => {
assert.match(ui, /runImmediateNavigation\(noun, navigate, releaseOptions = undefined\) \{\s*return this\._runExplicitNavigation\(noun, navigate, releaseOptions\);/);
assert.match(voice, /runManagedVoiceNavigation\(\s*styleManager, 'camera', 'move_camera', navigate, releaseOptions/);
assert.match(voice, /runManagedVoiceNavigation\(styleManager, 'route', 'fly_route', navigate/);
assert.match(voice, /runManagedVoiceNavigation\(styleManager, 'fire', 'track_entity'/);
assert.match(voice, /runManagedVoiceNavigation\(styleManager, family\.kind, 'track_entity'/);
assert.match(voice, /runManagedVoiceNavigation\(styleManager, 'frame', 'frame_overhead'/);
assert.match(voice, /runManagedVoiceNavigation\(\s*styleManager,\s*'camera',\s*'move_camera',\s*navigate,\s*releaseOptions/);
assert.match(voice, /runManagedVoiceNavigation\(\s*styleManager,\s*'route',\s*'fly_route',\s*navigate/);
assert.match(voice, /runManagedVoiceNavigation\(\s*styleManager,\s*'fire',\s*'track_entity'/);
assert.match(voice, /runManagedVoiceNavigation\(\s*styleManager,\s*family\.kind,\s*'track_entity'/);
assert.match(voice, /runManagedVoiceNavigation\(\s*styleManager,\s*'frame',\s*'frame_overhead'/);
const trackedVoice = voice.slice(
voice.indexOf('async function trackEntity'),
voice.indexOf('async function frameOverhead'),
@@ -224,20 +225,20 @@ test('validated voice camera destinations share the UI navigation authority faca
ordered(move, [
"if (!['orbit', 'pan', 'tilt', 'rotate'].includes(motion))",
'const start = () => {',
"const preserveCameraFlight = motion === 'orbit'",
/const preserveCameraFlight =\s*motion === 'orbit'/,
'runNavigation(start, { preserveCameraFlight })',
], 'move validation before handoff');
const route = body(
cameraVerbs,
/export function flyRoute\(annoList, args = \{\}, floorFn = null, runNavigation = null, warmFn = null\) \{([\s\S]*?)\n\}/,
/export function flyRoute\(\s*annoList,\s*args = \{\},\s*floorFn = null,\s*runNavigation = null,\s*warmFn = null,?\s*\) \{([\s\S]*?)\n\}/,
'fly route',
);
ordered(route, [
'if (!routes.length)',
'const pts = route.path.map',
'const start = () => {',
"return typeof runNavigation === 'function' ? runNavigation(start) : start();",
/return typeof runNavigation === 'function'\s*\? runNavigation\(start\)\s*: start\(\);/,
], 'route validation before handoff');
// The corridor warm is injected the same way the floor READ is — the dolly
// never reaches into the data layer itself, and the voice dispatch is the one
+1 -1
View File
@@ -17,7 +17,7 @@ test('Cockpit reduces only the bracket presentation multiplier', () => {
test('detection owns and releases the Cockpit lifecycle listener', async () => {
const source = await readFile(new URL('./detection.js', import.meta.url), 'utf8');
assert.match(source, /addEventListener\('gev:cockpit-mode-changed', _cockpitModeListener\)/);
assert.match(source, /removeEventListener\('gev:cockpit-mode-changed', _cockpitModeListener\)/);
assert.match(source, /removeEventListener\(\s*'gev:cockpit-mode-changed',\s*_cockpitModeListener,?\s*\)/);
assert.match(
source,
/fade \* entry\.alpha \* bracketPresentationOpacity/,
+4 -4
View File
@@ -277,7 +277,7 @@ test('detection holds nothing, and asks for its own frames instead', async () =>
assert.match(source, /governorRequestRender\('detection-visibility'\)/,
'mode/suspend transitions request their own repaint');
assert.match(source, /if \(detectionNeedsFollowUpFrame\(\{[\s\S]*?\}\)\) \{\s*\n\s*governorRequestRender\('detection-animation'\);/,
assert.match(source, /if \(\s*detectionNeedsFollowUpFrame\(\{[\s\S]*?\}\)\s*\) \{\s*\n\s*governorRequestRender\('detection-animation'\);/,
'the follow-up frame is gated on the policy, never unconditional');
// The demand call must read the FRAME's timestamp, not a fresh sample.
@@ -306,7 +306,7 @@ test('detection holds nothing, and asks for its own frames instead', async () =>
// the emptiest possible scene. (Caught by the governor gate at 301 renders/5 s
// with zero layers; the fix settles the solve there, because with nothing
// detectable it is vacuously complete.)
const emptyExit = /\/\/ Drop the replay buffer with it[\s\S]*?return \{ didSolve: false[^\n]*\n/.exec(source)?.[0];
const emptyExit = /\/\/ Drop the replay buffer with it[\s\S]*?return \{\s*didSolve: false[\s\S]*?\};/.exec(source)?.[0];
assert.ok(emptyExit, 'the zero-objects exit is still identifiable');
assert.match(emptyExit, /_labelSolveDirty = false;/,
'the zero-objects exit settles the solve instead of carrying it forward');
@@ -318,7 +318,7 @@ test('detection holds nothing, and asks for its own frames instead', async () =>
assert.ok(drawOverlay, 'detection.js still has a draw pass');
assert.doesNotMatch(drawOverlay, /Date\.now\(\)/,
'the draw pass must run on the frame timestamp, not a wall clock');
assert.match(drawOverlay, /const now = Number\.isFinite\(frame\.timestamp\) \? frame\.timestamp : _nowMs\(\);/);
assert.match(drawOverlay, /const now =\s*Number\.isFinite\(frame\.timestamp\) \? frame\.timestamp : _nowMs\(\);/);
assert.match(source, /_enableTime = _nowMs\(\);/,
'the enable stamp shares the monotonic clock the fade is measured against');
@@ -331,7 +331,7 @@ test('detection holds nothing, and asks for its own frames instead', async () =>
'the valve asks the shared policy instead of inlining its own threshold');
assert.doesNotMatch(shouldPaint, /_lastPaintMs > 22/,
'the old inline threshold must be gone, not shadowing the policy');
assert.match(shouldPaint, /if \(decision\.requestFollowUp\) governorRequestRender\('detection-paint-skipped'\)/,
assert.match(shouldPaint, /if \(decision\.requestFollowUp\)\s*governorRequestRender\('detection-paint-skipped'\)/,
'skipping a paint must hand the request forward, not swallow it');
// The scanline must not go back to the frame counter: that is what made a
+4 -4
View File
@@ -222,8 +222,8 @@ test('the key handler refuses to act for a card that is not really on screen', (
assert.match(module, /isActive: \(\) => !closing && isTopmost\(\)/);
// Real visibility, not just the class: the class survives while CSS hides the
// card, which is precisely how a Scene left an invisible ESC handler armed.
assert.match(module, /const isTopmost = \(\) => root\.isConnected/);
assert.match(module, /&& root\.getClientRects\(\)\.length > 0\s*\n\s*&& !coveredByOverlay\(\);/);
assert.match(module, /const isTopmost = \(\) =>\s*root\.isConnected/);
assert.match(module, /&&\s*root\.getClientRects\(\)\.length > 0 &&\s*!coveredByOverlay\(\);/);
const keyboard = fs.readFileSync(new URL('./ui/surfaceKeyboard.js', import.meta.url), 'utf8');
const handler = keyboard.slice(keyboard.indexOf('const onKeyDown = (event) => {'));
assert.match(
@@ -373,7 +373,7 @@ test('the launcher yields on engage and waits when a surface is already up', ()
assert.match(module, /dismiss\(\{ restoreFocus: false \}\)/);
// A cheap attribute watch, not a per-frame poll — the render governor must
// not see a new hold because of onboarding chrome.
assert.match(module, /attributes: true, attributeFilter: \['class'\]/);
assert.match(module, /attributes: true,\s*attributeFilter: \['class'\]/);
assert.match(module, /surfaceObserver\?\.disconnect\(\)/);
assert.doesNotMatch(module, /setInterval|requestAnimationFrame\(function poll/);
});
@@ -536,7 +536,7 @@ test('no mission writes a preference the visitor did not choose by picking it',
const panelWrites = code.match(/setPanelCollapsed/g) || [];
assert.equal(panelWrites.length, 1, 'exactly one panel reveal, on the Context path');
const contextPath = code.slice(code.indexOf('setContextMode: async (mode)'), code.indexOf('setLayerEnabled:'));
assert.match(contextPath, /result\?\.ok[\s\S]*?setPanelCollapsed\?\.\('global-context-panel', false, \{ explicit: true \}\)/);
assert.match(contextPath, /result\?\.ok[\s\S]*?setPanelCollapsed\?\.\('global-context-panel', false, \{\s*explicit: true,?\s*\}\)/);
});
test('the decision table is written down where the next editor will read it', () => {
+1 -1
View File
@@ -108,7 +108,7 @@ test('hud.js corrects the camera height to MSL through the geoid module', () =>
'the ~2.7 MB grid must be requested once, on demand — not at HUD construction',
);
assert.equal(
has(/\.catch\(\(\) => \{ \/\* readout falls back to the uncorrected height \*\/ \}\)/),
has(/\.catch\(\(\) => \{\s*\/\* readout falls back to the uncorrected height \*\/\s*\}\)/),
true,
'a failed geoid load must leave the readout uncorrected, not unhandled',
);
+1 -1
View File
@@ -349,5 +349,5 @@ test('successful explicit user playback hands the speaker from voice to Radio',
assert.match(radioBindings, /togglePlayback\(\{ origin: 'user' \}\)/);
assert.match(radioBindings, /cycleStation\(direction, \{[\s\S]*?origin: 'user'/);
assert.match(radioBindings, /commitTuningStation\(station\.id, \{ origin: 'user' \}\)/);
assert.match(realtime, /event\.origin === 'user' && event\.action === 'play' && this\.isActive\(\)[\s\S]*?this\.stop\(\{ preserveRadioPlayback: true \}\)/);
assert.match(realtime, /event\.origin === 'user' &&\s*event\.action === 'play' &&\s*this\.isActive\(\)[\s\S]*?this\.stop\(\{ preserveRadioPlayback: true \}\)/);
});
+90
View File
@@ -1,4 +1,5 @@
import test from 'node:test';
import { execFileSync } from 'node:child_process';
import assert from 'node:assert/strict';
import {
mkdtemp,
@@ -93,3 +94,92 @@ test(
);
},
);
test('runtime discovery includes new nested modules and respects Git and formatter exclusions', async (t) => {
const root = await fixture(t);
execFileSync('git', ['init', '-q'], { cwd: root });
await mkdir(path.join(root, 'src/nested'), { recursive: true });
await mkdir(path.join(root, 'vendor'), { recursive: true });
await writeFile(
path.join(root, 'scripts/format-runtime.json'),
JSON.stringify({ roots: ['src'] }),
);
await writeFile(path.join(root, '.gitignore'), 'src/ignored.js\n');
await writeFile(path.join(root, '.prettierignore'), 'src/generated.js\n');
const source = 'export const value="yes"';
for (const name of [
'src/nested/new.js',
'src/module.mjs',
'src/check.test.mjs',
'src/ignored.js',
'src/generated.js',
'vendor/other.js',
])
await writeFile(path.join(root, name), source);
const expected = ['adopted.js', 'src/module.mjs', 'src/nested/new.js'];
assert.deepEqual(
(await formatAdoptedFiles(root, '--check')).changed,
expected,
);
await formatAdoptedFiles(root, '--write');
assert.deepEqual((await formatAdoptedFiles(root, '--check')).changed, []);
for (const name of [
'src/check.test.mjs',
'src/ignored.js',
'src/generated.js',
'vendor/other.js',
])
assert.equal(await readFile(path.join(root, name), 'utf8'), source);
});
test('runtime scope rejects unsafe roots before formatting existing entries', async (t) => {
for (const roots of [
[],
['src', 'src'],
['../outside'],
['/absolute'],
['.'],
['src/*'],
]) {
const root = await fixture(t);
await writeFile(
path.join(root, 'scripts/format-runtime.json'),
JSON.stringify({ roots }),
);
await assert.rejects(
formatAdoptedFiles(root, '--write'),
/Runtime formatting roots/,
);
assert.equal(
await readFile(path.join(root, 'adopted.js'), 'utf8'),
'const value="yes"\r\n',
);
}
});
test(
'discovered runtime symlinks cannot escape the repository',
{ skip: process.platform === 'win32' },
async (t) => {
const root = await fixture(t);
const other = await fixture(t);
execFileSync('git', ['init', '-q'], { cwd: root });
await mkdir(path.join(root, 'src'));
await writeFile(
path.join(root, 'scripts/format-runtime.json'),
JSON.stringify({ roots: ['src'] }),
);
await symlink(
path.join(other, 'adopted.js'),
path.join(root, 'src/outside.js'),
);
await assert.rejects(
formatAdoptedFiles(root, '--write'),
/repository files/,
);
assert.equal(
await readFile(path.join(root, 'adopted.js'), 'utf8'),
'const value="yes"\r\n',
);
},
);
+1 -1
View File
@@ -30,7 +30,7 @@ test('aircraft identity narration acknowledges missing enrichment', () => {
assert.match(followup, /explicitly cover operator, aircraft type, and route before finishing/);
assert.match(followup, /selectedProperties\.operator/);
assert.match(followup, /selectedProperties\.type/);
assert.match(followup, /selectedProperties\.route \|\| selectedProperties\.routeOrigin \|\| selectedProperties\.routeDestination/);
assert.match(followup, /selectedProperties\.route \|\|\s*selectedProperties\.routeOrigin \|\|\s*selectedProperties\.routeDestination/);
assert.match(followup, /Operator details are unavailable/);
assert.match(followup, /Aircraft type is unavailable/);
assert.match(followup, /Route details are unavailable/);