diff --git a/src/features/housekeeping/foundation/shell/housekeeping-shell.test.tsx b/src/features/housekeeping/foundation/shell/housekeeping-shell.test.tsx index 4277f531..fdc88b7a 100644 --- a/src/features/housekeeping/foundation/shell/housekeeping-shell.test.tsx +++ b/src/features/housekeeping/foundation/shell/housekeeping-shell.test.tsx @@ -86,7 +86,7 @@ const structuralBoundaryRules = [ { label: "palette color", pattern: - /(?:bg|text|border|from|to)-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-\d{2,3}/, + /(?:bg|text|border|from|to)-(?:white|black|slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)(?:-\d{2,3})?/, }, { label: "hex color", pattern: new RegExp("#" + "[0-9a-fA-F]{3,8}") }, { @@ -98,12 +98,17 @@ const structuralBoundaryRules = [ const componentBoundaryRules = [ { label: "React hook", - pattern: - /\buse(?:State|Effect|Memo|Callback|Ref|Reducer|LayoutEffect|Transition)(?:\s*\(|\s*(?:,|}))/, + pattern: /\b(?:React\.)?use[A-Z]\w*(?:\s*\(|\s*(?:as|,|}))/, }, { label: "click handler", pattern: /\bonClick\s*=/ }, { label: "keyboard handler", pattern: /\bonKey(?:Down|Up|Press)\s*=/ }, + { label: "executable JSX event prop", pattern: /\bon[A-Z]\w*\s*=/ }, { label: "event listener", pattern: new RegExp("addEvent" + "Listener") }, + { + label: "inline literal color", + pattern: + /\bstyle\s*=\s*\{\{[^}]*\b(?:color|background(?:Color)?|borderColor|fill|stroke)\s*:\s*["'](?!var\(--admin-[^)]+\))[^"']+["']/, + }, { label: "database or action import", pattern: new RegExp( @@ -269,4 +274,32 @@ describe("HousekeepingShell", () => { ), ).toContain("rgb or hsl color"); }); + it("detects generic hook, event, neutral color, and inline-style mutations", () => { + const componentMutations = [ + ["React hook", "useActionState();"], + ["React hook", 'import { useState as state } from "react";'], + ["React hook", "React.useId();"], + ["executable JSX event prop", "
undefined} />"], + ["executable JSX event prop", "
undefined} />"], + ["inline literal color", '
'], + ] as const; + + for (const [expectedViolation, source] of componentMutations) { + expect(boundaryViolations(source, componentBoundaryRules)).toContain( + expectedViolation, + ); + } + expect( + boundaryViolations( + 'const color = "bg-' + 'white";', + structuralBoundaryRules, + ), + ).toContain("palette color"); + expect( + boundaryViolations( + 'const color = "text-' + 'black";', + structuralBoundaryRules, + ), + ).toContain("palette color"); + }); });