Skip to content

Commit d8d2aba

Browse files
committed
refactor: rewrite of vite-plugin-runtime
1 parent 4caaa70 commit d8d2aba

File tree

12 files changed

+343
-533
lines changed

12 files changed

+343
-533
lines changed

packages/vite-plugin-runtime/package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@
44
"version": "0.0.0",
55
"license": "Apache-2.0",
66
"exports": {
7-
".": {
8-
"types": "./src/index.d.ts",
9-
"default": "./src/index.js"
10-
}
7+
".": "./src/index.js"
118
},
129
"scripts": {
1310
"format": "prettier --write src",

packages/vite-plugin-runtime/src/__tests__/index.test.ts

Lines changed: 0 additions & 108 deletions
This file was deleted.

packages/vite-plugin-runtime/src/__tests__/load-resource.test.ts

Lines changed: 0 additions & 83 deletions
This file was deleted.
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import * as path from 'path';
2+
3+
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
4+
5+
import { generateMetadataForVersion, MANIFEST_FILENAME, plugin, RUNTIME_DIR, RUNTIME_DIST_DIRNAME } from '../plugin';
6+
7+
const fs = vi.hoisted(() => ({
8+
existsSync: vi.fn().mockReturnValue(true),
9+
lstatSync: vi.fn().mockImplementation((filepath: string) => ({
10+
isDirectory: () => !filepath.split('/').at(-1)!.includes('.')
11+
})),
12+
promises: {
13+
cp: vi.fn(),
14+
readdir: vi.fn().mockImplementation((filepath: string) => {
15+
if (filepath === RUNTIME_DIR) {
16+
return ['v1', '.DS_Store'];
17+
} else if (filepath === path.join(RUNTIME_DIR, 'v1', RUNTIME_DIST_DIRNAME)) {
18+
return ['@opendatacapture'];
19+
} else if (filepath.endsWith('@opendatacapture')) {
20+
return ['runtime-core'];
21+
} else if (filepath.endsWith('runtime-core')) {
22+
return ['index.js', 'index.d.ts', 'styles'];
23+
} else if (filepath.endsWith('styles')) {
24+
return ['index.css'];
25+
}
26+
throw new Error(`Unexpected filepath for test mock: ${filepath}`);
27+
}),
28+
readFile: vi.fn(),
29+
writeFile: vi.fn()
30+
}
31+
}));
32+
33+
vi.mock('fs', () => fs);
34+
35+
describe('generateMetadataForVersion', () => {
36+
it('should throw if the resolved baseDir does not exist', async () => {
37+
fs.existsSync.mockReturnValueOnce(false);
38+
await expect(() => generateMetadataForVersion('v0')).rejects.toThrow('Not a directory');
39+
});
40+
41+
it('should throw if the resolved baseDir is not a directory', async () => {
42+
fs.lstatSync.mockReturnValueOnce({ isDirectory: () => false });
43+
await expect(() => generateMetadataForVersion('v0')).rejects.toThrow('Not a directory');
44+
});
45+
});
46+
47+
describe('plugin', () => {
48+
let result: any;
49+
50+
beforeAll(async () => {
51+
result = await plugin();
52+
});
53+
54+
it('should return false if disabled', async () => {
55+
await expect(plugin({ disabled: true })).resolves.toBe(false);
56+
});
57+
58+
describe('buildStart', () => {
59+
it('should copy the runtime dist and the manifest to the output dir', async () => {
60+
await result.buildStart();
61+
const destination = path.join(process.cwd(), 'dist/runtime/v1');
62+
expect(fs.promises.cp).toHaveBeenCalledOnce();
63+
expect(fs.promises.cp).toHaveBeenLastCalledWith(path.join(RUNTIME_DIR, 'v1', RUNTIME_DIST_DIRNAME), destination, {
64+
recursive: true
65+
});
66+
expect(fs.promises.writeFile).toHaveBeenCalledOnce();
67+
expect(fs.promises.writeFile).toHaveBeenLastCalledWith(expect.any(String), expect.any(String), 'utf-8');
68+
const manifest = JSON.parse(fs.promises.writeFile.mock.lastCall![1] as string);
69+
expect(manifest).toStrictEqual({
70+
declarations: ['@opendatacapture/runtime-core/index.d.ts'],
71+
sources: ['@opendatacapture/runtime-core/index.js'],
72+
styles: ['@opendatacapture/runtime-core/styles/index.css']
73+
});
74+
});
75+
});
76+
77+
describe('config', () => {
78+
it('should exclude the runtime import paths for optimizeDeps', () => {
79+
const config = result.config();
80+
expect(config).toMatchObject({
81+
optimizeDeps: {
82+
exclude: expect.any(Array)
83+
}
84+
});
85+
expect(config.optimizeDeps.exclude.every((s: any) => typeof s === 'string' && s.startsWith('/runtime')));
86+
});
87+
});
88+
89+
describe('configureServer', () => {
90+
let middleware: any;
91+
92+
const res = {
93+
end: vi.fn(),
94+
writeHead: vi.fn()
95+
};
96+
97+
const next = vi.fn();
98+
99+
afterEach(() => {
100+
vi.clearAllMocks();
101+
});
102+
103+
it('should configure a middleware function for /runtime', () => {
104+
const server = {
105+
middlewares: {
106+
use: vi.fn()
107+
}
108+
};
109+
result.configureServer(server);
110+
expect(server.middlewares.use).toHaveBeenCalledWith('/runtime', expect.any(Function));
111+
middleware = server.middlewares.use.mock.lastCall![1];
112+
});
113+
114+
it('should invoke next if the request url is null', async () => {
115+
await middleware({ url: null } as any, {} as any, next);
116+
expect(next).toHaveBeenCalledOnce();
117+
});
118+
119+
it('should invoke next if the request is for an unknown version', async () => {
120+
await middleware({ url: `/v0/${MANIFEST_FILENAME}` } as any, {} as any, next);
121+
expect(next).toHaveBeenCalledOnce();
122+
});
123+
124+
it('should correctly handle the manifest', async () => {
125+
await middleware({ url: `/v1/${MANIFEST_FILENAME}` } as any, res, next);
126+
expect(res.writeHead).toHaveBeenLastCalledWith(200, { 'Content-Type': 'application/json' });
127+
expect(res.end).toHaveBeenCalledOnce();
128+
});
129+
130+
it('should correctly handle declaration files', async () => {
131+
await middleware({ url: '/v1/@opendatacapture/runtime-core/index.d.ts' } as any, res, next);
132+
expect(res.writeHead).toHaveBeenLastCalledWith(200, { 'Content-Type': 'text/plain' });
133+
expect(res.end).toHaveBeenCalledOnce();
134+
});
135+
136+
it('should correctly handle source files', async () => {
137+
await middleware({ url: '/v1/@opendatacapture/runtime-core/index.js' } as any, res, next);
138+
expect(res.writeHead).toHaveBeenLastCalledWith(200, { 'Content-Type': 'text/javascript' });
139+
expect(res.end).toHaveBeenCalledOnce();
140+
});
141+
142+
it('should correctly handle css files', async () => {
143+
await middleware({ url: '/v1/@opendatacapture/runtime-core/styles/index.css' } as any, res, next);
144+
expect(res.writeHead).toHaveBeenLastCalledWith(200, { 'Content-Type': 'text/css' });
145+
expect(res.end).toHaveBeenCalledOnce();
146+
});
147+
148+
it('should invoke next for unknown files', async () => {
149+
await middleware({ url: '/v1/@opendatacapture/runtime-core/foo/index.js' } as any, {} as any, next);
150+
expect(next).toHaveBeenCalledOnce();
151+
expect(res.end).not.toHaveBeenCalled();
152+
});
153+
});
154+
});

0 commit comments

Comments
 (0)