test: add unit tests for challenge distribution, ranked challenges, answer edge cases, and mock bot coverage

Covers plan section 4.1: pickChallenge 70/30 distribution, pickRankedChallenge never returns choices,
True/False auto-generation, special characters and long answers, all 16 challenge types produce valid
mock responses, and timeout/error answer verification. 113 → 125 tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-09 07:42:55 +00:00
co-authored by Claude Opus 4.6
parent 46d560af24
commit 5007d009fe
3 changed files with 127 additions and 2 deletions
+24
View File
@@ -120,4 +120,28 @@ describe('checkAnswer', () => {
// 'a' length is 1, so containment shouldn't trigger (requires >= 2)
expect(score).toBeLessThanOrEqual(0.8)
})
it('special characters in answer', () => {
expect(checkAnswer('C++', ['C++'])).toBe(1.0)
expect(checkAnswer('c++', ['C++'])).toBe(1.0)
expect(checkAnswer('$100', ['$100'])).toBe(1.0)
expect(checkAnswer('42%', ['42'])).toBe(1.0)
})
it('very long answer still matches if correct keyword present', () => {
const longAnswer = 'Well, after much deliberation and careful consideration of all the facts, ' +
'weighing the evidence both for and against, consulting multiple sources, and thinking deeply ' +
'about the philosophical implications, I believe the answer you are looking for is Paris, ' +
'which is of course the beautiful capital of France.'
expect(checkAnswer(longAnswer, ['Paris'])).toBe(1.0)
})
it('very long answer with no match returns 0', () => {
const longWrong = 'A'.repeat(2000) + ' banana ' + 'B'.repeat(2000)
expect(checkAnswer(longWrong, ['Paris'])).toBe(0)
})
it('whitespace-only answer returns 0', () => {
expect(checkAnswer('\t\n \r', ['Paris'])).toBe(0)
})
})