You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
58 lines
2.2 KiB
58 lines
2.2 KiB
// Tests of create-words.ts: the list of the page, fetched once, with its
|
|
// pinned SHA-256, and fetched again after a failure.
|
|
|
|
import { readFileSync } from 'node:fs';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { describe, expect, it } from 'vitest';
|
|
import { type Fetcher, wordListLoader, WORDS_LANGUAGE } from './create-words.ts';
|
|
|
|
const list = new Uint8Array(readFileSync(fileURLToPath(new URL('../../../wordlists/es.txt', import.meta.url))));
|
|
|
|
describe('wordListLoader', () => {
|
|
it('fetches the Spanish list of the site once, and reads it with its pinned SHA-256', async () => {
|
|
const urls: string[] = [];
|
|
const load = wordListLoader(async (url) => {
|
|
urls.push(url);
|
|
return new Response(list.slice());
|
|
});
|
|
const [a, b] = await Promise.all([load(), load()]);
|
|
expect(WORDS_LANGUAGE).toBe('es');
|
|
expect(a).toHaveLength(7776);
|
|
expect(b).toBe(a);
|
|
expect(await load()).toBe(a);
|
|
expect(urls).toHaveLength(1);
|
|
expect(urls[0]).toMatch(/wordlists\/es\.txt$/);
|
|
});
|
|
|
|
it('tries again after a failure: an answer that is not 200, another list, a fetch that fails', async () => {
|
|
const changed = list.slice();
|
|
changed[0]! ^= 1;
|
|
const answers: (() => Promise<Response>)[] = [
|
|
async () => new Response('missing', { status: 404 }),
|
|
async () => new Response(changed),
|
|
async () => {
|
|
throw new TypeError('Failed to fetch');
|
|
},
|
|
async () => new Response(list.slice()),
|
|
];
|
|
let calls = 0;
|
|
const fetcher: Fetcher = () => answers[calls++]!();
|
|
const load = wordListLoader(fetcher);
|
|
await expect(load()).rejects.toThrow(/^the site answered 404 for the word list$/);
|
|
await expect(load()).rejects.toThrow(/^wordkey: the list "es" has the SHA-256 [0-9a-f]{64}, not ff77b487/);
|
|
await expect(load()).rejects.toThrow('Failed to fetch');
|
|
expect(await load()).toHaveLength(7776);
|
|
expect(calls).toBe(4);
|
|
});
|
|
|
|
it('fetches with the fetch of the page by default', async () => {
|
|
const real = globalThis.fetch;
|
|
globalThis.fetch = async () => new Response(list.slice());
|
|
try {
|
|
expect(await wordListLoader()()).toHaveLength(7776);
|
|
} finally {
|
|
globalThis.fetch = real;
|
|
}
|
|
});
|
|
});
|