# 一致性套件

[English](./README.md) · **简体中文**

对这个编译器必须产出什么的、与语言无关的描述。

每个用例都是纯数据——CSS 文本与 JSON。这个目录里没有任何东西 import 参考实现，因此任何语言的任何实现都可以通过遍历 `cases/` 并比对字符串来做验收。

这套用例是本转换的**规范定义**。行为与用例不一致时，以用例为准，直到某个用例在改变行为的同一个提交里被有意更新。

> 用例文本本身保持英文，因为它面向的是其它语言的实现者。使用说明请见 [docs/](../docs/README.zh-CN.md)。

## 目录结构

```
cases/<group>/<name>/
  case.json      必需 —— 元数据与插件选项
  input.css      必需 —— 源样式表
  expected.css   必需 —— 精确的期望输出
```

## `case.json`

```jsonc
{
  "description": "One sentence describing the guarantee under test.",
  "from": "/project/src/app.css",   // 可选，默认 "/project/src/app.css"
  "options": { },                    // 可选，默认 {}
  "warnings": ["substring"]          // 可选，默认 []
}
```

- `options` 原样传给编译器。
- `warnings` 列出的每个子串必须恰好出现在一条告警里，且条数要与实际发出的告警数相等。

### 正则表达式的编码方式

JSON 没有正则字面量，所以接受模式的选项同时接受一个带标签的对象：

```json
{ "$regex": "\\.module\\.css$", "$flags": "i" }
```

不支持正则的实现可以跳过使用这种形式的用例，但必须报告为「跳过」而不是「通过」。

## 那条通用不变量

除了要与 `expected.css` 一致，每个用例还必须满足一条没有专属 fixture 的规则：

> 把 `expected.css` 再编译一遍，必须逐字节返回原文。

它没有专属 fixture，是因为它不是一个特性——它必须处处成立。发布预编译 CSS 的包会再经过消费方应用的流水线一次，框架预设也可能不声不响地把编译器注册两遍。两种情况都不会自报家门，所以「对某人恰好写下来的那些用例幂等」的实现，其实并不幂等。

有三条行为的存在只是为了满足它：已经带视口单位的有界表达式不再处理、忽略指令保留在产物里、根基础样式由一条标记注释引入以抑制第二次注入。

## 刻意不覆盖的部分

接受**回调**的选项（`designWidth` 写成函数、函数式文件匹配器）无法表达成数据，因此不在这里覆盖，改由参考实现自己的单元测试验证。把它们排除在外是有意的：这套用例必须保持可移植。

## 运行

```bash
npm test                    # 校验全部用例
npm run conformance:update  # 按当前行为重写 expected.css
```

`conformance:update` 是一次快照刷新。务必读一遍产生的 diff——那里出现意料之外的变化，是行为回归，不是格式细节。

## 输出归一化

比对针对精确的输出字符串，只做这两项归一化：

1. `\r\n` 归一为 `\n`；
2. 忽略结尾的单个换行。

CSS 内部的空白是有意义的，因为保留作者的排版本身就是这个编译器的一项保证。
