52 lines
2.7 KiB
JavaScript
52 lines
2.7 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const { readFileSync, existsSync } = require('node:fs');
|
|
const { join } = require('node:path');
|
|
|
|
const root = join(__dirname, '..');
|
|
const html = readFileSync(join(__dirname, 'index.html'), 'utf8');
|
|
const sw = readFileSync(join(__dirname, 'sw.js'), 'utf8');
|
|
const shellMatch = sw.match(/const SHELL = \[([\s\S]*?)\n\];/);
|
|
assert.ok(shellMatch, 'service worker SHELL list is present');
|
|
const shell = [...shellMatch[1].matchAll(/['"](\/[^'"]+)['"]/g)].map((match) => match[1]);
|
|
const listed = new Set(shell);
|
|
|
|
test('every local script and stylesheet in index.html is precached by the service worker', () => {
|
|
const localAssets = [];
|
|
for (const match of html.matchAll(/<(?:script\b[^>]*\bsrc|link\b[^>]*\bhref)="([^"]+)"/gi)) {
|
|
const url = match[1];
|
|
if (/^(?:[a-z]+:|\/|#)/i.test(url)) continue;
|
|
if (!/\.(?:js|css)(?:[?#]|$)/i.test(url)) continue;
|
|
localAssets.push(`/${url.split(/[?#]/, 1)[0]}`);
|
|
}
|
|
assert.ok(localAssets.length > 0, 'found local script/style assets');
|
|
for (const asset of localAssets) assert.ok(listed.has(asset), `${asset} appears in SHELL`);
|
|
});
|
|
|
|
test('every SHELL asset exists on disk and there are no duplicate entries', () => {
|
|
assert.equal(new Set(shell).size, shell.length, 'SHELL has no duplicate entries');
|
|
for (const asset of shell) assert.ok(existsSync(join(__dirname, asset.slice(1))), `${asset} exists`);
|
|
});
|
|
|
|
test('assets.json describes the complete existing shell exactly once with eager core features', () => {
|
|
const { groups } = JSON.parse(readFileSync(join(__dirname, 'assets.json'), 'utf8'));
|
|
const described = new Set();
|
|
for (const [name, group] of Object.entries(groups)) {
|
|
assert.equal(group.contract, 1, `${name} initial contract`);
|
|
assert.equal(typeof group.eager, 'boolean');
|
|
for (const asset of group.files) {
|
|
assert.ok(!described.has(asset), `${asset} has one group`);
|
|
described.add(asset);
|
|
assert.ok(existsSync(join(__dirname, asset.slice(1))), `${asset} exists`);
|
|
}
|
|
}
|
|
for (const asset of shell) if (asset !== '/') assert.ok(described.has(asset), `${asset} is described`);
|
|
// piano-engine is dynamically imported and historically absent from SHELL.
|
|
for (const asset of described) assert.ok(listed.has(asset) || asset === '/piano-engine.mjs', `${asset} shell or documented dynamic import`);
|
|
assert.equal(groups.core.eager, true);
|
|
for (const name of ['playlist', 'settings', 'service-mode', 'lyrics-editor']) {
|
|
assert.equal(groups[`feature:${name}`].eager, true);
|
|
for (const asset of groups[`feature:${name}`].embeddedIn) assert.ok(groups.core.files.includes(asset), `${name} remains in core`);
|
|
}
|
|
});
|