(claim)
| 88 | } |
| 89 | |
| 90 | async function verifyPatternCount(claim) { |
| 91 | const { file, pattern, expected } = claim; |
| 92 | if (!file || !pattern) return { disposition: 'unsupported', reason: 'pattern_count requires file + pattern' }; |
| 93 | let content; |
| 94 | try { ({ content } = await readClaimFile(claim)); } |
| 95 | catch { return { disposition: 'failed', reason: `cannot read ${file}` }; } |
| 96 | |
| 97 | // "42" alone (from `filename:42`) is a line number, not a pattern. |
| 98 | if (/^\d+$/.test(pattern.trim())) { |
| 99 | return { disposition: 'unsupported', reason: 'pattern looks like a line number, not a pattern' }; |
| 100 | } |
| 101 | |
| 102 | const re = compilePattern(pattern, 'g'); |
| 103 | const matches = content.match(re) ?? []; |
| 104 | const actual = matches.length; |
| 105 | return actual === expected |
| 106 | ? { disposition: 'verified', actual, expected, reason: 'exact count match' } |
| 107 | : { disposition: 'failed', actual, expected, reason: `count mismatch: claim=${expected}, actual=${actual}` }; |
| 108 | } |
| 109 | |
| 110 | async function verifyPatternExists(claim) { |
| 111 | const { file, pattern } = claim; |
no test coverage detected