Conformance Suite
English · 简体中文
A language-neutral description of what this compiler must produce.
Every case is plain data — CSS text and JSON. Nothing in this directory imports the reference implementation, so any implementation in any language can be validated against it by walking cases/ and comparing strings.
The suite is the normative definition of the transform. When behaviour and suite disagree, the suite wins until a case is deliberately updated in the same commit that changes the behaviour.
Layout
cases/<group>/<name>/
case.json required — metadata and plugin options
input.css required — source stylesheet
expected.css required — exact expected outputcase.json
{
"description": "One sentence describing the guarantee under test.",
"from": "/project/src/app.css", // optional, default "/project/src/app.css"
"options": { }, // optional, default {}
"warnings": ["substring"] // optional, default []
}optionsis passed verbatim to the compiler.warningslists substrings that must each appear in exactly one emitted warning. The count must match the number of warnings emitted.
Encoding regular expressions
JSON has no regex literal, so options that accept a pattern also accept a tagged object:
{ "$regex": "\\.module\\.css$", "$flags": "i" }An implementation without regex support may skip cases that use this form and must report them as skipped rather than passed.
The universal invariant
Beyond matching expected.css, every case must satisfy one rule that has no fixture of its own:
Compiling
expected.cssagain must return it byte for byte.
It has no fixture because it is not a feature — it has to hold everywhere. A package that ships pre-compiled CSS goes through the consuming application's pipeline a second time, and a framework preset can register the compiler twice without saying so. Neither situation announces itself, so an implementation that is idempotent for the cases someone thought to write down is not idempotent.
Three behaviours exist only to satisfy it: bounded expressions that already carry a viewport unit are left alone, ignore directives survive into the output, and the root foundation is introduced by a marker comment that suppresses a second injection.
Deliberately out of scope
Options that take a callback (designWidth as a function, function file matchers) cannot be expressed as data and are therefore not covered here. They are exercised by the reference implementation's own unit tests. Keeping them out of the suite is intentional: the suite must stay portable.
Running
npm test # verifies every case
npm run conformance:update # rewrites expected.css from current behaviourconformance:update is a snapshot refresh. Always read the resulting diff — an unexpected change there is a behaviour regression, not a formatting detail.
Output normalisation
Comparison is done on the exact output string with only these normalisations:
\r\nis normalised to\n.- A single trailing newline is ignored.
Whitespace inside the CSS is significant, because preserving author formatting is itself a guarantee of this compiler.