Biome JSON 格式化器 Prettier 兼容性测试套件:快照提取、运行与更新实战指南
Biome JSON 格式化器 Prettier 兼容性测试套件快照提取、运行与更新实战指南【免费下载链接】biomeA toolchain for web projects, aimed to provide functionalities to maintain them. Biome offers formatter and linter, usable via CLI and LSP.项目地址: https://gitcode.com/gh_mirrors/bi/biome本篇技术指南围绕 Biome 仓库中biome_json_formatter的 Prettier 兼容性测试套件展开讲解这套从 Prettier 上游仓库提取的快照测试如何运行、如何理解其.snap快照与差异报告以及当上游 Prettier 更新时如何重新提取并同步测试数据。读完本文你将掌握cargo test -p biome_json_formatter --test prettier_tests的完整使用方式、REPORT_PRETTIER1差异报告机制以及通过prepare_tests.js一键重建快照的标准化流程并能结合源码理解其底层工作原理。一、测试套件定位为什么 JSON 格式化器需要 Prettier 快照Biome 的格式化器在设计目标上与 Prettier 保持对齐因此需要一套能够持续度量两个格式化器输出差异的机制。这套 Prettier 测试套件的做法是直接把 Prettier 官方仓库中的格式化测试快照提取到 Biome 仓库内再让biome_json_formatter以这些快照为基准运行测试。相关说明见 crates/biome_json_formatter/tests/specs/prettier/README.md。从目录结构看测试输入组织在crates/biome_json_formatter/tests/specs/prettier/下按 JSON 语法特性分组json/json/基础 JSON 语法用例覆盖数组、布尔值、键值对、null、数字含pass1标准压力测试、正数、科学计数法、单行/多行、单引号、字符串转义等json/range/Range 格式化用例包含json-stringify、json5子目录以及跨数组cross-array、跨对象cross-object、issue-2297、issue-4009、issue-7116等历史回归场景json/with-comment/块注释、行注释在 JSON 中的排版行为json5-as-json-with-trailing-commas/以 JSON 语法解析 JSON5 风格的尾随逗号输入。每个用例目录下通常同时存在三种文件原始输入文件.json/.jsonc*.prettier-snap从 Prettier 仓库提取的 Prettier 期望输出*.snapBiome 运行后生成的 insta 快照内含与 Prettier 输出的逐行差异。二、运行 Prettier 兼容性测试2.1 随测试套件运行这些测试默认作为biome_json_formatter测试套件的一部分执行即普通的cargo test -p biome_json_formatter就会覆盖它们。也可以单独运行cargo test -p biome_json_formatter --test prettier_tests从测试入口 crates/biome_json_formatter/tests/prettier_tests.rs 可以看到该文件通过tests_macros::gen_tests!宏按目录通配符自动生成测试函数tests_macros::gen_tests! {tests/specs/prettier/{json}/**/*.{json,jsonc}, crate::test_snapshot, }即遍历tests/specs/prettier/json/下所有.json与.jsonc文件逐一执行test_snapshot。测试运行时默认使用空格缩进IndentStyle::Space与默认缩进宽度IndentWidth::default()与 Biome 的默认格式化配置保持一致let options JsonFormatOptions::default() .with_indent_style(IndentStyle::Space) .with_indent_width(IndentWidth::default());2.2 生成 Prettier 差异报告设置环境变量REPORT_PRETTIER1再运行测试会额外输出一份report.md文件其中包含biome_json_formatter输出与 Prettier 自身快照之间的全部差异而非仅失败用例。这适合做整体回归审计例如在大版本升级后量化与 Prettier 的对齐程度REPORT_PRETTIER1 cargo test -p biome_json_formatter --test prettier_tests三、测试机制源码解析3.1 输入文件的预处理快照运行器位于 crates/biome_formatter_test/src/test_prettier_snapshot.rs 中的PrettierTestFile。它在读取输入文件后会做两件事剥离占位符通过strip_prettier_placeholders解析输入中标记 Range 格式化范围的rangeStart/rangeEnd占位符得到可选的起止索引指令翻译把 Prettier 的prettier-ignore注释翻译成 Biome 的biome-ignore format: prettier ignore指令格式化完成后再翻译回来从而让两个生态的忽略语义在测试中一一对应const PRETTIER_IGNORE: str prettier-ignore; const BIOME_IGNORE: str biome-ignore format: prettier ignore;3.2 忽略列表PrettierSnapshot::test()会读取crates/biome_json_formatter/tests/specs/prettier_ignored_tests文件load_ignored_tests实际加载的是tests/specs/../prettier_ignored_tests即tests/specs/prettier_ignored_tests。凡是相对路径命中该列表中前缀模式的用例都会被跳过同时清理其残留的snap、snap.new、prettier-snap文件。这一机制用于暂时挂起已知不一致、尚未解决的用例。3.3 格式化与幂等性验证对每个用例PrettierSnapshot先解析输入再按三种情况分发存在 Range 范围时调用format_range将格式化结果回填到原输入中无 Range 时走format_node_once对整棵语法树执行格式化并打印对于含嵌入式代码的文档如 Vue/Svelte 模板则通过内存文件系统 workspace 服务调用format_document走完整文档格式化链路。当输入解析无错误时还会执行CheckReformat二次格式化验证——即把首次格式化输出再次作为输入格式化比较两次结果是否一致从而保证格式化器的幂等性格式化结果再次格式化不应发生变化。3.4 快照生成与差异展示PrettierSnapshot::test()最后调用get_prettier_diff比较 Biome 输出与*.prettier-snap若完全相同则直接返回不生成快照否则生成包含差异的.snap快照。快照结构由 crates/biome_formatter_test/src/snapshot_builder.rs 负责组装。以 crates/biome_json_formatter/tests/specs/prettier/json/json/pass1.json.snap 为例一份快照包含四个区块Input原始输入Prettier differences--- Prettier/ Biome格式的 unified diff精确指出差异行OutputBiome 的格式化输出Lines exceeding max width超出最大行宽默认 80的行清单。例如pass1.json的差异显示 Biome 在数字99.44与1066之间多保留了一个空行同时1e00、2e00、2e-00在 Biome 侧被规范化为1、2、2——这就是两个格式化器在空白保留与数字规范化策略上的典型差异也是该测试套件要持续跟踪的内容。四、更新快照从 Prettier 仓库重新提取当 Prettier 上游更新了 JSON 格式化行为或 Biome 需要纳入新的上游用例时需要重新提取快照。README 给出的标准流程如下克隆 Prettier 仓库到本地清理旧测试删除crates/biome_json_formatter/tests/specs/prettier下的所有目录确保已过时的测试被移除准备提取工具进入crates/biome_formatter_test/src/prettier目录执行pnpm install安装提取脚本依赖进入目标目录切换到crates/biome_json_formatter/tests/specs/prettier执行提取脚本node crates/biome_json_formatter/tests/specs/prettier/prepare_tests.js prettier root directory其中prettier root directory是第一步克隆的 Prettier 仓库根路径。脚本会遍历 Prettier 仓库的tests/format/json目录读取其 Jest 快照__snapshots__/format.test.js.snap把输入文件复制进 Biome 的 specs 目录并写出*.prettier-snap期望输出文件。Biome 侧对应入口是 crates/biome_json_formatter/tests/specs/prettier/prepare_tests.js它声明了语言类型与解析器await extractPrettierTests(json, { parser: json, });五、提取脚本核心原理5.1 与 Prettier 对齐的默认配置通用提取逻辑实现在 crates/biome_formatter_test/src/prettier/prepare_tests.js。由于 Biome 与 Prettier 的默认选项不同脚本用一套显式配置统一格式化期望输出const defaultConfig { trailingComma: all, tabWidth: 2, printWidth: 80, singleQuote: false, jsxSingleQuote: false, useTabs: false, embeddedLanguageFormatting: off };即尾随逗号全部启用、Tab 宽度 2、行宽 80、默认双引号、不使用 Tab、禁用嵌入式语言格式化。5.2 Jest 快照的解析Prettier 使用 Jest 运行快照测试快照文本内部用固定分隔线划分输入、选项与输出三段input、options、output、footer。脚本通过正则定位这些分隔符const optionsStart snapshotContent.match(new RegExp(OPTIONS \\n)); const optionsEnd snapshotContent.match(new RegExp(\\n INPUT)); const outputStart snapshotContent.match(new RegExp(OUTPUT \\n)); const outputEnd snapshotContent.match(new RegExp(\\n FOOTER));随后从options段落中解析 Range 选项并填充默认值const rangeOptions { rangeStart: Number(optionsContent.match(new RegExp(/rangeStart: (\d)/))?.[1] ?? 0), rangeEnd: Number(optionsContent.match(new RegExp(/rangeEnd: (\d)/))?.[1] ?? Infinity) };5.3 期望输出的再格式化与回退文件提取出的 Prettier 输出会先按上述统一配置重新用 Prettier 格式化一遍prettier.format以消除两方默认选项差异带来的噪声。如果重新格式化后的结果与原始快照不一致说明 Prettier 自身存在二次格式化不一致问题此时原始内容会被单独保存为*.prettier-snap-original文件供人工核查。若某个输入文件在 Jest 快照中没有对应键例如新增用例尚未生成快照脚本会回退到直接调用prettier.format(content, config)现场生成期望输出。依赖版本方面crates/biome_formatter_test/src/prettier/package.json 声明了prettier3.8.4因此提取结果对应的是该版本的 Prettier 行为。六、运行环境与前置条件工具链Rust 工作区测试依赖仓库根目录的Cargo.toml工作区配置运行cargo test前需确保 Rust 工具链就绪见 rust-toolchain.tomlNode.js 环境只有执行快照提取prepare_tests.js时才需要 Node.js 与 pnpm目录读写更新快照需要清理crates/biome_json_formatter/tests/specs/prettier下的旧目录属于维护者主动执行的开发操作快照断言体系.snap由 insta 管理见 insta.yaml测试失败时可借助 insta 工具链审查与接受新快照。七、实战排查建议先看差异再决定是否接受运行测试后若出现失败优先阅读.snap中的Prettier differences区块区分是 Biome 的行为变更需要接受新快照还是真正的回归需要修复格式化器。善用忽略列表对短期内无法对齐的用例可在crates/biome_json_formatter/tests/specs/prettier_ignored_tests中按前缀挂起同时清理对应残留快照文件。用 REPORT_PRETTIER 做整体评估在格式化行为大改前后分别生成report.md对比量化与 Prettier 的差异总数变化。更新前先备份重新提取快照前务必确认本地没有未提交的用例定制因为提取脚本会以 Prettier 仓库内容为准重建整个目录。八、关键文件速查用途仓库相对路径套件说明文档crates/biome_json_formatter/tests/specs/prettier/README.md测试入口宏生成用例crates/biome_json_formatter/tests/prettier_tests.rs快照运行器解析/格式化/diffcrates/biome_formatter_test/src/test_prettier_snapshot.rs快照构建器crates/biome_formatter_test/src/snapshot_builder.rs通用提取脚本含默认配置crates/biome_formatter_test/src/prettier/prepare_tests.jsJSON 提取入口crates/biome_json_formatter/tests/specs/prettier/prepare_tests.js提取脚本依赖Prettier 3.8.4crates/biome_formatter_test/src/prettier/package.json忽略用例列表crates/biome_json_formatter/tests/specs/prettier_ignored_tests结语这套 Prettier 兼容性测试套件是 Biome JSON 格式化器质量保障的关键一环它把上游 Prettier 的格式化预期固化成本地快照通过cargo test持续度量差异并通过prepare_tests.js提供了一条可复现的快照同步路径。理解其目录组织、运行机制与更新流程不仅有助于排查格式化回归也能为其他语言的 Prettier 对齐工作同一套biome_formatter_test基础设施被多种语言格式化器共用提供可直接复用的方法论。【免费下载链接】biomeA toolchain for web projects, aimed to provide functionalities to maintain them. Biome offers formatter and linter, usable via CLI and LSP.项目地址: https://gitcode.com/gh_mirrors/bi/biome创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考