Files
SubMiner/src/anki-integration/known-word-cache-format.test.ts
T

77 lines
2.3 KiB
TypeScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
KnownWordCacheState,
knownWordsFromState,
parseKnownWordCacheState,
} from './known-word-cache-format';
function parseOrThrow(value: unknown): KnownWordCacheState {
const parsed = parseKnownWordCacheState(value);
assert.ok(parsed, 'expected the payload to parse');
return parsed;
}
const BASE = { refreshedAtMs: 1, scope: 'deck:test' };
test('known-word cache format reads words from every version the union covers', () => {
assert.deepEqual(
knownWordsFromState(parseOrThrow({ ...BASE, version: 1, words: ['する'] })),
new Set(['する']),
);
assert.deepEqual(
knownWordsFromState(
parseOrThrow({ ...BASE, version: 2, words: ['する'], notes: { '1': ['する'] } }),
),
new Set(['する']),
);
assert.deepEqual(
knownWordsFromState(
parseOrThrow({
...BASE,
version: 3,
notes: { '1': [{ word: 'する', reading: 'する' }], '2': [{ word: '猫', reading: null }] },
}),
),
new Set(['する', '猫']),
);
// v4 only adds `tiers`; the words a reader sees must not change.
assert.deepEqual(
knownWordsFromState(
parseOrThrow({
...BASE,
version: 4,
notes: { '1': [{ word: 'する', reading: 'する' }], '2': [{ word: '猫', reading: null }] },
tiers: { '1': 'mature', '2': 'young' },
}),
),
new Set(['する', '猫']),
);
});
test('known-word cache format rejects payloads that are not a known cache state', () => {
const notes = { '1': [{ word: 'する', reading: null }] };
assert.equal(parseKnownWordCacheState(null), null);
assert.equal(parseKnownWordCacheState('{}'), null);
// An unknown version must not be read as an empty cache.
assert.equal(parseKnownWordCacheState({ ...BASE, version: 99, notes }), null);
assert.equal(
parseKnownWordCacheState({ version: 4, scope: 'deck:test', notes, tiers: {} }),
null,
);
assert.equal(parseKnownWordCacheState({ version: 4, refreshedAtMs: 1, notes, tiers: {} }), null);
// v4 without its tiers map is a v3 payload mislabelled as v4.
assert.equal(parseKnownWordCacheState({ ...BASE, version: 4, notes }), null);
// v3 carries entry objects, not the bare strings v2 used.
assert.equal(parseKnownWordCacheState({ ...BASE, version: 3, notes: { '1': ['する'] } }), null);
});