feat(bgm): add vite plugin and build integration test
Move the bgm vite plugin into the package so it can be tested in isolation from the web app. Serve each package as a JSON module, serializing its maps, and verify resolution through a real vite build against a self-contained fixture.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import * as path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { bgm } from './vite.js';
|
||||
|
||||
const fixtureRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '__fixtures__');
|
||||
const gamesRoot = path.join(fixtureRoot, 'harbor');
|
||||
|
||||
/**
|
||||
* Vite 8 types plugin hooks as `ObjectHook`, which may be a plain function or
|
||||
* a `{ handler, order }` object. Our plugin uses plain functions, so cast the
|
||||
* hook to a callable for direct invocation in tests.
|
||||
*/
|
||||
type Callable<T> = T extends (...args: infer A) => infer R ? (...args: A) => R : never;
|
||||
|
||||
function resolveId(plugin: ReturnType<typeof bgm>, id: string): unknown {
|
||||
return (plugin.resolveId as Callable<typeof plugin.resolveId>)(id, undefined, {
|
||||
isEntry: false,
|
||||
});
|
||||
}
|
||||
|
||||
function load(plugin: ReturnType<typeof bgm>, id: string): unknown {
|
||||
return (plugin.load as Callable<typeof plugin.load>)(id, { ssr: false });
|
||||
}
|
||||
|
||||
describe('bgm vite plugin', () => {
|
||||
it('resolves bgm/ imports to the virtual module', () => {
|
||||
const plugin = bgm({ root: gamesRoot });
|
||||
expect(resolveId(plugin, 'bgm/harbor')).toBe('\0bgm:bgm/harbor');
|
||||
expect(resolveId(plugin, 'bgm/nope')).toBe('\0bgm:bgm/nope');
|
||||
expect(resolveId(plugin, 'other')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('loads a package as a JSON module', () => {
|
||||
const plugin = bgm({ root: gamesRoot });
|
||||
const code = load(plugin, '\0bgm:bgm/harbor');
|
||||
expect(code).toBeDefined();
|
||||
expect(String(code).startsWith('export default ')).toBe(true);
|
||||
const pkg = JSON.parse(String(code).slice('export default '.length));
|
||||
expect(pkg.meta.id).toBe('harbor');
|
||||
expect(pkg.parts).toHaveProperty('token#wood');
|
||||
expect(pkg.surfaces).toHaveProperty('board#harbor');
|
||||
});
|
||||
|
||||
it('errors on an unknown package', () => {
|
||||
const plugin = bgm({ root: gamesRoot });
|
||||
expect(() => load(plugin, '\0bgm:bgm/unknown')).toThrow(/not found/);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user