test(app-iced): P2-3 尺寸硬编码守门扩到 pages/(并补图标语汇守门)

代码 reviewer 指出:`no_hardcoded_tokens` 的**尺寸**守门只扫 `src/shell`,`pages/` 是新增目录、
**根本没被扫到**,页面里写 `.width(24)` 没人会发现(颜色守门扫全 `src/**`,所以颜色那条是覆盖的)。

- `shell_takes_every_size_from_tokens` → `layout_sources_take_every_size_from_tokens`:
  扫描面改成 `src/shell` + `src/pages`,并把「至少 2 个文件」的哨兵断言提到 **≥10 个**(防扫描逻辑坏掉)。
- 实测结果:**扩了之后 `pages/` 是干净的(0 处)**——所有尺寸都走 `layout::*` 常量 / `LayoutMetrics` /
  `Space` / `TypeStyle`,没有需要修的违规。
- 顺带补 `pages_use_only_stroked_icons`:`pages/` 里不许出现令牌层的填充字形(`Play`/`Stop`/`More`),
  这是视觉 P2-3「图标语汇不一致」的机器化守门(修法见下一条 commit)。
- 文件顶到 403 行 → 压到 399(仓库硬限 400)。
This commit is contained in:
AskaEth committed 2026-11-02 00:39:48 +08:00
1 parent 367100848a
commit a0ccf79b2b
1 file changed
+53 -5
+53 -5
View File
@@ -202,20 +202,26 @@ fn size_literal(argument: &str) -> Option<String> {
Some(number)
}
/// 尺寸字面量守门:`src/shell` + `src/pages` 都扫。
///
/// P2-3(M84 复审):原先只扫 `shell`,新增的 `pages/` **没被覆盖**(页面里写 `.width(24)` 没人发现)。
/// `pages/layout.rs` 允许有布局常量(它是布局系统的定义点),控件调用点上不许再出现字面量。
#[test]
fn shell_takes_every_size_from_tokens() {
fn layout_sources_take_every_size_from_tokens() {
let mut files = Vec::new();
rust_files(&manifest_dir().join("src").join("shell"), &mut files);
for dir in ["shell", "pages"] {
rust_files(&manifest_dir().join("src").join(dir), &mut files);
}
assert!(
files.len() >= 2,
"shell 模块至少有两个文件(mod.rs + nav.rs),实际扫到 {}",
files.len() >= 10,
"shell + pages 至少 10 个文件(shell 2 + pages 8+),实际扫到 {}:扫描逻辑坏了,这条门禁等于没跑",
files.len()
);
let mut offenders = Vec::new();
for path in files {
let text = std::fs::read_to_string(&path).expect("读 shell 源文件");
let text = std::fs::read_to_string(&path).expect("读布局源文件");
for (index, line) in text.lines().enumerate() {
// 文档注释是散文不是代码:里面写 `.width(24)` 是在解释坑,不该判违规
@@ -247,6 +253,48 @@ fn shell_takes_every_size_from_tokens() {
);
}
/// 图标语汇守门(视觉复审 P2-3):`pages/` 里只用**描边**字形。
///
/// 令牌层把 `Play` / `Stop` / `More` 定义成填充字形,其余是描边;页面骨架里混用会让同屏线宽
/// 语汇打架。将来要支持「主操作允许实心图标」,应由 `components/` 统一定义并只留一处。
#[test]
fn pages_use_only_stroked_icons() {
const FILLED: [&str; 3] = ["IconKind::Play", "IconKind::Stop", "IconKind::More"];
let mut files = Vec::new();
rust_files(&manifest_dir().join("src").join("pages"), &mut files);
assert!(
files.len() >= 8,
"pages 至少 8 个文件,实扫 {}",
files.len()
);
let mut offenders = Vec::new();
for path in files {
let text = std::fs::read_to_string(&path).expect("读 pages 源文件");
for (index, line) in text.lines().enumerate() {
if line.trim_start().starts_with("//") {
continue;
}
for kind in FILLED {
if line.contains(kind) {
offenders.push(format!("{}:{} {line:?}", path.display(), index + 1));
}
}
}
}
assert!(
offenders.is_empty(),
"pages 里出现了填充字形图标(令牌层 Play/Stop/More),与同屏描边语汇冲突:
{}",
offenders.join(
"
"
)
);
}
/// 依赖行里出现 `slint` 就算违规(注释行放过:说明并存期要提到 slint)。
fn manifest_has_slint_dependency(manifest: &str) -> Vec<String> {
manifest