mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 16:02:32 +00:00
The ninth named group, and a pure query: it reads no shared state, so it has no qualifier sites at all. Two things this group forced. The generator now drops lint directive lines before the transform, because a directive inside an expression makes esbuild parenthesise that expression to keep the comment where it was, and those parentheses are tokens the document does not have. And the two regexes keep their `no-useless-escape` escapes behind a line-scoped disable, for the same reason the theme group keeps `Math.pow`. One name the document declares twice in one function stays `var`. Two block-scoped declarations would be two bindings where the document has one, and esbuild renames the inner one to say so. Counts: qualified 0, scope declarations 0, rebindings 31, braced bodies 20, unbound catches 0, number properties 2. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
87 lines
3.4 KiB
TypeScript
87 lines
3.4 KiB
TypeScript
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { afterAll, beforeAll, describe, expect, it } from 'vitest'
|
|
import { emitTerminalDocumentModule } from './build-terminal-document-script.mjs'
|
|
import { terminalBackgroundFallback } from '../src/terminal/document/document-constants'
|
|
|
|
/**
|
|
* What the generator drops, what it keeps, and how it puts a module back into the document.
|
|
*
|
|
* The per-group tests compare a real module against the string the document carries, which says
|
|
* the two agree; these say why, on inputs small enough to read. The import and export cases are
|
|
* the ones that bit: esbuild wraps a long list across lines, and skipping only the first line
|
|
* leaves the rest of the names loose in the document.
|
|
*/
|
|
let directory: string
|
|
|
|
async function emit(source: string): Promise<string> {
|
|
const path = join(directory, `module-${Math.random().toString(36).slice(2)}.ts`)
|
|
await writeFile(path, source)
|
|
return emitTerminalDocumentModule(path)
|
|
}
|
|
|
|
beforeAll(async () => {
|
|
directory = await mkdtemp(join(tmpdir(), 'orca-terminal-document-'))
|
|
})
|
|
|
|
afterAll(async () => {
|
|
await rm(directory, { recursive: true, force: true })
|
|
})
|
|
|
|
describe('emitting one terminal document module', () => {
|
|
it('unmarks an export and indents it into the document scope', async () => {
|
|
expect(await emit('export function f() {\n return 1\n}\n')).toBe(
|
|
' function f() {\n return 1;\n }'
|
|
)
|
|
})
|
|
|
|
it('drops an import that fits on one line', async () => {
|
|
expect(await emit("import { a } from './x'\nexport const b = 1\n")).toBe(' const b = 1;')
|
|
})
|
|
|
|
it('drops an import esbuild wrapped across lines', async () => {
|
|
// The case that produced an unparseable document: the names after the first line stayed.
|
|
const source =
|
|
"import { alpha, beta, gamma, delta, epsilon, zeta, eta, theta } from './document-externals'\n" +
|
|
'export const b = alpha\n'
|
|
expect(await emit(source)).toBe(' const b = alpha;')
|
|
})
|
|
|
|
it('drops the trailing export block esbuild prints, not just its keyword', async () => {
|
|
// Left behind it is a bare block statement, which parses and does nothing.
|
|
const emitted = await emit('function f() {}\nfunction g() {}\nexport { f, g }\n')
|
|
expect(emitted).not.toContain('{ f, g }')
|
|
expect(emitted).toBe(' function f() {\n }\n function g() {\n }')
|
|
})
|
|
|
|
it('erases types without touching the program', async () => {
|
|
expect(
|
|
await emit(
|
|
'export type T = { a: number }\nexport function f(v: T): number {\n return v.a\n}\n'
|
|
)
|
|
).toBe(' function f(v) {\n return v.a;\n }')
|
|
})
|
|
|
|
it('substitutes a build-time constant the document carries as a literal', async () => {
|
|
const emitted = await emit(
|
|
"import { terminalBackgroundFallback } from '../src/terminal/document/document-constants'\n" +
|
|
'export function paint() {\n' +
|
|
' return terminalBackgroundFallback\n' +
|
|
'}\n'
|
|
)
|
|
expect(emitted).toContain(JSON.stringify(terminalBackgroundFallback))
|
|
expect(emitted).not.toContain('terminalBackgroundFallback')
|
|
})
|
|
|
|
it('drops a lint directive rather than let it parenthesise the expression it guards', async () => {
|
|
expect(
|
|
await emit(
|
|
'export const R =\n' +
|
|
' // oxlint-disable-next-line no-useless-escape\n' +
|
|
' /a/g\n'
|
|
)
|
|
).toBe(' const R = /a/g;')
|
|
})
|
|
})
|