Public: anyone can read this; the crew can change it.
forked from trevato/cs
One GL recorder, behind the door: the renderer's test double stops being written four times #364
Check · Review · Land · Live done — Landed and live in production.
The engine now ships one fake WebGL2 context, `fakeGl()`, and its `GlRecorder` type from `src/engine/gl.ts`, alongside `fakePage`. It replaces four copies that had drifted apart: `stubGl` in `renderer.test.ts` and `glRecorder` in the shooter's, range's and example's `stage.test-helper.ts`. The range gains the `deleteVertexArray` and `deleteBuffer` its copy was missing. `bun run test` (typecheck pl…
shipped production is serving it deploy ae07c2d
The engine now ships one fake WebGL2 context, fakeGl(), and its GlRecorder type from src/engine/gl.ts, alongside fakePage. It replaces four copies that had drifted apart: stubGl in renderer.test.ts and glRecorder in the shooter's, range's and example's stage.test-helper.ts. The range gains the deleteVertexArray and deleteBuffer its copy was missing. bun run test (typecheck plus bun test) passes, 1448 tests, and rg "GL_ENUMS|export function glRecorder" src finds nothing.
The names are checked against the renderer. src/engine/gl.test.ts pulls every gl.<name> out of renderer.ts with comments removed. It fails if the renderer uses a name the recorder doesn't answer, or if the recorder still answers a name the renderer no longer uses. A separate test adds a fake gl.deleteTexture call and checks that the comparison reports it.
Written-out lists, not the example's Proxy. A Proxy needs no upkeep, but it answers any name, so a typo or a renamed GL call would pass every test. The lists are explicit and the test above keeps them in step with the renderer. The recorder still only records what was asked for and never grows into a fake GPU; that rule moved into gl.ts's docstring.
Resource kinds are now consistent. Shaders are "Shader" like every other kind; renderer.test.ts used "shader". No test reads that value. renderer.test.ts keeps its resources history.
The games keep only their own parts. Each helper keeps its ids, actions, audio and install(), and sets scene.gl = fakeGl(). The range's two test files import GlRecorder from the engine now. The docstrings in the three helpers and in page.ts that argued the recorder belonged to each game now say what is true.
Door, version and guide:
index.tsexports both names.surface.jsonmoves to 0.9.0, since two names were added and none removed.GUIDE.mdhas a new### glsection with its measured weight. The page section and the "a host" row of the seam table now namefakeGl. The page and whole-door weight lines are updated to whatscripts/cost.ts --guidereports today.
Not in any bundle:
- All three bundles are exactly the same size as on
main(app 125,524 B, range 40,816 B, example 25,004 B). gl.test.tschecks that no built bundle contains the module's marker sentence.- It also checks that no non-test file outside
gl.tsandindex.tsmentionsfakeGl, since tree-shaking could drop the sentence without dropping the code.
Also fixed: the flaky range boot test that failed the first preview. The range seeds each run from the clock. Its pop-up drill hangs plates with their feet up to 130 units high, but SHADOW_REACH in src/range/scene.ts was 128. On about 1.7% of seeds the first plate cast no shadow, and "every standing plate is one more draw" failed; main has the same flake, from #330.
SHADOW_REACHis now 160.- A new test in
src/range/scene.test.tsputs every drill's highest plate in a frame and expects a shadow under it. It failed before the change. - A script over all 65,536 seeds now finds none without a shadow, and the boot test passed 60 runs in a row.
- Side effect: every plate's shadow is a little darker and less wide than before.
Not done: nothing reads GL enum values from WebGL2RenderingContext itself; the numbers are only guaranteed distinct, which is all the tests need.
Where to look: src/engine/gl.ts, src/engine/gl.test.ts, the ### gl section of src/engine/GUIDE.md, and SHADOW_REACH in src/range/scene.ts. Try it with bun test src/engine/gl.test.ts; deleting a line from either list in gl.ts makes it fail and name the missing call.
🤖 Generated with Claude Code
The engine now ships one fake WebGL2 context,
fakeGl(), and itsGlRecordertype fromsrc/engine/gl.ts, alongsidefakePage. It replaces four copies that had drifted apart:stubGlinrenderer.test.tsandglRecorderin the shooter's, range's and example'sstage.test-helper.ts. The range gains thedeleteVertexArrayanddeleteBufferits copy was missing.bun run test(typecheck plusbun test) passes, 1447 tests, andrg "GL_ENUMS|export function glRecorder" srcfinds nothing.The names are checked against the renderer.
src/engine/gl.test.tspulls everygl.<name>out ofrenderer.tswith comments removed. It fails if the renderer uses a name the recorder doesn't answer, or if the recorder still answers a name the renderer no longer uses. A separate test adds a fakegl.deleteTexturecall and checks that the comparison reports it.Written-out lists, not the example's
Proxy. A Proxy needs no upkeep, but it answers any name, so a typo or a renamed GL call would pass every test. The lists are explicit and the test above keeps them in step with the renderer. The recorder still only records what was asked for and never grows into a fake GPU; that rule moved intogl.ts's docstring.Resource kinds are now consistent. Shaders are
"Shader"like every other kind;renderer.test.tsused"shader". No test reads that value.renderer.test.tskeeps itsresourceshistory.The games keep only their own parts. Each helper keeps its ids, actions, audio and
install(), and setsscene.gl = fakeGl(). The range's two test files importGlRecorderfrom the engine now. The docstrings in the three helpers and inpage.tsthat argued the recorder belonged to each game now say what is true.Door, version and guide:
index.tsexports both names.surface.jsonmoves to 0.9.0, since two names were added and none removed.GUIDE.mdhas a new### glsection with its measured weight. The page section and the "a host" row of the seam table now namefakeGl. The page and whole-door weight lines are updated to whatscripts/cost.ts --guidereports today.Not in any bundle:
main(app 125,524 B, range 40,816 B, example 25,004 B).gl.test.tschecks that no built bundle contains the module's marker sentence.gl.tsandindex.tsmentionsfakeGl, since tree-shaking could drop the sentence without dropping the code.Not done: nothing reads GL enum values from
WebGL2RenderingContextitself; the numbers are only guaranteed distinct, which is all the tests need.Where to look:
src/engine/gl.ts,src/engine/gl.test.ts, and the### glsection ofsrc/engine/GUIDE.md. Try it withbun test src/engine/gl.test.ts; deleting a line from either list ingl.tsmakes it fail and name the missing call.🤖 Generated with Claude Code
Closes #331