Skip to content

Commit 0b27540

Browse files
committed
test(ui): tighten empty state align samples
1 parent 451db3f commit 0b27540

1 file changed

Lines changed: 18 additions & 15 deletions

File tree

‎app/src/ui/primitives/EmptyState.align.test.tsx‎

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
*
1818
* ② 另判 `EmptyState.css` 的修饰类**内容**(`align-items` + `text-align`)并带反例样本:
1919
* `style-contract.test.ts` 的全枚举只判「规则存在」,一条空的 `{}` 也能过 —— 那正是"新档位忘了写
20-
* 排版"的静默失效面。
20+
* 排版"的静默失效面。⚠️ 反例样本必须**经同一条取段器**(`bodyOf`)求值,否则退化成对本地字面量的
21+
* 自证(恒真、不承重 —— T13–T15 评审 M-8 的原款,已在本单元改成真断言)。
2122
*
2223
* 副作用:只挂 React 树 + 只读同目录 `EmptyState.css`。边界:本仓未装 jest-dom ⇒ 原生 DOM API。
2324
*/
@@ -34,11 +35,12 @@ const read = (file: string): string => readFileSync(join(HERE, file), "utf8").re
3435
const stripComments = (s: string): string => s.replace(/\/\*[\s\S]*?\*\//g, "");
3536

3637
const CSS = stripComments(read("EmptyState.css"));
37-
/** 取 `.ed-empty--start` 的规则体(`选择器 {` 到第一个 `}`)—— 防「写在别的规则里也算过」 */
38-
const START_BODY = (() => {
39-
const at = CSS.indexOf(".ed-empty--start");
40-
return at < 0 ? "" : CSS.slice(at, CSS.indexOf("}", at));
41-
})();
38+
/** 取某选择器的规则体(`选择器 {` 到第一个 `}`)—— 防「写在别的规则里也算过」;判据与反例样本共用它 */
39+
function bodyOf(css: string, sel: string): string {
40+
const at = css.indexOf(sel);
41+
return at < 0 ? "" : css.slice(at, css.indexOf("}", at));
42+
}
43+
const START_BODY = bodyOf(CSS, ".ed-empty--start");
4244

4345
const ACTION = { label: "新建第一篇笔记", onClick: (): void => {} } as const;
4446

@@ -74,10 +76,15 @@ describe("② align=\"start\" ⇒ 修饰类 + CSS 内容(带反例样本)",
7476
expect(START_BODY, "EmptyState.css 缺 `.ed-empty--start` 规则").not.toBe("");
7577
expect(START_BODY, "缺横向对齐(align-items)").toContain("align-items: flex-start");
7678
expect(START_BODY, "缺文本对齐(text-align)").toContain("text-align: start");
77-
// 反例守门:一条只写了 align-items 的规则必须**不满足**上面第二条(否则该断言是永真)
78-
const mutated = ".ed-empty--start {\n align-items: flex-start;\n}";
79-
expect(mutated).toContain("align-items: flex-start");
80-
expect(mutated).not.toContain("text-align: start");
79+
// 反例守门(T13–T15 评审 M-8 的结清):把**同一条取段器** `bodyOf` 喂给一条只写 align-items 的
80+
// 合成规则(后面紧跟一条带 `text-align: start` 的无关规则)—— 取段器必须只取到前者。修前那两行
81+
// 只对刚刚手写的字面量求值(`mutated` 与 `EmptyState.css` 无关)⇒ 恒真、不承重,取段器越界也照样绿。
82+
const mutated = bodyOf(
83+
".ed-empty--start {\n align-items: flex-start;\n}\n.ed-empty__other {\n text-align: start;\n}",
84+
".ed-empty--start",
85+
);
86+
expect(mutated, "取段器没取到合成规则的规则体 ⇒ 反例样本失效").toContain("align-items: flex-start");
87+
expect(mutated, "取段器越界取到后面的规则 ⇒ 上面两条断言不承重").not.toContain("text-align: start");
8188
});
8289
});
8390

@@ -103,11 +110,7 @@ describe("④ 四个槽位在两种对齐下都渲染(对齐档不改结构)
103110

104111
describe("⑤ start 档下**次要槽内部**也左对齐(T2/T3 评审 Minor ② 的结清;批 4 T13)", () => {
105112
/** 取 `.ed-empty--start > .ed-empty__secondary` 的规则体(选择器到第一个 `}`) */
106-
const SECONDARY_START_BODY = (() => {
107-
const sel = ".ed-empty--start > .ed-empty__secondary";
108-
const at = CSS.indexOf(sel);
109-
return at < 0 ? "" : CSS.slice(at, CSS.indexOf("}", at));
110-
})();
113+
const SECONDARY_START_BODY = bodyOf(CSS, ".ed-empty--start > .ed-empty__secondary");
111114

112115
it("`.ed-empty__secondary` 自身仍是居中行(默认档形态逐字不变)", () => {
113116
// 锚点带前导换行 ⇒ 命中**基础规则**本身,不会落到 `--start > __secondary` 那条覆盖上

0 commit comments

Comments
 (0)