(query: EvalQuery, results: SearchResult[])
| 54 | } |
| 55 | |
| 56 | function evaluateQuery(query: EvalQuery, results: SearchResult[]): EvalResult { |
| 57 | const uniqueResults = dedupeByFile(results); |
| 58 | const topFile = uniqueResults.length > 0 ? uniqueResults[0].filePath : null; |
| 59 | const top3Files = uniqueResults.slice(0, 3).map((result) => result.filePath); |
| 60 | |
| 61 | const expectedPatterns = getExpectedPatterns(query); |
| 62 | const expectedNotPatterns = getExpectedNotPatterns(query); |
| 63 | |
| 64 | const top1Correct = |
| 65 | topFile !== null && |
| 66 | matchesPattern(topFile, expectedPatterns) && |
| 67 | !matchesPattern(topFile, expectedNotPatterns); |
| 68 | |
| 69 | const top3Recall = top3Files.some( |
| 70 | (filePath) => |
| 71 | matchesPattern(filePath, expectedPatterns) && !matchesPattern(filePath, expectedNotPatterns) |
| 72 | ); |
| 73 | |
| 74 | const specCount = top3Files.filter((filePath) => isTestFile(filePath)).length; |
| 75 | const specContaminated = specCount >= 2; |
| 76 | |
| 77 | return { |
| 78 | queryId: query.id, |
| 79 | query: query.query, |
| 80 | category: query.category, |
| 81 | expectedPatterns, |
| 82 | expectedNotPatterns, |
| 83 | topFile, |
| 84 | top3Files, |
| 85 | top1Correct, |
| 86 | top3Recall, |
| 87 | specContaminated, |
| 88 | score: uniqueResults.length > 0 ? uniqueResults[0].score : 0 |
| 89 | }; |
| 90 | } |
| 91 | |
| 92 | function resolveGateThreshold(total: number, gate: EvalGate): number { |
| 93 | if (gate <= 1) { |
no test coverage detected