From cfd771d1d8121e80791b8cc9cf148853c5b845d1 Mon Sep 17 00:00:00 2001 From: Michael Grundberg Date: Fri, 18 Sep 2026 18:44:04 +0200 Subject: [PATCH] test(terminal): pin all four buffer-load paths to the shared flush helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first version of this fix decided the flush policy in `selectSession` alone, and a later pass found it still covering one path of four. Nothing in the CI gate stops a fifth path, or an inlined `{ flushQueued: true }`, from splitting that policy up again — the browser suite that would notice is excluded from `npm test`. A static scan over `selectSession`, `_onSessionNeedsRefresh`, `_onSessionClearTerminal` and `_maybeRefetchFullHistory` asserts each one asks `_bufferLoadFinishOpts`, reusing the `methodBody` slice the sticky-scroll guard already needed. Verified by inlining the policy back into `_onSessionClearTerminal`, which fails it by name. Co-Authored-By: Claude Opus 5 (1M context) --- test/terminal-buffer-flush.test.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/terminal-buffer-flush.test.ts b/test/terminal-buffer-flush.test.ts index 36f652ef..9bc61771 100644 --- a/test/terminal-buffer-flush.test.ts +++ b/test/terminal-buffer-flush.test.ts @@ -339,6 +339,26 @@ describe('buffer-load flush (COD-144)', () => { } }); + it('every path that fetches a terminal buffer and writes it asks the shared helper', () => { + // Drift guard. The first version of this fix covered one of the four paths, + // and a later pass found it still covering one of four. Nothing else in the + // gate stops a fifth path, or an inlined `{ flushQueued: true }`, from + // splitting the policy up again; the browser suite that would notice does + // not run in CI. + const source = readFileSync(resolve(import.meta.dirname, '../src/web/public/app.js'), 'utf8'); + + for (const method of [ + 'selectSession', + '_onSessionNeedsRefresh', + '_onSessionClearTerminal', + '_maybeRefetchFullHistory', + ]) { + expect(methodBody(source, method), `${method} decides the flush policy itself`).toContain( + 'this._bufferLoadFinishOpts(' + ); + } + }); + it('empty queue + flushQueued is a no-op (no throw, no writes)', () => { const { app, writes } = makeApp(); const owner = app._beginBufferLoad('load-empty');