GitNexus/gitnexus/test/unit/node-workspace-vite-structure.test.ts
Abhinav Pandey 79f210c5b5
fix(go, workspace): resolve test siblings and tighten package discovery (#3191)
* fix(go): resolve test helpers through package sibling tables

* fix(workspace): discover source entries from scoped static configuration

* Address PR review feedback (#3191)

- Align sibling comments with the no-bare-name partition and drop the stale same-dir fallback claim.
- Pin `_test.go` dot-import wildcard augmentation so a revert to nonTestFiles cannot stay green.

Note: pre-existing failure in worker-pool startup crashes in the full vitest suite not addressed by this PR.
Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: tighten workspace discovery and index Go sibling bindings

Skip leftover test/ workspace roots and extra Vite configs. Publish
same-package Go names from per-package indexes instead of pairing every file.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-10 12:22:12 +01:00

113 lines
5 KiB
TypeScript

import { afterAll, describe, expect, it } from 'vitest';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { loadNodeWorkspacePackages } from '../../src/core/ingestion/import-resolvers/node-workspace-packages.js';
const roots: string[] = [];
afterAll(() => {
for (const root of roots) fs.rmSync(root, { recursive: true, force: true });
});
async function entriesFor(config: string, legacy = false): Promise<readonly string[]> {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'gn-vite-structure-'));
roots.push(root);
fs.mkdirSync(path.join(root, 'src'));
fs.writeFileSync(
path.join(root, 'package.json'),
JSON.stringify({
name: '@test/config',
...(legacy ? { main: './dist/bundle.js' } : { exports: { '.': './dist/bundle.js' } }),
}),
);
fs.writeFileSync(path.join(root, 'vite.config.ts'), config);
for (const name of ['wrong', 'right', 'index']) {
fs.writeFileSync(path.join(root, 'src', `${name}.ts`), `export const ${name} = 1;`);
}
return (await loadNodeWorkspacePackages(root))!.byName.get('@test/config')!.entries;
}
describe('Vite discovery follows only the exported static build.lib.entry', () => {
it('refuses conventional legacy main fallbacks when a config is dynamic', async () => {
expect(
await entriesFor(`export default { build: { lib: { entry: dynamic } } };`, true),
).toEqual(['dist/bundle']);
});
it('does not let a conventional legacy entry outrank the explicit Vite entry', async () => {
expect(
await entriesFor(`export default { build: { lib: { entry: 'src/right.ts' } } };`, true),
).toEqual(['dist/bundle', 'src/right']);
});
it.each([
`const old = { lib: { entry: 'src/wrong.ts' } };`,
`const text = "lib: { entry: 'src/wrong.ts' }";`,
'const text = `lib: { entry: "src/wrong.ts" }`;',
])('ignores unrelated config-shaped syntax: %s', async (prefix) => {
const entries = await entriesFor(
`${prefix}\nexport default { build: { lib: { entry: 'src/right.ts' } } };`,
);
expect(entries).toContain('src/right');
expect(entries).not.toContain('src/wrong');
});
it.each([
`const old = { lib: { entry: 'src/wrong.ts' } }; export default {};`,
`export default choose({ build: { lib: { entry: 'src/wrong.ts' } } });`,
`import { defineConfig } from './custom'; export default defineConfig({ build: { lib: { entry: 'src/wrong.ts' } } });`,
`function defineConfig() { return {}; } export default defineConfig({ build: { lib: { entry: 'src/wrong.ts' } } });`,
`export default { build: { lib: { entry: 'src/wrong.ts', ...override } } };`,
`export default { build: { lib: { entry: 'src/wrong.ts' } }, ...override };`,
`export default { build: { lib: { entry: 'src/wrong.ts', ['entry']: dynamic } } };`,
`export default { build: { lib: { entry: dynamic } } };`,
`export default process.env.X ? {} : { build: { lib: { entry: 'src/wrong.ts' } } };`,
])('refuses an unestablished entry without conventional fallback: %s', async (config) => {
expect(await entriesFor(config)).toEqual(['dist/bundle']);
});
it('accepts quoted property names through defineConfig', async () => {
expect(
await entriesFor(
`import { defineConfig } from 'vite'; export default defineConfig({ 'build': { "lib": { entry: 'src/right.ts' } } });`,
),
).toContain('src/right');
});
});
describe('Vite discovery uses the first existing config filename', () => {
async function entriesForConfigs(files: Record<string, string>): Promise<readonly string[]> {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'gn-vite-leftover-'));
roots.push(root);
fs.mkdirSync(path.join(root, 'src'));
fs.writeFileSync(
path.join(root, 'package.json'),
JSON.stringify({ name: '@test/config', main: './dist/bundle.js' }),
);
for (const [name, text] of Object.entries(files)) {
fs.writeFileSync(path.join(root, name), text);
}
for (const name of ['from-js', 'from-ts', 'from-mjs']) {
fs.writeFileSync(path.join(root, 'src', `${name}.ts`), `export const ${name} = 1;`);
}
return (await loadNodeWorkspacePackages(root))!.byName.get('@test/config')!.entries;
}
it("adopts Vite's first existing file instead of refusing leftover siblings", async () => {
const entries = await entriesForConfigs({
'vite.config.js': `export default { build: { lib: { entry: 'src/from-js.ts' } } };\n`,
'vite.config.ts': `export default { build: { lib: { entry: 'src/from-ts.ts' } } };\n`,
});
expect(entries).toContain('src/from-js');
expect(entries).not.toContain('src/from-ts');
expect(entries).toContain('dist/bundle');
});
it('does not fall through to a later filename when the first config exists', async () => {
const entries = await entriesForConfigs({
'vite.config.mjs': `export default { build: { lib: { entry: 'src/from-mjs.ts' } } };\n`,
'vite.config.ts': `export default { build: { lib: { entry: 'src/from-ts.ts' } } };\n`,
});
expect(entries).toContain('src/from-mjs');
expect(entries).not.toContain('src/from-ts');
});
});