diff --git a/mobile/scripts/build-terminal-document-fixture.mjs b/mobile/scripts/build-terminal-document-fixture.mjs new file mode 100644 index 00000000000..f4c65a09c49 --- /dev/null +++ b/mobile/scripts/build-terminal-document-fixture.mjs @@ -0,0 +1,91 @@ +import { writeFile } from 'node:fs/promises' +import path from 'node:path' +import * as esbuild from 'esbuild' + +/** + * Writes the committed copy of the terminal WebView document that + * `terminal-document-identity.test.ts` diffs against. + * + * The document is a build artifact: fourteen source slices joined in a pinned order, with the + * generated xterm engine spliced into two of them. `terminal-webview-payload-hash.test.ts` already + * says *whether* it moved; what it cannot say is *where*, and a refactor whose whole claim is that + * the document did not move needs the diff, not the digest. + * + * The two generated engine strings are stored as placeholders rather than inline. They are already + * pinned by the hash test, they are regenerated by postinstall from whatever xterm version the + * lockfile holds, and inlining them would put 612 KiB of vendored bytes in the fixture and turn + * every xterm bump into an unreadable diff of the file that is supposed to isolate hand-written + * changes. + * + * Regenerating this fixture is a review event: it is only correct when the emitted document was + * meant to change, and the diff is the evidence for that. Run `node scripts/build-terminal-document-fixture.mjs` + * from `mobile/`. + */ +const mobileRoot = path.resolve(import.meta.dirname, '..') +const entry = path.join(mobileRoot, 'src', 'terminal', 'terminal-webview-html.ts') +const enginePath = path.join(mobileRoot, 'src', 'terminal', 'terminal-webview-engine.generated.ts') + +export const TERMINAL_DOCUMENT_FIXTURE_PATH = path.join( + mobileRoot, + 'src', + 'terminal', + 'terminal-document-golden.txt' +) + +/** Chosen so the document cannot contain one by accident; asserted below and in the test. */ +export const ENGINE_JS_PLACEHOLDER = '__ORCA_TERMINAL_ENGINE_JS__' +export const ENGINE_CSS_PLACEHOLDER = '__ORCA_TERMINAL_ENGINE_CSS__' + +async function loadModule(entryPoint) { + const result = await esbuild.build({ + entryPoints: [entryPoint], + bundle: true, + format: 'esm', + platform: 'node', + write: false, + logLevel: 'silent' + }) + const code = result.outputFiles[0].text + return import(`data:text/javascript;base64,${Buffer.from(code, 'utf8').toString('base64')}`) +} + +/** + * The document with both generated sections replaced by their placeholders. + * + * Exported so the test builds the same text the script writes, rather than restating the + * substitution and agreeing with a fixture that was written wrong. + */ +export function terminalDocumentFixture(document, engineJs, engineCss) { + for (const placeholder of [ENGINE_JS_PLACEHOLDER, ENGINE_CSS_PLACEHOLDER]) { + if (document.includes(placeholder)) { + throw new Error(`the document already contains ${placeholder}`) + } + } + for (const [name, value] of [ + ['XTERM_ENGINE_JS', engineJs], + ['XTERM_ENGINE_CSS', engineCss] + ]) { + if (document.split(value).length !== 2) { + throw new Error(`${name} does not appear exactly once in the document`) + } + } + return document + .replace(engineJs, ENGINE_JS_PLACEHOLDER) + .replace(engineCss, ENGINE_CSS_PLACEHOLDER) +} + +async function main() { + const [{ XTERM_HTML }, { XTERM_ENGINE_JS, XTERM_ENGINE_CSS }] = await Promise.all([ + loadModule(entry), + loadModule(enginePath) + ]) + const fixture = terminalDocumentFixture(XTERM_HTML, XTERM_ENGINE_JS, XTERM_ENGINE_CSS) + await writeFile(TERMINAL_DOCUMENT_FIXTURE_PATH, fixture) + console.log( + `[build-terminal-document-fixture] ${Buffer.byteLength(fixture, 'utf8')} bytes (document ${Buffer.byteLength(XTERM_HTML, 'utf8')})` + ) +} + +if (import.meta.filename === process.argv[1]) { + await main() +} diff --git a/mobile/src/terminal/terminal-document-golden.txt b/mobile/src/terminal/terminal-document-golden.txt new file mode 100644 index 00000000000..12a6d3e1fe0 --- /dev/null +++ b/mobile/src/terminal/terminal-document-golden.txt @@ -0,0 +1,2920 @@ + + +
+ + + + + + + +