test(m126 r2): 加一支枚举不更新对外契约现在必然红(集合断言 + help 守卫)

r2 复审指出「加一家加载器会被逼着表态」只做到一半:编译期只拦「漏 match」,三处消费方
用最省事的 `=> Vanilla` 糊过去既编得过、测试也全绿——新加载器会静默显示成原版,正是本
mission 要消灭的形态(r1 里「Rift 会红」是负样本名字撞上的巧合,不是守卫)。

- presenter 的 `loader_kind_ids_are_the_released_contract` 增加**第 ② 段**:把 core 的
  `LoaderKind::ALL.map(as_str)` 与独立手写的七个 id 做**集合相等**比较。加一支而不更新
  契约 → 红;改词表 → 红。(r1 删掉 `assert!(ALL.len()==7)` 后缺的正是这一环:数组宽度
  只保证「表里那一行写成 7 个」,不保证枚举没多一支。)
- 新增 `cli::commands::instances::help_vocabulary_tests::help_lists_every_stable_id`:
  按 `LoaderKind::ALL` 遍历 `ull help instances` 的词表行,漏写一个新 id 必红(此前
  `help.rs:67` 那段词表没有任何测试,而旧的 `help_documents_the_loader_field_contract`
  只查关键词,加一家新加载器时它照样绿)。
- `addon::loader::tests::vocabulary` 补 `installable_list_matches_the_from_core_mapping`:
  把唯一还手写的 `LoaderKind::all()` 与 `from_core` 认可的集合对齐(不重抄字面量)。
- 模块文档第 ③ 步改成真话:契约测试会拦「改词表」与「加新种类」;但 `=> Vanilla` 这种
  糊法**编得过**,拦住它的是那条集合断言,不是编译器(改名同理,只有契约测试会红)。
- 一并修掉 presenter 那条测试 doc 里指向已被删除的 `MARKERS` /
  `markers_cover_every_kind_that_has_one` 的引用,改指向现在真实存在的守卫。
- loader.rs 从 398 压到 395(≤400,留 5 行余量;拆测试到子模块需要 scope 放宽到
  `crates/core/src/game/loader/**`,超出本任务文件清单,已按规矩记账)。

验收实测(临时加 `Abyss` + 三处 `=> Vanilla` 糊过去,已还原):presenter 契约测试红
(left 8 项 / right 7 项),CLI help 测试红(漏了 `abyss`);core 往返测试与安装侧清单
守卫、CLI 的 `json_rows_*` 仍绿(它们本就管别的事)。
This commit is contained in:
AskaEth committed 2026-11-05 18:08:59 +08:00
1 parent a322cfcbfe
commit 14ac0dc248
4 files changed
+101 -35

No files matched your search

@@ -61,3 +61,24 @@ fn modrinth_alias_is_input_only() {
assert_eq!(LoaderKind::parse(raw), None, "`{raw}` 不该被安装侧接受");
}
}
/// [`LoaderKind::all`] 是安装侧唯一还手写的清单(CF id 前缀匹配、CLI `--loader` 提示用),
/// 它与 [`LoaderKind::from_core`] 认可的集合必须一致——不重抄字面量,直接对映射本身。
///
/// 抓得住:往 core 加一家**能装**的加载器,`from_core` 补了却忘了 `all()`(CLI 提示会漏一家、
/// CF id 不认识它的前缀);反过来 `all()` 里多一家而 `from_core` 说装不了。
/// 抓不住:`all()` 的顺序(那是 CLI 提示的展示序,没有对外契约意义)。
#[test]
fn installable_list_matches_the_from_core_mapping() {
let mut derived: Vec<LoaderKind> = Wide::ALL
.into_iter()
.filter_map(LoaderKind::from_core)
.collect();
derived.sort_unstable();
let mut listed = LoaderKind::all().to_vec();
listed.sort_unstable();
assert_eq!(
listed, derived,
"`LoaderKind::all()` 必须正好是 `from_core` 认可的那几家"
);
}