diff --git a/app/__tests__/pre-push-check.test.ts b/app/__tests__/pre-push-check.test.ts index 1cb17e9..9f400a7 100644 --- a/app/__tests__/pre-push-check.test.ts +++ b/app/__tests__/pre-push-check.test.ts @@ -268,7 +268,7 @@ describe("Accessibility: images have alt text", () => { const content = readFile(file); const rel = path.relative(SRC_ROOT, file); - const imgRegex = /]*>/gs; + const imgRegex = /]*>/g; let match: RegExpExecArray | null; while ((match = imgRegex.exec(content)) !== null) { const tag = match[0]; @@ -406,7 +406,19 @@ describe("Convention: no raw hex colors in classNames", () => { // ═══════════════════════════════════════════════════════════════════════════ describe("Convention: no emoji in app/ source code", () => { - const EMOJI_REGEX = /[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{FE00}-\u{FE0F}\u{1F000}-\u{1F02F}\u{1F0A0}-\u{1F0FF}\u{1F100}-\u{1F64F}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA6F}\u{1FA70}-\u{1FAFF}\u{1FC00}-\u{1FCFF}\u{1FD00}-\u{1FDFF}\u{1FE00}-\u{1FEFF}\u{200D}\u{20E3}\u{E0020}-\u{E007F}]/gu; + function lineContainsEmoji(line: string): boolean { + for (let i = 0; i < line.length; i++) { + const code = line.codePointAt(i); + if (code === undefined) continue; + if (code >= 0x1F300 && code <= 0x1FAFF) return true; + if (code >= 0x2600 && code <= 0x27BF) return true; + if (code >= 0xFE00 && code <= 0xFE0F) return true; + if (code === 0x200D) return true; + if (code === 0x20E3) return true; + if (code > 0xFFFF) i++; + } + return false; + } const EXCLUDED_DIRS = new Set(["components/admin", "components/modern", "editor"]); const EXCLUDED_FILES = new Set([ @@ -433,13 +445,17 @@ describe("Convention: no emoji in app/ source code", () => { for (let i = 0; i < lines.length; i++) { const line = lines[i]; if (line.trim().startsWith("//") || line.trim().startsWith("*")) continue; - if (EMOJI_REGEX.test(line)) { - const emoji = line.match(EMOJI_REGEX); - if (emoji) { - violations.push(`${rel}:${i + 1} — found emoji: ${emoji.join(", ")}`); + if (lineContainsEmoji(line)) { + const emojiChars: string[] = []; + for (let j = 0; j < line.length; j++) { + const code = line.codePointAt(j); + if (code !== undefined && ((code >= 0x1F300 && code <= 0x1FAFF) || (code >= 0x2600 && code <= 0x27BF) || (code >= 0xFE00 && code <= 0xFE0F) || code === 0x200D || code === 0x20E3)) { + emojiChars.push(String.fromCodePoint(code)); + if (code > 0xFFFF) j++; + } } + violations.push(`${rel}:${i + 1} — found emoji: ${emojiChars.join(", ")}`); } - EMOJI_REGEX.lastIndex = 0; } }