Skip to content

Commit 1e58b8e

Browse files
NullVoxPopuliclaude
andcommitted
test(syntax): update error assertions to Peggy-native format
Parse errors now emit Peggy's diagnostic format: Unclosed element `div` --> route.hbs:1:1 | 1 | <div> | ^^^^^ Two changes: 1. test-utils/syntax-error.ts — adds `parseErrorFor(msg, source, module, line, col, spanLength?)` which replicates Peggy's format() output from the full source text + span position. Keeps `syntaxErrorFor(msg, code, module, line, col)` producing `formatSyntaxError` output for the semantic compiler errors in integration tests. 2. parser-node-test.ts — migrates all 20 syntaxErrorFor() calls to parseErrorFor(), passing the full template source and the correct span length derived by running the parser. The integration tests that test semantic errors (strict-mode-test.ts, dynamic-modifiers-test.ts) continue to use syntaxErrorFor unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
1 parent 60f862b commit 1e58b8e

2 files changed

Lines changed: 145 additions & 55 deletions

File tree

packages/@glimmer-workspace/test-utils/lib/syntax-error.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,63 @@
11
import { formatSyntaxError } from '@glimmer/syntax';
22

3+
/**
4+
* Build an expected error for parse errors thrown by the Peggy grammar.
5+
* Produces the Peggy-native diagnostic format:
6+
*
7+
* {message}
8+
* --> {module}:{line}:{col}
9+
* |
10+
* {line} | {full source line}
11+
* | ^^^^
12+
*
13+
* Parameters:
14+
* source – the full template source text (the same string passed to parse()).
15+
* line – 1-based line number.
16+
* column – 0-based column (SourceSpan.loc.start.column).
17+
* spanLength – number of '^' carets. Defaults to 1.
18+
*/
19+
export function parseErrorFor(
20+
message: string,
21+
source: string,
22+
moduleName: string,
23+
line: number,
24+
column: number,
25+
spanLength = 1
26+
): Error {
27+
const peggyCol = column + 1;
28+
const loc = `${moduleName}:${line}:${peggyCol}`;
29+
30+
let formatted: string;
31+
if (source) {
32+
const srcLines = source.split(/\r\n|\n|\r/g);
33+
const sourceLine = srcLines[line - 1] ?? '';
34+
const filler = ''.padEnd(String(line).length, ' ');
35+
const hatLen = spanLength || 1;
36+
formatted =
37+
`${message}\n --> ${loc}\n` +
38+
`${filler} |\n` +
39+
`${line} | ${sourceLine}\n` +
40+
`${filler} | ${''.padEnd(column, ' ')}${''.padEnd(hatLen, '^')}`;
41+
} else {
42+
formatted = `${message}\n at ${loc}`;
43+
}
44+
45+
const error = new Error(formatted);
46+
error.name = 'SyntaxError';
47+
return error;
48+
}
49+
50+
/**
51+
* Build an expected error for semantic compiler errors thrown via generateSyntaxError.
52+
* Produces the formatSyntaxError format (used outside of Peggy parse errors).
53+
*
54+
* {message}
55+
*
56+
* {line} | {code snippet}
57+
* | ^^^^^^^^^^^^^
58+
*
59+
* at {module}:{line}:{col}
60+
*/
361
export function syntaxErrorFor(
462
message: string,
563
code: string,

0 commit comments

Comments
 (0)