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:
AskaEth committed 2026-11-04 19:53:43 +08:00
1 parent 824bb36f8e
commit f499961e5b
6 files changed
+238 -21

No files matched your search

+32 -4
View File
@@ -11,7 +11,7 @@ use unlucky_i18n::Lang;
use crate::theme::Families;
use super::super::layout::{frame_metrics, measure_cap_px, wrap, PaneKit};
use super::super::layout::{frame_metrics, measure_cap_px, source, wrap, PaneKit};
use super::model::{self, GROUPS, SUMMARY_HEADER};
use super::{demo, lines, *};
@@ -44,10 +44,13 @@ fn page_is_single_column_and_never_wider_than_the_measure_cap() {
}
}
/// **M102 ③**:日志行与一行摘要都带软断点——否则 iced 只能按字形硬断,`gl_o` / `peration` 复现。
/// **M102 ③**:`wrap::breakable` 这张表本身是好的,且**只改显示**(原文能还原)。
///
/// **抓得住**:`entry()` / `summary_block()` 又把原文直接喂给 `mono_owned`(软断点不见了);
/// **抓不住**:渲染器最终断在哪一列(那要量图,报告里有前后对照)。
/// **抓得住**:断点表被掏空(`BREAK_AFTER` 少了一档 ⇒ 长标识符又没有断点)、
/// `breakable` 开始污染原文(`strip` 还不了原);
/// **抓不住**:页面到底有没有把 `breakable` 接在渲染路径上——那条由
/// [`the_page_wires_the_soft_breaks_into_both_rendering_paths`] 扫调用点守
/// (r2 复审的变异 I:两处接线去掉后这条仍全绿,所以 docstring 不能替它吹牛)。
#[test]
fn log_text_carries_soft_breaks_but_keeps_the_original() {
let logs = demo::crash();
@@ -79,6 +82,31 @@ fn log_text_carries_soft_breaks_but_keeps_the_original() {
);
}
/// **源码结构(调用点)**:日志页必须把 `wrap::breakable` 接在**两条渲染路径**上。
///
/// r2 复审的变异 I:把 `lines::entry()` 的 `mono_owned(ui, wrap::breakable(body), …)` 改回
/// `mono(ui, body, …)`、把 `diagnostic::summary_block()` 的 `wrap::breakable(&logs.summary())`
/// 改回原文 ⇒ 420 条全绿,而视觉复审 ③(`graphics.gl_o` / `peration_failure`)原样回来。
/// 断点表那侧已经 [`log_text_carries_soft_breaks_but_keeps_the_original`] 守着了,
/// 这里守的是**接线**:页面真把显示串过了一遍它。
///
/// **抓得住**:任一处接线被摘掉(日志行 / 一行摘要);
/// **抓不住**:接线写得对但断点表被掏空(那是上一条的事)。
#[test]
fn the_page_wires_the_soft_breaks_into_both_rendering_paths() {
let entry = source::function_body(include_str!("lines.rs"), "fn entry");
assert!(
entry.contains("wrap::breakable("),
"日志行没接软断点(`graphics.gl_operation_failure` 会被按字形劈开):\n{entry}"
);
let summary = source::function_body(include_str!("diagnostic.rs"), "fn summary_block");
assert!(
summary.contains("wrap::breakable("),
"一行摘要没接软断点:\n{summary}"
);
}
#[test]
fn mono_lines_use_the_mono_stack_with_the_body_small_metrics() {
let ui = ui();