test(app-iced): M102 r3 护栏补到「页面调用点」——回退 body/软断点接线一律红,等价重构不再假红
r2 复审抓的两条 p1 都是「守卫只到函数内部」:把页面调用点改回 frame::single_column(变体 G)、
或把日志页两处 wrap::breakable 接线摘掉(变体 I),420 条全绿,而视觉复审 ① / ③ 原样回来。
r3 用 r2 自建的 layout/source.rs 把守卫推进到调用点,并把三条 p2 的假红/假强一并修掉:
- 新增 `single_column_pages_call_the_body_box_not_the_centred_one`:四个页面文件
(download / logs / instances / instances/detail,共 7 个调用点)必须出现 `frame::body(`、
不许出现 `frame::single_column(`;narrow_detail 单独再断言一次。(变体 G → 红)
- 新增 `the_page_wires_the_soft_breaks_into_both_rendering_paths`:扫 `lines::entry` 与
`diagnostic::summary_block`,必须含 `wrap::breakable(`(变体 I → 红);
同时把 `log_text_carries_soft_breaks_but_keeps_the_original` 的 docstring 改成它实际守的东西
(断点表 + 原文可还原),不再冒充「抓得住接线」。
- p2-1:`frame_body_is_built_from_the_block_quantities` 改用新的
`source::function_region`(函数体 + 本文件内被转调的函数,最多两层)⇒ 把 body 拆成
`body` → `body_impl` 的等价重构不再假红(H1 → 绿),换回 centered 仍红(A → 红)。
顺带修掉 region 的泛型签名 bug:早先拿 `fn {name}(` 当定义 needle,
遇到 `fn body_impl<'a>(` 会 panic(护栏自己假红);现在按 `fn {name}` 找定义,并补了一条
`the_region_follows_delegation_into_a_generic_function` 自测。
- p2-2:`list_column_spaces_rows_only_from_the_shared_constant` 的禁词收窄到
`let mut rows = column(…)` **这一条**构建链(新工具 `source::statement`,停在第一个 `;`),
于是 `column![head, scroller]` 上加合法间距不再假红(J → 绿),行容器叠间距仍红(D → 红)。
- p2-3:`frame::body` 的 align_x 改成「出现就必须是 `.align_x(Alignment::Start)`」,
不再被 `.align_y(Alignment::Start)` 顺手满足;「干脆不写 align_x」(默认 Start)视为等价重构放行。
- p2-4(措辞):`layout/block.rs` 文档写明 1440 上限是**有意行为变化**(≥1576 窗宽),
1180/900 上才是零像素变化。
变异矩阵(本轮自跑,逐条回滚,`git status` 已核):A/C/D/E/G/I 全红且各自只红对应那一条;
H1(body_impl 转调)/H2b(删显式 align_x)/H3(ROW_SPACING 经局部变量)/J(head/scroller 加合法间距)
全绿。基线 `cargo test -p unlucky-app-iced --lib` = 426 passed / 0 failed。
This commit is contained in:
1 parent
824bb36f8e
commit
f499961e5b
6 files changed
+238
-21
No files matched your search
@@ -138,24 +138,34 @@ fn body_block_starts_at_the_header_title_and_fills_the_page() {
|
||||
/// `centered(metrics.column, content)`(**就是视觉复审 ① 的改前写法**)不会红任何数值断言 ——
|
||||
/// M102 r1 的变异实测就是这样漏掉的(`pages/tests.rs` 那条只喂 `frame_metrics()` 与
|
||||
/// `body_width()`)。所以这条盯的是**摆法**:宽度来自 `body_width(metrics)`、左内边距来自
|
||||
/// `body_offset(metrics)`、对齐 `Start`,且不出现居中/散文列宽。
|
||||
/// `body_offset(metrics)`、`align_x` 只许是 `Start`(不写 = container 默认 Start,等价),
|
||||
/// 且不出现居中/散文列宽。
|
||||
///
|
||||
/// **抓得住**:`body()` 被换回居中、`align_x` 改成 `Center`、宽度改回 `metrics.column`;
|
||||
/// **抓不住**:绕过这段契约的重写(先取局部变量再建盒)——它守的是这 8 行的写法契约。
|
||||
/// 扫的是 [`layout::source::function_region`](函数体 + 本文件内被它转调的函数),
|
||||
/// 所以「拆成 `body` → `body_impl` 两层再转调」这种**等价重构不假红**(r2 复审的变异 H1)。
|
||||
///
|
||||
/// **抓得住**:`body()` 被换回居中(变异 A)、宽度改回 `metrics.column`、`align_x` 改成 `Center`;
|
||||
/// **抓不住**:跨文件转调、或先赋局部变量再建盒的写法(见 `layout/source.rs` 的边界说明)。
|
||||
#[test]
|
||||
fn frame_body_is_built_from_the_block_quantities() {
|
||||
let body = layout::source::function_body(include_str!("frame.rs"), "pub fn body<'a>(");
|
||||
let body = layout::source::function_region(include_str!("frame.rs"), "pub fn body<'a>(");
|
||||
|
||||
for needle in [
|
||||
"body_width(metrics)",
|
||||
"body_offset(metrics)",
|
||||
"Alignment::Start",
|
||||
] {
|
||||
for needle in ["body_width(metrics)", "body_offset(metrics)"] {
|
||||
assert!(
|
||||
body.contains(needle),
|
||||
"`frame::body` 必须从 {needle} 建盒(贴左 + 块宽 + 零偏移):\n{body}"
|
||||
);
|
||||
}
|
||||
|
||||
// `align_x` 出现就必须是 Start:`.align_y(Alignment::Start)` 单独存在不算数(r2 复审 P2-3),
|
||||
// 而「干脆不写 align_x」(container 默认 Start)视为等价重构,放行。
|
||||
if let Some(at) = body.find(".align_x(") {
|
||||
assert!(
|
||||
body[at..].starts_with(".align_x(Alignment::Start)"),
|
||||
"`frame::body` 的 align_x 只许是 Start:\n{body}"
|
||||
);
|
||||
}
|
||||
|
||||
for forbidden in [
|
||||
"centered(",
|
||||
"single_column(",
|
||||
@@ -188,6 +198,45 @@ fn frame_prose_is_built_from_the_prose_width() {
|
||||
}
|
||||
}
|
||||
|
||||
/// **源码结构(调用点)**:单列页必须调 `frame::body`,不许退回 `frame::single_column`。
|
||||
///
|
||||
/// r2 复审的变异 G:把四个页面文件里的 7 个调用点(`download.rs` 2 / `logs.rs` 3 /
|
||||
/// `instances.rs` 1 / `instances/detail.rs` 1)一键改回 `frame::single_column` ⇒ 420 条全绿,
|
||||
/// 而视觉复审 ① 原样回来。r2 的护栏只盯 `frame::body` **内部**,`single_column` 又是为设置页
|
||||
/// 合法保留的,所以「哪个页面用它」必须单独守。
|
||||
///
|
||||
/// 逐文件断言(而不是只数一条调用):**同一个文件里退一个调用点**也会让
|
||||
/// `frame::single_column(` 出现,立刻红。
|
||||
///
|
||||
/// **抓得住**:页面退回居中的老写法(视觉复审 ① 原样);
|
||||
/// **抓不住**:新增的页面文件(它不在这个清单里——新页要自己登记)。
|
||||
#[test]
|
||||
fn single_column_pages_call_the_body_box_not_the_centred_one() {
|
||||
for (name, source) in [
|
||||
("download.rs", include_str!("download.rs")),
|
||||
("logs.rs", include_str!("logs.rs")),
|
||||
("instances.rs", include_str!("instances.rs")),
|
||||
("instances/detail.rs", include_str!("instances/detail.rs")),
|
||||
] {
|
||||
assert!(
|
||||
source.contains("frame::body("),
|
||||
"{name} 没有调用 frame::body —— 正文块不再从块宽/块偏移建盒"
|
||||
);
|
||||
assert!(
|
||||
!source.contains("frame::single_column("),
|
||||
"{name} 退回了 frame::single_column(= 424 居中,视觉复审 ① 的原样)"
|
||||
);
|
||||
}
|
||||
|
||||
// 实例页窄窗那一屏的唯一入口也得走 body
|
||||
let narrow =
|
||||
layout::source::function_body(include_str!("instances/detail.rs"), "fn narrow_detail");
|
||||
assert!(
|
||||
narrow.contains("frame::body("),
|
||||
"narrow_detail 没走 frame::body:\n{narrow}"
|
||||
);
|
||||
}
|
||||
|
||||
/// **M84 的行宽红线**:任何页、任何窗口宽度、任何版面,正文列都不许超过 424px。
|
||||
///
|
||||
/// **抓得住**:`frame_metrics` 的 `column`(页面唯一的列宽来源)不会越界;
|
||||
|
||||
Reference in new issue
Block a user