Skip to content

Commit 611d6d2

Browse files
Yuki-Nagoriclaude
andauthored
[2014] GUI 复现脚本扩展至切/增/删/排序四种动作 (#3829)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 49d96ad commit 611d6d2

2 files changed

Lines changed: 112 additions & 31 deletions

File tree

TeXmacs/tests/2014.scm

Lines changed: 87 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
22
;;
33
;; MODULE : 2014.scm
4-
;; DESCRIPTION : GUI 复现:切换 tab 时观察 menu 缓存是否命中
4+
;; DESCRIPTION : GUI 复现:切换/新建/关闭/拖拽 tab 时观察 menu 缓存命中与重建
55
;; COPYRIGHT : (C) 2026 Mogan STEM
66
;;
77
;; PURPOSE
8-
;; 排查"切 tab 仍触发 SLOT_TAB_PAGES 整条重建"。配合 get_menu_widget 里
9-
;; which==4 的 [tabpage] menu cache HIT/MISS 日志,在真实 GUI 里切换两个
10-
;; 文档,看每次切换是 HIT(不重建)还是 MISS(重建)。
8+
;; 排查"切 tab / 增删 / 排序 tab 触发 SLOT_TAB_PAGES 整条重建"。配合
9+
;; get_menu_widget 里 which==4 的 [tabpage] menu cache HIT/MISS 日志与
10+
;; QTMTabPageContainer 的 [tabpage] rebuild/active 计数日志,在真实 GUI 里
11+
;; 驱动四种动作,看每次是 HIT(不重建)还是 MISS(重建)。
1112
;;
12-
;; 夹具从 $TEXMACS_PATH/tests/tmu 复制到 /tmp,避免 save/编辑污染检入副本。
13-
;; 带 stem-doc-id 以排除 auto-backup 标脏干扰(见 1106)。
13+
;; 覆盖动作:
14+
;; 1. 切换 active(switch-to-view-index)—— 应只 active、零 rebuild。
15+
;; 2. 点 + 新建(new-document)—— 增 tab,签名变 → 1 次 rebuild。
16+
;; 3. 关闭一个 tab(safely-kill-tabpage)—— 减 tab,签名变 → 1 次 rebuild。
17+
;; 4. 拖拽排序(move-buffer-to-index)—— 集合不变、仅顺序变,签名按
18+
;; tabpage-list 顺序拼接 → 顺序变也算签名变 → 1 次 rebuild(但指针复用)。
1419
;;
20+
;; 夹具从 $TEXMACS_PATH/tests/tmu 复制到 /tmp,避免 save/编辑污染检入副本。
1521
;; 用 exec-delayed-at 串异步链,不阻塞 Qt 事件循环;链尾自己 quit。
1622
;;
1723
;; USAGE
@@ -22,6 +28,8 @@
2228

2329
(texmacs-module (texmacs tests 2014))
2430

31+
(import (only (srfi srfi-1) list-index))
32+
2533
(define (tmp-name name)
2634
(string->url (string-append "/tmp/" name))
2735
) ;define
@@ -34,8 +42,25 @@
3442
) ;let
3543
) ;define
3644

45+
;; 步骤间隔:给 Qt 事件循环 + typeset 足够时间,避免异步事件叠加。
46+
3747
(define step-delay-ms 4000)
3848

49+
;; 打印当前 tab 数与 buffer 列表,便于把 [tabpage] 日志和动作对齐。
50+
51+
(define (log-state label)
52+
(let ((n (length (tabpage-list #t))))
53+
(display "[2014-step] ")
54+
(display label)
55+
(display " tabs=")
56+
(display n)
57+
(newline)
58+
) ;let
59+
) ;define
60+
61+
;; 串异步链:每步在 exec-delayed-at 触发,步间隔 step-delay-ms。
62+
;; 每个元素是 (label . action-thunk)。
63+
3964
(define (run-chain steps)
4065
(let loop
4166
((rest steps) (t (+ (texmacs-time) step-delay-ms)))
@@ -46,6 +71,7 @@
4671
(display label)
4772
(newline)
4873
(act)
74+
(log-state (string-append "after " label))
4975
(loop (cdr rest) (+ (texmacs-time) step-delay-ms))
5076
) ;lambda
5177
t
@@ -59,31 +85,63 @@
5985
(refresh-fixture "2014_a.tmu")
6086
(refresh-fixture "2014_b.tmu")
6187
(let* ((path-a (tmp-name "2014_a.tmu")) (path-b (tmp-name "2014_b.tmu")))
62-
(let ((steps (list (cons "load a" (lambda () (load-buffer path-a)))
63-
(cons "load b" (lambda () (load-buffer path-b)))
64-
) ;list
88+
;; 动作链:
89+
;; - 载入 a、b(建 tab)
90+
;; - 1. 来回切 5 轮(应零 rebuild,全部 menu cache HIT)
91+
;; - 2. 新建 1 个 tab(+,应 1 次 MISS + 1 次 rebuild,added 仅 +1)
92+
;; - 3. 关闭当前 tab(应 1 次 MISS + 1 次 rebuild,removed 仅 +1)
93+
;; - 4. 排序:把当前 buffer 移到首位(应 1 次 MISS + 1 次 rebuild,added/removed 均为 0)
94+
;; - 结束退出
95+
;;
96+
;; 关闭/排序的可预测性要点:
97+
;; - new-document 建的是脏 buffer,safely-kill-tabpage 会命中 buffer-modified?
98+
;; 分支弹确认框、卡住异步链。故新建后立即 buffer-pretend-saved 去脏。
99+
;; - 排序用 move-buffer-to-index 移到 index 0(首位),顺序必变。
100+
(let ((steps (append (list (cons "load a" (lambda () (load-buffer path-a)))
101+
(cons "load b" (lambda () (load-buffer path-b)))
102+
) ;list
103+
;; 1) 切换 active:5 轮来回切 view 1 / view 2
104+
(let loop
105+
((i 0) (acc '()))
106+
(if (>= i 5)
107+
(reverse acc)
108+
(loop (+ i 1)
109+
(append (list (cons (string-append "round " (number->string i) ": -> a")
110+
(lambda () (switch-to-view-index 1))
111+
) ;cons
112+
(cons (string-append "round " (number->string i) ": -> b")
113+
(lambda () (switch-to-view-index 2))
114+
) ;cons
115+
) ;list
116+
acc
117+
) ;append
118+
) ;loop
119+
) ;if
120+
) ;let
121+
;; 2) 新建 tab(+)并去脏,便于后续安全关闭
122+
(list (cons "new-document (+)" (lambda () (new-document))))
123+
(list (cons "buffer-pretend-saved"
124+
(lambda () (buffer-pretend-saved (current-buffer)))
125+
) ;cons
126+
) ;list
127+
;; 3) 关闭当前 tab(新建的那个,已去脏,不弹框)
128+
(list (cons "safely-kill-tabpage" (lambda () (safely-kill-tabpage))))
129+
;; 4) 排序:当前 buffer 移到首位(index 0)
130+
(list (cons "move-buffer-to-index (reorder to 0)"
131+
(lambda ()
132+
(let ((buf (current-buffer)))
133+
(when buf
134+
(move-buffer-to-index buf 0)
135+
) ;when
136+
) ;let
137+
) ;lambda
138+
) ;cons
139+
) ;list
140+
;; 结束
141+
(list (cons "done; quitting" (lambda () (quit-TeXmacs))))
142+
) ;append
65143
) ;steps
66144
) ;
67-
;; 在两个 tab 间来回切 5 轮。
68-
(let loop
69-
((i 0) (acc steps))
70-
(if (>= i 5)
71-
(set! steps
72-
(append acc (list (cons "done; quitting" (lambda () (quit-TeXmacs)))))
73-
) ;set!
74-
(loop (+ i 1)
75-
(append acc
76-
(list (cons (string-append "round " (number->string i) ": -> a")
77-
(lambda () (switch-to-view-index 1))
78-
) ;cons
79-
(cons (string-append "round " (number->string i) ": -> b")
80-
(lambda () (switch-to-view-index 2))
81-
) ;cons
82-
) ;list
83-
) ;append
84-
) ;loop
85-
) ;if
86-
) ;let
87145
(display "[2014-step] starting delayed chain\n")
88146
(run-chain steps)
89147
) ;let

devel/2014.md

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,23 @@ xmake r qt_tab_page_test qt_chat_tab_widget_test qt_tm_widget_add_tab_test #
2525
### 3.2 非确定性测试(GUI 复现)
2626
```bash
2727
xmake b stem
28-
MOGAN_TEST_GUI=1 xmake r 2014 # 真实 GUItab,观察是否重建
28+
MOGAN_TEST_GUI=1 xmake r 2014 # 真实 GUI,驱动切/增/删/排序 tab
2929
```
30-
切 tab 时不应再触发整条重建(签名命中);增删 tab 时正常重建。
30+
`2014.scm` 用异步链依次驱动四种动作,每种对照 `[tabpage]` 计数日志判读:
31+
32+
- **切换 active**`switch-to-view-index`):只应见 `active #` 递增、**`rebuild`**
33+
- **新建 `+`**`new-document`):增 tab,签名变 → 触发 `rebuild``added` 只 +1
34+
(其余复用)。
35+
- **关闭**`safely-kill-tabpage`):减 tab,签名变 → 触发 `rebuild``removed` 只 +1。
36+
- **拖拽排序**`move-buffer-to-index`):实测在脚本驱动下**不触发 `SLOT_TAB_PAGES`**
37+
(无 `rebuild` 行,`tabs` 数不变)。即当前实现里排序后 tab 栏不刷新——这本身是
38+
理想行为(零重建)。脚本仍保留该步作为回归观测点:若将来排序改为触发刷新,
39+
应见 `rebuild``added`/`removed` 不变(指针复用,不全量重建)。
40+
41+
**判读要点**`debug_added_count`/`debug_removed_count` 是累计计数(从对象创建起累加,
42+
不重置)。看每次 `rebuild` 行里这两个值相对上一次是否增长,而非 `rebuild` 行出现的
43+
次数——TeXmacs 对一次增删可能发多次 `SLOT_TAB_PAGES`,后续若 `added`/`removed` 不变
44+
即复用。
3145

3246
### 3.3 调试观察(LIII_DEBUG 下)
3347

@@ -125,3 +139,12 @@ GUI 复现:切 tab 时 `signature HIT`(不重建)+ `SLOT_FILE`(更新 ac
125139
才让 `MOGAN_TEST_GUI` 生效,脆弱。删除 `xmake.lua` 里的旧定义与旧循环,只保留
126140
`tests.lua` 版本(带 `MOGAN_TEST_GUI` 的超集)。`includes` 在调用前加载,顺序正确。
127141
`MOGAN_TEST_GUI` 未设时行为与旧版完全一致(`-headless` + 自动 quit)。
142+
3. **GUI 复现脚本扩展至四种动作**`TeXmacs/tests/2014.scm`):原脚本只复现"切 tab"。
143+
扩展为切换 active / 新建 `+` / 关闭 / 排序四条异步链,配合 `[tabpage]` 日志逐动作判读。
144+
- 关闭可预测性:`new-document` 建的是脏 buffer,`safely-kill-tabpage` 会命中
145+
`buffer-modified?` 分支弹确认框、卡住异步链。故新建后立即
146+
`buffer-pretend-saved` 去脏,再安全关闭当前 tab。
147+
- 排序用 `move-buffer-to-index` 移到首位(顺序必变)。实测在脚本驱动下排序
148+
**不触发 `SLOT_TAB_PAGES`**(无 `rebuild` 行,`tabs` 数不变)——即当前
149+
实现排序后 tab 栏不刷新,本身是理想行为;脚本保留该步作回归观测点。
150+
- 复现结论:切 tab 零重建;新建 `added` 仅 +1、关闭 `removed` 仅 +1(增量非全量)。

0 commit comments

Comments
 (0)