dex/test/konami.test.js
chris fb299d11f9 Hidden mini-game: "Who's that Pokémon?"
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
2026-09-10 12:34:45 -04:00

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);
});
});