Repository navigation
Conversation
clauderic
added this pull request to stack #1360
October 21, 2026 00:48
This was referenced Oct 21, 2026
clauderic
force-pushed
the
parser-specs
branch
2 times, most recently
from
October 21, 2026 12:47
a1ef941 to
134ae37
Compare
2 tasks done
clauderic
force-pushed
the
parser-specs
branch
from
October 21, 2026 12:59
134ae37 to
f264339
Compare
clauderic
force-pushed
the
parser-specs
branch
from
October 21, 2026 14:49
f264339 to
f8f191e
Compare
The Liquid HTML parser gets language-neutral specs in specs/parser: a YAML list of cases, each a template, the parses it's for (html, liquid or both) and the whole tree it parses to, or the error it throws. Positions are a 0-based line and UTF-16 character, and the text they cover. specs/parser/README.md describes the format. packages/liquid-html-parser/src/specs.test.ts runs them with the rest of the suite. With UPDATE_SPECS=1, it writes each case's tree or error from this parser instead. Every parse the parser tests made became a case, recorded from the suite, re-run from the YAML and compared: 591 parses, 412 cases. A test was deleted when all of its parses became cases and everything it asserted was a function of what those parses returned. Coverage of liquid-html-parser is unchanged, except one branch of deepGet, which only tests use. Three more cases cover what no test did: a description glued to @description (@descriptionText), a position after an emoji, which is two UTF-16 code units, and an error after emoji and past the first line. These stay in TypeScript: - tests of the tokenizers, the node factories, tolerant parsing and the tree builder; - tests that parse with allowUnclosedDocumentNode other than its default; - the completion-mode tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
clauderic
force-pushed
the
parser-specs
branch
from
October 22, 2026 00:51
f8f191e to
ff7de33
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #1347, which is stacked on #1357. Review those first; this PR's base moves down the stack as they merge.
What are you adding in this PR?
The parser tests become executable, language-neutral specs, like the check specs in #1347: YAML files in
specs/parser/, at the repo root. Each case is a template, the parses it's for, and the whole tree it parses to:parsenames the parses, not TypeScript functions:htmlis Liquid and HTML (toLiquidHtmlAST), andliquidis Liquid with HTML as text (toLiquidAST). When they give different results for a template, they're two cases.astis every node with every property. A case fails on a missing, extra or different one, so there's no partial matching and no snapshot.errorinstead: its message, and where it is.[line, character]in UTF-16, and the text it covers, cut out of the template at the range. That's how the check specs give offenses.src/specs.test.tsruns them with the rest of the suite. WithUPDATE_SPECS=1, it writes each case's tree or error from this parser instead, so writing a case is writing itsname,sourceandparse.specs/parser/README.mdcovers the format, what the trees leave out (the template on every node, and the links between nodes, which the parser doesn't set), and errors.The specs cover what the parser builds, not how. Another implementation can tokenize however it likes, as long as it builds the same trees.
The specs replace the tests they cover:
How the conversion was done, and checked
toLiquidHtmlASTandtoLiquidASTcall in the parser tests was recorded from the running suite: 591 parses, which became 412 cases, since many tests parse the same template.expectin it was about what those parses returned. As in Add executable check specs #1347, a script checks this with the TypeScript compiler API.deepGet, which only tests use.@description, as in@descriptionText; a position after an emoji, which is two UTF-16 code units; and an error after emoji, on the second line. Every other error case is on the first line.What stays in TypeScript
allowUnclosedDocumentNodeother than its default (11 calls).What's next? Any followup issues?
LiquidHTMLASTParsingErrorhas anunclosedproperty, the node left open, and the language server'sHtmlElementAutoclosingOnTypeFormattingProviderreads it. The parser never sets it, so the specs leave it out, and the runner fails if an error has one.What did you learn?
A position that ran past the end of the template couldn't be cut out of it, which is how #1357 turned up. An existing case recorded the same bug without anyone noticing: its unclosed
ifhappened to end inside the template, on\n.Tophatting
npx vitest run packages/liquid-html-parser/src/specs.test.tsruns just the 415 cases.textin a spec file.UPDATE_SPECS=1 npx vitest run packages/liquid-html-parser/src/specs.test.tsrewrites the specs, and changes nothing.Before you deploy
🤖 Generated with Claude Code