110 lines
3.1 KiB
TypeScript
110 lines
3.1 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { resolveViteAssetClosure } from '../../scripts/build-contract.mjs';
|
|
import type { ViteManifest } from '../../scripts/prerender.mjs';
|
|
|
|
const recursiveManifest = (): ViteManifest => ({
|
|
'index.html': {
|
|
file: 'assets/entry-a1.js',
|
|
src: 'index.html',
|
|
isEntry: true,
|
|
css: ['assets/entry-a1.css'],
|
|
assets: ['assets/entry-logo-a1.webp'],
|
|
imports: ['src/shared.ts'],
|
|
dynamicImports: ['src/lazy.ts'],
|
|
},
|
|
'src/shared.ts': {
|
|
file: 'assets/shared-b2.js',
|
|
src: 'src/shared.ts',
|
|
css: ['assets/shared-b2.css'],
|
|
imports: ['src/deep.ts'],
|
|
},
|
|
'src/deep.ts': {
|
|
file: 'assets/deep-c3.js',
|
|
src: 'src/deep.ts',
|
|
},
|
|
'src/lazy.ts': {
|
|
file: 'assets/lazy-d4.js',
|
|
src: 'src/lazy.ts',
|
|
css: ['assets/lazy-d4.css'],
|
|
},
|
|
});
|
|
|
|
describe('trusted Vite asset closure', () => {
|
|
it('resolves the exact recursive executable, preload, style, and Vite asset sets', () => {
|
|
expect(resolveViteAssetClosure(recursiveManifest())).toEqual({
|
|
entryModule: 'assets/entry-a1.js',
|
|
executableModules: [
|
|
'assets/deep-c3.js',
|
|
'assets/entry-a1.js',
|
|
'assets/lazy-d4.js',
|
|
'assets/shared-b2.js',
|
|
],
|
|
modulePreloads: [
|
|
'assets/deep-c3.js',
|
|
'assets/entry-a1.js',
|
|
'assets/shared-b2.js',
|
|
],
|
|
styles: [
|
|
'assets/entry-a1.css',
|
|
'assets/lazy-d4.css',
|
|
'assets/shared-b2.css',
|
|
],
|
|
viteAssets: ['assets/entry-logo-a1.webp'],
|
|
});
|
|
});
|
|
|
|
it('accepts Vite emitted-asset records when a reachable module owns the emitted file', () => {
|
|
const manifest = recursiveManifest();
|
|
manifest['index.html']!.assets = [
|
|
'assets/entry-logo-a1.webp',
|
|
'assets/geist-latin-a1.woff2',
|
|
];
|
|
manifest['node_modules/font/files/geist-latin.woff2'] = {
|
|
file: 'assets/geist-latin-a1.woff2',
|
|
src: 'node_modules/font/files/geist-latin.woff2',
|
|
};
|
|
|
|
expect(resolveViteAssetClosure(manifest).viteAssets).toEqual([
|
|
'assets/entry-logo-a1.webp',
|
|
'assets/geist-latin-a1.woff2',
|
|
]);
|
|
});
|
|
|
|
it.each([
|
|
{
|
|
name: 'a missing exact index.html entry',
|
|
mutate: (manifest: ViteManifest) => {
|
|
manifest['src/entry-client.ts'] = manifest['index.html']!;
|
|
delete manifest['index.html'];
|
|
},
|
|
error: /exact index\.html/i,
|
|
},
|
|
{
|
|
name: 'an unreachable manifest record',
|
|
mutate: (manifest: ViteManifest) => {
|
|
manifest['src/orphan.ts'] = { file: 'assets/orphan.js', src: 'src/orphan.ts' };
|
|
},
|
|
error: /unreachable manifest/i,
|
|
},
|
|
{
|
|
name: 'an unsafe emitted path',
|
|
mutate: (manifest: ViteManifest) => {
|
|
manifest['src/shared.ts']!.file = '../outside.js';
|
|
},
|
|
error: /unsafe.*path/i,
|
|
},
|
|
{
|
|
name: 'a missing recursive import',
|
|
mutate: (manifest: ViteManifest) => {
|
|
manifest['src/shared.ts']!.imports = ['src/missing.ts'];
|
|
},
|
|
error: /missing manifest import/i,
|
|
},
|
|
])('rejects $name', ({ mutate, error }) => {
|
|
const manifest = recursiveManifest();
|
|
mutate(manifest);
|
|
|
|
expect(() => resolveViteAssetClosure(manifest)).toThrow(error);
|
|
});
|
|
});
|