// 复刻函数漂移防护:content.js / popup.js 的内联函数块必须与 scripts/verify-chat-range.mjs // 基准照搬区逐字一致。比对前统一 CRLF→LF(content.js 全文件 CRLF,基准/popup 为 LF, // 行尾风格非漂移信号)并去尾部空白(切块端点的空行/缩进差异非漂移信号); // 除此之外必须逐字节一致 —— 改基准或实现任一侧后此测试变红 = 你忘了同步另一侧。 import { describe, it, expect } from 'vitest'; import { readFileSync } from 'node:fs'; const read = p => readFileSync(new URL(p, import.meta.url), 'utf8'); const verify = read('../scripts/verify-chat-range.mjs'); const content = read('../content.js'); const popup = read('../popup.js'); // CRLF→LF + 去尾部空白(仅此两项豁免,内容仍须逐字一致) const norm = s => s.replace(/\r\n/g, '\n').replace(/\s+$/, ''); // 从 src 中切出 [startMarker, endMarker) 之间的文本(含 start,不含 end) function sliceBetween(src, startMarker, endMarker) { const s = src.indexOf(startMarker); if (s < 0) return null; const e = endMarker ? src.indexOf(endMarker, s) : -1; return src.slice(s, e < 0 ? undefined : e); } describe('replica sync drift guard', () => { it('content.js 5-function block byte-matches verify baseline region', () => { const base = sliceBetween(verify, '// 范围过滤(null sendTime 防御性保留', '// ---- 用例'); const inl = sliceBetween(content, '// 范围过滤(null sendTime 防御性保留', '// ============ 安全层:风控关键词'); expect(base).toBeTruthy(); expect(inl).toBeTruthy(); expect(norm(inl)).toBe(norm(base)); }); it('popup.js minusMonths+computeChatRange byte-matches verify baseline region', () => { const base = sliceBetween(verify, '// 自然月回退:直接 setMonth', '// 范围过滤(null sendTime 防御性保留'); const inl = sliceBetween(popup, '// 自然月回退:直接 setMonth', 'function syncChatModeUI'); expect(base).toBeTruthy(); expect(inl).toBeTruthy(); expect(norm(inl)).toBe(norm(base)); }); });