feat(app-iced): M101 r2 设置页状态漏斗 + pages/mod.rs 拆分 + r1 复审订正
r1 复审的 P1:消息漏斗只解决了「加一支消息」,一组要画真值仍要改 `settings/mod.rs` (`Group.body` 与 `view` 只认 `appearance::State`)。本 commit 补齐与消息漏斗同构的状态漏斗: - 新增 `pages/settings/state.rs`:`Groups`(一个组一个字段,字段类型在组自己文件里)+ `States`(按值传给渲染器的只读视图:外观状态 + 组状态)+ `demo_groups()`(harness 的 `'static` 默认状态)。 - `Group.body` 签名改成 `for<'a> fn(&'a Ui, States<'a>) -> Option<Element>`:每组自己从 `States` 取自己要的数据,「没有可画的状态」返回 `None` 由 `form` 退回演示行。 `appearance` 组照旧接 `pages/appearance/section.rs`(M93 路径行为不变)。 - `App.settings: pages::settings::Groups`(`app/state.rs` 字段列表末尾)+ `app/view.rs` 构造 `States` 走新入口 `pages::page_with_settings`。加/改某一组的字段只改那一组的文件。 - 四个组各自的 `State` 落在各自文件;`java::Message` 留一支只有测试构造的 `Ping`,配 `app/update/settings/tests.rs` 的 `a_group_message_reaches_its_handler_through_the_funnel` ——消息漏斗第一次有**运行时**证据。 r1 其余条目: - P2-1 删掉 `only_the_appearance_group_carries_a_real_control_body`(被四条 per-group 断言蕴含), 并在同处写明删掉之后「唯一性」没人守;三份 section 文档从「改 3 个文件」订正为 2 个。 - P2-2 `pub mod settings` → `pub(crate) mod settings`(四个消息口模块 `pub(crate)`), 并订正两处理由(lint 按类型自身可见性判,不是可达性)。 - P2-3 `pages/mod.rs` 397 行 → 拆出 `pages/message.rs` / `pages/screen.rs`(纯搬移,`pub use` 保证 `pages::Message` / `Action` / `Screen` 路径不变),并删掉 M101 自己那 18 行重复文档。 - P3-1 订正共享点清单(`Key` 由宏从域文件累积生成,加 key 不改 `catalog.rs`)。 - P3-2 守门改成「除已知臂外任何含 `=>` 的行都算兜底」(`other =>` 也拦),并加「恰好四臂」断言。 - P3-3 `ai.rs` → `ai_about.rs` 单独一条 R100 改名提交,`git log --follow` 不断链。 - P3-4 `message.rs` 的「加一支消息改 1 个文件」订正为 2 个。
This commit is contained in:
1 parent
423ea77758
commit
029ece3f17
25 files changed
+1004
-240
No files matched your search
@@ -1,8 +1,8 @@
|
||||
//! 「Downloads」分组自己的断言(M100 **新增**:`settings/tests.rs` 那 7 条全是跨 section 的,
|
||||
//! 一条 section 断言都没有;这 3 条是新增,不是搬移)。
|
||||
//!
|
||||
//! **归 download 线**。接真控件那天要改**三个**文件:本文件 `the_downloads_group_is_still_demo_rows`
|
||||
//! (`body.is_none()` 绊线)+ `settings/download.rs` + `tests/mod.rs` 的跨 section 绊线。
|
||||
//! **归 download 线**。接真控件那天要改**两个**文件(M101 r2 删掉了原先的第 3 处跨 section 绊线):
|
||||
//! `settings/download.rs` + 本文件 `the_downloads_group_is_still_demo_rows`。
|
||||
//!
|
||||
//! 别把它和下载页(`pages/download*`)搞混:那是「装哪个版本」,这一组是「怎么下」的默认值。
|
||||
|
||||
@@ -38,8 +38,8 @@ fn the_downloads_group_keeps_its_icon() {
|
||||
/// 抓得住:download 线接上了 `body` 却没更新这里的期望(那会让本文件静默变成假绿)。
|
||||
/// 抓不住:界面上真控件长什么样。
|
||||
///
|
||||
/// 接真控件时:把 `is_none()` 改成 `is_some()`,**只改这一行**;再去 `tests/mod.rs` 的
|
||||
/// `only_the_appearance_group_carries_a_real_control_body` 那条绊线上手工确认一次(那条是四组共用的)。
|
||||
/// 接真控件时:把 `is_none()` 改成 `is_some()`,**只改这一行**(M101 r2 起不必再去
|
||||
/// `tests/mod.rs` 报到:那条跨 section 聚合绊线已删)。
|
||||
#[test]
|
||||
fn the_downloads_group_is_still_demo_rows() {
|
||||
assert!(
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
//! 「General」分组自己的断言(M100 **新增**:`settings/tests.rs` 那 7 条全是跨 section 的,
|
||||
//! 一条 section 断言都没有;这 3 条是新增,不是搬移)。
|
||||
//!
|
||||
//! **归 language+appearance 线**。接真控件那天要改**三个**文件:本文件
|
||||
//! `the_general_group_is_still_demo_rows`(`body.is_none()` 绊线)+ `settings/general.rs` +
|
||||
//! `tests/mod.rs` 的跨 section 绊线。
|
||||
//! **归 language+appearance 线**。接真控件那天要改**两个**文件(M101 r2 删掉了原先的第 3 处跨
|
||||
//! section 绊线):`settings/general.rs` + 本文件 `the_general_group_is_still_demo_rows`。
|
||||
|
||||
use super::super::general;
|
||||
use unlucky_design::icons::IconKind;
|
||||
@@ -38,8 +37,8 @@ fn the_general_group_keeps_its_icon() {
|
||||
/// 抓得住:language+appearance 线接上了 `body` 却没更新这里的期望(那会让本文件静默变成假绿)。
|
||||
/// 抓不住:界面上真控件长什么样。
|
||||
///
|
||||
/// 接真控件时:把 `is_none()` 改成 `is_some()`,**只改这一行**;再去 `tests/mod.rs` 的
|
||||
/// `only_the_appearance_group_carries_a_real_control_body` 那条绊线上手工确认一次(那条是四组共用的)。
|
||||
/// 接真控件时:把 `is_none()` 改成 `is_some()`,**只改这一行**(M101 r2 起不必再去
|
||||
/// `tests/mod.rs` 报到:那条跨 section 聚合绊线已删)。
|
||||
#[test]
|
||||
fn the_general_group_is_still_demo_rows() {
|
||||
assert!(
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
//! 「Java」分组自己的断言(M100 **新增**:`settings/tests.rs` 里一条 section 断言都没有,
|
||||
//! 那 7 条全是跨 section 的;所以这 3 条是新增,不是搬移)。
|
||||
//!
|
||||
//! **归 java 线**。接真控件那天要改**三个**文件:
|
||||
//! 1. 本文件 `the_java_group_is_still_demo_rows`(它断言 `body.is_none()`,接上就红);
|
||||
//! 2. `settings/java.rs`(写 `body = Some(..)`);
|
||||
//! 3. `tests/mod.rs` 的 `only_the_appearance_group_carries_a_real_control_body`(跨 section 绊线)。
|
||||
//! **归 java 线**。接真控件那天要改**两个**文件(M101 r2 删掉了原先的第 3 处跨 section 绊线,
|
||||
//! 见 `tests/mod.rs` 的 `every_line_can_be_wired_alone` 说明):
|
||||
//! 1. `settings/java.rs`(`body = Some(java::body)` + 渲染器);
|
||||
//! 2. 本文件 `the_java_group_is_still_demo_rows`(把 `is_none()` 改成 `is_some()`)。
|
||||
//!
|
||||
//! download / general 同型。
|
||||
//!
|
||||
@@ -46,8 +46,8 @@ fn the_java_group_keeps_the_folder_icon_from_the_visual_review() {
|
||||
/// 抓得住:java 线接上了 `body` 却没更新这里的期望(那会让本文件静默变成假绿)。
|
||||
/// 抓不住:界面上真控件长什么样。
|
||||
///
|
||||
/// 接真控件时:把 `is_none()` 改成 `is_some()`,**只改这一行**;再去 `tests/mod.rs` 的
|
||||
/// `only_the_appearance_group_carries_a_real_control_body` 那条绊线上手工确认一次(那条是四组共用的)。
|
||||
/// 接真控件时:把 `is_none()` 改成 `is_some()`,**只改这一行**(M101 r2 起不必再去
|
||||
/// `tests/mod.rs` 报到:那条跨 section 聚合绊线已删,见那里的 `every_line_can_be_wired_alone`)。
|
||||
#[test]
|
||||
fn the_java_group_is_still_demo_rows() {
|
||||
assert!(
|
||||
|
||||
@@ -130,33 +130,62 @@ fn the_split_kept_the_left_column_order() {
|
||||
assert_eq!(names, vec!["General", "Appearance", "Java", "Downloads"]);
|
||||
}
|
||||
|
||||
/// M99:「外观」是**当前唯一**接了真控件的那一组。
|
||||
/// M101 r2:`settings/mod.rs` 里**不许出现任何一组的 `State` 类型**(r1 复审 P1 的判据钉在这里)。
|
||||
///
|
||||
/// 抓得住:拆分时把 `body: Some(…)` 搬丢 / 搬到了别的组(那会让真控件消失,退回演示行——
|
||||
/// 而截图对这种「只在有外观状态时出现」的差别不一定抓得住,见报告「没验的部分」);
|
||||
/// 也抓「别组偷偷接了 body 却没人知道」。
|
||||
/// 抓不住:`body` 指向的那个渲染器画得对不对(那是 `pages::appearance` 的事)。
|
||||
///
|
||||
/// **为什么不能下放**(任务书点名要求写清):这条断言的全部内容是**四组的 body 现状对比**
|
||||
/// ——「只有第 2 组是 Some,其余三组都是 None」。放进 `appearance_section.rs` 它就得替 java /
|
||||
/// download / general 三组作证(那三条线一接真控件,本文件以外的地方无缘无故变红,且责任方
|
||||
/// 不是改代码的人);拆成四份「我这组是 None」又会丢掉「唯一」这个要点。
|
||||
/// 它是**绊线**:哪条线接上真控件,就必须来本文件手工改这一条(T1:绊线保持字面量,
|
||||
/// 动态取活值等于把绊线剪了)。
|
||||
/// 抓得住:谁把状态漏斗拆回去——让 `view` / `form` 直接收 `appearance::State` 或某一组的 `State`
|
||||
/// (那正是四条线「加一个字段就要改本文件」的形状,本次复审要求修掉的就是它)。
|
||||
/// 抓不住:各组的**字段**(那些活在各组自己的文件里,本文件本来就不该知道,也就没有可断言的东西)。
|
||||
#[test]
|
||||
fn only_the_appearance_group_carries_a_real_control_body() {
|
||||
fn the_settings_module_does_not_name_any_group_state() {
|
||||
let source = include_str!("../mod.rs");
|
||||
let forbidden = [
|
||||
"appearance::State",
|
||||
"java::State",
|
||||
"download::State",
|
||||
"language_appearance::State",
|
||||
"ai_about::State",
|
||||
];
|
||||
|
||||
let hits: Vec<&str> = forbidden
|
||||
.into_iter()
|
||||
.filter(|needle| source.contains(needle))
|
||||
.collect();
|
||||
|
||||
assert!(
|
||||
GROUPS[APPEARANCE_GROUP].body.is_some(),
|
||||
"外观分组必须是接了真控件的那一组"
|
||||
hits.is_empty(),
|
||||
"`settings/mod.rs` 里出现了具体的组状态类型 {hits:?}:状态漏斗被打回去了——\
|
||||
四条填页线又要改本文件。状态应该只在 `settings/state.rs` 的 `Groups` 与各组自己的\
|
||||
`State` 定义里出现,本文件只转发 `States`"
|
||||
);
|
||||
for (index, group) in GROUPS.iter().enumerate() {
|
||||
if index == APPEARANCE_GROUP {
|
||||
continue;
|
||||
}
|
||||
assert!(
|
||||
group.body.is_none(),
|
||||
"{} 现在应该还是演示行(真控件由它自己那条 section 线接)",
|
||||
group.name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// 为什么能删:`tests/appearance_section.rs` 断言外观组 `body.is_some()`,
|
||||
/// `tests/{general,java,download}_section.rs` 各自断言本组 `body.is_none()`——四条合起来与
|
||||
/// 原来那条聚合断言等价(成员与顺序另有 [`the_split_kept_the_left_column_order`] 钉住)。
|
||||
/// 删掉之后每条线「接真控件」只需改自己那 2 个文件,不必来本文件报到。
|
||||
///
|
||||
/// ## 删掉之后**抓不住什么**(tower 要求写明)
|
||||
///
|
||||
/// 那四条都只看**本组**,没有任何一条再断言「唯一性」——「四组里恰好一组挂了真控件」这件事
|
||||
/// **现在没有守卫**。具体漏法:
|
||||
///
|
||||
/// | 情形 | 还红吗 |
|
||||
/// |---|---|
|
||||
/// | 某条线接上 `body` 却忘了翻自己那条 `is_none()` | **红**(本组断言还在) |
|
||||
/// | 两条线的断言被同时改成 `is_some()`,页面上两组同时长真控件 | **绿着过去**(没人指认「唯一」) |
|
||||
/// | 谁把 `body: Some(..)` 挂到一个不该有的组、又顺手改了它那条断言 | **绿着过去** |
|
||||
///
|
||||
/// 接受这个损失的理由:接真控件是**每组各自的一次性动作**,谁做谁翻自己那一条;而「唯一」在
|
||||
/// 四条线并行的阶段是最容易假红的约束(一条线接上就替另外三条红)。想要回这条守卫,等四条线
|
||||
/// 都落地后在这里加一条**计数**断言(`GROUPS.iter().filter(|g| g.body.is_some()).count()`),
|
||||
/// 而不是现在钉死某个下标。
|
||||
///
|
||||
/// 这条 `#[test]` 本体已删;保留这段文档是为了让后来的人知道「这里原本有一条绊线」。
|
||||
#[test]
|
||||
fn every_line_can_be_wired_alone() {
|
||||
// 判据是「每条线只改自己的文件」,不是任何一条具体断言:这里只钉住架子本身的两件事——
|
||||
// ① 每组都有 `GROUP`(成员齐);② 演示下标合法。真正的 per-group 断言在各自文件里。
|
||||
assert_eq!(GROUPS.len(), 4, "四条线各一个分组");
|
||||
assert!(SELECTED < GROUPS.len(), "演示下标仍在范围内");
|
||||
}
|
||||
Reference in new issue
Block a user