@@ -179,6 +179,129 @@ for (const sample of jsoncSamples) {
179179
180180console . log ( `Validated ${ jsoncSamples . length } JSONC parser fixtures.` ) ;
181181
182+ const yamlBehaviorBundle = path . join ( os . tmpdir ( ) , "acode-yaml-behavior-test-bundle.mjs" ) ;
183+ const yamlBehaviorSource = String . raw `
184+ import assert from "node:assert/strict";
185+ import { EditorState } from "@codemirror/state";
186+ import { foldable, getIndentation, indentUnit, syntaxTree } from "@codemirror/language";
187+ import { classHighlighter, highlightTree } from "@lezer/highlight";
188+ import { yaml, yamlLanguage } from "./src/languages/yaml/index.js";
189+
190+ const source = [
191+ "%YAML 1.2",
192+ "---",
193+ "defaults: &defaults",
194+ " enabled: true",
195+ " retries: 3",
196+ " ratio: -1.25e+2",
197+ " missing: null",
198+ " image: ghcr.io/acme/app:latest",
199+ "jobs:",
200+ " build:",
201+ " <<: *defaults",
202+ " runs-on: ubuntu-latest # runner label",
203+ " strategy: {matrix: {node: [18, 20]}}",
204+ " steps:",
205+ " - name: Test",
206+ " run: |-",
207+ " npm test # block scalar content",
208+ "tagged: !!str value",
209+ "...",
210+ "",
211+ ].join("\n");
212+
213+ const tree = yamlLanguage.parser.parse(source);
214+ const names = new Set();
215+ const errors = [];
216+ tree.iterate({
217+ enter(node) {
218+ names.add(node.name);
219+ if (node.type.isError) errors.push([node.from, node.to]);
220+ },
221+ });
222+
223+ assert.equal(errors.length, 0, "YAML fixture produced parse errors");
224+ for (const name of [
225+ "Directive",
226+ "BlockMapping",
227+ "BlockSequence",
228+ "FlowMapping",
229+ "FlowSequence",
230+ "BlockLiteral",
231+ "Anchor",
232+ "Alias",
233+ "Tag",
234+ "Boolean",
235+ "Integer",
236+ "Float",
237+ "Null",
238+ "PlainString",
239+ ]) {
240+ assert(names.has(name), "YAML fixture did not produce " + name);
241+ }
242+
243+ const spans = [];
244+ highlightTree(tree, classHighlighter, (from, to, cls) => {
245+ spans.push({ text: source.slice(from, to), cls });
246+ });
247+
248+ function isHighlighted(text, tokenClass) {
249+ return spans.some((span) => span.text === text && span.cls.includes(tokenClass));
250+ }
251+
252+ assert(isHighlighted("defaults", "tok-propertyName"));
253+ assert(isHighlighted("true", "tok-bool"));
254+ assert(isHighlighted("3", "tok-number"));
255+ assert(isHighlighted("-1.25e+2", "tok-number"));
256+ assert(isHighlighted("null", "tok-keyword"));
257+ assert(isHighlighted("ubuntu-latest", "tok-string"));
258+ assert(isHighlighted("&defaults", "tok-labelName"));
259+ assert(isHighlighted("*defaults", "tok-labelName"));
260+ assert(isHighlighted("!!str", "tok-typeName"));
261+ assert(isHighlighted("# runner label", "tok-comment"));
262+ assert(!isHighlighted("# block scalar content", "tok-comment"));
263+
264+ const indentSource = "jobs:\n build:\n steps:\n - name: Test\n run: npm test\n";
265+ const indentState = EditorState.create({
266+ doc: indentSource,
267+ extensions: [yaml(), indentUnit.of(" ")],
268+ });
269+ syntaxTree(indentState);
270+ assert.equal(getIndentation(indentState, indentState.doc.line(4).from), 4);
271+ assert.equal(getIndentation(indentState, indentState.doc.line(5).from), 8);
272+ assert(foldable(indentState, indentState.doc.line(1).from, indentState.doc.line(1).to));
273+
274+ const flowSource = "matrix: {\n node: [18, 20]\n}\n";
275+ const flowState = EditorState.create({
276+ doc: flowSource,
277+ extensions: [yaml(), indentUnit.of(" ")],
278+ });
279+ syntaxTree(flowState);
280+ assert.equal(getIndentation(flowState, flowState.doc.line(3).from), 0);
281+
282+ console.log("Validated YAML parsing, highlighting, indentation, and folding fixtures.");
283+ ` ;
284+
285+ await build ( {
286+ stdin : {
287+ contents : yamlBehaviorSource ,
288+ resolveDir : process . cwd ( ) ,
289+ sourcefile : "yaml-behavior-test.mjs" ,
290+ loader : "js" ,
291+ } ,
292+ bundle : true ,
293+ format : "esm" ,
294+ platform : "node" ,
295+ outfile : yamlBehaviorBundle ,
296+ logLevel : "silent" ,
297+ } ) ;
298+
299+ try {
300+ await import ( pathToFileURL ( yamlBehaviorBundle ) . href + `?t=${ Date . now ( ) } ` ) ;
301+ } finally {
302+ fs . rmSync ( yamlBehaviorBundle , { force : true } ) ;
303+ }
304+
182305const { parser : ejsParser } = await bundledRequire (
183306 "src/languages/ejs/parser.js" ,
184307 "acode-ejs-parser-test.cjs" ,
@@ -487,4 +610,3 @@ for (const sample of gleamSamples) {
487610}
488611
489612console . log ( `Validated ${ gleamSamples . length } Gleam parser fixtures.` ) ;
490-
0 commit comments