textmate-grammar-test
v0.4.2
Published
Test runner for VSCode textmate grammars
Maintainers
Readme
TextMate Grammar Test
Write unit and snapshot tests for TextMate grammars, validated against the VS Code TextMate engine.
📦 Installation
npm install --save-dev textmate-grammar-test🔄 Migrating from vscode-tmgrammar-test
Looking for up-to-date dependencies, cleaner and fully refactored codebase, plus additional bug fixes and features?
Migration is straightforward and should only take a few minutes:
- Install the new package:
npm i -D textmate-grammar-test - Replace occurrences of
vscode-tmgrammar-test->textmate-grammar-testvscode-tmgrammar-snap->textmate-grammar-snap
- Newer versions include a few minor breaking changes. For migration notes see:
🚀 Usage
This package provides the commands textmate-grammar-test and textmate-grammar-snap.
Add a package.json script like:
"scripts": {
"test:grammar": "npx textmate-grammar-test syntax/tests/**/*.foo"
}To see all available command line options, run:
npx textmate-grammar-test --help
# or
npx textmate-grammar-snap --help🧩 Unit Testing Syntax
File Header
Every test file must start with a header line in the format
<comment token> SYNTAX TEST "<scopeName>" "Optional description".
For example:
// SYNTAX TEST "source.ts" "Example header for a TypeScript grammar test"Require specific scopes
Assert that a token has a specific scope using ^:
let count: number = 1
// ^^^^^ variable.other.readwrite.ts
// ^^^^^^ support.type.primitive.tsYou can also assert multiple scopes on the same token. Scopes must be ordered from most general to most specifc:
let count: number = 1
// ^^^^^^ meta.type.annotation.ts meta.var-single-variable.expr.ts meta.var.expr.tsPrevent specific scopes
To ensure a token does not receive an unexpected scope,
use ! (surrounded by spaces):
/ not a comment
// ^ ! comment.line.double-slash.tsPositive and negative assertions can be combined.
The ! is only needed to separate the groups:
/ not a comment
// ^ source.ts ! comment.line.double-slash.ts storage.type.tsTest the first token of a line
To target a token at the start of a line, use <-.
The number of - characters defines the token length.
If an offset is needed, use ~:
let x = "a"
// <--- storage.type.ts
// With offset:
x = "b"
// <~~- keyword.operator.assignment.tsSnapshot tests
As alternative to manually writing test files, you can use textmate-grammar-snap to generate snapshots for the provied source files including tests for all scopes.
The resulting .snap files should be commited to version control alongside the test sources.
After making changes to a grammar, rerun the tool and review the diff. If the changes are expected, update the snapshots:
textmate-grammar-snap --updateSnapshot ...Language configuration via package.json
Needed information about the grammars is read from the package.json contribution points contributes.grammars and contributes.languages.
If it's not in your project root, provide the path with the --config option.
You can also pass the path to a custom json file imitating the structure.
Setup VSCode unit test task
You can setup a vscode unit test task for convenience:
{
"label": "Run tests",
"type": "shell",
"command": "textmate-grammar-test -c -g testcase/dhall.tmLanguage.json '**/*.dhall'",
"group": "test",
"presentation": {
"reveal": "always",
"panel":"new",
},
"problemMatcher": {
"owner": "textmate-grammar-test",
"fileLocation": [
"relative",
"${workspaceFolder}",
],
"pattern": [
{
"regexp": "^(ERROR)\\s([^:]+):(\\d+):(\\d+):(\\d+)\\s(.*)$",
"severity": 1,
"file": 2,
"line": 3,
"column": 4,
"endColumn": 5,
"message": 6,
},
],
},
},Notice the -c option that will output messages in a handy format for the problemMatcher.
📜 License
This repo is licensed under the MIT License.


