diff --git a/README.md b/README.md index e8acbbf..6b3dc49 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,6 @@ builder. Calling the builder with a handler map keyed by `T`'s members returns a matcher: a function from `T` to the common return type. ```ts -import { strict as assert } from "node:assert"; import { getPrimitiveUnionMatcher } from "tiny-pattern-ts"; const matchAnswer = getPrimitiveUnionMatcher<"yes" | "no">(); @@ -65,7 +64,6 @@ Add a fallback as the second argument to leave members unhandled; the fallback receives the remainder: ```ts -import { strict as assert } from "node:assert"; import { getPrimitiveUnionMatcher } from "tiny-pattern-ts"; const matchLabel = getPrimitiveUnionMatcher<"yes" | "no" | "maybe">(); @@ -92,7 +90,6 @@ function takes the discriminant property's name and returns the handler-map builder, keyed by that property's tags. ```ts -import { strict as assert } from "node:assert"; import { getTaggedUnionMatcher } from "tiny-pattern-ts"; type Shape = diff --git a/development/docs.md b/development/docs.md index 8fa727c..d93aa0d 100644 --- a/development/docs.md +++ b/development/docs.md @@ -38,9 +38,8 @@ Compile every `ts / `typescript fence in the prose docs into a real `docs/` + `examples/` list is the natural extension; `development/` must never be scanned (its fences are illustrative, not compilable). - The generator hoists and merges leading imports, rewrites `tiny-pattern-ts` to - the `#test-tiny-pattern-ts` source alias, merges an example's `node:assert` - import into the prelude assert, and rejects an example that imports - `node:test` (the prelude binds `test`). Titles are the + the `#test-tiny-pattern-ts` source alias, and rejects an example that imports + `node:assert` / `node:test` (the prelude already binds both). Titles are the immediately preceding paragraph; a fence with no such paragraph is a fatal error, which keeps every example described. - `oxlint src/doc-test` reports "No files found" because the generated diff --git a/scripts/create-doc-tests.ts b/scripts/create-doc-tests.ts index ad23f15..3628dd9 100644 --- a/scripts/create-doc-tests.ts +++ b/scripts/create-doc-tests.ts @@ -46,14 +46,18 @@ const OUTPUT_DIR = "src/doc-test/__generated__"; const TYPESCRIPT_LANGS: ReadonlySet = new Set(["ts", "typescript"]); /** - * Modules the generated file already binds. An example that imports `node:test` - * would collide with the prelude `test` binding, so it is surfaced as a fatal - * error. `node:assert` is allowed: it is merged into the prelude assert import. + * Modules the generated file already imports. An example that imports one of + * these would collide with the prelude binding (duplicate `test` / `assert`), so + * it is surfaced as a fatal error and the example is rewritten. */ -const PRELUDE_MODULES: ReadonlySet = new Set(["node:test"]); +const PRELUDE_MODULES: ReadonlySet = new Set([ + "node:assert", + "node:test", +]); /** One line of the prelude every generated file starts with. */ const PRELUDE_TEST = 'import { test } from "node:test";'; +const PRELUDE_ASSERT = 'import { strict as assert } from "node:assert";'; /** Indentation applied to every fence body line inside the `test` callback. */ const INDENT = " "; @@ -321,17 +325,6 @@ const handleNode = (state: BuilderState, name: string, node: Block): void => { } }; -/** - * Guarantee `assert` is in scope in every generated file. The import is merged - * into any `node:assert` import an example already declares, so an example can - * stay self-contained without colliding with the harness. - */ -const ensurePreludeAssert = (named: Map): void => { - addNamedImport(named, { source: "node:assert", isType: false }, [ - "strict as assert", - ]); -}; - /** Walk one Markdown file and collect its cases and hoisted imports. */ const parseDoc = ( name: string, @@ -346,7 +339,6 @@ const parseDoc = ( for (const node of fromMarkdown(markdown).children) { handleNode(state, name, node); } - ensurePreludeAssert(state.named); return { named: state.named, passthrough: state.passthrough, @@ -376,6 +368,7 @@ const buildHeader = (name: string, imports: readonly string[]): string[] => { `// Source: ${name}`, EMPTY, PRELUDE_TEST, + PRELUDE_ASSERT, ]; if (imports.length > INITIAL_COUNT) { header.push(EMPTY, ...imports);