Skip to content

Commit d27bc8c

Browse files
committed
refactor: wip
1 parent 203cb69 commit d27bc8c

File tree

5 files changed

+110
-90
lines changed

5 files changed

+110
-90
lines changed

packages/core/src/lib/implementation/read-rc-file.unit.test.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,33 @@ import { CONFIG_FILE_NAME, type CoreConfig } from '@code-pushup/models';
33
import { MEMFS_VOLUME } from '@code-pushup/test-utils';
44
import { autoloadRc } from './read-rc-file.js';
55

6-
// mock bundleRequire inside importEsmModule used for fetching config
7-
vi.mock('bundle-require', async () => {
6+
// mock importModule from @code-pushup/utils used for fetching config
7+
vi.mock('@code-pushup/utils', async () => {
8+
const utils =
9+
await vi.importActual<typeof import('@code-pushup/utils')>(
10+
'@code-pushup/utils',
11+
);
812
const { CORE_CONFIG_MOCK }: Record<string, CoreConfig> =
913
await vi.importActual('@code-pushup/test-fixtures');
1014

1115
return {
12-
bundleRequire: vi
16+
...utils,
17+
importModule: vi
1318
.fn()
14-
.mockImplementation((options: { filepath: string }) => {
19+
.mockImplementation(async (options: { filepath: string }) => {
1520
const extension = options.filepath.split('.').at(-1);
1621
return {
17-
mod: {
18-
default: {
19-
...CORE_CONFIG_MOCK,
20-
upload: {
21-
...CORE_CONFIG_MOCK?.upload,
22-
project: extension, // returns loaded file extension to check format precedence
23-
},
24-
},
22+
...CORE_CONFIG_MOCK,
23+
upload: {
24+
...CORE_CONFIG_MOCK?.upload,
25+
project: extension, // returns loaded file extension to check format precedence
2526
},
2627
};
2728
}),
2829
};
2930
});
3031

31-
// Note: memfs files are only listed to satisfy a system check, value is used from bundle-require mock
32+
// Note: memfs files are only listed to satisfy a system check, value is used from importModule mock
3233
describe('autoloadRc', () => {
3334
it('prioritise a .ts configuration file', async () => {
3435
vol.fromJSON(

packages/plugin-coverage/src/lib/nx/coverage-paths.unit.test.ts

Lines changed: 69 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -13,80 +13,86 @@ import {
1313
getCoveragePathsForTarget,
1414
} from './coverage-paths.js';
1515

16-
vi.mock('bundle-require', () => ({
17-
bundleRequire: vi.fn().mockImplementation((options: { filepath: string }) => {
18-
const VITEST_VALID: VitestCoverageConfig = {
19-
test: {
20-
coverage: {
21-
reporter: ['lcov'],
22-
reportsDirectory: path.join('coverage', 'cli'),
23-
},
24-
},
25-
};
16+
vi.mock('@code-pushup/utils', async () => {
17+
const utils =
18+
await vi.importActual<typeof import('@code-pushup/utils')>(
19+
'@code-pushup/utils',
20+
);
2621

27-
const VITEST_NO_DIR: VitestCoverageConfig = {
28-
test: { coverage: { reporter: ['lcov'] } },
29-
};
22+
return {
23+
...utils,
24+
importModule: vi
25+
.fn()
26+
.mockImplementation(async (options: { filepath: string }) => {
27+
const VITEST_VALID: VitestCoverageConfig = {
28+
test: {
29+
coverage: {
30+
reporter: ['lcov'],
31+
reportsDirectory: path.join('coverage', 'cli'),
32+
},
33+
},
34+
};
3035

31-
const VITEST_NO_LCOV: VitestCoverageConfig = {
32-
test: {
33-
coverage: {
34-
reporter: ['json'],
35-
reportsDirectory: 'coverage',
36-
},
37-
},
38-
};
36+
const VITEST_NO_DIR: VitestCoverageConfig = {
37+
test: { coverage: { reporter: ['lcov'] } },
38+
};
3939

40-
const JEST_VALID: JestCoverageConfig = {
41-
coverageReporters: ['lcov'],
42-
coverageDirectory: path.join('coverage', 'core'),
43-
};
40+
const VITEST_NO_LCOV: VitestCoverageConfig = {
41+
test: {
42+
coverage: {
43+
reporter: ['json'],
44+
reportsDirectory: 'coverage',
45+
},
46+
},
47+
};
4448

45-
const JEST_NO_DIR: JestCoverageConfig = {
46-
coverageReporters: ['lcov'],
47-
};
49+
const JEST_VALID: JestCoverageConfig = {
50+
coverageReporters: ['lcov'],
51+
coverageDirectory: path.join('coverage', 'core'),
52+
};
4853

49-
const JEST_NO_LCOV: JestCoverageConfig = {
50-
coverageReporters: ['json'],
51-
coverageDirectory: 'coverage',
52-
};
54+
const JEST_NO_DIR: JestCoverageConfig = {
55+
coverageReporters: ['lcov'],
56+
};
5357

54-
const JEST_PRESET: JestCoverageConfig & { preset?: string } = {
55-
preset: '../../jest.preset.ts',
56-
coverageDirectory: 'coverage',
57-
};
58+
const JEST_NO_LCOV: JestCoverageConfig = {
59+
coverageReporters: ['json'],
60+
coverageDirectory: 'coverage',
61+
};
5862

59-
const wrapReturnValue = (
60-
value: VitestCoverageConfig | JestCoverageConfig,
61-
) => ({ mod: { default: value } });
63+
const JEST_PRESET: JestCoverageConfig & { preset?: string } = {
64+
preset: '../../jest.preset.ts',
65+
coverageDirectory: 'coverage',
66+
};
6267

63-
const config = options.filepath.split('.')[0];
64-
switch (config) {
65-
case 'vitest-valid':
66-
return wrapReturnValue(VITEST_VALID);
67-
case 'vitest-no-lcov':
68-
return wrapReturnValue(VITEST_NO_LCOV);
69-
case 'vitest-no-dir':
70-
return wrapReturnValue(VITEST_NO_DIR);
71-
case 'jest-valid':
72-
return wrapReturnValue(JEST_VALID);
73-
case 'jest-no-lcov':
74-
return wrapReturnValue(JEST_NO_LCOV);
75-
case 'jest-no-dir':
76-
return wrapReturnValue(JEST_NO_DIR);
77-
case 'jest-preset':
78-
return wrapReturnValue(JEST_PRESET);
79-
default:
80-
return wrapReturnValue({});
81-
}
82-
}),
83-
}));
68+
const config = options.filepath.split('.')[0];
69+
switch (config) {
70+
case 'vitest-valid':
71+
return VITEST_VALID;
72+
case 'vitest-no-lcov':
73+
return VITEST_NO_LCOV;
74+
case 'vitest-no-dir':
75+
return VITEST_NO_DIR;
76+
case 'jest-valid':
77+
return JEST_VALID;
78+
case 'jest-no-lcov':
79+
return JEST_NO_LCOV;
80+
case 'jest-no-dir':
81+
return JEST_NO_DIR;
82+
case 'jest-preset':
83+
return JEST_PRESET;
84+
default:
85+
return {};
86+
}
87+
}),
88+
};
89+
});
8490

8591
describe('getCoveragePathForTarget', () => {
8692
beforeEach(() => {
8793
vol.fromJSON(
8894
{
89-
// values come from bundle-require mock above
95+
// values come from importModule mock above
9096
'vitest-valid.config.ts': '',
9197
'jest-valid.config.ts': '',
9298
},
@@ -162,7 +168,7 @@ describe('getCoveragePathForVitest', () => {
162168
beforeEach(() => {
163169
vol.fromJSON(
164170
{
165-
// values come from bundle-require mock above
171+
// values come from importModule mock above
166172
'vitest-valid.config.unit.ts': '',
167173
'vitest-no-dir.config.integration.ts': '',
168174
'vitest-no-lcov.config.integration.ts': '',
@@ -260,7 +266,7 @@ describe('getCoveragePathForJest', () => {
260266
beforeEach(() => {
261267
vol.fromJSON(
262268
{
263-
// values come from bundle-require mock above
269+
// values come from importModule mock above
264270
'jest-preset.config.ts': '',
265271
'jest-valid.config.unit.ts': '',
266272
'jest-valid.config.integration.ts': '',

packages/plugin-lighthouse/src/lib/runner/utils.unit.test.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,26 @@ import {
2525
withLocalTmpDir,
2626
} from './utils.js';
2727

28-
// mock bundleRequire inside importEsmModule used for fetching config
29-
vi.mock('bundle-require', async () => {
28+
// mock importModule from @code-pushup/utils used for fetching config
29+
vi.mock('@code-pushup/utils', async () => {
30+
const utils =
31+
await vi.importActual<typeof import('@code-pushup/utils')>(
32+
'@code-pushup/utils',
33+
);
3034
const { CORE_CONFIG_MOCK }: Record<string, CoreConfig> =
3135
await vi.importActual('@code-pushup/test-utils');
3236

3337
return {
34-
bundleRequire: vi
38+
...utils,
39+
importModule: vi
3540
.fn()
36-
.mockImplementation((options: { filepath: string }) => {
41+
.mockImplementation(async (options: { filepath: string }) => {
3742
const project = options.filepath.split('.').at(-2);
3843
return {
39-
mod: {
40-
default: {
41-
...CORE_CONFIG_MOCK,
42-
upload: {
43-
...CORE_CONFIG_MOCK?.upload,
44-
project, // returns loaded file extension to check in test
45-
},
46-
},
44+
...CORE_CONFIG_MOCK,
45+
upload: {
46+
...CORE_CONFIG_MOCK?.upload,
47+
project, // returns loaded file extension to check in test
4748
},
4849
};
4950
}),

packages/utils/src/lib/import-module.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ export type ImportModuleOptions = JitiOptions & {
2828
};
2929

3030
export function toFileUrl(filepath: string): string {
31+
// Handle Windows absolute paths (C:\Users\... or C:/Users/...) on all platforms
32+
// pathToFileURL on non-Windows systems treats Windows paths as relative paths
33+
const windowsAbsolutePathMatch = filepath.match(/^([A-Za-z]:)([\\/].*)$/);
34+
if (windowsAbsolutePathMatch) {
35+
const [, drive, rest] = windowsAbsolutePathMatch;
36+
// Normalize backslashes to forward slashes and construct file URL manually
37+
const normalizedPath = `${drive}${rest.replace(/\\/g, '/')}`;
38+
return `file:///${normalizedPath}`;
39+
}
3140
return pathToFileURL(filepath).href;
3241
}
3342

@@ -56,7 +65,7 @@ export async function importModule<T = unknown>(
5665
tsconfigPath: tsconfig,
5766
});
5867

59-
return (await jitiInstance.import(toFileUrl(absoluteFilePath), {
68+
return (await jitiInstance.import(absoluteFilePath, {
6069
default: true,
6170
})) as T;
6271
}

packages/utils/src/lib/import-module.unit.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,10 @@ describe('toFileUrl', () => {
117117
expect(toFileUrl(absolutePath)).toBe(pathToFileURL(absolutePath).href);
118118
});
119119

120-
it('normalizes Windows absolute paths to file URLs', () => {
120+
it('normalizes Windows absolute paths to file URLs for native import()', () => {
121+
// Note: This is only needed for native import() calls, not for jiti.import()
122+
// jiti handles Windows paths directly without URL conversion
123+
// We should avoid native import calls in general
121124
const windowsPath = path.win32.join('C:\\', 'Users', 'me', 'config.ts');
122125
expect(toFileUrl(windowsPath)).toBe('file:///C:/Users/me/config.ts');
123126
});

0 commit comments

Comments
 (0)