From 1cb5cb136c2f41ce50e4c4bd443ebd91540d6645 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Fri, 5 Dec 2025 22:19:04 +0100 Subject: [PATCH 01/13] refactor: fixtures out of test project --- .../fixtures/configs/code-pushup.config.js | 0 .../fixtures/configs/code-pushup.config.mjs | 0 .../fixtures/configs/code-pushup.config.ts | 0 .../configs/code-pushup.empty.config.js | 0 .../configs/code-pushup.invalid.config.ts | 0 .../code-pushup.needs-tsconfig.config.ts | 0 .../mocks}/fixtures/configs/custom-plugin.ts | 0 .../cli/mocks}/fixtures/configs/tsconfig.json | 0 .../core-config.middleware.int.test.ts | 7 +-- .../fixtures/configs/code-pushup.config.js | 43 +++++++++++++++ .../fixtures/configs/code-pushup.config.mjs | 43 +++++++++++++++ .../fixtures/configs/code-pushup.config.ts | 45 ++++++++++++++++ .../configs/code-pushup.empty.config.js | 1 + .../configs/code-pushup.invalid.config.ts | 53 +++++++++++++++++++ .../code-pushup.needs-tsconfig.config.ts | 10 ++++ .../mocks/fixtures/configs/custom-plugin.ts | 24 +++++++++ .../core/mocks/fixtures/configs/tsconfig.json | 7 +++ .../implementation/read-rc-file.int.test.ts | 7 +-- 18 files changed, 228 insertions(+), 12 deletions(-) rename {testing/test-utils/src/lib => packages/cli/mocks}/fixtures/configs/code-pushup.config.js (100%) rename {testing/test-utils/src/lib => packages/cli/mocks}/fixtures/configs/code-pushup.config.mjs (100%) rename {testing/test-utils/src/lib => packages/cli/mocks}/fixtures/configs/code-pushup.config.ts (100%) rename {testing/test-utils/src/lib => packages/cli/mocks}/fixtures/configs/code-pushup.empty.config.js (100%) rename {testing/test-utils/src/lib => packages/cli/mocks}/fixtures/configs/code-pushup.invalid.config.ts (100%) rename {testing/test-utils/src/lib => packages/cli/mocks}/fixtures/configs/code-pushup.needs-tsconfig.config.ts (100%) rename {testing/test-utils/src/lib => packages/cli/mocks}/fixtures/configs/custom-plugin.ts (100%) rename {testing/test-utils/src/lib => packages/cli/mocks}/fixtures/configs/tsconfig.json (100%) create mode 100644 packages/core/mocks/fixtures/configs/code-pushup.config.js create mode 100644 packages/core/mocks/fixtures/configs/code-pushup.config.mjs create mode 100644 packages/core/mocks/fixtures/configs/code-pushup.config.ts create mode 100644 packages/core/mocks/fixtures/configs/code-pushup.empty.config.js create mode 100644 packages/core/mocks/fixtures/configs/code-pushup.invalid.config.ts create mode 100644 packages/core/mocks/fixtures/configs/code-pushup.needs-tsconfig.config.ts create mode 100644 packages/core/mocks/fixtures/configs/custom-plugin.ts create mode 100644 packages/core/mocks/fixtures/configs/tsconfig.json diff --git a/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.js b/packages/cli/mocks/fixtures/configs/code-pushup.config.js similarity index 100% rename from testing/test-utils/src/lib/fixtures/configs/code-pushup.config.js rename to packages/cli/mocks/fixtures/configs/code-pushup.config.js diff --git a/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.mjs b/packages/cli/mocks/fixtures/configs/code-pushup.config.mjs similarity index 100% rename from testing/test-utils/src/lib/fixtures/configs/code-pushup.config.mjs rename to packages/cli/mocks/fixtures/configs/code-pushup.config.mjs diff --git a/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.ts b/packages/cli/mocks/fixtures/configs/code-pushup.config.ts similarity index 100% rename from testing/test-utils/src/lib/fixtures/configs/code-pushup.config.ts rename to packages/cli/mocks/fixtures/configs/code-pushup.config.ts diff --git a/testing/test-utils/src/lib/fixtures/configs/code-pushup.empty.config.js b/packages/cli/mocks/fixtures/configs/code-pushup.empty.config.js similarity index 100% rename from testing/test-utils/src/lib/fixtures/configs/code-pushup.empty.config.js rename to packages/cli/mocks/fixtures/configs/code-pushup.empty.config.js diff --git a/testing/test-utils/src/lib/fixtures/configs/code-pushup.invalid.config.ts b/packages/cli/mocks/fixtures/configs/code-pushup.invalid.config.ts similarity index 100% rename from testing/test-utils/src/lib/fixtures/configs/code-pushup.invalid.config.ts rename to packages/cli/mocks/fixtures/configs/code-pushup.invalid.config.ts diff --git a/testing/test-utils/src/lib/fixtures/configs/code-pushup.needs-tsconfig.config.ts b/packages/cli/mocks/fixtures/configs/code-pushup.needs-tsconfig.config.ts similarity index 100% rename from testing/test-utils/src/lib/fixtures/configs/code-pushup.needs-tsconfig.config.ts rename to packages/cli/mocks/fixtures/configs/code-pushup.needs-tsconfig.config.ts diff --git a/testing/test-utils/src/lib/fixtures/configs/custom-plugin.ts b/packages/cli/mocks/fixtures/configs/custom-plugin.ts similarity index 100% rename from testing/test-utils/src/lib/fixtures/configs/custom-plugin.ts rename to packages/cli/mocks/fixtures/configs/custom-plugin.ts diff --git a/testing/test-utils/src/lib/fixtures/configs/tsconfig.json b/packages/cli/mocks/fixtures/configs/tsconfig.json similarity index 100% rename from testing/test-utils/src/lib/fixtures/configs/tsconfig.json rename to packages/cli/mocks/fixtures/configs/tsconfig.json diff --git a/packages/cli/src/lib/implementation/core-config.middleware.int.test.ts b/packages/cli/src/lib/implementation/core-config.middleware.int.test.ts index 464b1dfc2..d20641364 100644 --- a/packages/cli/src/lib/implementation/core-config.middleware.int.test.ts +++ b/packages/cli/src/lib/implementation/core-config.middleware.int.test.ts @@ -8,12 +8,7 @@ const configDirPath = path.join( '..', '..', '..', - '..', - '..', - 'testing', - 'test-utils', - 'src', - 'lib', + 'mocks', 'fixtures', 'configs', ); diff --git a/packages/core/mocks/fixtures/configs/code-pushup.config.js b/packages/core/mocks/fixtures/configs/code-pushup.config.js new file mode 100644 index 000000000..9f1661d4d --- /dev/null +++ b/packages/core/mocks/fixtures/configs/code-pushup.config.js @@ -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', + }, + ], +}; diff --git a/packages/core/mocks/fixtures/configs/code-pushup.config.mjs b/packages/core/mocks/fixtures/configs/code-pushup.config.mjs new file mode 100644 index 000000000..d7f531533 --- /dev/null +++ b/packages/core/mocks/fixtures/configs/code-pushup.config.mjs @@ -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', + }, + ], +}; diff --git a/packages/core/mocks/fixtures/configs/code-pushup.config.ts b/packages/core/mocks/fixtures/configs/code-pushup.config.ts new file mode 100644 index 000000000..aad20f9b6 --- /dev/null +++ b/packages/core/mocks/fixtures/configs/code-pushup.config.ts @@ -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; diff --git a/packages/core/mocks/fixtures/configs/code-pushup.empty.config.js b/packages/core/mocks/fixtures/configs/code-pushup.empty.config.js new file mode 100644 index 000000000..ff8b4c563 --- /dev/null +++ b/packages/core/mocks/fixtures/configs/code-pushup.empty.config.js @@ -0,0 +1 @@ +export default {}; diff --git a/packages/core/mocks/fixtures/configs/code-pushup.invalid.config.ts b/packages/core/mocks/fixtures/configs/code-pushup.invalid.config.ts new file mode 100644 index 000000000..7396948b9 --- /dev/null +++ b/packages/core/mocks/fixtures/configs/code-pushup.invalid.config.ts @@ -0,0 +1,53 @@ +import type { CoreConfig } from '@code-pushup/models'; + +export default { + persist: { outputDir: 'tmp' }, + upload: { + organization: 'code-pushup', + project: 'cli-ts', + apiKey: 'e2e-api-key', + server: 'https://e2e.com/api', + }, + categories: [ + { + slug: 'bug-prevention', + title: 'Bug prevention', + // due to duplicate category references, the config is invalid + refs: [ + { + type: 'audit', + plugin: 'node', + slug: 'node-version', + weight: 1, + }, + { + 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; diff --git a/packages/core/mocks/fixtures/configs/code-pushup.needs-tsconfig.config.ts b/packages/core/mocks/fixtures/configs/code-pushup.needs-tsconfig.config.ts new file mode 100644 index 000000000..44b4d0a2d --- /dev/null +++ b/packages/core/mocks/fixtures/configs/code-pushup.needs-tsconfig.config.ts @@ -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 '@example/custom-plugin'; + +const config = { + plugins: [customPlugin], +}; + +export default config; diff --git a/packages/core/mocks/fixtures/configs/custom-plugin.ts b/packages/core/mocks/fixtures/configs/custom-plugin.ts new file mode 100644 index 000000000..6afe6bc80 --- /dev/null +++ b/packages/core/mocks/fixtures/configs/custom-plugin.ts @@ -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; diff --git a/packages/core/mocks/fixtures/configs/tsconfig.json b/packages/core/mocks/fixtures/configs/tsconfig.json new file mode 100644 index 000000000..42976b47b --- /dev/null +++ b/packages/core/mocks/fixtures/configs/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "paths": { + "@example/custom-plugin": ["./custom-plugin.ts"] + } + } +} diff --git a/packages/core/src/lib/implementation/read-rc-file.int.test.ts b/packages/core/src/lib/implementation/read-rc-file.int.test.ts index dae34e77a..835e12551 100644 --- a/packages/core/src/lib/implementation/read-rc-file.int.test.ts +++ b/packages/core/src/lib/implementation/read-rc-file.int.test.ts @@ -9,12 +9,7 @@ describe('readRcByPath', () => { '..', '..', '..', - '..', - '..', - 'testing', - 'test-utils', - 'src', - 'lib', + 'mocks', 'fixtures', 'configs', ); From ec56398e237ddd43dae53b66d557a93306a68269 Mon Sep 17 00:00:00 2001 From: John Doe Date: Fri, 5 Dec 2025 23:02:20 +0100 Subject: [PATCH 02/13] refactor: intro test-fixtures project --- .../core-config.middleware.int.test.ts | 7 +- .../fixtures/configs/code-pushup.config.js | 43 - .../fixtures/configs/code-pushup.config.mjs | 43 - .../implementation/read-rc-file.int.test.ts | 7 +- testing/test-fixtures/README.md | 19 + testing/test-fixtures/eslint.config.js | 12 + testing/test-fixtures/package.json | 4 + testing/test-fixtures/project.json | 14 + testing/test-fixtures/src/index.ts | 21 + .../fixtures/configs/code-pushup.config.ts | 0 .../configs/code-pushup.empty.config.js | 0 .../configs/code-pushup.invalid.config.ts | 0 .../code-pushup.needs-tsconfig.config.ts | 0 .../lib}/fixtures/configs/custom-plugin.ts | 0 .../src/lib}/fixtures/configs/tsconfig.json | 0 .../src/lib/utils/commit.mock.ts | 15 + .../src/lib/utils/core-config.mock.ts | 72 ++ .../utils/dynamic-mocks/categories.mock.ts | 81 ++ .../lib/utils/dynamic-mocks/config.mock.ts | 68 ++ .../utils/dynamic-mocks/eslint-audits.mock.ts | 820 ++++++++++++++++++ .../utils/dynamic-mocks/eslint-plugin.mock.ts | 103 +++ .../dynamic-mocks/lighthouse-audits.mock.ts | 95 ++ .../dynamic-mocks/lighthouse-plugin.mock.ts | 96 ++ .../dynamic-mocks/persist-config.mock.ts | 19 + .../utils/dynamic-mocks/plugin-config.mock.ts | 57 ++ .../utils/dynamic-mocks/report-diff.mock.ts | 434 +++++++++ .../lib/utils/dynamic-mocks/report.mock.ts | 39 + .../utils/dynamic-mocks/runner-config.mock.ts | 43 + .../utils/dynamic-mocks/upload-config.mock.ts | 15 + .../src/lib/utils/minimal-config.mock.ts | 60 ++ .../src/lib/utils/omit-report-data.ts | 46 + .../src/lib/utils/os-agnostic.ts | 38 + .../src/lib/utils/report.mock.ts | 299 +++++++ testing/test-fixtures/tsconfig.json | 23 + testing/test-fixtures/tsconfig.lib.json | 14 + testing/test-fixtures/tsconfig.test.json | 8 + .../fixtures/configs/code-pushup.config.js | 0 .../fixtures/configs/code-pushup.config.mjs | 0 .../fixtures/configs/code-pushup.config.ts | 0 .../configs/code-pushup.empty.config.js | 0 .../configs/code-pushup.invalid.config.ts | 0 .../code-pushup.needs-tsconfig.config.ts | 0 .../lib}/fixtures/configs/custom-plugin.ts | 0 .../src/lib}/fixtures/configs/tsconfig.json | 0 44 files changed, 2527 insertions(+), 88 deletions(-) delete mode 100644 packages/core/mocks/fixtures/configs/code-pushup.config.js delete mode 100644 packages/core/mocks/fixtures/configs/code-pushup.config.mjs create mode 100644 testing/test-fixtures/README.md create mode 100644 testing/test-fixtures/eslint.config.js create mode 100644 testing/test-fixtures/package.json create mode 100644 testing/test-fixtures/project.json create mode 100644 testing/test-fixtures/src/index.ts rename {packages/cli/mocks => testing/test-fixtures/src/lib}/fixtures/configs/code-pushup.config.ts (100%) rename {packages/cli/mocks => testing/test-fixtures/src/lib}/fixtures/configs/code-pushup.empty.config.js (100%) rename {packages/cli/mocks => testing/test-fixtures/src/lib}/fixtures/configs/code-pushup.invalid.config.ts (100%) rename {packages/cli/mocks => testing/test-fixtures/src/lib}/fixtures/configs/code-pushup.needs-tsconfig.config.ts (100%) rename {packages/cli/mocks => testing/test-fixtures/src/lib}/fixtures/configs/custom-plugin.ts (100%) rename {packages/cli/mocks => testing/test-fixtures/src/lib}/fixtures/configs/tsconfig.json (100%) create mode 100644 testing/test-fixtures/src/lib/utils/commit.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/core-config.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/dynamic-mocks/categories.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/dynamic-mocks/config.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/dynamic-mocks/eslint-audits.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/dynamic-mocks/eslint-plugin.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/dynamic-mocks/lighthouse-audits.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/dynamic-mocks/lighthouse-plugin.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/dynamic-mocks/persist-config.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/dynamic-mocks/plugin-config.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/dynamic-mocks/report-diff.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/dynamic-mocks/report.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/dynamic-mocks/runner-config.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/dynamic-mocks/upload-config.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/minimal-config.mock.ts create mode 100644 testing/test-fixtures/src/lib/utils/omit-report-data.ts create mode 100644 testing/test-fixtures/src/lib/utils/os-agnostic.ts create mode 100644 testing/test-fixtures/src/lib/utils/report.mock.ts create mode 100644 testing/test-fixtures/tsconfig.json create mode 100644 testing/test-fixtures/tsconfig.lib.json create mode 100644 testing/test-fixtures/tsconfig.test.json rename {packages/cli/mocks => testing/test-utils/src/lib}/fixtures/configs/code-pushup.config.js (100%) rename {packages/cli/mocks => testing/test-utils/src/lib}/fixtures/configs/code-pushup.config.mjs (100%) rename {packages/core/mocks => testing/test-utils/src/lib}/fixtures/configs/code-pushup.config.ts (100%) rename {packages/core/mocks => testing/test-utils/src/lib}/fixtures/configs/code-pushup.empty.config.js (100%) rename {packages/core/mocks => testing/test-utils/src/lib}/fixtures/configs/code-pushup.invalid.config.ts (100%) rename {packages/core/mocks => testing/test-utils/src/lib}/fixtures/configs/code-pushup.needs-tsconfig.config.ts (100%) rename {packages/core/mocks => testing/test-utils/src/lib}/fixtures/configs/custom-plugin.ts (100%) rename {packages/core/mocks => testing/test-utils/src/lib}/fixtures/configs/tsconfig.json (100%) diff --git a/packages/cli/src/lib/implementation/core-config.middleware.int.test.ts b/packages/cli/src/lib/implementation/core-config.middleware.int.test.ts index d20641364..464b1dfc2 100644 --- a/packages/cli/src/lib/implementation/core-config.middleware.int.test.ts +++ b/packages/cli/src/lib/implementation/core-config.middleware.int.test.ts @@ -8,7 +8,12 @@ const configDirPath = path.join( '..', '..', '..', - 'mocks', + '..', + '..', + 'testing', + 'test-utils', + 'src', + 'lib', 'fixtures', 'configs', ); diff --git a/packages/core/mocks/fixtures/configs/code-pushup.config.js b/packages/core/mocks/fixtures/configs/code-pushup.config.js deleted file mode 100644 index 9f1661d4d..000000000 --- a/packages/core/mocks/fixtures/configs/code-pushup.config.js +++ /dev/null @@ -1,43 +0,0 @@ -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', - }, - ], -}; diff --git a/packages/core/mocks/fixtures/configs/code-pushup.config.mjs b/packages/core/mocks/fixtures/configs/code-pushup.config.mjs deleted file mode 100644 index d7f531533..000000000 --- a/packages/core/mocks/fixtures/configs/code-pushup.config.mjs +++ /dev/null @@ -1,43 +0,0 @@ -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', - }, - ], -}; diff --git a/packages/core/src/lib/implementation/read-rc-file.int.test.ts b/packages/core/src/lib/implementation/read-rc-file.int.test.ts index 835e12551..dae34e77a 100644 --- a/packages/core/src/lib/implementation/read-rc-file.int.test.ts +++ b/packages/core/src/lib/implementation/read-rc-file.int.test.ts @@ -9,7 +9,12 @@ describe('readRcByPath', () => { '..', '..', '..', - 'mocks', + '..', + '..', + 'testing', + 'test-utils', + 'src', + 'lib', 'fixtures', 'configs', ); diff --git a/testing/test-fixtures/README.md b/testing/test-fixtures/README.md new file mode 100644 index 000000000..e17ac2a87 --- /dev/null +++ b/testing/test-fixtures/README.md @@ -0,0 +1,19 @@ +# test-utils + +This library contains testing utilities, such as helper functions or fixtures. +Any reusable mocks should live here. + +More on this subject as well as all the testing strategy principles can be found on the GitHub [wiki](https://github.com/code-pushup/cli/wiki/Testing-Strategy#testing-utilities). + +## Library utilities + +### Mock data + +Hardcoded mocks, often referring to a smaller configuration object, live in [`utils`](./src/lib/utils/). +Dynamic mocks (functions that accept objects), referring to a bigger example of a configuration and report object, live in [`dynamic-mocks`](./src/lib/utils/dynamic-mocks/). + +Please prefer using static mocks over dynamic ones for better readability. Dynamic mocks to be used with care when testing a snapshot after report generation or similar. + +### Fixtures + +Example configuration files that are to be used in integration or E2E tests live in [`configs`](./src//lib/fixtures/configs/). diff --git a/testing/test-fixtures/eslint.config.js b/testing/test-fixtures/eslint.config.js new file mode 100644 index 000000000..2656b27cb --- /dev/null +++ b/testing/test-fixtures/eslint.config.js @@ -0,0 +1,12 @@ +import tseslint from 'typescript-eslint'; +import baseConfig from '../../eslint.config.js'; + +export default tseslint.config(...baseConfig, { + files: ['**/*.ts'], + languageOptions: { + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, +}); diff --git a/testing/test-fixtures/package.json b/testing/test-fixtures/package.json new file mode 100644 index 000000000..c77280f3f --- /dev/null +++ b/testing/test-fixtures/package.json @@ -0,0 +1,4 @@ +{ + "name": "@code-pushup/test-fixtures", + "type": "module" +} diff --git a/testing/test-fixtures/project.json b/testing/test-fixtures/project.json new file mode 100644 index 000000000..5e61f31bb --- /dev/null +++ b/testing/test-fixtures/project.json @@ -0,0 +1,14 @@ +{ + "name": "test-fixtures", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "testing/test-fixtures/src", + "projectType": "library", + "targets": { + "build": {}, + "lint": {}, + "nx-release-publish": { + "executor": "nx:noop" + } + }, + "tags": ["scope:shared", "type:testing"] +} diff --git a/testing/test-fixtures/src/index.ts b/testing/test-fixtures/src/index.ts new file mode 100644 index 000000000..8c9102eda --- /dev/null +++ b/testing/test-fixtures/src/index.ts @@ -0,0 +1,21 @@ +export * from './lib/utils/omit-report-data.js'; + +// static mocks +export * from './lib/utils/commit.mock.js'; +export * from './lib/utils/core-config.mock.js'; +export * from './lib/utils/minimal-config.mock.js'; +export * from './lib/utils/report.mock.js'; + +// dynamic mocks +export * from './lib/utils/dynamic-mocks/categories.mock.js'; +export * from './lib/utils/dynamic-mocks/config.mock.js'; +export * from './lib/utils/dynamic-mocks/eslint-audits.mock.js'; +export * from './lib/utils/dynamic-mocks/eslint-plugin.mock.js'; +export * from './lib/utils/dynamic-mocks/lighthouse-audits.mock.js'; +export * from './lib/utils/dynamic-mocks/lighthouse-plugin.mock.js'; +export * from './lib/utils/dynamic-mocks/persist-config.mock.js'; +export * from './lib/utils/dynamic-mocks/plugin-config.mock.js'; +export * from './lib/utils/dynamic-mocks/report-diff.mock.js'; +export * from './lib/utils/dynamic-mocks/report.mock.js'; +export * from './lib/utils/dynamic-mocks/runner-config.mock.js'; +export * from './lib/utils/dynamic-mocks/upload-config.mock.js'; diff --git a/packages/cli/mocks/fixtures/configs/code-pushup.config.ts b/testing/test-fixtures/src/lib/fixtures/configs/code-pushup.config.ts similarity index 100% rename from packages/cli/mocks/fixtures/configs/code-pushup.config.ts rename to testing/test-fixtures/src/lib/fixtures/configs/code-pushup.config.ts diff --git a/packages/cli/mocks/fixtures/configs/code-pushup.empty.config.js b/testing/test-fixtures/src/lib/fixtures/configs/code-pushup.empty.config.js similarity index 100% rename from packages/cli/mocks/fixtures/configs/code-pushup.empty.config.js rename to testing/test-fixtures/src/lib/fixtures/configs/code-pushup.empty.config.js diff --git a/packages/cli/mocks/fixtures/configs/code-pushup.invalid.config.ts b/testing/test-fixtures/src/lib/fixtures/configs/code-pushup.invalid.config.ts similarity index 100% rename from packages/cli/mocks/fixtures/configs/code-pushup.invalid.config.ts rename to testing/test-fixtures/src/lib/fixtures/configs/code-pushup.invalid.config.ts diff --git a/packages/cli/mocks/fixtures/configs/code-pushup.needs-tsconfig.config.ts b/testing/test-fixtures/src/lib/fixtures/configs/code-pushup.needs-tsconfig.config.ts similarity index 100% rename from packages/cli/mocks/fixtures/configs/code-pushup.needs-tsconfig.config.ts rename to testing/test-fixtures/src/lib/fixtures/configs/code-pushup.needs-tsconfig.config.ts diff --git a/packages/cli/mocks/fixtures/configs/custom-plugin.ts b/testing/test-fixtures/src/lib/fixtures/configs/custom-plugin.ts similarity index 100% rename from packages/cli/mocks/fixtures/configs/custom-plugin.ts rename to testing/test-fixtures/src/lib/fixtures/configs/custom-plugin.ts diff --git a/packages/cli/mocks/fixtures/configs/tsconfig.json b/testing/test-fixtures/src/lib/fixtures/configs/tsconfig.json similarity index 100% rename from packages/cli/mocks/fixtures/configs/tsconfig.json rename to testing/test-fixtures/src/lib/fixtures/configs/tsconfig.json diff --git a/testing/test-fixtures/src/lib/utils/commit.mock.ts b/testing/test-fixtures/src/lib/utils/commit.mock.ts new file mode 100644 index 000000000..228a09960 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/commit.mock.ts @@ -0,0 +1,15 @@ +import type { Commit } from '@code-pushup/models'; + +export const COMMIT_MOCK: Commit = { + hash: 'abcdef0123456789abcdef0123456789abcdef01', + message: 'Minor fixes', + author: 'John Doe', + date: new Date('2023-08-16T08:30:00.000Z'), +}; + +export const COMMIT_ALT_MOCK: Commit = { + hash: '0123456789abcdef0123456789abcdef01234567', + message: 'Major fixes', + author: 'Jane Doe', + date: new Date('2023-08-16T10:00:00.000Z'), +}; diff --git a/testing/test-fixtures/src/lib/utils/core-config.mock.ts b/testing/test-fixtures/src/lib/utils/core-config.mock.ts new file mode 100644 index 000000000..193eaf06f --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/core-config.mock.ts @@ -0,0 +1,72 @@ +import { type CoreConfig } from '@code-pushup/models'; + +export const CORE_CONFIG_MOCK = { + upload: { + organization: 'code-pushup', + project: 'cli', + apiKey: 'dummy-api-key', + server: 'https://example.com/api', + }, + categories: [ + { + slug: 'bug-prevention', + title: 'Bug prevention', + refs: [ + { + type: 'audit', + plugin: 'vitest', + slug: 'vitest-unit-tests', + weight: 1, + }, + { + type: 'audit', + plugin: 'cypress', + slug: 'cypress-e2e-tests', + weight: 1, + }, + ], + }, + ], + plugins: [ + { + slug: 'vitest', + title: 'Vitest results', + icon: 'vitest', + description: 'Vitest test results analysis', + docsUrl: 'https://vitest.dev/', + audits: [ + { + slug: 'vitest-unit-tests', + title: 'Vitest unit tests', + description: 'Vitest unit tests results analysis', + docsUrl: 'https://vitest.dev/', + }, + ], + runner: { + command: 'npx', + args: ['nx run cli:unit-test'], + outputFile: 'cli-unit-tests.json', + }, + }, + { + slug: 'cypress', + title: 'Cypress results', + icon: 'cypress', + description: 'Cypress test results analysis', + docsUrl: 'https://Cypress.dev/', + audits: [ + { + slug: 'cypress-e2e-tests', + title: 'Cypress e2e tests', + description: 'Cypress e2e tests results analysis', + docsUrl: 'https://docs.cypress.io/', + }, + ], + runner: { + command: 'npx', + args: ['cypress run'], + outputFile: 'ui-e2e-tests.json', + }, + }, + ], +} satisfies CoreConfig; diff --git a/testing/test-fixtures/src/lib/utils/dynamic-mocks/categories.mock.ts b/testing/test-fixtures/src/lib/utils/dynamic-mocks/categories.mock.ts new file mode 100644 index 000000000..e35b9ee47 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/dynamic-mocks/categories.mock.ts @@ -0,0 +1,81 @@ +import type { CategoryConfig } from '@code-pushup/models'; +import { eslintAuditRefMock } from './eslint-plugin.mock.js'; + +export const CATEGORIES_MAP = { + performance: { + slug: 'performance', + title: 'Performance', + description: 'Performance metrics', + docsUrl: 'https://developers.google.com/web/fundamentals/performance', + refs: [ + { + type: 'group', + plugin: 'eslint', + slug: 'max-line-limitation', + weight: 0, + }, + { + type: 'group', + plugin: 'lighthouse', + slug: 'performance', + weight: 1, + }, + eslintAuditRefMock('react-jsx-key', 0), + ], + }, + 'bug-prevention': { + slug: 'bug-prevention', + title: 'Bug prevention', + refs: [ + eslintAuditRefMock('no-cond-assign'), + eslintAuditRefMock('no-const-assign'), + eslintAuditRefMock('no-debugger'), + eslintAuditRefMock('no-invalid-regexp'), + eslintAuditRefMock('no-undef'), + eslintAuditRefMock('no-unreachable-loop'), + eslintAuditRefMock('no-unsafe-negation'), + eslintAuditRefMock('no-unsafe-optional-chaining'), + eslintAuditRefMock('use-isnan'), + eslintAuditRefMock('valid-typeof'), + eslintAuditRefMock('eqeqeq'), + eslintAuditRefMock('react-jsx-key', 2), + eslintAuditRefMock('react-prop-types'), + eslintAuditRefMock('react-react-in-jsx-scope'), + eslintAuditRefMock('react-hooks-rules-of-hooks', 2), + eslintAuditRefMock('react-hooks-exhaustive-deps', 2), + ], + }, + 'code-style': { + slug: 'code-style', + title: 'Code style', + refs: [ + eslintAuditRefMock('no-unused-vars'), + eslintAuditRefMock('arrow-body-style'), + eslintAuditRefMock('camelcase'), + eslintAuditRefMock('curly'), + eslintAuditRefMock('eqeqeq'), + eslintAuditRefMock('max-lines-per-function'), + eslintAuditRefMock('max-lines'), + eslintAuditRefMock('object-shorthand'), + eslintAuditRefMock('prefer-arrow-callback'), + eslintAuditRefMock('prefer-const'), + eslintAuditRefMock('prefer-object-spread'), + eslintAuditRefMock('yoda'), + eslintAuditRefMock('no-var'), + ], + }, +} satisfies Record; + +export type CategorySlug = keyof typeof CATEGORIES_MAP; + +export const CATEGORY_SLUGS = Object.keys(CATEGORIES_MAP) as CategorySlug[]; + +export function categoryConfigMock( + slug: CategorySlug = 'performance', +): CategoryConfig { + return CATEGORIES_MAP[slug]; +} + +export function categoryConfigsMock(): CategoryConfig[] { + return Object.values(JSON.parse(JSON.stringify(CATEGORIES_MAP))); +} diff --git a/testing/test-fixtures/src/lib/utils/dynamic-mocks/config.mock.ts b/testing/test-fixtures/src/lib/utils/dynamic-mocks/config.mock.ts new file mode 100644 index 000000000..ee6ea0e06 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/dynamic-mocks/config.mock.ts @@ -0,0 +1,68 @@ +import { + type CoreConfig, + coreConfigSchema, + validate, +} from '@code-pushup/models'; +import { categoryConfigsMock } from './categories.mock.js'; +import { eslintPluginConfigMock } from './eslint-plugin.mock.js'; +import { lighthousePluginConfigMock } from './lighthouse-plugin.mock.js'; +import { persistConfigMock } from './persist-config.mock.js'; +import { auditReportMock, pluginConfigMock } from './plugin-config.mock.js'; + +export function configMock(outputDir = 'tmp'): CoreConfig { + return validate(coreConfigSchema, { + persist: persistConfigMock({ outputDir }), + upload: { + organization: 'code-pushup', + project: 'cli', + apiKey: 'dummy-api-key', + server: 'https://example.com/api', + }, + categories: categoryConfigsMock(), + plugins: [ + eslintPluginConfigMock(outputDir), + lighthousePluginConfigMock(outputDir), + ], + }); +} + +export function minimalConfigMock( + outputDir = 'tmp', +): Omit & Required> { + const PLUGIN_1_SLUG = 'plugin-1'; + const AUDIT_1_SLUG = 'audit-1'; + const outputFile = `${PLUGIN_1_SLUG}.${Date.now()}.json`; + + const cfg = validate(coreConfigSchema, { + persist: persistConfigMock({ outputDir }), + upload: { + organization: 'code-pushup', + project: 'cli', + apiKey: 'dummy-api-key', + server: 'https://example.com/api', + }, + categories: [ + { + slug: 'category-1', + title: 'Category 1', + refs: [ + { + type: 'audit', + plugin: PLUGIN_1_SLUG, + slug: AUDIT_1_SLUG, + weight: 1, + }, + ], + }, + ], + plugins: [ + pluginConfigMock([auditReportMock({ slug: AUDIT_1_SLUG })], { + slug: PLUGIN_1_SLUG, + outputDir, + outputFile, + }), + ], + }); + + return JSON.parse(JSON.stringify(cfg)); +} diff --git a/testing/test-fixtures/src/lib/utils/dynamic-mocks/eslint-audits.mock.ts b/testing/test-fixtures/src/lib/utils/dynamic-mocks/eslint-audits.mock.ts new file mode 100644 index 000000000..e6adbf507 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/dynamic-mocks/eslint-audits.mock.ts @@ -0,0 +1,820 @@ +import type { AuditReport } from '@code-pushup/models'; + +export const ESLINT_AUDITS_FIXED_SLUGS: (keyof typeof ESLINT_AUDITS_MAP)[] = [ + 'no-unused-vars', + 'arrow-body-style', + 'eqeqeq', + 'max-lines-per-function', + 'no-shadow', + 'object-shorthand', + 'prefer-const', + 'react-jsx-key', + 'react-hooks-exhaustive-deps', +]; + +export const ESLINT_AUDITS_MAP = { + 'no-cond-assign': { + slug: 'no-cond-assign', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow assignment operators in conditional expressions', + description: 'ESLint rule **no-cond-assign**.', + docsUrl: 'https://eslint.org/docs/latest/rules/no-cond-assign', + }, + 'no-const-assign': { + slug: 'no-const-assign', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow reassigning `const` variables', + description: 'ESLint rule **no-const-assign**.', + docsUrl: 'https://eslint.org/docs/latest/rules/no-const-assign', + }, + 'no-debugger': { + slug: 'no-debugger', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow the use of `debugger`', + description: 'ESLint rule **no-debugger**.', + docsUrl: 'https://eslint.org/docs/latest/rules/no-debugger', + }, + 'no-invalid-regexp': { + slug: 'no-invalid-regexp', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: + 'Disallow invalid regular expression strings in `RegExp` constructors', + description: 'ESLint rule **no-invalid-regexp**.', + docsUrl: 'https://eslint.org/docs/latest/rules/no-invalid-regexp', + }, + 'no-undef': { + slug: 'no-undef', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: + 'Disallow the use of undeclared variables unless mentioned in `/*global */` comments', + description: 'ESLint rule **no-undef**.', + docsUrl: 'https://eslint.org/docs/latest/rules/no-undef', + }, + 'no-unreachable-loop': { + slug: 'no-unreachable-loop', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow loops with a body that allows only one iteration', + description: 'ESLint rule **no-unreachable-loop**.', + docsUrl: 'https://eslint.org/docs/latest/rules/no-unreachable-loop', + }, + 'no-unsafe-negation': { + slug: 'no-unsafe-negation', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow negating the left operand of relational operators', + description: 'ESLint rule **no-unsafe-negation**.', + docsUrl: 'https://eslint.org/docs/latest/rules/no-unsafe-negation', + }, + 'no-unsafe-optional-chaining': { + slug: 'no-unsafe-optional-chaining', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: + 'Disallow use of optional chaining in contexts where the `undefined` value is not allowed', + description: 'ESLint rule **no-unsafe-optional-chaining**.', + docsUrl: 'https://eslint.org/docs/latest/rules/no-unsafe-optional-chaining', + }, + 'no-unused-vars': { + slug: 'no-unused-vars', + displayValue: '1 warning', + value: 1, + score: 0, + details: { + issues: [ + { + message: "'loading' is assigned a value but never used.", + severity: 'warning', + source: { + file: 'src/App.jsx', + position: { + startLine: 8, + startColumn: 11, + endLine: 8, + endColumn: 18, + }, + }, + }, + ], + }, + title: 'Disallow unused variables', + description: 'ESLint rule **no-unused-vars**.', + docsUrl: 'https://eslint.org/docs/latest/rules/no-unused-vars', + }, + 'use-isnan': { + slug: 'use-isnan', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Require calls to `isNaN()` when checking for `NaN`', + description: 'ESLint rule **use-isnan**.', + docsUrl: 'https://eslint.org/docs/latest/rules/use-isnan', + }, + 'valid-typeof': { + slug: 'valid-typeof', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Enforce comparing `typeof` expressions against valid strings', + description: 'ESLint rule **valid-typeof**.', + docsUrl: 'https://eslint.org/docs/latest/rules/valid-typeof', + }, + 'arrow-body-style': { + slug: 'arrow-body-style', + displayValue: '1 warning', + value: 1, + score: 0, + details: { + issues: [ + { + message: + 'Unexpected block statement surrounding arrow body; move the returned value immediately after the `=>`.', + severity: 'warning', + source: { + file: 'src/components/TodoFilter.jsx', + position: { + startLine: 3, + startColumn: 29, + endLine: 25, + endColumn: 2, + }, + }, + }, + ], + }, + title: 'Require braces around arrow function bodies', + description: 'ESLint rule **arrow-body-style**.', + docsUrl: 'https://eslint.org/docs/latest/rules/arrow-body-style', + }, + camelcase: { + slug: 'camelcase', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Enforce camelcase naming convention', + description: 'ESLint rule **camelcase**.', + docsUrl: 'https://eslint.org/docs/latest/rules/camelcase', + }, + curly: { + slug: 'curly', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Enforce consistent brace style for all control statements', + description: 'ESLint rule **curly**.', + docsUrl: 'https://eslint.org/docs/latest/rules/curly', + }, + eqeqeq: { + slug: 'eqeqeq', + displayValue: '1 warning', + value: 1, + score: 0, + details: { + issues: [ + { + message: "Expected '===' and instead saw '=='.", + severity: 'warning', + source: { + file: 'src/hooks/useTodos.js', + position: { + startLine: 41, + startColumn: 41, + endLine: 41, + endColumn: 43, + }, + }, + }, + ], + }, + title: 'Require the use of `===` and `!==`', + description: 'ESLint rule **eqeqeq**.', + docsUrl: 'https://eslint.org/docs/latest/rules/eqeqeq', + }, + 'max-lines-per-function': { + slug: 'max-lines-per-function', + displayValue: '1 warning', + value: 1, + score: 0, + details: { + issues: [ + { + message: + 'Arrow function has too many lines (71). Maximum allowed is 50.', + severity: 'warning', + source: { + file: 'src/hooks/useTodos.js', + position: { + startLine: 3, + startColumn: 25, + endLine: 73, + endColumn: 2, + }, + }, + }, + ], + }, + title: 'Enforce a maximum number of lines of code in a function', + description: 'ESLint rule **max-lines-per-function**.', + docsUrl: 'https://eslint.org/docs/latest/rules/max-lines-per-function', + }, + 'max-lines': { + slug: 'max-lines', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Enforce a maximum number of lines per file', + description: 'ESLint rule **max-lines**.', + docsUrl: 'https://eslint.org/docs/latest/rules/max-lines', + }, + 'no-shadow': { + slug: 'no-shadow', + displayValue: '3 warnings', + value: 3, + score: 0, + details: { + issues: [ + { + message: + "'data' is already declared in the upper scope on line 5 column 10.", + severity: 'warning', + source: { + file: 'src/hooks/useTodos.js', + position: { + startLine: 11, + startColumn: 13, + endLine: 11, + endColumn: 17, + }, + }, + }, + { + message: + "'data' is already declared in the upper scope on line 5 column 10.", + severity: 'warning', + source: { + file: 'src/hooks/useTodos.js', + position: { + startLine: 29, + startColumn: 17, + endLine: 29, + endColumn: 21, + }, + }, + }, + { + message: + "'data' is already declared in the upper scope on line 5 column 10.", + severity: 'warning', + source: { + file: 'src/hooks/useTodos.js', + position: { + startLine: 41, + startColumn: 13, + endLine: 41, + endColumn: 17, + }, + }, + }, + ], + }, + title: + 'Disallow variable declarations from shadowing variables declared in the outer scope', + description: 'ESLint rule **no-shadow**.', + docsUrl: 'https://eslint.org/docs/latest/rules/no-shadow', + }, + 'no-var': { + slug: 'no-var', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Require `let` or `const` instead of `var`', + description: 'ESLint rule **no-var**.', + docsUrl: 'https://eslint.org/docs/latest/rules/no-var', + }, + 'object-shorthand': { + slug: 'object-shorthand', + displayValue: '3 warnings', + value: 3, + score: 0, + details: { + issues: [ + { + message: 'Expected property shorthand.', + severity: 'warning', + source: { + file: 'src/hooks/useTodos.js', + position: { + startLine: 19, + startColumn: 7, + endLine: 19, + endColumn: 19, + }, + }, + }, + { + message: 'Expected property shorthand.', + severity: 'warning', + source: { + file: 'src/hooks/useTodos.js', + position: { + startLine: 32, + startColumn: 13, + endLine: 32, + endColumn: 19, + }, + }, + }, + { + message: 'Expected property shorthand.', + severity: 'warning', + source: { + file: 'src/hooks/useTodos.js', + position: { + startLine: 33, + startColumn: 13, + endLine: 33, + endColumn: 25, + }, + }, + }, + ], + }, + title: + 'Require or disallow method and property shorthand syntax for object literals', + description: 'ESLint rule **object-shorthand**.', + docsUrl: 'https://eslint.org/docs/latest/rules/object-shorthand', + }, + 'prefer-arrow-callback': { + slug: 'prefer-arrow-callback', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Require using arrow functions for callbacks', + description: 'ESLint rule **prefer-arrow-callback**.', + docsUrl: 'https://eslint.org/docs/latest/rules/prefer-arrow-callback', + }, + 'prefer-const': { + slug: 'prefer-const', + displayValue: '1 warning', + value: 1, + score: 0, + details: { + issues: [ + { + message: "'root' is never reassigned. Use 'const' instead.", + severity: 'warning', + source: { + file: 'src/index.jsx', + position: { + startLine: 5, + startColumn: 5, + endLine: 5, + endColumn: 9, + }, + }, + }, + ], + }, + title: + 'Require `const` declarations for variables that are never reassigned after declared', + description: 'ESLint rule **prefer-const**.', + docsUrl: 'https://eslint.org/docs/latest/rules/prefer-const', + }, + 'prefer-object-spread': { + slug: 'prefer-object-spread', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: + 'Disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead', + description: 'ESLint rule **prefer-object-spread**.', + docsUrl: 'https://eslint.org/docs/latest/rules/prefer-object-spread', + }, + yoda: { + slug: 'yoda', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Require or disallow "Yoda" conditions', + description: 'ESLint rule **yoda**.', + docsUrl: 'https://eslint.org/docs/latest/rules/yoda', + }, + 'react-jsx-key': { + slug: 'react-jsx-key', + displayValue: '1 warning', + value: 1, + score: 0, + details: { + issues: [ + { + message: 'Missing "key" prop for element in iterator', + severity: 'warning', + source: { + file: 'src/components/TodoList.jsx', + position: { + startLine: 7, + startColumn: 7, + endLine: 28, + endColumn: 12, + }, + }, + }, + ], + }, + title: 'Disallow missing `key` props in iterators/collection literals', + description: 'ESLint rule **jsx-key**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-key.md', + }, + 'react-prop-types': { + slug: 'react-prop-types', + displayValue: '6 warnings', + value: 6, + score: 0, + details: { + issues: [ + { + message: "'onCreate' is missing in props validation", + severity: 'warning', + source: { + file: 'src/components/CreateTodo.jsx', + position: { + startLine: 15, + startColumn: 15, + endLine: 15, + endColumn: 23, + }, + }, + }, + { + message: "'setQuery' is missing in props validation", + severity: 'warning', + source: { + file: 'src/components/TodoFilter.jsx', + position: { + startLine: 10, + startColumn: 17, + endLine: 10, + endColumn: 25, + }, + }, + }, + { + message: "'setHideComplete' is missing in props validation", + severity: 'warning', + source: { + file: 'src/components/TodoFilter.jsx', + position: { + startLine: 18, + startColumn: 19, + endLine: 18, + endColumn: 34, + }, + }, + }, + { + message: "'todos' is missing in props validation", + severity: 'warning', + source: { + file: 'src/components/TodoList.jsx', + position: { + startLine: 6, + startColumn: 12, + endLine: 6, + endColumn: 17, + }, + }, + }, + { + message: "'todos.map' is missing in props validation", + severity: 'warning', + source: { + file: 'src/components/TodoList.jsx', + position: { + startLine: 6, + startColumn: 18, + endLine: 6, + endColumn: 21, + }, + }, + }, + { + message: "'onEdit' is missing in props validation", + severity: 'warning', + source: { + file: 'src/components/TodoList.jsx', + position: { + startLine: 13, + startColumn: 21, + endLine: 13, + endColumn: 27, + }, + }, + }, + ], + }, + title: 'Disallow missing props validation in a React component definition', + description: 'ESLint rule **prop-types**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/prop-types.md', + }, + 'react-react-in-jsx-scope': { + slug: 'react-react-in-jsx-scope', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow missing React when using JSX', + description: 'ESLint rule **react-in-jsx-scope**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/react-in-jsx-scope.md', + }, + 'react-hooks-rules-of-hooks': { + slug: 'react-hooks-rules-of-hooks', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'enforces the Rules of Hooks', + description: 'ESLint rule **rules-of-hooks**, from _react-hooks_ plugin.', + docsUrl: 'https://reactjs.org/docs/hooks-rules.html', + }, + 'react-hooks-exhaustive-deps': { + slug: 'react-hooks-exhaustive-deps', + displayValue: '2 warnings', + value: 2, + score: 0, + details: { + issues: [ + { + message: + 'React Hook useCallback does nothing when called with only one argument. Did you forget to pass an array of dependencies?', + severity: 'warning', + source: { + file: 'src/hooks/useTodos.js', + position: { + startLine: 17, + startColumn: 20, + endLine: 17, + endColumn: 31, + }, + }, + }, + { + message: + 'React Hook useCallback does nothing when called with only one argument. Did you forget to pass an array of dependencies?', + severity: 'warning', + source: { + file: 'src/hooks/useTodos.js', + position: { + startLine: 40, + startColumn: 18, + endLine: 40, + endColumn: 29, + }, + }, + }, + ], + }, + title: + 'verifies the list of dependencies for Hooks like useEffect and similar', + description: 'ESLint rule **exhaustive-deps**, from _react-hooks_ plugin.', + docsUrl: 'https://github.com/facebook/react/issues/14920', + }, + 'react-display-name': { + slug: 'react-display-name', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow missing displayName in a React component definition', + description: 'ESLint rule **display-name**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/display-name.md', + }, + 'react-jsx-no-comment-textnodes': { + slug: 'react-jsx-no-comment-textnodes', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow comments from being inserted as text nodes', + description: + 'ESLint rule **jsx-no-comment-textnodes**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-no-comment-textnodes.md', + }, + 'react-jsx-no-duplicate-props': { + slug: 'react-jsx-no-duplicate-props', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow duplicate properties in JSX', + description: 'ESLint rule **jsx-no-duplicate-props**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-no-duplicate-props.md', + }, + 'react-jsx-no-target-blank': { + slug: 'react-jsx-no-target-blank', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow `target="_blank"` attribute without `rel="noreferrer"`', + description: 'ESLint rule **jsx-no-target-blank**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-no-target-blank.md', + }, + 'react-jsx-no-undef': { + slug: 'react-jsx-no-undef', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow undeclared variables in JSX', + description: 'ESLint rule **jsx-no-undef**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-no-undef.md', + }, + 'react-jsx-uses-react': { + slug: 'react-jsx-uses-react', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow React to be incorrectly marked as unused', + description: 'ESLint rule **jsx-uses-react**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-uses-react.md', + }, + 'react-jsx-uses-vars': { + slug: 'react-jsx-uses-vars', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow variables used in JSX to be incorrectly marked as unused', + description: 'ESLint rule **jsx-uses-vars**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-uses-vars.md', + }, + 'react-no-children-prop': { + slug: 'react-no-children-prop', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow passing of children as props', + description: 'ESLint rule **no-children-prop**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-children-prop.md', + }, + 'react-no-danger-with-children': { + slug: 'react-no-danger-with-children', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: + 'Disallow when a DOM element is using both children and dangerouslySetInnerHTML', + description: + 'ESLint rule **no-danger-with-children**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-danger-with-children.md', + }, + 'react-no-deprecated': { + slug: 'react-no-deprecated', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow usage of deprecated methods', + description: 'ESLint rule **no-deprecated**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-deprecated.md', + }, + 'react-no-direct-mutation-state': { + slug: 'react-no-direct-mutation-state', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow direct mutation of this.state', + description: + 'ESLint rule **no-direct-mutation-state**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-direct-mutation-state.md', + }, + 'react-no-find-dom-node': { + slug: 'react-no-find-dom-node', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow usage of findDOMNode', + description: 'ESLint rule **no-find-dom-node**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-find-dom-node.md', + }, + 'react-no-is-mounted': { + slug: 'react-no-is-mounted', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow usage of isMounted', + description: 'ESLint rule **no-is-mounted**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-is-mounted.md', + }, + 'react-no-render-return-value': { + slug: 'react-no-render-return-value', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow usage of the return value of ReactDOM.render', + description: 'ESLint rule **no-render-return-value**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-render-return-value.md', + }, + 'react-no-string-refs': { + slug: 'react-no-string-refs', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow using string references', + description: 'ESLint rule **no-string-refs**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-string-refs.md', + }, + 'react-no-unescaped-entities': { + slug: 'react-no-unescaped-entities', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow unescaped HTML entities from appearing in markup', + description: 'ESLint rule **no-unescaped-entities**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-unescaped-entities.md', + }, + 'react-no-unknown-property': { + slug: 'react-no-unknown-property', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Disallow usage of unknown DOM property', + description: 'ESLint rule **no-unknown-property**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-unknown-property.md', + }, + 'react-require-render-return': { + slug: 'react-require-render-return', + displayValue: 'passed', + value: 0, + score: 1, + details: { issues: [] }, + title: 'Enforce ES5 or ES6 class for returning value in render function', + description: 'ESLint rule **require-render-return**, from _react_ plugin.', + docsUrl: + 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/require-render-return.md', + }, +} satisfies Record; + +export const ESLINT_AUDIT_SLUGS = Object.keys( + ESLINT_AUDITS_MAP, +) as (keyof typeof ESLINT_AUDITS_MAP)[]; diff --git a/testing/test-fixtures/src/lib/utils/dynamic-mocks/eslint-plugin.mock.ts b/testing/test-fixtures/src/lib/utils/dynamic-mocks/eslint-plugin.mock.ts new file mode 100644 index 000000000..672f32fec --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/dynamic-mocks/eslint-plugin.mock.ts @@ -0,0 +1,103 @@ +import path from 'node:path'; +import type { + Audit, + AuditReport, + CategoryRef, + Group, + PluginConfig, + PluginReport, +} from '@code-pushup/models'; +import { + ESLINT_AUDITS_FIXED_SLUGS, + ESLINT_AUDITS_MAP, + ESLINT_AUDIT_SLUGS, +} from './eslint-audits.mock.js'; +import { echoRunnerConfigMock } from './runner-config.mock.js'; + +export const ESLINT_PLUGIN_GROUP_MAX_LINES: Group = { + slug: 'max-line-limitation', + title: 'Maximum lines limitation', + refs: [ + { + slug: ESLINT_AUDITS_MAP['max-lines-per-function'].slug, + weight: 1, + }, + { + slug: ESLINT_AUDITS_MAP['max-lines'].slug, + weight: 1, + }, + ], +}; + +export const ESLINT_PLUGIN_META = { + slug: 'eslint', + title: 'ESLint', + icon: 'eslint', + description: 'Official Code PushUp ESLint plugin', + docsUrl: 'https://www.npmjs.com/package/@code-pushup/eslint-plugin', + packageName: '@code-pushup/eslint-plugin', + version: '0.1.0', +} satisfies Partial; + +export function eslintPluginConfigMock(outputDir = 'tmp'): PluginConfig { + const audits = Object.values(ESLINT_AUDITS_MAP).map( + ({ slug, description, title, docsUrl }) => + ({ + slug, + description, + title, + docsUrl, + }) satisfies Audit, + ); + return { + ...ESLINT_PLUGIN_META, + runner: echoRunnerConfigMock( + Object.values(ESLINT_AUDITS_MAP), + path.join(outputDir, 'eslint-out.json'), + ), + audits, + }; +} + +export function eslintPluginReportMock(): PluginReport { + return { + ...ESLINT_PLUGIN_META, + date: '2023-10-18T07:49:45.531Z', + duration: 368, + audits: Object.values(ESLINT_AUDITS_MAP), + groups: [ESLINT_PLUGIN_GROUP_MAX_LINES], + }; +} +export function eslintPluginReportAltMock(): PluginReport { + return { + ...eslintPluginReportMock(), + date: '2024-03-12T12:42:05.388Z', + duration: 316, + audits: ESLINT_AUDIT_SLUGS.map( + (slug): AuditReport => + ESLINT_AUDITS_FIXED_SLUGS.includes(slug) + ? { + ...ESLINT_AUDITS_MAP[slug], + score: 1, + value: 0, + displayValue: 'passed', + details: { issues: [] }, + } + : ESLINT_AUDITS_MAP[slug], + ), + }; +} + +export type ESLintAuditSlug = keyof typeof ESLINT_AUDITS_MAP; + +export function eslintAuditRefMock( + slug: ESLintAuditSlug, + weight = 1, +): CategoryRef { + return { + type: 'audit', + plugin: 'eslint', + slug, + weight, + }; +} diff --git a/testing/test-fixtures/src/lib/utils/dynamic-mocks/lighthouse-audits.mock.ts b/testing/test-fixtures/src/lib/utils/dynamic-mocks/lighthouse-audits.mock.ts new file mode 100644 index 000000000..2fe262e51 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/dynamic-mocks/lighthouse-audits.mock.ts @@ -0,0 +1,95 @@ +import type { AuditReport } from '@code-pushup/models'; + +export const LIGHTHOUSE_AUDITS_CHANGES: Partial< + Record< + keyof typeof LIGHTHOUSE_AUDITS_MAP, + Pick + > +> = { + 'largest-contentful-paint': { + score: 0.85, + value: 1369, + displayValue: '1.4 s', + }, + 'first-contentful-paint': { + score: 0.79, + value: 1146, + displayValue: '1.1 s', + }, + 'speed-index': { + score: 0.94, + value: 1146, + displayValue: '1.1 s', + }, +}; + +export const LIGHTHOUSE_AUDITS_MAP = { + 'first-contentful-paint': { + slug: 'first-contentful-paint', + title: 'First Contentful Paint', + description: + 'First Contentful Paint marks the time at which the first text or image is painted.', + docsUrl: + 'https://developer.chrome.com/docs/lighthouse/performance/first-contentful-paint/', + score: 0.76, + value: 1189, + displayValue: '1.2 s', + }, + 'largest-contentful-paint': { + slug: 'largest-contentful-paint', + title: 'Largest Contentful Paint', + description: + 'Largest Contentful Paint marks the time at which the largest text or image is painted.', + docsUrl: + 'https://developer.chrome.com/docs/lighthouse/performance/largest-contentful-paint/', + score: 0.81, + value: 1491, + displayValue: '1.5 s', + }, + 'total-blocking-time': { + slug: 'total-blocking-time', + title: 'Total Blocking Time', + description: + 'Sum of all time periods between FCP and Time to Interactive, when task length exceeded 50ms, expressed in milliseconds.', + docsUrl: + 'https://developer.chrome.com/docs/lighthouse/performance/lighthouse-total-blocking-time/', + score: 1, + value: 0, + displayValue: '0 ms', + }, + 'cumulative-layout-shift': { + slug: 'cumulative-layout-shift', + title: 'Cumulative Layout Shift', + description: + 'Cumulative Layout Shift measures the movement of visible elements within the viewport.', + docsUrl: 'https://web.dev/cls/', + score: 1, + value: 0, + displayValue: '0', + }, + 'speed-index': { + slug: 'speed-index', + title: 'Speed Index', + description: + 'Speed Index shows how quickly the contents of a page are visibly populated.', + docsUrl: + 'https://developer.chrome.com/docs/lighthouse/performance/speed-index/', + score: 0.93, + value: 1189, + displayValue: '1.2 s', + }, + 'third-party-summary': { + slug: 'third-party-summary', + title: 'Minimize third-party usage', + description: + 'Third-party code can significantly impact load performance. Limit the number of redundant third-party providers and try to load third-party code after your page has primarily finished loading. [Learn how to minimize third-party impact](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/).', + docsUrl: undefined, + displayValue: 'Third-party code blocked the main thread for 6,850 ms', + value: 0, + score: 0, + }, +} satisfies Record; + +export const LIGHTHOUSE_AUDIT_SLUGS = Object.keys( + LIGHTHOUSE_AUDITS_MAP, +) as (keyof typeof LIGHTHOUSE_AUDITS_MAP)[]; diff --git a/testing/test-fixtures/src/lib/utils/dynamic-mocks/lighthouse-plugin.mock.ts b/testing/test-fixtures/src/lib/utils/dynamic-mocks/lighthouse-plugin.mock.ts new file mode 100644 index 000000000..ea3b43edd --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/dynamic-mocks/lighthouse-plugin.mock.ts @@ -0,0 +1,96 @@ +import path from 'node:path'; +import type { + Audit, + AuditReport, + Group, + PluginConfig, + PluginReport, +} from '@code-pushup/models'; +import { + LIGHTHOUSE_AUDITS_CHANGES, + LIGHTHOUSE_AUDITS_MAP, + LIGHTHOUSE_AUDIT_SLUGS, +} from './lighthouse-audits.mock.js'; +import { echoRunnerConfigMock } from './runner-config.mock.js'; + +export const LH_PLUGIN_GROUP_PERFORMANCE: Group = { + slug: 'performance', + title: 'Performance', + refs: [ + { + slug: 'first-contentful-paint', + weight: 10, + }, + { + slug: 'largest-contentful-paint', + weight: 25, + }, + { + slug: 'speed-index', + weight: 10, + }, + { + slug: 'total-blocking-time', + weight: 30, + }, + { + slug: 'cumulative-layout-shift', + weight: 25, + }, + ], +}; + +export const LH_PLUGIN_META: Omit = { + slug: 'lighthouse', + title: 'Lighthouse', + icon: 'lighthouse', + packageName: '@code-pushup/lighthouse-plugin', + version: '0.1.0', +}; + +export function lighthousePluginConfigMock(outputDir = 'tmp'): PluginConfig { + const audits = Object.values(LIGHTHOUSE_AUDITS_MAP).map( + ({ slug, description, title, docsUrl }): Audit => ({ + slug, + description, + title, + docsUrl, + }), + ); + return { + ...LH_PLUGIN_META, + runner: echoRunnerConfigMock( + Object.values(LIGHTHOUSE_AUDITS_MAP), + path.join(outputDir, 'lighthouse-out.json'), + ), + audits, + groups: [LH_PLUGIN_GROUP_PERFORMANCE], + }; +} + +export function lighthousePluginReportMock(): PluginReport { + return { + ...LH_PLUGIN_META, + date: '2023-10-18T07:49:45.899Z', + duration: 1234, + audits: Object.values(LIGHTHOUSE_AUDITS_MAP), + groups: [LH_PLUGIN_GROUP_PERFORMANCE], + }; +} + +export function lighthousePluginReportAltMock(): PluginReport { + return { + ...lighthousePluginReportMock(), + date: '2024-03-12T12:42:05.704Z', + duration: 1212, + audits: LIGHTHOUSE_AUDIT_SLUGS.map( + (slug): AuditReport => + slug in LIGHTHOUSE_AUDITS_CHANGES + ? { + ...LIGHTHOUSE_AUDITS_MAP[slug], + ...LIGHTHOUSE_AUDITS_CHANGES[slug], + } + : LIGHTHOUSE_AUDITS_MAP[slug], + ), + }; +} diff --git a/testing/test-fixtures/src/lib/utils/dynamic-mocks/persist-config.mock.ts b/testing/test-fixtures/src/lib/utils/dynamic-mocks/persist-config.mock.ts new file mode 100644 index 000000000..f4537d719 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/dynamic-mocks/persist-config.mock.ts @@ -0,0 +1,19 @@ +import { + DEFAULT_PERSIST_FILENAME, + DEFAULT_PERSIST_FORMAT, + DEFAULT_PERSIST_OUTPUT_DIR, + type PersistConfig, + persistConfigSchema, + validate, +} from '@code-pushup/models'; + +export function persistConfigMock( + opt?: Partial, +): Required { + return validate(persistConfigSchema, { + outputDir: DEFAULT_PERSIST_OUTPUT_DIR, + filename: DEFAULT_PERSIST_FILENAME, + format: DEFAULT_PERSIST_FORMAT, + ...opt, + }) as Required; +} diff --git a/testing/test-fixtures/src/lib/utils/dynamic-mocks/plugin-config.mock.ts b/testing/test-fixtures/src/lib/utils/dynamic-mocks/plugin-config.mock.ts new file mode 100644 index 000000000..0ff24a144 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/dynamic-mocks/plugin-config.mock.ts @@ -0,0 +1,57 @@ +import path from 'node:path'; +import { + type Audit, + type AuditReport, + type PluginConfig, + auditReportSchema, + auditSchema, + pluginConfigSchema, + validate, +} from '@code-pushup/models'; +import { echoRunnerConfigMock } from './runner-config.mock.js'; + +export function pluginConfigMock( + auditOutputs: AuditReport[], + opt?: Partial & { outputDir?: string; outputFile?: string }, +): PluginConfig { + const { outputDir, outputFile } = opt || {}; + const pluginOutputFile = path.join( + outputDir || 'tmp', + outputFile || `out.${Date.now()}.json`, + ); + return validate(pluginConfigSchema, { + slug: 'mock-plugin-slug', + title: 'Plugin Title', + icon: 'nrwl', + description: 'Plugin description', + docsUrl: 'https://my-plugin.docs.dev?1', + audits: auditOutputs.map(auditOutput => auditConfigMock(auditOutput)), + runner: echoRunnerConfigMock(auditOutputs, pluginOutputFile), + ...opt, + }); +} + +export function auditConfigMock(opt?: Partial): Audit { + return validate(auditSchema, { + slug: opt?.slug || 'mock-audit-slug', + title: opt?.title || 'Audit Title', + description: opt?.description || 'audit description', + docsUrl: opt?.docsUrl || 'http://www.my-docs.dev', + }) as Required; +} + +export function auditReportMock(opt?: Partial): AuditReport { + return validate(auditReportSchema, { + slug: 'mock-audit-slug', + title: 'Audit Title', + description: 'audit description', + docsUrl: 'http://www.my-docs.dev', + score: 0, + value: 0, + displayValue: '0x', + details: { + issues: [], + }, + ...opt, + }) as Required; +} diff --git a/testing/test-fixtures/src/lib/utils/dynamic-mocks/report-diff.mock.ts b/testing/test-fixtures/src/lib/utils/dynamic-mocks/report-diff.mock.ts new file mode 100644 index 000000000..9bd8fb100 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/dynamic-mocks/report-diff.mock.ts @@ -0,0 +1,434 @@ +import type { + AuditDiff, + AuditResult, + CategoryDiff, + ReportsDiff, +} from '@code-pushup/models'; +import { COMMIT_ALT_MOCK, COMMIT_MOCK } from '../commit.mock.js'; +import { + CATEGORIES_MAP, + CATEGORY_SLUGS, + type CategorySlug, +} from './categories.mock.js'; +import { + ESLINT_AUDITS_FIXED_SLUGS, + ESLINT_AUDITS_MAP, + ESLINT_AUDIT_SLUGS, +} from './eslint-audits.mock.js'; +import { + ESLINT_PLUGIN_GROUP_MAX_LINES, + ESLINT_PLUGIN_META, + type ESLintAuditSlug, +} from './eslint-plugin.mock.js'; +import { + LIGHTHOUSE_AUDITS_CHANGES, + LIGHTHOUSE_AUDITS_MAP, + LIGHTHOUSE_AUDIT_SLUGS, +} from './lighthouse-audits.mock.js'; +import { + LH_PLUGIN_GROUP_PERFORMANCE, + LH_PLUGIN_META, +} from './lighthouse-plugin.mock.js'; + +export function reportsDiffMock(): ReportsDiff { + return { + commits: { + before: COMMIT_MOCK, + after: COMMIT_ALT_MOCK, + }, + categories: { + changed: CATEGORY_SLUGS.map(slug => { + const category = CATEGORIES_MAP[slug]; + return { + slug, + title: category.title, + ...('docsUrl' in category && { + docsUrl: category.docsUrl, + }), + scores: categoryScores(slug), + }; + }), + unchanged: [], + added: [], + removed: [], + }, + groups: { + changed: [ + { + slug: ESLINT_PLUGIN_GROUP_MAX_LINES.slug, + title: ESLINT_PLUGIN_GROUP_MAX_LINES.title, + plugin: { + slug: ESLINT_PLUGIN_META.slug, + title: ESLINT_PLUGIN_META.title, + docsUrl: ESLINT_PLUGIN_META.docsUrl, + }, + scores: { before: 0.5, after: 1, diff: 0.5 }, + }, + { + slug: LH_PLUGIN_GROUP_PERFORMANCE.slug, + title: LH_PLUGIN_GROUP_PERFORMANCE.title, + plugin: { slug: LH_PLUGIN_META.slug, title: LH_PLUGIN_META.title }, + scores: { before: 0.92, after: 0.94, diff: 0.02 }, + }, + ], + unchanged: [], + added: [], + removed: [], + }, + audits: { + changed: [ + ...ESLINT_AUDITS_FIXED_SLUGS.map( + (slug): AuditDiff => ({ + slug, + title: ESLINT_AUDITS_MAP[slug].title, + docsUrl: ESLINT_AUDITS_MAP[slug].docsUrl, + plugin: { + slug: ESLINT_PLUGIN_META.slug, + title: ESLINT_PLUGIN_META.title, + docsUrl: ESLINT_PLUGIN_META.docsUrl, + }, + scores: toNumberComparison({ + before: ESLINT_AUDITS_MAP[slug].score, + after: 1, + }), + values: toNumberComparison({ + before: ESLINT_AUDITS_MAP[slug].value, + after: 0, + }), + displayValues: { + before: ESLINT_AUDITS_MAP[slug].displayValue, + after: 'passed', + }, + }), + ), + ...LIGHTHOUSE_AUDIT_SLUGS.filter( + slug => slug in LIGHTHOUSE_AUDITS_CHANGES, + ).map( + (slug): AuditDiff => ({ + slug, + title: LIGHTHOUSE_AUDITS_MAP[slug].title, + docsUrl: LIGHTHOUSE_AUDITS_MAP[slug].docsUrl, + plugin: { + slug: LH_PLUGIN_META.slug, + title: LH_PLUGIN_META.title, + }, + scores: toNumberComparison({ + before: LIGHTHOUSE_AUDITS_MAP[slug].score, + after: LIGHTHOUSE_AUDITS_CHANGES[slug]!.score, + }), + values: toNumberComparison({ + before: LIGHTHOUSE_AUDITS_MAP[slug].value, + after: LIGHTHOUSE_AUDITS_CHANGES[slug]!.value, + }), + displayValues: { + before: LIGHTHOUSE_AUDITS_MAP[slug].displayValue, + after: LIGHTHOUSE_AUDITS_CHANGES[slug]!.displayValue, + }, + }), + ), + ], + unchanged: [ + ...ESLINT_AUDIT_SLUGS.filter( + slug => !ESLINT_AUDITS_FIXED_SLUGS.includes(slug), + ).map( + (slug): AuditResult => ({ + slug, + title: ESLINT_AUDITS_MAP[slug].title, + docsUrl: ESLINT_AUDITS_MAP[slug].docsUrl, + plugin: { + slug: ESLINT_PLUGIN_META.slug, + title: ESLINT_PLUGIN_META.title, + docsUrl: ESLINT_PLUGIN_META.docsUrl, + }, + score: ESLINT_AUDITS_MAP[slug].score, + value: ESLINT_AUDITS_MAP[slug].value, + displayValue: ESLINT_AUDITS_MAP[slug].displayValue, + }), + ), + ...LIGHTHOUSE_AUDIT_SLUGS.filter( + slug => !(slug in LIGHTHOUSE_AUDITS_CHANGES), + ).map( + (slug): AuditResult => ({ + slug, + title: LIGHTHOUSE_AUDITS_MAP[slug].title, + docsUrl: LIGHTHOUSE_AUDITS_MAP[slug].docsUrl, + plugin: { slug: LH_PLUGIN_META.slug, title: LH_PLUGIN_META.title }, + score: LIGHTHOUSE_AUDITS_MAP[slug].score, + value: LIGHTHOUSE_AUDITS_MAP[slug].value, + displayValue: LIGHTHOUSE_AUDITS_MAP[slug].displayValue, + }), + ), + ], + added: [], + removed: [], + }, + date: '2024-03-12T17:15:34.831Z', + duration: 105, + packageName: '@code-pushup/core', + version: '1.0.0', + }; +} + +export function reportsDiffAltMock(): ReportsDiff { + const originalDiff = reportsDiffMock(); + return { + ...originalDiff, + categories: { + changed: [ + { + slug: 'performance' satisfies CategorySlug, + title: CATEGORIES_MAP['performance'].title, + scores: { before: 0.92, after: 0.94, diff: 0.02 }, + }, + { + slug: 'bug-prevention' satisfies CategorySlug, + title: CATEGORIES_MAP['bug-prevention'].title, + scores: { before: 0.68, after: 0.6795, diff: -0.0005 }, + }, + ], + unchanged: [ + { + slug: 'code-style' satisfies CategorySlug, + title: CATEGORIES_MAP['code-style'].title, + score: 0.54, + }, + ], + added: [], + removed: [], + }, + groups: { + changed: [ + { + slug: LH_PLUGIN_GROUP_PERFORMANCE.slug, + title: LH_PLUGIN_GROUP_PERFORMANCE.title, + plugin: { slug: LH_PLUGIN_META.slug, title: LH_PLUGIN_META.title }, + scores: { before: 0.92, after: 0.94, diff: 0.02 }, + }, + ], + unchanged: [ + { + slug: ESLINT_PLUGIN_GROUP_MAX_LINES.slug, + title: ESLINT_PLUGIN_GROUP_MAX_LINES.title, + plugin: { + slug: ESLINT_PLUGIN_META.slug, + title: ESLINT_PLUGIN_META.title, + }, + score: 0.5, + }, + ], + added: [], + removed: [], + }, + audits: { + changed: [ + { + slug: 'no-unused-vars' satisfies ESLintAuditSlug, + title: ESLINT_AUDITS_MAP['no-unused-vars'].title, + docsUrl: ESLINT_AUDITS_MAP['no-unused-vars'].docsUrl, + plugin: { + slug: ESLINT_PLUGIN_META.slug, + title: ESLINT_PLUGIN_META.title, + docsUrl: ESLINT_PLUGIN_META.docsUrl, + }, + scores: { before: 1, after: 0, diff: -1 }, + values: { before: 0, after: 1, diff: 1 }, + displayValues: { before: 'passed', after: '1 error' }, + }, + ...originalDiff.audits.changed.filter( + ({ plugin }) => plugin.slug === 'lighthouse', + ), + ], + unchanged: [ + ...ESLINT_AUDIT_SLUGS.filter(slug => slug !== 'no-unused-vars').map( + (slug): AuditResult => ({ + slug, + title: ESLINT_AUDITS_MAP[slug].title, + docsUrl: ESLINT_AUDITS_MAP[slug].docsUrl, + plugin: { + slug: ESLINT_PLUGIN_META.slug, + title: ESLINT_PLUGIN_META.title, + docsUrl: ESLINT_PLUGIN_META.docsUrl, + }, + score: ESLINT_AUDITS_MAP[slug].score, + value: ESLINT_AUDITS_MAP[slug].value, + displayValue: ESLINT_AUDITS_MAP[slug].displayValue, + }), + ), + ...originalDiff.audits.unchanged.filter( + ({ plugin }) => plugin.slug === 'lighthouse', + ), + ], + added: [], + removed: [], + }, + }; +} + +export function reportsDiffUnchangedMock(): ReportsDiff { + return { + ...reportsDiffMock(), + categories: { + changed: [], + unchanged: CATEGORY_SLUGS.map(slug => ({ + slug, + title: CATEGORIES_MAP[slug].title, + score: categoryScores(slug).before, + })), + added: [], + removed: [], + }, + groups: { + changed: [], + unchanged: [ + { + slug: ESLINT_PLUGIN_GROUP_MAX_LINES.slug, + title: ESLINT_PLUGIN_GROUP_MAX_LINES.title, + plugin: { + slug: ESLINT_PLUGIN_META.slug, + title: ESLINT_PLUGIN_META.title, + docsUrl: ESLINT_PLUGIN_META.docsUrl, + }, + score: 0.5, + }, + { + slug: LH_PLUGIN_GROUP_PERFORMANCE.slug, + title: LH_PLUGIN_GROUP_PERFORMANCE.title, + plugin: { slug: LH_PLUGIN_META.slug, title: LH_PLUGIN_META.title }, + score: 0.92, + }, + ], + added: [], + removed: [], + }, + audits: { + changed: [], + unchanged: [ + ...ESLINT_AUDIT_SLUGS.map( + (slug): AuditResult => ({ + slug, + title: ESLINT_AUDITS_MAP[slug].title, + docsUrl: ESLINT_AUDITS_MAP[slug].docsUrl, + plugin: { + slug: ESLINT_PLUGIN_META.slug, + title: ESLINT_PLUGIN_META.title, + docsUrl: ESLINT_PLUGIN_META.docsUrl, + }, + score: ESLINT_AUDITS_MAP[slug].score, + value: ESLINT_AUDITS_MAP[slug].value, + displayValue: ESLINT_AUDITS_MAP[slug].displayValue, + }), + ), + ...LIGHTHOUSE_AUDIT_SLUGS.map( + (slug): AuditResult => ({ + slug, + title: LIGHTHOUSE_AUDITS_MAP[slug].title, + docsUrl: LIGHTHOUSE_AUDITS_MAP[slug].docsUrl, + plugin: { slug: LH_PLUGIN_META.slug, title: LH_PLUGIN_META.title }, + score: LIGHTHOUSE_AUDITS_MAP[slug].score, + value: LIGHTHOUSE_AUDITS_MAP[slug].value, + displayValue: LIGHTHOUSE_AUDITS_MAP[slug].displayValue, + }), + ), + ], + added: [], + removed: [], + }, + }; +} + +export function reportsDiffChangedMock(): ReportsDiff { + const originalDiff = reportsDiffUnchangedMock(); + return { + ...originalDiff, + audits: { + ...originalDiff.audits, + changed: [ + { + slug: 'no-unused-vars' satisfies ESLintAuditSlug, + title: ESLINT_AUDITS_MAP['no-unused-vars'].title, + docsUrl: ESLINT_AUDITS_MAP['no-unused-vars'].docsUrl, + plugin: { + slug: ESLINT_PLUGIN_META.slug, + title: ESLINT_PLUGIN_META.title, + docsUrl: ESLINT_PLUGIN_META.docsUrl, + }, + scores: { before: 0, after: 0, diff: 0 }, + values: { before: 12, after: 10, diff: -2 }, + displayValues: { before: '12 warnings', after: '10 warnings' }, + }, + ], + }, + }; +} + +export function reportsDiffAddedPluginMock(): ReportsDiff { + const originalDiff = reportsDiffAltMock(); + return { + ...originalDiff, + categories: { + ...originalDiff.categories, + changed: originalDiff.categories.changed.filter( + ({ slug }) => slug !== ('performance' satisfies CategorySlug), + ), + added: [ + { + slug: 'performance' satisfies CategorySlug, + title: CATEGORIES_MAP['performance'].title, + score: categoryScores('performance').after, + }, + ], + }, + groups: { + ...originalDiff.groups, + changed: originalDiff.groups.changed.filter( + ({ plugin }) => plugin.slug !== 'lighthouse', + ), + added: originalDiff.groups.changed + .filter(({ plugin }) => plugin.slug === 'lighthouse') + .map(group => ({ + slug: group.slug, + title: group.title, + plugin: group.plugin, + score: group.scores.after, + })), + }, + audits: { + ...originalDiff.audits, + changed: originalDiff.audits.changed.filter( + ({ plugin }) => plugin.slug !== 'lighthouse', + ), + added: originalDiff.audits.changed + .filter(({ plugin }) => plugin.slug === 'lighthouse') + .map(audit => ({ + slug: audit.slug, + title: audit.title, + docsUrl: audit.docsUrl, + plugin: audit.plugin, + score: audit.scores.after, + value: audit.values.after, + displayValue: audit.displayValues.after, + })), + }, + }; +} + +function categoryScores(slug: CategorySlug): CategoryDiff['scores'] { + switch (slug) { + case 'performance': + return { before: 0.92, after: 0.94, diff: 0.02 }; + case 'bug-prevention': + return { before: 0.68, after: 0.95, diff: 0.27 }; + case 'code-style': + return { before: 0.54, after: 1, diff: 0.46 }; + } +} + +function toNumberComparison({ + before, + after, +}: { + before: number; + after: number; +}) { + return { before, after, diff: after - before }; +} diff --git a/testing/test-fixtures/src/lib/utils/dynamic-mocks/report.mock.ts b/testing/test-fixtures/src/lib/utils/dynamic-mocks/report.mock.ts new file mode 100644 index 000000000..69895386c --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/dynamic-mocks/report.mock.ts @@ -0,0 +1,39 @@ +import type { Report } from '@code-pushup/models'; +import { COMMIT_ALT_MOCK, COMMIT_MOCK } from '../commit.mock.js'; +import { categoryConfigsMock } from './categories.mock.js'; +import { + eslintPluginReportAltMock, + eslintPluginReportMock, +} from './eslint-plugin.mock.js'; +import { + lighthousePluginReportAltMock, + lighthousePluginReportMock, +} from './lighthouse-plugin.mock.js'; + +export function reportMock(): Report { + return { + packageName: '@code-pushup/core', + version: '0.0.1', + date: '2023-10-18T07:49:45.506Z', + duration: + eslintPluginReportMock().duration + + lighthousePluginReportMock().duration + + 50, + commit: COMMIT_MOCK, + categories: categoryConfigsMock(), + plugins: [eslintPluginReportMock(), lighthousePluginReportMock()], + }; +} + +export function reportAltMock(): Report { + return { + ...reportMock(), + date: '2024-03-12T12:42:05.370Z', + duration: + eslintPluginReportAltMock().duration + + lighthousePluginReportAltMock().duration + + 20, + commit: COMMIT_ALT_MOCK, + plugins: [eslintPluginReportAltMock(), lighthousePluginReportAltMock()], + }; +} diff --git a/testing/test-fixtures/src/lib/utils/dynamic-mocks/runner-config.mock.ts b/testing/test-fixtures/src/lib/utils/dynamic-mocks/runner-config.mock.ts new file mode 100644 index 000000000..b6dae5e92 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/dynamic-mocks/runner-config.mock.ts @@ -0,0 +1,43 @@ +import { platform } from 'node:os'; +import { + type AuditOutput, + type RunnerConfig, + runnerConfigSchema, +} from '@code-pushup/models'; + +/** + * Use this helper as a general purpose mock with working defaults + * @param options + */ +export function runnerConfigMock( + options?: Partial, +): RunnerConfig { + const outputFile = `out.${Date.now()}.json`; + return runnerConfigSchema.parse({ + command: 'node', + args: ['-v', '>', outputFile], + outputFile, + ...options, + }); +} + +/** + * Use this helper to mock the output data of a plugin synchronously + * + * @param output + * @param outputFile + */ +export function echoRunnerConfigMock( + output: AuditOutput[], + outputFile: string, +): RunnerConfig { + const auditOutput = + platform() === 'win32' + ? JSON.stringify(output) + : `'${JSON.stringify(output)}'`; + return { + command: 'echo', + args: [auditOutput, '>', outputFile], + outputFile, + }; +} diff --git a/testing/test-fixtures/src/lib/utils/dynamic-mocks/upload-config.mock.ts b/testing/test-fixtures/src/lib/utils/dynamic-mocks/upload-config.mock.ts new file mode 100644 index 000000000..2cd3924a0 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/dynamic-mocks/upload-config.mock.ts @@ -0,0 +1,15 @@ +import { + type UploadConfig, + uploadConfigSchema, + validate, +} from '@code-pushup/models'; + +export function uploadConfig(opt?: Partial): UploadConfig { + return validate(uploadConfigSchema, { + apiKey: 'm0ck-API-k3y', + server: 'http://test.server.io', + organization: 'code-pushup', + project: 'cli', + ...opt, + }); +} diff --git a/testing/test-fixtures/src/lib/utils/minimal-config.mock.ts b/testing/test-fixtures/src/lib/utils/minimal-config.mock.ts new file mode 100644 index 000000000..8416632d4 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/minimal-config.mock.ts @@ -0,0 +1,60 @@ +import type { + AuditOutput, + CoreConfig, + PluginConfig, + RunnerConfig, + RunnerFunction, +} from '@code-pushup/models'; + +// Note: In order for the runner to not expect an actual file, set up fs mocks +// Then add output.json to the in-memory file system and customise content as needed +export const MINIMAL_RUNNER_CONFIG_MOCK: RunnerConfig = { + command: 'node', + args: ['-v'], + outputFile: 'output.json', +}; + +export const MINIMAL_RUNNER_FUNCTION_MOCK: RunnerFunction = () => [ + { + slug: 'node-version', + score: 0.3, + value: 16, + displayValue: '16.0.0', + details: { + issues: [ + { + severity: 'error', + message: 'The required Node version to run Code PushUp CLI is 18.', + }, + ], + }, + } satisfies AuditOutput, +]; + +export const MINIMAL_PLUGIN_CONFIG_MOCK: PluginConfig = { + slug: 'node', + title: 'Node', + icon: 'javascript', + audits: [ + { + slug: 'node-version', + title: 'Node version', + description: 'Returns node version', + docsUrl: 'https://nodejs.org/', + }, + ], + runner: MINIMAL_RUNNER_FUNCTION_MOCK, +}; + +export const MINIMAL_CONFIG_MOCK: CoreConfig = { + plugins: [MINIMAL_PLUGIN_CONFIG_MOCK], +}; + +export const MINIMAL_HISTORY_CONFIG_MOCK: CoreConfig = { + persist: { + outputDir: '.code-pushup', + filename: 'history-report', + format: ['json'], + }, + plugins: [MINIMAL_PLUGIN_CONFIG_MOCK], +}; diff --git a/testing/test-fixtures/src/lib/utils/omit-report-data.ts b/testing/test-fixtures/src/lib/utils/omit-report-data.ts new file mode 100644 index 000000000..26b6f959b --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/omit-report-data.ts @@ -0,0 +1,46 @@ +import type { + AuditOutput, + AuditReport, + PluginReport, + Report, +} from '@code-pushup/models'; + +export function omitVariableAuditData({ + score: _, + value: __, + displayValue: ___, + details: ____, + ...auditReport +}: AuditReport | AuditOutput) { + return auditReport; +} + +export function omitVariablePluginData( + { date: _, duration: __, version: ___, ...pluginReport }: PluginReport, + options?: { + omitAuditData: boolean; + }, +) { + const { omitAuditData } = options ?? {}; + if (omitAuditData) { + return { + ...pluginReport, + audits: pluginReport.audits.map(omitVariableAuditData), + }; + } + return pluginReport; +} + +export function omitVariableReportData( + { commit: _, date: __, duration: ___, version: ____, ...report }: Report, + options?: { + omitAuditData: boolean; + }, +) { + return { + ...report, + plugins: report.plugins.map(plugin => + omitVariablePluginData(plugin, options), + ), + }; +} diff --git a/testing/test-fixtures/src/lib/utils/os-agnostic.ts b/testing/test-fixtures/src/lib/utils/os-agnostic.ts new file mode 100644 index 000000000..e00d0f175 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/os-agnostic.ts @@ -0,0 +1,38 @@ +import type { AuditOutput, AuditReport } from '@code-pushup/models'; +import { osAgnosticPath } from '@code-pushup/test-utils'; + +export function osAgnosticAudit( + audit: T, + transformMessage: (message: string) => string = s => s, +): T { + const { issues = [] } = audit.details ?? {}; + if (issues.every(({ source }) => source == null)) { + return audit; + } + return { + ...audit, + details: { + issues: issues.map(issue => + issue.source == null + ? issue + : { + ...issue, + source: { + ...issue.source, + file: osAgnosticPath(issue.source.file), + }, + message: transformMessage(issue.message), + }, + ), + }, + }; +} + +export function osAgnosticAuditOutputs( + audits: T[], + transformAuditIssueMessage?: (message: string) => string, +): T[] { + return audits.map(audit => + osAgnosticAudit(audit, transformAuditIssueMessage), + ); +} diff --git a/testing/test-fixtures/src/lib/utils/report.mock.ts b/testing/test-fixtures/src/lib/utils/report.mock.ts new file mode 100644 index 000000000..3b2020ee6 --- /dev/null +++ b/testing/test-fixtures/src/lib/utils/report.mock.ts @@ -0,0 +1,299 @@ +import type { PluginConfig, PluginReport, Report } from '@code-pushup/models'; +import { COMMIT_MOCK } from './commit.mock.js'; +import { + auditReportMock, + pluginConfigMock, +} from './dynamic-mocks/plugin-config.mock.js'; + +export const MINIMAL_REPORT_MOCK: Report = { + packageName: '@code-pushup/core', + version: '0.0.1', + date: '2023-08-16T09:00:00.000Z', + duration: 666, + commit: COMMIT_MOCK, + plugins: [ + { + slug: 'eslint', + title: 'ESLint', + icon: 'eslint', + audits: [ + { + slug: 'no-any', + title: 'No any type.', + value: 1, + score: 0, + }, + ], + date: '2023-08-16T09:00:00.000Z', + duration: 420, + }, + ], +}; + +export const REPORT_MOCK: Report = { + packageName: '@code-pushup/core', + version: '1.0.0', + date: '2023-08-16T09:00:00.000Z', + duration: 666, + commit: COMMIT_MOCK, + categories: [ + { + slug: 'test-results', + title: 'Test results', + refs: [ + { + type: 'audit', + slug: 'cypress-component-tests', + plugin: 'cypress', + weight: 1, + }, + { + type: 'audit', + slug: 'cypress-e2e-tests', + plugin: 'cypress', + weight: 3, + }, + ], + }, + { + slug: 'bug-prevention', + title: 'Bug prevention', + refs: [ + { + type: 'group', + slug: 'typescript-eslint-extra', + plugin: 'eslint', + weight: 0, + }, + { + type: 'audit', + slug: 'eslint-functional', + plugin: 'eslint', + weight: 1, + }, + + { + type: 'group', + slug: 'typescript-eslint', + plugin: 'eslint', + weight: 8, + }, + { + type: 'audit', + slug: 'eslint-jest-consistent-naming', + plugin: 'eslint', + weight: 1, + }, + { + type: 'audit', + slug: 'eslint-cypress', + plugin: 'eslint', + weight: 0, + }, + ], + }, + ], + plugins: [ + { + slug: 'cypress', + title: 'Cypress results', + date: '2023-08-16T09:00:00.000Z', + duration: 42, + icon: 'cypress', + audits: [ + { + slug: 'cypress-component-tests', + title: 'Cypress component tests', + value: 0, + score: 1, + }, + { + slug: 'cypress-e2e-tests', + title: 'Cypress e2e tests', + value: 3, + score: 0.5, + details: { + issues: [ + { + message: 'Test `Display progress for selected commit` failed.', + severity: 'error', + }, + { + message: 'Test `Sort audit table based on value` failed.', + severity: 'error', + }, + { + message: 'Test `Open Bug prevention category detail` failed.', + severity: 'error', + }, + ], + }, + }, + ], + }, + { + slug: 'eslint', + title: 'ESLint', + date: '2023-08-16T09:00:00.000Z', + duration: 624, + icon: 'eslint', + groups: [ + { + slug: 'typescript-eslint', + title: 'TypeScript ESLint', + refs: [ + { + slug: 'typescript-eslint-typing', + weight: 3, + }, + { + slug: 'typescript-eslint-enums', + weight: 1, + }, + { + slug: 'typescript-eslint-experimental', + weight: 0, + }, + ], + }, + { + slug: 'typescript-eslint-extra', + title: 'TypeScript ESLint Extra', + refs: [ + { + slug: 'typescript-eslint-experimental', + weight: 1, + }, + ], + }, + ], + audits: [ + { + slug: 'eslint-cypress', + title: 'Cypress rules', + value: 0, + score: 1, + }, + { + slug: 'typescript-eslint-typing', + title: 'Type checking', + value: 2, + score: 0, + details: { + issues: [ + { + message: 'command might be undefined', + severity: 'warning', + source: { + file: 'packages/cli/cli.ts', + position: { + startLine: 5, + startColumn: 10, + endLine: 5, + endColumn: 20, + }, + }, + }, + { + message: 'outputFile does not exist in type Cli', + severity: 'error', + source: { + file: 'packages/cli/cli.ts', + position: { + startLine: 1, + startColumn: 1, + endLine: 5, + endColumn: 10, + }, + }, + }, + ], + }, + }, + { + slug: 'typescript-eslint-enums', + title: 'Enumeration value checks', + value: 0, + score: 1, + }, + { + slug: 'typescript-eslint-experimental', + title: 'TypeScript experimental checks', + value: 1, + score: 0, + details: { + issues: [{ message: 'Use better-enums.', severity: 'info' }], + }, + }, + { + slug: 'eslint-functional', + title: 'Functional principles', + value: 1, + score: 0, + details: { + issues: [ + { + message: 'Unexpected let, use const instead.', + severity: 'error', + source: { + file: 'packages/core/report.ts', + }, + }, + ], + }, + }, + { + slug: 'eslint-jest-consistent-naming', + title: 'Consistent naming', + value: 0, + score: 1, + }, + ], + }, + ], +}; + +export function minimalReportMock(outputDir = 'tmp'): Report { + const PLUGIN_1_SLUG = 'plugin-1'; + const AUDIT_1_SLUG = 'audit-1'; + + const plg1: PluginConfig = pluginConfigMock([], { + slug: PLUGIN_1_SLUG, + outputDir, + }); + + const { runner: _, ...rest } = plg1; + const pluginReport: PluginReport = { + ...rest, + duration: 0, + date: 'dummy-data-string', + version: '', + packageName: '', + audits: [auditReportMock({ slug: AUDIT_1_SLUG })], + }; + + return JSON.parse( + JSON.stringify({ + packageName: '@code-pushup/core', + version: '0.1.0', + date: 'today', + commit: null, + duration: 42, + categories: [ + { + slug: 'category-1', + title: 'Category 1', + refs: [ + { + type: 'audit', + plugin: PLUGIN_1_SLUG, + slug: AUDIT_1_SLUG, + weight: 1, + }, + ], + }, + ], + plugins: [pluginReport], + } satisfies Report), + ); +} diff --git a/testing/test-fixtures/tsconfig.json b/testing/test-fixtures/tsconfig.json new file mode 100644 index 000000000..c370491f9 --- /dev/null +++ b/testing/test-fixtures/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "es2022", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "types": ["vitest"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.test.json" + } + ] +} diff --git a/testing/test-fixtures/tsconfig.lib.json b/testing/test-fixtures/tsconfig.lib.json new file mode 100644 index 000000000..3975fe4ed --- /dev/null +++ b/testing/test-fixtures/tsconfig.lib.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": [ + "vitest.unit.config.ts", + "src/**/*.unit.test.ts", + "src/lib/fixtures/configs" + ] +} diff --git a/testing/test-fixtures/tsconfig.test.json b/testing/test-fixtures/tsconfig.test.json new file mode 100644 index 000000000..cafb05dd2 --- /dev/null +++ b/testing/test-fixtures/tsconfig.test.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"] + }, + "include": ["vitest.unit.config.ts", "src/**/*.unit.test.ts"] +} diff --git a/packages/cli/mocks/fixtures/configs/code-pushup.config.js b/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.js similarity index 100% rename from packages/cli/mocks/fixtures/configs/code-pushup.config.js rename to testing/test-utils/src/lib/fixtures/configs/code-pushup.config.js diff --git a/packages/cli/mocks/fixtures/configs/code-pushup.config.mjs b/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.mjs similarity index 100% rename from packages/cli/mocks/fixtures/configs/code-pushup.config.mjs rename to testing/test-utils/src/lib/fixtures/configs/code-pushup.config.mjs diff --git a/packages/core/mocks/fixtures/configs/code-pushup.config.ts b/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.ts similarity index 100% rename from packages/core/mocks/fixtures/configs/code-pushup.config.ts rename to testing/test-utils/src/lib/fixtures/configs/code-pushup.config.ts diff --git a/packages/core/mocks/fixtures/configs/code-pushup.empty.config.js b/testing/test-utils/src/lib/fixtures/configs/code-pushup.empty.config.js similarity index 100% rename from packages/core/mocks/fixtures/configs/code-pushup.empty.config.js rename to testing/test-utils/src/lib/fixtures/configs/code-pushup.empty.config.js diff --git a/packages/core/mocks/fixtures/configs/code-pushup.invalid.config.ts b/testing/test-utils/src/lib/fixtures/configs/code-pushup.invalid.config.ts similarity index 100% rename from packages/core/mocks/fixtures/configs/code-pushup.invalid.config.ts rename to testing/test-utils/src/lib/fixtures/configs/code-pushup.invalid.config.ts diff --git a/packages/core/mocks/fixtures/configs/code-pushup.needs-tsconfig.config.ts b/testing/test-utils/src/lib/fixtures/configs/code-pushup.needs-tsconfig.config.ts similarity index 100% rename from packages/core/mocks/fixtures/configs/code-pushup.needs-tsconfig.config.ts rename to testing/test-utils/src/lib/fixtures/configs/code-pushup.needs-tsconfig.config.ts diff --git a/packages/core/mocks/fixtures/configs/custom-plugin.ts b/testing/test-utils/src/lib/fixtures/configs/custom-plugin.ts similarity index 100% rename from packages/core/mocks/fixtures/configs/custom-plugin.ts rename to testing/test-utils/src/lib/fixtures/configs/custom-plugin.ts diff --git a/packages/core/mocks/fixtures/configs/tsconfig.json b/testing/test-utils/src/lib/fixtures/configs/tsconfig.json similarity index 100% rename from packages/core/mocks/fixtures/configs/tsconfig.json rename to testing/test-utils/src/lib/fixtures/configs/tsconfig.json From 242428fa40baa0efaee059cf54bfba4aa78f9a31 Mon Sep 17 00:00:00 2001 From: John Doe Date: Fri, 5 Dec 2025 23:02:35 +0100 Subject: [PATCH 03/13] refactor: intro test-fixtures project 2 --- .../fixtures/configs/code-pushup.config.js | 43 +++++++++++++++++++ .../fixtures/configs/code-pushup.config.mjs | 43 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 testing/test-fixtures/src/lib/fixtures/configs/code-pushup.config.js create mode 100644 testing/test-fixtures/src/lib/fixtures/configs/code-pushup.config.mjs diff --git a/testing/test-fixtures/src/lib/fixtures/configs/code-pushup.config.js b/testing/test-fixtures/src/lib/fixtures/configs/code-pushup.config.js new file mode 100644 index 000000000..9f1661d4d --- /dev/null +++ b/testing/test-fixtures/src/lib/fixtures/configs/code-pushup.config.js @@ -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', + }, + ], +}; diff --git a/testing/test-fixtures/src/lib/fixtures/configs/code-pushup.config.mjs b/testing/test-fixtures/src/lib/fixtures/configs/code-pushup.config.mjs new file mode 100644 index 000000000..d7f531533 --- /dev/null +++ b/testing/test-fixtures/src/lib/fixtures/configs/code-pushup.config.mjs @@ -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', + }, + ], +}; From aea8224ab359087d3d0c0c7becacfd60ffb0144a Mon Sep 17 00:00:00 2001 From: John Doe Date: Fri, 5 Dec 2025 23:26:05 +0100 Subject: [PATCH 04/13] refactor: update imports --- .../lib/autorun/autorun-command.unit.test.ts | 7 +- .../lib/collect/collect-command.unit.test.ts | 4 +- .../lib/compare/compare-command.unit.test.ts | 4 +- .../lib/history/history-command.unit.test.ts | 4 +- .../implementation/core-config.int.test.ts | 5 +- .../core-config.middleware.int.test.ts | 2 +- .../core-config.middleware.unit.test.ts | 4 +- .../filter.middleware.unit.test.ts | 4 +- .../merge-diffs-command.unit.test.ts | 4 +- .../print-config-command.unit.test.ts | 4 +- .../lib/upload/upload-command.unit.test.ts | 11 +- .../src/lib/collect-and-persist.unit.test.ts | 2 +- packages/core/src/lib/compare.unit.test.ts | 4 +- packages/core/src/lib/history.unit.test.ts | 2 +- .../lib/implementation/collect.int.test.ts | 3 +- .../execute-plugin.unit.test.ts | 6 +- .../lib/implementation/persist.unit.test.ts | 7 +- .../implementation/read-rc-file.int.test.ts | 2 +- .../implementation/read-rc-file.unit.test.ts | 2 +- .../lib/implementation/runner.unit.test.ts | 5 +- .../core/src/lib/merge-diffs.unit.test.ts | 4 +- packages/core/src/lib/upload.unit.test.ts | 7 +- .../reports/generate-md-report.int.test.ts | 2 +- .../generate-md-reports-diff.int.test.ts | 2 +- .../src/lib/reports/load-report.unit.test.ts | 3 +- .../reports/log-stdout-summary.int.test.ts | 3 +- .../src/lib/reports/scoring.unit.test.ts | 2 +- .../utils/src/lib/reports/sorting.int.test.ts | 2 +- testing/test-utils/src/index.ts | 21 - .../fixtures/configs/code-pushup.config.js | 43 - .../fixtures/configs/code-pushup.config.mjs | 43 - .../fixtures/configs/code-pushup.config.ts | 45 - .../configs/code-pushup.empty.config.js | 1 - .../configs/code-pushup.invalid.config.ts | 53 -- .../code-pushup.needs-tsconfig.config.ts | 10 - .../src/lib/fixtures/configs/custom-plugin.ts | 24 - .../src/lib/fixtures/configs/tsconfig.json | 7 - .../test-utils/src/lib/utils/commit.mock.ts | 15 - .../src/lib/utils/core-config.mock.ts | 72 -- .../utils/dynamic-mocks/categories.mock.ts | 81 -- .../lib/utils/dynamic-mocks/config.mock.ts | 68 -- .../utils/dynamic-mocks/eslint-audits.mock.ts | 820 ------------------ .../utils/dynamic-mocks/eslint-plugin.mock.ts | 103 --- .../dynamic-mocks/lighthouse-audits.mock.ts | 95 -- .../dynamic-mocks/lighthouse-plugin.mock.ts | 96 -- .../dynamic-mocks/persist-config.mock.ts | 19 - .../utils/dynamic-mocks/plugin-config.mock.ts | 57 -- .../utils/dynamic-mocks/report-diff.mock.ts | 434 --------- .../lib/utils/dynamic-mocks/report.mock.ts | 39 - .../utils/dynamic-mocks/runner-config.mock.ts | 43 - .../utils/dynamic-mocks/upload-config.mock.ts | 15 - .../src/lib/utils/minimal-config.mock.ts | 60 -- .../src/lib/utils/omit-report-data.ts | 46 - .../src/lib/utils/os-agnostic-paths.ts | 38 - .../test-utils/src/lib/utils/report.mock.ts | 299 ------- tsconfig.base.json | 1 + 56 files changed, 54 insertions(+), 2705 deletions(-) delete mode 100644 testing/test-utils/src/lib/fixtures/configs/code-pushup.config.js delete mode 100644 testing/test-utils/src/lib/fixtures/configs/code-pushup.config.mjs delete mode 100644 testing/test-utils/src/lib/fixtures/configs/code-pushup.config.ts delete mode 100644 testing/test-utils/src/lib/fixtures/configs/code-pushup.empty.config.js delete mode 100644 testing/test-utils/src/lib/fixtures/configs/code-pushup.invalid.config.ts delete mode 100644 testing/test-utils/src/lib/fixtures/configs/code-pushup.needs-tsconfig.config.ts delete mode 100644 testing/test-utils/src/lib/fixtures/configs/custom-plugin.ts delete mode 100644 testing/test-utils/src/lib/fixtures/configs/tsconfig.json delete mode 100644 testing/test-utils/src/lib/utils/commit.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/core-config.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/dynamic-mocks/categories.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/dynamic-mocks/config.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/dynamic-mocks/eslint-audits.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/dynamic-mocks/eslint-plugin.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/dynamic-mocks/lighthouse-audits.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/dynamic-mocks/lighthouse-plugin.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/dynamic-mocks/persist-config.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/dynamic-mocks/plugin-config.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/dynamic-mocks/report-diff.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/dynamic-mocks/report.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/dynamic-mocks/runner-config.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/dynamic-mocks/upload-config.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/minimal-config.mock.ts delete mode 100644 testing/test-utils/src/lib/utils/omit-report-data.ts delete mode 100644 testing/test-utils/src/lib/utils/report.mock.ts diff --git a/packages/cli/src/lib/autorun/autorun-command.unit.test.ts b/packages/cli/src/lib/autorun/autorun-command.unit.test.ts index 040fb44c7..a44d4a2bb 100644 --- a/packages/cli/src/lib/autorun/autorun-command.unit.test.ts +++ b/packages/cli/src/lib/autorun/autorun-command.unit.test.ts @@ -2,14 +2,15 @@ import { vol } from 'memfs'; import { describe, expect, it, vi } from 'vitest'; import { uploadReportToPortal } from '@code-pushup/portal-client'; import { collectAndPersistReports, readRcByPath } from '@code-pushup/core'; -import { MEMFS_VOLUME, MINIMAL_REPORT_MOCK } from '@code-pushup/test-utils'; +import { MINIMAL_REPORT_MOCK } from '@code-pushup/test-fixtures'; +import { MEMFS_VOLUME } from '@code-pushup/test-utils'; import { DEFAULT_CLI_CONFIGURATION } from '../../../mocks/constants.js'; import { yargsCli } from '../yargs-cli.js'; import { yargsAutorunCommandObject } from './autorun-command.js'; vi.mock('@code-pushup/core', async () => { - const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-utils') = - await vi.importActual('@code-pushup/test-utils'); + const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-fixtures') = + await vi.importActual('@code-pushup/test-fixtures'); const core: object = await vi.importActual('@code-pushup/core'); return { ...core, diff --git a/packages/cli/src/lib/collect/collect-command.unit.test.ts b/packages/cli/src/lib/collect/collect-command.unit.test.ts index 6765add61..71dd50339 100644 --- a/packages/cli/src/lib/collect/collect-command.unit.test.ts +++ b/packages/cli/src/lib/collect/collect-command.unit.test.ts @@ -11,8 +11,8 @@ import { yargsCli } from '../yargs-cli.js'; import { yargsCollectCommandObject } from './collect-command.js'; vi.mock('@code-pushup/core', async () => { - const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-utils') = - await vi.importActual('@code-pushup/test-utils'); + const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-fixtures') = + await vi.importActual('@code-pushup/test-fixtures'); const core: object = await vi.importActual('@code-pushup/core'); return { ...core, diff --git a/packages/cli/src/lib/compare/compare-command.unit.test.ts b/packages/cli/src/lib/compare/compare-command.unit.test.ts index d0ccb5199..25e6ad5b0 100644 --- a/packages/cli/src/lib/compare/compare-command.unit.test.ts +++ b/packages/cli/src/lib/compare/compare-command.unit.test.ts @@ -12,8 +12,8 @@ import { yargsCompareCommandObject } from './compare-command.js'; vi.mock('@code-pushup/core', async () => { const core: object = await vi.importActual('@code-pushup/core'); - const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-utils') = - await vi.importActual('@code-pushup/test-utils'); + const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-fixtures') = + await vi.importActual('@code-pushup/test-fixtures'); return { ...core, autoloadRc: vi.fn().mockResolvedValue(CORE_CONFIG_MOCK), diff --git a/packages/cli/src/lib/history/history-command.unit.test.ts b/packages/cli/src/lib/history/history-command.unit.test.ts index e1892d7f0..d7016526d 100644 --- a/packages/cli/src/lib/history/history-command.unit.test.ts +++ b/packages/cli/src/lib/history/history-command.unit.test.ts @@ -8,8 +8,8 @@ import { yargsHistoryCommandObject } from './history-command.js'; vi.mock('@code-pushup/core', async () => { const { MINIMAL_HISTORY_CONFIG_MOCK, - }: typeof import('@code-pushup/test-utils') = await vi.importActual( - '@code-pushup/test-utils', + }: typeof import('@code-pushup/test-fixtures') = await vi.importActual( + '@code-pushup/test-fixtures', ); const core: object = await vi.importActual('@code-pushup/core'); return { diff --git a/packages/cli/src/lib/implementation/core-config.int.test.ts b/packages/cli/src/lib/implementation/core-config.int.test.ts index 7c0a156d1..c933eccfe 100644 --- a/packages/cli/src/lib/implementation/core-config.int.test.ts +++ b/packages/cli/src/lib/implementation/core-config.int.test.ts @@ -8,7 +8,10 @@ import { type PersistConfig, type UploadConfig, } from '@code-pushup/models'; -import { CORE_CONFIG_MOCK, MINIMAL_CONFIG_MOCK } from '@code-pushup/test-utils'; +import { + CORE_CONFIG_MOCK, + MINIMAL_CONFIG_MOCK, +} from '@code-pushup/test-fixtures'; import { yargsCli } from '../yargs-cli.js'; import { coreConfigMiddleware } from './core-config.middleware.js'; import { yargsCoreConfigOptionsDefinition } from './core-config.options.js'; diff --git a/packages/cli/src/lib/implementation/core-config.middleware.int.test.ts b/packages/cli/src/lib/implementation/core-config.middleware.int.test.ts index 464b1dfc2..12ed17eb3 100644 --- a/packages/cli/src/lib/implementation/core-config.middleware.int.test.ts +++ b/packages/cli/src/lib/implementation/core-config.middleware.int.test.ts @@ -11,7 +11,7 @@ const configDirPath = path.join( '..', '..', 'testing', - 'test-utils', + 'test-fixtures', 'src', 'lib', 'fixtures', diff --git a/packages/cli/src/lib/implementation/core-config.middleware.unit.test.ts b/packages/cli/src/lib/implementation/core-config.middleware.unit.test.ts index 8c27e3abd..aca5da99d 100644 --- a/packages/cli/src/lib/implementation/core-config.middleware.unit.test.ts +++ b/packages/cli/src/lib/implementation/core-config.middleware.unit.test.ts @@ -10,8 +10,8 @@ import type { FilterOptions } from './filter.model.js'; import type { GeneralCliOptions } from './global.model.js'; vi.mock('@code-pushup/core', async () => { - const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-utils') = - await vi.importActual('@code-pushup/test-utils'); + const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-fixtures') = + await vi.importActual('@code-pushup/test-fixtures'); const core: object = await vi.importActual('@code-pushup/core'); return { ...core, diff --git a/packages/cli/src/lib/implementation/filter.middleware.unit.test.ts b/packages/cli/src/lib/implementation/filter.middleware.unit.test.ts index 414b2c79e..5cfec546f 100644 --- a/packages/cli/src/lib/implementation/filter.middleware.unit.test.ts +++ b/packages/cli/src/lib/implementation/filter.middleware.unit.test.ts @@ -8,8 +8,8 @@ import { import { OptionValidationError } from './validate-filter-options.utils.js'; vi.mock('@code-pushup/core', async () => { - const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-utils') = - await vi.importActual('@code-pushup/test-utils'); + const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-fixtures') = + await vi.importActual('@code-pushup/test-fixtures'); const core: object = await vi.importActual('@code-pushup/core'); return { ...core, diff --git a/packages/cli/src/lib/merge-diffs/merge-diffs-command.unit.test.ts b/packages/cli/src/lib/merge-diffs/merge-diffs-command.unit.test.ts index 991538750..5c2ea38b4 100644 --- a/packages/cli/src/lib/merge-diffs/merge-diffs-command.unit.test.ts +++ b/packages/cli/src/lib/merge-diffs/merge-diffs-command.unit.test.ts @@ -12,8 +12,8 @@ import { yargsMergeDiffsCommandObject } from './merge-diffs-command.js'; vi.mock('@code-pushup/core', async () => { const core: object = await vi.importActual('@code-pushup/core'); - const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-utils') = - await vi.importActual('@code-pushup/test-utils'); + const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-fixtures') = + await vi.importActual('@code-pushup/test-fixtures'); return { ...core, autoloadRc: vi.fn().mockResolvedValue(CORE_CONFIG_MOCK), diff --git a/packages/cli/src/lib/print-config/print-config-command.unit.test.ts b/packages/cli/src/lib/print-config/print-config-command.unit.test.ts index 83da94a1b..53979c2df 100644 --- a/packages/cli/src/lib/print-config/print-config-command.unit.test.ts +++ b/packages/cli/src/lib/print-config/print-config-command.unit.test.ts @@ -9,8 +9,8 @@ import { yargsCli } from '../yargs-cli.js'; import { yargsPrintConfigCommandObject } from './print-config-command.js'; vi.mock('@code-pushup/core', async () => { - const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-utils') = - await vi.importActual('@code-pushup/test-utils'); + const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-fixtures') = + await vi.importActual('@code-pushup/test-fixtures'); const core: object = await vi.importActual('@code-pushup/core'); return { ...core, diff --git a/packages/cli/src/lib/upload/upload-command.unit.test.ts b/packages/cli/src/lib/upload/upload-command.unit.test.ts index 7ffb7fbb1..13a54c83a 100644 --- a/packages/cli/src/lib/upload/upload-command.unit.test.ts +++ b/packages/cli/src/lib/upload/upload-command.unit.test.ts @@ -2,18 +2,15 @@ import { vol } from 'memfs'; import { describe, expect, it } from 'vitest'; import { uploadReportToPortal } from '@code-pushup/portal-client'; import { readRcByPath } from '@code-pushup/core'; -import { - ISO_STRING_REGEXP, - MEMFS_VOLUME, - MINIMAL_REPORT_MOCK, -} from '@code-pushup/test-utils'; +import { MINIMAL_REPORT_MOCK } from '@code-pushup/test-fixtures'; +import { ISO_STRING_REGEXP, MEMFS_VOLUME } from '@code-pushup/test-utils'; import { DEFAULT_CLI_CONFIGURATION } from '../../../mocks/constants.js'; import { yargsCli } from '../yargs-cli.js'; import { yargsUploadCommandObject } from './upload-command.js'; vi.mock('@code-pushup/core', async () => { - const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-utils') = - await vi.importActual('@code-pushup/test-utils'); + const { CORE_CONFIG_MOCK }: typeof import('@code-pushup/test-fixtures') = + await vi.importActual('@code-pushup/test-fixtures'); const core: object = await vi.importActual('@code-pushup/core'); return { ...core, diff --git a/packages/core/src/lib/collect-and-persist.unit.test.ts b/packages/core/src/lib/collect-and-persist.unit.test.ts index ffd3a5975..4d303232a 100644 --- a/packages/core/src/lib/collect-and-persist.unit.test.ts +++ b/packages/core/src/lib/collect-and-persist.unit.test.ts @@ -2,7 +2,7 @@ import { type MockInstance, describe } from 'vitest'; import { MINIMAL_CONFIG_MOCK, MINIMAL_REPORT_MOCK, -} from '@code-pushup/test-utils'; +} from '@code-pushup/test-fixtures'; import * as utils from '@code-pushup/utils'; import { type ScoredReport, diff --git a/packages/core/src/lib/compare.unit.test.ts b/packages/core/src/lib/compare.unit.test.ts index 303aaa7cf..cef29a6ce 100644 --- a/packages/core/src/lib/compare.unit.test.ts +++ b/packages/core/src/lib/compare.unit.test.ts @@ -11,11 +11,11 @@ import { import { COMMIT_ALT_MOCK, COMMIT_MOCK, - MEMFS_VOLUME, MINIMAL_REPORT_MOCK, REPORT_MOCK, reportMock, -} from '@code-pushup/test-utils'; +} from '@code-pushup/test-fixtures'; +import { MEMFS_VOLUME } from '@code-pushup/test-utils'; import { type Diff, fileExists, readJsonFile } from '@code-pushup/utils'; import { compareReportFiles, compareReports } from './compare.js'; diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index 787ef5a51..b1d964d03 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -1,5 +1,5 @@ import { describe, expect, vi } from 'vitest'; -import { MINIMAL_PLUGIN_CONFIG_MOCK } from '@code-pushup/test-utils'; +import { MINIMAL_PLUGIN_CONFIG_MOCK } from '@code-pushup/test-fixtures'; import { getCurrentBranchOrTag, safeCheckout } from '@code-pushup/utils'; import { collectAndPersistReports } from './collect-and-persist.js'; import { type HistoryOptions, history } from './history.js'; diff --git a/packages/core/src/lib/implementation/collect.int.test.ts b/packages/core/src/lib/implementation/collect.int.test.ts index 0e2c86972..929ca8304 100644 --- a/packages/core/src/lib/implementation/collect.int.test.ts +++ b/packages/core/src/lib/implementation/collect.int.test.ts @@ -2,7 +2,8 @@ import { writeFile } from 'node:fs/promises'; import path from 'node:path'; import { describe, expect, it } from 'vitest'; import { commitSchema } from '@code-pushup/models'; -import { MINIMAL_CONFIG_MOCK, cleanTestFolder } from '@code-pushup/test-utils'; +import { MINIMAL_CONFIG_MOCK } from '@code-pushup/test-fixtures'; +import { cleanTestFolder } from '@code-pushup/test-utils'; import { ensureDirectoryExists, fileExists, diff --git a/packages/core/src/lib/implementation/execute-plugin.unit.test.ts b/packages/core/src/lib/implementation/execute-plugin.unit.test.ts index dcb2b7582..aa5dcfdb1 100644 --- a/packages/core/src/lib/implementation/execute-plugin.unit.test.ts +++ b/packages/core/src/lib/implementation/execute-plugin.unit.test.ts @@ -6,10 +6,8 @@ import { DEFAULT_PERSIST_CONFIG, type PluginConfig, } from '@code-pushup/models'; -import { - MEMFS_VOLUME, - MINIMAL_PLUGIN_CONFIG_MOCK, -} from '@code-pushup/test-utils'; +import { MINIMAL_PLUGIN_CONFIG_MOCK } from '@code-pushup/test-fixtures'; +import { MEMFS_VOLUME } from '@code-pushup/test-utils'; import { logger } from '@code-pushup/utils'; import { executePlugin, executePlugins } from './execute-plugin.js'; import * as runnerModule from './runner.js'; diff --git a/packages/core/src/lib/implementation/persist.unit.test.ts b/packages/core/src/lib/implementation/persist.unit.test.ts index bcb10158c..1804bccb3 100644 --- a/packages/core/src/lib/implementation/persist.unit.test.ts +++ b/packages/core/src/lib/implementation/persist.unit.test.ts @@ -3,11 +3,8 @@ import { readFile } from 'node:fs/promises'; import path from 'node:path'; import { beforeEach, describe, expect, it } from 'vitest'; import type { Report } from '@code-pushup/models'; -import { - MEMFS_VOLUME, - MINIMAL_REPORT_MOCK, - REPORT_MOCK, -} from '@code-pushup/test-utils'; +import { MINIMAL_REPORT_MOCK, REPORT_MOCK } from '@code-pushup/test-fixtures'; +import { MEMFS_VOLUME } from '@code-pushup/test-utils'; import { logger, scoreReport, sortReport } from '@code-pushup/utils'; import { logPersistedResults, persistReport } from './persist.js'; diff --git a/packages/core/src/lib/implementation/read-rc-file.int.test.ts b/packages/core/src/lib/implementation/read-rc-file.int.test.ts index dae34e77a..d5bc3f33c 100644 --- a/packages/core/src/lib/implementation/read-rc-file.int.test.ts +++ b/packages/core/src/lib/implementation/read-rc-file.int.test.ts @@ -12,7 +12,7 @@ describe('readRcByPath', () => { '..', '..', 'testing', - 'test-utils', + 'test-fixtures', 'src', 'lib', 'fixtures', diff --git a/packages/core/src/lib/implementation/read-rc-file.unit.test.ts b/packages/core/src/lib/implementation/read-rc-file.unit.test.ts index d9c5e2001..dd5ee43b2 100644 --- a/packages/core/src/lib/implementation/read-rc-file.unit.test.ts +++ b/packages/core/src/lib/implementation/read-rc-file.unit.test.ts @@ -7,7 +7,7 @@ import { autoloadRc } from './read-rc-file.js'; // mock bundleRequire inside importEsmModule used for fetching config vi.mock('bundle-require', async () => { const { CORE_CONFIG_MOCK }: Record = - await vi.importActual('@code-pushup/test-utils'); + await vi.importActual('@code-pushup/test-fixtures'); return { bundleRequire: vi diff --git a/packages/core/src/lib/implementation/runner.unit.test.ts b/packages/core/src/lib/implementation/runner.unit.test.ts index 57770a279..233ac7211 100644 --- a/packages/core/src/lib/implementation/runner.unit.test.ts +++ b/packages/core/src/lib/implementation/runner.unit.test.ts @@ -9,12 +9,11 @@ import { auditOutputsSchema, } from '@code-pushup/models'; import { - MEMFS_VOLUME, MINIMAL_PLUGIN_CONFIG_MOCK, MINIMAL_RUNNER_CONFIG_MOCK, MINIMAL_RUNNER_FUNCTION_MOCK, - osAgnosticPath, -} from '@code-pushup/test-utils'; +} from '@code-pushup/test-fixtures'; +import { MEMFS_VOLUME, osAgnosticPath } from '@code-pushup/test-utils'; import * as utils from '@code-pushup/utils'; import { executePluginRunner, diff --git a/packages/core/src/lib/merge-diffs.unit.test.ts b/packages/core/src/lib/merge-diffs.unit.test.ts index be5e31e4e..cde61fffa 100644 --- a/packages/core/src/lib/merge-diffs.unit.test.ts +++ b/packages/core/src/lib/merge-diffs.unit.test.ts @@ -3,12 +3,12 @@ import { readFile } from 'node:fs/promises'; import path from 'node:path'; import type { PersistConfig } from '@code-pushup/models'; import { - MEMFS_VOLUME, reportsDiffAddedPluginMock, reportsDiffAltMock, reportsDiffMock, reportsDiffUnchangedMock, -} from '@code-pushup/test-utils'; +} from '@code-pushup/test-fixtures'; +import { MEMFS_VOLUME } from '@code-pushup/test-utils'; import { fileExists, logger } from '@code-pushup/utils'; import { mergeDiffs } from './merge-diffs.js'; diff --git a/packages/core/src/lib/upload.unit.test.ts b/packages/core/src/lib/upload.unit.test.ts index 92712b113..e9367ce66 100644 --- a/packages/core/src/lib/upload.unit.test.ts +++ b/packages/core/src/lib/upload.unit.test.ts @@ -1,11 +1,8 @@ import { vol } from 'memfs'; import { describe, expect } from 'vitest'; import { uploadReportToPortal } from '@code-pushup/portal-client'; -import { - ISO_STRING_REGEXP, - MEMFS_VOLUME, - MINIMAL_REPORT_MOCK, -} from '@code-pushup/test-utils'; +import { MINIMAL_REPORT_MOCK } from '@code-pushup/test-fixtures'; +import { ISO_STRING_REGEXP, MEMFS_VOLUME } from '@code-pushup/test-utils'; import { upload } from './upload.js'; describe('upload', () => { diff --git a/packages/utils/src/lib/reports/generate-md-report.int.test.ts b/packages/utils/src/lib/reports/generate-md-report.int.test.ts index 26a16f870..33ca1357c 100644 --- a/packages/utils/src/lib/reports/generate-md-report.int.test.ts +++ b/packages/utils/src/lib/reports/generate-md-report.int.test.ts @@ -1,5 +1,5 @@ import { describe } from 'vitest'; -import { reportMock } from '@code-pushup/test-utils'; +import { reportMock } from '@code-pushup/test-fixtures'; import { generateMdReport } from './generate-md-report.js'; import { scoreReport } from './scoring.js'; import { sortReport } from './sorting.js'; diff --git a/packages/utils/src/lib/reports/generate-md-reports-diff.int.test.ts b/packages/utils/src/lib/reports/generate-md-reports-diff.int.test.ts index 29a6d73d1..cb2aaee1a 100644 --- a/packages/utils/src/lib/reports/generate-md-reports-diff.int.test.ts +++ b/packages/utils/src/lib/reports/generate-md-reports-diff.int.test.ts @@ -6,7 +6,7 @@ import { reportsDiffChangedMock, reportsDiffMock, reportsDiffUnchangedMock, -} from '@code-pushup/test-utils'; +} from '@code-pushup/test-fixtures'; import { generateMdReportsDiff, generateMdReportsDiffForMonorepo, diff --git a/packages/utils/src/lib/reports/load-report.unit.test.ts b/packages/utils/src/lib/reports/load-report.unit.test.ts index 67d43a492..acafeb61c 100644 --- a/packages/utils/src/lib/reports/load-report.unit.test.ts +++ b/packages/utils/src/lib/reports/load-report.unit.test.ts @@ -1,6 +1,7 @@ import { vol } from 'memfs'; import type { Report } from '@code-pushup/models'; -import { MEMFS_VOLUME, REPORT_MOCK, reportMock } from '@code-pushup/test-utils'; +import { REPORT_MOCK, reportMock } from '@code-pushup/test-fixtures'; +import { MEMFS_VOLUME } from '@code-pushup/test-utils'; import { loadReport } from './load-report.js'; describe('loadReport', () => { diff --git a/packages/utils/src/lib/reports/log-stdout-summary.int.test.ts b/packages/utils/src/lib/reports/log-stdout-summary.int.test.ts index cf2267ff1..f89ae887a 100644 --- a/packages/utils/src/lib/reports/log-stdout-summary.int.test.ts +++ b/packages/utils/src/lib/reports/log-stdout-summary.int.test.ts @@ -1,5 +1,6 @@ import { beforeAll, describe, expect, vi } from 'vitest'; -import { removeColorCodes, reportMock } from '@code-pushup/test-utils'; +import { reportMock } from '@code-pushup/test-fixtures'; +import { removeColorCodes } from '@code-pushup/test-utils'; import { logger } from '../logger.js'; import { logStdoutSummary } from './log-stdout-summary.js'; import { scoreReport } from './scoring.js'; diff --git a/packages/utils/src/lib/reports/scoring.unit.test.ts b/packages/utils/src/lib/reports/scoring.unit.test.ts index fe0862f31..b92cd70c6 100644 --- a/packages/utils/src/lib/reports/scoring.unit.test.ts +++ b/packages/utils/src/lib/reports/scoring.unit.test.ts @@ -1,5 +1,5 @@ import { describe, expect } from 'vitest'; -import { REPORT_MOCK } from '@code-pushup/test-utils'; +import { REPORT_MOCK } from '@code-pushup/test-fixtures'; import { calculateScore, scoreAuditWithTarget, diff --git a/packages/utils/src/lib/reports/sorting.int.test.ts b/packages/utils/src/lib/reports/sorting.int.test.ts index 57212b3e0..71e75bfb9 100644 --- a/packages/utils/src/lib/reports/sorting.int.test.ts +++ b/packages/utils/src/lib/reports/sorting.int.test.ts @@ -1,4 +1,4 @@ -import { REPORT_MOCK } from '@code-pushup/test-utils'; +import { REPORT_MOCK } from '@code-pushup/test-fixtures'; import { scoreReport } from './scoring.js'; import { sortReport } from './sorting.js'; diff --git a/testing/test-utils/src/index.ts b/testing/test-utils/src/index.ts index 3c8a3626b..78bdba6df 100644 --- a/testing/test-utils/src/index.ts +++ b/testing/test-utils/src/index.ts @@ -6,26 +6,5 @@ export * from './lib/utils/git.js'; export * from './lib/utils/string.js'; export * from './lib/utils/file-system.js'; export * from './lib/utils/create-npm-workshpace.js'; -export * from './lib/utils/omit-report-data.js'; export * from './lib/utils/project-graph.js'; export * from './lib/utils/test-folder-setup.js'; - -// static mocks -export * from './lib/utils/commit.mock.js'; -export * from './lib/utils/core-config.mock.js'; -export * from './lib/utils/minimal-config.mock.js'; -export * from './lib/utils/report.mock.js'; - -// dynamic mocks -export * from './lib/utils/dynamic-mocks/categories.mock.js'; -export * from './lib/utils/dynamic-mocks/config.mock.js'; -export * from './lib/utils/dynamic-mocks/eslint-audits.mock.js'; -export * from './lib/utils/dynamic-mocks/eslint-plugin.mock.js'; -export * from './lib/utils/dynamic-mocks/lighthouse-audits.mock.js'; -export * from './lib/utils/dynamic-mocks/lighthouse-plugin.mock.js'; -export * from './lib/utils/dynamic-mocks/persist-config.mock.js'; -export * from './lib/utils/dynamic-mocks/plugin-config.mock.js'; -export * from './lib/utils/dynamic-mocks/report-diff.mock.js'; -export * from './lib/utils/dynamic-mocks/report.mock.js'; -export * from './lib/utils/dynamic-mocks/runner-config.mock.js'; -export * from './lib/utils/dynamic-mocks/upload-config.mock.js'; diff --git a/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.js b/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.js deleted file mode 100644 index 9f1661d4d..000000000 --- a/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.js +++ /dev/null @@ -1,43 +0,0 @@ -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', - }, - ], -}; diff --git a/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.mjs b/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.mjs deleted file mode 100644 index d7f531533..000000000 --- a/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.mjs +++ /dev/null @@ -1,43 +0,0 @@ -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', - }, - ], -}; diff --git a/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.ts b/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.ts deleted file mode 100644 index aad20f9b6..000000000 --- a/testing/test-utils/src/lib/fixtures/configs/code-pushup.config.ts +++ /dev/null @@ -1,45 +0,0 @@ -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; diff --git a/testing/test-utils/src/lib/fixtures/configs/code-pushup.empty.config.js b/testing/test-utils/src/lib/fixtures/configs/code-pushup.empty.config.js deleted file mode 100644 index ff8b4c563..000000000 --- a/testing/test-utils/src/lib/fixtures/configs/code-pushup.empty.config.js +++ /dev/null @@ -1 +0,0 @@ -export default {}; diff --git a/testing/test-utils/src/lib/fixtures/configs/code-pushup.invalid.config.ts b/testing/test-utils/src/lib/fixtures/configs/code-pushup.invalid.config.ts deleted file mode 100644 index 7396948b9..000000000 --- a/testing/test-utils/src/lib/fixtures/configs/code-pushup.invalid.config.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { CoreConfig } from '@code-pushup/models'; - -export default { - persist: { outputDir: 'tmp' }, - upload: { - organization: 'code-pushup', - project: 'cli-ts', - apiKey: 'e2e-api-key', - server: 'https://e2e.com/api', - }, - categories: [ - { - slug: 'bug-prevention', - title: 'Bug prevention', - // due to duplicate category references, the config is invalid - refs: [ - { - type: 'audit', - plugin: 'node', - slug: 'node-version', - weight: 1, - }, - { - 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; diff --git a/testing/test-utils/src/lib/fixtures/configs/code-pushup.needs-tsconfig.config.ts b/testing/test-utils/src/lib/fixtures/configs/code-pushup.needs-tsconfig.config.ts deleted file mode 100644 index 44b4d0a2d..000000000 --- a/testing/test-utils/src/lib/fixtures/configs/code-pushup.needs-tsconfig.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -// 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 '@example/custom-plugin'; - -const config = { - plugins: [customPlugin], -}; - -export default config; diff --git a/testing/test-utils/src/lib/fixtures/configs/custom-plugin.ts b/testing/test-utils/src/lib/fixtures/configs/custom-plugin.ts deleted file mode 100644 index 6afe6bc80..000000000 --- a/testing/test-utils/src/lib/fixtures/configs/custom-plugin.ts +++ /dev/null @@ -1,24 +0,0 @@ -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; diff --git a/testing/test-utils/src/lib/fixtures/configs/tsconfig.json b/testing/test-utils/src/lib/fixtures/configs/tsconfig.json deleted file mode 100644 index 42976b47b..000000000 --- a/testing/test-utils/src/lib/fixtures/configs/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "compilerOptions": { - "paths": { - "@example/custom-plugin": ["./custom-plugin.ts"] - } - } -} diff --git a/testing/test-utils/src/lib/utils/commit.mock.ts b/testing/test-utils/src/lib/utils/commit.mock.ts deleted file mode 100644 index 228a09960..000000000 --- a/testing/test-utils/src/lib/utils/commit.mock.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { Commit } from '@code-pushup/models'; - -export const COMMIT_MOCK: Commit = { - hash: 'abcdef0123456789abcdef0123456789abcdef01', - message: 'Minor fixes', - author: 'John Doe', - date: new Date('2023-08-16T08:30:00.000Z'), -}; - -export const COMMIT_ALT_MOCK: Commit = { - hash: '0123456789abcdef0123456789abcdef01234567', - message: 'Major fixes', - author: 'Jane Doe', - date: new Date('2023-08-16T10:00:00.000Z'), -}; diff --git a/testing/test-utils/src/lib/utils/core-config.mock.ts b/testing/test-utils/src/lib/utils/core-config.mock.ts deleted file mode 100644 index 193eaf06f..000000000 --- a/testing/test-utils/src/lib/utils/core-config.mock.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { type CoreConfig } from '@code-pushup/models'; - -export const CORE_CONFIG_MOCK = { - upload: { - organization: 'code-pushup', - project: 'cli', - apiKey: 'dummy-api-key', - server: 'https://example.com/api', - }, - categories: [ - { - slug: 'bug-prevention', - title: 'Bug prevention', - refs: [ - { - type: 'audit', - plugin: 'vitest', - slug: 'vitest-unit-tests', - weight: 1, - }, - { - type: 'audit', - plugin: 'cypress', - slug: 'cypress-e2e-tests', - weight: 1, - }, - ], - }, - ], - plugins: [ - { - slug: 'vitest', - title: 'Vitest results', - icon: 'vitest', - description: 'Vitest test results analysis', - docsUrl: 'https://vitest.dev/', - audits: [ - { - slug: 'vitest-unit-tests', - title: 'Vitest unit tests', - description: 'Vitest unit tests results analysis', - docsUrl: 'https://vitest.dev/', - }, - ], - runner: { - command: 'npx', - args: ['nx run cli:unit-test'], - outputFile: 'cli-unit-tests.json', - }, - }, - { - slug: 'cypress', - title: 'Cypress results', - icon: 'cypress', - description: 'Cypress test results analysis', - docsUrl: 'https://Cypress.dev/', - audits: [ - { - slug: 'cypress-e2e-tests', - title: 'Cypress e2e tests', - description: 'Cypress e2e tests results analysis', - docsUrl: 'https://docs.cypress.io/', - }, - ], - runner: { - command: 'npx', - args: ['cypress run'], - outputFile: 'ui-e2e-tests.json', - }, - }, - ], -} satisfies CoreConfig; diff --git a/testing/test-utils/src/lib/utils/dynamic-mocks/categories.mock.ts b/testing/test-utils/src/lib/utils/dynamic-mocks/categories.mock.ts deleted file mode 100644 index e35b9ee47..000000000 --- a/testing/test-utils/src/lib/utils/dynamic-mocks/categories.mock.ts +++ /dev/null @@ -1,81 +0,0 @@ -import type { CategoryConfig } from '@code-pushup/models'; -import { eslintAuditRefMock } from './eslint-plugin.mock.js'; - -export const CATEGORIES_MAP = { - performance: { - slug: 'performance', - title: 'Performance', - description: 'Performance metrics', - docsUrl: 'https://developers.google.com/web/fundamentals/performance', - refs: [ - { - type: 'group', - plugin: 'eslint', - slug: 'max-line-limitation', - weight: 0, - }, - { - type: 'group', - plugin: 'lighthouse', - slug: 'performance', - weight: 1, - }, - eslintAuditRefMock('react-jsx-key', 0), - ], - }, - 'bug-prevention': { - slug: 'bug-prevention', - title: 'Bug prevention', - refs: [ - eslintAuditRefMock('no-cond-assign'), - eslintAuditRefMock('no-const-assign'), - eslintAuditRefMock('no-debugger'), - eslintAuditRefMock('no-invalid-regexp'), - eslintAuditRefMock('no-undef'), - eslintAuditRefMock('no-unreachable-loop'), - eslintAuditRefMock('no-unsafe-negation'), - eslintAuditRefMock('no-unsafe-optional-chaining'), - eslintAuditRefMock('use-isnan'), - eslintAuditRefMock('valid-typeof'), - eslintAuditRefMock('eqeqeq'), - eslintAuditRefMock('react-jsx-key', 2), - eslintAuditRefMock('react-prop-types'), - eslintAuditRefMock('react-react-in-jsx-scope'), - eslintAuditRefMock('react-hooks-rules-of-hooks', 2), - eslintAuditRefMock('react-hooks-exhaustive-deps', 2), - ], - }, - 'code-style': { - slug: 'code-style', - title: 'Code style', - refs: [ - eslintAuditRefMock('no-unused-vars'), - eslintAuditRefMock('arrow-body-style'), - eslintAuditRefMock('camelcase'), - eslintAuditRefMock('curly'), - eslintAuditRefMock('eqeqeq'), - eslintAuditRefMock('max-lines-per-function'), - eslintAuditRefMock('max-lines'), - eslintAuditRefMock('object-shorthand'), - eslintAuditRefMock('prefer-arrow-callback'), - eslintAuditRefMock('prefer-const'), - eslintAuditRefMock('prefer-object-spread'), - eslintAuditRefMock('yoda'), - eslintAuditRefMock('no-var'), - ], - }, -} satisfies Record; - -export type CategorySlug = keyof typeof CATEGORIES_MAP; - -export const CATEGORY_SLUGS = Object.keys(CATEGORIES_MAP) as CategorySlug[]; - -export function categoryConfigMock( - slug: CategorySlug = 'performance', -): CategoryConfig { - return CATEGORIES_MAP[slug]; -} - -export function categoryConfigsMock(): CategoryConfig[] { - return Object.values(JSON.parse(JSON.stringify(CATEGORIES_MAP))); -} diff --git a/testing/test-utils/src/lib/utils/dynamic-mocks/config.mock.ts b/testing/test-utils/src/lib/utils/dynamic-mocks/config.mock.ts deleted file mode 100644 index ee6ea0e06..000000000 --- a/testing/test-utils/src/lib/utils/dynamic-mocks/config.mock.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { - type CoreConfig, - coreConfigSchema, - validate, -} from '@code-pushup/models'; -import { categoryConfigsMock } from './categories.mock.js'; -import { eslintPluginConfigMock } from './eslint-plugin.mock.js'; -import { lighthousePluginConfigMock } from './lighthouse-plugin.mock.js'; -import { persistConfigMock } from './persist-config.mock.js'; -import { auditReportMock, pluginConfigMock } from './plugin-config.mock.js'; - -export function configMock(outputDir = 'tmp'): CoreConfig { - return validate(coreConfigSchema, { - persist: persistConfigMock({ outputDir }), - upload: { - organization: 'code-pushup', - project: 'cli', - apiKey: 'dummy-api-key', - server: 'https://example.com/api', - }, - categories: categoryConfigsMock(), - plugins: [ - eslintPluginConfigMock(outputDir), - lighthousePluginConfigMock(outputDir), - ], - }); -} - -export function minimalConfigMock( - outputDir = 'tmp', -): Omit & Required> { - const PLUGIN_1_SLUG = 'plugin-1'; - const AUDIT_1_SLUG = 'audit-1'; - const outputFile = `${PLUGIN_1_SLUG}.${Date.now()}.json`; - - const cfg = validate(coreConfigSchema, { - persist: persistConfigMock({ outputDir }), - upload: { - organization: 'code-pushup', - project: 'cli', - apiKey: 'dummy-api-key', - server: 'https://example.com/api', - }, - categories: [ - { - slug: 'category-1', - title: 'Category 1', - refs: [ - { - type: 'audit', - plugin: PLUGIN_1_SLUG, - slug: AUDIT_1_SLUG, - weight: 1, - }, - ], - }, - ], - plugins: [ - pluginConfigMock([auditReportMock({ slug: AUDIT_1_SLUG })], { - slug: PLUGIN_1_SLUG, - outputDir, - outputFile, - }), - ], - }); - - return JSON.parse(JSON.stringify(cfg)); -} diff --git a/testing/test-utils/src/lib/utils/dynamic-mocks/eslint-audits.mock.ts b/testing/test-utils/src/lib/utils/dynamic-mocks/eslint-audits.mock.ts deleted file mode 100644 index e6adbf507..000000000 --- a/testing/test-utils/src/lib/utils/dynamic-mocks/eslint-audits.mock.ts +++ /dev/null @@ -1,820 +0,0 @@ -import type { AuditReport } from '@code-pushup/models'; - -export const ESLINT_AUDITS_FIXED_SLUGS: (keyof typeof ESLINT_AUDITS_MAP)[] = [ - 'no-unused-vars', - 'arrow-body-style', - 'eqeqeq', - 'max-lines-per-function', - 'no-shadow', - 'object-shorthand', - 'prefer-const', - 'react-jsx-key', - 'react-hooks-exhaustive-deps', -]; - -export const ESLINT_AUDITS_MAP = { - 'no-cond-assign': { - slug: 'no-cond-assign', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow assignment operators in conditional expressions', - description: 'ESLint rule **no-cond-assign**.', - docsUrl: 'https://eslint.org/docs/latest/rules/no-cond-assign', - }, - 'no-const-assign': { - slug: 'no-const-assign', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow reassigning `const` variables', - description: 'ESLint rule **no-const-assign**.', - docsUrl: 'https://eslint.org/docs/latest/rules/no-const-assign', - }, - 'no-debugger': { - slug: 'no-debugger', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow the use of `debugger`', - description: 'ESLint rule **no-debugger**.', - docsUrl: 'https://eslint.org/docs/latest/rules/no-debugger', - }, - 'no-invalid-regexp': { - slug: 'no-invalid-regexp', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: - 'Disallow invalid regular expression strings in `RegExp` constructors', - description: 'ESLint rule **no-invalid-regexp**.', - docsUrl: 'https://eslint.org/docs/latest/rules/no-invalid-regexp', - }, - 'no-undef': { - slug: 'no-undef', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: - 'Disallow the use of undeclared variables unless mentioned in `/*global */` comments', - description: 'ESLint rule **no-undef**.', - docsUrl: 'https://eslint.org/docs/latest/rules/no-undef', - }, - 'no-unreachable-loop': { - slug: 'no-unreachable-loop', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow loops with a body that allows only one iteration', - description: 'ESLint rule **no-unreachable-loop**.', - docsUrl: 'https://eslint.org/docs/latest/rules/no-unreachable-loop', - }, - 'no-unsafe-negation': { - slug: 'no-unsafe-negation', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow negating the left operand of relational operators', - description: 'ESLint rule **no-unsafe-negation**.', - docsUrl: 'https://eslint.org/docs/latest/rules/no-unsafe-negation', - }, - 'no-unsafe-optional-chaining': { - slug: 'no-unsafe-optional-chaining', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: - 'Disallow use of optional chaining in contexts where the `undefined` value is not allowed', - description: 'ESLint rule **no-unsafe-optional-chaining**.', - docsUrl: 'https://eslint.org/docs/latest/rules/no-unsafe-optional-chaining', - }, - 'no-unused-vars': { - slug: 'no-unused-vars', - displayValue: '1 warning', - value: 1, - score: 0, - details: { - issues: [ - { - message: "'loading' is assigned a value but never used.", - severity: 'warning', - source: { - file: 'src/App.jsx', - position: { - startLine: 8, - startColumn: 11, - endLine: 8, - endColumn: 18, - }, - }, - }, - ], - }, - title: 'Disallow unused variables', - description: 'ESLint rule **no-unused-vars**.', - docsUrl: 'https://eslint.org/docs/latest/rules/no-unused-vars', - }, - 'use-isnan': { - slug: 'use-isnan', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Require calls to `isNaN()` when checking for `NaN`', - description: 'ESLint rule **use-isnan**.', - docsUrl: 'https://eslint.org/docs/latest/rules/use-isnan', - }, - 'valid-typeof': { - slug: 'valid-typeof', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Enforce comparing `typeof` expressions against valid strings', - description: 'ESLint rule **valid-typeof**.', - docsUrl: 'https://eslint.org/docs/latest/rules/valid-typeof', - }, - 'arrow-body-style': { - slug: 'arrow-body-style', - displayValue: '1 warning', - value: 1, - score: 0, - details: { - issues: [ - { - message: - 'Unexpected block statement surrounding arrow body; move the returned value immediately after the `=>`.', - severity: 'warning', - source: { - file: 'src/components/TodoFilter.jsx', - position: { - startLine: 3, - startColumn: 29, - endLine: 25, - endColumn: 2, - }, - }, - }, - ], - }, - title: 'Require braces around arrow function bodies', - description: 'ESLint rule **arrow-body-style**.', - docsUrl: 'https://eslint.org/docs/latest/rules/arrow-body-style', - }, - camelcase: { - slug: 'camelcase', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Enforce camelcase naming convention', - description: 'ESLint rule **camelcase**.', - docsUrl: 'https://eslint.org/docs/latest/rules/camelcase', - }, - curly: { - slug: 'curly', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Enforce consistent brace style for all control statements', - description: 'ESLint rule **curly**.', - docsUrl: 'https://eslint.org/docs/latest/rules/curly', - }, - eqeqeq: { - slug: 'eqeqeq', - displayValue: '1 warning', - value: 1, - score: 0, - details: { - issues: [ - { - message: "Expected '===' and instead saw '=='.", - severity: 'warning', - source: { - file: 'src/hooks/useTodos.js', - position: { - startLine: 41, - startColumn: 41, - endLine: 41, - endColumn: 43, - }, - }, - }, - ], - }, - title: 'Require the use of `===` and `!==`', - description: 'ESLint rule **eqeqeq**.', - docsUrl: 'https://eslint.org/docs/latest/rules/eqeqeq', - }, - 'max-lines-per-function': { - slug: 'max-lines-per-function', - displayValue: '1 warning', - value: 1, - score: 0, - details: { - issues: [ - { - message: - 'Arrow function has too many lines (71). Maximum allowed is 50.', - severity: 'warning', - source: { - file: 'src/hooks/useTodos.js', - position: { - startLine: 3, - startColumn: 25, - endLine: 73, - endColumn: 2, - }, - }, - }, - ], - }, - title: 'Enforce a maximum number of lines of code in a function', - description: 'ESLint rule **max-lines-per-function**.', - docsUrl: 'https://eslint.org/docs/latest/rules/max-lines-per-function', - }, - 'max-lines': { - slug: 'max-lines', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Enforce a maximum number of lines per file', - description: 'ESLint rule **max-lines**.', - docsUrl: 'https://eslint.org/docs/latest/rules/max-lines', - }, - 'no-shadow': { - slug: 'no-shadow', - displayValue: '3 warnings', - value: 3, - score: 0, - details: { - issues: [ - { - message: - "'data' is already declared in the upper scope on line 5 column 10.", - severity: 'warning', - source: { - file: 'src/hooks/useTodos.js', - position: { - startLine: 11, - startColumn: 13, - endLine: 11, - endColumn: 17, - }, - }, - }, - { - message: - "'data' is already declared in the upper scope on line 5 column 10.", - severity: 'warning', - source: { - file: 'src/hooks/useTodos.js', - position: { - startLine: 29, - startColumn: 17, - endLine: 29, - endColumn: 21, - }, - }, - }, - { - message: - "'data' is already declared in the upper scope on line 5 column 10.", - severity: 'warning', - source: { - file: 'src/hooks/useTodos.js', - position: { - startLine: 41, - startColumn: 13, - endLine: 41, - endColumn: 17, - }, - }, - }, - ], - }, - title: - 'Disallow variable declarations from shadowing variables declared in the outer scope', - description: 'ESLint rule **no-shadow**.', - docsUrl: 'https://eslint.org/docs/latest/rules/no-shadow', - }, - 'no-var': { - slug: 'no-var', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Require `let` or `const` instead of `var`', - description: 'ESLint rule **no-var**.', - docsUrl: 'https://eslint.org/docs/latest/rules/no-var', - }, - 'object-shorthand': { - slug: 'object-shorthand', - displayValue: '3 warnings', - value: 3, - score: 0, - details: { - issues: [ - { - message: 'Expected property shorthand.', - severity: 'warning', - source: { - file: 'src/hooks/useTodos.js', - position: { - startLine: 19, - startColumn: 7, - endLine: 19, - endColumn: 19, - }, - }, - }, - { - message: 'Expected property shorthand.', - severity: 'warning', - source: { - file: 'src/hooks/useTodos.js', - position: { - startLine: 32, - startColumn: 13, - endLine: 32, - endColumn: 19, - }, - }, - }, - { - message: 'Expected property shorthand.', - severity: 'warning', - source: { - file: 'src/hooks/useTodos.js', - position: { - startLine: 33, - startColumn: 13, - endLine: 33, - endColumn: 25, - }, - }, - }, - ], - }, - title: - 'Require or disallow method and property shorthand syntax for object literals', - description: 'ESLint rule **object-shorthand**.', - docsUrl: 'https://eslint.org/docs/latest/rules/object-shorthand', - }, - 'prefer-arrow-callback': { - slug: 'prefer-arrow-callback', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Require using arrow functions for callbacks', - description: 'ESLint rule **prefer-arrow-callback**.', - docsUrl: 'https://eslint.org/docs/latest/rules/prefer-arrow-callback', - }, - 'prefer-const': { - slug: 'prefer-const', - displayValue: '1 warning', - value: 1, - score: 0, - details: { - issues: [ - { - message: "'root' is never reassigned. Use 'const' instead.", - severity: 'warning', - source: { - file: 'src/index.jsx', - position: { - startLine: 5, - startColumn: 5, - endLine: 5, - endColumn: 9, - }, - }, - }, - ], - }, - title: - 'Require `const` declarations for variables that are never reassigned after declared', - description: 'ESLint rule **prefer-const**.', - docsUrl: 'https://eslint.org/docs/latest/rules/prefer-const', - }, - 'prefer-object-spread': { - slug: 'prefer-object-spread', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: - 'Disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead', - description: 'ESLint rule **prefer-object-spread**.', - docsUrl: 'https://eslint.org/docs/latest/rules/prefer-object-spread', - }, - yoda: { - slug: 'yoda', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Require or disallow "Yoda" conditions', - description: 'ESLint rule **yoda**.', - docsUrl: 'https://eslint.org/docs/latest/rules/yoda', - }, - 'react-jsx-key': { - slug: 'react-jsx-key', - displayValue: '1 warning', - value: 1, - score: 0, - details: { - issues: [ - { - message: 'Missing "key" prop for element in iterator', - severity: 'warning', - source: { - file: 'src/components/TodoList.jsx', - position: { - startLine: 7, - startColumn: 7, - endLine: 28, - endColumn: 12, - }, - }, - }, - ], - }, - title: 'Disallow missing `key` props in iterators/collection literals', - description: 'ESLint rule **jsx-key**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-key.md', - }, - 'react-prop-types': { - slug: 'react-prop-types', - displayValue: '6 warnings', - value: 6, - score: 0, - details: { - issues: [ - { - message: "'onCreate' is missing in props validation", - severity: 'warning', - source: { - file: 'src/components/CreateTodo.jsx', - position: { - startLine: 15, - startColumn: 15, - endLine: 15, - endColumn: 23, - }, - }, - }, - { - message: "'setQuery' is missing in props validation", - severity: 'warning', - source: { - file: 'src/components/TodoFilter.jsx', - position: { - startLine: 10, - startColumn: 17, - endLine: 10, - endColumn: 25, - }, - }, - }, - { - message: "'setHideComplete' is missing in props validation", - severity: 'warning', - source: { - file: 'src/components/TodoFilter.jsx', - position: { - startLine: 18, - startColumn: 19, - endLine: 18, - endColumn: 34, - }, - }, - }, - { - message: "'todos' is missing in props validation", - severity: 'warning', - source: { - file: 'src/components/TodoList.jsx', - position: { - startLine: 6, - startColumn: 12, - endLine: 6, - endColumn: 17, - }, - }, - }, - { - message: "'todos.map' is missing in props validation", - severity: 'warning', - source: { - file: 'src/components/TodoList.jsx', - position: { - startLine: 6, - startColumn: 18, - endLine: 6, - endColumn: 21, - }, - }, - }, - { - message: "'onEdit' is missing in props validation", - severity: 'warning', - source: { - file: 'src/components/TodoList.jsx', - position: { - startLine: 13, - startColumn: 21, - endLine: 13, - endColumn: 27, - }, - }, - }, - ], - }, - title: 'Disallow missing props validation in a React component definition', - description: 'ESLint rule **prop-types**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/prop-types.md', - }, - 'react-react-in-jsx-scope': { - slug: 'react-react-in-jsx-scope', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow missing React when using JSX', - description: 'ESLint rule **react-in-jsx-scope**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/react-in-jsx-scope.md', - }, - 'react-hooks-rules-of-hooks': { - slug: 'react-hooks-rules-of-hooks', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'enforces the Rules of Hooks', - description: 'ESLint rule **rules-of-hooks**, from _react-hooks_ plugin.', - docsUrl: 'https://reactjs.org/docs/hooks-rules.html', - }, - 'react-hooks-exhaustive-deps': { - slug: 'react-hooks-exhaustive-deps', - displayValue: '2 warnings', - value: 2, - score: 0, - details: { - issues: [ - { - message: - 'React Hook useCallback does nothing when called with only one argument. Did you forget to pass an array of dependencies?', - severity: 'warning', - source: { - file: 'src/hooks/useTodos.js', - position: { - startLine: 17, - startColumn: 20, - endLine: 17, - endColumn: 31, - }, - }, - }, - { - message: - 'React Hook useCallback does nothing when called with only one argument. Did you forget to pass an array of dependencies?', - severity: 'warning', - source: { - file: 'src/hooks/useTodos.js', - position: { - startLine: 40, - startColumn: 18, - endLine: 40, - endColumn: 29, - }, - }, - }, - ], - }, - title: - 'verifies the list of dependencies for Hooks like useEffect and similar', - description: 'ESLint rule **exhaustive-deps**, from _react-hooks_ plugin.', - docsUrl: 'https://github.com/facebook/react/issues/14920', - }, - 'react-display-name': { - slug: 'react-display-name', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow missing displayName in a React component definition', - description: 'ESLint rule **display-name**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/display-name.md', - }, - 'react-jsx-no-comment-textnodes': { - slug: 'react-jsx-no-comment-textnodes', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow comments from being inserted as text nodes', - description: - 'ESLint rule **jsx-no-comment-textnodes**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-no-comment-textnodes.md', - }, - 'react-jsx-no-duplicate-props': { - slug: 'react-jsx-no-duplicate-props', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow duplicate properties in JSX', - description: 'ESLint rule **jsx-no-duplicate-props**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-no-duplicate-props.md', - }, - 'react-jsx-no-target-blank': { - slug: 'react-jsx-no-target-blank', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow `target="_blank"` attribute without `rel="noreferrer"`', - description: 'ESLint rule **jsx-no-target-blank**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-no-target-blank.md', - }, - 'react-jsx-no-undef': { - slug: 'react-jsx-no-undef', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow undeclared variables in JSX', - description: 'ESLint rule **jsx-no-undef**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-no-undef.md', - }, - 'react-jsx-uses-react': { - slug: 'react-jsx-uses-react', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow React to be incorrectly marked as unused', - description: 'ESLint rule **jsx-uses-react**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-uses-react.md', - }, - 'react-jsx-uses-vars': { - slug: 'react-jsx-uses-vars', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow variables used in JSX to be incorrectly marked as unused', - description: 'ESLint rule **jsx-uses-vars**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-uses-vars.md', - }, - 'react-no-children-prop': { - slug: 'react-no-children-prop', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow passing of children as props', - description: 'ESLint rule **no-children-prop**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-children-prop.md', - }, - 'react-no-danger-with-children': { - slug: 'react-no-danger-with-children', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: - 'Disallow when a DOM element is using both children and dangerouslySetInnerHTML', - description: - 'ESLint rule **no-danger-with-children**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-danger-with-children.md', - }, - 'react-no-deprecated': { - slug: 'react-no-deprecated', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow usage of deprecated methods', - description: 'ESLint rule **no-deprecated**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-deprecated.md', - }, - 'react-no-direct-mutation-state': { - slug: 'react-no-direct-mutation-state', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow direct mutation of this.state', - description: - 'ESLint rule **no-direct-mutation-state**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-direct-mutation-state.md', - }, - 'react-no-find-dom-node': { - slug: 'react-no-find-dom-node', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow usage of findDOMNode', - description: 'ESLint rule **no-find-dom-node**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-find-dom-node.md', - }, - 'react-no-is-mounted': { - slug: 'react-no-is-mounted', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow usage of isMounted', - description: 'ESLint rule **no-is-mounted**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-is-mounted.md', - }, - 'react-no-render-return-value': { - slug: 'react-no-render-return-value', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow usage of the return value of ReactDOM.render', - description: 'ESLint rule **no-render-return-value**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-render-return-value.md', - }, - 'react-no-string-refs': { - slug: 'react-no-string-refs', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow using string references', - description: 'ESLint rule **no-string-refs**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-string-refs.md', - }, - 'react-no-unescaped-entities': { - slug: 'react-no-unescaped-entities', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow unescaped HTML entities from appearing in markup', - description: 'ESLint rule **no-unescaped-entities**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-unescaped-entities.md', - }, - 'react-no-unknown-property': { - slug: 'react-no-unknown-property', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Disallow usage of unknown DOM property', - description: 'ESLint rule **no-unknown-property**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/no-unknown-property.md', - }, - 'react-require-render-return': { - slug: 'react-require-render-return', - displayValue: 'passed', - value: 0, - score: 1, - details: { issues: [] }, - title: 'Enforce ES5 or ES6 class for returning value in render function', - description: 'ESLint rule **require-render-return**, from _react_ plugin.', - docsUrl: - 'https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/require-render-return.md', - }, -} satisfies Record; - -export const ESLINT_AUDIT_SLUGS = Object.keys( - ESLINT_AUDITS_MAP, -) as (keyof typeof ESLINT_AUDITS_MAP)[]; diff --git a/testing/test-utils/src/lib/utils/dynamic-mocks/eslint-plugin.mock.ts b/testing/test-utils/src/lib/utils/dynamic-mocks/eslint-plugin.mock.ts deleted file mode 100644 index 672f32fec..000000000 --- a/testing/test-utils/src/lib/utils/dynamic-mocks/eslint-plugin.mock.ts +++ /dev/null @@ -1,103 +0,0 @@ -import path from 'node:path'; -import type { - Audit, - AuditReport, - CategoryRef, - Group, - PluginConfig, - PluginReport, -} from '@code-pushup/models'; -import { - ESLINT_AUDITS_FIXED_SLUGS, - ESLINT_AUDITS_MAP, - ESLINT_AUDIT_SLUGS, -} from './eslint-audits.mock.js'; -import { echoRunnerConfigMock } from './runner-config.mock.js'; - -export const ESLINT_PLUGIN_GROUP_MAX_LINES: Group = { - slug: 'max-line-limitation', - title: 'Maximum lines limitation', - refs: [ - { - slug: ESLINT_AUDITS_MAP['max-lines-per-function'].slug, - weight: 1, - }, - { - slug: ESLINT_AUDITS_MAP['max-lines'].slug, - weight: 1, - }, - ], -}; - -export const ESLINT_PLUGIN_META = { - slug: 'eslint', - title: 'ESLint', - icon: 'eslint', - description: 'Official Code PushUp ESLint plugin', - docsUrl: 'https://www.npmjs.com/package/@code-pushup/eslint-plugin', - packageName: '@code-pushup/eslint-plugin', - version: '0.1.0', -} satisfies Partial; - -export function eslintPluginConfigMock(outputDir = 'tmp'): PluginConfig { - const audits = Object.values(ESLINT_AUDITS_MAP).map( - ({ slug, description, title, docsUrl }) => - ({ - slug, - description, - title, - docsUrl, - }) satisfies Audit, - ); - return { - ...ESLINT_PLUGIN_META, - runner: echoRunnerConfigMock( - Object.values(ESLINT_AUDITS_MAP), - path.join(outputDir, 'eslint-out.json'), - ), - audits, - }; -} - -export function eslintPluginReportMock(): PluginReport { - return { - ...ESLINT_PLUGIN_META, - date: '2023-10-18T07:49:45.531Z', - duration: 368, - audits: Object.values(ESLINT_AUDITS_MAP), - groups: [ESLINT_PLUGIN_GROUP_MAX_LINES], - }; -} -export function eslintPluginReportAltMock(): PluginReport { - return { - ...eslintPluginReportMock(), - date: '2024-03-12T12:42:05.388Z', - duration: 316, - audits: ESLINT_AUDIT_SLUGS.map( - (slug): AuditReport => - ESLINT_AUDITS_FIXED_SLUGS.includes(slug) - ? { - ...ESLINT_AUDITS_MAP[slug], - score: 1, - value: 0, - displayValue: 'passed', - details: { issues: [] }, - } - : ESLINT_AUDITS_MAP[slug], - ), - }; -} - -export type ESLintAuditSlug = keyof typeof ESLINT_AUDITS_MAP; - -export function eslintAuditRefMock( - slug: ESLintAuditSlug, - weight = 1, -): CategoryRef { - return { - type: 'audit', - plugin: 'eslint', - slug, - weight, - }; -} diff --git a/testing/test-utils/src/lib/utils/dynamic-mocks/lighthouse-audits.mock.ts b/testing/test-utils/src/lib/utils/dynamic-mocks/lighthouse-audits.mock.ts deleted file mode 100644 index 2fe262e51..000000000 --- a/testing/test-utils/src/lib/utils/dynamic-mocks/lighthouse-audits.mock.ts +++ /dev/null @@ -1,95 +0,0 @@ -import type { AuditReport } from '@code-pushup/models'; - -export const LIGHTHOUSE_AUDITS_CHANGES: Partial< - Record< - keyof typeof LIGHTHOUSE_AUDITS_MAP, - Pick - > -> = { - 'largest-contentful-paint': { - score: 0.85, - value: 1369, - displayValue: '1.4 s', - }, - 'first-contentful-paint': { - score: 0.79, - value: 1146, - displayValue: '1.1 s', - }, - 'speed-index': { - score: 0.94, - value: 1146, - displayValue: '1.1 s', - }, -}; - -export const LIGHTHOUSE_AUDITS_MAP = { - 'first-contentful-paint': { - slug: 'first-contentful-paint', - title: 'First Contentful Paint', - description: - 'First Contentful Paint marks the time at which the first text or image is painted.', - docsUrl: - 'https://developer.chrome.com/docs/lighthouse/performance/first-contentful-paint/', - score: 0.76, - value: 1189, - displayValue: '1.2 s', - }, - 'largest-contentful-paint': { - slug: 'largest-contentful-paint', - title: 'Largest Contentful Paint', - description: - 'Largest Contentful Paint marks the time at which the largest text or image is painted.', - docsUrl: - 'https://developer.chrome.com/docs/lighthouse/performance/largest-contentful-paint/', - score: 0.81, - value: 1491, - displayValue: '1.5 s', - }, - 'total-blocking-time': { - slug: 'total-blocking-time', - title: 'Total Blocking Time', - description: - 'Sum of all time periods between FCP and Time to Interactive, when task length exceeded 50ms, expressed in milliseconds.', - docsUrl: - 'https://developer.chrome.com/docs/lighthouse/performance/lighthouse-total-blocking-time/', - score: 1, - value: 0, - displayValue: '0 ms', - }, - 'cumulative-layout-shift': { - slug: 'cumulative-layout-shift', - title: 'Cumulative Layout Shift', - description: - 'Cumulative Layout Shift measures the movement of visible elements within the viewport.', - docsUrl: 'https://web.dev/cls/', - score: 1, - value: 0, - displayValue: '0', - }, - 'speed-index': { - slug: 'speed-index', - title: 'Speed Index', - description: - 'Speed Index shows how quickly the contents of a page are visibly populated.', - docsUrl: - 'https://developer.chrome.com/docs/lighthouse/performance/speed-index/', - score: 0.93, - value: 1189, - displayValue: '1.2 s', - }, - 'third-party-summary': { - slug: 'third-party-summary', - title: 'Minimize third-party usage', - description: - 'Third-party code can significantly impact load performance. Limit the number of redundant third-party providers and try to load third-party code after your page has primarily finished loading. [Learn how to minimize third-party impact](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/).', - docsUrl: undefined, - displayValue: 'Third-party code blocked the main thread for 6,850 ms', - value: 0, - score: 0, - }, -} satisfies Record; - -export const LIGHTHOUSE_AUDIT_SLUGS = Object.keys( - LIGHTHOUSE_AUDITS_MAP, -) as (keyof typeof LIGHTHOUSE_AUDITS_MAP)[]; diff --git a/testing/test-utils/src/lib/utils/dynamic-mocks/lighthouse-plugin.mock.ts b/testing/test-utils/src/lib/utils/dynamic-mocks/lighthouse-plugin.mock.ts deleted file mode 100644 index ea3b43edd..000000000 --- a/testing/test-utils/src/lib/utils/dynamic-mocks/lighthouse-plugin.mock.ts +++ /dev/null @@ -1,96 +0,0 @@ -import path from 'node:path'; -import type { - Audit, - AuditReport, - Group, - PluginConfig, - PluginReport, -} from '@code-pushup/models'; -import { - LIGHTHOUSE_AUDITS_CHANGES, - LIGHTHOUSE_AUDITS_MAP, - LIGHTHOUSE_AUDIT_SLUGS, -} from './lighthouse-audits.mock.js'; -import { echoRunnerConfigMock } from './runner-config.mock.js'; - -export const LH_PLUGIN_GROUP_PERFORMANCE: Group = { - slug: 'performance', - title: 'Performance', - refs: [ - { - slug: 'first-contentful-paint', - weight: 10, - }, - { - slug: 'largest-contentful-paint', - weight: 25, - }, - { - slug: 'speed-index', - weight: 10, - }, - { - slug: 'total-blocking-time', - weight: 30, - }, - { - slug: 'cumulative-layout-shift', - weight: 25, - }, - ], -}; - -export const LH_PLUGIN_META: Omit = { - slug: 'lighthouse', - title: 'Lighthouse', - icon: 'lighthouse', - packageName: '@code-pushup/lighthouse-plugin', - version: '0.1.0', -}; - -export function lighthousePluginConfigMock(outputDir = 'tmp'): PluginConfig { - const audits = Object.values(LIGHTHOUSE_AUDITS_MAP).map( - ({ slug, description, title, docsUrl }): Audit => ({ - slug, - description, - title, - docsUrl, - }), - ); - return { - ...LH_PLUGIN_META, - runner: echoRunnerConfigMock( - Object.values(LIGHTHOUSE_AUDITS_MAP), - path.join(outputDir, 'lighthouse-out.json'), - ), - audits, - groups: [LH_PLUGIN_GROUP_PERFORMANCE], - }; -} - -export function lighthousePluginReportMock(): PluginReport { - return { - ...LH_PLUGIN_META, - date: '2023-10-18T07:49:45.899Z', - duration: 1234, - audits: Object.values(LIGHTHOUSE_AUDITS_MAP), - groups: [LH_PLUGIN_GROUP_PERFORMANCE], - }; -} - -export function lighthousePluginReportAltMock(): PluginReport { - return { - ...lighthousePluginReportMock(), - date: '2024-03-12T12:42:05.704Z', - duration: 1212, - audits: LIGHTHOUSE_AUDIT_SLUGS.map( - (slug): AuditReport => - slug in LIGHTHOUSE_AUDITS_CHANGES - ? { - ...LIGHTHOUSE_AUDITS_MAP[slug], - ...LIGHTHOUSE_AUDITS_CHANGES[slug], - } - : LIGHTHOUSE_AUDITS_MAP[slug], - ), - }; -} diff --git a/testing/test-utils/src/lib/utils/dynamic-mocks/persist-config.mock.ts b/testing/test-utils/src/lib/utils/dynamic-mocks/persist-config.mock.ts deleted file mode 100644 index f4537d719..000000000 --- a/testing/test-utils/src/lib/utils/dynamic-mocks/persist-config.mock.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { - DEFAULT_PERSIST_FILENAME, - DEFAULT_PERSIST_FORMAT, - DEFAULT_PERSIST_OUTPUT_DIR, - type PersistConfig, - persistConfigSchema, - validate, -} from '@code-pushup/models'; - -export function persistConfigMock( - opt?: Partial, -): Required { - return validate(persistConfigSchema, { - outputDir: DEFAULT_PERSIST_OUTPUT_DIR, - filename: DEFAULT_PERSIST_FILENAME, - format: DEFAULT_PERSIST_FORMAT, - ...opt, - }) as Required; -} diff --git a/testing/test-utils/src/lib/utils/dynamic-mocks/plugin-config.mock.ts b/testing/test-utils/src/lib/utils/dynamic-mocks/plugin-config.mock.ts deleted file mode 100644 index 0ff24a144..000000000 --- a/testing/test-utils/src/lib/utils/dynamic-mocks/plugin-config.mock.ts +++ /dev/null @@ -1,57 +0,0 @@ -import path from 'node:path'; -import { - type Audit, - type AuditReport, - type PluginConfig, - auditReportSchema, - auditSchema, - pluginConfigSchema, - validate, -} from '@code-pushup/models'; -import { echoRunnerConfigMock } from './runner-config.mock.js'; - -export function pluginConfigMock( - auditOutputs: AuditReport[], - opt?: Partial & { outputDir?: string; outputFile?: string }, -): PluginConfig { - const { outputDir, outputFile } = opt || {}; - const pluginOutputFile = path.join( - outputDir || 'tmp', - outputFile || `out.${Date.now()}.json`, - ); - return validate(pluginConfigSchema, { - slug: 'mock-plugin-slug', - title: 'Plugin Title', - icon: 'nrwl', - description: 'Plugin description', - docsUrl: 'https://my-plugin.docs.dev?1', - audits: auditOutputs.map(auditOutput => auditConfigMock(auditOutput)), - runner: echoRunnerConfigMock(auditOutputs, pluginOutputFile), - ...opt, - }); -} - -export function auditConfigMock(opt?: Partial): Audit { - return validate(auditSchema, { - slug: opt?.slug || 'mock-audit-slug', - title: opt?.title || 'Audit Title', - description: opt?.description || 'audit description', - docsUrl: opt?.docsUrl || 'http://www.my-docs.dev', - }) as Required; -} - -export function auditReportMock(opt?: Partial): AuditReport { - return validate(auditReportSchema, { - slug: 'mock-audit-slug', - title: 'Audit Title', - description: 'audit description', - docsUrl: 'http://www.my-docs.dev', - score: 0, - value: 0, - displayValue: '0x', - details: { - issues: [], - }, - ...opt, - }) as Required; -} diff --git a/testing/test-utils/src/lib/utils/dynamic-mocks/report-diff.mock.ts b/testing/test-utils/src/lib/utils/dynamic-mocks/report-diff.mock.ts deleted file mode 100644 index 9bd8fb100..000000000 --- a/testing/test-utils/src/lib/utils/dynamic-mocks/report-diff.mock.ts +++ /dev/null @@ -1,434 +0,0 @@ -import type { - AuditDiff, - AuditResult, - CategoryDiff, - ReportsDiff, -} from '@code-pushup/models'; -import { COMMIT_ALT_MOCK, COMMIT_MOCK } from '../commit.mock.js'; -import { - CATEGORIES_MAP, - CATEGORY_SLUGS, - type CategorySlug, -} from './categories.mock.js'; -import { - ESLINT_AUDITS_FIXED_SLUGS, - ESLINT_AUDITS_MAP, - ESLINT_AUDIT_SLUGS, -} from './eslint-audits.mock.js'; -import { - ESLINT_PLUGIN_GROUP_MAX_LINES, - ESLINT_PLUGIN_META, - type ESLintAuditSlug, -} from './eslint-plugin.mock.js'; -import { - LIGHTHOUSE_AUDITS_CHANGES, - LIGHTHOUSE_AUDITS_MAP, - LIGHTHOUSE_AUDIT_SLUGS, -} from './lighthouse-audits.mock.js'; -import { - LH_PLUGIN_GROUP_PERFORMANCE, - LH_PLUGIN_META, -} from './lighthouse-plugin.mock.js'; - -export function reportsDiffMock(): ReportsDiff { - return { - commits: { - before: COMMIT_MOCK, - after: COMMIT_ALT_MOCK, - }, - categories: { - changed: CATEGORY_SLUGS.map(slug => { - const category = CATEGORIES_MAP[slug]; - return { - slug, - title: category.title, - ...('docsUrl' in category && { - docsUrl: category.docsUrl, - }), - scores: categoryScores(slug), - }; - }), - unchanged: [], - added: [], - removed: [], - }, - groups: { - changed: [ - { - slug: ESLINT_PLUGIN_GROUP_MAX_LINES.slug, - title: ESLINT_PLUGIN_GROUP_MAX_LINES.title, - plugin: { - slug: ESLINT_PLUGIN_META.slug, - title: ESLINT_PLUGIN_META.title, - docsUrl: ESLINT_PLUGIN_META.docsUrl, - }, - scores: { before: 0.5, after: 1, diff: 0.5 }, - }, - { - slug: LH_PLUGIN_GROUP_PERFORMANCE.slug, - title: LH_PLUGIN_GROUP_PERFORMANCE.title, - plugin: { slug: LH_PLUGIN_META.slug, title: LH_PLUGIN_META.title }, - scores: { before: 0.92, after: 0.94, diff: 0.02 }, - }, - ], - unchanged: [], - added: [], - removed: [], - }, - audits: { - changed: [ - ...ESLINT_AUDITS_FIXED_SLUGS.map( - (slug): AuditDiff => ({ - slug, - title: ESLINT_AUDITS_MAP[slug].title, - docsUrl: ESLINT_AUDITS_MAP[slug].docsUrl, - plugin: { - slug: ESLINT_PLUGIN_META.slug, - title: ESLINT_PLUGIN_META.title, - docsUrl: ESLINT_PLUGIN_META.docsUrl, - }, - scores: toNumberComparison({ - before: ESLINT_AUDITS_MAP[slug].score, - after: 1, - }), - values: toNumberComparison({ - before: ESLINT_AUDITS_MAP[slug].value, - after: 0, - }), - displayValues: { - before: ESLINT_AUDITS_MAP[slug].displayValue, - after: 'passed', - }, - }), - ), - ...LIGHTHOUSE_AUDIT_SLUGS.filter( - slug => slug in LIGHTHOUSE_AUDITS_CHANGES, - ).map( - (slug): AuditDiff => ({ - slug, - title: LIGHTHOUSE_AUDITS_MAP[slug].title, - docsUrl: LIGHTHOUSE_AUDITS_MAP[slug].docsUrl, - plugin: { - slug: LH_PLUGIN_META.slug, - title: LH_PLUGIN_META.title, - }, - scores: toNumberComparison({ - before: LIGHTHOUSE_AUDITS_MAP[slug].score, - after: LIGHTHOUSE_AUDITS_CHANGES[slug]!.score, - }), - values: toNumberComparison({ - before: LIGHTHOUSE_AUDITS_MAP[slug].value, - after: LIGHTHOUSE_AUDITS_CHANGES[slug]!.value, - }), - displayValues: { - before: LIGHTHOUSE_AUDITS_MAP[slug].displayValue, - after: LIGHTHOUSE_AUDITS_CHANGES[slug]!.displayValue, - }, - }), - ), - ], - unchanged: [ - ...ESLINT_AUDIT_SLUGS.filter( - slug => !ESLINT_AUDITS_FIXED_SLUGS.includes(slug), - ).map( - (slug): AuditResult => ({ - slug, - title: ESLINT_AUDITS_MAP[slug].title, - docsUrl: ESLINT_AUDITS_MAP[slug].docsUrl, - plugin: { - slug: ESLINT_PLUGIN_META.slug, - title: ESLINT_PLUGIN_META.title, - docsUrl: ESLINT_PLUGIN_META.docsUrl, - }, - score: ESLINT_AUDITS_MAP[slug].score, - value: ESLINT_AUDITS_MAP[slug].value, - displayValue: ESLINT_AUDITS_MAP[slug].displayValue, - }), - ), - ...LIGHTHOUSE_AUDIT_SLUGS.filter( - slug => !(slug in LIGHTHOUSE_AUDITS_CHANGES), - ).map( - (slug): AuditResult => ({ - slug, - title: LIGHTHOUSE_AUDITS_MAP[slug].title, - docsUrl: LIGHTHOUSE_AUDITS_MAP[slug].docsUrl, - plugin: { slug: LH_PLUGIN_META.slug, title: LH_PLUGIN_META.title }, - score: LIGHTHOUSE_AUDITS_MAP[slug].score, - value: LIGHTHOUSE_AUDITS_MAP[slug].value, - displayValue: LIGHTHOUSE_AUDITS_MAP[slug].displayValue, - }), - ), - ], - added: [], - removed: [], - }, - date: '2024-03-12T17:15:34.831Z', - duration: 105, - packageName: '@code-pushup/core', - version: '1.0.0', - }; -} - -export function reportsDiffAltMock(): ReportsDiff { - const originalDiff = reportsDiffMock(); - return { - ...originalDiff, - categories: { - changed: [ - { - slug: 'performance' satisfies CategorySlug, - title: CATEGORIES_MAP['performance'].title, - scores: { before: 0.92, after: 0.94, diff: 0.02 }, - }, - { - slug: 'bug-prevention' satisfies CategorySlug, - title: CATEGORIES_MAP['bug-prevention'].title, - scores: { before: 0.68, after: 0.6795, diff: -0.0005 }, - }, - ], - unchanged: [ - { - slug: 'code-style' satisfies CategorySlug, - title: CATEGORIES_MAP['code-style'].title, - score: 0.54, - }, - ], - added: [], - removed: [], - }, - groups: { - changed: [ - { - slug: LH_PLUGIN_GROUP_PERFORMANCE.slug, - title: LH_PLUGIN_GROUP_PERFORMANCE.title, - plugin: { slug: LH_PLUGIN_META.slug, title: LH_PLUGIN_META.title }, - scores: { before: 0.92, after: 0.94, diff: 0.02 }, - }, - ], - unchanged: [ - { - slug: ESLINT_PLUGIN_GROUP_MAX_LINES.slug, - title: ESLINT_PLUGIN_GROUP_MAX_LINES.title, - plugin: { - slug: ESLINT_PLUGIN_META.slug, - title: ESLINT_PLUGIN_META.title, - }, - score: 0.5, - }, - ], - added: [], - removed: [], - }, - audits: { - changed: [ - { - slug: 'no-unused-vars' satisfies ESLintAuditSlug, - title: ESLINT_AUDITS_MAP['no-unused-vars'].title, - docsUrl: ESLINT_AUDITS_MAP['no-unused-vars'].docsUrl, - plugin: { - slug: ESLINT_PLUGIN_META.slug, - title: ESLINT_PLUGIN_META.title, - docsUrl: ESLINT_PLUGIN_META.docsUrl, - }, - scores: { before: 1, after: 0, diff: -1 }, - values: { before: 0, after: 1, diff: 1 }, - displayValues: { before: 'passed', after: '1 error' }, - }, - ...originalDiff.audits.changed.filter( - ({ plugin }) => plugin.slug === 'lighthouse', - ), - ], - unchanged: [ - ...ESLINT_AUDIT_SLUGS.filter(slug => slug !== 'no-unused-vars').map( - (slug): AuditResult => ({ - slug, - title: ESLINT_AUDITS_MAP[slug].title, - docsUrl: ESLINT_AUDITS_MAP[slug].docsUrl, - plugin: { - slug: ESLINT_PLUGIN_META.slug, - title: ESLINT_PLUGIN_META.title, - docsUrl: ESLINT_PLUGIN_META.docsUrl, - }, - score: ESLINT_AUDITS_MAP[slug].score, - value: ESLINT_AUDITS_MAP[slug].value, - displayValue: ESLINT_AUDITS_MAP[slug].displayValue, - }), - ), - ...originalDiff.audits.unchanged.filter( - ({ plugin }) => plugin.slug === 'lighthouse', - ), - ], - added: [], - removed: [], - }, - }; -} - -export function reportsDiffUnchangedMock(): ReportsDiff { - return { - ...reportsDiffMock(), - categories: { - changed: [], - unchanged: CATEGORY_SLUGS.map(slug => ({ - slug, - title: CATEGORIES_MAP[slug].title, - score: categoryScores(slug).before, - })), - added: [], - removed: [], - }, - groups: { - changed: [], - unchanged: [ - { - slug: ESLINT_PLUGIN_GROUP_MAX_LINES.slug, - title: ESLINT_PLUGIN_GROUP_MAX_LINES.title, - plugin: { - slug: ESLINT_PLUGIN_META.slug, - title: ESLINT_PLUGIN_META.title, - docsUrl: ESLINT_PLUGIN_META.docsUrl, - }, - score: 0.5, - }, - { - slug: LH_PLUGIN_GROUP_PERFORMANCE.slug, - title: LH_PLUGIN_GROUP_PERFORMANCE.title, - plugin: { slug: LH_PLUGIN_META.slug, title: LH_PLUGIN_META.title }, - score: 0.92, - }, - ], - added: [], - removed: [], - }, - audits: { - changed: [], - unchanged: [ - ...ESLINT_AUDIT_SLUGS.map( - (slug): AuditResult => ({ - slug, - title: ESLINT_AUDITS_MAP[slug].title, - docsUrl: ESLINT_AUDITS_MAP[slug].docsUrl, - plugin: { - slug: ESLINT_PLUGIN_META.slug, - title: ESLINT_PLUGIN_META.title, - docsUrl: ESLINT_PLUGIN_META.docsUrl, - }, - score: ESLINT_AUDITS_MAP[slug].score, - value: ESLINT_AUDITS_MAP[slug].value, - displayValue: ESLINT_AUDITS_MAP[slug].displayValue, - }), - ), - ...LIGHTHOUSE_AUDIT_SLUGS.map( - (slug): AuditResult => ({ - slug, - title: LIGHTHOUSE_AUDITS_MAP[slug].title, - docsUrl: LIGHTHOUSE_AUDITS_MAP[slug].docsUrl, - plugin: { slug: LH_PLUGIN_META.slug, title: LH_PLUGIN_META.title }, - score: LIGHTHOUSE_AUDITS_MAP[slug].score, - value: LIGHTHOUSE_AUDITS_MAP[slug].value, - displayValue: LIGHTHOUSE_AUDITS_MAP[slug].displayValue, - }), - ), - ], - added: [], - removed: [], - }, - }; -} - -export function reportsDiffChangedMock(): ReportsDiff { - const originalDiff = reportsDiffUnchangedMock(); - return { - ...originalDiff, - audits: { - ...originalDiff.audits, - changed: [ - { - slug: 'no-unused-vars' satisfies ESLintAuditSlug, - title: ESLINT_AUDITS_MAP['no-unused-vars'].title, - docsUrl: ESLINT_AUDITS_MAP['no-unused-vars'].docsUrl, - plugin: { - slug: ESLINT_PLUGIN_META.slug, - title: ESLINT_PLUGIN_META.title, - docsUrl: ESLINT_PLUGIN_META.docsUrl, - }, - scores: { before: 0, after: 0, diff: 0 }, - values: { before: 12, after: 10, diff: -2 }, - displayValues: { before: '12 warnings', after: '10 warnings' }, - }, - ], - }, - }; -} - -export function reportsDiffAddedPluginMock(): ReportsDiff { - const originalDiff = reportsDiffAltMock(); - return { - ...originalDiff, - categories: { - ...originalDiff.categories, - changed: originalDiff.categories.changed.filter( - ({ slug }) => slug !== ('performance' satisfies CategorySlug), - ), - added: [ - { - slug: 'performance' satisfies CategorySlug, - title: CATEGORIES_MAP['performance'].title, - score: categoryScores('performance').after, - }, - ], - }, - groups: { - ...originalDiff.groups, - changed: originalDiff.groups.changed.filter( - ({ plugin }) => plugin.slug !== 'lighthouse', - ), - added: originalDiff.groups.changed - .filter(({ plugin }) => plugin.slug === 'lighthouse') - .map(group => ({ - slug: group.slug, - title: group.title, - plugin: group.plugin, - score: group.scores.after, - })), - }, - audits: { - ...originalDiff.audits, - changed: originalDiff.audits.changed.filter( - ({ plugin }) => plugin.slug !== 'lighthouse', - ), - added: originalDiff.audits.changed - .filter(({ plugin }) => plugin.slug === 'lighthouse') - .map(audit => ({ - slug: audit.slug, - title: audit.title, - docsUrl: audit.docsUrl, - plugin: audit.plugin, - score: audit.scores.after, - value: audit.values.after, - displayValue: audit.displayValues.after, - })), - }, - }; -} - -function categoryScores(slug: CategorySlug): CategoryDiff['scores'] { - switch (slug) { - case 'performance': - return { before: 0.92, after: 0.94, diff: 0.02 }; - case 'bug-prevention': - return { before: 0.68, after: 0.95, diff: 0.27 }; - case 'code-style': - return { before: 0.54, after: 1, diff: 0.46 }; - } -} - -function toNumberComparison({ - before, - after, -}: { - before: number; - after: number; -}) { - return { before, after, diff: after - before }; -} diff --git a/testing/test-utils/src/lib/utils/dynamic-mocks/report.mock.ts b/testing/test-utils/src/lib/utils/dynamic-mocks/report.mock.ts deleted file mode 100644 index 69895386c..000000000 --- a/testing/test-utils/src/lib/utils/dynamic-mocks/report.mock.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { Report } from '@code-pushup/models'; -import { COMMIT_ALT_MOCK, COMMIT_MOCK } from '../commit.mock.js'; -import { categoryConfigsMock } from './categories.mock.js'; -import { - eslintPluginReportAltMock, - eslintPluginReportMock, -} from './eslint-plugin.mock.js'; -import { - lighthousePluginReportAltMock, - lighthousePluginReportMock, -} from './lighthouse-plugin.mock.js'; - -export function reportMock(): Report { - return { - packageName: '@code-pushup/core', - version: '0.0.1', - date: '2023-10-18T07:49:45.506Z', - duration: - eslintPluginReportMock().duration + - lighthousePluginReportMock().duration + - 50, - commit: COMMIT_MOCK, - categories: categoryConfigsMock(), - plugins: [eslintPluginReportMock(), lighthousePluginReportMock()], - }; -} - -export function reportAltMock(): Report { - return { - ...reportMock(), - date: '2024-03-12T12:42:05.370Z', - duration: - eslintPluginReportAltMock().duration + - lighthousePluginReportAltMock().duration + - 20, - commit: COMMIT_ALT_MOCK, - plugins: [eslintPluginReportAltMock(), lighthousePluginReportAltMock()], - }; -} diff --git a/testing/test-utils/src/lib/utils/dynamic-mocks/runner-config.mock.ts b/testing/test-utils/src/lib/utils/dynamic-mocks/runner-config.mock.ts deleted file mode 100644 index b6dae5e92..000000000 --- a/testing/test-utils/src/lib/utils/dynamic-mocks/runner-config.mock.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { platform } from 'node:os'; -import { - type AuditOutput, - type RunnerConfig, - runnerConfigSchema, -} from '@code-pushup/models'; - -/** - * Use this helper as a general purpose mock with working defaults - * @param options - */ -export function runnerConfigMock( - options?: Partial, -): RunnerConfig { - const outputFile = `out.${Date.now()}.json`; - return runnerConfigSchema.parse({ - command: 'node', - args: ['-v', '>', outputFile], - outputFile, - ...options, - }); -} - -/** - * Use this helper to mock the output data of a plugin synchronously - * - * @param output - * @param outputFile - */ -export function echoRunnerConfigMock( - output: AuditOutput[], - outputFile: string, -): RunnerConfig { - const auditOutput = - platform() === 'win32' - ? JSON.stringify(output) - : `'${JSON.stringify(output)}'`; - return { - command: 'echo', - args: [auditOutput, '>', outputFile], - outputFile, - }; -} diff --git a/testing/test-utils/src/lib/utils/dynamic-mocks/upload-config.mock.ts b/testing/test-utils/src/lib/utils/dynamic-mocks/upload-config.mock.ts deleted file mode 100644 index 2cd3924a0..000000000 --- a/testing/test-utils/src/lib/utils/dynamic-mocks/upload-config.mock.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { - type UploadConfig, - uploadConfigSchema, - validate, -} from '@code-pushup/models'; - -export function uploadConfig(opt?: Partial): UploadConfig { - return validate(uploadConfigSchema, { - apiKey: 'm0ck-API-k3y', - server: 'http://test.server.io', - organization: 'code-pushup', - project: 'cli', - ...opt, - }); -} diff --git a/testing/test-utils/src/lib/utils/minimal-config.mock.ts b/testing/test-utils/src/lib/utils/minimal-config.mock.ts deleted file mode 100644 index 8416632d4..000000000 --- a/testing/test-utils/src/lib/utils/minimal-config.mock.ts +++ /dev/null @@ -1,60 +0,0 @@ -import type { - AuditOutput, - CoreConfig, - PluginConfig, - RunnerConfig, - RunnerFunction, -} from '@code-pushup/models'; - -// Note: In order for the runner to not expect an actual file, set up fs mocks -// Then add output.json to the in-memory file system and customise content as needed -export const MINIMAL_RUNNER_CONFIG_MOCK: RunnerConfig = { - command: 'node', - args: ['-v'], - outputFile: 'output.json', -}; - -export const MINIMAL_RUNNER_FUNCTION_MOCK: RunnerFunction = () => [ - { - slug: 'node-version', - score: 0.3, - value: 16, - displayValue: '16.0.0', - details: { - issues: [ - { - severity: 'error', - message: 'The required Node version to run Code PushUp CLI is 18.', - }, - ], - }, - } satisfies AuditOutput, -]; - -export const MINIMAL_PLUGIN_CONFIG_MOCK: PluginConfig = { - slug: 'node', - title: 'Node', - icon: 'javascript', - audits: [ - { - slug: 'node-version', - title: 'Node version', - description: 'Returns node version', - docsUrl: 'https://nodejs.org/', - }, - ], - runner: MINIMAL_RUNNER_FUNCTION_MOCK, -}; - -export const MINIMAL_CONFIG_MOCK: CoreConfig = { - plugins: [MINIMAL_PLUGIN_CONFIG_MOCK], -}; - -export const MINIMAL_HISTORY_CONFIG_MOCK: CoreConfig = { - persist: { - outputDir: '.code-pushup', - filename: 'history-report', - format: ['json'], - }, - plugins: [MINIMAL_PLUGIN_CONFIG_MOCK], -}; diff --git a/testing/test-utils/src/lib/utils/omit-report-data.ts b/testing/test-utils/src/lib/utils/omit-report-data.ts deleted file mode 100644 index 26b6f959b..000000000 --- a/testing/test-utils/src/lib/utils/omit-report-data.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { - AuditOutput, - AuditReport, - PluginReport, - Report, -} from '@code-pushup/models'; - -export function omitVariableAuditData({ - score: _, - value: __, - displayValue: ___, - details: ____, - ...auditReport -}: AuditReport | AuditOutput) { - return auditReport; -} - -export function omitVariablePluginData( - { date: _, duration: __, version: ___, ...pluginReport }: PluginReport, - options?: { - omitAuditData: boolean; - }, -) { - const { omitAuditData } = options ?? {}; - if (omitAuditData) { - return { - ...pluginReport, - audits: pluginReport.audits.map(omitVariableAuditData), - }; - } - return pluginReport; -} - -export function omitVariableReportData( - { commit: _, date: __, duration: ___, version: ____, ...report }: Report, - options?: { - omitAuditData: boolean; - }, -) { - return { - ...report, - plugins: report.plugins.map(plugin => - omitVariablePluginData(plugin, options), - ), - }; -} diff --git a/testing/test-utils/src/lib/utils/os-agnostic-paths.ts b/testing/test-utils/src/lib/utils/os-agnostic-paths.ts index 9dd00fb5e..750432418 100644 --- a/testing/test-utils/src/lib/utils/os-agnostic-paths.ts +++ b/testing/test-utils/src/lib/utils/os-agnostic-paths.ts @@ -1,5 +1,3 @@ -import type { AuditOutput, AuditReport } from '@code-pushup/models'; - const AGNOSTIC_PATH_SEP_REGEX = /[/\\]/g; const OS_AGNOSTIC_PATH_SEP = '/'; const OS_AGNOSTIC_CWD = ``; @@ -95,39 +93,3 @@ export function osAgnosticPath(filePath?: string): string | undefined { // path is segment (my-folder/my-file.ts or my-folder/sub-folder) return osAgnosticPathWithoutCwd; } - -export function osAgnosticAudit( - audit: T, - transformMessage: (message: string) => string = s => s, -): T { - const { issues = [] } = audit.details ?? {}; - if (issues.every(({ source }) => source == null)) { - return audit; - } - return { - ...audit, - details: { - issues: issues.map(issue => - issue.source == null - ? issue - : { - ...issue, - source: { - ...issue.source, - file: osAgnosticPath(issue.source.file), - }, - message: transformMessage(issue.message), - }, - ), - }, - }; -} - -export function osAgnosticAuditOutputs( - audits: T[], - transformAuditIssueMessage?: (message: string) => string, -): T[] { - return audits.map(audit => - osAgnosticAudit(audit, transformAuditIssueMessage), - ); -} diff --git a/testing/test-utils/src/lib/utils/report.mock.ts b/testing/test-utils/src/lib/utils/report.mock.ts deleted file mode 100644 index 3b2020ee6..000000000 --- a/testing/test-utils/src/lib/utils/report.mock.ts +++ /dev/null @@ -1,299 +0,0 @@ -import type { PluginConfig, PluginReport, Report } from '@code-pushup/models'; -import { COMMIT_MOCK } from './commit.mock.js'; -import { - auditReportMock, - pluginConfigMock, -} from './dynamic-mocks/plugin-config.mock.js'; - -export const MINIMAL_REPORT_MOCK: Report = { - packageName: '@code-pushup/core', - version: '0.0.1', - date: '2023-08-16T09:00:00.000Z', - duration: 666, - commit: COMMIT_MOCK, - plugins: [ - { - slug: 'eslint', - title: 'ESLint', - icon: 'eslint', - audits: [ - { - slug: 'no-any', - title: 'No any type.', - value: 1, - score: 0, - }, - ], - date: '2023-08-16T09:00:00.000Z', - duration: 420, - }, - ], -}; - -export const REPORT_MOCK: Report = { - packageName: '@code-pushup/core', - version: '1.0.0', - date: '2023-08-16T09:00:00.000Z', - duration: 666, - commit: COMMIT_MOCK, - categories: [ - { - slug: 'test-results', - title: 'Test results', - refs: [ - { - type: 'audit', - slug: 'cypress-component-tests', - plugin: 'cypress', - weight: 1, - }, - { - type: 'audit', - slug: 'cypress-e2e-tests', - plugin: 'cypress', - weight: 3, - }, - ], - }, - { - slug: 'bug-prevention', - title: 'Bug prevention', - refs: [ - { - type: 'group', - slug: 'typescript-eslint-extra', - plugin: 'eslint', - weight: 0, - }, - { - type: 'audit', - slug: 'eslint-functional', - plugin: 'eslint', - weight: 1, - }, - - { - type: 'group', - slug: 'typescript-eslint', - plugin: 'eslint', - weight: 8, - }, - { - type: 'audit', - slug: 'eslint-jest-consistent-naming', - plugin: 'eslint', - weight: 1, - }, - { - type: 'audit', - slug: 'eslint-cypress', - plugin: 'eslint', - weight: 0, - }, - ], - }, - ], - plugins: [ - { - slug: 'cypress', - title: 'Cypress results', - date: '2023-08-16T09:00:00.000Z', - duration: 42, - icon: 'cypress', - audits: [ - { - slug: 'cypress-component-tests', - title: 'Cypress component tests', - value: 0, - score: 1, - }, - { - slug: 'cypress-e2e-tests', - title: 'Cypress e2e tests', - value: 3, - score: 0.5, - details: { - issues: [ - { - message: 'Test `Display progress for selected commit` failed.', - severity: 'error', - }, - { - message: 'Test `Sort audit table based on value` failed.', - severity: 'error', - }, - { - message: 'Test `Open Bug prevention category detail` failed.', - severity: 'error', - }, - ], - }, - }, - ], - }, - { - slug: 'eslint', - title: 'ESLint', - date: '2023-08-16T09:00:00.000Z', - duration: 624, - icon: 'eslint', - groups: [ - { - slug: 'typescript-eslint', - title: 'TypeScript ESLint', - refs: [ - { - slug: 'typescript-eslint-typing', - weight: 3, - }, - { - slug: 'typescript-eslint-enums', - weight: 1, - }, - { - slug: 'typescript-eslint-experimental', - weight: 0, - }, - ], - }, - { - slug: 'typescript-eslint-extra', - title: 'TypeScript ESLint Extra', - refs: [ - { - slug: 'typescript-eslint-experimental', - weight: 1, - }, - ], - }, - ], - audits: [ - { - slug: 'eslint-cypress', - title: 'Cypress rules', - value: 0, - score: 1, - }, - { - slug: 'typescript-eslint-typing', - title: 'Type checking', - value: 2, - score: 0, - details: { - issues: [ - { - message: 'command might be undefined', - severity: 'warning', - source: { - file: 'packages/cli/cli.ts', - position: { - startLine: 5, - startColumn: 10, - endLine: 5, - endColumn: 20, - }, - }, - }, - { - message: 'outputFile does not exist in type Cli', - severity: 'error', - source: { - file: 'packages/cli/cli.ts', - position: { - startLine: 1, - startColumn: 1, - endLine: 5, - endColumn: 10, - }, - }, - }, - ], - }, - }, - { - slug: 'typescript-eslint-enums', - title: 'Enumeration value checks', - value: 0, - score: 1, - }, - { - slug: 'typescript-eslint-experimental', - title: 'TypeScript experimental checks', - value: 1, - score: 0, - details: { - issues: [{ message: 'Use better-enums.', severity: 'info' }], - }, - }, - { - slug: 'eslint-functional', - title: 'Functional principles', - value: 1, - score: 0, - details: { - issues: [ - { - message: 'Unexpected let, use const instead.', - severity: 'error', - source: { - file: 'packages/core/report.ts', - }, - }, - ], - }, - }, - { - slug: 'eslint-jest-consistent-naming', - title: 'Consistent naming', - value: 0, - score: 1, - }, - ], - }, - ], -}; - -export function minimalReportMock(outputDir = 'tmp'): Report { - const PLUGIN_1_SLUG = 'plugin-1'; - const AUDIT_1_SLUG = 'audit-1'; - - const plg1: PluginConfig = pluginConfigMock([], { - slug: PLUGIN_1_SLUG, - outputDir, - }); - - const { runner: _, ...rest } = plg1; - const pluginReport: PluginReport = { - ...rest, - duration: 0, - date: 'dummy-data-string', - version: '', - packageName: '', - audits: [auditReportMock({ slug: AUDIT_1_SLUG })], - }; - - return JSON.parse( - JSON.stringify({ - packageName: '@code-pushup/core', - version: '0.1.0', - date: 'today', - commit: null, - duration: 42, - categories: [ - { - slug: 'category-1', - title: 'Category 1', - refs: [ - { - type: 'audit', - plugin: PLUGIN_1_SLUG, - slug: AUDIT_1_SLUG, - weight: 1, - }, - ], - }, - ], - plugins: [pluginReport], - } satisfies Report), - ); -} diff --git a/tsconfig.base.json b/tsconfig.base.json index ac98b47ed..6c548ac08 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -38,6 +38,7 @@ ], "@code-pushup/models": ["packages/models/src/index.ts"], "@code-pushup/nx-plugin": ["packages/nx-plugin/src/index.ts"], + "@code-pushup/test-fixtures": ["testing/test-fixtures/src/index.ts"], "@code-pushup/test-nx-utils": ["testing/test-nx-utils/src/index.ts"], "@code-pushup/test-setup": ["testing/test-setup/src/index.ts"], "@code-pushup/test-setup-config": [ From 7df610119c4f552bdfae74e9c46b2d9d8860cdcb Mon Sep 17 00:00:00 2001 From: John Doe Date: Sat, 6 Dec 2025 14:46:21 +0100 Subject: [PATCH 05/13] refactor: remove references to utils fron test-nx-utils --- testing/test-nx-utils/project.json | 3 ++- testing/test-nx-utils/vitest.int.config.ts | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 testing/test-nx-utils/vitest.int.config.ts diff --git a/testing/test-nx-utils/project.json b/testing/test-nx-utils/project.json index d76cad67e..c7e5d39dc 100644 --- a/testing/test-nx-utils/project.json +++ b/testing/test-nx-utils/project.json @@ -6,7 +6,8 @@ "targets": { "build": {}, "lint": {}, - "unit-test": {} + "unit-test": {}, + "int-test": {} }, "tags": ["scope:shared", "type:testing"] } diff --git a/testing/test-nx-utils/vitest.int.config.ts b/testing/test-nx-utils/vitest.int.config.ts new file mode 100644 index 000000000..d08636f48 --- /dev/null +++ b/testing/test-nx-utils/vitest.int.config.ts @@ -0,0 +1,3 @@ +import { createIntTestConfig } from '../test-setup-config/src/index.js'; + +export default createIntTestConfig('test-nx-utils'); From 768ca497d5f83a90e3f7c52684608dafeeb78b46 Mon Sep 17 00:00:00 2001 From: John Doe Date: Sat, 6 Dec 2025 14:46:34 +0100 Subject: [PATCH 06/13] refactor: add int-test target to test-nx-utils --- testing/test-nx-utils/src/lib/utils/nx.ts | 26 ++++++++++++++----- .../src/lib/utils/tree.int.test.ts | 8 +++--- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/testing/test-nx-utils/src/lib/utils/nx.ts b/testing/test-nx-utils/src/lib/utils/nx.ts index 050bdc541..823169dec 100644 --- a/testing/test-nx-utils/src/lib/utils/nx.ts +++ b/testing/test-nx-utils/src/lib/utils/nx.ts @@ -9,9 +9,12 @@ import { } from '@nx/devkit'; import { libraryGenerator } from '@nx/js'; import type { LibraryGeneratorSchema } from '@nx/js/src/generators/library/schema'; +import { execFile } from 'node:child_process'; import path from 'node:path'; +import { promisify } from 'node:util'; import { createTreeWithEmptyWorkspace } from 'nx/src/generators/testing-utils/create-tree-with-empty-workspace'; -import { executeProcess } from '@code-pushup/utils'; + +const execFileAsync = promisify(execFile); export function executorContext< T extends { projectName: string; cwd?: string }, @@ -82,11 +85,20 @@ export async function nxShowProjectJson( cwd: string, project: string, ) { - const { code, stderr, stdout } = await executeProcess({ - command: 'npx', - args: ['nx', 'show', `project --json ${project}`], - cwd, - }); + try { + const { stdout, stderr } = await execFileAsync( + 'npx', + ['nx', 'show', 'project', project, '--json'], + { cwd }, + ); - return { code, stderr, projectJson: JSON.parse(stdout) as T }; + return { code: 0, stderr, projectJson: JSON.parse(stdout) as T }; + } catch (error) { + const execError = error as { code?: number; stderr?: string }; + return { + code: execError.code ?? 1, + stderr: execError.stderr ?? String(error), + projectJson: {} as T, + }; + } } diff --git a/testing/test-nx-utils/src/lib/utils/tree.int.test.ts b/testing/test-nx-utils/src/lib/utils/tree.int.test.ts index 0e06aabf6..4223540be 100644 --- a/testing/test-nx-utils/src/lib/utils/tree.int.test.ts +++ b/testing/test-nx-utils/src/lib/utils/tree.int.test.ts @@ -1,7 +1,7 @@ +import { readFile } from 'node:fs/promises'; import path from 'node:path'; import { createTreeWithEmptyWorkspace } from 'nx/src/generators/testing-utils/create-tree-with-empty-workspace'; import { describe, expect, it } from 'vitest'; -import { readJsonFile } from '@code-pushup/utils'; import { materializeTree } from './tree.js'; describe('materializeTree', () => { @@ -14,8 +14,10 @@ describe('materializeTree', () => { expect(tree.exists('nx.json')).toBe(true); await materializeTree(tree, root); - - await expect(readJsonFile(path.join(root, 'nx.json'))).resolves.toEqual({ + const nxJson = JSON.parse( + await readFile(path.join(root, 'nx.json'), 'utf-8'), + ); + expect(nxJson).toStrictEqual({ affected: { defaultBase: 'main', }, From 9cba9fc80e68865f1c7396a32fbae4bb8a869170 Mon Sep 17 00:00:00 2001 From: John Doe Date: Wed, 10 Dec 2025 18:41:41 +0100 Subject: [PATCH 07/13] refactor: wip --- e2e/plugin-axe-e2e/tests/collect.e2e.test.ts | 2 +- e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts | 2 +- e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts | 2 +- e2e/plugin-jsdocs-e2e/tests/collect.e2e.test.ts | 2 +- e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts | 2 +- e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts | 6 ++++-- .../src/lib/runner/lcov/lcov-runner.int.test.ts | 2 +- packages/plugin-eslint/src/lib/runner.int.test.ts | 2 +- .../plugin-typescript/src/lib/runner/runner.int.test.ts | 2 +- testing/test-fixtures/src/index.ts | 1 + testing/test-nx-utils/src/lib/utils/nx.ts | 2 +- testing/test-nx-utils/src/lib/utils/tree.int.test.ts | 2 +- testing/test-nx-utils/tsconfig.test.json | 7 ++++++- 13 files changed, 21 insertions(+), 13 deletions(-) diff --git a/e2e/plugin-axe-e2e/tests/collect.e2e.test.ts b/e2e/plugin-axe-e2e/tests/collect.e2e.test.ts index 2d663c1d7..a128c9b47 100644 --- a/e2e/plugin-axe-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-axe-e2e/tests/collect.e2e.test.ts @@ -2,11 +2,11 @@ import { cp } from 'node:fs/promises'; import path from 'node:path'; import { afterAll, beforeAll, describe, expect, it } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; +import { omitVariableReportData } from '@code-pushup/test-fixtures'; import { nxTargetProject } from '@code-pushup/test-nx-utils'; import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR, - omitVariableReportData, teardownTestFolder, } from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; diff --git a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts index 3f36c3a22..31bd9850f 100644 --- a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts @@ -3,12 +3,12 @@ import path from 'node:path'; import { simpleGit } from 'simple-git'; import { afterAll, afterEach, beforeAll } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; +import { omitVariableReportData } from '@code-pushup/test-fixtures'; import { nxTargetProject } from '@code-pushup/test-nx-utils'; import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR, initGitRepo, - omitVariableReportData, restoreNxIgnoredFiles, teardownTestFolder, } from '@code-pushup/test-utils'; diff --git a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts index a2e20bd54..e0931f92f 100644 --- a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts @@ -2,11 +2,11 @@ import { cp } from 'node:fs/promises'; import path from 'node:path'; import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; +import { omitVariableReportData } from '@code-pushup/test-fixtures'; import { nxTargetProject } from '@code-pushup/test-nx-utils'; import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR, - omitVariableReportData, restoreNxIgnoredFiles, teardownTestFolder, } from '@code-pushup/test-utils'; diff --git a/e2e/plugin-jsdocs-e2e/tests/collect.e2e.test.ts b/e2e/plugin-jsdocs-e2e/tests/collect.e2e.test.ts index 4b9bdc492..09c6f6113 100644 --- a/e2e/plugin-jsdocs-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-jsdocs-e2e/tests/collect.e2e.test.ts @@ -3,12 +3,12 @@ import path from 'node:path'; import { simpleGit } from 'simple-git'; import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; +import { omitVariableReportData } from '@code-pushup/test-fixtures'; import { nxTargetProject } from '@code-pushup/test-nx-utils'; import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR, initGitRepo, - omitVariableReportData, restoreNxIgnoredFiles, teardownTestFolder, } from '@code-pushup/test-utils'; diff --git a/e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts b/e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts index 85c734c0c..5bd1db014 100644 --- a/e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts @@ -2,11 +2,11 @@ import { cp } from 'node:fs/promises'; import path from 'node:path'; import { afterAll, beforeAll, expect } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; +import { omitVariableReportData } from '@code-pushup/test-fixtures'; import { nxTargetProject } from '@code-pushup/test-nx-utils'; import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR, - omitVariableReportData, restoreNxIgnoredFiles, teardownTestFolder, } from '@code-pushup/test-utils'; diff --git a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts index b92e53153..00df879ad 100644 --- a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts @@ -2,12 +2,14 @@ import { cp } from 'node:fs/promises'; import path from 'node:path'; import { afterAll, beforeAll, expect } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; +import { + omitVariableReportData, + osAgnosticAuditOutputs, +} from '@code-pushup/test-fixtures'; import { nxTargetProject } from '@code-pushup/test-nx-utils'; import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR, - omitVariableReportData, - osAgnosticAuditOutputs, osAgnosticPath, restoreNxIgnoredFiles, teardownTestFolder, diff --git a/packages/plugin-coverage/src/lib/runner/lcov/lcov-runner.int.test.ts b/packages/plugin-coverage/src/lib/runner/lcov/lcov-runner.int.test.ts index 0478e1043..412bffa1f 100644 --- a/packages/plugin-coverage/src/lib/runner/lcov/lcov-runner.int.test.ts +++ b/packages/plugin-coverage/src/lib/runner/lcov/lcov-runner.int.test.ts @@ -1,7 +1,7 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { describe, expect, it } from 'vitest'; -import { osAgnosticAuditOutputs } from '@code-pushup/test-utils'; +import { osAgnosticAuditOutputs } from '@code-pushup/test-fixtures'; import { lcovResultsToAuditOutputs } from './lcov-runner.js'; describe('lcovResultsToAuditOutputs', () => { diff --git a/packages/plugin-eslint/src/lib/runner.int.test.ts b/packages/plugin-eslint/src/lib/runner.int.test.ts index a8c3f4a25..2dc0824e9 100644 --- a/packages/plugin-eslint/src/lib/runner.int.test.ts +++ b/packages/plugin-eslint/src/lib/runner.int.test.ts @@ -11,8 +11,8 @@ import { DEFAULT_PERSIST_CONFIG, type Issue, } from '@code-pushup/models'; +import { osAgnosticAuditOutputs } from '@code-pushup/test-fixtures'; import { - osAgnosticAuditOutputs, restoreNxIgnoredFiles, teardownTestFolder, } from '@code-pushup/test-utils'; diff --git a/packages/plugin-typescript/src/lib/runner/runner.int.test.ts b/packages/plugin-typescript/src/lib/runner/runner.int.test.ts index eb4e41683..75dac6549 100644 --- a/packages/plugin-typescript/src/lib/runner/runner.int.test.ts +++ b/packages/plugin-typescript/src/lib/runner/runner.int.test.ts @@ -1,6 +1,6 @@ import { describe, expect } from 'vitest'; import type { AuditOutputs } from '@code-pushup/models'; -import { osAgnosticAuditOutputs } from '@code-pushup/test-utils'; +import { osAgnosticAuditOutputs } from '@code-pushup/test-fixtures'; import { getAudits } from '../utils.js'; import { createRunnerFunction } from './runner.js'; diff --git a/testing/test-fixtures/src/index.ts b/testing/test-fixtures/src/index.ts index 8c9102eda..869b9e3da 100644 --- a/testing/test-fixtures/src/index.ts +++ b/testing/test-fixtures/src/index.ts @@ -1,4 +1,5 @@ export * from './lib/utils/omit-report-data.js'; +export * from './lib/utils/os-agnostic.js'; // static mocks export * from './lib/utils/commit.mock.js'; diff --git a/testing/test-nx-utils/src/lib/utils/nx.ts b/testing/test-nx-utils/src/lib/utils/nx.ts index 823169dec..baa0c0f13 100644 --- a/testing/test-nx-utils/src/lib/utils/nx.ts +++ b/testing/test-nx-utils/src/lib/utils/nx.ts @@ -98,7 +98,7 @@ export async function nxShowProjectJson( return { code: execError.code ?? 1, stderr: execError.stderr ?? String(error), - projectJson: {} as T, + projectJson: { name: project, root: '' } as T, }; } } diff --git a/testing/test-nx-utils/src/lib/utils/tree.int.test.ts b/testing/test-nx-utils/src/lib/utils/tree.int.test.ts index 4223540be..202f24a91 100644 --- a/testing/test-nx-utils/src/lib/utils/tree.int.test.ts +++ b/testing/test-nx-utils/src/lib/utils/tree.int.test.ts @@ -15,7 +15,7 @@ describe('materializeTree', () => { await materializeTree(tree, root); const nxJson = JSON.parse( - await readFile(path.join(root, 'nx.json'), 'utf-8'), + await readFile(path.join(root, 'nx.json'), 'utf8'), ); expect(nxJson).toStrictEqual({ affected: { diff --git a/testing/test-nx-utils/tsconfig.test.json b/testing/test-nx-utils/tsconfig.test.json index cafb05dd2..44ccaf163 100644 --- a/testing/test-nx-utils/tsconfig.test.json +++ b/testing/test-nx-utils/tsconfig.test.json @@ -4,5 +4,10 @@ "outDir": "../../dist/out-tsc", "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"] }, - "include": ["vitest.unit.config.ts", "src/**/*.unit.test.ts"] + "include": [ + "vitest.unit.config.ts", + "vitest.int.config.ts", + "src/**/*.unit.test.ts", + "src/**/*.int.test.ts" + ] } From 3ee7ccfbe6714158b85b37afdb206fec8b205fc7 Mon Sep 17 00:00:00 2001 From: John Doe Date: Wed, 10 Dec 2025 18:41:58 +0100 Subject: [PATCH 08/13] refactor: format code --- testing/test-nx-utils/src/lib/utils/nx.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/test-nx-utils/src/lib/utils/nx.ts b/testing/test-nx-utils/src/lib/utils/nx.ts index baa0c0f13..e505cbaad 100644 --- a/testing/test-nx-utils/src/lib/utils/nx.ts +++ b/testing/test-nx-utils/src/lib/utils/nx.ts @@ -95,10 +95,11 @@ export async function nxShowProjectJson( return { code: 0, stderr, projectJson: JSON.parse(stdout) as T }; } catch (error) { const execError = error as { code?: number; stderr?: string }; + const fallbackProject: T = { name: project, root: '' } as T; return { code: execError.code ?? 1, stderr: execError.stderr ?? String(error), - projectJson: { name: project, root: '' } as T, + projectJson: fallbackProject, }; } } From 0af60f1ac502f151ba9f54e0797d7450e35a6cef Mon Sep 17 00:00:00 2001 From: John Doe Date: Wed, 10 Dec 2025 18:42:51 +0100 Subject: [PATCH 09/13] refactor: wip --- testing/test-nx-utils/src/lib/utils/nx.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/test-nx-utils/src/lib/utils/nx.ts b/testing/test-nx-utils/src/lib/utils/nx.ts index e505cbaad..db4f5ef3e 100644 --- a/testing/test-nx-utils/src/lib/utils/nx.ts +++ b/testing/test-nx-utils/src/lib/utils/nx.ts @@ -95,11 +95,11 @@ export async function nxShowProjectJson( return { code: 0, stderr, projectJson: JSON.parse(stdout) as T }; } catch (error) { const execError = error as { code?: number; stderr?: string }; - const fallbackProject: T = { name: project, root: '' } as T; + const fallbackProject = { name: project, root: '' }; return { code: execError.code ?? 1, stderr: execError.stderr ?? String(error), - projectJson: fallbackProject, + projectJson: fallbackProject as T, }; } } From 3cc3449212e11db507dd634dbc8f4c8867572331 Mon Sep 17 00:00:00 2001 From: John Doe Date: Wed, 10 Dec 2025 19:12:42 +0100 Subject: [PATCH 10/13] refactor: fix docs --- testing/test-fixtures/README.md | 13 ++++--------- testing/test-utils/README.md | 15 +-------------- 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/testing/test-fixtures/README.md b/testing/test-fixtures/README.md index e17ac2a87..487f8f4a9 100644 --- a/testing/test-fixtures/README.md +++ b/testing/test-fixtures/README.md @@ -1,19 +1,14 @@ -# test-utils +# test-fixtures -This library contains testing utilities, such as helper functions or fixtures. -Any reusable mocks should live here. +This library contains testing fixtures. -More on this subject as well as all the testing strategy principles can be found on the GitHub [wiki](https://github.com/code-pushup/cli/wiki/Testing-Strategy#testing-utilities). - -## Library utilities - -### Mock data +## Mock data Hardcoded mocks, often referring to a smaller configuration object, live in [`utils`](./src/lib/utils/). Dynamic mocks (functions that accept objects), referring to a bigger example of a configuration and report object, live in [`dynamic-mocks`](./src/lib/utils/dynamic-mocks/). Please prefer using static mocks over dynamic ones for better readability. Dynamic mocks to be used with care when testing a snapshot after report generation or similar. -### Fixtures +## Fixtures Example configuration files that are to be used in integration or E2E tests live in [`configs`](./src//lib/fixtures/configs/). diff --git a/testing/test-utils/README.md b/testing/test-utils/README.md index e17ac2a87..23cabe3ae 100644 --- a/testing/test-utils/README.md +++ b/testing/test-utils/README.md @@ -1,19 +1,6 @@ # test-utils -This library contains testing utilities, such as helper functions or fixtures. +This library contains testing utilities, such as helper functions. Any reusable mocks should live here. More on this subject as well as all the testing strategy principles can be found on the GitHub [wiki](https://github.com/code-pushup/cli/wiki/Testing-Strategy#testing-utilities). - -## Library utilities - -### Mock data - -Hardcoded mocks, often referring to a smaller configuration object, live in [`utils`](./src/lib/utils/). -Dynamic mocks (functions that accept objects), referring to a bigger example of a configuration and report object, live in [`dynamic-mocks`](./src/lib/utils/dynamic-mocks/). - -Please prefer using static mocks over dynamic ones for better readability. Dynamic mocks to be used with care when testing a snapshot after report generation or similar. - -### Fixtures - -Example configuration files that are to be used in integration or E2E tests live in [`configs`](./src//lib/fixtures/configs/). From a02907da3f241b1ba1f675babf0a236e28db26a7 Mon Sep 17 00:00:00 2001 From: John Doe Date: Wed, 10 Dec 2025 19:13:57 +0100 Subject: [PATCH 11/13] refactor: fix project setup --- testing/test-fixtures/package.json | 4 ---- testing/test-fixtures/project.json | 1 - 2 files changed, 5 deletions(-) delete mode 100644 testing/test-fixtures/package.json diff --git a/testing/test-fixtures/package.json b/testing/test-fixtures/package.json deleted file mode 100644 index c77280f3f..000000000 --- a/testing/test-fixtures/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "@code-pushup/test-fixtures", - "type": "module" -} diff --git a/testing/test-fixtures/project.json b/testing/test-fixtures/project.json index 5e61f31bb..d4c3127ce 100644 --- a/testing/test-fixtures/project.json +++ b/testing/test-fixtures/project.json @@ -4,7 +4,6 @@ "sourceRoot": "testing/test-fixtures/src", "projectType": "library", "targets": { - "build": {}, "lint": {}, "nx-release-publish": { "executor": "nx:noop" From 241df6a1a62c83a0cf756dc38bba2ddc6572931b Mon Sep 17 00:00:00 2001 From: John Doe Date: Wed, 10 Dec 2025 19:32:17 +0100 Subject: [PATCH 12/13] refactor: fix project setup 2 --- testing/test-fixtures/package.json | 4 ++++ testing/test-fixtures/project.json | 1 + 2 files changed, 5 insertions(+) create mode 100644 testing/test-fixtures/package.json diff --git a/testing/test-fixtures/package.json b/testing/test-fixtures/package.json new file mode 100644 index 000000000..c77280f3f --- /dev/null +++ b/testing/test-fixtures/package.json @@ -0,0 +1,4 @@ +{ + "name": "@code-pushup/test-fixtures", + "type": "module" +} diff --git a/testing/test-fixtures/project.json b/testing/test-fixtures/project.json index d4c3127ce..5e61f31bb 100644 --- a/testing/test-fixtures/project.json +++ b/testing/test-fixtures/project.json @@ -4,6 +4,7 @@ "sourceRoot": "testing/test-fixtures/src", "projectType": "library", "targets": { + "build": {}, "lint": {}, "nx-release-publish": { "executor": "nx:noop" From 3aedacf3e00bf68baacf6049cd73fdb57c134d9f Mon Sep 17 00:00:00 2001 From: John Doe Date: Wed, 10 Dec 2025 19:54:38 +0100 Subject: [PATCH 13/13] refactor: revert changes --- testing/test-nx-utils/src/lib/utils/nx.ts | 27 ++++++----------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/testing/test-nx-utils/src/lib/utils/nx.ts b/testing/test-nx-utils/src/lib/utils/nx.ts index db4f5ef3e..050bdc541 100644 --- a/testing/test-nx-utils/src/lib/utils/nx.ts +++ b/testing/test-nx-utils/src/lib/utils/nx.ts @@ -9,12 +9,9 @@ import { } from '@nx/devkit'; import { libraryGenerator } from '@nx/js'; import type { LibraryGeneratorSchema } from '@nx/js/src/generators/library/schema'; -import { execFile } from 'node:child_process'; import path from 'node:path'; -import { promisify } from 'node:util'; import { createTreeWithEmptyWorkspace } from 'nx/src/generators/testing-utils/create-tree-with-empty-workspace'; - -const execFileAsync = promisify(execFile); +import { executeProcess } from '@code-pushup/utils'; export function executorContext< T extends { projectName: string; cwd?: string }, @@ -85,21 +82,11 @@ export async function nxShowProjectJson( cwd: string, project: string, ) { - try { - const { stdout, stderr } = await execFileAsync( - 'npx', - ['nx', 'show', 'project', project, '--json'], - { cwd }, - ); + const { code, stderr, stdout } = await executeProcess({ + command: 'npx', + args: ['nx', 'show', `project --json ${project}`], + cwd, + }); - return { code: 0, stderr, projectJson: JSON.parse(stdout) as T }; - } catch (error) { - const execError = error as { code?: number; stderr?: string }; - const fallbackProject = { name: project, root: '' }; - return { - code: execError.code ?? 1, - stderr: execError.stderr ?? String(error), - projectJson: fallbackProject as T, - }; - } + return { code, stderr, projectJson: JSON.parse(stdout) as T }; }