跨端: 修「两个动作球不能重叠」那条判据自身(它的结束边界把几十行外的东西也吃进来了)
上一步扩 Unicode 图标扫描面时,这条判据立刻报:
MailDetailPage.ets:664(Stack 里有 2 个圆角元素且没有 Row 包住)
而 L664 那个 `Stack` 是**新加的返回键**,里面**只有一个子元素**(chevron 图标)。
查清根因(判据自身两个缺陷):
① **结束边界靠猜缩进**:原来写 `\n\s{8}\}` —— "8 空格 + 右括号"。
而那个 Stack 的 `}` 缩进是 10 空格、它下面还有一整段同缩进的兄弟节点
⇒ 非贪婪匹配一路吃到**下一个** 8 空格的 `}`,
把几十行外两行的**小徽标**(权限/未读,`.borderRadius(4)`)也算了进来。
⇒ 改成**按大括号配平**取块。缩进是可变的,配平是语法事实。
② **"圆角"被当成"圆球"**:原判据数的是所有 `.borderRadius(\d+)`。
而 `borderRadius(4)` 是**圆角方**(徽标),根本不是球。
本判据要防的是"两个**球**叠在同一个角",不是"任何带圆角的东西"。
⇒ 只认 `borderRadius(N)` 且 **N ≥ 16** 的(动作球是 24/28 那一档)。
★ 改完做了**变异验证**(判据自己的要求:必须"在变异下咬得住"):
把包着两个球的 `Row({ space: 12 })` 拆掉、让它们直接待在 `Stack` 里 ——
判据**立刻转红**(30→29 pass/1 fail);还原后 30 pass。
这说明它测的还是原来那件事,只是不再误伤。
This commit is contained in:
@ -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, [],
|
||||
|
||||
Reference in New Issue
Block a user