diff --git a/client/electron/test/harmony-admin.test.mjs b/client/electron/test/harmony-admin.test.mjs index 1c28af4..7f09f4a 100644 --- a/client/electron/test/harmony-admin.test.mjs +++ b/client/electron/test/harmony-admin.test.mjs @@ -760,14 +760,50 @@ test('★ 详情页的两个动作球必须**分开摆**(Stack 的同一个角 * 简化判定:在同一个 Stack 块内出现 ≥2 处 `.borderRadius(` + 各自 `.margin(` * 而没有包在 Row 里。 */ - const stackBlocks = [...src.matchAll(/Stack\(\{[^}]*alignContent[^}]*\}\)\s*\{([\s\S]*?)\n\s{8}\}/g)]; + /* + * ★★ 2026-09-20 修(判据自身的缺陷,扩展扫描面时暴露出来的)。 + * + * 原来的结束边界写的是 `\n\s{8}\}` —— "8 个空格 + 右括号"。 + * 这个边界**远早于** Stack 真正的收尾(那个 Stack 的 `}` 只有 10 空格缩进, + * 但它下面还有一整段同缩进的兄弟节点)⇒ 非贪婪匹配会一路吃到**下一个** + * 缩进 8 空格的 `}`,把几十行不相干的内容(权限/未读**徽标**的 + * `.borderRadius(4)`)也算成"Stack 里的圆形按钮"。 + * + * 实测后果:我在返回键那里新加了一个 `Stack({ alignContent: Center })` + * (**只有一个子元素**:chevron 图标),判据立刻报 + * 「Stack 里有 2 个圆角元素且没有 Row 包住」—— 那 2 个是页面下方两行的 + * 小徽标(`borderRadius(4)`,圆角方,根本不是圆球)。 + * + * 两处修: + * ① **按大括号配平**取块,而不是猜缩进 —— 缩进是可变的,配平是语法事实。 + * ② 只在**直接子元素**层找圆球(`borderRadius(N)` 且 N 足够大、是圆角)。 + * 徽标那种 `borderRadius(4)` 的圆角方不该算进来:本判据要防的是 + * "两个**圆球**叠在同一个角",不是"任何带圆角的东西"。 + */ + const blockOf = (from) => { + let depth = 0, started = false; + for (let i = from; i < src.length; i++) { + const ch = src[i]; + if (ch === '{') { depth++; started = true; } + else if (ch === '}') { + depth--; + if (started && depth === 0) return src.slice(from, i + 1); + } + } + return ''; + }; const bad = []; - for (const m of stackBlocks) { - const body = m[1]; - const circles = (body.match(/\.borderRadius\(\d+\)/g) ?? []).length; - if (circles >= 2 && !/Row\(\{\s*space:/.test(body)) { + for (const m of src.matchAll(/Stack\(\{[^}]*alignContent[^}]*\}\)\s*\{/g)) { + const body = blockOf(m.index + m[0].length - 1); + /* + * 只认**圆**:`.borderRadius(N)` 的 N ≥ 16(动作球是 24/28 这一档)。 + * 小徽标的 `borderRadius(4)` 是圆角方,不是"球",不能算。 + */ + const radii = [...body.matchAll(/\.borderRadius\((\d+)\)/g)].map(x => Number(x[1])); + const balls = radii.filter(r => r >= 16).length; + if (balls >= 2 && !/Row\(\{\s*space:/.test(body)) { const line = src.slice(0, m.index).split('\n').length; - bad.push(`MailDetailPage.ets:${line}(Stack 里有 ${circles} 个圆角元素且没有 Row 包住)`); + bad.push(`MailDetailPage.ets:${line}(Stack 里有 ${balls} 个圆角球且没有 Row 包住)`); } } assert.deepEqual(bad, [],