// test/helpers/known-differences.ts // // The single source of truth for the known, deliberately documented ways // this parser's tree deviates from tree-sitter-bash 0.25.0. Every entry is: // - referenced by @known-diff samples in test/fixtures/differential/ and // test/fixtures/corpus/known-diffs.txt (the stored dump in each sample // pins the exact deviation shape — if our output drifts, or starts // matching the reference, the differential tests fail); // - anchored in README.md's "Known differences" section: `readmeAnchor` // must appear there verbatim, so the list and the README cannot // silently drift apart (enforced by test/differential.test.ts). export interface KnownDifference { /** Identifier referenced from fixture @known-diff directives. */ readonly id: string; /** Verbatim substring of README.md's Known differences section. */ readonly readmeAnchor: string; /** Short human-readable description. */ readonly summary: string; } export const KNOWN_DIFFERENCES: readonly KnownDifference[] = [ { id: 'redirect-readwrite', readmeAnchor: '`<>` (read-write redirect) is parsed as a normal `file_redirect`', summary: '<> parses as file_redirect; the reference fails to parse it.', }, { id: 'heredoc-multiple-on-line', readmeAnchor: 'Several heredocs on one line', summary: 'cat < is a word in the reference (scanner-state quirk); a continuation INSIDE a pattern is an error there. This parser classifies by content and keeps continuations.', }, { id: 'nonascii-identifier-assignment', readmeAnchor: 'A non-ASCII “identifier” in assignment position', summary: '变量=值 is a hasError variable_assignment in the reference; this parser keeps it a plain command word (bash itself rejects such names).', }, { id: 'case-rejected-group', readmeAnchor: 'An extglob group the reference rejects in a case pattern', summary: 'x@(y)): the reference reparses the group as a new case item; this parser degrades the whole pattern to ERROR.', }, { id: 'expansion-replacement-escaped-backslash', readmeAnchor: 'A double backslash in a replacement value (`${x// /\\\\|}`)', summary: 'The reference drops the first backslash (a quirk); this parser keeps both.', }, ]; const KNOWN_DIFFERENCE_IDS: ReadonlySet = new Set(KNOWN_DIFFERENCES.map((entry) => entry.id)); export function isKnownDifferenceId(id: string): boolean { return KNOWN_DIFFERENCE_IDS.has(id); }