Fuzzy: src/lib/fuzzy.js — editDistance + closeEnough (length-scaled typo tolerance, 0 for names ≤4 chars). submitGuess() accepts a near-miss, so "charizrd" counts. Plus inline ghost-text completion: once the typed prefix matches exactly one Pokémon, the rest of the name shows greyed after the caret; → (at end), Tab or End accepts it. Generation filter: a "Pull from" select (All / Gen 1–9, built from the snapshot's species.generation). Choice persists in pdx.whosThat.gen; changing it reshuffles the pool (and the completion list) and resets the streak. 7 new unit tests for fuzzy.js (48 total). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
33 lines
1.1 KiB
JavaScript
33 lines
1.1 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { editDistance, closeEnough } from '../src/lib/fuzzy.js';
|
|
|
|
describe('editDistance', () => {
|
|
it('counts insert / delete / substitute', () => {
|
|
expect(editDistance('', '')).toBe(0);
|
|
expect(editDistance('abc', 'abc')).toBe(0);
|
|
expect(editDistance('abc', 'ab')).toBe(1);
|
|
expect(editDistance('abc', 'abx')).toBe(1);
|
|
expect(editDistance('kitten', 'sitting')).toBe(3);
|
|
expect(editDistance('charizard', 'charizrd')).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('closeEnough', () => {
|
|
it('accepts a small typo on a long name', () => {
|
|
expect(closeEnough('charizrd', 'charizard')).toBe(true);
|
|
expect(closeEnough('tyraniter', 'tyranitar')).toBe(true);
|
|
expect(closeEnough('gardevor', 'gardevoir')).toBe(true);
|
|
});
|
|
|
|
it('is strict on short names', () => {
|
|
expect(closeEnough('meh', 'mew')).toBe(false);
|
|
expect(closeEnough('mow', 'muk')).toBe(false);
|
|
expect(closeEnough('mew', 'mew')).toBe(true);
|
|
});
|
|
|
|
it("won't bridge two genuinely different names", () => {
|
|
expect(closeEnough('pikachu', 'raichu')).toBe(false);
|
|
expect(closeEnough('bulbasaur', 'ivysaur')).toBe(false);
|
|
});
|
|
});
|