Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"@nx/react": "22.3.3",
"@nx/vite": "22.3.3",
"@nx/workspace": "22.3.3",
"@push-based/jiti-tsc": "^0.0.2",
"@push-based/nx-verdaccio": "0.0.7",
"@swc-node/register": "1.9.2",
"@swc/cli": "0.6.0",
Expand Down Expand Up @@ -102,7 +103,7 @@
"husky": "^8.0.0",
"inquirer": "^9.3.7",
"jest-extended": "^6.0.0",
"jiti": "2.4.2",
"jiti": "^2.6.1",
"jsdom": "~24.0.0",
"jsonc-eslint-parser": "^2.4.0",
"knip": "^5.33.3",
Expand Down
43 changes: 43 additions & 0 deletions packages/cli/mocks/fixtures/configs/code-pushup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export default {
upload: {
organization: 'code-pushup',
project: 'cli-js',
apiKey: 'e2e-api-key',
server: 'https://e2e.com/api',
},
categories: [
{
slug: 'category-1',
title: 'Category 1',
refs: [
{
type: 'audit',
plugin: 'node',
slug: 'node-version',
weight: 1,
},
],
},
],
plugins: [
{
audits: [
{
slug: 'node-version',
title: 'Node version',
description: 'prints node version to file',
docsUrl: 'https://nodejs.org/',
},
],
runner: {
command: 'node',
args: ['-v'],
outputFile: 'output.json',
},
groups: [],
slug: 'node',
title: 'Node.js',
icon: 'javascript',
},
],
};
43 changes: 43 additions & 0 deletions packages/cli/mocks/fixtures/configs/code-pushup.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export default {
upload: {
organization: 'code-pushup',
project: 'cli-mjs',
apiKey: 'e2e-api-key',
server: 'https://e2e.com/api',
},
categories: [
{
slug: 'category-1',
title: 'Category 1',
refs: [
{
type: 'audit',
plugin: 'node',
slug: 'node-version',
weight: 1,
},
],
},
],
plugins: [
{
audits: [
{
slug: 'node-version',
title: 'Node version',
description: 'prints node version to file',
docsUrl: 'https://nodejs.org/',
},
],
runner: {
command: 'node',
args: ['-v'],
outputFile: 'output.json',
},
groups: [],
slug: 'node',
title: 'Node.js',
icon: 'javascript',
},
],
};
45 changes: 45 additions & 0 deletions packages/cli/mocks/fixtures/configs/code-pushup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { type CoreConfig } from '@code-pushup/models';

export default {
upload: {
organization: 'code-pushup',
project: 'cli-ts',
apiKey: 'e2e-api-key',
server: 'https://e2e.com/api',
},
categories: [
{
slug: 'category-1',
title: 'Category 1',
refs: [
{
type: 'audit',
plugin: 'node',
slug: 'node-version',
weight: 1,
},
],
},
],
plugins: [
{
audits: [
{
slug: 'node-version',
title: 'Node version',
description: 'prints node version to file',
docsUrl: 'https://nodejs.org/',
},
],
runner: {
command: 'node',
args: ['-v'],
outputFile: 'output.json',
},
groups: [],
slug: 'node',
title: 'Node.js',
icon: 'javascript',
},
],
} satisfies CoreConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// the point is to test runtime import which relies on alias defined in tsconfig.json "paths"
// non-type import from '@example/custom-plugin' wouldn't work without --tsconfig
// eslint-disable-next-line import/no-unresolved
import customPlugin from '@definitely-non-existent-package/custom-plugin';

const config = {
plugins: [customPlugin],
};

export default config;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// the point is to test runtime import which relies on alias defined in tsconfig.json "paths"
// non-type import from '@example/custom-plugin' wouldn't work without --tsconfig
// eslint-disable-next-line import/no-unresolved
import customPlugin from '@definitely-non-existent-package/custom-plugin';

const config = {
plugins: [customPlugin],
};

export default config;
24 changes: 24 additions & 0 deletions packages/cli/mocks/fixtures/configs/custom-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const customPluginConfig = {
slug: 'good-feels',
title: 'Good feels',
icon: 'javascript',
audits: [
{
slug: 'always-perfect',
title: 'Always perfect',
},
],
runner: () => [
{
slug: 'always-perfect',
score: 1,
value: 100,
displayValue: '✅ Perfect! 👌',
},
],
};

export function customPlugin() {
return customPluginConfig;
}
export default customPluginConfig;
7 changes: 7 additions & 0 deletions packages/cli/mocks/fixtures/configs/tsconfig.alias.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"paths": {
"@definitely-non-existent-package/custom-plugin": ["./custom-plugin.ts"]
}
}
}
5 changes: 5 additions & 0 deletions packages/cli/mocks/fixtures/configs/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"paths": {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ const configDirPath = path.join(
'configs',
);

const localMocks = path.join(
fileURLToPath(path.dirname(import.meta.url)),
'..',
'..',
'..',
'mocks',
'fixtures',
'configs',
);

describe('coreConfigMiddleware', () => {
const CLI_DEFAULTS = {
plugins: [],
Expand All @@ -29,7 +39,7 @@ describe('coreConfigMiddleware', () => {
'should load a valid .%s config',
async extension => {
const config = await coreConfigMiddleware({
config: path.join(configDirPath, `code-pushup.config.${extension}`),
config: path.join(localMocks, `code-pushup.config.${extension}`),
...CLI_DEFAULTS,
});
expect(config.config).toContain(`code-pushup.config.${extension}`);
Expand All @@ -46,11 +56,8 @@ describe('coreConfigMiddleware', () => {
it('should load config which relies on provided --tsconfig', async () => {
await expect(
coreConfigMiddleware({
config: path.join(
configDirPath,
'code-pushup.needs-tsconfig.config.ts',
),
tsconfig: path.join(configDirPath, 'tsconfig.json'),
config: path.join(localMocks, 'code-pushup.needs-tsconfig.config.ts'),
tsconfig: path.join(localMocks, 'tsconfig.alias.json'),
...CLI_DEFAULTS,
}),
).resolves.toBeTruthy();
Expand All @@ -60,11 +67,13 @@ describe('coreConfigMiddleware', () => {
await expect(
coreConfigMiddleware({
config: path.join(
configDirPath,
'code-pushup.needs-tsconfig.config.ts',
localMocks,
'code-pushup.needs-tsconfig-fail.config.ts',
),
...CLI_DEFAULTS,
}),
).rejects.toThrow("Cannot find package '@example/custom-plugin'");
).rejects.toThrow(
"Cannot find module '@definitely-non-existent-package/custom-plugin'",
);
});
});
33 changes: 20 additions & 13 deletions packages/core/src/lib/implementation/read-rc-file.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,39 @@ import { CONFIG_FILE_NAME, type CoreConfig } from '@code-pushup/models';
import { MEMFS_VOLUME } from '@code-pushup/test-utils';
import { autoloadRc } from './read-rc-file.js';

// mock bundleRequire inside importEsmModule used for fetching config
vi.mock('bundle-require', async () => {
// mock jiti used for fetching config
vi.mock('jiti', async () => {
const { CORE_CONFIG_MOCK }: Record<string, CoreConfig> =
await vi.importActual('@code-pushup/test-fixtures');

const actualJiti = await vi.importActual('jiti');

return {
bundleRequire: vi
.fn()
.mockImplementation((options: { filepath: string }) => {
const extension = options.filepath.split('.').at(-1);
return {
mod: {
default: {
...actualJiti,
createJiti: vi.fn().mockImplementation(() => ({
import: vi
.fn()
.mockImplementation(
(filepath: string, options: { default?: boolean }) => {
const extension = filepath.split('.').at(-1);
const config = {
...CORE_CONFIG_MOCK,
upload: {
...CORE_CONFIG_MOCK?.upload,
project: extension, // returns loaded file extension to check format precedence
},
},
};

// When default: true is passed, return the config directly
// Otherwise return { default: config }
return options?.default ? config : { default: config };
},
};
}),
),
})),
};
});

// Note: memfs files are only listed to satisfy a system check, value is used from bundle-require mock
// Note: memfs files are only listed to satisfy a system check, value is used from jiti mock
describe('autoloadRc', () => {
it('prioritise a .ts configuration file', async () => {
vol.fromJSON(
Expand Down
Loading
Loading