Guess the Pokémon from its silhouette (official artwork, filter:brightness(0) until revealed). Streak + best + win% persisted in pdx.whosThat. Three misses auto-reveal; hints (letter count, then first letter) after wrong guesses; guess matching is punctuation/space/case-insensitive. Not in the nav or any link. Reached by the Konami code (↑↑↓↓←→←→BA, lib/konami.js wired in main.js), seven quick taps on the nav wordmark, or the bare #/whos-that hash once you know it. 9 new unit tests for the konami matcher (sequence, case-insensitivity, rewind, partial). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
49 lines
1.3 KiB
JavaScript
49 lines
1.3 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { konamiHandler, KONAMI_SEQUENCE } from '../src/lib/konami.js';
|
|
|
|
describe('konamiHandler', () => {
|
|
it('fires once the full sequence is entered', () => {
|
|
let hits = 0;
|
|
const step = konamiHandler(() => hits++);
|
|
KONAMI_SEQUENCE.forEach((k) => step(k));
|
|
expect(hits).toBe(1);
|
|
});
|
|
|
|
it('is case-insensitive and fires again on a repeat', () => {
|
|
let hits = 0;
|
|
const step = konamiHandler(() => hits++);
|
|
const upper = [
|
|
'ArrowUp',
|
|
'ArrowUp',
|
|
'ArrowDown',
|
|
'ArrowDown',
|
|
'ArrowLeft',
|
|
'ArrowRight',
|
|
'ArrowLeft',
|
|
'ArrowRight',
|
|
'B',
|
|
'A',
|
|
];
|
|
upper.forEach((k) => step(k));
|
|
upper.forEach((k) => step(k));
|
|
expect(hits).toBe(2);
|
|
});
|
|
|
|
it('a wrong key rewinds, but a stray ↑ starts a fresh attempt', () => {
|
|
let hits = 0;
|
|
const step = konamiHandler(() => hits++);
|
|
step('arrowup');
|
|
step('arrowdown'); // wrong (expected another arrowup) -> reset
|
|
step('x'); // noise
|
|
KONAMI_SEQUENCE.forEach((k) => step(k)); // clean run
|
|
expect(hits).toBe(1);
|
|
});
|
|
|
|
it('does not fire on a partial sequence', () => {
|
|
let hits = 0;
|
|
const step = konamiHandler(() => hits++);
|
|
KONAMI_SEQUENCE.slice(0, -1).forEach((k) => step(k));
|
|
expect(hits).toBe(0);
|
|
});
|
|
});
|