Skip to content

Commit

Permalink
Improved vitest and importing getInputString
Browse files Browse the repository at this point in the history
  • Loading branch information
rmarscher committed Oct 2, 2024
1 parent 16690bb commit 676ba0e
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 34 deletions.
15 changes: 6 additions & 9 deletions packages/waku/src/lib/plugins/vite-plugin-fs-router-typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,10 @@ import { readdir, writeFile } from 'node:fs/promises';
import { existsSync, readFileSync } from 'node:fs';
import { SRC_ENTRIES, EXTENSIONS } from '../constants.js';
import { joinPath } from '../utils/path.js';
import { getInputString } from '../../router/common.js';

const SRC_PAGES = 'pages';

// from waku/router/common
export function getInputString(path: string): string {
if (!path.startsWith('/')) {
throw new Error('Path should start with `/`');
}
return path.slice(1);
}

// https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html#sec-names-and-keywords
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#identifiers
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#reserved_words
Expand Down Expand Up @@ -50,7 +43,11 @@ export function getImportModuleNames(filePaths: string[]): {
if (moduleNameCount[identifier]) {
identifier = `${identifier}_${moduleNameCount[identifier]}`;
}
moduleNames[getInputString(filePath)] = identifier;
try {
moduleNames[getInputString(filePath)] = identifier;
} catch (e) {
console.log(e);
}
}
return moduleNames;
}
Expand Down
74 changes: 49 additions & 25 deletions packages/waku/tests/vite-plugin-fs-router-typegen.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,56 @@ import {
getImportModuleNames,
toIdentifier,
} from '../src/lib/plugins/vite-plugin-fs-router-typegen.js';
import { LoggingFunction, RollupLog } from 'rollup';
import { fileURLToPath } from 'node:url';
import { build, FSWatcher, ViteDevServer } from 'vite';
import path from 'node:path';
import { existsSync, readFileSync, rmSync } from 'node:fs';
import { FSWatcher, ViteDevServer } from 'vite';
import { writeFile } from 'node:fs/promises';

const root = fileURLToPath(
new URL('./fixtures', import.meta.url),
);
const root = fileURLToPath(new URL('./fixtures', import.meta.url));

async function runTest(root: string, expectedEntriesGen: string, srcDir = 'plugin-fs-router-typegen') {
const entriesPath = path.join(root, srcDir, 'entries.gen.tsx');
if (existsSync(entriesPath)) {
rmSync(entriesPath);
}
vi.mock('prettier', () => {
return { format: (x: string) => x, resolveConfig: () => ({}) };
});
vi.mock('node:fs/promises', async (importOriginal) => {
const mod = await importOriginal();
return {
// https://vitest.dev/api/vi.html#vi-mock
// @ts-expect-error - docs say this should be inferred...
...mod,
writeFile: vi.fn(),
};
});

async function runTest(
root: string,
expectedEntriesGen: string,
srcDir = 'plugin-fs-router-typegen',
) {
const plugin = fsRouterTypegenPlugin({
srcDir,
});
expect(plugin.configureServer).toBeDefined();
expect(typeof plugin.configureServer).toBe('function');
expect(plugin.configResolved).toBeDefined();
expect(typeof plugin.configResolved).toBe('function');
if (typeof plugin.configureServer !== 'function' || typeof plugin.configResolved !== 'function') {
if (
typeof plugin.configureServer !== 'function' ||
typeof plugin.configResolved !== 'function'
) {
return;
}
// @ts-expect-error - we're not passing the full Vite config
await plugin.configResolved?.({ root });
await plugin.configureServer?.({ watcher: { add: () => { }, on: () => {} } as unknown as FSWatcher } as ViteDevServer);
const generated = readFileSync(entriesPath, 'utf-8');
expect(generated).toEqual(expectedEntriesGen);
await plugin.configureServer?.({
watcher: { add: () => {}, on: () => {} } as unknown as FSWatcher,
} as ViteDevServer);
await vi.waitFor(async () => {
if (vi.mocked(writeFile).mock.lastCall === undefined) {
throw new Error('writeFile not called');
}
});
expect(vi.mocked(writeFile).mock.lastCall?.[1]).toContain(expectedEntriesGen);
}

vi.mock('prettier', () => {
return { format: (x: string) => x, resolveConfig: () => ({ }) }
})

describe('vite-plugin-fs-router-typegen', () => {
test('generates valid module names for fs entries', async () => {
expect(toIdentifier('/_layout.tsx')).toBe('Layout');
Expand All @@ -61,14 +75,24 @@ describe('vite-plugin-fs-router-typegen', () => {
'/one__two_three.tsx',
]),
).toEqual({
'/one-two-three.tsx': 'OneTwoThree',
'/one/two/three.tsx': 'OneTwoThree_1',
'/one_two_three.tsx': 'OneTwoThree_2',
'/one__two_three.tsx': 'OneTwoThree_3',
'one-two-three.tsx': 'OneTwoThree',
'one/two/three.tsx': 'OneTwoThree_1',
'one_two_three.tsx': 'OneTwoThree_2',
'one__two_three.tsx': 'OneTwoThree_3',
});
});

test('creates the expected imports the generated entries file', async () => {
await runTest(root, `export * from './_layout';\n`);
await runTest(
root,
`import CategoryTagsIndex, { getConfig as CategoryTagsIndex_getConfig } from './pages/[category]/[...tags]/index';
import CategoryLayout, { getConfig as CategoryLayout_getConfig } from './pages/[category]/_layout';
import Layout, { getConfig as Layout_getConfig } from './pages/_layout';
import Index, { getConfig as Index_getConfig } from './pages/index';
import OneTwoThree, { getConfig as OneTwoThree_getConfig } from './pages/one-two-three';
import OneTwoThree_1, { getConfig as OneTwoThree_1_getConfig } from './pages/one__two_three';
import OneTwoThree_2, { getConfig as OneTwoThree_2_getConfig } from './pages/one_two_three';
import ØnéTwoThree, { getConfig as ØnéTwoThree_getConfig } from './pages/øné_two_three';`,
);
});
});

0 comments on commit 676ba0e

Please sign in to comment.