From bd1b8e1bf570097f6590d8962f9381623a3765f5 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 02:02:36 +0100 Subject: [PATCH 01/80] cherry-pick --- .github/workflows/ci.yml | 2 +- .gitignore | 2 + e2e/cli-e2e/project.json | 11 +-- e2e/cli-e2e/tests/collect.e2e.test.ts | 35 +++++++--- e2e/cli-e2e/tests/compare.e2e.test.ts | 9 ++- e2e/cli-e2e/tests/help.e2e.test.ts | 15 ++-- e2e/cli-e2e/tests/print-config.e2e.test.ts | 22 +++--- e2e/cli-e2e/vite.config.e2e.ts | 1 - examples/react-todos-app/.eslintrc.js | 69 ------------------- examples/react-todos-app/.eslintrc.json | 64 +++++++++++++++++ ...pushup.config.js => code-pushup.config.ts} | 6 +- examples/react-todos-app/package.json | 16 ----- nx.json | 3 + 13 files changed, 130 insertions(+), 125 deletions(-) delete mode 100644 examples/react-todos-app/.eslintrc.js create mode 100644 examples/react-todos-app/.eslintrc.json rename examples/react-todos-app/{code-pushup.config.js => code-pushup.config.ts} (93%) delete mode 100644 examples/react-todos-app/package.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 845def216..55fb01fe6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,7 +122,7 @@ jobs: - name: E2E test affected projects run: npx nx affected -t nxv-e2e --exclude cli-e2e --parallel=1 - name: E2E test cli-e2e project (due to bugs in the setup it has to run last :( ) - run: npx nx run cli-e2e:e2e-old + run: npx nx run cli-e2e:nxv-e2e build: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 21c8b0424..01481eeee 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,8 @@ node_modules /connect.lock /coverage /examples/react-todos-app/coverage +/examples/react-todos-app/package.json +/examples/react-todos-app/package-lock.json /libpeerconnection.log npm-debug.log yarn-error.log diff --git a/e2e/cli-e2e/project.json b/e2e/cli-e2e/project.json index 5bef1175d..f61dab7cc 100644 --- a/e2e/cli-e2e/project.json +++ b/e2e/cli-e2e/project.json @@ -11,17 +11,20 @@ "lintFilePatterns": ["e2e/cli-e2e/**/*.ts"] } }, + "nxv-env-setup": { + "options": { + "environmentRoot": "examples/react-todos-app" + } + }, "e2e-old": { "executor": "@nx/vite:test", "options": { - "configFile": "e2e/cli-e2e/vite.config.e2e.ts" + "configFile": "e2e/cli-e2e/vite.config.e2e.ts", + "environmentRoot": "examples/react-todos-app" } } }, "implicitDependencies": [ - "models", - "utils", - "core", "cli", "plugin-eslint", "plugin-coverage", diff --git a/e2e/cli-e2e/tests/collect.e2e.test.ts b/e2e/cli-e2e/tests/collect.e2e.test.ts index 5e301ab29..ba4676d49 100644 --- a/e2e/cli-e2e/tests/collect.e2e.test.ts +++ b/e2e/cli-e2e/tests/collect.e2e.test.ts @@ -51,8 +51,13 @@ describe('CLI collect', () => { it('should run ESLint plugin and create report.json', async () => { const { code, stderr } = await executeProcess({ - command: 'code-pushup', - args: ['collect', '--no-progress', '--onlyPlugins=eslint'], + command: 'npx', + args: [ + '@code-pushup/cli', + 'collect', + '--no-progress', + '--onlyPlugins=eslint', + ], cwd: 'examples/react-todos-app', }); @@ -83,14 +88,16 @@ describe('CLI collect', () => { ); const { code, stderr } = await executeProcess({ - command: 'code-pushup', + command: 'npx', args: [ + '@code-pushup/cli', 'collect', '--no-progress', `--config=${configPath}`, '--persist.outputDir=tmp/e2e', '--onlyPlugins=coverage', ], + cwd: 'examples/react-todos-app', }); expect(code).toBe(0); @@ -104,8 +111,13 @@ describe('CLI collect', () => { it('should run Code coverage plugin that runs coverage tool and creates report.json', async () => { const { code, stderr } = await executeProcess({ - command: 'code-pushup', - args: ['collect', '--no-progress', '--onlyPlugins=coverage'], + command: 'npx', + args: [ + '@code-pushup/cli', + 'collect', + '--no-progress', + '--onlyPlugins=coverage', + ], cwd: 'examples/react-todos-app', }); @@ -120,8 +132,13 @@ describe('CLI collect', () => { it('should create report.md', async () => { const { code, stderr } = await executeProcess({ - command: 'code-pushup', - args: ['collect', '--persist.format=md', '--no-progress'], + command: 'npx', + args: [ + '@code-pushup/cli', + 'collect', + '--persist.format=md', + '--no-progress', + ], cwd: 'examples/react-todos-app', }); @@ -137,8 +154,8 @@ describe('CLI collect', () => { it('should print report summary to stdout', async () => { const { code, stdout, stderr } = await executeProcess({ - command: 'code-pushup', - args: ['collect', '--no-progress'], + command: 'npx', + args: ['@code-pushup/cli', 'collect', '--no-progress'], cwd: 'examples/react-todos-app', }); diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index 9f5744c9f..c80eb9e24 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -14,8 +14,9 @@ describe('CLI compare', () => { } await cleanTestFolder('tmp/e2e/react-todos-app'); await executeProcess({ - command: 'code-pushup', + command: 'npx', args: [ + '@code-pushup/cli', 'collect', '--persist.filename=source-report', '--onlyPlugins=eslint', @@ -28,8 +29,9 @@ describe('CLI compare', () => { cwd: 'examples/react-todos-app', }); await executeProcess({ - command: 'code-pushup', + command: 'npx', args: [ + '@code-pushup/cli', 'collect', '--persist.filename=target-report', '--onlyPlugins=eslint', @@ -45,8 +47,9 @@ describe('CLI compare', () => { it('should compare report.json files and create report-diff.json and report-diff.md', async () => { await executeProcess({ - command: 'code-pushup', + command: 'npx', args: [ + '@code-pushup/cli', 'compare', '--before=../../tmp/e2e/react-todos-app/source-report.json', '--after=../../tmp/e2e/react-todos-app/target-report.json', diff --git a/e2e/cli-e2e/tests/help.e2e.test.ts b/e2e/cli-e2e/tests/help.e2e.test.ts index cf5316be1..40032dfe9 100644 --- a/e2e/cli-e2e/tests/help.e2e.test.ts +++ b/e2e/cli-e2e/tests/help.e2e.test.ts @@ -4,8 +4,9 @@ import { executeProcess } from '@code-pushup/utils'; describe('CLI help', () => { it('should print help with help command', async () => { const { code, stdout, stderr } = await executeProcess({ - command: 'code-pushup', - args: ['help'], + command: 'npx', + args: ['@code-pushup/cli', 'help'], + cwd: 'examples/react-todos-app', }); expect(code).toBe(0); expect(stderr).toBe(''); @@ -14,12 +15,14 @@ describe('CLI help', () => { it('should produce the same output to stdout for both help argument and help command', async () => { const helpArgResult = await executeProcess({ - command: 'code-pushup', - args: ['help'], + command: 'npx', + args: ['@code-pushup/cli', 'help'], + cwd: 'examples/react-todos-app', }); const helpCommandResult = await executeProcess({ - command: 'code-pushup', - args: ['--help'], + command: 'npx', + args: ['@code-pushup/cli', '--help'], + cwd: 'examples/react-todos-app', }); expect(helpArgResult.code).toBe(0); expect(helpCommandResult.code).toBe(0); diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index 46190659d..75ef57e76 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -6,29 +6,29 @@ const extensions = ['js', 'mjs', 'ts'] as const; export const configFilePath = (ext: (typeof extensions)[number]) => join(process.cwd(), `e2e/cli-e2e/mocks/fixtures/code-pushup.config.${ext}`); -describe('print-config', () => { +describe('CLI print-config', () => { it.each(extensions)( 'should load .%s config file with correct arguments', async ext => { const { code, stdout } = await executeProcess({ - command: 'code-pushup', + command: 'npx', args: [ + '@code-pushup/cli', 'print-config', '--no-progress', - `--config=${configFilePath(ext)}`, '--tsconfig=tsconfig.base.json', '--persist.outputDir=output-dir', '--persist.format=md', `--persist.filename=${ext}-report`, '--onlyPlugins=coverage', ], + cwd: 'examples/react-todos-app', }); expect(code).toBe(0); expect(JSON.parse(stdout)).toEqual( expect.objectContaining({ - config: expect.stringContaining(`code-pushup.config.${ext}`), tsconfig: 'tsconfig.base.json', // filled by command options persist: { @@ -36,19 +36,15 @@ describe('print-config', () => { filename: `${ext}-report`, format: ['md'], }, - upload: { - organization: 'code-pushup', - project: `cli-${ext}`, - apiKey: 'e2e-api-key', - server: 'https://e2e.com/api', - }, - plugins: [ + plugins: expect.arrayContaining([ expect.objectContaining({ slug: 'coverage', title: 'Code coverage', }), - ], - categories: [expect.objectContaining({ slug: 'code-coverage' })], + ]), + categories: expect.arrayContaining([ + expect.objectContaining({ slug: 'code-coverage' }), + ]), onlyPlugins: ['coverage'], }), ); diff --git a/e2e/cli-e2e/vite.config.e2e.ts b/e2e/cli-e2e/vite.config.e2e.ts index f1b3c3b93..2514c0209 100644 --- a/e2e/cli-e2e/vite.config.e2e.ts +++ b/e2e/cli-e2e/vite.config.e2e.ts @@ -16,7 +16,6 @@ export default defineConfig({ }, environment: 'node', include: ['tests/**/*.e2e.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], - globalSetup: ['../../global-setup.e2e.ts'], setupFiles: ['../../testing/test-setup/src/lib/reset.mocks.ts'], }, }); diff --git a/examples/react-todos-app/.eslintrc.js b/examples/react-todos-app/.eslintrc.js deleted file mode 100644 index e05f2bb62..000000000 --- a/examples/react-todos-app/.eslintrc.js +++ /dev/null @@ -1,69 +0,0 @@ -/** @type {import('eslint').ESLint.ConfigData} */ -module.exports = { - root: true, - env: { - browser: true, - es2021: true, - }, - plugins: ['react', 'react-hooks'], - overrides: [ - { - env: { - node: true, - }, - files: ['.eslintrc.{js,cjs}'], - parserOptions: { - sourceType: 'script', - }, - }, - ], - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - }, - settings: { - react: { - version: 'detect', - }, - }, - rules: { - // https://eslint.org/docs/latest/rules/#possible-problems - 'no-cond-assign': 'warn', - 'no-const-assign': 'warn', - 'no-debugger': 'warn', - 'no-invalid-regexp': 'warn', - 'no-undef': 'warn', - 'no-unreachable-loop': 'warn', - 'no-unsafe-negation': 'warn', - 'no-unsafe-optional-chaining': 'warn', - 'no-unused-vars': 'warn', - 'use-isnan': 'warn', - 'valid-typeof': 'warn', - // https://eslint.org/docs/latest/rules/#suggestions - 'arrow-body-style': 'warn', - camelcase: 'warn', - curly: 'warn', - eqeqeq: 'warn', - 'max-lines-per-function': 'warn', - 'max-lines': 'warn', - 'no-shadow': 'warn', - 'no-var': 'warn', - 'object-shorthand': 'warn', - 'prefer-arrow-callback': 'warn', - 'prefer-const': 'warn', - 'prefer-object-spread': 'warn', - yoda: 'warn', - // https://github.com/jsx-eslint/eslint-plugin-react#list-of-supported-rules - 'react/jsx-key': 'warn', - 'react/prop-types': 'warn', - 'react/react-in-jsx-scope': 'warn', - 'react/jsx-uses-vars': 'warn', - 'react/jsx-uses-react': 'error', - // https://www.npmjs.com/package/eslint-plugin-react-hooks - 'react-hooks/rules-of-hooks': 'error', - 'react-hooks/exhaustive-deps': 'warn', - }, -}; diff --git a/examples/react-todos-app/.eslintrc.json b/examples/react-todos-app/.eslintrc.json new file mode 100644 index 000000000..9c50e51ca --- /dev/null +++ b/examples/react-todos-app/.eslintrc.json @@ -0,0 +1,64 @@ +{ + "root": true, + "env": { + "browser": true, + "es2021": true + }, + "plugins": ["react", "react-hooks"], + "overrides": [ + { + "env": { + "node": true + }, + "files": [".eslintrc.{js,cjs}"], + "parserOptions": { + "sourceType": "script" + } + } + ], + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module", + "ecmaFeatures": { + "jsx": true + } + }, + "settings": { + "react": { + "version": "detect" + } + }, + "rules": { + "no-cond-assign": "warn", + "no-const-assign": "warn", + "no-debugger": "warn", + "no-invalid-regexp": "warn", + "no-undef": "warn", + "no-unreachable-loop": "warn", + "no-unsafe-negation": "warn", + "no-unsafe-optional-chaining": "warn", + "no-unused-vars": "warn", + "use-isnan": "warn", + "valid-typeof": "warn", + "arrow-body-style": "warn", + "camelcase": "warn", + "curly": "warn", + "eqeqeq": "warn", + "max-lines-per-function": "warn", + "max-lines": "warn", + "no-shadow": "warn", + "no-var": "warn", + "object-shorthand": "warn", + "prefer-arrow-callback": "warn", + "prefer-const": "warn", + "prefer-object-spread": "warn", + "yoda": "warn", + "react/jsx-key": "warn", + "react/prop-types": "warn", + "react/react-in-jsx-scope": "warn", + "react/jsx-uses-vars": "warn", + "react/jsx-uses-react": "error", + "react-hooks/rules-of-hooks": "error", + "react-hooks/exhaustive-deps": "warn" + } +} diff --git a/examples/react-todos-app/code-pushup.config.js b/examples/react-todos-app/code-pushup.config.ts similarity index 93% rename from examples/react-todos-app/code-pushup.config.js rename to examples/react-todos-app/code-pushup.config.ts index dcef94a7f..60780c794 100644 --- a/examples/react-todos-app/code-pushup.config.js +++ b/examples/react-todos-app/code-pushup.config.ts @@ -1,5 +1,5 @@ -import coveragePlugin from '../../dist/packages/plugin-coverage'; -import eslintPlugin from '../../dist/packages/plugin-eslint'; +import coveragePlugin from '@code-pushup/coverage-plugin'; +import eslintPlugin from '@code-pushup/eslint-plugin'; const eslintAuditRef = (slug, weight) => ({ type: 'audit', @@ -21,7 +21,7 @@ export default { }, }), await eslintPlugin({ - eslintrc: '.eslintrc.js', + eslintrc: '.eslintrc.json', patterns: ['src/**/*.js', 'src/**/*.jsx'], }), ], diff --git a/examples/react-todos-app/package.json b/examples/react-todos-app/package.json deleted file mode 100644 index d9e892a84..000000000 --- a/examples/react-todos-app/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "todo-app", - "private": true, - "scripts": { - "start": "esbuild src/index.jsx --bundle --outdir=www/js --servedir=www", - "build": "esbuild src/index.jsx --bundle --outdir=www/js --minify" - }, - "dependencies": { - "react": "^16.12.0", - "semver": "5.7.1" - }, - "devDependencies": { - "vite": "~4.5.0", - "vitest": "0.34.0" - } -} diff --git a/nx.json b/nx.json index bebd69d65..b660413ce 100644 --- a/nx.json +++ b/nx.json @@ -28,6 +28,9 @@ "e2e": { "dependsOn": ["^build"] }, + "nxv-env-setup": { + "executor": "@push-based/nx-verdaccio:env-setup" + }, "@nx/vite:test": { "cache": true, "inputs": ["default", "^production"], From d92bf4684e72a8a0faecd925bfc224d3c6112aae Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 02:12:33 +0100 Subject: [PATCH 02/80] adjust target name --- e2e/cli-e2e/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/cli-e2e/project.json b/e2e/cli-e2e/project.json index f61dab7cc..c14b2d8cb 100644 --- a/e2e/cli-e2e/project.json +++ b/e2e/cli-e2e/project.json @@ -16,7 +16,7 @@ "environmentRoot": "examples/react-todos-app" } }, - "e2e-old": { + "e2e": { "executor": "@nx/vite:test", "options": { "configFile": "e2e/cli-e2e/vite.config.e2e.ts", From 8cc75ee47c71f08c7ca173c271b5a6dea1f6d35c Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 03:34:40 +0100 Subject: [PATCH 03/80] test: add eslint e2e project --- e2e/plugin-eslint-e2e/.eslintrc.json | 12 +++++++ e2e/plugin-eslint-e2e/project.json | 29 +++++++++++++++ .../tests/collect.e2e.test.ts | 35 +++++++++++++++++++ e2e/plugin-eslint-e2e/tsconfig.json | 20 +++++++++++ e2e/plugin-eslint-e2e/tsconfig.test.json | 14 ++++++++ e2e/plugin-eslint-e2e/vite.config.e2e.ts | 21 +++++++++++ 6 files changed, 131 insertions(+) create mode 100644 e2e/plugin-eslint-e2e/.eslintrc.json create mode 100644 e2e/plugin-eslint-e2e/project.json create mode 100644 e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts create mode 100644 e2e/plugin-eslint-e2e/tsconfig.json create mode 100644 e2e/plugin-eslint-e2e/tsconfig.test.json create mode 100644 e2e/plugin-eslint-e2e/vite.config.e2e.ts diff --git a/e2e/plugin-eslint-e2e/.eslintrc.json b/e2e/plugin-eslint-e2e/.eslintrc.json new file mode 100644 index 000000000..622f1f491 --- /dev/null +++ b/e2e/plugin-eslint-e2e/.eslintrc.json @@ -0,0 +1,12 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*", "code-pushup.config*.ts"], + "overrides": [ + { + "files": ["*.ts", "*.tsx"], + "parserOptions": { + "project": ["e2e/plugin-eslint-e2e/tsconfig.*?.json"] + } + } + ] +} diff --git a/e2e/plugin-eslint-e2e/project.json b/e2e/plugin-eslint-e2e/project.json new file mode 100644 index 000000000..8edc665f8 --- /dev/null +++ b/e2e/plugin-eslint-e2e/project.json @@ -0,0 +1,29 @@ +{ + "name": "plugin-eslint-e2e", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "e2e/plugin-eslint-e2e/src", + "projectType": "application", + "targets": { + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["e2e/plugin-eslint-e2e/**/*.ts"] + } + }, + "nxv-env-setup": { + "options": { + "environmentRoot": "examples/eslint-example-app" + } + }, + "e2e": { + "executor": "@nx/vite:test", + "options": { + "configFile": "e2e/plugin-eslint-e2e/vite.config.e2e.ts", + "environmentRoot": "examples/eslint-example-app" + } + } + }, + "implicitDependencies": ["cli", "plugin-eslint", "eslint-e2e-env"], + "tags": ["scope:plugin", "type:e2e"] +} diff --git a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts new file mode 100644 index 000000000..52d6ebbaf --- /dev/null +++ b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts @@ -0,0 +1,35 @@ +import { join } from 'node:path'; +import { afterEach } from 'vitest'; +import { type Report, reportSchema } from '@code-pushup/models'; +import { teardownTestFolder } from '@code-pushup/test-setup'; +import { omitVariableReportData } from '@code-pushup/test-utils'; +import { executeProcess, readJsonFile } from '@code-pushup/utils'; + +describe('collect report with eslint-plugin NPM package', () => { + const baseDir = 'eslint-e2e-env/__test__'; + + afterEach(async () => { + await teardownTestFolder(baseDir); + }); + + it('should run ESLint plugin and create report.json', async () => { + const { code, stderr } = await executeProcess({ + command: 'npx', + args: [ + '@code-pushup/cli', + 'collect', + '--no-progress', + '--onlyPlugins=eslint', + ], + cwd: baseDir, + }); + + expect(code).toBe(0); + expect(stderr).toBe(''); + + const report = await readJsonFile(join(baseDir, 'code-pushup/report.json')); + + expect(() => reportSchema.parse(report)).not.toThrow(); + expect(omitVariableReportData(report as Report)).toMatchSnapshot(); + }); +}); diff --git a/e2e/plugin-eslint-e2e/tsconfig.json b/e2e/plugin-eslint-e2e/tsconfig.json new file mode 100644 index 000000000..f5a2f890a --- /dev/null +++ b/e2e/plugin-eslint-e2e/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "ESNext", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "types": ["vitest"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.test.json" + } + ] +} diff --git a/e2e/plugin-eslint-e2e/tsconfig.test.json b/e2e/plugin-eslint-e2e/tsconfig.test.json new file mode 100644 index 000000000..10c7f79de --- /dev/null +++ b/e2e/plugin-eslint-e2e/tsconfig.test.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"], + "target": "ES2020" + }, + "include": [ + "vite.config.e2e.ts", + "tests/**/*.e2e.test.ts", + "tests/**/*.d.ts", + "mocks/**/*.ts" + ] +} diff --git a/e2e/plugin-eslint-e2e/vite.config.e2e.ts b/e2e/plugin-eslint-e2e/vite.config.e2e.ts new file mode 100644 index 000000000..3956da52e --- /dev/null +++ b/e2e/plugin-eslint-e2e/vite.config.e2e.ts @@ -0,0 +1,21 @@ +/// +import { defineConfig } from 'vite'; +import { tsconfigPathAliases } from '../../tools/vitest-tsconfig-path-aliases'; + +export default defineConfig({ + cacheDir: '../../node_modules/.vite/plugin-lighthouse-e2e', + test: { + reporters: ['basic'], + testTimeout: 120_000, + globals: true, + alias: tsconfigPathAliases(), + pool: 'threads', + poolOptions: { threads: { singleThread: true } }, + cache: { + dir: '../../node_modules/.vitest', + }, + environment: 'node', + include: ['tests/**/*.e2e.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + setupFiles: ['../../testing/test-setup/src/lib/reset.mocks.ts'], + }, +}); From 71ff81a71c90a6b78c29185ac37490869899cef8 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 03:34:57 +0100 Subject: [PATCH 04/80] test: add eslint e2e env project --- .../eslint-e2e-env/.eslintrc.json | 15 +++++++++++++++ .../eslint-e2e-env/code-pushup.config.ts | 10 ++++++++++ .../eslint-e2e-env/project.json | 18 ++++++++++++++++++ .../eslint-e2e-env/src/index.js | 1 + 4 files changed, 44 insertions(+) create mode 100644 static-environments/eslint-e2e-env/.eslintrc.json create mode 100644 static-environments/eslint-e2e-env/code-pushup.config.ts create mode 100644 static-environments/eslint-e2e-env/project.json create mode 100644 static-environments/eslint-e2e-env/src/index.js diff --git a/static-environments/eslint-e2e-env/.eslintrc.json b/static-environments/eslint-e2e-env/.eslintrc.json new file mode 100644 index 000000000..451833b75 --- /dev/null +++ b/static-environments/eslint-e2e-env/.eslintrc.json @@ -0,0 +1,15 @@ +{ + "root": true, + "ignorePatterns": ["code-pushup.config.ts"], + "overrides": [ + { + "files": ["*.js"], + "env": { + "node": true + }, + "parserOptions": { + "sourceType": "script" + } + } + ] +} diff --git a/static-environments/eslint-e2e-env/code-pushup.config.ts b/static-environments/eslint-e2e-env/code-pushup.config.ts new file mode 100644 index 000000000..a2c2ef291 --- /dev/null +++ b/static-environments/eslint-e2e-env/code-pushup.config.ts @@ -0,0 +1,10 @@ +import eslintPlugin from '../../dist/packages/plugin-eslint'; + +export default { + plugins: [ + await eslintPlugin({ + eslintrc: '.eslintrc.json', + patterns: ['*.js'], + }), + ], +}; diff --git a/static-environments/eslint-e2e-env/project.json b/static-environments/eslint-e2e-env/project.json new file mode 100644 index 000000000..d8cc640d4 --- /dev/null +++ b/static-environments/eslint-e2e-env/project.json @@ -0,0 +1,18 @@ +{ + "name": "eslint-e2e-env", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "static-environments/eslint-e2e-env/src", + "projectType": "library", + "targets": { + "lint": { + "command": "npx eslint --config static-environments/eslint-e2e-env/.eslintrc.json static-environments/eslint-e2e-env/src" + }, + "run-collect": { + "command": "npx ../../dist/packages/cli collect", + "options": { + "cwd": "static-environments/eslint-e2e-env" + } + } + }, + "tags": ["scope:internal", "type:feature"] +} diff --git a/static-environments/eslint-e2e-env/src/index.js b/static-environments/eslint-e2e-env/src/index.js new file mode 100644 index 000000000..44dba22ef --- /dev/null +++ b/static-environments/eslint-e2e-env/src/index.js @@ -0,0 +1 @@ +export const test = 42; From 7718c06652bdfebeeb8738dbae1641ee7eddc95b Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 14:17:02 +0100 Subject: [PATCH 05/80] wip --- e2e/plugin-eslint-e2e/project.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/plugin-eslint-e2e/project.json b/e2e/plugin-eslint-e2e/project.json index 8edc665f8..a1a657ed4 100644 --- a/e2e/plugin-eslint-e2e/project.json +++ b/e2e/plugin-eslint-e2e/project.json @@ -13,14 +13,14 @@ }, "nxv-env-setup": { "options": { - "environmentRoot": "examples/eslint-example-app" + "environmentRoot": "static-environments/eslint-e2e-env" } }, "e2e": { "executor": "@nx/vite:test", "options": { "configFile": "e2e/plugin-eslint-e2e/vite.config.e2e.ts", - "environmentRoot": "examples/eslint-example-app" + "environmentRoot": "static-environments/eslint-e2e-env" } } }, From a0ef58eb28054abdd8239d0e94f151d160e26cba Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 14:38:54 +0100 Subject: [PATCH 06/80] wip --- static-environments/eslint-e2e-env/code-pushup.config.ts | 2 +- static-environments/eslint-e2e-env/project.json | 2 +- static-environments/eslint-e2e-env/src/index.js | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/static-environments/eslint-e2e-env/code-pushup.config.ts b/static-environments/eslint-e2e-env/code-pushup.config.ts index a2c2ef291..8895efa4a 100644 --- a/static-environments/eslint-e2e-env/code-pushup.config.ts +++ b/static-environments/eslint-e2e-env/code-pushup.config.ts @@ -1,4 +1,4 @@ -import eslintPlugin from '../../dist/packages/plugin-eslint'; +import eslintPlugin from '@code-pushup/eslint-plugin'; export default { plugins: [ diff --git a/static-environments/eslint-e2e-env/project.json b/static-environments/eslint-e2e-env/project.json index d8cc640d4..7f8687c4a 100644 --- a/static-environments/eslint-e2e-env/project.json +++ b/static-environments/eslint-e2e-env/project.json @@ -8,7 +8,7 @@ "command": "npx eslint --config static-environments/eslint-e2e-env/.eslintrc.json static-environments/eslint-e2e-env/src" }, "run-collect": { - "command": "npx ../../dist/packages/cli collect", + "command": "npx @code-pushup/cli collect", "options": { "cwd": "static-environments/eslint-e2e-env" } diff --git a/static-environments/eslint-e2e-env/src/index.js b/static-environments/eslint-e2e-env/src/index.js index 44dba22ef..717d5891b 100644 --- a/static-environments/eslint-e2e-env/src/index.js +++ b/static-environments/eslint-e2e-env/src/index.js @@ -1 +1,3 @@ -export const test = 42; +function random() { + return '42'; +} From ba625bbfd5da84a93ed24abc55444fe75e538e39 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 14:53:04 +0100 Subject: [PATCH 07/80] wip --- e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts index 52d6ebbaf..47f4025d2 100644 --- a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts @@ -6,7 +6,7 @@ import { omitVariableReportData } from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; describe('collect report with eslint-plugin NPM package', () => { - const baseDir = 'eslint-e2e-env/__test__'; + const baseDir = 'static-environments/eslint-e2e-env'; afterEach(async () => { await teardownTestFolder(baseDir); From 30602756d4f8a66088ef600b0d5b5572c75f42e4 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 14:56:57 +0100 Subject: [PATCH 08/80] wip --- static-environments/eslint-e2e-env/.eslintrc.json | 3 +++ static-environments/eslint-e2e-env/project.json | 5 ++++- static-environments/eslint-e2e-env/src/index.js | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/static-environments/eslint-e2e-env/.eslintrc.json b/static-environments/eslint-e2e-env/.eslintrc.json index 451833b75..d9684a6dd 100644 --- a/static-environments/eslint-e2e-env/.eslintrc.json +++ b/static-environments/eslint-e2e-env/.eslintrc.json @@ -9,6 +9,9 @@ }, "parserOptions": { "sourceType": "script" + }, + "rules": { + "no-unused-vars": "error" } } ] diff --git a/static-environments/eslint-e2e-env/project.json b/static-environments/eslint-e2e-env/project.json index 7f8687c4a..76c90ba64 100644 --- a/static-environments/eslint-e2e-env/project.json +++ b/static-environments/eslint-e2e-env/project.json @@ -5,7 +5,10 @@ "projectType": "library", "targets": { "lint": { - "command": "npx eslint --config static-environments/eslint-e2e-env/.eslintrc.json static-environments/eslint-e2e-env/src" + "command": "npx eslint src", + "options": { + "cwd": "static-environments/eslint-e2e-env" + } }, "run-collect": { "command": "npx @code-pushup/cli collect", diff --git a/static-environments/eslint-e2e-env/src/index.js b/static-environments/eslint-e2e-env/src/index.js index 717d5891b..7b2d56d8e 100644 --- a/static-environments/eslint-e2e-env/src/index.js +++ b/static-environments/eslint-e2e-env/src/index.js @@ -1,3 +1,3 @@ -function random() { +function random(unused) { return '42'; } From d4b84ad23c792956951de76ddb6391d9ad695bcf Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 16:08:42 +0100 Subject: [PATCH 09/80] wip --- .github/workflows/ci.yml | 2 +- .gitignore | 2 - e2e/cli-e2e/project.json | 13 ++-- e2e/cli-e2e/tests/collect.e2e.test.ts | 35 +++------- e2e/cli-e2e/tests/compare.e2e.test.ts | 9 +-- e2e/cli-e2e/tests/help.e2e.test.ts | 15 ++-- e2e/cli-e2e/tests/print-config.e2e.test.ts | 22 +++--- e2e/cli-e2e/vite.config.e2e.ts | 1 + .../tests/collect.e2e.test.ts | 5 +- examples/react-todos-app/.eslintrc.js | 69 +++++++++++++++++++ examples/react-todos-app/.eslintrc.json | 64 ----------------- ...pushup.config.ts => code-pushup.config.js} | 6 +- 12 files changed, 113 insertions(+), 130 deletions(-) create mode 100644 examples/react-todos-app/.eslintrc.js delete mode 100644 examples/react-todos-app/.eslintrc.json rename examples/react-todos-app/{code-pushup.config.ts => code-pushup.config.js} (93%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55fb01fe6..845def216 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,7 +122,7 @@ jobs: - name: E2E test affected projects run: npx nx affected -t nxv-e2e --exclude cli-e2e --parallel=1 - name: E2E test cli-e2e project (due to bugs in the setup it has to run last :( ) - run: npx nx run cli-e2e:nxv-e2e + run: npx nx run cli-e2e:e2e-old build: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 01481eeee..21c8b0424 100644 --- a/.gitignore +++ b/.gitignore @@ -33,8 +33,6 @@ node_modules /connect.lock /coverage /examples/react-todos-app/coverage -/examples/react-todos-app/package.json -/examples/react-todos-app/package-lock.json /libpeerconnection.log npm-debug.log yarn-error.log diff --git a/e2e/cli-e2e/project.json b/e2e/cli-e2e/project.json index c14b2d8cb..5bef1175d 100644 --- a/e2e/cli-e2e/project.json +++ b/e2e/cli-e2e/project.json @@ -11,20 +11,17 @@ "lintFilePatterns": ["e2e/cli-e2e/**/*.ts"] } }, - "nxv-env-setup": { - "options": { - "environmentRoot": "examples/react-todos-app" - } - }, - "e2e": { + "e2e-old": { "executor": "@nx/vite:test", "options": { - "configFile": "e2e/cli-e2e/vite.config.e2e.ts", - "environmentRoot": "examples/react-todos-app" + "configFile": "e2e/cli-e2e/vite.config.e2e.ts" } } }, "implicitDependencies": [ + "models", + "utils", + "core", "cli", "plugin-eslint", "plugin-coverage", diff --git a/e2e/cli-e2e/tests/collect.e2e.test.ts b/e2e/cli-e2e/tests/collect.e2e.test.ts index ba4676d49..5e301ab29 100644 --- a/e2e/cli-e2e/tests/collect.e2e.test.ts +++ b/e2e/cli-e2e/tests/collect.e2e.test.ts @@ -51,13 +51,8 @@ describe('CLI collect', () => { it('should run ESLint plugin and create report.json', async () => { const { code, stderr } = await executeProcess({ - command: 'npx', - args: [ - '@code-pushup/cli', - 'collect', - '--no-progress', - '--onlyPlugins=eslint', - ], + command: 'code-pushup', + args: ['collect', '--no-progress', '--onlyPlugins=eslint'], cwd: 'examples/react-todos-app', }); @@ -88,16 +83,14 @@ describe('CLI collect', () => { ); const { code, stderr } = await executeProcess({ - command: 'npx', + command: 'code-pushup', args: [ - '@code-pushup/cli', 'collect', '--no-progress', `--config=${configPath}`, '--persist.outputDir=tmp/e2e', '--onlyPlugins=coverage', ], - cwd: 'examples/react-todos-app', }); expect(code).toBe(0); @@ -111,13 +104,8 @@ describe('CLI collect', () => { it('should run Code coverage plugin that runs coverage tool and creates report.json', async () => { const { code, stderr } = await executeProcess({ - command: 'npx', - args: [ - '@code-pushup/cli', - 'collect', - '--no-progress', - '--onlyPlugins=coverage', - ], + command: 'code-pushup', + args: ['collect', '--no-progress', '--onlyPlugins=coverage'], cwd: 'examples/react-todos-app', }); @@ -132,13 +120,8 @@ describe('CLI collect', () => { it('should create report.md', async () => { const { code, stderr } = await executeProcess({ - command: 'npx', - args: [ - '@code-pushup/cli', - 'collect', - '--persist.format=md', - '--no-progress', - ], + command: 'code-pushup', + args: ['collect', '--persist.format=md', '--no-progress'], cwd: 'examples/react-todos-app', }); @@ -154,8 +137,8 @@ describe('CLI collect', () => { it('should print report summary to stdout', async () => { const { code, stdout, stderr } = await executeProcess({ - command: 'npx', - args: ['@code-pushup/cli', 'collect', '--no-progress'], + command: 'code-pushup', + args: ['collect', '--no-progress'], cwd: 'examples/react-todos-app', }); diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index c80eb9e24..9f5744c9f 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -14,9 +14,8 @@ describe('CLI compare', () => { } await cleanTestFolder('tmp/e2e/react-todos-app'); await executeProcess({ - command: 'npx', + command: 'code-pushup', args: [ - '@code-pushup/cli', 'collect', '--persist.filename=source-report', '--onlyPlugins=eslint', @@ -29,9 +28,8 @@ describe('CLI compare', () => { cwd: 'examples/react-todos-app', }); await executeProcess({ - command: 'npx', + command: 'code-pushup', args: [ - '@code-pushup/cli', 'collect', '--persist.filename=target-report', '--onlyPlugins=eslint', @@ -47,9 +45,8 @@ describe('CLI compare', () => { it('should compare report.json files and create report-diff.json and report-diff.md', async () => { await executeProcess({ - command: 'npx', + command: 'code-pushup', args: [ - '@code-pushup/cli', 'compare', '--before=../../tmp/e2e/react-todos-app/source-report.json', '--after=../../tmp/e2e/react-todos-app/target-report.json', diff --git a/e2e/cli-e2e/tests/help.e2e.test.ts b/e2e/cli-e2e/tests/help.e2e.test.ts index 40032dfe9..cf5316be1 100644 --- a/e2e/cli-e2e/tests/help.e2e.test.ts +++ b/e2e/cli-e2e/tests/help.e2e.test.ts @@ -4,9 +4,8 @@ import { executeProcess } from '@code-pushup/utils'; describe('CLI help', () => { it('should print help with help command', async () => { const { code, stdout, stderr } = await executeProcess({ - command: 'npx', - args: ['@code-pushup/cli', 'help'], - cwd: 'examples/react-todos-app', + command: 'code-pushup', + args: ['help'], }); expect(code).toBe(0); expect(stderr).toBe(''); @@ -15,14 +14,12 @@ describe('CLI help', () => { it('should produce the same output to stdout for both help argument and help command', async () => { const helpArgResult = await executeProcess({ - command: 'npx', - args: ['@code-pushup/cli', 'help'], - cwd: 'examples/react-todos-app', + command: 'code-pushup', + args: ['help'], }); const helpCommandResult = await executeProcess({ - command: 'npx', - args: ['@code-pushup/cli', '--help'], - cwd: 'examples/react-todos-app', + command: 'code-pushup', + args: ['--help'], }); expect(helpArgResult.code).toBe(0); expect(helpCommandResult.code).toBe(0); diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index 75ef57e76..46190659d 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -6,29 +6,29 @@ const extensions = ['js', 'mjs', 'ts'] as const; export const configFilePath = (ext: (typeof extensions)[number]) => join(process.cwd(), `e2e/cli-e2e/mocks/fixtures/code-pushup.config.${ext}`); -describe('CLI print-config', () => { +describe('print-config', () => { it.each(extensions)( 'should load .%s config file with correct arguments', async ext => { const { code, stdout } = await executeProcess({ - command: 'npx', + command: 'code-pushup', args: [ - '@code-pushup/cli', 'print-config', '--no-progress', + `--config=${configFilePath(ext)}`, '--tsconfig=tsconfig.base.json', '--persist.outputDir=output-dir', '--persist.format=md', `--persist.filename=${ext}-report`, '--onlyPlugins=coverage', ], - cwd: 'examples/react-todos-app', }); expect(code).toBe(0); expect(JSON.parse(stdout)).toEqual( expect.objectContaining({ + config: expect.stringContaining(`code-pushup.config.${ext}`), tsconfig: 'tsconfig.base.json', // filled by command options persist: { @@ -36,15 +36,19 @@ describe('CLI print-config', () => { filename: `${ext}-report`, format: ['md'], }, - plugins: expect.arrayContaining([ + upload: { + organization: 'code-pushup', + project: `cli-${ext}`, + apiKey: 'e2e-api-key', + server: 'https://e2e.com/api', + }, + plugins: [ expect.objectContaining({ slug: 'coverage', title: 'Code coverage', }), - ]), - categories: expect.arrayContaining([ - expect.objectContaining({ slug: 'code-coverage' }), - ]), + ], + categories: [expect.objectContaining({ slug: 'code-coverage' })], onlyPlugins: ['coverage'], }), ); diff --git a/e2e/cli-e2e/vite.config.e2e.ts b/e2e/cli-e2e/vite.config.e2e.ts index 2514c0209..f1b3c3b93 100644 --- a/e2e/cli-e2e/vite.config.e2e.ts +++ b/e2e/cli-e2e/vite.config.e2e.ts @@ -16,6 +16,7 @@ export default defineConfig({ }, environment: 'node', include: ['tests/**/*.e2e.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + globalSetup: ['../../global-setup.e2e.ts'], setupFiles: ['../../testing/test-setup/src/lib/reset.mocks.ts'], }, }); diff --git a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts index 47f4025d2..05e45277b 100644 --- a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts @@ -6,10 +6,10 @@ import { omitVariableReportData } from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; describe('collect report with eslint-plugin NPM package', () => { - const baseDir = 'static-environments/eslint-e2e-env'; + const baseDir = 'static-environments/eslint-e2e-env/__tests__'; afterEach(async () => { - await teardownTestFolder(baseDir); + // await teardownTestFolder(baseDir); }); it('should run ESLint plugin and create report.json', async () => { @@ -18,6 +18,7 @@ describe('collect report with eslint-plugin NPM package', () => { args: [ '@code-pushup/cli', 'collect', + `--persist.outputDir=${join(baseDir, '.code-pushup')}`, '--no-progress', '--onlyPlugins=eslint', ], diff --git a/examples/react-todos-app/.eslintrc.js b/examples/react-todos-app/.eslintrc.js new file mode 100644 index 000000000..e05f2bb62 --- /dev/null +++ b/examples/react-todos-app/.eslintrc.js @@ -0,0 +1,69 @@ +/** @type {import('eslint').ESLint.ConfigData} */ +module.exports = { + root: true, + env: { + browser: true, + es2021: true, + }, + plugins: ['react', 'react-hooks'], + overrides: [ + { + env: { + node: true, + }, + files: ['.eslintrc.{js,cjs}'], + parserOptions: { + sourceType: 'script', + }, + }, + ], + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, + }, + settings: { + react: { + version: 'detect', + }, + }, + rules: { + // https://eslint.org/docs/latest/rules/#possible-problems + 'no-cond-assign': 'warn', + 'no-const-assign': 'warn', + 'no-debugger': 'warn', + 'no-invalid-regexp': 'warn', + 'no-undef': 'warn', + 'no-unreachable-loop': 'warn', + 'no-unsafe-negation': 'warn', + 'no-unsafe-optional-chaining': 'warn', + 'no-unused-vars': 'warn', + 'use-isnan': 'warn', + 'valid-typeof': 'warn', + // https://eslint.org/docs/latest/rules/#suggestions + 'arrow-body-style': 'warn', + camelcase: 'warn', + curly: 'warn', + eqeqeq: 'warn', + 'max-lines-per-function': 'warn', + 'max-lines': 'warn', + 'no-shadow': 'warn', + 'no-var': 'warn', + 'object-shorthand': 'warn', + 'prefer-arrow-callback': 'warn', + 'prefer-const': 'warn', + 'prefer-object-spread': 'warn', + yoda: 'warn', + // https://github.com/jsx-eslint/eslint-plugin-react#list-of-supported-rules + 'react/jsx-key': 'warn', + 'react/prop-types': 'warn', + 'react/react-in-jsx-scope': 'warn', + 'react/jsx-uses-vars': 'warn', + 'react/jsx-uses-react': 'error', + // https://www.npmjs.com/package/eslint-plugin-react-hooks + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'warn', + }, +}; diff --git a/examples/react-todos-app/.eslintrc.json b/examples/react-todos-app/.eslintrc.json deleted file mode 100644 index 9c50e51ca..000000000 --- a/examples/react-todos-app/.eslintrc.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "root": true, - "env": { - "browser": true, - "es2021": true - }, - "plugins": ["react", "react-hooks"], - "overrides": [ - { - "env": { - "node": true - }, - "files": [".eslintrc.{js,cjs}"], - "parserOptions": { - "sourceType": "script" - } - } - ], - "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module", - "ecmaFeatures": { - "jsx": true - } - }, - "settings": { - "react": { - "version": "detect" - } - }, - "rules": { - "no-cond-assign": "warn", - "no-const-assign": "warn", - "no-debugger": "warn", - "no-invalid-regexp": "warn", - "no-undef": "warn", - "no-unreachable-loop": "warn", - "no-unsafe-negation": "warn", - "no-unsafe-optional-chaining": "warn", - "no-unused-vars": "warn", - "use-isnan": "warn", - "valid-typeof": "warn", - "arrow-body-style": "warn", - "camelcase": "warn", - "curly": "warn", - "eqeqeq": "warn", - "max-lines-per-function": "warn", - "max-lines": "warn", - "no-shadow": "warn", - "no-var": "warn", - "object-shorthand": "warn", - "prefer-arrow-callback": "warn", - "prefer-const": "warn", - "prefer-object-spread": "warn", - "yoda": "warn", - "react/jsx-key": "warn", - "react/prop-types": "warn", - "react/react-in-jsx-scope": "warn", - "react/jsx-uses-vars": "warn", - "react/jsx-uses-react": "error", - "react-hooks/rules-of-hooks": "error", - "react-hooks/exhaustive-deps": "warn" - } -} diff --git a/examples/react-todos-app/code-pushup.config.ts b/examples/react-todos-app/code-pushup.config.js similarity index 93% rename from examples/react-todos-app/code-pushup.config.ts rename to examples/react-todos-app/code-pushup.config.js index 60780c794..dcef94a7f 100644 --- a/examples/react-todos-app/code-pushup.config.ts +++ b/examples/react-todos-app/code-pushup.config.js @@ -1,5 +1,5 @@ -import coveragePlugin from '@code-pushup/coverage-plugin'; -import eslintPlugin from '@code-pushup/eslint-plugin'; +import coveragePlugin from '../../dist/packages/plugin-coverage'; +import eslintPlugin from '../../dist/packages/plugin-eslint'; const eslintAuditRef = (slug, weight) => ({ type: 'audit', @@ -21,7 +21,7 @@ export default { }, }), await eslintPlugin({ - eslintrc: '.eslintrc.json', + eslintrc: '.eslintrc.js', patterns: ['src/**/*.js', 'src/**/*.jsx'], }), ], From edaa857356da1aa8c417a01c33335a18b4971c56 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 16:37:06 +0100 Subject: [PATCH 10/80] use minimal eslint rules --- .../__snapshots__/collect.e2e.test.ts.snap | 139 ++++++++++++++++++ .../tests/collect.e2e.test.ts | 17 ++- .../eslint-e2e-env/.eslintrc.json | 4 +- .../eslint-e2e-env/code-pushup.config.ts | 19 ++- .../eslint-e2e-env/src/index.js | 6 +- 5 files changed, 176 insertions(+), 9 deletions(-) create mode 100644 e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap diff --git a/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap new file mode 100644 index 000000000..39f169153 --- /dev/null +++ b/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -0,0 +1,139 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`collect report with eslint-plugin NPM package > should run ESLint plugin and create report.json 1`] = ` +{ + "categories": [ + { + "description": "Lint rules that find **potential bugs** in your code.", + "refs": [ + { + "plugin": "eslint", + "slug": "problems", + "type": "group", + "weight": 1, + }, + ], + "slug": "bug-prevention", + "title": "Bug prevention", + }, + { + "description": "Lint rules that promote **good practices** and consistency in your code.", + "refs": [ + { + "plugin": "eslint", + "slug": "suggestions", + "type": "group", + "weight": 1, + }, + ], + "slug": "code-style", + "title": "Code style", + }, + ], + "packageName": "@code-pushup/core", + "plugins": [ + { + "audits": [ + { + "description": "ESLint rule **no-unused-vars**.", + "details": { + "issues": [ + { + "message": "'unusedFn' is defined but never used.", + "severity": "error", + "source": { + "file": "static-environments/eslint-e2e-env/src/index.js", + "position": { + "endColumn": 18, + "endLine": 1, + "startColumn": 10, + "startLine": 1, + }, + }, + }, + ], + }, + "displayValue": "1 error", + "docsUrl": "https://eslint.org/docs/latest/rules/no-unused-vars", + "score": 0, + "slug": "no-unused-vars", + "title": "Disallow unused variables", + "value": 1, + }, + { + "description": "ESLint rule **no-console**.", + "details": { + "issues": [ + { + "message": "Unexpected console statement.", + "severity": "warning", + "source": { + "file": "static-environments/eslint-e2e-env/src/index.js", + "position": { + "endColumn": 14, + "endLine": 6, + "startColumn": 3, + "startLine": 6, + }, + }, + }, + ], + }, + "displayValue": "1 warning", + "docsUrl": "https://eslint.org/docs/latest/rules/no-console", + "score": 0, + "slug": "no-console", + "title": "Disallow the use of \`console\`", + "value": 1, + }, + { + "description": "ESLint rule **no-undef**.", + "details": { + "issues": [], + }, + "displayValue": "passed", + "docsUrl": "https://eslint.org/docs/latest/rules/no-undef", + "score": 1, + "slug": "no-undef", + "title": "Disallow the use of undeclared variables unless mentioned in \`/*global */\` comments", + "value": 0, + }, + ], + "description": "Official Code PushUp ESLint plugin", + "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", + "groups": [ + { + "description": "Code that either will cause an error or may cause confusing behavior. Developers should consider this a high priority to resolve.", + "refs": [ + { + "slug": "no-unused-vars", + "weight": 1, + }, + { + "slug": "no-undef", + "weight": 1, + }, + ], + "slug": "problems", + "title": "Problems", + }, + { + "description": "Something that could be done in a better way but no errors will occur if the code isn't changed.", + "refs": [ + { + "slug": "no-console", + "weight": 1, + }, + ], + "slug": "suggestions", + "title": "Suggestions", + }, + ], + "icon": "eslint", + "packageName": "@code-pushup/eslint-plugin", + "slug": "eslint", + "title": "ESLint", + }, + ], +} +`; diff --git a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts index 05e45277b..17d7d05be 100644 --- a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts @@ -1,4 +1,4 @@ -import { join } from 'node:path'; +import { join, relative } from 'node:path'; import { afterEach } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; import { teardownTestFolder } from '@code-pushup/test-setup'; @@ -6,29 +6,34 @@ import { omitVariableReportData } from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; describe('collect report with eslint-plugin NPM package', () => { - const baseDir = 'static-environments/eslint-e2e-env/__tests__'; + const envRoot = 'static-environments/eslint-e2e-env'; + const baseDir = join(envRoot, '__tests__'); afterEach(async () => { - // await teardownTestFolder(baseDir); + await teardownTestFolder(baseDir); }); it('should run ESLint plugin and create report.json', async () => { + const outputDir = relative( + envRoot, + join(baseDir, 'default-report', '.code-pushup'), + ); const { code, stderr } = await executeProcess({ command: 'npx', args: [ '@code-pushup/cli', 'collect', - `--persist.outputDir=${join(baseDir, '.code-pushup')}`, + `--persist.outputDir=${outputDir}`, '--no-progress', '--onlyPlugins=eslint', ], - cwd: baseDir, + cwd: envRoot, }); expect(code).toBe(0); expect(stderr).toBe(''); - const report = await readJsonFile(join(baseDir, 'code-pushup/report.json')); + const report = await readJsonFile(join(envRoot, outputDir, 'report.json')); expect(() => reportSchema.parse(report)).not.toThrow(); expect(omitVariableReportData(report as Report)).toMatchSnapshot(); diff --git a/static-environments/eslint-e2e-env/.eslintrc.json b/static-environments/eslint-e2e-env/.eslintrc.json index d9684a6dd..113136c93 100644 --- a/static-environments/eslint-e2e-env/.eslintrc.json +++ b/static-environments/eslint-e2e-env/.eslintrc.json @@ -11,7 +11,9 @@ "sourceType": "script" }, "rules": { - "no-unused-vars": "error" + "no-unused-vars": "error", + "no-console": "warn", + "no-undef": "error" } } ] diff --git a/static-environments/eslint-e2e-env/code-pushup.config.ts b/static-environments/eslint-e2e-env/code-pushup.config.ts index 8895efa4a..01feaf2ff 100644 --- a/static-environments/eslint-e2e-env/code-pushup.config.ts +++ b/static-environments/eslint-e2e-env/code-pushup.config.ts @@ -4,7 +4,24 @@ export default { plugins: [ await eslintPlugin({ eslintrc: '.eslintrc.json', - patterns: ['*.js'], + patterns: ['src/*.js'], }), ], + categories: [ + { + slug: 'bug-prevention', + title: 'Bug prevention', + description: 'Lint rules that find **potential bugs** in your code.', + refs: [{ type: 'group', plugin: 'eslint', slug: 'problems', weight: 1 }], + }, + { + slug: 'code-style', + title: 'Code style', + description: + 'Lint rules that promote **good practices** and consistency in your code.', + refs: [ + { type: 'group', plugin: 'eslint', slug: 'suggestions', weight: 1 }, + ], + }, + ], }; diff --git a/static-environments/eslint-e2e-env/src/index.js b/static-environments/eslint-e2e-env/src/index.js index 7b2d56d8e..4710a3767 100644 --- a/static-environments/eslint-e2e-env/src/index.js +++ b/static-environments/eslint-e2e-env/src/index.js @@ -1,3 +1,7 @@ -function random(unused) { +function unusedFn() { return '42'; } + +module.exports = function consoleLog() { + console.log('No console.log()!'); +}; From efd1b07170e6508b77acebf5a8afff0d7632e0b7 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 16:47:19 +0100 Subject: [PATCH 11/80] wip --- nx.json | 15 ++++++++++++++- static-environments/eslint-e2e-env/project.json | 15 +-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/nx.json b/nx.json index b660413ce..55fc16bb7 100644 --- a/nx.json +++ b/nx.json @@ -29,7 +29,20 @@ "dependsOn": ["^build"] }, "nxv-env-setup": { - "executor": "@push-based/nx-verdaccio:env-setup" + "cache": true, + "inputs": [ + "{projectRoot}/project.json", + { + "runtime": "node --version" + }, + { + "runtime": "npm --version" + }, + { + "externalDependencies": ["verdaccio"] + }, + "^production" + ] }, "@nx/vite:test": { "cache": true, diff --git a/static-environments/eslint-e2e-env/project.json b/static-environments/eslint-e2e-env/project.json index 76c90ba64..857adc78f 100644 --- a/static-environments/eslint-e2e-env/project.json +++ b/static-environments/eslint-e2e-env/project.json @@ -3,19 +3,6 @@ "$schema": "../../node_modules/nx/schemas/project-schema.json", "sourceRoot": "static-environments/eslint-e2e-env/src", "projectType": "library", - "targets": { - "lint": { - "command": "npx eslint src", - "options": { - "cwd": "static-environments/eslint-e2e-env" - } - }, - "run-collect": { - "command": "npx @code-pushup/cli collect", - "options": { - "cwd": "static-environments/eslint-e2e-env" - } - } - }, + "targets": {}, "tags": ["scope:internal", "type:feature"] } From f4253d0263e4f63c0be3085640ef2761f9210ebf Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 16:56:55 +0100 Subject: [PATCH 12/80] wip --- nx.json | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/nx.json b/nx.json index 55fc16bb7..c0cddefbf 100644 --- a/nx.json +++ b/nx.json @@ -84,23 +84,7 @@ "appsDir": "examples", "libsDir": "packages" }, - "generators": { - "@nx/react": { - "application": { - "style": "css", - "linter": "eslint", - "bundler": "vite", - "babel": true - }, - "component": { - "style": "css" - }, - "library": { - "style": "css", - "linter": "eslint" - } - } - }, + "generators": {}, "release": { "projects": ["packages/*"], "projectsRelationship": "fixed", From f9911fbdf092d23c0be589ac43f0400c087f0ebf Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 17:23:27 +0100 Subject: [PATCH 13/80] wip --- nx.json | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/nx.json b/nx.json index c0cddefbf..c7603298b 100644 --- a/nx.json +++ b/nx.json @@ -29,20 +29,7 @@ "dependsOn": ["^build"] }, "nxv-env-setup": { - "cache": true, - "inputs": [ - "{projectRoot}/project.json", - { - "runtime": "node --version" - }, - { - "runtime": "npm --version" - }, - { - "externalDependencies": ["verdaccio"] - }, - "^production" - ] + "executor": "@push-based/nx-verdaccio:env-setup" }, "@nx/vite:test": { "cache": true, From 5f0dfbe2793906f066567c9e79fa817ac34aa972 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 17:37:42 +0100 Subject: [PATCH 14/80] reduce configuration --- e2e/plugin-eslint-e2e/project.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/e2e/plugin-eslint-e2e/project.json b/e2e/plugin-eslint-e2e/project.json index a1a657ed4..6487d3102 100644 --- a/e2e/plugin-eslint-e2e/project.json +++ b/e2e/plugin-eslint-e2e/project.json @@ -19,8 +19,7 @@ "e2e": { "executor": "@nx/vite:test", "options": { - "configFile": "e2e/plugin-eslint-e2e/vite.config.e2e.ts", - "environmentRoot": "static-environments/eslint-e2e-env" + "configFile": "e2e/plugin-eslint-e2e/vite.config.e2e.ts" } } }, From 14ad3c09701b8d56c613954dec53f977ae78207f Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 17:39:46 +0100 Subject: [PATCH 15/80] wip --- examples/react-todos-app/package.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 examples/react-todos-app/package.json diff --git a/examples/react-todos-app/package.json b/examples/react-todos-app/package.json new file mode 100644 index 000000000..d9e892a84 --- /dev/null +++ b/examples/react-todos-app/package.json @@ -0,0 +1,16 @@ +{ + "name": "todo-app", + "private": true, + "scripts": { + "start": "esbuild src/index.jsx --bundle --outdir=www/js --servedir=www", + "build": "esbuild src/index.jsx --bundle --outdir=www/js --minify" + }, + "dependencies": { + "react": "^16.12.0", + "semver": "5.7.1" + }, + "devDependencies": { + "vite": "~4.5.0", + "vitest": "0.34.0" + } +} From 83bdb9864211c13c650b6313205e9f305c015850 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 17:48:59 +0100 Subject: [PATCH 16/80] update nx-verdaccio to alpha.26 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 80639ae4b..960950fda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,7 +49,7 @@ "@nx/react": "17.3.2", "@nx/vite": "17.3.2", "@nx/workspace": "17.3.2", - "@push-based/nx-verdaccio": "0.0.0-alpha.25", + "@push-based/nx-verdaccio": "0.0.0-alpha.26", "@swc-node/register": "^1.10.9", "@swc/cli": "~0.1.62", "@swc/core": "^1.3.99", @@ -5457,9 +5457,9 @@ } }, "node_modules/@push-based/nx-verdaccio": { - "version": "0.0.0-alpha.25", - "resolved": "https://registry.npmjs.org/@push-based/nx-verdaccio/-/nx-verdaccio-0.0.0-alpha.25.tgz", - "integrity": "sha512-5keAr9Gpw0TjUEwtMZVu/qweBYPPHHxHRNaRJgw94uOGSwcQwFcYn92w3+Z4/VdXhM0/RINALGc+/DgG1PV5fg==", + "version": "0.0.0-alpha.26", + "resolved": "https://registry.npmjs.org/@push-based/nx-verdaccio/-/nx-verdaccio-0.0.0-alpha.26.tgz", + "integrity": "sha512-Go11Dg+w5Ntl5Ig8YNzVVPbpOG85aVszjyBIK0FvVBX+/QllQY1F4fP8K8fYnMJnO9v5Tao3cryGFY5Zo9i+/g==", "dev": true, "dependencies": { "@nx/devkit": "19.8.0", diff --git a/package.json b/package.json index da4f9fb46..354f89a4b 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "@nx/react": "17.3.2", "@nx/vite": "17.3.2", "@nx/workspace": "17.3.2", - "@push-based/nx-verdaccio": "0.0.0-alpha.25", + "@push-based/nx-verdaccio": "0.0.0-alpha.26", "@swc-node/register": "^1.10.9", "@swc/cli": "~0.1.62", "@swc/core": "^1.3.99", From 7dad5b5ac47ae7a992ef07cba007daf4271b5c34 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 18:42:25 +0100 Subject: [PATCH 17/80] test: split coverage tests --- e2e/plugin-coverage-e2e/.eslintrc.json | 12 ++ e2e/plugin-coverage-e2e/project.json | 28 ++++ .../__snapshots__/collect.e2e.test.ts.snap | 129 ++++++++++++++++++ .../tests/collect.e2e.test.ts | 72 ++++++++++ e2e/plugin-coverage-e2e/tsconfig.json | 20 +++ e2e/plugin-coverage-e2e/tsconfig.test.json | 14 ++ e2e/plugin-coverage-e2e/vite.config.e2e.ts | 21 +++ nx.json | 21 +-- package-lock.json | 8 +- package.json | 2 +- .../coverage-e2e-env/.gitignore | 3 + .../coverage-e2e-env/code-pushup.config.ts | 16 +++ .../coverage-e2e-env/project.json | 8 ++ .../coverage-e2e-env/src/index.mjs | 16 +++ .../coverage-e2e-env/src/index.test.mjs | 20 +++ .../coverage-e2e-env/vite.config.ts | 25 ++++ 16 files changed, 393 insertions(+), 22 deletions(-) create mode 100644 e2e/plugin-coverage-e2e/.eslintrc.json create mode 100644 e2e/plugin-coverage-e2e/project.json create mode 100644 e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap create mode 100644 e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts create mode 100644 e2e/plugin-coverage-e2e/tsconfig.json create mode 100644 e2e/plugin-coverage-e2e/tsconfig.test.json create mode 100644 e2e/plugin-coverage-e2e/vite.config.e2e.ts create mode 100644 static-environments/coverage-e2e-env/.gitignore create mode 100644 static-environments/coverage-e2e-env/code-pushup.config.ts create mode 100644 static-environments/coverage-e2e-env/project.json create mode 100644 static-environments/coverage-e2e-env/src/index.mjs create mode 100644 static-environments/coverage-e2e-env/src/index.test.mjs create mode 100644 static-environments/coverage-e2e-env/vite.config.ts diff --git a/e2e/plugin-coverage-e2e/.eslintrc.json b/e2e/plugin-coverage-e2e/.eslintrc.json new file mode 100644 index 000000000..7ef7b6dc8 --- /dev/null +++ b/e2e/plugin-coverage-e2e/.eslintrc.json @@ -0,0 +1,12 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*", "code-pushup.config*.ts"], + "overrides": [ + { + "files": ["*.ts", "*.tsx"], + "parserOptions": { + "project": ["e2e/plugin-coverage-e2e/tsconfig.*?.json"] + } + } + ] +} diff --git a/e2e/plugin-coverage-e2e/project.json b/e2e/plugin-coverage-e2e/project.json new file mode 100644 index 000000000..fdf8f2e3c --- /dev/null +++ b/e2e/plugin-coverage-e2e/project.json @@ -0,0 +1,28 @@ +{ + "name": "plugin-coverage-e2e", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "e2e/plugin-coverage-e2e/src", + "projectType": "application", + "targets": { + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["e2e/plugin-coverage-e2e/**/*.ts"] + } + }, + "nxv-env-setup": { + "options": { + "environmentRoot": "static-environments/coverage-e2e-env" + } + }, + "e2e": { + "executor": "@nx/vite:test", + "options": { + "configFile": "e2e/plugin-coverage-e2e/vite.config.e2e.ts" + } + } + }, + "implicitDependencies": ["cli", "plugin-coverage", "coverage-e2e-env"], + "tags": ["scope:plugin", "type:e2e"] +} diff --git a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap new file mode 100644 index 000000000..4dfa1545d --- /dev/null +++ b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -0,0 +1,129 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`collect report with coverage-plugin NPM package > should run Code coverage plugin that runs coverage tool and creates report.json 1`] = ` +{ + "categories": [], + "packageName": "@code-pushup/core", + "plugins": [ + { + "audits": [ + { + "description": "Measures how many functions were called in at least one test.", + "details": { + "issues": [ + { + "message": "Function untested is not called in any test case.", + "severity": "error", + "source": { + "file": "static-environments/coverage-e2e-env/src/index.mjs", + "position": { + "startLine": 1, + }, + }, + }, + ], + }, + "displayValue": "66.7 %", + "score": 0.6667, + "slug": "function-coverage", + "title": "Function coverage", + "value": 66.66666666666666, + }, + { + "description": "Measures how many branches were executed after conditional statements in at least one test.", + "details": { + "issues": [ + { + "message": "1st branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "static-environments/coverage-e2e-env/src/index.mjs", + "position": { + "startLine": 11, + }, + }, + }, + { + "message": "1st branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "static-environments/coverage-e2e-env/src/index.mjs", + "position": { + "startLine": 15, + }, + }, + }, + ], + }, + "displayValue": "50 %", + "score": 0.5, + "slug": "branch-coverage", + "title": "Branch coverage", + "value": 50, + }, + { + "description": "Measures how many lines of code were executed in at least one test.", + "details": { + "issues": [ + { + "message": "Lines 2-3 are not covered in any test case.", + "severity": "warning", + "source": { + "file": "static-environments/coverage-e2e-env/src/index.mjs", + "position": { + "endLine": 3, + "startLine": 2, + }, + }, + }, + { + "message": "Lines 12-13 are not covered in any test case.", + "severity": "warning", + "source": { + "file": "static-environments/coverage-e2e-env/src/index.mjs", + "position": { + "endLine": 13, + "startLine": 12, + }, + }, + }, + ], + }, + "displayValue": "75 %", + "score": 0.75, + "slug": "line-coverage", + "title": "Line coverage", + "value": 75, + }, + ], + "description": "Official Code PushUp code coverage plugin.", + "docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/", + "groups": [ + { + "description": "Group containing all defined coverage types as audits.", + "refs": [ + { + "slug": "function-coverage", + "weight": 6, + }, + { + "slug": "branch-coverage", + "weight": 3, + }, + { + "slug": "line-coverage", + "weight": 1, + }, + ], + "slug": "coverage", + "title": "Code coverage metrics", + }, + ], + "icon": "folder-coverage-open", + "packageName": "@code-pushup/coverage-plugin", + "slug": "coverage", + "title": "Code coverage", + }, + ], +} +`; diff --git a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts new file mode 100644 index 000000000..5ed03a756 --- /dev/null +++ b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts @@ -0,0 +1,72 @@ +import {dirname, join} from 'node:path'; +import {afterEach} from 'vitest'; +import {teardownTestFolder} from '@code-pushup/test-setup'; +import {fileURLToPath} from "node:url"; +import {executeProcess, readJsonFile} from "@code-pushup/utils"; +import {type Report, reportSchema} from "@code-pushup/models"; +import {omitVariableReportData} from "@code-pushup/test-utils"; + +describe('collect report with coverage-plugin NPM package', () => { + const envRoot = 'static-environments/coverage-e2e-env'; + const baseDir = join(envRoot, '__tests__'); + + afterEach(async () => { + await teardownTestFolder(baseDir); + }); + + it('should run Code coverage plugin which collects passed results and creates report.json', async () => { + /** + * The stats passed in the fixture are as follows + * 3 files: one partially covered, one with no coverage, one with full coverage + * Functions: 2 + 1 + 2 found | 1 + 0 + 2 covered (60% coverage) + * Branches: 10 + 2 + 5 found | 8 + 0 + 5 covered (76% coverage) + * Lines: 10 + 5 + 10 found | 7 + 0 + 10 covered (68% coverage) + */ + + const configPath = join( + fileURLToPath(dirname(import.meta.url)), + '..', + 'mocks', + 'fixtures', + 'code-pushup.config.ts', + ); + + const {code, stderr} = await executeProcess({ + command: 'npx', + args: [ + '@code-pushup/cli', + 'collect', + '--no-progress', + `--config=${configPath}`, + '--persist.outputDir=tmp/e2e', + '--onlyPlugins=coverage', + ], + }); + + expect(code).toBe(0); + expect(stderr).toBe(''); + + const report = await readJsonFile(join(envRoot, 'e2e', 'report.json')); + + expect(() => reportSchema.parse(report)).not.toThrow(); + expect(omitVariableReportData(report as Report)).toMatchSnapshot(); + }); + + it('should run Code coverage plugin that runs coverage tool and creates report.json', async () => { + const {code, stderr} = await executeProcess({ + command: 'npx', + args: ['@code-pushup/cli', 'collect', '--no-progress', '--onlyPlugins=coverage'], + cwd: 'examples/react-todos-app', + }); + + expect(code).toBe(0); + expect(stderr).toBe(''); + + const report = await readJsonFile(join(envRoot, '.code-pushup/report.json')); + + expect(() => reportSchema.parse(report)).not.toThrow(); + expect(omitVariableReportData(report as Report)).toMatchSnapshot(); + }); + + +}); diff --git a/e2e/plugin-coverage-e2e/tsconfig.json b/e2e/plugin-coverage-e2e/tsconfig.json new file mode 100644 index 000000000..f5a2f890a --- /dev/null +++ b/e2e/plugin-coverage-e2e/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "ESNext", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "types": ["vitest"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.test.json" + } + ] +} diff --git a/e2e/plugin-coverage-e2e/tsconfig.test.json b/e2e/plugin-coverage-e2e/tsconfig.test.json new file mode 100644 index 000000000..10c7f79de --- /dev/null +++ b/e2e/plugin-coverage-e2e/tsconfig.test.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"], + "target": "ES2020" + }, + "include": [ + "vite.config.e2e.ts", + "tests/**/*.e2e.test.ts", + "tests/**/*.d.ts", + "mocks/**/*.ts" + ] +} diff --git a/e2e/plugin-coverage-e2e/vite.config.e2e.ts b/e2e/plugin-coverage-e2e/vite.config.e2e.ts new file mode 100644 index 000000000..3956da52e --- /dev/null +++ b/e2e/plugin-coverage-e2e/vite.config.e2e.ts @@ -0,0 +1,21 @@ +/// +import { defineConfig } from 'vite'; +import { tsconfigPathAliases } from '../../tools/vitest-tsconfig-path-aliases'; + +export default defineConfig({ + cacheDir: '../../node_modules/.vite/plugin-lighthouse-e2e', + test: { + reporters: ['basic'], + testTimeout: 120_000, + globals: true, + alias: tsconfigPathAliases(), + pool: 'threads', + poolOptions: { threads: { singleThread: true } }, + cache: { + dir: '../../node_modules/.vitest', + }, + environment: 'node', + include: ['tests/**/*.e2e.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + setupFiles: ['../../testing/test-setup/src/lib/reset.mocks.ts'], + }, +}); diff --git a/nx.json b/nx.json index bebd69d65..c7603298b 100644 --- a/nx.json +++ b/nx.json @@ -28,6 +28,9 @@ "e2e": { "dependsOn": ["^build"] }, + "nxv-env-setup": { + "executor": "@push-based/nx-verdaccio:env-setup" + }, "@nx/vite:test": { "cache": true, "inputs": ["default", "^production"], @@ -68,23 +71,7 @@ "appsDir": "examples", "libsDir": "packages" }, - "generators": { - "@nx/react": { - "application": { - "style": "css", - "linter": "eslint", - "bundler": "vite", - "babel": true - }, - "component": { - "style": "css" - }, - "library": { - "style": "css", - "linter": "eslint" - } - } - }, + "generators": {}, "release": { "projects": ["packages/*"], "projectsRelationship": "fixed", diff --git a/package-lock.json b/package-lock.json index 80639ae4b..960950fda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,7 +49,7 @@ "@nx/react": "17.3.2", "@nx/vite": "17.3.2", "@nx/workspace": "17.3.2", - "@push-based/nx-verdaccio": "0.0.0-alpha.25", + "@push-based/nx-verdaccio": "0.0.0-alpha.26", "@swc-node/register": "^1.10.9", "@swc/cli": "~0.1.62", "@swc/core": "^1.3.99", @@ -5457,9 +5457,9 @@ } }, "node_modules/@push-based/nx-verdaccio": { - "version": "0.0.0-alpha.25", - "resolved": "https://registry.npmjs.org/@push-based/nx-verdaccio/-/nx-verdaccio-0.0.0-alpha.25.tgz", - "integrity": "sha512-5keAr9Gpw0TjUEwtMZVu/qweBYPPHHxHRNaRJgw94uOGSwcQwFcYn92w3+Z4/VdXhM0/RINALGc+/DgG1PV5fg==", + "version": "0.0.0-alpha.26", + "resolved": "https://registry.npmjs.org/@push-based/nx-verdaccio/-/nx-verdaccio-0.0.0-alpha.26.tgz", + "integrity": "sha512-Go11Dg+w5Ntl5Ig8YNzVVPbpOG85aVszjyBIK0FvVBX+/QllQY1F4fP8K8fYnMJnO9v5Tao3cryGFY5Zo9i+/g==", "dev": true, "dependencies": { "@nx/devkit": "19.8.0", diff --git a/package.json b/package.json index da4f9fb46..354f89a4b 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "@nx/react": "17.3.2", "@nx/vite": "17.3.2", "@nx/workspace": "17.3.2", - "@push-based/nx-verdaccio": "0.0.0-alpha.25", + "@push-based/nx-verdaccio": "0.0.0-alpha.26", "@swc-node/register": "^1.10.9", "@swc/cli": "~0.1.62", "@swc/core": "^1.3.99", diff --git a/static-environments/coverage-e2e-env/.gitignore b/static-environments/coverage-e2e-env/.gitignore new file mode 100644 index 000000000..9e76e5c81 --- /dev/null +++ b/static-environments/coverage-e2e-env/.gitignore @@ -0,0 +1,3 @@ +coverage +node_modules +.code-pushup diff --git a/static-environments/coverage-e2e-env/code-pushup.config.ts b/static-environments/coverage-e2e-env/code-pushup.config.ts new file mode 100644 index 000000000..6421554cf --- /dev/null +++ b/static-environments/coverage-e2e-env/code-pushup.config.ts @@ -0,0 +1,16 @@ +import coveragePlugin from '@code-pushup/coverage-plugin'; + +export default { + plugins: [ + await coveragePlugin({ + reports: ['coverage/lcov.info'], + coverageToolCommand: { + command: 'npx', + args: ['vitest', 'run', '--coverage'], + }, + }), + ], + categories: [ + + ], +}; diff --git a/static-environments/coverage-e2e-env/project.json b/static-environments/coverage-e2e-env/project.json new file mode 100644 index 000000000..f8d390e28 --- /dev/null +++ b/static-environments/coverage-e2e-env/project.json @@ -0,0 +1,8 @@ +{ + "name": "coverage-e2e-env", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "static-environments/coverage-e2e-env/src", + "projectType": "library", + "targets": {}, + "tags": ["scope:internal", "type:feature"] +} diff --git a/static-environments/coverage-e2e-env/src/index.mjs b/static-environments/coverage-e2e-env/src/index.mjs new file mode 100644 index 000000000..18178fd1a --- /dev/null +++ b/static-environments/coverage-e2e-env/src/index.mjs @@ -0,0 +1,16 @@ +export function untested() { + console.log('This function is not tested'); +}; + +export function get42() { + return 42; +}; + +export function isEven(num) { + if(num === undefined){ + return false; + } + const parsedNumber = parseInt(num, 10); + return parsedNumber % 2 === 0; +}; + diff --git a/static-environments/coverage-e2e-env/src/index.test.mjs b/static-environments/coverage-e2e-env/src/index.test.mjs new file mode 100644 index 000000000..992e13f71 --- /dev/null +++ b/static-environments/coverage-e2e-env/src/index.test.mjs @@ -0,0 +1,20 @@ +import {describe, expect, it} from "vitest"; +import {get42, isEven, untested} from "./index"; + +describe("get42", () => { + it("should return 42", async () => { + expect(get42()).toBe(42); + }); +}); + +describe("isEven", () => { + it("should return true for even number 42", async () => { + expect(isEven(42)).toBe(true); + }); + + it.todo("should return false for odd number 1") +}); + +describe.todo("untested", () => { + +}); diff --git a/static-environments/coverage-e2e-env/vite.config.ts b/static-environments/coverage-e2e-env/vite.config.ts new file mode 100644 index 000000000..7051bfcef --- /dev/null +++ b/static-environments/coverage-e2e-env/vite.config.ts @@ -0,0 +1,25 @@ +/// +import {dirname} from 'node:path'; +import {fileURLToPath} from 'node:url'; +import {defineConfig} from 'vite'; + +export default defineConfig({ + root: fileURLToPath(dirname(import.meta.url)), + cacheDir: 'node_modules/.vite/coverage-e2e-env', + + test: { + reporters: ['basic'], + globals: true, + cache: { + dir: 'node_modules/.vitest', + }, + coverage: { + reporter: ['lcov', 'text'], + provider: 'v8', + reportsDirectory: 'coverage', + include: ['src/**/*.{js,mjs}'], + }, + environment: 'node', + include: ['src/**/*.{test,spec}.{js,mjs}'] + }, +}); From e8cba86a402a45534cabd009e570523094e168fd Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 18:57:05 +0100 Subject: [PATCH 18/80] config --- e2e/cli-e2e/tests/collect.e2e.test.ts | 55 ------------- .../__snapshots__/collect.e2e.test.ts.snap | 45 ++++++----- .../tests/collect.e2e.test.ts | 49 ++++++------ .../coverage-e2e-env/code-pushup.config.ts | 13 +++- .../code-pushup.existing-report.config.ts | 25 ++++++ .../coverage-e2e-env/mocks/fixtures/lcov.info | 78 +++++++++++++++++++ .../coverage-e2e-env/src/index.mjs | 9 +-- .../coverage-e2e-env/src/index.test.mjs | 18 ++--- .../coverage-e2e-env/vite.config.ts | 8 +- 9 files changed, 179 insertions(+), 121 deletions(-) create mode 100644 static-environments/coverage-e2e-env/code-pushup.existing-report.config.ts create mode 100644 static-environments/coverage-e2e-env/mocks/fixtures/lcov.info diff --git a/e2e/cli-e2e/tests/collect.e2e.test.ts b/e2e/cli-e2e/tests/collect.e2e.test.ts index 5e301ab29..269fae9fb 100644 --- a/e2e/cli-e2e/tests/collect.e2e.test.ts +++ b/e2e/cli-e2e/tests/collect.e2e.test.ts @@ -1,5 +1,3 @@ -import { dirname, join } from 'node:path'; -import { fileURLToPath } from 'node:url'; import { type AuditReport, type PluginReport, @@ -65,59 +63,6 @@ describe('CLI collect', () => { expect(omitVariableReportData(report as Report)).toMatchSnapshot(); }); - it('should run Code coverage plugin which collects passed results and creates report.json', async () => { - /** - * The stats passed in the fixture are as follows - * 3 files: one partially covered, one with no coverage, one with full coverage - * Functions: 2 + 1 + 2 found | 1 + 0 + 2 covered (60% coverage) - * Branches: 10 + 2 + 5 found | 8 + 0 + 5 covered (76% coverage) - * Lines: 10 + 5 + 10 found | 7 + 0 + 10 covered (68% coverage) - */ - - const configPath = join( - fileURLToPath(dirname(import.meta.url)), - '..', - 'mocks', - 'fixtures', - 'code-pushup.config.ts', - ); - - const { code, stderr } = await executeProcess({ - command: 'code-pushup', - args: [ - 'collect', - '--no-progress', - `--config=${configPath}`, - '--persist.outputDir=tmp/e2e', - '--onlyPlugins=coverage', - ], - }); - - expect(code).toBe(0); - expect(stderr).toBe(''); - - const report = await readJsonFile(join('tmp', 'e2e', 'report.json')); - - expect(() => reportSchema.parse(report)).not.toThrow(); - expect(omitVariableReportData(report as Report)).toMatchSnapshot(); - }); - - it('should run Code coverage plugin that runs coverage tool and creates report.json', async () => { - const { code, stderr } = await executeProcess({ - command: 'code-pushup', - args: ['collect', '--no-progress', '--onlyPlugins=coverage'], - cwd: 'examples/react-todos-app', - }); - - expect(code).toBe(0); - expect(stderr).toBe(''); - - const report = await readJsonFile('tmp/e2e/react-todos-app/report.json'); - - expect(() => reportSchema.parse(report)).not.toThrow(); - expect(omitVariableReportData(report as Report)).toMatchSnapshot(); - }); - it('should create report.md', async () => { const { code, stderr } = await executeProcess({ command: 'code-pushup', diff --git a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index 4dfa1545d..857acd4f4 100644 --- a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -2,7 +2,20 @@ exports[`collect report with coverage-plugin NPM package > should run Code coverage plugin that runs coverage tool and creates report.json 1`] = ` { - "categories": [], + "categories": [ + { + "refs": [ + { + "plugin": "coverage", + "slug": "coverage", + "type": "group", + "weight": 1, + }, + ], + "slug": "code-coverage", + "title": "Code coverage", + }, + ], "packageName": "@code-pushup/core", "plugins": [ { @@ -39,27 +52,17 @@ exports[`collect report with coverage-plugin NPM package > should run Code cover "source": { "file": "static-environments/coverage-e2e-env/src/index.mjs", "position": { - "startLine": 11, - }, - }, - }, - { - "message": "1st branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "static-environments/coverage-e2e-env/src/index.mjs", - "position": { - "startLine": 15, + "startLine": 10, }, }, }, ], }, - "displayValue": "50 %", - "score": 0.5, + "displayValue": "66.7 %", + "score": 0.6667, "slug": "branch-coverage", "title": "Branch coverage", - "value": 50, + "value": 66.66666666666666, }, { "description": "Measures how many lines of code were executed in at least one test.", @@ -77,23 +80,23 @@ exports[`collect report with coverage-plugin NPM package > should run Code cover }, }, { - "message": "Lines 12-13 are not covered in any test case.", + "message": "Lines 11-12 are not covered in any test case.", "severity": "warning", "source": { "file": "static-environments/coverage-e2e-env/src/index.mjs", "position": { - "endLine": 13, - "startLine": 12, + "endLine": 12, + "startLine": 11, }, }, }, ], }, - "displayValue": "75 %", - "score": 0.75, + "displayValue": "73.3 %", + "score": 0.7333, "slug": "line-coverage", "title": "Line coverage", - "value": 75, + "value": 73.33333333333333, }, ], "description": "Official Code PushUp code coverage plugin.", diff --git a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts index 5ed03a756..4b169df74 100644 --- a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts @@ -1,10 +1,10 @@ -import {dirname, join} from 'node:path'; -import {afterEach} from 'vitest'; -import {teardownTestFolder} from '@code-pushup/test-setup'; -import {fileURLToPath} from "node:url"; -import {executeProcess, readJsonFile} from "@code-pushup/utils"; -import {type Report, reportSchema} from "@code-pushup/models"; -import {omitVariableReportData} from "@code-pushup/test-utils"; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { afterEach } from 'vitest'; +import { type Report, reportSchema } from '@code-pushup/models'; +import { teardownTestFolder } from '@code-pushup/test-setup'; +import { omitVariableReportData } from '@code-pushup/test-utils'; +import { executeProcess, readJsonFile } from '@code-pushup/utils'; describe('collect report with coverage-plugin NPM package', () => { const envRoot = 'static-environments/coverage-e2e-env'; @@ -23,50 +23,49 @@ describe('collect report with coverage-plugin NPM package', () => { * Lines: 10 + 5 + 10 found | 7 + 0 + 10 covered (68% coverage) */ - const configPath = join( - fileURLToPath(dirname(import.meta.url)), - '..', - 'mocks', - 'fixtures', - 'code-pushup.config.ts', - ); - - const {code, stderr} = await executeProcess({ + const { code, stderr } = await executeProcess({ command: 'npx', args: [ '@code-pushup/cli', 'collect', '--no-progress', - `--config=${configPath}`, - '--persist.outputDir=tmp/e2e', + `--config=code-pushup.existing-report.config.ts`, '--onlyPlugins=coverage', ], + cwd: envRoot, }); expect(code).toBe(0); expect(stderr).toBe(''); - const report = await readJsonFile(join(envRoot, 'e2e', 'report.json')); + const report = await readJsonFile( + join(envRoot, '.code-pushup', 'report.json'), + ); expect(() => reportSchema.parse(report)).not.toThrow(); expect(omitVariableReportData(report as Report)).toMatchSnapshot(); }); it('should run Code coverage plugin that runs coverage tool and creates report.json', async () => { - const {code, stderr} = await executeProcess({ + const { code, stderr } = await executeProcess({ command: 'npx', - args: ['@code-pushup/cli', 'collect', '--no-progress', '--onlyPlugins=coverage'], - cwd: 'examples/react-todos-app', + args: [ + '@code-pushup/cli', + 'collect', + '--no-progress', + '--onlyPlugins=coverage', + ], + cwd: envRoot, }); expect(code).toBe(0); expect(stderr).toBe(''); - const report = await readJsonFile(join(envRoot, '.code-pushup/report.json')); + const report = await readJsonFile( + join(envRoot, '.code-pushup/report.json'), + ); expect(() => reportSchema.parse(report)).not.toThrow(); expect(omitVariableReportData(report as Report)).toMatchSnapshot(); }); - - }); diff --git a/static-environments/coverage-e2e-env/code-pushup.config.ts b/static-environments/coverage-e2e-env/code-pushup.config.ts index 6421554cf..7fdd945d5 100644 --- a/static-environments/coverage-e2e-env/code-pushup.config.ts +++ b/static-environments/coverage-e2e-env/code-pushup.config.ts @@ -11,6 +11,17 @@ export default { }), ], categories: [ - + { + slug: 'code-coverage', + title: 'Code coverage', + refs: [ + { + type: 'group', + plugin: 'coverage', + slug: 'coverage', + weight: 1, + }, + ], + }, ], }; diff --git a/static-environments/coverage-e2e-env/code-pushup.existing-report.config.ts b/static-environments/coverage-e2e-env/code-pushup.existing-report.config.ts new file mode 100644 index 000000000..3ecb63128 --- /dev/null +++ b/static-environments/coverage-e2e-env/code-pushup.existing-report.config.ts @@ -0,0 +1,25 @@ +import { join } from 'node:path'; +import coveragePlugin from '@code-pushup/coverage-plugin'; +import type { CoreConfig } from '@code-pushup/models'; + +export default { + plugins: [ + await coveragePlugin({ + reports: [join('e2e', 'cli-e2e', 'mocks', 'fixtures', 'lcov.info')], + }), + ], + categories: [ + { + slug: 'code-coverage', + title: 'Code coverage', + refs: [ + { + type: 'group', + plugin: 'coverage', + slug: 'coverage', + weight: 1, + }, + ], + }, + ], +} satisfies CoreConfig; diff --git a/static-environments/coverage-e2e-env/mocks/fixtures/lcov.info b/static-environments/coverage-e2e-env/mocks/fixtures/lcov.info new file mode 100644 index 000000000..474ad74e7 --- /dev/null +++ b/static-environments/coverage-e2e-env/mocks/fixtures/lcov.info @@ -0,0 +1,78 @@ +TN: +SF:src\lib\partly-covered\utils.ts +FN:2,formatReportScore +FN:6,calcDuration +FNF:2 +FNH:1 +FNDA:0,formatReportScore +FNDA:6,calcDuration +DA:1,1 +DA:2,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:6,1 +DA:7,0 +DA:8,0 +DA:9,0 +DA:10,1 +LF:10 +LH:7 +BRDA:1,0,0,6 +BRDA:1,1,0,5 +BRDA:2,4,0,1 +BRDA:4,5,0,17 +BRDA:5,6,0,4 +BRDA:6,7,0,13 +BRDA:6,10,1,0 +BRDA:7,11,0,3 +BRDA:10,12,0,12 +BRDA:10,13,1,0 +BRF:10 +BRH:8 +end_of_record +SF:src\lib\not-covered\sorting.ts +FN:1,sortReport +FNF:1 +FNH:0 +FNDA:0,sortReport +DA:1,0 +DA:2,0 +DA:3,0 +DA:4,0 +DA:5,0 +LF:5 +LH:0 +BRDA:7,1,0,0 +BRDA:7,2,1,0 +BRF:2 +BRH:0 +end_of_record +TN: +SF:src\lib\fully-covered\scoring.ts +FN:2,scoreReport +FN:8,calculateScore +FNF:2 +FNH:2 +FNDA:3,scoreReport +FNDA:5,calculateScore +DA:1,1 +DA:2,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:6,1 +DA:7,1 +DA:8,1 +DA:9,1 +DA:10,1 +LF:10 +LH:10 +BRDA:1,0,0,5 +BRDA:2,1,0,1 +BRDA:2,2,1,4 +BRDA:2,3,2,3 +BRDA:6,4,0,4 +BRF:5 +BRH:5 +end_of_record diff --git a/static-environments/coverage-e2e-env/src/index.mjs b/static-environments/coverage-e2e-env/src/index.mjs index 18178fd1a..b698a1fac 100644 --- a/static-environments/coverage-e2e-env/src/index.mjs +++ b/static-environments/coverage-e2e-env/src/index.mjs @@ -1,16 +1,15 @@ export function untested() { console.log('This function is not tested'); -}; +} export function get42() { return 42; -}; +} export function isEven(num) { - if(num === undefined){ + if (num === undefined) { return false; } const parsedNumber = parseInt(num, 10); return parsedNumber % 2 === 0; -}; - +} diff --git a/static-environments/coverage-e2e-env/src/index.test.mjs b/static-environments/coverage-e2e-env/src/index.test.mjs index 992e13f71..efef0528b 100644 --- a/static-environments/coverage-e2e-env/src/index.test.mjs +++ b/static-environments/coverage-e2e-env/src/index.test.mjs @@ -1,20 +1,18 @@ -import {describe, expect, it} from "vitest"; -import {get42, isEven, untested} from "./index"; +import { describe, expect, it } from 'vitest'; +import { get42, isEven, untested } from './index'; -describe("get42", () => { - it("should return 42", async () => { +describe('get42', () => { + it('should return 42', async () => { expect(get42()).toBe(42); }); }); -describe("isEven", () => { - it("should return true for even number 42", async () => { +describe('isEven', () => { + it('should return true for even number 42', async () => { expect(isEven(42)).toBe(true); }); - it.todo("should return false for odd number 1") + it.todo('should return false for odd number 1'); }); -describe.todo("untested", () => { - -}); +describe.todo('untested', () => {}); diff --git a/static-environments/coverage-e2e-env/vite.config.ts b/static-environments/coverage-e2e-env/vite.config.ts index 7051bfcef..7a6636feb 100644 --- a/static-environments/coverage-e2e-env/vite.config.ts +++ b/static-environments/coverage-e2e-env/vite.config.ts @@ -1,7 +1,7 @@ /// -import {dirname} from 'node:path'; -import {fileURLToPath} from 'node:url'; -import {defineConfig} from 'vite'; +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { defineConfig } from 'vite'; export default defineConfig({ root: fileURLToPath(dirname(import.meta.url)), @@ -20,6 +20,6 @@ export default defineConfig({ include: ['src/**/*.{js,mjs}'], }, environment: 'node', - include: ['src/**/*.{test,spec}.{js,mjs}'] + include: ['src/**/*.{test,spec}.{js,mjs}'], }, }); From 436673f1ca2cd0ab14f4f14159650b231154ee6b Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 18:57:58 +0100 Subject: [PATCH 19/80] remove duplicate test --- e2e/cli-e2e/tests/collect.e2e.test.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/e2e/cli-e2e/tests/collect.e2e.test.ts b/e2e/cli-e2e/tests/collect.e2e.test.ts index 5e301ab29..f9aa4eefa 100644 --- a/e2e/cli-e2e/tests/collect.e2e.test.ts +++ b/e2e/cli-e2e/tests/collect.e2e.test.ts @@ -49,22 +49,6 @@ describe('CLI collect', () => { await cleanTestFolder('tmp/e2e/react-todos-app'); }); - it('should run ESLint plugin and create report.json', async () => { - const { code, stderr } = await executeProcess({ - command: 'code-pushup', - args: ['collect', '--no-progress', '--onlyPlugins=eslint'], - cwd: 'examples/react-todos-app', - }); - - expect(code).toBe(0); - expect(stderr).toBe(''); - - const report = await readJsonFile('tmp/e2e/react-todos-app/report.json'); - - expect(() => reportSchema.parse(report)).not.toThrow(); - expect(omitVariableReportData(report as Report)).toMatchSnapshot(); - }); - it('should run Code coverage plugin which collects passed results and creates report.json', async () => { /** * The stats passed in the fixture are as follows From 69eba2522893ff4afb78aa28eaf28e18d93cffd5 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 19:01:08 +0100 Subject: [PATCH 20/80] polish --- .../__snapshots__/collect.e2e.test.ts.snap | 171 ++++++++++++++++++ .../tests/collect.e2e.test.ts | 3 +- .../code-pushup.existing-report.config.ts | 2 +- .../coverage-e2e-env/package.json | 17 ++ 4 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 static-environments/coverage-e2e-env/package.json diff --git a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index 857acd4f4..610e3b0a3 100644 --- a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -130,3 +130,174 @@ exports[`collect report with coverage-plugin NPM package > should run Code cover ], } `; + +exports[`collect report with coverage-plugin NPM package > should run Code coverage plugin which collects passed results and creates report.json 1`] = ` +{ + "categories": [ + { + "refs": [ + { + "plugin": "coverage", + "slug": "coverage", + "type": "group", + "weight": 1, + }, + ], + "slug": "code-coverage", + "title": "Code coverage", + }, + ], + "packageName": "@code-pushup/core", + "plugins": [ + { + "audits": [ + { + "description": "Measures how many functions were called in at least one test.", + "details": { + "issues": [ + { + "message": "Function formatReportScore is not called in any test case.", + "severity": "error", + "source": { + "file": "static-environments/coverage-e2e-env/src/lib/partly-covered/utils.ts", + "position": { + "startLine": 2, + }, + }, + }, + { + "message": "Function sortReport is not called in any test case.", + "severity": "error", + "source": { + "file": "static-environments/coverage-e2e-env/src/lib/not-covered/sorting.ts", + "position": { + "startLine": 1, + }, + }, + }, + ], + }, + "displayValue": "60 %", + "score": 0.6, + "slug": "function-coverage", + "title": "Function coverage", + "value": 60, + }, + { + "description": "Measures how many branches were executed after conditional statements in at least one test.", + "details": { + "issues": [ + { + "message": "2nd branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "static-environments/coverage-e2e-env/src/lib/partly-covered/utils.ts", + "position": { + "startLine": 6, + }, + }, + }, + { + "message": "2nd branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "static-environments/coverage-e2e-env/src/lib/partly-covered/utils.ts", + "position": { + "startLine": 10, + }, + }, + }, + { + "message": "1st branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "static-environments/coverage-e2e-env/src/lib/not-covered/sorting.ts", + "position": { + "startLine": 7, + }, + }, + }, + { + "message": "2nd branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "static-environments/coverage-e2e-env/src/lib/not-covered/sorting.ts", + "position": { + "startLine": 7, + }, + }, + }, + ], + }, + "displayValue": "76.5 %", + "score": 0.7647, + "slug": "branch-coverage", + "title": "Branch coverage", + "value": 76.47058823529412, + }, + { + "description": "Measures how many lines of code were executed in at least one test.", + "details": { + "issues": [ + { + "message": "Lines 7-9 are not covered in any test case.", + "severity": "warning", + "source": { + "file": "static-environments/coverage-e2e-env/src/lib/partly-covered/utils.ts", + "position": { + "endLine": 9, + "startLine": 7, + }, + }, + }, + { + "message": "Lines 1-5 are not covered in any test case.", + "severity": "warning", + "source": { + "file": "static-environments/coverage-e2e-env/src/lib/not-covered/sorting.ts", + "position": { + "endLine": 5, + "startLine": 1, + }, + }, + }, + ], + }, + "displayValue": "68 %", + "score": 0.68, + "slug": "line-coverage", + "title": "Line coverage", + "value": 68, + }, + ], + "description": "Official Code PushUp code coverage plugin.", + "docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/", + "groups": [ + { + "description": "Group containing all defined coverage types as audits.", + "refs": [ + { + "slug": "function-coverage", + "weight": 6, + }, + { + "slug": "branch-coverage", + "weight": 3, + }, + { + "slug": "line-coverage", + "weight": 1, + }, + ], + "slug": "coverage", + "title": "Code coverage metrics", + }, + ], + "icon": "folder-coverage-open", + "packageName": "@code-pushup/coverage-plugin", + "slug": "coverage", + "title": "Code coverage", + }, + ], +} +`; diff --git a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts index 4b169df74..6b3a01e42 100644 --- a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts @@ -1,5 +1,4 @@ -import { dirname, join } from 'node:path'; -import { fileURLToPath } from 'node:url'; +import { join } from 'node:path'; import { afterEach } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; import { teardownTestFolder } from '@code-pushup/test-setup'; diff --git a/static-environments/coverage-e2e-env/code-pushup.existing-report.config.ts b/static-environments/coverage-e2e-env/code-pushup.existing-report.config.ts index 3ecb63128..9f6fffbb8 100644 --- a/static-environments/coverage-e2e-env/code-pushup.existing-report.config.ts +++ b/static-environments/coverage-e2e-env/code-pushup.existing-report.config.ts @@ -5,7 +5,7 @@ import type { CoreConfig } from '@code-pushup/models'; export default { plugins: [ await coveragePlugin({ - reports: [join('e2e', 'cli-e2e', 'mocks', 'fixtures', 'lcov.info')], + reports: [join('mocks', 'fixtures', 'lcov.info')], }), ], categories: [ diff --git a/static-environments/coverage-e2e-env/package.json b/static-environments/coverage-e2e-env/package.json new file mode 100644 index 000000000..a300af90f --- /dev/null +++ b/static-environments/coverage-e2e-env/package.json @@ -0,0 +1,17 @@ +{ + "name": "coverage-e2e-env", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@code-pushup/coverage-plugin": "^0.54.0", + "@code-pushup/models": "^0.54.0", + "@code-pushup/utils": "^0.54.0" + }, + "description": "" +} From ff441116c136acd4d5d0310d21b007bda6d2b232 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 19:02:34 +0100 Subject: [PATCH 21/80] polish --- e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts index 6b3a01e42..747fe0571 100644 --- a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts @@ -14,14 +14,6 @@ describe('collect report with coverage-plugin NPM package', () => { }); it('should run Code coverage plugin which collects passed results and creates report.json', async () => { - /** - * The stats passed in the fixture are as follows - * 3 files: one partially covered, one with no coverage, one with full coverage - * Functions: 2 + 1 + 2 found | 1 + 0 + 2 covered (60% coverage) - * Branches: 10 + 2 + 5 found | 8 + 0 + 5 covered (76% coverage) - * Lines: 10 + 5 + 10 found | 7 + 0 + 10 covered (68% coverage) - */ - const { code, stderr } = await executeProcess({ command: 'npx', args: [ From 9ddce4df4d051d5791e470aa4b5c20e30b0d716a Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 19:08:41 +0100 Subject: [PATCH 22/80] remove duplicate CP runs --- .../react-todos-app/code-pushup.config.js | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/examples/react-todos-app/code-pushup.config.js b/examples/react-todos-app/code-pushup.config.js index dcef94a7f..988dca804 100644 --- a/examples/react-todos-app/code-pushup.config.js +++ b/examples/react-todos-app/code-pushup.config.js @@ -1,4 +1,3 @@ -import coveragePlugin from '../../dist/packages/plugin-coverage'; import eslintPlugin from '../../dist/packages/plugin-eslint'; const eslintAuditRef = (slug, weight) => ({ @@ -13,31 +12,12 @@ export default { outputDir: '../../tmp/e2e/react-todos-app', }, plugins: [ - await coveragePlugin({ - reports: ['../../coverage/react-todos-app/lcov.info'], - coverageToolCommand: { - command: 'npx', - args: ['vitest', 'run', '--coverage'], - }, - }), await eslintPlugin({ eslintrc: '.eslintrc.js', patterns: ['src/**/*.js', 'src/**/*.jsx'], }), ], categories: [ - { - slug: 'code-coverage', - title: 'Code coverage', - refs: [ - { - type: 'group', - plugin: 'coverage', - slug: 'coverage', - weight: 1, - }, - ], - }, { slug: 'bug-prevention', title: 'Bug prevention', @@ -60,7 +40,6 @@ export default { eslintAuditRef('react-hooks-exhaustive-deps', 2), ], }, - { slug: 'code-style', title: 'Code style', From 3239423359f83022f8101a9b36d4c17b2286305d Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 19:37:59 +0100 Subject: [PATCH 23/80] add test script --- static-environments/coverage-e2e-env/code-pushup.config.ts | 4 ++-- static-environments/coverage-e2e-env/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/static-environments/coverage-e2e-env/code-pushup.config.ts b/static-environments/coverage-e2e-env/code-pushup.config.ts index 7fdd945d5..8d506c569 100644 --- a/static-environments/coverage-e2e-env/code-pushup.config.ts +++ b/static-environments/coverage-e2e-env/code-pushup.config.ts @@ -5,8 +5,8 @@ export default { await coveragePlugin({ reports: ['coverage/lcov.info'], coverageToolCommand: { - command: 'npx', - args: ['vitest', 'run', '--coverage'], + command: 'npm', + args: ['run', 'test'], }, }), ], diff --git a/static-environments/coverage-e2e-env/package.json b/static-environments/coverage-e2e-env/package.json index a300af90f..34be6d532 100644 --- a/static-environments/coverage-e2e-env/package.json +++ b/static-environments/coverage-e2e-env/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "npx vitest run --coverage" }, "keywords": [], "author": "", From 3ad8ee4b6c4be3be57d953108501a694c0c23403 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 9 Nov 2024 19:47:38 +0100 Subject: [PATCH 24/80] verbose gh action --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 845def216..a8ad36da1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,7 +120,7 @@ jobs: - name: Install dependencies run: npm ci - name: E2E test affected projects - run: npx nx affected -t nxv-e2e --exclude cli-e2e --parallel=1 + run: npx nx affected -t nxv-e2e --exclude cli-e2e --parallel=1 --verbose - name: E2E test cli-e2e project (due to bugs in the setup it has to run last :( ) run: npx nx run cli-e2e:e2e-old From a624b5aa582613597ce6976c71ba305763bf8fa3 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 02:34:14 +0100 Subject: [PATCH 25/80] adjust tests --- e2e/plugin-coverage-e2e/project.json | 5 +++++ nx.json | 1 + static-environments/coverage-e2e-env/package.json | 5 +++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/e2e/plugin-coverage-e2e/project.json b/e2e/plugin-coverage-e2e/project.json index fdf8f2e3c..4c4f76881 100644 --- a/e2e/plugin-coverage-e2e/project.json +++ b/e2e/plugin-coverage-e2e/project.json @@ -11,6 +11,11 @@ "lintFilePatterns": ["e2e/plugin-coverage-e2e/**/*.ts"] } }, + "nxv-e2e": { + "options": { + "environmentRoot": "static-environments/coverage-e2e-env" + } + }, "nxv-env-setup": { "options": { "environmentRoot": "static-environments/coverage-e2e-env" diff --git a/nx.json b/nx.json index c7603298b..299156fe9 100644 --- a/nx.json +++ b/nx.json @@ -28,6 +28,7 @@ "e2e": { "dependsOn": ["^build"] }, + "nxv-e2e": {}, "nxv-env-setup": { "executor": "@push-based/nx-verdaccio:env-setup" }, diff --git a/static-environments/coverage-e2e-env/package.json b/static-environments/coverage-e2e-env/package.json index 34be6d532..c132d93f1 100644 --- a/static-environments/coverage-e2e-env/package.json +++ b/static-environments/coverage-e2e-env/package.json @@ -8,10 +8,11 @@ "keywords": [], "author": "", "license": "ISC", + "description": "", "dependencies": { + "@code-pushup/core": "^0.54.0", "@code-pushup/coverage-plugin": "^0.54.0", "@code-pushup/models": "^0.54.0", "@code-pushup/utils": "^0.54.0" - }, - "description": "" + } } From 7811490caaf023e2c9b421ced789ed2d825c65c3 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 14:03:41 +0100 Subject: [PATCH 26/80] adjust react example setup --- .../__snapshots__/collect.e2e.test.ts.snap | 1421 ----------------- e2e/cli-e2e/tests/collect.e2e.test.ts | 133 +- e2e/cli-e2e/tests/compare.e2e.test.ts | 7 +- .../react-todos-app/code-pushup.config.js | 84 - .../react-todos-app/code-pushup.config.ts | 22 + examples/react-todos-app/dummy.plugin.ts | 34 + nx.json | 21 +- package-lock.json | 8 +- package.json | 2 +- 9 files changed, 84 insertions(+), 1648 deletions(-) delete mode 100644 e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap delete mode 100644 examples/react-todos-app/code-pushup.config.js create mode 100644 examples/react-todos-app/code-pushup.config.ts create mode 100644 examples/react-todos-app/dummy.plugin.ts diff --git a/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap deleted file mode 100644 index 47a9e0f07..000000000 --- a/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ /dev/null @@ -1,1421 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`CLI collect > should run Code coverage plugin that runs coverage tool and creates report.json 1`] = ` -{ - "categories": [ - { - "refs": [ - { - "plugin": "coverage", - "slug": "coverage", - "type": "group", - "weight": 1, - }, - ], - "slug": "code-coverage", - "title": "Code coverage", - }, - ], - "packageName": "@code-pushup/core", - "plugins": [ - { - "audits": [ - { - "description": "Measures how many functions were called in at least one test.", - "details": { - "issues": [ - { - "message": "Function onSubmit is not called in any test case.", - "severity": "error", - "source": { - "file": "examples/react-todos-app/src/components/CreateTodo.jsx", - "position": { - "startLine": 13, - }, - }, - }, - { - "message": "Function onInput is not called in any test case.", - "severity": "error", - "source": { - "file": "examples/react-todos-app/src/components/CreateTodo.jsx", - "position": { - "startLine": 21, - }, - }, - }, - { - "message": "Function onInput is not called in any test case.", - "severity": "error", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "startLine": 9, - }, - }, - }, - { - "message": "Function onChange is not called in any test case.", - "severity": "error", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "startLine": 17, - }, - }, - }, - ], - }, - "displayValue": "55.6 %", - "score": 0.5556, - "slug": "function-coverage", - "title": "Function coverage", - "value": 55.55555555555556, - }, - { - "description": "Measures how many branches were executed after conditional statements in at least one test.", - "details": { - "issues": [ - { - "message": "1st branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "examples/react-todos-app/src/index.jsx", - "position": { - "startLine": 1, - }, - }, - }, - ], - }, - "displayValue": "87.5 %", - "score": 0.875, - "slug": "branch-coverage", - "title": "Branch coverage", - "value": 87.5, - }, - { - "description": "Measures how many lines of code were executed in at least one test.", - "details": { - "issues": [ - { - "message": "Lines 1-6 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/index.jsx", - "position": { - "endLine": 6, - "startLine": 1, - }, - }, - }, - { - "message": "Lines 14-17 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/CreateTodo.jsx", - "position": { - "endLine": 17, - "startLine": 14, - }, - }, - }, - { - "message": "Lines 22-23 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/CreateTodo.jsx", - "position": { - "endLine": 23, - "startLine": 22, - }, - }, - }, - { - "message": "Lines 10-11 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "endLine": 11, - "startLine": 10, - }, - }, - }, - { - "message": "Lines 18-19 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "endLine": 19, - "startLine": 18, - }, - }, - }, - { - "message": "Lines 7-28 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoList.jsx", - "position": { - "endLine": 28, - "startLine": 7, - }, - }, - }, - { - "message": "Lines 12-13 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endLine": 13, - "startLine": 12, - }, - }, - }, - { - "message": "Lines 18-37 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endLine": 37, - "startLine": 18, - }, - }, - }, - { - "message": "Lines 41-45 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endLine": 45, - "startLine": 41, - }, - }, - }, - { - "message": "Lines 54-60 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endLine": 60, - "startLine": 54, - }, - }, - }, - ], - }, - "displayValue": "62.1 %", - "score": 0.6211, - "slug": "line-coverage", - "title": "Line coverage", - "value": 62.10526315789474, - }, - ], - "description": "Official Code PushUp code coverage plugin.", - "docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/", - "groups": [ - { - "description": "Group containing all defined coverage types as audits.", - "refs": [ - { - "slug": "function-coverage", - "weight": 6, - }, - { - "slug": "branch-coverage", - "weight": 3, - }, - { - "slug": "line-coverage", - "weight": 1, - }, - ], - "slug": "coverage", - "title": "Code coverage metrics", - }, - ], - "icon": "folder-coverage-open", - "packageName": "@code-pushup/coverage-plugin", - "slug": "coverage", - "title": "Code coverage", - }, - ], -} -`; - -exports[`CLI collect > should run Code coverage plugin which collects passed results and creates report.json 1`] = ` -{ - "categories": [ - { - "refs": [ - { - "plugin": "coverage", - "slug": "coverage", - "type": "group", - "weight": 1, - }, - ], - "slug": "code-coverage", - "title": "Code coverage", - }, - ], - "packageName": "@code-pushup/core", - "plugins": [ - { - "audits": [ - { - "description": "Measures how many functions were called in at least one test.", - "details": { - "issues": [ - { - "message": "Function formatReportScore is not called in any test case.", - "severity": "error", - "source": { - "file": "src/lib/partly-covered/utils.ts", - "position": { - "startLine": 2, - }, - }, - }, - { - "message": "Function sortReport is not called in any test case.", - "severity": "error", - "source": { - "file": "src/lib/not-covered/sorting.ts", - "position": { - "startLine": 1, - }, - }, - }, - ], - }, - "displayValue": "60 %", - "score": 0.6, - "slug": "function-coverage", - "title": "Function coverage", - "value": 60, - }, - { - "description": "Measures how many branches were executed after conditional statements in at least one test.", - "details": { - "issues": [ - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "src/lib/partly-covered/utils.ts", - "position": { - "startLine": 6, - }, - }, - }, - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "src/lib/partly-covered/utils.ts", - "position": { - "startLine": 10, - }, - }, - }, - { - "message": "1st branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "src/lib/not-covered/sorting.ts", - "position": { - "startLine": 7, - }, - }, - }, - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "src/lib/not-covered/sorting.ts", - "position": { - "startLine": 7, - }, - }, - }, - ], - }, - "displayValue": "76.5 %", - "score": 0.7647, - "slug": "branch-coverage", - "title": "Branch coverage", - "value": 76.47058823529412, - }, - { - "description": "Measures how many lines of code were executed in at least one test.", - "details": { - "issues": [ - { - "message": "Lines 7-9 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "src/lib/partly-covered/utils.ts", - "position": { - "endLine": 9, - "startLine": 7, - }, - }, - }, - { - "message": "Lines 1-5 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "src/lib/not-covered/sorting.ts", - "position": { - "endLine": 5, - "startLine": 1, - }, - }, - }, - ], - }, - "displayValue": "68 %", - "score": 0.68, - "slug": "line-coverage", - "title": "Line coverage", - "value": 68, - }, - ], - "description": "Official Code PushUp code coverage plugin.", - "docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/", - "groups": [ - { - "description": "Group containing all defined coverage types as audits.", - "refs": [ - { - "slug": "function-coverage", - "weight": 6, - }, - { - "slug": "branch-coverage", - "weight": 3, - }, - { - "slug": "line-coverage", - "weight": 1, - }, - ], - "slug": "coverage", - "title": "Code coverage metrics", - }, - ], - "icon": "folder-coverage-open", - "packageName": "@code-pushup/coverage-plugin", - "slug": "coverage", - "title": "Code coverage", - }, - ], -} -`; - -exports[`CLI collect > should run ESLint plugin and create report.json 1`] = ` -{ - "categories": [ - { - "refs": [ - { - "plugin": "eslint", - "slug": "no-cond-assign", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-const-assign", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-debugger", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-invalid-regexp", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-undef", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-unreachable-loop", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-unsafe-negation", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-unsafe-optional-chaining", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "use-isnan", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "valid-typeof", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "eqeqeq", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "react-jsx-key", - "type": "audit", - "weight": 2, - }, - { - "plugin": "eslint", - "slug": "react-prop-types", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "react-react-in-jsx-scope", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "react-hooks-rules-of-hooks", - "type": "audit", - "weight": 2, - }, - { - "plugin": "eslint", - "slug": "react-hooks-exhaustive-deps", - "type": "audit", - "weight": 2, - }, - ], - "slug": "bug-prevention", - "title": "Bug prevention", - }, - { - "refs": [ - { - "plugin": "eslint", - "slug": "no-unused-vars", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "arrow-body-style", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "camelcase", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "curly", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "eqeqeq", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "max-lines-per-function", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "max-lines", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "object-shorthand", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "prefer-arrow-callback", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "prefer-const", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "prefer-object-spread", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "yoda", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-var", - "type": "audit", - "weight": 1, - }, - ], - "slug": "code-style", - "title": "Code style", - }, - ], - "packageName": "@code-pushup/core", - "plugins": [ - { - "audits": [ - { - "description": "ESLint rule **no-cond-assign**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-cond-assign", - "score": 1, - "slug": "no-cond-assign", - "title": "Disallow assignment operators in conditional expressions", - "value": 0, - }, - { - "description": "ESLint rule **no-const-assign**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-const-assign", - "score": 1, - "slug": "no-const-assign", - "title": "Disallow reassigning \`const\` variables", - "value": 0, - }, - { - "description": "ESLint rule **no-debugger**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-debugger", - "score": 1, - "slug": "no-debugger", - "title": "Disallow the use of \`debugger\`", - "value": 0, - }, - { - "description": "ESLint rule **no-invalid-regexp**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-invalid-regexp", - "score": 1, - "slug": "no-invalid-regexp", - "title": "Disallow invalid regular expression strings in \`RegExp\` constructors", - "value": 0, - }, - { - "description": "ESLint rule **no-undef**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-undef", - "score": 1, - "slug": "no-undef", - "title": "Disallow the use of undeclared variables unless mentioned in \`/*global */\` comments", - "value": 0, - }, - { - "description": "ESLint rule **no-unreachable-loop**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unreachable-loop", - "score": 1, - "slug": "no-unreachable-loop", - "title": "Disallow loops with a body that allows only one iteration", - "value": 0, - }, - { - "description": "ESLint rule **no-unsafe-negation**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unsafe-negation", - "score": 1, - "slug": "no-unsafe-negation", - "title": "Disallow negating the left operand of relational operators", - "value": 0, - }, - { - "description": "ESLint rule **no-unsafe-optional-chaining**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unsafe-optional-chaining", - "score": 1, - "slug": "no-unsafe-optional-chaining", - "title": "Disallow use of optional chaining in contexts where the \`undefined\` value is not allowed", - "value": 0, - }, - { - "description": "ESLint rule **no-unused-vars**.", - "details": { - "issues": [ - { - "message": "'loading' is assigned a value but never used.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/App.jsx", - "position": { - "endColumn": 18, - "endLine": 8, - "startColumn": 11, - "startLine": 8, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unused-vars", - "score": 0, - "slug": "no-unused-vars", - "title": "Disallow unused variables", - "value": 1, - }, - { - "description": "ESLint rule **use-isnan**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/use-isnan", - "score": 1, - "slug": "use-isnan", - "title": "Require calls to \`isNaN()\` when checking for \`NaN\`", - "value": 0, - }, - { - "description": "ESLint rule **valid-typeof**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/valid-typeof", - "score": 1, - "slug": "valid-typeof", - "title": "Enforce comparing \`typeof\` expressions against valid strings", - "value": 0, - }, - { - "description": "ESLint rule **arrow-body-style**.", - "details": { - "issues": [ - { - "message": "Unexpected block statement surrounding arrow body; move the returned value immediately after the \`=>\`.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "endColumn": 2, - "endLine": 25, - "startColumn": 29, - "startLine": 3, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/arrow-body-style", - "score": 0, - "slug": "arrow-body-style", - "title": "Require braces around arrow function bodies", - "value": 1, - }, - { - "description": "ESLint rule **camelcase**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/camelcase", - "score": 1, - "slug": "camelcase", - "title": "Enforce camelcase naming convention", - "value": 0, - }, - { - "description": "ESLint rule **curly**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/curly", - "score": 1, - "slug": "curly", - "title": "Enforce consistent brace style for all control statements", - "value": 0, - }, - { - "description": "ESLint rule **eqeqeq**.", - "details": { - "issues": [ - { - "message": "Expected '===' and instead saw '=='.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 43, - "endLine": 41, - "startColumn": 41, - "startLine": 41, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/eqeqeq", - "score": 0, - "slug": "eqeqeq", - "title": "Require the use of \`===\` and \`!==\`", - "value": 1, - }, - { - "description": "ESLint rule **max-lines-per-function**.", - "details": { - "issues": [ - { - "message": "Arrow function has too many lines (71). Maximum allowed is 50.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 2, - "endLine": 73, - "startColumn": 25, - "startLine": 3, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/max-lines-per-function", - "score": 0, - "slug": "max-lines-per-function", - "title": "Enforce a maximum number of lines of code in a function", - "value": 1, - }, - { - "description": "ESLint rule **max-lines**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/max-lines", - "score": 1, - "slug": "max-lines", - "title": "Enforce a maximum number of lines per file", - "value": 0, - }, - { - "description": "ESLint rule **no-shadow**.", - "details": { - "issues": [ - { - "message": "'data' is already declared in the upper scope on line 5 column 10.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 17, - "endLine": 11, - "startColumn": 13, - "startLine": 11, - }, - }, - }, - { - "message": "'data' is already declared in the upper scope on line 5 column 10.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 21, - "endLine": 29, - "startColumn": 17, - "startLine": 29, - }, - }, - }, - { - "message": "'data' is already declared in the upper scope on line 5 column 10.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 17, - "endLine": 41, - "startColumn": 13, - "startLine": 41, - }, - }, - }, - ], - }, - "displayValue": "3 warnings", - "docsUrl": "https://eslint.org/docs/latest/rules/no-shadow", - "score": 0, - "slug": "no-shadow", - "title": "Disallow variable declarations from shadowing variables declared in the outer scope", - "value": 3, - }, - { - "description": "ESLint rule **no-var**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-var", - "score": 1, - "slug": "no-var", - "title": "Require \`let\` or \`const\` instead of \`var\`", - "value": 0, - }, - { - "description": "ESLint rule **object-shorthand**.", - "details": { - "issues": [ - { - "message": "Expected property shorthand.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 19, - "endLine": 19, - "startColumn": 7, - "startLine": 19, - }, - }, - }, - { - "message": "Expected property shorthand.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 19, - "endLine": 32, - "startColumn": 13, - "startLine": 32, - }, - }, - }, - { - "message": "Expected property shorthand.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 25, - "endLine": 33, - "startColumn": 13, - "startLine": 33, - }, - }, - }, - ], - }, - "displayValue": "3 warnings", - "docsUrl": "https://eslint.org/docs/latest/rules/object-shorthand", - "score": 0, - "slug": "object-shorthand", - "title": "Require or disallow method and property shorthand syntax for object literals", - "value": 3, - }, - { - "description": "ESLint rule **prefer-arrow-callback**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/prefer-arrow-callback", - "score": 1, - "slug": "prefer-arrow-callback", - "title": "Require using arrow functions for callbacks", - "value": 0, - }, - { - "description": "ESLint rule **prefer-const**.", - "details": { - "issues": [ - { - "message": "'root' is never reassigned. Use 'const' instead.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/index.jsx", - "position": { - "endColumn": 9, - "endLine": 5, - "startColumn": 5, - "startLine": 5, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/prefer-const", - "score": 0, - "slug": "prefer-const", - "title": "Require \`const\` declarations for variables that are never reassigned after declared", - "value": 1, - }, - { - "description": "ESLint rule **prefer-object-spread**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/prefer-object-spread", - "score": 1, - "slug": "prefer-object-spread", - "title": "Disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead", - "value": 0, - }, - { - "description": "ESLint rule **yoda**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/yoda", - "score": 1, - "slug": "yoda", - "title": "Require or disallow "Yoda" conditions", - "value": 0, - }, - { - "description": "ESLint rule **jsx-key**, from _react_ plugin.", - "details": { - "issues": [ - { - "message": "Missing "key" prop for element in iterator", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoList.jsx", - "position": { - "endColumn": 12, - "endLine": 28, - "startColumn": 7, - "startLine": 7, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-key.md", - "score": 0, - "slug": "react-jsx-key", - "title": "Disallow missing \`key\` props in iterators/collection literals", - "value": 1, - }, - { - "description": "ESLint rule **prop-types**, from _react_ plugin.", - "details": { - "issues": [ - { - "message": "'onCreate' is missing in props validation", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/CreateTodo.jsx", - "position": { - "endColumn": 23, - "endLine": 15, - "startColumn": 15, - "startLine": 15, - }, - }, - }, - { - "message": "'setQuery' is missing in props validation", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "endColumn": 25, - "endLine": 10, - "startColumn": 17, - "startLine": 10, - }, - }, - }, - { - "message": "'setHideComplete' is missing in props validation", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "endColumn": 34, - "endLine": 18, - "startColumn": 19, - "startLine": 18, - }, - }, - }, - { - "message": "'todos' is missing in props validation", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoList.jsx", - "position": { - "endColumn": 17, - "endLine": 6, - "startColumn": 12, - "startLine": 6, - }, - }, - }, - { - "message": "'todos.map' is missing in props validation", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoList.jsx", - "position": { - "endColumn": 21, - "endLine": 6, - "startColumn": 18, - "startLine": 6, - }, - }, - }, - { - "message": "'onEdit' is missing in props validation", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoList.jsx", - "position": { - "endColumn": 27, - "endLine": 13, - "startColumn": 21, - "startLine": 13, - }, - }, - }, - ], - }, - "displayValue": "6 warnings", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/prop-types.md", - "score": 0, - "slug": "react-prop-types", - "title": "Disallow missing props validation in a React component definition", - "value": 6, - }, - { - "description": "ESLint rule **react-in-jsx-scope**, from _react_ plugin.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/react-in-jsx-scope.md", - "score": 1, - "slug": "react-react-in-jsx-scope", - "title": "Disallow missing React when using JSX", - "value": 0, - }, - { - "description": "ESLint rule **jsx-uses-vars**, from _react_ plugin.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-uses-vars.md", - "score": 1, - "slug": "react-jsx-uses-vars", - "title": "Disallow variables used in JSX to be incorrectly marked as unused", - "value": 0, - }, - { - "description": "ESLint rule **jsx-uses-react**, from _react_ plugin.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-uses-react.md", - "score": 1, - "slug": "react-jsx-uses-react", - "title": "Disallow React to be incorrectly marked as unused", - "value": 0, - }, - { - "description": "ESLint rule **rules-of-hooks**, from _react-hooks_ plugin.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://reactjs.org/docs/hooks-rules.html", - "score": 1, - "slug": "react-hooks-rules-of-hooks", - "title": "enforces the Rules of Hooks", - "value": 0, - }, - { - "description": "ESLint rule **exhaustive-deps**, from _react-hooks_ plugin.", - "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": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 31, - "endLine": 17, - "startColumn": 20, - "startLine": 17, - }, - }, - }, - { - "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": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 29, - "endLine": 40, - "startColumn": 18, - "startLine": 40, - }, - }, - }, - ], - }, - "displayValue": "2 warnings", - "docsUrl": "https://github.com/facebook/react/issues/14920", - "score": 0, - "slug": "react-hooks-exhaustive-deps", - "title": "verifies the list of dependencies for Hooks like useEffect and similar", - "value": 2, - }, - ], - "description": "Official Code PushUp ESLint plugin", - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "groups": [ - { - "description": "Code that either will cause an error or may cause confusing behavior. Developers should consider this a high priority to resolve.", - "refs": [ - { - "slug": "no-cond-assign", - "weight": 1, - }, - { - "slug": "no-const-assign", - "weight": 1, - }, - { - "slug": "no-debugger", - "weight": 1, - }, - { - "slug": "no-invalid-regexp", - "weight": 1, - }, - { - "slug": "no-undef", - "weight": 1, - }, - { - "slug": "no-unreachable-loop", - "weight": 1, - }, - { - "slug": "no-unsafe-negation", - "weight": 1, - }, - { - "slug": "no-unsafe-optional-chaining", - "weight": 1, - }, - { - "slug": "no-unused-vars", - "weight": 1, - }, - { - "slug": "use-isnan", - "weight": 1, - }, - { - "slug": "valid-typeof", - "weight": 1, - }, - { - "slug": "react-hooks-rules-of-hooks", - "weight": 1, - }, - ], - "slug": "problems", - "title": "Problems", - }, - { - "description": "Something that could be done in a better way but no errors will occur if the code isn't changed.", - "refs": [ - { - "slug": "arrow-body-style", - "weight": 1, - }, - { - "slug": "camelcase", - "weight": 1, - }, - { - "slug": "curly", - "weight": 1, - }, - { - "slug": "eqeqeq", - "weight": 1, - }, - { - "slug": "max-lines-per-function", - "weight": 1, - }, - { - "slug": "max-lines", - "weight": 1, - }, - { - "slug": "no-shadow", - "weight": 1, - }, - { - "slug": "no-var", - "weight": 1, - }, - { - "slug": "object-shorthand", - "weight": 1, - }, - { - "slug": "prefer-arrow-callback", - "weight": 1, - }, - { - "slug": "prefer-const", - "weight": 1, - }, - { - "slug": "prefer-object-spread", - "weight": 1, - }, - { - "slug": "yoda", - "weight": 1, - }, - { - "slug": "react-hooks-exhaustive-deps", - "weight": 1, - }, - ], - "slug": "suggestions", - "title": "Suggestions", - }, - { - "refs": [ - { - "slug": "react-prop-types", - "weight": 1, - }, - { - "slug": "react-jsx-uses-vars", - "weight": 1, - }, - { - "slug": "react-jsx-uses-react", - "weight": 1, - }, - ], - "slug": "react-best-practices", - "title": "Best Practices (react)", - }, - { - "refs": [ - { - "slug": "react-jsx-key", - "weight": 1, - }, - { - "slug": "react-react-in-jsx-scope", - "weight": 1, - }, - ], - "slug": "react-possible-errors", - "title": "Possible Errors (react)", - }, - ], - "icon": "eslint", - "packageName": "@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - ], -} -`; diff --git a/e2e/cli-e2e/tests/collect.e2e.test.ts b/e2e/cli-e2e/tests/collect.e2e.test.ts index 5e301ab29..5b7210b5c 100644 --- a/e2e/cli-e2e/tests/collect.e2e.test.ts +++ b/e2e/cli-e2e/tests/collect.e2e.test.ts @@ -1,121 +1,20 @@ -import { dirname, join } from 'node:path'; -import { fileURLToPath } from 'node:url'; -import { - type AuditReport, - type PluginReport, - type Report, - reportSchema, -} from '@code-pushup/models'; -import { cleanTestFolder } from '@code-pushup/test-setup'; -import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; +import {cleanTestFolder, teardownTestFolder} from '@code-pushup/test-setup'; +import {executeProcess, readTextFile} from '@code-pushup/utils'; +import {join} from "node:path"; +import {afterEach} from "vitest"; describe('CLI collect', () => { - const exampleCategoryTitle = 'Code style'; - const exampleAuditTitle = 'Disallow unused variables'; + const dummyPluginTitle = 'Dummy Plugin'; + const dummyAuditTitle = 'Dummy Audit'; + const envRoot = 'static-environments/eslint-e2e-env'; + const baseDir = join(envRoot, '__tests__'); - /* eslint-disable @typescript-eslint/no-unused-vars */ - const omitVariableAuditData = ({ - score, - value, - displayValue, - ...auditReport - }: AuditReport) => auditReport; - const omitVariablePluginData = ({ - date, - duration, - version, - audits, - ...pluginReport - }: PluginReport) => - ({ - ...pluginReport, - audits: audits.map( - pluginReport.slug === 'lighthouse' ? omitVariableAuditData : p => p, - ) as AuditReport[], - }) as PluginReport; - const omitVariableReportData = ({ - commit, - date, - duration, - version, - ...report - }: Report) => ({ - ...report, - plugins: report.plugins.map(omitVariablePluginData), + afterEach(async () => { + await teardownTestFolder(baseDir); }); - /* eslint-enable @typescript-eslint/no-unused-vars */ beforeEach(async () => { - await cleanTestFolder('tmp/e2e/react-todos-app'); - }); - - it('should run ESLint plugin and create report.json', async () => { - const { code, stderr } = await executeProcess({ - command: 'code-pushup', - args: ['collect', '--no-progress', '--onlyPlugins=eslint'], - cwd: 'examples/react-todos-app', - }); - - expect(code).toBe(0); - expect(stderr).toBe(''); - - const report = await readJsonFile('tmp/e2e/react-todos-app/report.json'); - - expect(() => reportSchema.parse(report)).not.toThrow(); - expect(omitVariableReportData(report as Report)).toMatchSnapshot(); - }); - - it('should run Code coverage plugin which collects passed results and creates report.json', async () => { - /** - * The stats passed in the fixture are as follows - * 3 files: one partially covered, one with no coverage, one with full coverage - * Functions: 2 + 1 + 2 found | 1 + 0 + 2 covered (60% coverage) - * Branches: 10 + 2 + 5 found | 8 + 0 + 5 covered (76% coverage) - * Lines: 10 + 5 + 10 found | 7 + 0 + 10 covered (68% coverage) - */ - - const configPath = join( - fileURLToPath(dirname(import.meta.url)), - '..', - 'mocks', - 'fixtures', - 'code-pushup.config.ts', - ); - - const { code, stderr } = await executeProcess({ - command: 'code-pushup', - args: [ - 'collect', - '--no-progress', - `--config=${configPath}`, - '--persist.outputDir=tmp/e2e', - '--onlyPlugins=coverage', - ], - }); - - expect(code).toBe(0); - expect(stderr).toBe(''); - - const report = await readJsonFile(join('tmp', 'e2e', 'report.json')); - - expect(() => reportSchema.parse(report)).not.toThrow(); - expect(omitVariableReportData(report as Report)).toMatchSnapshot(); - }); - - it('should run Code coverage plugin that runs coverage tool and creates report.json', async () => { - const { code, stderr } = await executeProcess({ - command: 'code-pushup', - args: ['collect', '--no-progress', '--onlyPlugins=coverage'], - cwd: 'examples/react-todos-app', - }); - - expect(code).toBe(0); - expect(stderr).toBe(''); - - const report = await readJsonFile('tmp/e2e/react-todos-app/report.json'); - - expect(() => reportSchema.parse(report)).not.toThrow(); - expect(omitVariableReportData(report as Report)).toMatchSnapshot(); + await cleanTestFolder(baseDir); }); it('should create report.md', async () => { @@ -128,11 +27,11 @@ describe('CLI collect', () => { expect(code).toBe(0); expect(stderr).toBe(''); - const md = await readTextFile('tmp/e2e/react-todos-app/report.md'); + const md = await readTextFile('examples/react-todos-app/.code-pushup/report.md'); expect(md).toContain('# Code PushUp Report'); - expect(md).toContain(exampleCategoryTitle); - expect(md).toContain(exampleAuditTitle); + expect(md).toContain(dummyPluginTitle); + expect(md).toContain(dummyAuditTitle); }); it('should print report summary to stdout', async () => { @@ -147,7 +46,7 @@ describe('CLI collect', () => { expect(stdout).toContain('Code PushUp Report'); expect(stdout).not.toContain('Generated reports'); - expect(stdout).toContain(exampleCategoryTitle); - expect(stdout).toContain(exampleAuditTitle); + expect(stdout).toContain(dummyPluginTitle); + expect(stdout).toContain(dummyAuditTitle); }); }); diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index 9f5744c9f..345713f4a 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -5,6 +5,7 @@ import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; describe('CLI compare', () => { const git = simpleGit(); + const dummyPluginSlug = 'dummy-plugin'; beforeEach(async () => { if (await git.diff(['--', 'examples/react-todos-app'])) { @@ -17,8 +18,7 @@ describe('CLI compare', () => { command: 'code-pushup', args: [ 'collect', - '--persist.filename=source-report', - '--onlyPlugins=eslint', + '--persist.filename=source-report' ], cwd: 'examples/react-todos-app', }); @@ -31,8 +31,7 @@ describe('CLI compare', () => { command: 'code-pushup', args: [ 'collect', - '--persist.filename=target-report', - '--onlyPlugins=eslint', + '--persist.filename=target-report' ], cwd: 'examples/react-todos-app', }); diff --git a/examples/react-todos-app/code-pushup.config.js b/examples/react-todos-app/code-pushup.config.js deleted file mode 100644 index dcef94a7f..000000000 --- a/examples/react-todos-app/code-pushup.config.js +++ /dev/null @@ -1,84 +0,0 @@ -import coveragePlugin from '../../dist/packages/plugin-coverage'; -import eslintPlugin from '../../dist/packages/plugin-eslint'; - -const eslintAuditRef = (slug, weight) => ({ - type: 'audit', - plugin: 'eslint', - slug, - weight, -}); - -export default { - persist: { - outputDir: '../../tmp/e2e/react-todos-app', - }, - plugins: [ - await coveragePlugin({ - reports: ['../../coverage/react-todos-app/lcov.info'], - coverageToolCommand: { - command: 'npx', - args: ['vitest', 'run', '--coverage'], - }, - }), - await eslintPlugin({ - eslintrc: '.eslintrc.js', - patterns: ['src/**/*.js', 'src/**/*.jsx'], - }), - ], - categories: [ - { - slug: 'code-coverage', - title: 'Code coverage', - refs: [ - { - type: 'group', - plugin: 'coverage', - slug: 'coverage', - weight: 1, - }, - ], - }, - { - slug: 'bug-prevention', - title: 'Bug prevention', - refs: [ - eslintAuditRef('no-cond-assign', 1), - eslintAuditRef('no-const-assign', 1), - eslintAuditRef('no-debugger', 1), - eslintAuditRef('no-invalid-regexp', 1), - eslintAuditRef('no-undef', 1), - eslintAuditRef('no-unreachable-loop', 1), - eslintAuditRef('no-unsafe-negation', 1), - eslintAuditRef('no-unsafe-optional-chaining', 1), - eslintAuditRef('use-isnan', 1), - eslintAuditRef('valid-typeof', 1), - eslintAuditRef('eqeqeq', 1), - eslintAuditRef('react-jsx-key', 2), - eslintAuditRef('react-prop-types', 1), - eslintAuditRef('react-react-in-jsx-scope', 1), - eslintAuditRef('react-hooks-rules-of-hooks', 2), - eslintAuditRef('react-hooks-exhaustive-deps', 2), - ], - }, - - { - slug: 'code-style', - title: 'Code style', - refs: [ - eslintAuditRef('no-unused-vars', 1), - eslintAuditRef('arrow-body-style', 1), - eslintAuditRef('camelcase', 1), - eslintAuditRef('curly', 1), - eslintAuditRef('eqeqeq', 1), - eslintAuditRef('max-lines-per-function', 1), - eslintAuditRef('max-lines', 1), - eslintAuditRef('object-shorthand', 1), - eslintAuditRef('prefer-arrow-callback', 1), - eslintAuditRef('prefer-const', 1), - eslintAuditRef('prefer-object-spread', 1), - eslintAuditRef('yoda', 1), - eslintAuditRef('no-var', 1), - ], - }, - ], -}; diff --git a/examples/react-todos-app/code-pushup.config.ts b/examples/react-todos-app/code-pushup.config.ts new file mode 100644 index 000000000..b31e55c17 --- /dev/null +++ b/examples/react-todos-app/code-pushup.config.ts @@ -0,0 +1,22 @@ +import dummyPlugin, {dummyAudit, dummyPluginSlug} from "./dummy.plugin"; + +export default { + persist: { + outputDir: "../../tmp/e2e/react-todos-app", + }, + plugins: [dummyPlugin()], + categories: [ + { + slug: 'dummy-category', + title: 'Dummy Category', + refs: [ + { + type: 'audit', + plugin: dummyPluginSlug, + audit: dummyAudit.slug, + weight: 1 + } + ] + } + ], +}; diff --git a/examples/react-todos-app/dummy.plugin.ts b/examples/react-todos-app/dummy.plugin.ts new file mode 100644 index 000000000..54582875e --- /dev/null +++ b/examples/react-todos-app/dummy.plugin.ts @@ -0,0 +1,34 @@ +import type {PluginConfig,} from '@code-pushup/models'; + +export type PluginOptions = { + directory: string; + pattern?: string | RegExp; + budget?: number; +}; + +export const pluginSlug = 'dummy-plugin'; + +const dummyAuditSlug = 'dummy-audit'; +export const dummyAudit = { + slug: dummyAuditSlug, + title: 'Dummy Audit', + description: + 'A dummy audit to test the cli.', +}; +export function create(): PluginConfig { + return { + slug: pluginSlug, + title: 'Dummy Plugin', + icon: 'folder-javascript', + description: 'A dummy plugin to test the cli.', + runner: () => ([{ + ...dummyAudit, + slug: dummyAuditSlug, + score: 1, + value: 0 + }]), + audits: [dummyAudit], + }; +} + +export default create; diff --git a/nx.json b/nx.json index bebd69d65..c7603298b 100644 --- a/nx.json +++ b/nx.json @@ -28,6 +28,9 @@ "e2e": { "dependsOn": ["^build"] }, + "nxv-env-setup": { + "executor": "@push-based/nx-verdaccio:env-setup" + }, "@nx/vite:test": { "cache": true, "inputs": ["default", "^production"], @@ -68,23 +71,7 @@ "appsDir": "examples", "libsDir": "packages" }, - "generators": { - "@nx/react": { - "application": { - "style": "css", - "linter": "eslint", - "bundler": "vite", - "babel": true - }, - "component": { - "style": "css" - }, - "library": { - "style": "css", - "linter": "eslint" - } - } - }, + "generators": {}, "release": { "projects": ["packages/*"], "projectsRelationship": "fixed", diff --git a/package-lock.json b/package-lock.json index 80639ae4b..960950fda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,7 +49,7 @@ "@nx/react": "17.3.2", "@nx/vite": "17.3.2", "@nx/workspace": "17.3.2", - "@push-based/nx-verdaccio": "0.0.0-alpha.25", + "@push-based/nx-verdaccio": "0.0.0-alpha.26", "@swc-node/register": "^1.10.9", "@swc/cli": "~0.1.62", "@swc/core": "^1.3.99", @@ -5457,9 +5457,9 @@ } }, "node_modules/@push-based/nx-verdaccio": { - "version": "0.0.0-alpha.25", - "resolved": "https://registry.npmjs.org/@push-based/nx-verdaccio/-/nx-verdaccio-0.0.0-alpha.25.tgz", - "integrity": "sha512-5keAr9Gpw0TjUEwtMZVu/qweBYPPHHxHRNaRJgw94uOGSwcQwFcYn92w3+Z4/VdXhM0/RINALGc+/DgG1PV5fg==", + "version": "0.0.0-alpha.26", + "resolved": "https://registry.npmjs.org/@push-based/nx-verdaccio/-/nx-verdaccio-0.0.0-alpha.26.tgz", + "integrity": "sha512-Go11Dg+w5Ntl5Ig8YNzVVPbpOG85aVszjyBIK0FvVBX+/QllQY1F4fP8K8fYnMJnO9v5Tao3cryGFY5Zo9i+/g==", "dev": true, "dependencies": { "@nx/devkit": "19.8.0", diff --git a/package.json b/package.json index da4f9fb46..354f89a4b 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "@nx/react": "17.3.2", "@nx/vite": "17.3.2", "@nx/workspace": "17.3.2", - "@push-based/nx-verdaccio": "0.0.0-alpha.25", + "@push-based/nx-verdaccio": "0.0.0-alpha.26", "@swc-node/register": "^1.10.9", "@swc/cli": "~0.1.62", "@swc/core": "^1.3.99", From de6d0ec6fbf12358a1de586bd7098e7191860197 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 14:06:19 +0100 Subject: [PATCH 27/80] wip --- examples/react-todos-app/dummy.plugin.ts | 33 ++++++++++-------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/examples/react-todos-app/dummy.plugin.ts b/examples/react-todos-app/dummy.plugin.ts index 54582875e..31730b18d 100644 --- a/examples/react-todos-app/dummy.plugin.ts +++ b/examples/react-todos-app/dummy.plugin.ts @@ -1,32 +1,27 @@ -import type {PluginConfig,} from '@code-pushup/models'; +import type { PluginConfig } from '@code-pushup/models'; -export type PluginOptions = { - directory: string; - pattern?: string | RegExp; - budget?: number; -}; - -export const pluginSlug = 'dummy-plugin'; +export const dummyPluginSlug = 'dummy-plugin'; const dummyAuditSlug = 'dummy-audit'; export const dummyAudit = { - slug: dummyAuditSlug, - title: 'Dummy Audit', - description: - 'A dummy audit to test the cli.', + slug: dummyAuditSlug, + title: 'Dummy Audit', + description: 'A dummy audit to test the cli.', }; export function create(): PluginConfig { return { - slug: pluginSlug, + slug: dummyPluginSlug, title: 'Dummy Plugin', icon: 'folder-javascript', description: 'A dummy plugin to test the cli.', - runner: () => ([{ - ...dummyAudit, - slug: dummyAuditSlug, - score: 1, - value: 0 - }]), + runner: () => [ + { + ...dummyAudit, + slug: dummyAuditSlug, + score: 1, + value: 0, + }, + ], audits: [dummyAudit], }; } From 1e943b78d73f5c73b71ffb75cdc4367a0efe5abb Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 14:14:37 +0100 Subject: [PATCH 28/80] wip plugin --- .../react-todos-app/code-pushup.config.ts | 15 +------- examples/react-todos-app/dummy.plugin.ts | 37 ++++++++++++++----- examples/react-todos-app/items.json | 5 +++ 3 files changed, 35 insertions(+), 22 deletions(-) create mode 100644 examples/react-todos-app/items.json diff --git a/examples/react-todos-app/code-pushup.config.ts b/examples/react-todos-app/code-pushup.config.ts index b31e55c17..088720dd0 100644 --- a/examples/react-todos-app/code-pushup.config.ts +++ b/examples/react-todos-app/code-pushup.config.ts @@ -1,4 +1,4 @@ -import dummyPlugin, {dummyAudit, dummyPluginSlug} from "./dummy.plugin"; +import dummyPlugin, {dummyCategory} from "./dummy.plugin"; export default { persist: { @@ -6,17 +6,6 @@ export default { }, plugins: [dummyPlugin()], categories: [ - { - slug: 'dummy-category', - title: 'Dummy Category', - refs: [ - { - type: 'audit', - plugin: dummyPluginSlug, - audit: dummyAudit.slug, - weight: 1 - } - ] - } + dummyCategory ], }; diff --git a/examples/react-todos-app/dummy.plugin.ts b/examples/react-todos-app/dummy.plugin.ts index 31730b18d..69a5c4266 100644 --- a/examples/react-todos-app/dummy.plugin.ts +++ b/examples/react-todos-app/dummy.plugin.ts @@ -1,4 +1,5 @@ -import type { PluginConfig } from '@code-pushup/models'; +import type {PluginConfig} from '@code-pushup/models'; +import {readFile} from "node:fs/promises"; export const dummyPluginSlug = 'dummy-plugin'; @@ -8,20 +9,38 @@ export const dummyAudit = { title: 'Dummy Audit', description: 'A dummy audit to test the cli.', }; + +export const dummyCategory = { + slug: 'dummy-category', + title: 'Dummy Category', + refs: [ + { + type: 'audit', + plugin: dummyPluginSlug, + slug: dummyAuditSlug, + weight: 1 + } + ] +}; + + export function create(): PluginConfig { return { slug: dummyPluginSlug, title: 'Dummy Plugin', icon: 'folder-javascript', description: 'A dummy plugin to test the cli.', - runner: () => [ - { - ...dummyAudit, - slug: dummyAuditSlug, - score: 1, - value: 0, - }, - ], + runner: async () => { + const itemCount = JSON.parse(await readFile('items.json', 'utf-8')).length; + return [ + { + ...dummyAudit, + slug: dummyAuditSlug, + score: itemCount < 10 ? itemCount / 10 : 1, + value: itemCount, + }, + ] + }, audits: [dummyAudit], }; } diff --git a/examples/react-todos-app/items.json b/examples/react-todos-app/items.json new file mode 100644 index 000000000..a85b7c928 --- /dev/null +++ b/examples/react-todos-app/items.json @@ -0,0 +1,5 @@ +[ + 1, + 2, + 3 +] From d774356afdeed94c559221b98cbe321dff92b728 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 14:22:41 +0100 Subject: [PATCH 29/80] wip plugin --- e2e/cli-e2e/tests/compare.e2e.test.ts | 32 ++++++++++++++------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index 345713f4a..dd006f054 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -1,16 +1,18 @@ -import { simpleGit } from 'simple-git'; -import type { ReportsDiff } from '@code-pushup/models'; -import { cleanTestFolder } from '@code-pushup/test-setup'; -import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; +import {simpleGit} from 'simple-git'; +import type {ReportsDiff} from '@code-pushup/models'; +import {cleanTestFolder} from '@code-pushup/test-setup'; +import {executeProcess, readJsonFile, readTextFile} from '@code-pushup/utils'; +import {readFile, writeFile} from "node:fs/promises"; +import {join} from "node:path"; describe('CLI compare', () => { + const envRoot = join('examples', 'react-todos-app'); const git = simpleGit(); - const dummyPluginSlug = 'dummy-plugin'; beforeEach(async () => { - if (await git.diff(['--', 'examples/react-todos-app'])) { + if (await git.diff(['--', envRoot])) { throw new Error( - 'Unstaged changes found in examples/react-todos-app, please stage or commit them to prevent E2E tests interfering', + `Unstaged changes found in ${envRoot}, please stage or commit them to prevent E2E tests interfering`, ); } await cleanTestFolder('tmp/e2e/react-todos-app'); @@ -20,20 +22,20 @@ describe('CLI compare', () => { 'collect', '--persist.filename=source-report' ], - cwd: 'examples/react-todos-app', - }); - await executeProcess({ - command: 'npx', - args: ['eslint', '--fix', 'src', '--ext=js,jsx'], - cwd: 'examples/react-todos-app', + cwd: envRoot, }); + // adding items to create a report diff + const itemsFile = join(envRoot, 'items.json'); + const items = JSON.parse((await readFile(itemsFile)).toString()); + await writeFile(itemsFile, JSON.stringify([...items, 4,5,6,7], null, 2)); + await executeProcess({ command: 'code-pushup', args: [ 'collect', '--persist.filename=target-report' ], - cwd: 'examples/react-todos-app', + cwd: envRoot, }); }, 20_000); @@ -50,7 +52,7 @@ describe('CLI compare', () => { '--before=../../tmp/e2e/react-todos-app/source-report.json', '--after=../../tmp/e2e/react-todos-app/target-report.json', ], - cwd: 'examples/react-todos-app', + cwd: envRoot, }); const reportsDiff = await readJsonFile( From 0735e7fd24b4c74030aab156ca94d0410491cc03 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 14:32:33 +0100 Subject: [PATCH 30/80] wip env --- e2e/cli-e2e/project.json | 11 +------- e2e/cli-e2e/tests/compare.e2e.test.ts | 26 +++++++------------ .../react-todos-app/code-pushup.config.ts | 9 ++----- 3 files changed, 13 insertions(+), 33 deletions(-) diff --git a/e2e/cli-e2e/project.json b/e2e/cli-e2e/project.json index 5bef1175d..1f0873935 100644 --- a/e2e/cli-e2e/project.json +++ b/e2e/cli-e2e/project.json @@ -18,15 +18,6 @@ } } }, - "implicitDependencies": [ - "models", - "utils", - "core", - "cli", - "plugin-eslint", - "plugin-coverage", - "plugin-js-packages", - "react-todos-app" - ], + "implicitDependencies": ["models", "utils", "core", "cli", "react-todos-app"], "tags": ["scope:core", "scope:plugin", "type:e2e"] } diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index dd006f054..d1727fb3b 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -1,9 +1,9 @@ -import {simpleGit} from 'simple-git'; -import type {ReportsDiff} from '@code-pushup/models'; -import {cleanTestFolder} from '@code-pushup/test-setup'; -import {executeProcess, readJsonFile, readTextFile} from '@code-pushup/utils'; -import {readFile, writeFile} from "node:fs/promises"; -import {join} from "node:path"; +import { readFile, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { simpleGit } from 'simple-git'; +import type { ReportsDiff } from '@code-pushup/models'; +import { cleanTestFolder } from '@code-pushup/test-setup'; +import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; describe('CLI compare', () => { const envRoot = join('examples', 'react-todos-app'); @@ -18,30 +18,24 @@ describe('CLI compare', () => { await cleanTestFolder('tmp/e2e/react-todos-app'); await executeProcess({ command: 'code-pushup', - args: [ - 'collect', - '--persist.filename=source-report' - ], + args: ['collect', '--persist.filename=source-report'], cwd: envRoot, }); // adding items to create a report diff const itemsFile = join(envRoot, 'items.json'); const items = JSON.parse((await readFile(itemsFile)).toString()); - await writeFile(itemsFile, JSON.stringify([...items, 4,5,6,7], null, 2)); + await writeFile(itemsFile, JSON.stringify([...items, 4, 5, 6, 7], null, 2)); await executeProcess({ command: 'code-pushup', - args: [ - 'collect', - '--persist.filename=target-report' - ], + args: ['collect', '--persist.filename=target-report'], cwd: envRoot, }); }, 20_000); afterEach(async () => { await git.checkout(['--', 'examples/react-todos-app']); - await cleanTestFolder('tmp/e2e'); + // await cleanTestFolder('tmp/e2e'); }); it('should compare report.json files and create report-diff.json and report-diff.md', async () => { diff --git a/examples/react-todos-app/code-pushup.config.ts b/examples/react-todos-app/code-pushup.config.ts index 088720dd0..26928cba2 100644 --- a/examples/react-todos-app/code-pushup.config.ts +++ b/examples/react-todos-app/code-pushup.config.ts @@ -1,11 +1,6 @@ -import dummyPlugin, {dummyCategory} from "./dummy.plugin"; +import dummyPlugin, { dummyCategory } from './dummy.plugin'; export default { - persist: { - outputDir: "../../tmp/e2e/react-todos-app", - }, plugins: [dummyPlugin()], - categories: [ - dummyCategory - ], + categories: [dummyCategory], }; From 1e297ef3644ce7aff356ff13c43ccb1fa4949a76 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 14:36:49 +0100 Subject: [PATCH 31/80] wip test --- .../__snapshots__/compare.e2e.test.ts.snap | 529 ------------------ .../__snapshots__/compare.report-diff.md | 33 -- e2e/cli-e2e/tests/compare.e2e.test.ts | 22 +- 3 files changed, 11 insertions(+), 573 deletions(-) delete mode 100644 e2e/cli-e2e/tests/__snapshots__/compare.e2e.test.ts.snap delete mode 100644 e2e/cli-e2e/tests/__snapshots__/compare.report-diff.md diff --git a/e2e/cli-e2e/tests/__snapshots__/compare.e2e.test.ts.snap b/e2e/cli-e2e/tests/__snapshots__/compare.e2e.test.ts.snap deleted file mode 100644 index 33ededed0..000000000 --- a/e2e/cli-e2e/tests/__snapshots__/compare.e2e.test.ts.snap +++ /dev/null @@ -1,529 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`CLI compare > should compare report.json files and create report-diff.json and report-diff.md 1`] = ` -{ - "audits": { - "added": [], - "changed": [ - { - "displayValues": { - "after": "passed", - "before": "1 warning", - }, - "docsUrl": "https://eslint.org/docs/latest/rules/arrow-body-style", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "scores": { - "after": 1, - "before": 0, - "diff": 1, - }, - "slug": "arrow-body-style", - "title": "Require braces around arrow function bodies", - "values": { - "after": 0, - "before": 1, - "diff": -1, - }, - }, - { - "displayValues": { - "after": "passed", - "before": "3 warnings", - }, - "docsUrl": "https://eslint.org/docs/latest/rules/object-shorthand", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "scores": { - "after": 1, - "before": 0, - "diff": 1, - }, - "slug": "object-shorthand", - "title": "Require or disallow method and property shorthand syntax for object literals", - "values": { - "after": 0, - "before": 3, - "diff": -3, - }, - }, - { - "displayValues": { - "after": "passed", - "before": "1 warning", - }, - "docsUrl": "https://eslint.org/docs/latest/rules/prefer-const", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "scores": { - "after": 1, - "before": 0, - "diff": 1, - }, - "slug": "prefer-const", - "title": "Require \`const\` declarations for variables that are never reassigned after declared", - "values": { - "after": 0, - "before": 1, - "diff": -1, - }, - }, - ], - "removed": [], - "unchanged": [ - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-cond-assign", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "no-cond-assign", - "title": "Disallow assignment operators in conditional expressions", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-const-assign", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "no-const-assign", - "title": "Disallow reassigning \`const\` variables", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-debugger", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "no-debugger", - "title": "Disallow the use of \`debugger\`", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-invalid-regexp", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "no-invalid-regexp", - "title": "Disallow invalid regular expression strings in \`RegExp\` constructors", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-undef", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "no-undef", - "title": "Disallow the use of undeclared variables unless mentioned in \`/*global */\` comments", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unreachable-loop", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "no-unreachable-loop", - "title": "Disallow loops with a body that allows only one iteration", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unsafe-negation", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "no-unsafe-negation", - "title": "Disallow negating the left operand of relational operators", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unsafe-optional-chaining", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "no-unsafe-optional-chaining", - "title": "Disallow use of optional chaining in contexts where the \`undefined\` value is not allowed", - "value": 0, - }, - { - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unused-vars", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 0, - "slug": "no-unused-vars", - "title": "Disallow unused variables", - "value": 1, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/use-isnan", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "use-isnan", - "title": "Require calls to \`isNaN()\` when checking for \`NaN\`", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/valid-typeof", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "valid-typeof", - "title": "Enforce comparing \`typeof\` expressions against valid strings", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/camelcase", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "camelcase", - "title": "Enforce camelcase naming convention", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/curly", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "curly", - "title": "Enforce consistent brace style for all control statements", - "value": 0, - }, - { - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/eqeqeq", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 0, - "slug": "eqeqeq", - "title": "Require the use of \`===\` and \`!==\`", - "value": 1, - }, - { - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/max-lines-per-function", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 0, - "slug": "max-lines-per-function", - "title": "Enforce a maximum number of lines of code in a function", - "value": 1, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/max-lines", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "max-lines", - "title": "Enforce a maximum number of lines per file", - "value": 0, - }, - { - "displayValue": "3 warnings", - "docsUrl": "https://eslint.org/docs/latest/rules/no-shadow", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 0, - "slug": "no-shadow", - "title": "Disallow variable declarations from shadowing variables declared in the outer scope", - "value": 3, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-var", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "no-var", - "title": "Require \`let\` or \`const\` instead of \`var\`", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/prefer-arrow-callback", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "prefer-arrow-callback", - "title": "Require using arrow functions for callbacks", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/prefer-object-spread", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "prefer-object-spread", - "title": "Disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/yoda", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "yoda", - "title": "Require or disallow "Yoda" conditions", - "value": 0, - }, - { - "displayValue": "1 warning", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-key.md", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 0, - "slug": "react-jsx-key", - "title": "Disallow missing \`key\` props in iterators/collection literals", - "value": 1, - }, - { - "displayValue": "6 warnings", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/prop-types.md", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 0, - "slug": "react-prop-types", - "title": "Disallow missing props validation in a React component definition", - "value": 6, - }, - { - "displayValue": "passed", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/react-in-jsx-scope.md", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "react-react-in-jsx-scope", - "title": "Disallow missing React when using JSX", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-uses-vars.md", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "react-jsx-uses-vars", - "title": "Disallow variables used in JSX to be incorrectly marked as unused", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-uses-react.md", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "react-jsx-uses-react", - "title": "Disallow React to be incorrectly marked as unused", - "value": 0, - }, - { - "displayValue": "passed", - "docsUrl": "https://reactjs.org/docs/hooks-rules.html", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 1, - "slug": "react-hooks-rules-of-hooks", - "title": "enforces the Rules of Hooks", - "value": 0, - }, - { - "displayValue": "2 warnings", - "docsUrl": "https://github.com/facebook/react/issues/14920", - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 0, - "slug": "react-hooks-exhaustive-deps", - "title": "verifies the list of dependencies for Hooks like useEffect and similar", - "value": 2, - }, - ], - }, - "categories": { - "added": [], - "changed": [ - { - "scores": { - "after": 0.7692307692307693, - "before": 0.5384615384615384, - "diff": 0.23076923076923084, - }, - "slug": "code-style", - "title": "Code style", - }, - ], - "removed": [], - "unchanged": [ - { - "score": 0.6842105263157895, - "slug": "bug-prevention", - "title": "Bug prevention", - }, - ], - }, - "commits": Any, - "date": Any, - "duration": Any, - "groups": { - "added": [], - "changed": [ - { - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "scores": { - "after": 0.7142857142857143, - "before": 0.5, - "diff": 0.2142857142857143, - }, - "slug": "suggestions", - "title": "Suggestions", - }, - ], - "removed": [], - "unchanged": [ - { - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 0.9166666666666666, - "slug": "problems", - "title": "Problems", - }, - { - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 0.6666666666666666, - "slug": "react-best-practices", - "title": "Best Practices (react)", - }, - { - "plugin": { - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - "score": 0.5, - "slug": "react-possible-errors", - "title": "Possible Errors (react)", - }, - ], - }, - "packageName": "@code-pushup/core", - "version": Any, -} -`; diff --git a/e2e/cli-e2e/tests/__snapshots__/compare.report-diff.md b/e2e/cli-e2e/tests/__snapshots__/compare.report-diff.md deleted file mode 100644 index acb2069df..000000000 --- a/e2e/cli-e2e/tests/__snapshots__/compare.report-diff.md +++ /dev/null @@ -1,33 +0,0 @@ -# Code PushUp - -🥳 Code PushUp report has **improved** – compared target commit `` with source commit ``. - -## 🏷️ Categories - -| 🏷️ Category | ⭐ Previous score | ⭐ Current score | 🔄 Score change | -| :------------- | :--------------: | :-------------: | :----------------------------------------------------------------: | -| Code style | 🟡 54 | 🟡 **77** | ![↑ +23.1](https://img.shields.io/badge/%E2%86%91%20%2B23.1-green) | -| Bug prevention | 🟡 68 | 🟡 **68** | – | - -
-👍 1 group improved, 👍 3 audits improved - -## 🗃️ Groups - -| 🔌 Plugin | 🗃️ Group | ⭐ Previous score | ⭐ Current score | 🔄 Score change | -| :----------------------------------------------------------------- | :---------- | :--------------: | :-------------: | :----------------------------------------------------------------: | -| [ESLint](https://www.npmjs.com/package/@code-pushup/eslint-plugin) | Suggestions | 🟡 50 | 🟡 **71** | ![↑ +21.4](https://img.shields.io/badge/%E2%86%91%20%2B21.4-green) | - -3 other groups are unchanged. - -## 🛡️ Audits - -| 🔌 Plugin | 🛡️ Audit | 📏 Previous value | 📏 Current value | 🔄 Value change | -| :----------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------- | :---------------: | :--------------: | :----------------------------------------------------------------------------------: | -| [ESLint](https://www.npmjs.com/package/@code-pushup/eslint-plugin) | [Require or disallow method and property shorthand syntax for object literals](https://eslint.org/docs/latest/rules/object-shorthand) | 🟥 3 warnings | 🟩 **passed** | ![↓ −100 %](https://img.shields.io/badge/%E2%86%93%20%E2%88%92100%E2%80%89%25-green) | -| [ESLint](https://www.npmjs.com/package/@code-pushup/eslint-plugin) | [Require braces around arrow function bodies](https://eslint.org/docs/latest/rules/arrow-body-style) | 🟥 1 warning | 🟩 **passed** | ![↓ −100 %](https://img.shields.io/badge/%E2%86%93%20%E2%88%92100%E2%80%89%25-green) | -| [ESLint](https://www.npmjs.com/package/@code-pushup/eslint-plugin) | [Require `const` declarations for variables that are never reassigned after declared](https://eslint.org/docs/latest/rules/prefer-const) | 🟥 1 warning | 🟩 **passed** | ![↓ −100 %](https://img.shields.io/badge/%E2%86%93%20%E2%88%92100%E2%80%89%25-green) | - -28 other audits are unchanged. - -
diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index d1727fb3b..327aa0b80 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -1,9 +1,9 @@ -import { readFile, writeFile } from 'node:fs/promises'; -import { join } from 'node:path'; -import { simpleGit } from 'simple-git'; -import type { ReportsDiff } from '@code-pushup/models'; -import { cleanTestFolder } from '@code-pushup/test-setup'; -import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; +import {readFile, writeFile} from 'node:fs/promises'; +import {join} from 'node:path'; +import {simpleGit} from 'simple-git'; +import type {ReportsDiff} from '@code-pushup/models'; +import {cleanTestFolder} from '@code-pushup/test-setup'; +import {executeProcess, readJsonFile, readTextFile} from '@code-pushup/utils'; describe('CLI compare', () => { const envRoot = join('examples', 'react-todos-app'); @@ -34,7 +34,7 @@ describe('CLI compare', () => { }, 20_000); afterEach(async () => { - await git.checkout(['--', 'examples/react-todos-app']); + await git.checkout(['--', envRoot]); // await cleanTestFolder('tmp/e2e'); }); @@ -43,14 +43,14 @@ describe('CLI compare', () => { command: 'code-pushup', args: [ 'compare', - '--before=../../tmp/e2e/react-todos-app/source-report.json', - '--after=../../tmp/e2e/react-todos-app/target-report.json', + `--before=${join(envRoot, '.code-pushup', 'source-report.json')}`, + `--after=${join(envRoot, '.code-pushup', 'target-report.json')}`, ], cwd: envRoot, }); const reportsDiff = await readJsonFile( - 'tmp/e2e/react-todos-app/report-diff.json', + join(envRoot, '.code-pushup', 'report-diff.json') ); expect(reportsDiff).toMatchSnapshot({ commits: expect.any(Object), @@ -60,7 +60,7 @@ describe('CLI compare', () => { }); const reportsDiffMd = await readTextFile( - 'tmp/e2e/react-todos-app/report-diff.md', + join(envRoot, '.code-pushup', 'report-diff.md') ); // commits are variable, replace SHAs with placeholders const sanitizedMd = reportsDiffMd.replace(/[\da-f]{40}/g, '``'); From 2d5e51ed3165537a605fb8e2aac88706e784ef55 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 15:15:07 +0100 Subject: [PATCH 32/80] wip test --- e2e/cli-e2e/project.json | 12 +++- .../__snapshots__/compare.e2e.test.ts.snap | 59 +++++++++++++++++++ .../__snapshots__/compare.report-diff.md | 20 +++++++ e2e/cli-e2e/tests/collect.e2e.test.ts | 12 ++-- e2e/cli-e2e/tests/compare.e2e.test.ts | 24 ++++---- e2e/cli-e2e/vite.config.e2e.ts | 1 - examples/react-todos-app/dummy.plugin.ts | 17 +++--- examples/react-todos-app/items.json | 6 +- 8 files changed, 119 insertions(+), 32 deletions(-) create mode 100644 e2e/cli-e2e/tests/__snapshots__/compare.e2e.test.ts.snap create mode 100644 e2e/cli-e2e/tests/__snapshots__/compare.report-diff.md diff --git a/e2e/cli-e2e/project.json b/e2e/cli-e2e/project.json index 1f0873935..68a82ec85 100644 --- a/e2e/cli-e2e/project.json +++ b/e2e/cli-e2e/project.json @@ -11,7 +11,17 @@ "lintFilePatterns": ["e2e/cli-e2e/**/*.ts"] } }, - "e2e-old": { + "nxv-e2e": { + "options": { + "environmentRoot": "examples/react-todos-app" + } + }, + "nxv-env-setup": { + "options": { + "environmentRoot": "examples/react-todos-app" + } + }, + "e2e": { "executor": "@nx/vite:test", "options": { "configFile": "e2e/cli-e2e/vite.config.e2e.ts" diff --git a/e2e/cli-e2e/tests/__snapshots__/compare.e2e.test.ts.snap b/e2e/cli-e2e/tests/__snapshots__/compare.e2e.test.ts.snap new file mode 100644 index 000000000..c062cae7d --- /dev/null +++ b/e2e/cli-e2e/tests/__snapshots__/compare.e2e.test.ts.snap @@ -0,0 +1,59 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`CLI compare > should compare report.json files and create report-diff.json and report-diff.md 1`] = ` +{ + "audits": { + "added": [], + "changed": [ + { + "displayValues": {}, + "plugin": { + "slug": "dummy-plugin", + "title": "Dummy Plugin", + }, + "scores": { + "after": 0.7, + "before": 0.3, + "diff": 0.39999999999999997, + }, + "slug": "dummy-audit", + "title": "Dummy Audit", + "values": { + "after": 7, + "before": 3, + "diff": 4, + }, + }, + ], + "removed": [], + "unchanged": [], + }, + "categories": { + "added": [], + "changed": [ + { + "scores": { + "after": 0.7, + "before": 0.3, + "diff": 0.39999999999999997, + }, + "slug": "dummy-category", + "title": "Dummy Category", + }, + ], + "removed": [], + "unchanged": [], + }, + "commits": Any, + "date": Any, + "duration": Any, + "groups": { + "added": [], + "changed": [], + "removed": [], + "unchanged": [], + }, + "packageName": "@code-pushup/core", + "version": Any, +} +`; diff --git a/e2e/cli-e2e/tests/__snapshots__/compare.report-diff.md b/e2e/cli-e2e/tests/__snapshots__/compare.report-diff.md new file mode 100644 index 000000000..73afdafaa --- /dev/null +++ b/e2e/cli-e2e/tests/__snapshots__/compare.report-diff.md @@ -0,0 +1,20 @@ +# Code PushUp + +🥳 Code PushUp report has **improved** – compared target commit `` with source commit ``. + +## 🏷️ Categories + +| 🏷️ Category | ⭐ Previous score | ⭐ Current score | 🔄 Score change | +| :------------- | :--------------: | :-------------: | :------------------------------------------------------------: | +| Dummy Category | 🔴 30 | 🟡 **70** | ![↑ +40](https://img.shields.io/badge/%E2%86%91%20%2B40-green) | + +
+👍 1 audit improved + +## 🛡️ Audits + +| 🔌 Plugin | 🛡️ Audit | 📏 Previous value | 📏 Current value | 🔄 Value change | +| :----------- | :---------- | :---------------: | :--------------: | :--------------------------------------------------------------------------------: | +| Dummy Plugin | Dummy Audit | 🟥 3 | 🟨 **7** | ![↑ +133.3 %](https://img.shields.io/badge/%E2%86%91%20%2B133.3%E2%80%89%25-green) | + +
diff --git a/e2e/cli-e2e/tests/collect.e2e.test.ts b/e2e/cli-e2e/tests/collect.e2e.test.ts index 5b7210b5c..bf53be5e5 100644 --- a/e2e/cli-e2e/tests/collect.e2e.test.ts +++ b/e2e/cli-e2e/tests/collect.e2e.test.ts @@ -1,7 +1,7 @@ -import {cleanTestFolder, teardownTestFolder} from '@code-pushup/test-setup'; -import {executeProcess, readTextFile} from '@code-pushup/utils'; -import {join} from "node:path"; -import {afterEach} from "vitest"; +import { join } from 'node:path'; +import { afterEach } from 'vitest'; +import { cleanTestFolder, teardownTestFolder } from '@code-pushup/test-setup'; +import { executeProcess, readTextFile } from '@code-pushup/utils'; describe('CLI collect', () => { const dummyPluginTitle = 'Dummy Plugin'; @@ -27,7 +27,9 @@ describe('CLI collect', () => { expect(code).toBe(0); expect(stderr).toBe(''); - const md = await readTextFile('examples/react-todos-app/.code-pushup/report.md'); + const md = await readTextFile( + 'examples/react-todos-app/.code-pushup/report.md', + ); expect(md).toContain('# Code PushUp Report'); expect(md).toContain(dummyPluginTitle); diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index 327aa0b80..8bf7defa5 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -1,9 +1,9 @@ -import {readFile, writeFile} from 'node:fs/promises'; -import {join} from 'node:path'; -import {simpleGit} from 'simple-git'; -import type {ReportsDiff} from '@code-pushup/models'; -import {cleanTestFolder} from '@code-pushup/test-setup'; -import {executeProcess, readJsonFile, readTextFile} from '@code-pushup/utils'; +import { readFile, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { simpleGit } from 'simple-git'; +import type { ReportsDiff } from '@code-pushup/models'; +import { cleanTestFolder } from '@code-pushup/test-setup'; +import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; describe('CLI compare', () => { const envRoot = join('examples', 'react-todos-app'); @@ -15,7 +15,7 @@ describe('CLI compare', () => { `Unstaged changes found in ${envRoot}, please stage or commit them to prevent E2E tests interfering`, ); } - await cleanTestFolder('tmp/e2e/react-todos-app'); + await cleanTestFolder(join(envRoot, '.code-pushup')); await executeProcess({ command: 'code-pushup', args: ['collect', '--persist.filename=source-report'], @@ -35,7 +35,7 @@ describe('CLI compare', () => { afterEach(async () => { await git.checkout(['--', envRoot]); - // await cleanTestFolder('tmp/e2e'); + await cleanTestFolder('tmp/e2e'); }); it('should compare report.json files and create report-diff.json and report-diff.md', async () => { @@ -43,14 +43,14 @@ describe('CLI compare', () => { command: 'code-pushup', args: [ 'compare', - `--before=${join(envRoot, '.code-pushup', 'source-report.json')}`, - `--after=${join(envRoot, '.code-pushup', 'target-report.json')}`, + `--before=${join('.code-pushup', 'source-report.json')}`, + `--after=${join('.code-pushup', 'target-report.json')}`, ], cwd: envRoot, }); const reportsDiff = await readJsonFile( - join(envRoot, '.code-pushup', 'report-diff.json') + join(envRoot, '.code-pushup', 'report-diff.json'), ); expect(reportsDiff).toMatchSnapshot({ commits: expect.any(Object), @@ -60,7 +60,7 @@ describe('CLI compare', () => { }); const reportsDiffMd = await readTextFile( - join(envRoot, '.code-pushup', 'report-diff.md') + join(envRoot, '.code-pushup', 'report-diff.md'), ); // commits are variable, replace SHAs with placeholders const sanitizedMd = reportsDiffMd.replace(/[\da-f]{40}/g, '``'); diff --git a/e2e/cli-e2e/vite.config.e2e.ts b/e2e/cli-e2e/vite.config.e2e.ts index f1b3c3b93..2514c0209 100644 --- a/e2e/cli-e2e/vite.config.e2e.ts +++ b/e2e/cli-e2e/vite.config.e2e.ts @@ -16,7 +16,6 @@ export default defineConfig({ }, environment: 'node', include: ['tests/**/*.e2e.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], - globalSetup: ['../../global-setup.e2e.ts'], setupFiles: ['../../testing/test-setup/src/lib/reset.mocks.ts'], }, }); diff --git a/examples/react-todos-app/dummy.plugin.ts b/examples/react-todos-app/dummy.plugin.ts index 69a5c4266..8c6affe54 100644 --- a/examples/react-todos-app/dummy.plugin.ts +++ b/examples/react-todos-app/dummy.plugin.ts @@ -1,5 +1,5 @@ -import type {PluginConfig} from '@code-pushup/models'; -import {readFile} from "node:fs/promises"; +import { readFile } from 'node:fs/promises'; +import type { PluginConfig } from '@code-pushup/models'; export const dummyPluginSlug = 'dummy-plugin'; @@ -18,12 +18,11 @@ export const dummyCategory = { type: 'audit', plugin: dummyPluginSlug, slug: dummyAuditSlug, - weight: 1 - } - ] + weight: 1, + }, + ], }; - export function create(): PluginConfig { return { slug: dummyPluginSlug, @@ -31,7 +30,9 @@ export function create(): PluginConfig { icon: 'folder-javascript', description: 'A dummy plugin to test the cli.', runner: async () => { - const itemCount = JSON.parse(await readFile('items.json', 'utf-8')).length; + const itemCount = JSON.parse( + await readFile('items.json', 'utf-8'), + ).length; return [ { ...dummyAudit, @@ -39,7 +40,7 @@ export function create(): PluginConfig { score: itemCount < 10 ? itemCount / 10 : 1, value: itemCount, }, - ] + ]; }, audits: [dummyAudit], }; diff --git a/examples/react-todos-app/items.json b/examples/react-todos-app/items.json index a85b7c928..b5d8bb58d 100644 --- a/examples/react-todos-app/items.json +++ b/examples/react-todos-app/items.json @@ -1,5 +1 @@ -[ - 1, - 2, - 3 -] +[1, 2, 3] From 9751e92bb35fdd5d9608b35c75d4cafd4b73b619 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 15:21:41 +0100 Subject: [PATCH 33/80] wip test --- e2e/cli-e2e/tests/collect.e2e.test.ts | 25 ++++++++++++---------- e2e/cli-e2e/tests/compare.e2e.test.ts | 11 +++++----- e2e/cli-e2e/tests/help.e2e.test.ts | 16 ++++++++------ e2e/cli-e2e/tests/print-config.e2e.test.ts | 2 ++ 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/e2e/cli-e2e/tests/collect.e2e.test.ts b/e2e/cli-e2e/tests/collect.e2e.test.ts index bf53be5e5..617fa366d 100644 --- a/e2e/cli-e2e/tests/collect.e2e.test.ts +++ b/e2e/cli-e2e/tests/collect.e2e.test.ts @@ -6,8 +6,8 @@ import { executeProcess, readTextFile } from '@code-pushup/utils'; describe('CLI collect', () => { const dummyPluginTitle = 'Dummy Plugin'; const dummyAuditTitle = 'Dummy Audit'; - const envRoot = 'static-environments/eslint-e2e-env'; - const baseDir = join(envRoot, '__tests__'); + const envRoot = 'examples/react-todos-app'; + const baseDir = join(envRoot, '.code-pushup'); afterEach(async () => { await teardownTestFolder(baseDir); @@ -19,17 +19,20 @@ describe('CLI collect', () => { it('should create report.md', async () => { const { code, stderr } = await executeProcess({ - command: 'code-pushup', - args: ['collect', '--persist.format=md', '--no-progress'], - cwd: 'examples/react-todos-app', + command: 'npx', + args: [ + '@code-pushup/cli', + '--no-progress', + 'collect', + '--persist.format=md', + ], + cwd: envRoot, }); expect(code).toBe(0); expect(stderr).toBe(''); - const md = await readTextFile( - 'examples/react-todos-app/.code-pushup/report.md', - ); + const md = await readTextFile(join(envRoot, '.code-pushup/report.md')); expect(md).toContain('# Code PushUp Report'); expect(md).toContain(dummyPluginTitle); @@ -38,9 +41,9 @@ describe('CLI collect', () => { it('should print report summary to stdout', async () => { const { code, stdout, stderr } = await executeProcess({ - command: 'code-pushup', - args: ['collect', '--no-progress'], - cwd: 'examples/react-todos-app', + command: 'npx', + args: ['@code-pushup/cli', '--no-progress', 'collect'], + cwd: envRoot, }); expect(code).toBe(0); diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index 8bf7defa5..917769b23 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -17,8 +17,8 @@ describe('CLI compare', () => { } await cleanTestFolder(join(envRoot, '.code-pushup')); await executeProcess({ - command: 'code-pushup', - args: ['collect', '--persist.filename=source-report'], + command: 'npx', + args: ['@code-pushup/cli', 'collect', '--persist.filename=source-report'], cwd: envRoot, }); // adding items to create a report diff @@ -27,8 +27,8 @@ describe('CLI compare', () => { await writeFile(itemsFile, JSON.stringify([...items, 4, 5, 6, 7], null, 2)); await executeProcess({ - command: 'code-pushup', - args: ['collect', '--persist.filename=target-report'], + command: 'npx', + args: ['@code-pushup/cli', 'collect', '--persist.filename=target-report'], cwd: envRoot, }); }, 20_000); @@ -40,8 +40,9 @@ describe('CLI compare', () => { it('should compare report.json files and create report-diff.json and report-diff.md', async () => { await executeProcess({ - command: 'code-pushup', + command: 'npx', args: [ + '@code-pushup/cli', 'compare', `--before=${join('.code-pushup', 'source-report.json')}`, `--after=${join('.code-pushup', 'target-report.json')}`, diff --git a/e2e/cli-e2e/tests/help.e2e.test.ts b/e2e/cli-e2e/tests/help.e2e.test.ts index cf5316be1..40bfda4c3 100644 --- a/e2e/cli-e2e/tests/help.e2e.test.ts +++ b/e2e/cli-e2e/tests/help.e2e.test.ts @@ -2,10 +2,13 @@ import { removeColorCodes } from '@code-pushup/test-utils'; import { executeProcess } from '@code-pushup/utils'; describe('CLI help', () => { + const envRoot = 'examples/react-todos-app'; + it('should print help with help command', async () => { const { code, stdout, stderr } = await executeProcess({ - command: 'code-pushup', - args: ['help'], + command: 'npx', + args: ['@code-pushup/cli', 'help'], + cwd: envRoot, }); expect(code).toBe(0); expect(stderr).toBe(''); @@ -14,12 +17,13 @@ describe('CLI help', () => { it('should produce the same output to stdout for both help argument and help command', async () => { const helpArgResult = await executeProcess({ - command: 'code-pushup', - args: ['help'], + command: 'npx', + args: ['@code-pushup/cli', 'help'], }); const helpCommandResult = await executeProcess({ - command: 'code-pushup', - args: ['--help'], + command: 'npx', + args: ['@code-pushup/cli', '--help'], + cwd: envRoot, }); expect(helpArgResult.code).toBe(0); expect(helpCommandResult.code).toBe(0); diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index 46190659d..f74d8b5da 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -7,6 +7,7 @@ export const configFilePath = (ext: (typeof extensions)[number]) => join(process.cwd(), `e2e/cli-e2e/mocks/fixtures/code-pushup.config.${ext}`); describe('print-config', () => { + const envRoot = 'examples/react-todos-app'; it.each(extensions)( 'should load .%s config file with correct arguments', async ext => { @@ -22,6 +23,7 @@ describe('print-config', () => { `--persist.filename=${ext}-report`, '--onlyPlugins=coverage', ], + cwd: envRoot, }); expect(code).toBe(0); From e87e5ef4b6aba52729f99b1633a783a3cdc9cf8b Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 15:53:12 +0100 Subject: [PATCH 34/80] wip test --- .../mocks/fixtures/code-pushup.config.js | 44 ------------------ .../mocks/fixtures/code-pushup.config.mjs | 44 ------------------ .../mocks/fixtures/code-pushup.config.ts | 45 ------------------- e2e/cli-e2e/tests/compare.e2e.test.ts | 5 --- 4 files changed, 138 deletions(-) delete mode 100644 e2e/cli-e2e/mocks/fixtures/code-pushup.config.js delete mode 100644 e2e/cli-e2e/mocks/fixtures/code-pushup.config.mjs delete mode 100644 e2e/cli-e2e/mocks/fixtures/code-pushup.config.ts diff --git a/e2e/cli-e2e/mocks/fixtures/code-pushup.config.js b/e2e/cli-e2e/mocks/fixtures/code-pushup.config.js deleted file mode 100644 index 2a2f0c418..000000000 --- a/e2e/cli-e2e/mocks/fixtures/code-pushup.config.js +++ /dev/null @@ -1,44 +0,0 @@ -import { join } from 'node:path'; -import coveragePlugin from '@code-pushup/coverage-plugin'; -import eslintPlugin from '@code-pushup/eslint-plugin'; - -export default { - upload: { - organization: 'code-pushup', - project: 'cli-js', - apiKey: 'e2e-api-key', - server: 'https://e2e.com/api', - }, - categories: [ - { - slug: 'bug-prevention', - title: 'Bug prevention', - refs: [{ type: 'group', plugin: 'eslint', slug: 'problems', weight: 1 }], - }, - { - slug: 'code-style', - title: 'Code style', - refs: [ - { type: 'group', plugin: 'eslint', slug: 'suggestions', weight: 1 }, - ], - }, - { - slug: 'code-coverage', - title: 'Code coverage', - refs: [ - { - type: 'group', - plugin: 'coverage', - slug: 'coverage', - weight: 1, - }, - ], - }, - ], - plugins: [ - await eslintPlugin({ eslintrc: '.eslintrc.json', patterns: '**/*.ts' }), - await coveragePlugin({ - reports: [join('e2e', 'cli-e2e', 'mocks', 'fixtures', 'lcov.info')], - }), - ], -}; diff --git a/e2e/cli-e2e/mocks/fixtures/code-pushup.config.mjs b/e2e/cli-e2e/mocks/fixtures/code-pushup.config.mjs deleted file mode 100644 index ee282c54e..000000000 --- a/e2e/cli-e2e/mocks/fixtures/code-pushup.config.mjs +++ /dev/null @@ -1,44 +0,0 @@ -import { join } from 'node:path'; -import coveragePlugin from '@code-pushup/coverage-plugin'; -import eslintPlugin from '@code-pushup/eslint-plugin'; - -export default { - upload: { - organization: 'code-pushup', - project: 'cli-mjs', - apiKey: 'e2e-api-key', - server: 'https://e2e.com/api', - }, - categories: [ - { - slug: 'bug-prevention', - title: 'Bug prevention', - refs: [{ type: 'group', plugin: 'eslint', slug: 'problems', weight: 1 }], - }, - { - slug: 'code-style', - title: 'Code style', - refs: [ - { type: 'group', plugin: 'eslint', slug: 'suggestions', weight: 1 }, - ], - }, - { - slug: 'code-coverage', - title: 'Code coverage', - refs: [ - { - type: 'group', - plugin: 'coverage', - slug: 'coverage', - weight: 1, - }, - ], - }, - ], - plugins: [ - await eslintPlugin({ eslintrc: '.eslintrc.json', patterns: '**/*.ts' }), - await coveragePlugin({ - reports: [join('e2e', 'cli-e2e', 'mocks', 'fixtures', 'lcov.info')], - }), - ], -}; diff --git a/e2e/cli-e2e/mocks/fixtures/code-pushup.config.ts b/e2e/cli-e2e/mocks/fixtures/code-pushup.config.ts deleted file mode 100644 index f6f2229a8..000000000 --- a/e2e/cli-e2e/mocks/fixtures/code-pushup.config.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { join } from 'node:path'; -import coveragePlugin from '@code-pushup/coverage-plugin'; -import eslintPlugin from '@code-pushup/eslint-plugin'; -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: 'bug-prevention', - title: 'Bug prevention', - refs: [{ type: 'group', plugin: 'eslint', slug: 'problems', weight: 1 }], - }, - { - slug: 'code-style', - title: 'Code style', - refs: [ - { type: 'group', plugin: 'eslint', slug: 'suggestions', weight: 1 }, - ], - }, - { - slug: 'code-coverage', - title: 'Code coverage', - refs: [ - { - type: 'group', - plugin: 'coverage', - slug: 'coverage', - weight: 1, - }, - ], - }, - ], - plugins: [ - await eslintPlugin({ eslintrc: '.eslintrc.json', patterns: '**/*.ts' }), - await coveragePlugin({ - reports: [join('e2e', 'cli-e2e', 'mocks', 'fixtures', 'lcov.info')], - }), - ], -} satisfies CoreConfig; diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index 917769b23..402d2f804 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -10,11 +10,6 @@ describe('CLI compare', () => { const git = simpleGit(); beforeEach(async () => { - if (await git.diff(['--', envRoot])) { - throw new Error( - `Unstaged changes found in ${envRoot}, please stage or commit them to prevent E2E tests interfering`, - ); - } await cleanTestFolder(join(envRoot, '.code-pushup')); await executeProcess({ command: 'npx', From 75a112efb5c23ffb00516488ee37fa73be31aa25 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 15:54:50 +0100 Subject: [PATCH 35/80] wip env --- e2e/cli-e2e/mocks/fixtures/lcov.info | 78 ------------------ e2e/cli-e2e/project.json | 2 +- e2e/cli-e2e/tests/print-config.e2e.test.ts | 26 ++---- examples/react-todos-app/.eslintrc.js | 69 ---------------- .../react-todos-app/code-pushup.config.js | 6 ++ .../react-todos-app/code-pushup.config.mjs | 6 ++ examples/react-todos-app/index.html | 15 ---- examples/react-todos-app/public/favicon.ico | Bin 15086 -> 0 bytes examples/react-todos-app/src/App.jsx | 21 ----- examples/react-todos-app/src/App.test.jsx | 20 ----- .../src/components/CreateTodo.jsx | 30 ------- .../src/components/TodoFilter.jsx | 27 ------ .../src/components/TodoList.jsx | 33 -------- .../react-todos-app/src/hooks/useTodos.js | 73 ---------------- examples/react-todos-app/src/index.jsx | 6 -- examples/react-todos-app/test-setup.js | 9 -- examples/react-todos-app/tsconfig.app.json | 24 ------ examples/react-todos-app/tsconfig.json | 21 ----- examples/react-todos-app/tsconfig.spec.json | 16 ---- 19 files changed, 20 insertions(+), 462 deletions(-) delete mode 100644 e2e/cli-e2e/mocks/fixtures/lcov.info delete mode 100644 examples/react-todos-app/.eslintrc.js create mode 100644 examples/react-todos-app/code-pushup.config.js create mode 100644 examples/react-todos-app/code-pushup.config.mjs delete mode 100644 examples/react-todos-app/index.html delete mode 100644 examples/react-todos-app/public/favicon.ico delete mode 100644 examples/react-todos-app/src/App.jsx delete mode 100644 examples/react-todos-app/src/App.test.jsx delete mode 100644 examples/react-todos-app/src/components/CreateTodo.jsx delete mode 100644 examples/react-todos-app/src/components/TodoFilter.jsx delete mode 100644 examples/react-todos-app/src/components/TodoList.jsx delete mode 100644 examples/react-todos-app/src/hooks/useTodos.js delete mode 100644 examples/react-todos-app/src/index.jsx delete mode 100644 examples/react-todos-app/test-setup.js delete mode 100644 examples/react-todos-app/tsconfig.app.json delete mode 100644 examples/react-todos-app/tsconfig.json delete mode 100644 examples/react-todos-app/tsconfig.spec.json diff --git a/e2e/cli-e2e/mocks/fixtures/lcov.info b/e2e/cli-e2e/mocks/fixtures/lcov.info deleted file mode 100644 index 474ad74e7..000000000 --- a/e2e/cli-e2e/mocks/fixtures/lcov.info +++ /dev/null @@ -1,78 +0,0 @@ -TN: -SF:src\lib\partly-covered\utils.ts -FN:2,formatReportScore -FN:6,calcDuration -FNF:2 -FNH:1 -FNDA:0,formatReportScore -FNDA:6,calcDuration -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:7,0 -DA:8,0 -DA:9,0 -DA:10,1 -LF:10 -LH:7 -BRDA:1,0,0,6 -BRDA:1,1,0,5 -BRDA:2,4,0,1 -BRDA:4,5,0,17 -BRDA:5,6,0,4 -BRDA:6,7,0,13 -BRDA:6,10,1,0 -BRDA:7,11,0,3 -BRDA:10,12,0,12 -BRDA:10,13,1,0 -BRF:10 -BRH:8 -end_of_record -SF:src\lib\not-covered\sorting.ts -FN:1,sortReport -FNF:1 -FNH:0 -FNDA:0,sortReport -DA:1,0 -DA:2,0 -DA:3,0 -DA:4,0 -DA:5,0 -LF:5 -LH:0 -BRDA:7,1,0,0 -BRDA:7,2,1,0 -BRF:2 -BRH:0 -end_of_record -TN: -SF:src\lib\fully-covered\scoring.ts -FN:2,scoreReport -FN:8,calculateScore -FNF:2 -FNH:2 -FNDA:3,scoreReport -FNDA:5,calculateScore -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -LF:10 -LH:10 -BRDA:1,0,0,5 -BRDA:2,1,0,1 -BRDA:2,2,1,4 -BRDA:2,3,2,3 -BRDA:6,4,0,4 -BRF:5 -BRH:5 -end_of_record diff --git a/e2e/cli-e2e/project.json b/e2e/cli-e2e/project.json index 68a82ec85..8db41a017 100644 --- a/e2e/cli-e2e/project.json +++ b/e2e/cli-e2e/project.json @@ -28,6 +28,6 @@ } } }, - "implicitDependencies": ["models", "utils", "core", "cli", "react-todos-app"], + "implicitDependencies": ["cli", "react-todos-app"], "tags": ["scope:core", "scope:plugin", "type:e2e"] } diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index f74d8b5da..6db147fd9 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -4,16 +4,17 @@ import { executeProcess } from '@code-pushup/utils'; const extensions = ['js', 'mjs', 'ts'] as const; export const configFilePath = (ext: (typeof extensions)[number]) => - join(process.cwd(), `e2e/cli-e2e/mocks/fixtures/code-pushup.config.${ext}`); + join(process.cwd(), `examples/react-todos-app/code-pushup.config.${ext}`); -describe('print-config', () => { +describe('CLI print-config', () => { const envRoot = 'examples/react-todos-app'; it.each(extensions)( 'should load .%s config file with correct arguments', async ext => { const { code, stdout } = await executeProcess({ - command: 'code-pushup', + command: 'npx', args: [ + '@code-pushup/cli', 'print-config', '--no-progress', `--config=${configFilePath(ext)}`, @@ -21,7 +22,6 @@ describe('print-config', () => { '--persist.outputDir=output-dir', '--persist.format=md', `--persist.filename=${ext}-report`, - '--onlyPlugins=coverage', ], cwd: envRoot, }); @@ -33,25 +33,13 @@ describe('print-config', () => { config: expect.stringContaining(`code-pushup.config.${ext}`), tsconfig: 'tsconfig.base.json', // filled by command options - persist: { - outputDir: 'output-dir', - filename: `${ext}-report`, - format: ['md'], - }, - upload: { - organization: 'code-pushup', - project: `cli-${ext}`, - apiKey: 'e2e-api-key', - server: 'https://e2e.com/api', - }, plugins: [ expect.objectContaining({ - slug: 'coverage', - title: 'Code coverage', + slug: 'dummy-plugin', + title: 'Dummy Plugin', }), ], - categories: [expect.objectContaining({ slug: 'code-coverage' })], - onlyPlugins: ['coverage'], + categories: [expect.objectContaining({ slug: 'dummy-category' })], }), ); }, diff --git a/examples/react-todos-app/.eslintrc.js b/examples/react-todos-app/.eslintrc.js deleted file mode 100644 index e05f2bb62..000000000 --- a/examples/react-todos-app/.eslintrc.js +++ /dev/null @@ -1,69 +0,0 @@ -/** @type {import('eslint').ESLint.ConfigData} */ -module.exports = { - root: true, - env: { - browser: true, - es2021: true, - }, - plugins: ['react', 'react-hooks'], - overrides: [ - { - env: { - node: true, - }, - files: ['.eslintrc.{js,cjs}'], - parserOptions: { - sourceType: 'script', - }, - }, - ], - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - }, - settings: { - react: { - version: 'detect', - }, - }, - rules: { - // https://eslint.org/docs/latest/rules/#possible-problems - 'no-cond-assign': 'warn', - 'no-const-assign': 'warn', - 'no-debugger': 'warn', - 'no-invalid-regexp': 'warn', - 'no-undef': 'warn', - 'no-unreachable-loop': 'warn', - 'no-unsafe-negation': 'warn', - 'no-unsafe-optional-chaining': 'warn', - 'no-unused-vars': 'warn', - 'use-isnan': 'warn', - 'valid-typeof': 'warn', - // https://eslint.org/docs/latest/rules/#suggestions - 'arrow-body-style': 'warn', - camelcase: 'warn', - curly: 'warn', - eqeqeq: 'warn', - 'max-lines-per-function': 'warn', - 'max-lines': 'warn', - 'no-shadow': 'warn', - 'no-var': 'warn', - 'object-shorthand': 'warn', - 'prefer-arrow-callback': 'warn', - 'prefer-const': 'warn', - 'prefer-object-spread': 'warn', - yoda: 'warn', - // https://github.com/jsx-eslint/eslint-plugin-react#list-of-supported-rules - 'react/jsx-key': 'warn', - 'react/prop-types': 'warn', - 'react/react-in-jsx-scope': 'warn', - 'react/jsx-uses-vars': 'warn', - 'react/jsx-uses-react': 'error', - // https://www.npmjs.com/package/eslint-plugin-react-hooks - 'react-hooks/rules-of-hooks': 'error', - 'react-hooks/exhaustive-deps': 'warn', - }, -}; diff --git a/examples/react-todos-app/code-pushup.config.js b/examples/react-todos-app/code-pushup.config.js new file mode 100644 index 000000000..26928cba2 --- /dev/null +++ b/examples/react-todos-app/code-pushup.config.js @@ -0,0 +1,6 @@ +import dummyPlugin, { dummyCategory } from './dummy.plugin'; + +export default { + plugins: [dummyPlugin()], + categories: [dummyCategory], +}; diff --git a/examples/react-todos-app/code-pushup.config.mjs b/examples/react-todos-app/code-pushup.config.mjs new file mode 100644 index 000000000..26928cba2 --- /dev/null +++ b/examples/react-todos-app/code-pushup.config.mjs @@ -0,0 +1,6 @@ +import dummyPlugin, { dummyCategory } from './dummy.plugin'; + +export default { + plugins: [dummyPlugin()], + categories: [dummyCategory], +}; diff --git a/examples/react-todos-app/index.html b/examples/react-todos-app/index.html deleted file mode 100644 index 35db2fc31..000000000 --- a/examples/react-todos-app/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Todos app (React example) - - - - - - -
- - - diff --git a/examples/react-todos-app/public/favicon.ico b/examples/react-todos-app/public/favicon.ico deleted file mode 100644 index 317ebcb2336e0833a22dddf0ab287849f26fda57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 zcmeI332;U^%p|z7g|#(P)qFEA@4f!_@qOK2 z_lJl}!lhL!VT_U|uN7%8B2iKH??xhDa;*`g{yjTFWHvXn;2s{4R7kH|pKGdy(7z!K zgftM+Ku7~24TLlh(!g)gz|foI94G^t2^IO$uvX$3(OR0<_5L2sB)lMAMy|+`xodJ{ z_Uh_1m)~h?a;2W{dmhM;u!YGo=)OdmId_B<%^V^{ovI@y`7^g1_V9G}*f# zNzAtvou}I!W1#{M^@ROc(BZ! z+F!!_aR&Px3_reO(EW+TwlW~tv*2zr?iP7(d~a~yA|@*a89IUke+c472NXM0wiX{- zl`UrZC^1XYyf%1u)-Y)jj9;MZ!SLfd2Hl?o|80Su%Z?To_=^g_Jt0oa#CT*tjx>BI z16wec&AOWNK<#i0Qd=1O$fymLRoUR*%;h@*@v7}wApDl^w*h}!sYq%kw+DKDY)@&A z@9$ULEB3qkR#85`lb8#WZw=@})#kQig9oqy^I$dj&k4jU&^2(M3q{n1AKeGUKPFbr z1^<)aH;VsG@J|B&l>UtU#Ejv3GIqERzYgL@UOAWtW<{p#zy`WyJgpCy8$c_e%wYJL zyGHRRx38)HyjU3y{-4z6)pzb>&Q1pR)B&u01F-|&Gx4EZWK$nkUkOI|(D4UHOXg_- zw{OBf!oWQUn)Pe(=f=nt=zkmdjpO^o8ZZ9o_|4tW1ni+Un9iCW47*-ut$KQOww!;u z`0q)$s6IZO!~9$e_P9X!hqLxu`fpcL|2f^I5d4*a@Dq28;@2271v_N+5HqYZ>x;&O z05*7JT)mUe&%S0@UD)@&8SmQrMtsDfZT;fkdA!r(S=}Oz>iP)w=W508=Rc#nNn7ym z1;42c|8($ALY8#a({%1#IXbWn9-Y|0eDY$_L&j{63?{?AH{);EzcqfydD$@-B`Y3<%IIj7S7rK_N}je^=dEk%JQ4c z!tBdTPE3Tse;oYF>cnrapWq*o)m47X1`~6@(!Y29#>-#8zm&LXrXa(3=7Z)ElaQqj z-#0JJy3Fi(C#Rx(`=VXtJ63E2_bZGCz+QRa{W0e2(m3sI?LOcUBx)~^YCqZ{XEPX)C>G>U4tfqeH8L(3|pQR*zbL1 zT9e~4Tb5p9_G}$y4t`i*4t_Mr9QYvL9C&Ah*}t`q*}S+VYh0M6GxTTSXI)hMpMpIq zD1ImYqJLzbj0}~EpE-aH#VCH_udYEW#`P2zYmi&xSPs_{n6tBj=MY|-XrA;SGA_>y zGtU$?HXm$gYj*!N)_nQ59%lQdXtQZS3*#PC-{iB_sm+ytD*7j`D*k(P&IH2GHT}Eh z5697eQECVIGQAUe#eU2I!yI&%0CP#>%6MWV z@zS!p@+Y1i1b^QuuEF*13CuB zu69dve5k7&Wgb+^s|UB08Dr3u`h@yM0NTj4h7MnHo-4@xmyr7(*4$rpPwsCDZ@2be zRz9V^GnV;;?^Lk%ynzq&K(Aix`mWmW`^152Hoy$CTYVehpD-S1-W^#k#{0^L`V6CN+E z!w+xte;2vu4AmVNEFUOBmrBL>6MK@!O2*N|2=d|Y;oN&A&qv=qKn73lDD zI(+oJAdgv>Yr}8(&@ZuAZE%XUXmX(U!N+Z_sjL<1vjy1R+1IeHt`79fnYdOL{$ci7 z%3f0A*;Zt@ED&Gjm|OFTYBDe%bbo*xXAQsFz+Q`fVBH!N2)kaxN8P$c>sp~QXnv>b zwq=W3&Mtmih7xkR$YA)1Yi?avHNR6C99!u6fh=cL|KQ&PwF!n@ud^n(HNIImHD!h87!i*t?G|p0o+eelJ?B@A64_9%SBhNaJ64EvKgD&%LjLCYnNfc; znj?%*p@*?dq#NqcQFmmX($wms@CSAr9#>hUR^=I+=0B)vvGX%T&#h$kmX*s=^M2E!@N9#m?LhMvz}YB+kd zG~mbP|D(;{s_#;hsKK9lbVK&Lo734x7SIFJ9V_}2$@q?zm^7?*XH94w5Qae{7zOMUF z^?%F%)c1Y)Q?Iy?I>knw*8gYW#ok|2gdS=YYZLiD=CW|Nj;n^x!=S#iJ#`~Ld79+xXpVmUK^B(xO_vO!btA9y7w3L3-0j-y4 z?M-V{%z;JI`bk7yFDcP}OcCd*{Q9S5$iGA7*E1@tfkyjAi!;wP^O71cZ^Ep)qrQ)N z#wqw0_HS;T7x3y|`P==i3hEwK%|>fZ)c&@kgKO1~5<5xBSk?iZV?KI6&i72H6S9A* z=U(*e)EqEs?Oc04)V-~K5AUmh|62H4*`UAtItO$O(q5?6jj+K^oD!04r=6#dsxp?~}{`?&sXn#q2 zGuY~7>O2=!u@@Kfu7q=W*4egu@qPMRM>(eyYyaIE<|j%d=iWNdGsx%c!902v#ngNg z@#U-O_4xN$s_9?(`{>{>7~-6FgWpBpqXb`Ydc3OFL#&I}Irse9F_8R@4zSS*Y*o*B zXL?6*Aw!AfkNCgcr#*yj&p3ZDe2y>v$>FUdKIy_2N~}6AbHc7gA3`6$g@1o|dE>vz z4pl(j9;kyMsjaw}lO?(?Xg%4k!5%^t#@5n=WVc&JRa+XT$~#@rldvN3S1rEpU$;XgxVny7mki3 z-Hh|jUCHrUXuLr!)`w>wgO0N%KTB-1di>cj(x3Bav`7v z3G7EIbU$z>`Nad7Rk_&OT-W{;qg)-GXV-aJT#(ozdmnA~Rq3GQ_3mby(>q6Ocb-RgTUhTN)))x>m&eD;$J5Bg zo&DhY36Yg=J=$Z>t}RJ>o|@hAcwWzN#r(WJ52^g$lh^!63@hh+dR$&_dEGu&^CR*< z!oFqSqO@>xZ*nC2oiOd0eS*F^IL~W-rsrO`J`ej{=ou_q^_(<$&-3f^J z&L^MSYWIe{&pYq&9eGaArA~*kA { - const { loading, todos, onCreate, onEdit, setQuery, setHideComplete } = - useTodos(); - - return ( -
-

TODOs

- - - -
- ); -}; - -export default App; diff --git a/examples/react-todos-app/src/App.test.jsx b/examples/react-todos-app/src/App.test.jsx deleted file mode 100644 index c8e5667bc..000000000 --- a/examples/react-todos-app/src/App.test.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import '@testing-library/jest-dom'; -import { render, screen } from '@testing-library/react'; -import React from 'react'; -import { describe, expect, it } from 'vitest'; -import App from './App'; - -describe('App', () => { - it('should display the app title', async () => { - render(); - - expect(screen.getByRole('heading')).toHaveTextContent('TODOs'); - }); - - it('should display an Add button', async () => { - render(); - - expect(screen.getByRole('button')).toBeVisible(); - expect(screen.getByRole('button')).toHaveTextContent('Add'); - }); -}); diff --git a/examples/react-todos-app/src/components/CreateTodo.jsx b/examples/react-todos-app/src/components/CreateTodo.jsx deleted file mode 100644 index 63cdf9f47..000000000 --- a/examples/react-todos-app/src/components/CreateTodo.jsx +++ /dev/null @@ -1,30 +0,0 @@ -import React, { useState } from 'react'; - -const CreateTodo = props => { - const [title, setTitle] = useState(''); - - return ( -
{ - event.preventDefault(); - props.onCreate(title); - setTitle(''); - }} - > - { - setTitle(event.target.value); - }} - /> - -
- ); -}; - -export default CreateTodo; diff --git a/examples/react-todos-app/src/components/TodoFilter.jsx b/examples/react-todos-app/src/components/TodoFilter.jsx deleted file mode 100644 index 01985dbed..000000000 --- a/examples/react-todos-app/src/components/TodoFilter.jsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; - -const TodoFilter = props => { - return ( -
- { - props.setQuery(event.target.value); - }} - /> - - -
- ); -}; - -export default TodoFilter; diff --git a/examples/react-todos-app/src/components/TodoList.jsx b/examples/react-todos-app/src/components/TodoList.jsx deleted file mode 100644 index 3a3dbc8f7..000000000 --- a/examples/react-todos-app/src/components/TodoList.jsx +++ /dev/null @@ -1,33 +0,0 @@ -import moment from 'moment'; -import React from 'react'; - -const TodoList = props => ( -
    - {props.todos.map(todo => ( -
  • - -
  • - ))} -
-); - -export default TodoList; diff --git a/examples/react-todos-app/src/hooks/useTodos.js b/examples/react-todos-app/src/hooks/useTodos.js deleted file mode 100644 index 01091cfc0..000000000 --- a/examples/react-todos-app/src/hooks/useTodos.js +++ /dev/null @@ -1,73 +0,0 @@ -import { useCallback, useEffect, useMemo, useState } from 'react'; - -export const useTodos = () => { - const [loading, setLoading] = useState(false); - const [data, setData] = useState([]); - - useEffect(() => { - setLoading(true); - fetch('https://jsonplaceholder.typicode.com/todos') - .then(resp => resp.json()) - .then(data => { - setData(data); - setLoading(false); - }); - }, []); - - const onCreate = useCallback(title => { - const body = JSON.stringify({ - title: title, - complete: false, - }); - - fetch('https://jsonplaceholder.typicode.com/todos', { - method: 'POST', - body, - }) - .then(resp => resp.json()) - .then(({ id }) => { - setData(data => [ - ...data, - { - id: id, - title: title, - complete: false, - }, - ]); - }); - }); - - const onEdit = useCallback(todo => { - setData(data => data.map(t => (t.id == todo.id ? todo : t))); - fetch(`https://jsonplaceholder.typicode.com/todos/${todo.id}`, { - method: 'PUT', - body: JSON.stringify(todo), - }); - }); - - const [query, setQuery] = useState(''); - const [hideComplete, setHideComplete] = useState(false); - - const todos = useMemo( - () => - data.filter(todo => { - if (query && !todo.title.toLowerCase().includes(query.toLowerCase())) { - return false; - } - if (hideComplete && todo.complete) { - return false; - } - return true; - }), - [data, query, hideComplete], - ); - - return { - loading, - todos, - onCreate, - onEdit, - setQuery, - setHideComplete, - }; -}; diff --git a/examples/react-todos-app/src/index.jsx b/examples/react-todos-app/src/index.jsx deleted file mode 100644 index 6ee32ccaf..000000000 --- a/examples/react-todos-app/src/index.jsx +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react'; -import { createRoot } from 'react-dom/client'; -import App from './App'; - -let root = createRoot(document.querySelector('#root')); -root.render(); diff --git a/examples/react-todos-app/test-setup.js b/examples/react-todos-app/test-setup.js deleted file mode 100644 index 141cd45f9..000000000 --- a/examples/react-todos-app/test-setup.js +++ /dev/null @@ -1,9 +0,0 @@ -import * as matchers from '@testing-library/jest-dom/matchers'; -import { cleanup } from '@testing-library/react'; -import { afterEach, expect } from 'vitest'; - -expect.extend(matchers); - -afterEach(() => { - cleanup(); -}); diff --git a/examples/react-todos-app/tsconfig.app.json b/examples/react-todos-app/tsconfig.app.json deleted file mode 100644 index a86621c8c..000000000 --- a/examples/react-todos-app/tsconfig.app.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "types": [ - "node", - "@nx/react/typings/cssmodule.d.ts", - "@nx/react/typings/image.d.ts", - "vite/client" - ] - }, - "exclude": [ - "vite.config.ts", - "src/**/*.spec.ts", - "src/**/*.test.ts", - "src/**/*.spec.tsx", - "src/**/*.test.tsx", - "src/**/*.spec.js", - "src/**/*.test.js", - "src/**/*.spec.jsx", - "src/**/*.test.jsx" - ], - "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] -} diff --git a/examples/react-todos-app/tsconfig.json b/examples/react-todos-app/tsconfig.json deleted file mode 100644 index fdfab6c30..000000000 --- a/examples/react-todos-app/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "jsx": "react-jsx", - "allowJs": false, - "esModuleInterop": false, - "allowSyntheticDefaultImports": true, - "strict": true, - "types": ["vite/client", "vitest"] - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - } - ], - "extends": "../../tsconfig.base.json" -} diff --git a/examples/react-todos-app/tsconfig.spec.json b/examples/react-todos-app/tsconfig.spec.json deleted file mode 100644 index 9a202f348..000000000 --- a/examples/react-todos-app/tsconfig.spec.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"] - }, - "include": [ - "vite.config.ts", - "src/**/*.test.js", - "src/**/*.spec.js", - "src/**/*.test.jsx", - "src/**/*.spec.jsx", - "src/**/*.d.ts" - ], - "types": ["@nx/react/typings/cssmodule.d.ts", "@nx/react/typings/image.d.ts"] -} From ce7406470172fb0748cd5b747e44f9fb2ad10375 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 16:02:10 +0100 Subject: [PATCH 36/80] wip env --- e2e/cli-e2e/project.json | 6 +-- e2e/cli-e2e/tests/collect.e2e.test.ts | 2 +- e2e/cli-e2e/tests/compare.e2e.test.ts | 4 +- e2e/cli-e2e/tests/help.e2e.test.ts | 3 +- e2e/cli-e2e/tests/print-config.e2e.test.ts | 2 +- .../react-todos-app/code-pushup.config.js | 6 --- .../react-todos-app/code-pushup.config.mjs | 6 --- examples/react-todos-app/package.json | 16 ------- examples/react-todos-app/vite.config.ts | 44 ------------------- .../cli-e2e-env}/code-pushup.config.ts | 0 .../cli-e2e-env}/dummy.plugin.ts | 3 +- static-environments/cli-e2e-env/package.json | 19 ++++++++ .../cli-e2e-env}/project.json | 4 +- .../cli-e2e-env/src}/items.json | 0 14 files changed, 32 insertions(+), 83 deletions(-) delete mode 100644 examples/react-todos-app/code-pushup.config.js delete mode 100644 examples/react-todos-app/code-pushup.config.mjs delete mode 100644 examples/react-todos-app/package.json delete mode 100644 examples/react-todos-app/vite.config.ts rename {examples/react-todos-app => static-environments/cli-e2e-env}/code-pushup.config.ts (100%) rename {examples/react-todos-app => static-environments/cli-e2e-env}/dummy.plugin.ts (91%) create mode 100644 static-environments/cli-e2e-env/package.json rename {examples/react-todos-app => static-environments/cli-e2e-env}/project.json (96%) rename {examples/react-todos-app => static-environments/cli-e2e-env/src}/items.json (100%) diff --git a/e2e/cli-e2e/project.json b/e2e/cli-e2e/project.json index 8db41a017..964a19f81 100644 --- a/e2e/cli-e2e/project.json +++ b/e2e/cli-e2e/project.json @@ -13,12 +13,12 @@ }, "nxv-e2e": { "options": { - "environmentRoot": "examples/react-todos-app" + "environmentRoot": "static-environments/cli-e2e-env" } }, "nxv-env-setup": { "options": { - "environmentRoot": "examples/react-todos-app" + "environmentRoot": "static-environments/cli-e2e-env" } }, "e2e": { @@ -28,6 +28,6 @@ } } }, - "implicitDependencies": ["cli", "react-todos-app"], + "implicitDependencies": ["cli", "cli-e2e-env"], "tags": ["scope:core", "scope:plugin", "type:e2e"] } diff --git a/e2e/cli-e2e/tests/collect.e2e.test.ts b/e2e/cli-e2e/tests/collect.e2e.test.ts index 617fa366d..cabc810be 100644 --- a/e2e/cli-e2e/tests/collect.e2e.test.ts +++ b/e2e/cli-e2e/tests/collect.e2e.test.ts @@ -6,7 +6,7 @@ import { executeProcess, readTextFile } from '@code-pushup/utils'; describe('CLI collect', () => { const dummyPluginTitle = 'Dummy Plugin'; const dummyAuditTitle = 'Dummy Audit'; - const envRoot = 'examples/react-todos-app'; + const envRoot = join('static-environments', 'cli-e2e-env'); const baseDir = join(envRoot, '.code-pushup'); afterEach(async () => { diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index 402d2f804..e8350589e 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -6,7 +6,7 @@ import { cleanTestFolder } from '@code-pushup/test-setup'; import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; describe('CLI compare', () => { - const envRoot = join('examples', 'react-todos-app'); + const envRoot = join('static-environments', 'cli-e2e-env'); const git = simpleGit(); beforeEach(async () => { @@ -17,7 +17,7 @@ describe('CLI compare', () => { cwd: envRoot, }); // adding items to create a report diff - const itemsFile = join(envRoot, 'items.json'); + const itemsFile = join(envRoot, 'src', 'items.json'); const items = JSON.parse((await readFile(itemsFile)).toString()); await writeFile(itemsFile, JSON.stringify([...items, 4, 5, 6, 7], null, 2)); diff --git a/e2e/cli-e2e/tests/help.e2e.test.ts b/e2e/cli-e2e/tests/help.e2e.test.ts index 40bfda4c3..6e3586290 100644 --- a/e2e/cli-e2e/tests/help.e2e.test.ts +++ b/e2e/cli-e2e/tests/help.e2e.test.ts @@ -1,8 +1,9 @@ import { removeColorCodes } from '@code-pushup/test-utils'; import { executeProcess } from '@code-pushup/utils'; +import {join} from "node:path"; describe('CLI help', () => { - const envRoot = 'examples/react-todos-app'; + const envRoot = join('static-environments', 'cli-e2e-env'); it('should print help with help command', async () => { const { code, stdout, stderr } = await executeProcess({ diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index 6db147fd9..3a6998396 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -7,7 +7,7 @@ export const configFilePath = (ext: (typeof extensions)[number]) => join(process.cwd(), `examples/react-todos-app/code-pushup.config.${ext}`); describe('CLI print-config', () => { - const envRoot = 'examples/react-todos-app'; + const envRoot = join('static-environments', 'cli-e2e-env'); it.each(extensions)( 'should load .%s config file with correct arguments', async ext => { diff --git a/examples/react-todos-app/code-pushup.config.js b/examples/react-todos-app/code-pushup.config.js deleted file mode 100644 index 26928cba2..000000000 --- a/examples/react-todos-app/code-pushup.config.js +++ /dev/null @@ -1,6 +0,0 @@ -import dummyPlugin, { dummyCategory } from './dummy.plugin'; - -export default { - plugins: [dummyPlugin()], - categories: [dummyCategory], -}; diff --git a/examples/react-todos-app/code-pushup.config.mjs b/examples/react-todos-app/code-pushup.config.mjs deleted file mode 100644 index 26928cba2..000000000 --- a/examples/react-todos-app/code-pushup.config.mjs +++ /dev/null @@ -1,6 +0,0 @@ -import dummyPlugin, { dummyCategory } from './dummy.plugin'; - -export default { - plugins: [dummyPlugin()], - categories: [dummyCategory], -}; diff --git a/examples/react-todos-app/package.json b/examples/react-todos-app/package.json deleted file mode 100644 index d9e892a84..000000000 --- a/examples/react-todos-app/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "todo-app", - "private": true, - "scripts": { - "start": "esbuild src/index.jsx --bundle --outdir=www/js --servedir=www", - "build": "esbuild src/index.jsx --bundle --outdir=www/js --minify" - }, - "dependencies": { - "react": "^16.12.0", - "semver": "5.7.1" - }, - "devDependencies": { - "vite": "~4.5.0", - "vitest": "0.34.0" - } -} diff --git a/examples/react-todos-app/vite.config.ts b/examples/react-todos-app/vite.config.ts deleted file mode 100644 index 91e6f3d1b..000000000 --- a/examples/react-todos-app/vite.config.ts +++ /dev/null @@ -1,44 +0,0 @@ -/// -import react from '@vitejs/plugin-react'; -import { dirname } from 'node:path'; -import { fileURLToPath } from 'node:url'; -import { defineConfig } from 'vite'; - -export default defineConfig({ - root: fileURLToPath(dirname(import.meta.url)), - build: { - outDir: '../../dist/examples/react-todos-app', - emptyOutDir: true, - reportCompressedSize: true, - }, - cacheDir: '../../node_modules/.vite/react-todos-app', - - server: { - port: 3000, - host: 'localhost', - }, - - preview: { - port: 3100, - host: 'localhost', - }, - - plugins: [react()], - - test: { - reporters: ['basic'], - globals: true, - cache: { - dir: '../../node_modules/.vitest', - }, - coverage: { - reporter: ['lcov', 'text'], - provider: 'v8', - reportsDirectory: '../../coverage/react-todos-app', - include: ['src/**/*.{js,jsx}'], - }, - environment: 'jsdom', - include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], - setupFiles: ['test-setup.js'], - }, -}); diff --git a/examples/react-todos-app/code-pushup.config.ts b/static-environments/cli-e2e-env/code-pushup.config.ts similarity index 100% rename from examples/react-todos-app/code-pushup.config.ts rename to static-environments/cli-e2e-env/code-pushup.config.ts diff --git a/examples/react-todos-app/dummy.plugin.ts b/static-environments/cli-e2e-env/dummy.plugin.ts similarity index 91% rename from examples/react-todos-app/dummy.plugin.ts rename to static-environments/cli-e2e-env/dummy.plugin.ts index 8c6affe54..52de817b5 100644 --- a/examples/react-todos-app/dummy.plugin.ts +++ b/static-environments/cli-e2e-env/dummy.plugin.ts @@ -1,5 +1,6 @@ import { readFile } from 'node:fs/promises'; import type { PluginConfig } from '@code-pushup/models'; +import {join} from "benchmark"; export const dummyPluginSlug = 'dummy-plugin'; @@ -31,7 +32,7 @@ export function create(): PluginConfig { description: 'A dummy plugin to test the cli.', runner: async () => { const itemCount = JSON.parse( - await readFile('items.json', 'utf-8'), + await readFile(join('src','items.json'), 'utf-8'), ).length; return [ { diff --git a/static-environments/cli-e2e-env/package.json b/static-environments/cli-e2e-env/package.json new file mode 100644 index 000000000..40e9d621b --- /dev/null +++ b/static-environments/cli-e2e-env/package.json @@ -0,0 +1,19 @@ +{ + "name": "cli-e2e-env", + "private": true, + "scripts": { + "collect": "npx @code-pushup/cli collect" + }, + "version": "1.0.0", + "main": "index.js", + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@code-pushup/cli": "^0.54.0", + "@code-pushup/core": "^0.54.0", + "@code-pushup/models": "^0.54.0", + "@code-pushup/utils": "^0.54.0" + }, + "description": "" +} diff --git a/examples/react-todos-app/project.json b/static-environments/cli-e2e-env/project.json similarity index 96% rename from examples/react-todos-app/project.json rename to static-environments/cli-e2e-env/project.json index 3c7bf0c4b..bcedafb59 100644 --- a/examples/react-todos-app/project.json +++ b/static-environments/cli-e2e-env/project.json @@ -1,7 +1,7 @@ { - "name": "react-todos-app", + "name": "cli-e2e-env", "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "examples/react-todos-app/src", + "sourceRoot": "static-environments/cli-e2e-env/src", "projectType": "application", "targets": { "build": { diff --git a/examples/react-todos-app/items.json b/static-environments/cli-e2e-env/src/items.json similarity index 100% rename from examples/react-todos-app/items.json rename to static-environments/cli-e2e-env/src/items.json From 9c2619d37c3003ffd53af059166a27294306b151 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 16:03:12 +0100 Subject: [PATCH 37/80] wip env --- static-environments/cli-e2e-env/dummy.plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static-environments/cli-e2e-env/dummy.plugin.ts b/static-environments/cli-e2e-env/dummy.plugin.ts index 52de817b5..d2e51c2b6 100644 --- a/static-environments/cli-e2e-env/dummy.plugin.ts +++ b/static-environments/cli-e2e-env/dummy.plugin.ts @@ -1,6 +1,6 @@ import { readFile } from 'node:fs/promises'; import type { PluginConfig } from '@code-pushup/models'; -import {join} from "benchmark"; +import {join} from "node:path"; export const dummyPluginSlug = 'dummy-plugin'; From 89de2ca3a2516e180b0b7d7a411de85ea36ce7d1 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 16:06:26 +0100 Subject: [PATCH 38/80] wip env --- e2e/cli-e2e/tests/compare.e2e.test.ts | 6 ++++-- e2e/cli-e2e/tests/print-config.e2e.test.ts | 4 ++-- static-environments/cli-e2e-env/code-pushup.config.js | 6 ++++++ static-environments/cli-e2e-env/code-pushup.config.mjs | 6 ++++++ 4 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 static-environments/cli-e2e-env/code-pushup.config.js create mode 100644 static-environments/cli-e2e-env/code-pushup.config.mjs diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index e8350589e..2e05bec02 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -7,15 +7,17 @@ import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; describe('CLI compare', () => { const envRoot = join('static-environments', 'cli-e2e-env'); + const srcDir = join(envRoot, '.code-pushup'); const git = simpleGit(); beforeEach(async () => { - await cleanTestFolder(join(envRoot, '.code-pushup')); + await cleanTestFolder(srcDir); await executeProcess({ command: 'npx', args: ['@code-pushup/cli', 'collect', '--persist.filename=source-report'], cwd: envRoot, }); + // adding items to create a report diff const itemsFile = join(envRoot, 'src', 'items.json'); const items = JSON.parse((await readFile(itemsFile)).toString()); @@ -30,7 +32,7 @@ describe('CLI compare', () => { afterEach(async () => { await git.checkout(['--', envRoot]); - await cleanTestFolder('tmp/e2e'); + await cleanTestFolder(srcDir); }); it('should compare report.json files and create report-diff.json and report-diff.md', async () => { diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index 3a6998396..89738d78d 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -3,11 +3,11 @@ import { expect } from 'vitest'; import { executeProcess } from '@code-pushup/utils'; const extensions = ['js', 'mjs', 'ts'] as const; +const envRoot = join('static-environments', 'cli-e2e-env'); export const configFilePath = (ext: (typeof extensions)[number]) => - join(process.cwd(), `examples/react-todos-app/code-pushup.config.${ext}`); + join(process.cwd(), envRoot, `code-pushup.config.${ext}`); describe('CLI print-config', () => { - const envRoot = join('static-environments', 'cli-e2e-env'); it.each(extensions)( 'should load .%s config file with correct arguments', async ext => { diff --git a/static-environments/cli-e2e-env/code-pushup.config.js b/static-environments/cli-e2e-env/code-pushup.config.js new file mode 100644 index 000000000..26928cba2 --- /dev/null +++ b/static-environments/cli-e2e-env/code-pushup.config.js @@ -0,0 +1,6 @@ +import dummyPlugin, { dummyCategory } from './dummy.plugin'; + +export default { + plugins: [dummyPlugin()], + categories: [dummyCategory], +}; diff --git a/static-environments/cli-e2e-env/code-pushup.config.mjs b/static-environments/cli-e2e-env/code-pushup.config.mjs new file mode 100644 index 000000000..26928cba2 --- /dev/null +++ b/static-environments/cli-e2e-env/code-pushup.config.mjs @@ -0,0 +1,6 @@ +import dummyPlugin, { dummyCategory } from './dummy.plugin'; + +export default { + plugins: [dummyPlugin()], + categories: [dummyCategory], +}; From 5f2fbb072853c86858468d21717da5e88142092e Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 16:08:37 +0100 Subject: [PATCH 39/80] wip env --- nx.json | 20 +- tools/src/npm/README.md | 147 ------------- tools/src/npm/bin/check-package-range.ts | 63 ------ tools/src/npm/constants.ts | 1 - tools/src/npm/npm.plugin.ts | 99 --------- tools/src/npm/types.ts | 6 - tools/src/npm/utils.ts | 77 ------- tools/src/publish/README.md | 139 ------------ tools/src/publish/bin/bump-package.ts | 52 ----- tools/src/publish/bin/publish-package.ts | 84 -------- tools/src/publish/constants.ts | 3 - tools/src/publish/publish.plugin.ts | 106 --------- tools/src/publish/types.ts | 15 -- tools/src/publish/utils.ts | 88 -------- tools/src/verdaccio/README.md | 104 --------- .../src/verdaccio/bin/create-verdaccio-env.ts | 21 -- tools/src/verdaccio/constants.ts | 7 - tools/src/verdaccio/env.ts | 172 --------------- tools/src/verdaccio/registry.ts | 201 ------------------ tools/src/verdaccio/start-local-registry.ts | 110 ---------- tools/src/verdaccio/stop-local-registry.ts | 18 -- tools/src/verdaccio/utils.ts | 66 ------ tools/src/verdaccio/verdaccio.plugin.ts | 101 --------- 23 files changed, 1 insertion(+), 1699 deletions(-) delete mode 100644 tools/src/npm/README.md delete mode 100644 tools/src/npm/bin/check-package-range.ts delete mode 100644 tools/src/npm/constants.ts delete mode 100644 tools/src/npm/npm.plugin.ts delete mode 100644 tools/src/npm/types.ts delete mode 100644 tools/src/npm/utils.ts delete mode 100644 tools/src/publish/README.md delete mode 100644 tools/src/publish/bin/bump-package.ts delete mode 100644 tools/src/publish/bin/publish-package.ts delete mode 100644 tools/src/publish/constants.ts delete mode 100644 tools/src/publish/publish.plugin.ts delete mode 100644 tools/src/publish/types.ts delete mode 100644 tools/src/publish/utils.ts delete mode 100644 tools/src/verdaccio/README.md delete mode 100644 tools/src/verdaccio/bin/create-verdaccio-env.ts delete mode 100644 tools/src/verdaccio/constants.ts delete mode 100644 tools/src/verdaccio/env.ts delete mode 100644 tools/src/verdaccio/registry.ts delete mode 100644 tools/src/verdaccio/start-local-registry.ts delete mode 100644 tools/src/verdaccio/stop-local-registry.ts delete mode 100644 tools/src/verdaccio/utils.ts delete mode 100644 tools/src/verdaccio/verdaccio.plugin.ts diff --git a/nx.json b/nx.json index c7603298b..51dcda372 100644 --- a/nx.json +++ b/nx.json @@ -110,24 +110,6 @@ } } }, - "./tools/src/debug/debug.plugin.ts", - { - "plugin": "./tools/src/npm/npm.plugin.ts", - "options": { - "verbose": true - } - }, - { - "plugin": "./tools/src/publish/publish.plugin.ts", - "options": { - "verbose": true - } - }, - { - "plugin": "./tools/src/verdaccio/verdaccio.plugin.ts", - "options": { - "verbose": true - } - } + "./tools/src/debug/debug.plugin.ts" ] } diff --git a/tools/src/npm/README.md b/tools/src/npm/README.md deleted file mode 100644 index c8cbd6adb..000000000 --- a/tools/src/npm/README.md +++ /dev/null @@ -1,147 +0,0 @@ -# TODO - -Reduce file interactions: -https://docs.npmjs.com/cli/v8/commands/npm-install#package-lock -`--no-package-lock` - -Reduce target install folder -https://docs.npmjs.com/cli/v8/commands/npm-install#global (explains the prefix flag) -`--prefix=${join('tmp',packageName,'node_modules')}` - -# NPM Nx Plugin - -A Nx plugin that adds targets that help to work with packages published to NPM. - -## Usage - -Register the plugin in your `nx.json` - -```jsonc -// nx.json -{ - //... - "plugins": ["tools/npm/npm.plugin.ts"], -} -``` - -### Options - -You can configure the plugin by providing options object in addition to the plugin path - -**Options:** - -| Name | Type | Default | Description | -| -------------------- | ---------------------- | --------------------------- | ----------------------------------------------- | -| `verbose` | `boolean` | `false` | Log additional information. | -| `tsconfig` | `string` | `tools/tsconfig.tools.json` | The tsconfig file to use. | -| `npmCheckScript` | `string` | `check-package-range.ts` | The script to execute when checking a package. | -| `publishableTargets` | `string` or `string[]` | `["publishable"]` | The targets that mark a project as publishable. | - -Example: - -```jsonc -// nx.json -{ - //... - "plugins": [ - { - "plugin": "tools/npm/npm.plugin.ts", - "options": { - "tsconfig": "tools/tsconfig.tools.json", - "npmCheckScript": "check-package-range.ts", - "publishableTargets": ["add-to-npm-registry"], - }, - }, - ], -} -``` - -### Nx tags - -> [!NOTE] -> A project can be marked as publishable using `tags` in `project.json`. -> Default tag name is `publishable`. - -#### `npm-check` - -Added dynamically to every project that is publishable (has a target named `publishable`). -Checks if a given package is registered in a given registry. - -It will automatically use `tools/tsconfig.tools.ts` to execute the script as well as derives the package name from the project name from `package/root/package.json`. -By default, it registers the latest version of the package from the default registry. - -Run: -`nx run :npm-check` - -**Options:** - -| Name | Type | Default | Description | -| ------------ | -------- | ---------------------------- | -------------------------------------------------- | -| `pkgVersion` | `string` | `latest` | The package version to check. | -| `registry` | `string` | `https://registry.npmjs.org` | The registry to check the package version against. | - -Examples: - -- `nx run :npm-check` -- `nx run :npm-check --registry=http://localhost:58999` -- `nx run :npm-check --registry=http://localhost:58999 --pkgVersion=1.0.0` - -#### `npm-install` - -Added dynamically to every project that is publishable (has a target named `publishable`). -Installs a given package version from a given registry. - -It will automatically derive the package name from the project name from `package/root/package.json`. -By default, it installs the latest version of the package from the default registry. - -Run: -`nx run :npm-install` - -**Options:** - -| Name | Type | Default | Description | -| ------------ | -------- | ---------------------------- | ----------------------------------------- | -| `pkgVersion` | `string` | `latest` | The package version to install. | -| `registry` | `string` | `https://registry.npmjs.org` | The registry to install the package from. | - -Examples: - -- `nx run :npm-install` -- `nx run :npm-install --pkgVersion=1.0.0` -- `nx run :npm-install --pkgVersion=1.0.0 --registry=http://localhost:58999` - -#### `npm-uninstall` - -Added dynamically to every project that is publishable (has a target named `publishable`). -Uninstalls a given package. - -By default, it uninstalls the latest version of the package from the package.json in your CWD. - -Run: -`nx run :npm-uninstall` - -Examples: - -- `nx run :npm-uninstall` - -## Scripts - -### `check-package-range.ts` - -Checks if a given package is registered in a given registry. - -Run: -`tsx --tsconfig=tools/tsconfig.tools.json tools/npm/check-package-range.ts` - -**Options:** - -| Name | Type | Default | Description | -| ------------ | -------- | ---------------------------- | -------------------------------------------------- | -| `pkgVersion` | `string` | `latest` | The package version to check. | -| `registry` | `string` | `https://registry.npmjs.org` | The registry to check the package version against. | - -Examples: - -- `tsx --tsconfig=tools/tsconfig.tools.json tools/npm/check-package-range.ts` -- `tsx --tsconfig=tools/tsconfig.tools.json tools/npm/check-package-range.ts --registry=http://localhost:58999` -- `tsx --tsconfig=tools/tsconfig.tools.json tools/npm/check-package-range.ts --registry=http://localhost:58999 --pkgVersion=1.0.0` diff --git a/tools/src/npm/bin/check-package-range.ts b/tools/src/npm/bin/check-package-range.ts deleted file mode 100644 index 89c586b18..000000000 --- a/tools/src/npm/bin/check-package-range.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { execFileSync, execSync } from 'node:child_process'; -import yargs from 'yargs'; -import { hideBin } from 'yargs/helpers'; -import { objectToCliArgs } from '../../../../packages/utils/src'; -import type { NpmCheckOptions, NpmCheckResult } from '../types'; - -const argv = yargs(hideBin(process.argv)) - .options({ - pkgRange: { type: 'string', demandOption: true }, - registry: { type: 'string' }, - }) - .coerce('pkgRange', rawVersion => { - if (rawVersion != null && rawVersion !== '') { - return rawVersion; - } else { - return undefined; - } - }) - .coerce('registry', rawRegistry => { - if (rawRegistry != null && rawRegistry !== '') { - return rawRegistry; - } else { - return undefined; - } - }).argv; - -const { pkgRange, registry = 'https://registry.npmjs.org/' } = - argv as NpmCheckOptions; - -try { - const command = 'npm'; - const args = objectToCliArgs({ - _: ['view', pkgRange], - registry, - }); - - const viewResult = execFileSync( - command, - [ - ...args, - // Hide process output via "2>/dev/null". Otherwise, it will print the error message to the terminal. - '2>/dev/null', - ], - { - shell: true, - }, - ).toString(); - - const existingPackage = viewResult - .split('\n') - .filter(Boolean) - .at(0) - ?.split(' ') - .at(0); - console.log(`${existingPackage}#FOUND` satisfies NpmCheckResult); // process output to parse - process.exit(0); -} catch (error) { - // @TODO we use '2>/dev/null' to hide errors from process output, but also can't check error message. Find better solution. - // if (error.message.includes(`npm ERR! 404 '${pkgRange}' is not in this registry`)) { - console.log(`${pkgRange}#NOT_FOUND` satisfies NpmCheckResult); // process output to parse - process.exit(0); - // } -} diff --git a/tools/src/npm/constants.ts b/tools/src/npm/constants.ts deleted file mode 100644 index f7ae15e81..000000000 --- a/tools/src/npm/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const NPM_CHECK_SCRIPT = 'tools/src/npm/bin/check-package-range.ts'; diff --git a/tools/src/npm/npm.plugin.ts b/tools/src/npm/npm.plugin.ts deleted file mode 100644 index f0dd78633..000000000 --- a/tools/src/npm/npm.plugin.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { - type CreateNodes, - type CreateNodesContext, - readJsonFile, -} from '@nx/devkit'; -import { dirname, join } from 'node:path'; -import type { ProjectConfiguration } from 'nx/src/config/workspace-json-project-json'; -import { NPM_CHECK_SCRIPT } from './constants'; - -type CreateNodesOptions = { - tsconfig?: string; - npmCheckScript?: string; - verbose?: boolean; - publishableTags?: string; -}; - -export const createNodes: CreateNodes = [ - '**/project.json', - ( - projectConfigurationFile: string, - opts: undefined | unknown, - context: CreateNodesContext, - ) => { - const root = dirname(projectConfigurationFile); - const projectConfiguration: ProjectConfiguration = readJsonFile( - join(process.cwd(), projectConfigurationFile), - ); - const { - publishableTags = 'publishable', - tsconfig = 'tools/tsconfig.tools.json', - npmCheckScript = NPM_CHECK_SCRIPT, - verbose = false, - } = (opts ?? {}) as CreateNodesOptions; - - const isPublishable = (projectConfiguration?.tags ?? []).some(target => - publishableTags.includes(target), - ); - if (!isPublishable) { - return {}; - } - - return { - projects: { - [root]: { - targets: npmTargets({ root, tsconfig, npmCheckScript, verbose }), - }, - }, - }; - }, -]; - -function npmTargets({ - root, - tsconfig, - npmCheckScript, - verbose, -}: Required> & { - root: string; -}) { - const { name: packageName } = readJsonFile(join(root, 'package.json')); - return { - 'npm-check': { - command: `tsx --tsconfig={args.tsconfig} {args.script} --pkgRange=${packageName}@{args.pkgVersion} --registry={args.registry} --verbose=${verbose}`, - options: { - script: npmCheckScript, - tsconfig, - }, - }, - 'npm-install': { - dependsOn: [ - { project: 'dependencies', targets: 'npm-install', params: 'forward' }, - ], - command: `npm install -D ${packageName} --prefix={args.prefix} --userconfig={args.userconfig}`, - }, - 'npm-uninstall': { - command: `npm uninstall ${packageName} --prefix={args.prefix} --userconfig={args.userconfig}`, - }, - 'npm-install-e2e': { - dependsOn: [ - { - target: 'publish-e2e', - projects: 'self', - params: 'forward', - }, - { - target: 'npm-install-e2e', - projects: 'dependencies', - params: 'forward', - }, - { - target: 'publish-e2e', - projects: 'dependencies', - params: 'forward', - }, - ], - command: `npm install -D --no-fund ${packageName}@{args.pkgVersion} --prefix={args.prefix} --userconfig={args.userconfig}`, - }, - }; -} diff --git a/tools/src/npm/types.ts b/tools/src/npm/types.ts deleted file mode 100644 index 051162f18..000000000 --- a/tools/src/npm/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type NpmCheckToken = 'FOUND' | `NOT_FOUND`; -export type NpmCheckResult = `${string}#${NpmCheckToken}`; -export type NpmCheckOptions = { - pkgRange: string; - registry: string; -}; diff --git a/tools/src/npm/utils.ts b/tools/src/npm/utils.ts deleted file mode 100644 index 593a655ec..000000000 --- a/tools/src/npm/utils.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { execFileSync } from 'node:child_process'; -import { objectToCliArgs } from '../../../packages/utils/src'; - -export type NpmInstallOptions = { - directory?: string; - prefix?: string; - registry?: string; - userconfig?: string; - tag?: string; - pkgVersion?: string; - parallel?: number; -}; - -export function nxRunManyNpmInstall({ - registry, - prefix, - userconfig, - tag = 'e2e', - pkgVersion, - directory, - parallel, -}: NpmInstallOptions) { - console.info( - `Installing packages in ${directory} from registry: ${registry}.`, - ); - try { - execFileSync( - 'nx', - [ - ...objectToCliArgs({ - _: ['run-many'], - targets: 'npm-install', - ...(parallel ? { parallel } : {}), - ...(pkgVersion ? { pkgVersion } : {}), - ...(tag ? { tag } : {}), - ...(registry ? { registry } : {}), - ...(userconfig ? { userconfig } : {}), - ...(prefix ? { prefix } : {}), - }), - ], - { - env: process.env, - stdio: 'inherit', - shell: true, - cwd: directory ?? process.cwd(), - }, - ); - } catch (error) { - console.error('Error installing packages:\n' + error.message); - throw error; - } -} - -export function nxRunManyNpmUninstall({ - parallel, - ...opt -}: { - prefix?: string; - userconfig?: string; - parallel?: number; -}) { - console.info('Uninstalling all NPM packages.'); - try { - execFileSync( - 'npx', - objectToCliArgs({ - _: ['nx', 'run-many'], - targets: 'npm-uninstall', - parallel, - ...opt, - }), - { env: process.env, stdio: 'inherit', shell: true }, - ); - } catch (error) { - console.error('Uninstalling all NPM packages failed.'); - } -} diff --git a/tools/src/publish/README.md b/tools/src/publish/README.md deleted file mode 100644 index 38f9c4ded..000000000 --- a/tools/src/publish/README.md +++ /dev/null @@ -1,139 +0,0 @@ -# TODO - -- refactor version bumping -- reconsider latest version detection logic -- use executeProcess instead of execSync -- refactor targets to use objToCliArgs - -# Publish Nx Plugin - -A Nx plugin that adds targets that help to publish packages to NPM. - -## Usage - -Register the plugin in your `nx.json` - -```jsonc -// nx.json -{ - "name": "my-project", - "plugins": ["tools/publish/publish.plugin.ts"], -} -``` - -### Options - -You can configure the plugin by providing options object in addition to the plugin path - -**Options:** - -| Name | Type | Default | Description | -| -------------------- | ---------------------- | --------------------------- | ----------------------------------------------- | -| `verbose` | `boolean` | `false` | Log additional information. | -| `tsconfig` | `string` | `tools/tsconfig.tools.json` | The tsconfig file to use. | -| `publishScript` | `string` | `publish-package.ts` | The script to execute when publishing. | -| `publishableTargets` | `string` or `string[]` | `["publishable"]` | The targets that mark a project as publishable. | - -Example: - -```jsonc -// nx.json -{ - "name": "my-project", - "plugins": [ - { - "plugin": "tools/publish/publish.plugin.ts", - "options": { - "tsconfig": "tools/tsconfig.tools.json", - "publishScript": "publish-package.ts", - "publishableTargets": ["add-to-npm-registry"], - }, - }, - ], -} -``` - -### Targets - -> [!NOTE] -> A project can be marked as publishable by adding an empty target named `publishable`. - -#### `publish` - -Added dynamically to every project that is publishable (has a target named `publishable`). -Publishes a package to a given registry. - -It will automatically use `tools/tsconfig.tools.ts` to execute the script as well as derives the package name from the project name from `package/root/package.json`. -By default, it registers the latest version of the package from the default registry. - -Run: -`nx run :publish` - -**Options:** - -| Name | Type | Default | Description | -| ------------ | -------- | ---------------------------- | --------------------------------------- | -| `pkgVersion` | `string` | `latest` | The package version to publish. | -| `registry` | `string` | `https://registry.npmjs.org` | The registry to publish the package to. | - -Examples: - -- `nx run :publish` -- `nx run :publish --registry=http://localhost:58999` -- `nx run :publish --registry=http://localhost:58999 --pkgVersion=1.0.0` - -## Scripts - -### `publish-package.ts` - -The script that is executed when running the `publish` target. - -Options: - -| Name | Type | Default | Description | -| ------------- | --------- | -------- | -------------------------------------------------------------------- | -| `nextVersion` | `string` | `latest` | The version to publish. | -| `tag` | `string` | `latest` | The tag to publish. | -| `registry` | `string` | | The registry to publish the package to. | -| `directory` | `string` | | The directory to publish. (location of the build artefact e.g. dist) | -| `verbose` | `boolean` | `false` | Log additional information. | - -Examples: - -- `tsx tools/src/publish/bin/publish-package.ts` -- `tsx tools/src/publish/bin/publish-package.ts --directory=dist/packages/` -- `tsx tools/src/publish/bin/publish-package.ts --directory=dist/packages/ --registry=http://localhost:58999 --nextVersion=1.0.0` - -### `bump-package.ts` - -This script is used to bump the version of the package. It will automatically update the version in the `package.json` file. - -Options: - -| Name | Type | Default | Description | -| ------------- | --------- | --------------- | -------------------------------------------------------------------- | -| `directory` | `string` | `process.cwd()` | The directory to publish. (location of the build artefact e.g. dist) | -| `nextVersion` | `string` | | The version to publish. | -| `verbose` | `boolean` | `false` | Log additional information. | - -Examples: - -- `tsx tools/src/publish/bin/bump-package.ts --nextVersion=` -- `tsx tools/src/publish/bin/bump-package.ts --directory=dist/packages/ --nextVersion=` - -### `login-check.ts` - -This script is used to check if the user is logged in to the NPM registry. - -Options: - -| Name | Type | Default | Description | -| ---------- | --------- | ---------------------------- | --------------------------- | -| `registry` | `string` | `https://registry.npmjs.org` | The registry to check. | -| `verbose` | `boolean` | `false` | Log additional information. | - -Examples: - -- `tsx tools/src/publish/bin/login-check.ts` -- `tsx tools/src/publish/bin/login-check.ts --registry=http://localhost:58999` -- `tsx tools/src/publish/bin/login-check.ts --registry=http://localhost:58999 --verbose` diff --git a/tools/src/publish/bin/bump-package.ts b/tools/src/publish/bin/bump-package.ts deleted file mode 100644 index efd610e06..000000000 --- a/tools/src/publish/bin/bump-package.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { readFileSync, writeFileSync } from 'node:fs'; -import { join } from 'node:path'; -import yargs from 'yargs'; -import { hideBin } from 'yargs/helpers'; -import { parseVersion } from '../../utils'; -import type { BumpOptions } from '../types'; - -const argv = yargs(hideBin(process.argv)) - .options({ - nextVersion: { - type: 'string', - }, - verbose: { type: 'boolean' }, - }) - .coerce('nextVersion', parseVersion).argv; - -const { - nextVersion: version, - verbose, - directory = process.cwd(), -} = argv as BumpOptions; -// Updating the version in "package.json" -const packageJsonFile = join(directory, 'package.json'); -try { - const packageJson = JSON.parse(readFileSync(packageJsonFile).toString()); - if (version != null) { - if (packageJson.version === version) { - console.info(`Package version is already set to ${version}.`); - } - - console.info( - `Updating ${packageJsonFile} version from ${packageJson.version} to ${version}`, - ); - writeFileSync( - packageJsonFile, - JSON.stringify( - { ...packageJson, version, description: 'E2E test' }, - null, - 2, - ), - ); - process.exit(0); - } - // @TODO: Implement autodetect version bump - console.info( - 'Autodetecting version bump not yet implemented, exiting with error', - ); - process.exit(1); -} catch (e) { - console.info(`Error updating version in ${packageJsonFile} file.`); - process.exit(1); -} diff --git a/tools/src/publish/bin/publish-package.ts b/tools/src/publish/bin/publish-package.ts deleted file mode 100644 index eca0e7d57..000000000 --- a/tools/src/publish/bin/publish-package.ts +++ /dev/null @@ -1,84 +0,0 @@ -/** - * This is a minimal script to publish your package to "npm". - * This is meant to be used as-is or customize as you see fit. - * - * This script is executed on "dist/path/to/library" as "cwd" by default. - * - * You might need to authenticate with NPM before running this script. - */ -import { execSync } from 'node:child_process'; -import { readFileSync } from 'node:fs'; -import { join, relative } from 'node:path'; -import { DEFAULT_REGISTRY } from 'verdaccio/build/lib/constants'; -import yargs from 'yargs'; -import { hideBin } from 'yargs/helpers'; -import { objectToCliArgs } from '../../../../packages/utils/src'; -import { parseVersion } from '../../utils'; -import type { PublishOptions } from '../types'; -import { findLatestVersion, nxBumpVersion } from '../utils'; - -const argv = yargs(hideBin(process.argv)) - .options({ - directory: { type: 'string' }, - projectName: { type: 'string' }, - nextVersion: { type: 'string' }, - tag: { type: 'string', default: 'next' }, - registry: { type: 'string' }, - userconfig: { type: 'string' }, - verbose: { type: 'boolean' }, - }) - .coerce('nextVersion', parseVersion).argv; -const { - directory = process.cwd(), - projectName, - nextVersion, - tag, - registry = DEFAULT_REGISTRY, - userconfig, - verbose, -} = argv as PublishOptions; -const version = nextVersion ?? findLatestVersion(); - -// Updating the version in "package.json" before publishing -nxBumpVersion({ nextVersion: version, directory, projectName }); - -try { - execSync( - objectToCliArgs({ - _: ['npm', 'publish'], - access: 'public', - ...(tag ? { tag } : {}), - ...(registry ? { registry } : {}), - ...(userconfig - ? { - userconfig: relative( - join(process.cwd(), directory ?? ''), - join(process.cwd(), userconfig), - ), - } - : {}), - }).join(' '), - { - cwd: directory, - }, - ); -} catch (error) { - if ( - (error as Error).message.includes( - `need auth This command requires you to be logged in to ${registry}`, - ) - ) { - console.info( - `Authentication error! Check if your registry is set up correctly. If you publish to a public registry run login before.`, - ); - process.exit(1); - } else if ( - error instanceof Error && - error.message.includes(`Cannot publish over existing version`) - ) { - console.info(`Version ${version} already published to ${registry}.`); - process.exit(0); - } - throw error; -} -process.exit(0); diff --git a/tools/src/publish/constants.ts b/tools/src/publish/constants.ts deleted file mode 100644 index ed15a9451..000000000 --- a/tools/src/publish/constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const PUBLISH_SCRIPT = 'tools/src/publish/bin/publish-package.ts'; -export const BUMP_SCRIPT = 'tools/src/publish/bin/bump-package.ts'; -export const LOGIN_CHECK_SCRIPT = 'tools/src/publish/bin/login-check.ts'; diff --git a/tools/src/publish/publish.plugin.ts b/tools/src/publish/publish.plugin.ts deleted file mode 100644 index 3a20450f9..000000000 --- a/tools/src/publish/publish.plugin.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { - type CreateNodes, - type CreateNodesContext, - readJsonFile, -} from '@nx/devkit'; -import { dirname } from 'node:path'; -import type { ProjectConfiguration } from 'nx/src/config/workspace-json-project-json'; -import { BUMP_SCRIPT, PUBLISH_SCRIPT } from './constants'; - -type CreateNodesOptions = { - tsconfig?: string; - publishableTags?: string | string[]; - publishScript?: string; - bumpScript?: string; - directory?: string; - verbose?: boolean; -}; -export const createNodes: CreateNodes = [ - '**/project.json', - ( - projectConfigurationFile: string, - opts: undefined | unknown, - context: CreateNodesContext, - ) => { - const root = dirname(projectConfigurationFile); - const projectConfiguration: ProjectConfiguration = readJsonFile( - projectConfigurationFile, - ); - - const { - publishableTags = ['publishable'], - tsconfig = 'tools/tsconfig.tools.json', - publishScript = PUBLISH_SCRIPT, - bumpScript = BUMP_SCRIPT, - directory = projectConfiguration?.targets?.build?.options?.outputPath ?? - process.cwd(), - verbose = false, - } = (opts ?? {}) as CreateNodesOptions; - const isPublishable = (projectConfiguration?.tags ?? []).some(target => - publishableTags.includes(target), - ); - if (!isPublishable) { - return {}; - } - - const { name: projectName } = projectConfiguration; - return { - projects: { - [root]: { - targets: publishTargets({ - tsconfig, - publishScript, - bumpScript, - directory, - projectName, - verbose, - }), - }, - }, - }; - }, -]; - -function publishTargets({ - tsconfig, - publishScript, - bumpScript, - directory, - projectName, - verbose, -}: Required> & { - projectName: string; -}) { - return { - publish: { - command: `tsx --tsconfig={args.tsconfig} {args.script} --projectName=${projectName} --directory=${directory} --registry={args.registry} --userconfig={args.userconfig} --nextVersion={args.nextVersion} --tag={args.tag} --verbose=${verbose}`, - options: { - script: publishScript, - tsconfig, - }, - }, - 'publish-e2e': { - dependsOn: [ - 'build', - { - target: 'publish-e2e', - projects: 'dependencies', - params: 'forward', - }, - ], - command: `tsx --tsconfig={args.tsconfig} {args.script} --projectName=${projectName} --directory=${directory} --registry={args.registry} --userconfig={args.userconfig} --nextVersion={args.nextVersion} --tag={args.tag} --verbose=${verbose}`, - options: { - script: publishScript, - tsconfig, - }, - }, - 'bump-version': { - dependsOn: ['build'], - command: `tsx --tsconfig={args.tsconfig} {args.script} --directory=${directory} --nextVersion={args.nextVersion} --verbose=${verbose}`, - options: { - script: bumpScript, - tsconfig, - }, - }, - }; -} diff --git a/tools/src/publish/types.ts b/tools/src/publish/types.ts deleted file mode 100644 index c1c9d9426..000000000 --- a/tools/src/publish/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -export type PublishOptions = { - projectName?: string; - directory?: string; - userconfig?: string; - registry?: string; - tag?: string; - nextVersion: string; - verbose?: boolean; - parallel?: number; -}; -export type BumpOptions = { - nextVersion: string; - verbose?: boolean; - directory?: string; -}; diff --git a/tools/src/publish/utils.ts b/tools/src/publish/utils.ts deleted file mode 100644 index c2a84f08f..000000000 --- a/tools/src/publish/utils.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { execFileSync, execSync } from 'node:child_process'; -import { join } from 'node:path'; -import { objectToCliArgs } from '../../../packages/utils/src'; -import { BUMP_SCRIPT } from './constants'; -import type { PublishOptions } from './types'; - -export function nxRunManyPublish({ - registry, - tag = 'e2e', - nextVersion, - userconfig, - parallel, -}: PublishOptions) { - console.info(`Publish packages to registry: ${registry}.`); - try { - execFileSync( - 'npx', - [ - 'nx', - 'run-many', - '--targets=publish', - ...(parallel ? [`--parallel=${parallel}`] : []), - '--', - ...(nextVersion ? [`--nextVersion=${nextVersion}`] : []), - ...(tag ? [`--tag=${tag}`] : []), - ...(registry ? [`--registry=${registry}`] : []), - ...(userconfig ? [`--userconfig=${userconfig}`] : []), - ], - { env: process.env, stdio: 'inherit', shell: true }, - ); - } catch (error) { - console.error('Error publishing packages:\n' + error.message); - throw error; - } -} - -export function findLatestVersion(): string { - const version = execSync('git describe --tags --abbrev=0') - .toString() - .trim() - .replace(/^v/, ''); - console.info(`Version from "git describe --tags --abbrev=0": ${version}`); - return version; -} - -export function bumpVersion({ - nextVersion, - cwd, -}: { - nextVersion: string; - cwd: string; -}) { - try { - return execSync( - `tsx ${join(process.cwd(), BUMP_SCRIPT)} ${objectToCliArgs({ - nextVersion, - }).join(' ')}`, - { cwd }, - ).toString(); - } catch (error) { - console.error('Error bumping package version.'); - throw error; - } -} - -export function nxBumpVersion({ - projectName, - nextVersion, - directory, -}: { - projectName: string; - nextVersion: string; - directory: string; -}) { - try { - execSync( - `nx bump-version ${objectToCliArgs({ - _: projectName, - nextVersion, - directory, - }).join(' ')}`, - {}, - ).toString(); - } catch (error) { - console.error('Error Nx bump-version target failed.'); - throw error; - } -} diff --git a/tools/src/verdaccio/README.md b/tools/src/verdaccio/README.md deleted file mode 100644 index 2c73d9c7b..000000000 --- a/tools/src/verdaccio/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# TODO - -- in the future the root project has no verdaccio target anymore. only e2e projects have a verdaccio target. -- Use `.npmrc` form e2e folder -- move uniquePort into project targets of e2e projects - -https://verdaccio.org/docs/setup-npm#specific - -- Add post target - -```jsonc -'post-registry': { - dependsOn: [ - ...targets.map(target => ({ - projects: 'self', - target, - })), - ], - command: `echo POST E2E - stop verdaccio on port ${port}`, - }, -``` - -- Move verdaccio targets into every project that has a e2e target - -```typescript - - const hasPreVerdaccioTargets = someTargetsPresent(projectConfiguration?.targets ?? {}, preTargets); - if (!hasPreVerdaccioTargets) { - return {}; - } - -``` - -# Verdaccio Nx Plugin - -A Nx plugin that adds targets that help to test packages published to a package registry like NPM. -It uses Verdaccio to start a local registry and test the package against it. -This helps to catch tricky bugs before publishing the package to the public registry. - -## Usage - -Register the plugin in your `nx.json` - -```jsonc -// nx.json -{ - "name": "my-project", - "plugins": ["tools/verdaccio/verdaccio.plugin.ts"], -} -``` - -### Options - -You can configure the plugin by providing a options object in addition to the plugin path - -| Name | Type | Default | Description | -| ---------- | --------- | ------------------------------- | ------------------------------------------ | -| `verbose` | `boolean` | `false` | Log additional information. | -| `tsconfig` | `string` | `tools/tsconfig.tools.json` | The tsconfig file to use. | -| `port` | `number` | `4873` | The port to start the Verdaccio server on. | -| `config` | `string` | `tools/verdaccio/verdaccio.yml` | The Verdaccio configuration file. | -| `storage` | `string` | `tools/verdaccio/storage` | The storage directory for Verdaccio. | - -Example: - -```jsonc -// nx.json -{ - //... - "plugins": [ - { - "plugin": "tools/verdaccio/verdaccio.plugin.ts", - "options": { - "tsconfig": "tools/tsconfig.tools.json", - "verbose": true, - }, - }, - ], -} -``` - -### Targets - -> [!NOTE] -> By default target are only added to projects with a `e2e` target configured. - -#### `start-verdaccio` - -Starts a Verdaccio server. - -It will automatically use `tools/tsconfig.tools.ts` to execute the script as well as derives the package name from the project name from `package/root/package.json`. -By default, it registers the latest version of the package from the default registry. - -Run: -`nx run :start-verdaccio` - -**Options:** - -| Name | Type | Default | Description | -| ---------- | -------- | ------------------------------- | -------------------------------------------------- | -| `registry` | `string` | `https://registry.npmjs.org` | The registry to check the package version against. | -| `config` | `string` | `tools/verdaccio/verdaccio.yml` | The Verdaccio configuration file. | -| `port` | `number` | generated uniquePort | The port to start the Verdaccio server on. | -| `storage` | `string` | `tmp/e2e/storage ` | The storage directory for Verdaccio. | diff --git a/tools/src/verdaccio/bin/create-verdaccio-env.ts b/tools/src/verdaccio/bin/create-verdaccio-env.ts deleted file mode 100644 index 130f1535f..000000000 --- a/tools/src/verdaccio/bin/create-verdaccio-env.ts +++ /dev/null @@ -1,21 +0,0 @@ -import yargs, { Options } from 'yargs'; -import { hideBin } from 'yargs/helpers'; -import { - type StartVerdaccioAndSetupEnvOptions, - nxStartVerdaccioAndSetupEnv, -} from '../env'; - -const argv = yargs(hideBin(process.argv)) - .version(false) - .options({ - verbose: { type: 'boolean' }, - projectName: { type: 'string', demandOption: true }, - port: { type: 'string' }, - } satisfies Partial< - Record - >).argv; - -(async () => { - await nxStartVerdaccioAndSetupEnv(argv as StartVerdaccioAndSetupEnvOptions); - process.exit(0); -})(); diff --git a/tools/src/verdaccio/constants.ts b/tools/src/verdaccio/constants.ts deleted file mode 100644 index f1d75171f..000000000 --- a/tools/src/verdaccio/constants.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { join } from 'node:path'; - -export const START_VERDACCIO_SERVER_TARGET_NAME = 'start-verdaccio-server'; -export const START_VERDACCIO_ENV_TARGET_NAME = 'start-verdaccio-env'; -export const STOP_VERDACCIO_TARGET_NAME = 'stop-verdaccio'; -export const DEFAULT_VERDACCIO_STORAGE = join('tmp', 'verdaccio', 'storage'); -export const DEFAULT_VERDACCIO_CONFIG = join('.verdaccio', 'config.yml'); diff --git a/tools/src/verdaccio/env.ts b/tools/src/verdaccio/env.ts deleted file mode 100644 index e164064cc..000000000 --- a/tools/src/verdaccio/env.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { bold, gray, red } from 'ansis'; -// eslint-disable-next-line n/no-sync -import { execFileSync, execSync } from 'node:child_process'; -import { join } from 'node:path'; -// can't import from utils -import { objectToCliArgs } from '../../../packages/nx-plugin/src/executors/internal/cli'; -import { - setupTestFolder, - teardownTestFolder, -} from '../../../testing/test-setup/src'; -import { ensureDirectoryExists } from '../../../testing/test-utils/src'; -import { - NxStarVerdaccioOptions, - Registry, - nxStartVerdaccioServer, -} from './registry'; - -export function projectE2eScope(projectName: string): string { - return join('tmp', 'e2e', projectName); -} - -export type VerdaccioEnv = { - workspaceRoot: string; - userconfig?: string; -}; - -export function configureRegistry( - { - url, - urlNoProtocol, - userconfig, - }: Registry & Pick, - verbose?: boolean, -) { - /** - * Protocol-Agnostic Configuration: The use of // allows NPM to configure authentication for a registry without tying it to a specific protocol (http: or https:). - * This is particularly useful when the registry might be accessible via both HTTP and HTTPS. - * - * Example: //registry.npmjs.org/:_authToken=your-token - */ - const token = 'secretVerdaccioToken'; - const setAuthToken = `npm config set ${urlNoProtocol}/:_authToken "${token}" ${objectToCliArgs( - { userconfig }, - ).join(' ')}`; - if (verbose) { - console.info( - `${gray('>')} ${gray(bold('Verdaccio-Env'))} Execute: ${setAuthToken}`, - ); - } - execSync(setAuthToken); - - const setRegistry = `npm config set registry="${url}" ${objectToCliArgs({ - userconfig, - }).join(' ')}`; - if (verbose) { - console.info( - `${gray('>')} ${gray(bold('Verdaccio-Env'))} Execute: ${userconfig}`, - ); - } - execSync(setRegistry); -} - -export function unconfigureRegistry( - { urlNoProtocol }: Pick, - verbose?: boolean, -) { - execSync(`npm config delete registry`); - execSync(`npm config delete ${urlNoProtocol}/:_authToken`); - if (verbose) { - console.info(`${gray('>')} ${gray(bold('Verdaccio-Env'))} delete registry`); - console.info( - `${gray('>')} ${gray( - bold('Verdaccio-Env'), - )} delete npm authToken: ${urlNoProtocol}`, - ); - } -} - -export async function setupNpmWorkspace(directory: string, verbose?: boolean) { - if (verbose) { - console.info( - `${gray('>')} ${gray( - bold('Verdaccio-Env'), - )} Execute: npm init in directory ${directory}`, - ); - } - const cwd = process.cwd(); - await ensureDirectoryExists(directory); - process.chdir(join(cwd, directory)); - try { - execFileSync('npm', ['init', '--force']).toString(); - } catch (error) { - console.error( - `${red('>')} ${red( - bold('Verdaccio-Env'), - )} Error creating NPM workspace: ${(error as Error).message}`, - ); - } finally { - process.chdir(cwd); - } -} - -export type StartVerdaccioAndSetupEnvOptions = Partial< - NxStarVerdaccioOptions & VerdaccioEnv -> & - Pick; - -export type VerdaccioEnvResult = VerdaccioEnv & { - registry: Registry; - stop: () => void; -}; - -export async function nxStartVerdaccioAndSetupEnv({ - projectName, - port, - verbose = false, - workspaceRoot = projectE2eScope(projectName), - location = 'none', - // reset or remove cached packages and/or metadata. - clear = true, -}: StartVerdaccioAndSetupEnvOptions): Promise { - // set up NPM workspace environment - const storage = join(workspaceRoot, 'storage'); - - // @TODO potentially done by verdaccio task when clearing storage - await setupTestFolder(storage); - const registryResult = await nxStartVerdaccioServer({ - projectName, - storage, - port, - location, - clear, - verbose, - }); - - await setupNpmWorkspace(workspaceRoot, verbose); - - const userconfig = join(workspaceRoot, '.npmrc'); - configureRegistry({ ...registryResult.registry, userconfig }, verbose); - - return { - ...registryResult, - stop: () => { - registryResult.stop(); - unconfigureRegistry(registryResult.registry, verbose); - }, - workspaceRoot, - userconfig, - } satisfies VerdaccioEnvResult; -} - -export async function nxStopVerdaccioAndTeardownEnv( - result: VerdaccioEnvResult, -) { - if (result) { - const { stop, registry, workspaceRoot } = result; - if (stop == null) { - throw new Error( - 'global e2e teardown script was not able to derive the stop script for the active registry from "activeRegistry"', - ); - } - console.info(`Un configure registry: ${registry.url}`); - if (typeof stop === 'function') { - stop(); - } else { - console.error('Stop is not a function. Type:', typeof stop); - } - await teardownTestFolder(workspaceRoot); - } else { - throw new Error(`Failed to stop registry.`); - } -} diff --git a/tools/src/verdaccio/registry.ts b/tools/src/verdaccio/registry.ts deleted file mode 100644 index 3afe3788f..000000000 --- a/tools/src/verdaccio/registry.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { bold, gray, red } from 'ansis'; -import { executeProcess } from '@code-pushup/utils'; -// can't import from utils -import { objectToCliArgs } from '../../../packages/nx-plugin'; -import { teardownTestFolder } from '../../../testing/test-setup/src'; -import { killProcesses, listProcess } from '../debug/utils'; -import { START_VERDACCIO_SERVER_TARGET_NAME } from './constants'; - -export function uniquePort(): number { - return Number((6000 + Number(Math.random() * 1000)).toFixed(0)); -} - -export type RegistryServer = { - protocol: string; - port: string | number; - host: string; - urlNoProtocol: string; - url: string; -}; -export type Registry = RegistryServer & - Required>; - -export type RegistryResult = { - registry: Registry; - stop: () => void; -}; - -export function parseRegistryData(stdout: string): RegistryServer { - const output = stdout.toString(); - - // Extract protocol, host, and port - const match = output.match( - /(?https?):\/\/(?[^:]+):(?\d+)/, - ); - - if (!match?.groups) { - throw new Error('Could not parse registry data from stdout'); - } - - const protocol = match.groups['proto']; - if (!protocol || !['http', 'https'].includes(protocol)) { - throw new Error( - `Invalid protocol ${protocol}. Only http and https are allowed.`, - ); - } - const host = match.groups['host']; - if (!host) { - throw new Error(`Invalid host ${String(host)}.`); - } - const port = !Number.isNaN(Number(match.groups['port'])) - ? Number(match.groups['port']) - : undefined; - if (!port) { - throw new Error(`Invalid port ${String(port)}.`); - } - return { - protocol, - host, - port, - urlNoProtocol: `//${host}:${port}`, - url: `${protocol}://${host}:${port}`, - }; -} - -export type NxStarVerdaccioOnlyOptions = { - projectName?: string; - verbose?: boolean; -}; - -export type VerdaccioExecuterOptions = { - storage?: string; - port?: string; - p?: string; - config?: string; - c?: string; - location: string; - // reset or remove cached packages and/or metadata. - clear: boolean; -}; - -export type NxStarVerdaccioOptions = VerdaccioExecuterOptions & - NxStarVerdaccioOnlyOptions; - -export async function nxStartVerdaccioServer({ - projectName = '', - storage, - port, - location, - clear, - verbose = false, -}: NxStarVerdaccioOptions): Promise { - let startDetected = false; - - const positionalArgs = [ - 'exec', - 'nx', - START_VERDACCIO_SERVER_TARGET_NAME, - projectName ?? '', - '--', - ]; - const args = objectToCliArgs< - Partial< - VerdaccioExecuterOptions & { _: string[]; verbose: boolean; cwd: string } - > - >({ - _: positionalArgs, - storage, - port, - verbose, - location, - clear, - }); - - // a link to the process started by this command, not one of the child processes. (every port is spawned by a command) - const commandId = positionalArgs.join(' '); - - if (verbose) { - console.info( - `${gray('>')} ${gray( - bold('Verdaccio'), - )} Start server with command: ${commandId}`, - ); - } - - return ( - new Promise((resolve, reject) => { - executeProcess({ - command: 'npm', - args, - shell: true, - observer: { - onStdout: (stdout: string) => { - if (verbose) { - process.stdout.write( - `${gray('>')} ${gray(bold('Verdaccio'))} ${stdout}`, - ); - } - - // Log of interest: warn --- http address - http://localhost:/ - verdaccio/5.31.1 - if (!startDetected && stdout.includes('http://localhost:')) { - // only setup env one time - startDetected = true; - - const result: RegistryResult = { - registry: { - storage, - ...parseRegistryData(stdout), - }, - // https://verdaccio.org/docs/cli/#default-database-file-location - stop: () => { - // this makes the process throw - killProcesses({ commandMatch: commandId }); - }, - }; - - console.info( - `${gray('>')} ${gray( - bold('Verdaccio'), - )} Registry started on URL: ${bold( - result.registry.url, - )}, with PID: ${bold( - listProcess({ commandMatch: commandId }).at(0)?.pid, - )}`, - ); - if (verbose) { - console.info(`${gray('>')} ${gray(bold('Verdaccio'))}`); - console.table(result); - } - - resolve(result); - } - }, - onStderr: (stderr: string) => { - if (verbose) { - process.stdout.write( - `${red('>')} ${red(bold('Verdaccio'))} ${stderr}`, - ); - } - }, - }, - }) - // @TODO reconsider this error handling - .catch(error => { - if (error.message !== 'Failed to start verdaccio: undefined') { - console.error( - `${red('>')} ${red( - bold('Verdaccio'), - )} Error starting ${projectName} verdaccio registry:\n${error}`, - ); - } else { - reject(error); - } - }); - }) - // in case the server dies unexpectedly clean folder - .catch((error: unknown) => { - teardownTestFolder(storage); - throw error; - }) - ); -} diff --git a/tools/src/verdaccio/start-local-registry.ts b/tools/src/verdaccio/start-local-registry.ts deleted file mode 100644 index 5df3d8664..000000000 --- a/tools/src/verdaccio/start-local-registry.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * This script starts a local registry for e2e testing purposes. - * It is meant to be called in jest's globalSetup. - */ -import { execSync } from 'child_process'; -import { executeProcess } from '../../../packages/utils/src'; -import { - configureRegistry, - parseRegistryData, - unconfigureRegistry, -} from './utils'; - -export type RegistryOptions = { - // local registry target to run - localRegistryTarget: string; - // storage folder for the local registry - storage?: string; - verbose?: boolean; - port?: number; -}; - -export type RegistryData = { - protocol: string; - port: string | number; - host: string; - registryNoProtocol: string; - registry: string; -}; - -export type RegistryResult = { - registryData: RegistryData; - stop: () => void; -}; -export default async function startLocalRegistry({ - localRegistryTarget, - storage, - verbose, - port, -}: RegistryOptions): Promise { - if (verbose) { - console.info(`Set up registry for port: ${port}.`); - } - - return new Promise((resolve, reject) => { - executeProcess({ - command: 'npx', - args: [ - 'nx', - 'run', - localRegistryTarget, - '--', - '--location none', - // reset or remove cached packages and or metadata. - '--clear true', - ...(storage ? [`--storage=${storage}`] : []), - ...(port ? [`--port${String(port)}`] : []), - ...(verbose ? [`--verbose`] : []), - ], - // @TODO understand what it does - // stdio: 'pipe', - shell: true, - observer: { - onStdout: (data, childProcess) => { - if (verbose) { - process.stdout.write(data); - } - - if (data.toString().includes('//localhost:')) { - const registryData = parseRegistryData(data); - - configureRegistry(registryData); - - if (verbose) { - console.info('Registry started:'); - console.table(registryData); - } - - resolve({ - registryData, - stop: () => { - // this makes the process throw - childProcess?.kill(); - unconfigureRegistry(registryData); - execSync( - `npm config delete ${registryData.registryNoProtocol}/:_authToken`, - ); - }, - }); - } - }, - onStderr: data => { - if (verbose) { - process.stdout.write(data); - } - }, - }, - }).catch(error => { - if (error.message !== 'Failed to start verdaccio: undefined') { - reject(error); - } else { - reject({ - registryData: { port }, - stop: () => { - console.log('Stop from executeProcess error' + error.message); - }, - }); - } - }); - }); -} diff --git a/tools/src/verdaccio/stop-local-registry.ts b/tools/src/verdaccio/stop-local-registry.ts deleted file mode 100644 index 920f19fc6..000000000 --- a/tools/src/verdaccio/stop-local-registry.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * This script stops the local registry for e2e testing purposes. - * It is meant to be called in jest's globalTeardown. - */ - -export default (stopLocalRegistry?: () => void, registry?: string) => { - if (stopLocalRegistry == null) { - throw new Error( - 'global e2e teardown script was not able to derive the stop script for the active registry from "activeRegistry"', - ); - } - console.info(`Stop local registry: ${registry}`); - if (typeof stopLocalRegistry === 'function') { - stopLocalRegistry(); - } else { - console.log('WRONG stopLocalRegistry: ', stopLocalRegistry); - } -}; diff --git a/tools/src/verdaccio/utils.ts b/tools/src/verdaccio/utils.ts deleted file mode 100644 index f72734b2c..000000000 --- a/tools/src/verdaccio/utils.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { execSync } from 'node:child_process'; -import type { RegistryData } from './start-local-registry'; - -export function uniquePort(): number { - return Number((6000 + Number(Math.random() * 1000)).toFixed(0)); -} - -export function configureRegistry({ - host, - registry, - registryNoProtocol, -}: RegistryData) { - console.info(`Set NPM registry under location user to ${registry}`); - execSync(`npm config set registry "${registry}"`); - - console.info(`Set yarn whitelíst process.env`); - - /** - * Protocol-Agnostic Configuration: The use of // allows NPM to configure authentication for a registry without tying it to a specific protocol (http: or https:). - * This is particularly useful when the registry might be accessible via both HTTP and HTTPS. - * - * Example: //registry.npmjs.org/:_authToken=your-token - */ - const token = 'secretVerdaccioToken'; - execSync(`npm config set ${registryNoProtocol}/:_authToken "${token}"`); - console.info(`_authToken for ${registry} set to ${token}`); -} - -export function unconfigureRegistry({ - registryNoProtocol, -}: Pick) { - execSync('npm config delete registry'); - execSync(`npm config delete ${registryNoProtocol}/:_authToken`); - console.info('delete npm authToken: ' + registryNoProtocol); -} - -export function parseRegistryData(stdout: string): RegistryData { - const port = parseInt( - stdout.toString().match(/localhost:(?\d+)/)?.groups?.port ?? '', - ); - if (isNaN(port)) { - throw new Error('Invalid port number'); - } - const protocolMatch = stdout - .toString() - .match(/(?https?):\/\/localhost:/); - const protocol = protocolMatch?.groups?.proto; - - if (!protocol || !['http', 'https'].includes(protocol)) { - throw new Error( - `Invalid protocol ${protocol}. Only http and https are allowed.`, - ); - } - - const host = 'localhost'; - const registryNoProtocol = `//${host}:${port}`; - const registry = `${protocol}:${registryNoProtocol}`; - - return { - protocol, - host, - port, - registryNoProtocol, - registry, - }; -} diff --git a/tools/src/verdaccio/verdaccio.plugin.ts b/tools/src/verdaccio/verdaccio.plugin.ts deleted file mode 100644 index f1cf6ae53..000000000 --- a/tools/src/verdaccio/verdaccio.plugin.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { - type CreateNodes, - type CreateNodesContext, - readJsonFile, -} from '@nx/devkit'; -import { bold } from 'ansis'; -import { dirname } from 'node:path'; -import type { ProjectConfiguration } from 'nx/src/config/workspace-json-project-json'; -import { someTargetsPresent } from '../utils'; -import { START_VERDACCIO_SERVER_TARGET_NAME } from './constants'; -import { uniquePort } from './utils'; - -type CreateNodesOptions = { - port?: string | number; - config?: string; - storage?: string; - preTargets?: string | string[]; - verbose?: boolean; -}; - -export const createNodes: CreateNodes = [ - '**/project.json', - ( - projectConfigurationFile: string, - opts: undefined | unknown, - context: CreateNodesContext, - ) => { - const { - port = uniquePort(), - config = '.verdaccio/config.yml', - storage = 'tmp/local-registry/storage', - verbose = false, - preTargets = ['e2e'], - } = (opts ?? {}) as CreateNodesOptions; - const { workspaceRoot } = context; - const root = dirname(projectConfigurationFile); - const projectConfiguration: ProjectConfiguration = readJsonFile( - projectConfigurationFile, - ); - - const hasPreVerdaccioTargets = someTargetsPresent( - projectConfiguration.targets ?? {}, - preTargets, - ); - const isRootProject = root === '.'; - if (!hasPreVerdaccioTargets && !isRootProject) { - return {}; - } - - if (!projectConfiguration.implicitDependencies && !isRootProject) { - throw new Error( - `You have to specify the needed projects as implicitDependencies in ${bold( - projectConfiguration.name, - )} to have them set up.`, - ); - } - - return { - projects: { - [root]: { - targets: verdaccioTargets({ - port, - config, - storage, - preTargets, - deps: projectConfiguration.implicitDependencies, - }), - }, - }, - }; - }, -]; - -function verdaccioTargets({ - port, - config, - storage, - deps, -}: Required> & { deps: string[] }) { - return { - [START_VERDACCIO_SERVER_TARGET_NAME]: { - executor: '@nx/js:verdaccio', - options: { - port, - config, - storage, - }, - }, - ['setup-deps']: { - executor: 'nx:run-commands', - options: { - commands: [ - `nx run-many -t publish -p ${deps?.join(',')}`, - // NPM install needs to be run sequentially as it can cause issues with installing dependencies multiple times - `nx run-many -t npm-install -p ${deps?.join(',')} --parallel=1`, - ], - parallel: false, - }, - }, - }; -} From f39c5b67583287b097cbee04cb0bfb9008f95cd0 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 16:09:20 +0100 Subject: [PATCH 40/80] wip env --- static-environments/cli-e2e-env/package.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/static-environments/cli-e2e-env/package.json b/static-environments/cli-e2e-env/package.json index 40e9d621b..8788e3a02 100644 --- a/static-environments/cli-e2e-env/package.json +++ b/static-environments/cli-e2e-env/package.json @@ -9,11 +9,6 @@ "keywords": [], "author": "", "license": "ISC", - "dependencies": { - "@code-pushup/cli": "^0.54.0", - "@code-pushup/core": "^0.54.0", - "@code-pushup/models": "^0.54.0", - "@code-pushup/utils": "^0.54.0" - }, + "dependencies": {}, "description": "" } From 7abcae7937932e40fa768c12a5e777717d09c3ae Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 16:09:36 +0100 Subject: [PATCH 41/80] format --- e2e/cli-e2e/tests/help.e2e.test.ts | 2 +- static-environments/cli-e2e-env/dummy.plugin.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/cli-e2e/tests/help.e2e.test.ts b/e2e/cli-e2e/tests/help.e2e.test.ts index 6e3586290..574bc99c9 100644 --- a/e2e/cli-e2e/tests/help.e2e.test.ts +++ b/e2e/cli-e2e/tests/help.e2e.test.ts @@ -1,6 +1,6 @@ +import { join } from 'node:path'; import { removeColorCodes } from '@code-pushup/test-utils'; import { executeProcess } from '@code-pushup/utils'; -import {join} from "node:path"; describe('CLI help', () => { const envRoot = join('static-environments', 'cli-e2e-env'); diff --git a/static-environments/cli-e2e-env/dummy.plugin.ts b/static-environments/cli-e2e-env/dummy.plugin.ts index d2e51c2b6..8ff5ebd18 100644 --- a/static-environments/cli-e2e-env/dummy.plugin.ts +++ b/static-environments/cli-e2e-env/dummy.plugin.ts @@ -1,6 +1,6 @@ import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; import type { PluginConfig } from '@code-pushup/models'; -import {join} from "node:path"; export const dummyPluginSlug = 'dummy-plugin'; @@ -32,7 +32,7 @@ export function create(): PluginConfig { description: 'A dummy plugin to test the cli.', runner: async () => { const itemCount = JSON.parse( - await readFile(join('src','items.json'), 'utf-8'), + await readFile(join('src', 'items.json'), 'utf-8'), ).length; return [ { From 9923b5305a850cfa8a662b4e9f4af9cd9da9a937 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 16:14:21 +0100 Subject: [PATCH 42/80] cleanup gh action --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 845def216..3e8ebe65d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,9 +120,7 @@ jobs: - name: Install dependencies run: npm ci - name: E2E test affected projects - run: npx nx affected -t nxv-e2e --exclude cli-e2e --parallel=1 - - name: E2E test cli-e2e project (due to bugs in the setup it has to run last :( ) - run: npx nx run cli-e2e:e2e-old + run: npx nx affected -t nxv-e2e --parallel=1 build: runs-on: ubuntu-latest From 5211673b8965b472bf75d5593deefbff73968860 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 16:15:49 +0100 Subject: [PATCH 43/80] cleanup targets --- static-environments/cli-e2e-env/project.json | 60 +------------------- 1 file changed, 2 insertions(+), 58 deletions(-) diff --git a/static-environments/cli-e2e-env/project.json b/static-environments/cli-e2e-env/project.json index bcedafb59..f92b11d37 100644 --- a/static-environments/cli-e2e-env/project.json +++ b/static-environments/cli-e2e-env/project.json @@ -4,67 +4,11 @@ "sourceRoot": "static-environments/cli-e2e-env/src", "projectType": "application", "targets": { - "build": { - "executor": "@nx/vite:build", - "outputs": ["{options.outputPath}"], - "defaultConfiguration": "production", - "options": { - "outputPath": "dist/examples/react-todos-app" - }, - "configurations": { - "development": { - "mode": "development" - }, - "production": { - "mode": "production" - } - } - }, - "serve": { - "executor": "@nx/vite:dev-server", - "defaultConfiguration": "development", - "options": { - "buildTarget": "react-todos-app:build" - }, - "configurations": { - "development": { - "buildTarget": "react-todos-app:build:development", - "hmr": true - }, - "production": { - "buildTarget": "react-todos-app:build:production", - "hmr": false - } - } - }, - "test": { - "executor": "@nx/vite:test", - "outputs": ["{options.reportsDirectory}"], - "options": { - "configFile": "examples/react-todos-app/vite.config.ts", - "reportsDirectory": "../../coverage/react-todos-app" - } - }, - "preview": { - "executor": "@nx/vite:preview-server", - "defaultConfiguration": "development", - "options": { - "buildTarget": "react-todos-app:build" - }, - "configurations": { - "development": { - "buildTarget": "react-todos-app:build:development" - }, - "production": { - "buildTarget": "react-todos-app:build:production" - } - } - }, "run-collect": { "executor": "nx:run-commands", "options": { - "command": "npx ../../dist/packages/cli collect --no-progress", - "cwd": "examples/react-todos-app" + "command": "npx @code-pushup/cli collect --no-progress", + "cwd": "static-environments/cli-e2e-env" }, "dependsOn": [ { From cc9467526c1014a5f860ae2f145d681d38311f3a Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 16:23:59 +0100 Subject: [PATCH 44/80] cleanup cp --- code-pushup.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code-pushup.config.ts b/code-pushup.config.ts index 9d7def723..c96b7551c 100644 --- a/code-pushup.config.ts +++ b/code-pushup.config.ts @@ -37,7 +37,7 @@ const config: CoreConfig = { plugins: [ fileSizePlugin({ - directory: './dist/examples/react-todos-app', + directory: './dist/packages', pattern: /\.js$/, budget: 174_080, // 170 kB }), From 95c482ea3b98ce84c02129b410b487ae56f38d1a Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 10 Nov 2024 16:59:49 +0100 Subject: [PATCH 45/80] wip cp --- .github/workflows/code-pushup.yml | 2 +- nx.json | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/code-pushup.yml b/.github/workflows/code-pushup.yml index cc1351476..3c586d84b 100644 --- a/.github/workflows/code-pushup.yml +++ b/.github/workflows/code-pushup.yml @@ -36,4 +36,4 @@ jobs: - name: Run Code PushUp action uses: code-pushup/github-action@v0 with: - bin: npx nx code-pushup -- + bin: npx nx code-pushup -- --verbose diff --git a/nx.json b/nx.json index 51dcda372..e28c61379 100644 --- a/nx.json +++ b/nx.json @@ -109,7 +109,6 @@ "filterByTags": ["publishable"] } } - }, - "./tools/src/debug/debug.plugin.ts" + } ] } From 1647e380b15cf89a708a19cc75f438bbb435328b Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 11 Nov 2024 17:47:43 +0100 Subject: [PATCH 46/80] colocate e2e files --- e2e/plugin-eslint-e2e/project.json | 7 ++++- .../tests/collect.e2e.test.ts | 6 ++--- e2e/plugin-eslint-e2e/tsconfig.test.json | 3 +++ .../eslint-e2e-env/.eslintrc.json | 20 -------------- .../eslint-e2e-env/code-pushup.config.ts | 27 ------------------- .../eslint-e2e-env/project.json | 8 ------ .../eslint-e2e-env/src/index.js | 7 ----- 7 files changed, 12 insertions(+), 66 deletions(-) delete mode 100644 static-environments/eslint-e2e-env/.eslintrc.json delete mode 100644 static-environments/eslint-e2e-env/code-pushup.config.ts delete mode 100644 static-environments/eslint-e2e-env/project.json delete mode 100644 static-environments/eslint-e2e-env/src/index.js diff --git a/e2e/plugin-eslint-e2e/project.json b/e2e/plugin-eslint-e2e/project.json index 6487d3102..05dac3ffc 100644 --- a/e2e/plugin-eslint-e2e/project.json +++ b/e2e/plugin-eslint-e2e/project.json @@ -11,9 +11,14 @@ "lintFilePatterns": ["e2e/plugin-eslint-e2e/**/*.ts"] } }, + "nxv-e2e": { + "options": { + "environmentRoot": "e2e/plugin-eslint-e2e/__test-env__" + } + }, "nxv-env-setup": { "options": { - "environmentRoot": "static-environments/eslint-e2e-env" + "environmentRoot": "e2e/plugin-eslint-e2e/__test-env__" } }, "e2e": { diff --git a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts index 17d7d05be..5587090e5 100644 --- a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts @@ -6,8 +6,8 @@ import { omitVariableReportData } from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; describe('collect report with eslint-plugin NPM package', () => { - const envRoot = 'static-environments/eslint-e2e-env'; - const baseDir = join(envRoot, '__tests__'); + const envRoot = 'e2e/plugin-eslint-e2e/__test-env__'; + const baseDir = join(envRoot); afterEach(async () => { await teardownTestFolder(baseDir); @@ -16,7 +16,7 @@ describe('collect report with eslint-plugin NPM package', () => { it('should run ESLint plugin and create report.json', async () => { const outputDir = relative( envRoot, - join(baseDir, 'default-report', '.code-pushup'), + join(baseDir, '.code-pushup'), ); const { code, stderr } = await executeProcess({ command: 'npx', diff --git a/e2e/plugin-eslint-e2e/tsconfig.test.json b/e2e/plugin-eslint-e2e/tsconfig.test.json index 10c7f79de..419f13bc6 100644 --- a/e2e/plugin-eslint-e2e/tsconfig.test.json +++ b/e2e/plugin-eslint-e2e/tsconfig.test.json @@ -5,6 +5,9 @@ "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"], "target": "ES2020" }, + "exclude": [ + "__test-env__" + ], "include": [ "vite.config.e2e.ts", "tests/**/*.e2e.test.ts", diff --git a/static-environments/eslint-e2e-env/.eslintrc.json b/static-environments/eslint-e2e-env/.eslintrc.json deleted file mode 100644 index 113136c93..000000000 --- a/static-environments/eslint-e2e-env/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "root": true, - "ignorePatterns": ["code-pushup.config.ts"], - "overrides": [ - { - "files": ["*.js"], - "env": { - "node": true - }, - "parserOptions": { - "sourceType": "script" - }, - "rules": { - "no-unused-vars": "error", - "no-console": "warn", - "no-undef": "error" - } - } - ] -} diff --git a/static-environments/eslint-e2e-env/code-pushup.config.ts b/static-environments/eslint-e2e-env/code-pushup.config.ts deleted file mode 100644 index 01feaf2ff..000000000 --- a/static-environments/eslint-e2e-env/code-pushup.config.ts +++ /dev/null @@ -1,27 +0,0 @@ -import eslintPlugin from '@code-pushup/eslint-plugin'; - -export default { - plugins: [ - await eslintPlugin({ - eslintrc: '.eslintrc.json', - patterns: ['src/*.js'], - }), - ], - categories: [ - { - slug: 'bug-prevention', - title: 'Bug prevention', - description: 'Lint rules that find **potential bugs** in your code.', - refs: [{ type: 'group', plugin: 'eslint', slug: 'problems', weight: 1 }], - }, - { - slug: 'code-style', - title: 'Code style', - description: - 'Lint rules that promote **good practices** and consistency in your code.', - refs: [ - { type: 'group', plugin: 'eslint', slug: 'suggestions', weight: 1 }, - ], - }, - ], -}; diff --git a/static-environments/eslint-e2e-env/project.json b/static-environments/eslint-e2e-env/project.json deleted file mode 100644 index 857adc78f..000000000 --- a/static-environments/eslint-e2e-env/project.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "eslint-e2e-env", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "static-environments/eslint-e2e-env/src", - "projectType": "library", - "targets": {}, - "tags": ["scope:internal", "type:feature"] -} diff --git a/static-environments/eslint-e2e-env/src/index.js b/static-environments/eslint-e2e-env/src/index.js deleted file mode 100644 index 4710a3767..000000000 --- a/static-environments/eslint-e2e-env/src/index.js +++ /dev/null @@ -1,7 +0,0 @@ -function unusedFn() { - return '42'; -} - -module.exports = function consoleLog() { - console.log('No console.log()!'); -}; From 4a615242746e37cd2e5793cc967b60eec2d515ce Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 11 Nov 2024 18:06:55 +0100 Subject: [PATCH 47/80] cleanup --- .../__snapshots__/collect.e2e.test.ts.snap | 1000 ----------------- e2e/plugin-eslint-e2e/project.json | 2 +- .../tests/collect.e2e.test.ts | 5 +- e2e/plugin-eslint-e2e/tsconfig.test.json | 4 +- 4 files changed, 3 insertions(+), 1008 deletions(-) diff --git a/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index 47a9e0f07..063ffb7ea 100644 --- a/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -419,1003 +419,3 @@ exports[`CLI collect > should run Code coverage plugin which collects passed res ], } `; - -exports[`CLI collect > should run ESLint plugin and create report.json 1`] = ` -{ - "categories": [ - { - "refs": [ - { - "plugin": "eslint", - "slug": "no-cond-assign", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-const-assign", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-debugger", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-invalid-regexp", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-undef", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-unreachable-loop", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-unsafe-negation", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-unsafe-optional-chaining", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "use-isnan", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "valid-typeof", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "eqeqeq", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "react-jsx-key", - "type": "audit", - "weight": 2, - }, - { - "plugin": "eslint", - "slug": "react-prop-types", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "react-react-in-jsx-scope", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "react-hooks-rules-of-hooks", - "type": "audit", - "weight": 2, - }, - { - "plugin": "eslint", - "slug": "react-hooks-exhaustive-deps", - "type": "audit", - "weight": 2, - }, - ], - "slug": "bug-prevention", - "title": "Bug prevention", - }, - { - "refs": [ - { - "plugin": "eslint", - "slug": "no-unused-vars", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "arrow-body-style", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "camelcase", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "curly", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "eqeqeq", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "max-lines-per-function", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "max-lines", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "object-shorthand", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "prefer-arrow-callback", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "prefer-const", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "prefer-object-spread", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "yoda", - "type": "audit", - "weight": 1, - }, - { - "plugin": "eslint", - "slug": "no-var", - "type": "audit", - "weight": 1, - }, - ], - "slug": "code-style", - "title": "Code style", - }, - ], - "packageName": "@code-pushup/core", - "plugins": [ - { - "audits": [ - { - "description": "ESLint rule **no-cond-assign**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-cond-assign", - "score": 1, - "slug": "no-cond-assign", - "title": "Disallow assignment operators in conditional expressions", - "value": 0, - }, - { - "description": "ESLint rule **no-const-assign**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-const-assign", - "score": 1, - "slug": "no-const-assign", - "title": "Disallow reassigning \`const\` variables", - "value": 0, - }, - { - "description": "ESLint rule **no-debugger**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-debugger", - "score": 1, - "slug": "no-debugger", - "title": "Disallow the use of \`debugger\`", - "value": 0, - }, - { - "description": "ESLint rule **no-invalid-regexp**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-invalid-regexp", - "score": 1, - "slug": "no-invalid-regexp", - "title": "Disallow invalid regular expression strings in \`RegExp\` constructors", - "value": 0, - }, - { - "description": "ESLint rule **no-undef**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-undef", - "score": 1, - "slug": "no-undef", - "title": "Disallow the use of undeclared variables unless mentioned in \`/*global */\` comments", - "value": 0, - }, - { - "description": "ESLint rule **no-unreachable-loop**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unreachable-loop", - "score": 1, - "slug": "no-unreachable-loop", - "title": "Disallow loops with a body that allows only one iteration", - "value": 0, - }, - { - "description": "ESLint rule **no-unsafe-negation**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unsafe-negation", - "score": 1, - "slug": "no-unsafe-negation", - "title": "Disallow negating the left operand of relational operators", - "value": 0, - }, - { - "description": "ESLint rule **no-unsafe-optional-chaining**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unsafe-optional-chaining", - "score": 1, - "slug": "no-unsafe-optional-chaining", - "title": "Disallow use of optional chaining in contexts where the \`undefined\` value is not allowed", - "value": 0, - }, - { - "description": "ESLint rule **no-unused-vars**.", - "details": { - "issues": [ - { - "message": "'loading' is assigned a value but never used.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/App.jsx", - "position": { - "endColumn": 18, - "endLine": 8, - "startColumn": 11, - "startLine": 8, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unused-vars", - "score": 0, - "slug": "no-unused-vars", - "title": "Disallow unused variables", - "value": 1, - }, - { - "description": "ESLint rule **use-isnan**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/use-isnan", - "score": 1, - "slug": "use-isnan", - "title": "Require calls to \`isNaN()\` when checking for \`NaN\`", - "value": 0, - }, - { - "description": "ESLint rule **valid-typeof**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/valid-typeof", - "score": 1, - "slug": "valid-typeof", - "title": "Enforce comparing \`typeof\` expressions against valid strings", - "value": 0, - }, - { - "description": "ESLint rule **arrow-body-style**.", - "details": { - "issues": [ - { - "message": "Unexpected block statement surrounding arrow body; move the returned value immediately after the \`=>\`.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "endColumn": 2, - "endLine": 25, - "startColumn": 29, - "startLine": 3, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/arrow-body-style", - "score": 0, - "slug": "arrow-body-style", - "title": "Require braces around arrow function bodies", - "value": 1, - }, - { - "description": "ESLint rule **camelcase**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/camelcase", - "score": 1, - "slug": "camelcase", - "title": "Enforce camelcase naming convention", - "value": 0, - }, - { - "description": "ESLint rule **curly**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/curly", - "score": 1, - "slug": "curly", - "title": "Enforce consistent brace style for all control statements", - "value": 0, - }, - { - "description": "ESLint rule **eqeqeq**.", - "details": { - "issues": [ - { - "message": "Expected '===' and instead saw '=='.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 43, - "endLine": 41, - "startColumn": 41, - "startLine": 41, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/eqeqeq", - "score": 0, - "slug": "eqeqeq", - "title": "Require the use of \`===\` and \`!==\`", - "value": 1, - }, - { - "description": "ESLint rule **max-lines-per-function**.", - "details": { - "issues": [ - { - "message": "Arrow function has too many lines (71). Maximum allowed is 50.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 2, - "endLine": 73, - "startColumn": 25, - "startLine": 3, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/max-lines-per-function", - "score": 0, - "slug": "max-lines-per-function", - "title": "Enforce a maximum number of lines of code in a function", - "value": 1, - }, - { - "description": "ESLint rule **max-lines**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/max-lines", - "score": 1, - "slug": "max-lines", - "title": "Enforce a maximum number of lines per file", - "value": 0, - }, - { - "description": "ESLint rule **no-shadow**.", - "details": { - "issues": [ - { - "message": "'data' is already declared in the upper scope on line 5 column 10.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 17, - "endLine": 11, - "startColumn": 13, - "startLine": 11, - }, - }, - }, - { - "message": "'data' is already declared in the upper scope on line 5 column 10.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 21, - "endLine": 29, - "startColumn": 17, - "startLine": 29, - }, - }, - }, - { - "message": "'data' is already declared in the upper scope on line 5 column 10.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 17, - "endLine": 41, - "startColumn": 13, - "startLine": 41, - }, - }, - }, - ], - }, - "displayValue": "3 warnings", - "docsUrl": "https://eslint.org/docs/latest/rules/no-shadow", - "score": 0, - "slug": "no-shadow", - "title": "Disallow variable declarations from shadowing variables declared in the outer scope", - "value": 3, - }, - { - "description": "ESLint rule **no-var**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-var", - "score": 1, - "slug": "no-var", - "title": "Require \`let\` or \`const\` instead of \`var\`", - "value": 0, - }, - { - "description": "ESLint rule **object-shorthand**.", - "details": { - "issues": [ - { - "message": "Expected property shorthand.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 19, - "endLine": 19, - "startColumn": 7, - "startLine": 19, - }, - }, - }, - { - "message": "Expected property shorthand.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 19, - "endLine": 32, - "startColumn": 13, - "startLine": 32, - }, - }, - }, - { - "message": "Expected property shorthand.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 25, - "endLine": 33, - "startColumn": 13, - "startLine": 33, - }, - }, - }, - ], - }, - "displayValue": "3 warnings", - "docsUrl": "https://eslint.org/docs/latest/rules/object-shorthand", - "score": 0, - "slug": "object-shorthand", - "title": "Require or disallow method and property shorthand syntax for object literals", - "value": 3, - }, - { - "description": "ESLint rule **prefer-arrow-callback**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/prefer-arrow-callback", - "score": 1, - "slug": "prefer-arrow-callback", - "title": "Require using arrow functions for callbacks", - "value": 0, - }, - { - "description": "ESLint rule **prefer-const**.", - "details": { - "issues": [ - { - "message": "'root' is never reassigned. Use 'const' instead.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/index.jsx", - "position": { - "endColumn": 9, - "endLine": 5, - "startColumn": 5, - "startLine": 5, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/prefer-const", - "score": 0, - "slug": "prefer-const", - "title": "Require \`const\` declarations for variables that are never reassigned after declared", - "value": 1, - }, - { - "description": "ESLint rule **prefer-object-spread**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/prefer-object-spread", - "score": 1, - "slug": "prefer-object-spread", - "title": "Disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead", - "value": 0, - }, - { - "description": "ESLint rule **yoda**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/yoda", - "score": 1, - "slug": "yoda", - "title": "Require or disallow "Yoda" conditions", - "value": 0, - }, - { - "description": "ESLint rule **jsx-key**, from _react_ plugin.", - "details": { - "issues": [ - { - "message": "Missing "key" prop for element in iterator", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoList.jsx", - "position": { - "endColumn": 12, - "endLine": 28, - "startColumn": 7, - "startLine": 7, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-key.md", - "score": 0, - "slug": "react-jsx-key", - "title": "Disallow missing \`key\` props in iterators/collection literals", - "value": 1, - }, - { - "description": "ESLint rule **prop-types**, from _react_ plugin.", - "details": { - "issues": [ - { - "message": "'onCreate' is missing in props validation", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/CreateTodo.jsx", - "position": { - "endColumn": 23, - "endLine": 15, - "startColumn": 15, - "startLine": 15, - }, - }, - }, - { - "message": "'setQuery' is missing in props validation", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "endColumn": 25, - "endLine": 10, - "startColumn": 17, - "startLine": 10, - }, - }, - }, - { - "message": "'setHideComplete' is missing in props validation", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "endColumn": 34, - "endLine": 18, - "startColumn": 19, - "startLine": 18, - }, - }, - }, - { - "message": "'todos' is missing in props validation", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoList.jsx", - "position": { - "endColumn": 17, - "endLine": 6, - "startColumn": 12, - "startLine": 6, - }, - }, - }, - { - "message": "'todos.map' is missing in props validation", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoList.jsx", - "position": { - "endColumn": 21, - "endLine": 6, - "startColumn": 18, - "startLine": 6, - }, - }, - }, - { - "message": "'onEdit' is missing in props validation", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoList.jsx", - "position": { - "endColumn": 27, - "endLine": 13, - "startColumn": 21, - "startLine": 13, - }, - }, - }, - ], - }, - "displayValue": "6 warnings", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/prop-types.md", - "score": 0, - "slug": "react-prop-types", - "title": "Disallow missing props validation in a React component definition", - "value": 6, - }, - { - "description": "ESLint rule **react-in-jsx-scope**, from _react_ plugin.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/react-in-jsx-scope.md", - "score": 1, - "slug": "react-react-in-jsx-scope", - "title": "Disallow missing React when using JSX", - "value": 0, - }, - { - "description": "ESLint rule **jsx-uses-vars**, from _react_ plugin.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-uses-vars.md", - "score": 1, - "slug": "react-jsx-uses-vars", - "title": "Disallow variables used in JSX to be incorrectly marked as unused", - "value": 0, - }, - { - "description": "ESLint rule **jsx-uses-react**, from _react_ plugin.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/jsx-uses-react.md", - "score": 1, - "slug": "react-jsx-uses-react", - "title": "Disallow React to be incorrectly marked as unused", - "value": 0, - }, - { - "description": "ESLint rule **rules-of-hooks**, from _react-hooks_ plugin.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://reactjs.org/docs/hooks-rules.html", - "score": 1, - "slug": "react-hooks-rules-of-hooks", - "title": "enforces the Rules of Hooks", - "value": 0, - }, - { - "description": "ESLint rule **exhaustive-deps**, from _react-hooks_ plugin.", - "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": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 31, - "endLine": 17, - "startColumn": 20, - "startLine": 17, - }, - }, - }, - { - "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": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endColumn": 29, - "endLine": 40, - "startColumn": 18, - "startLine": 40, - }, - }, - }, - ], - }, - "displayValue": "2 warnings", - "docsUrl": "https://github.com/facebook/react/issues/14920", - "score": 0, - "slug": "react-hooks-exhaustive-deps", - "title": "verifies the list of dependencies for Hooks like useEffect and similar", - "value": 2, - }, - ], - "description": "Official Code PushUp ESLint plugin", - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "groups": [ - { - "description": "Code that either will cause an error or may cause confusing behavior. Developers should consider this a high priority to resolve.", - "refs": [ - { - "slug": "no-cond-assign", - "weight": 1, - }, - { - "slug": "no-const-assign", - "weight": 1, - }, - { - "slug": "no-debugger", - "weight": 1, - }, - { - "slug": "no-invalid-regexp", - "weight": 1, - }, - { - "slug": "no-undef", - "weight": 1, - }, - { - "slug": "no-unreachable-loop", - "weight": 1, - }, - { - "slug": "no-unsafe-negation", - "weight": 1, - }, - { - "slug": "no-unsafe-optional-chaining", - "weight": 1, - }, - { - "slug": "no-unused-vars", - "weight": 1, - }, - { - "slug": "use-isnan", - "weight": 1, - }, - { - "slug": "valid-typeof", - "weight": 1, - }, - { - "slug": "react-hooks-rules-of-hooks", - "weight": 1, - }, - ], - "slug": "problems", - "title": "Problems", - }, - { - "description": "Something that could be done in a better way but no errors will occur if the code isn't changed.", - "refs": [ - { - "slug": "arrow-body-style", - "weight": 1, - }, - { - "slug": "camelcase", - "weight": 1, - }, - { - "slug": "curly", - "weight": 1, - }, - { - "slug": "eqeqeq", - "weight": 1, - }, - { - "slug": "max-lines-per-function", - "weight": 1, - }, - { - "slug": "max-lines", - "weight": 1, - }, - { - "slug": "no-shadow", - "weight": 1, - }, - { - "slug": "no-var", - "weight": 1, - }, - { - "slug": "object-shorthand", - "weight": 1, - }, - { - "slug": "prefer-arrow-callback", - "weight": 1, - }, - { - "slug": "prefer-const", - "weight": 1, - }, - { - "slug": "prefer-object-spread", - "weight": 1, - }, - { - "slug": "yoda", - "weight": 1, - }, - { - "slug": "react-hooks-exhaustive-deps", - "weight": 1, - }, - ], - "slug": "suggestions", - "title": "Suggestions", - }, - { - "refs": [ - { - "slug": "react-prop-types", - "weight": 1, - }, - { - "slug": "react-jsx-uses-vars", - "weight": 1, - }, - { - "slug": "react-jsx-uses-react", - "weight": 1, - }, - ], - "slug": "react-best-practices", - "title": "Best Practices (react)", - }, - { - "refs": [ - { - "slug": "react-jsx-key", - "weight": 1, - }, - { - "slug": "react-react-in-jsx-scope", - "weight": 1, - }, - ], - "slug": "react-possible-errors", - "title": "Possible Errors (react)", - }, - ], - "icon": "eslint", - "packageName": "@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - ], -} -`; diff --git a/e2e/plugin-eslint-e2e/project.json b/e2e/plugin-eslint-e2e/project.json index 05dac3ffc..301f6d19a 100644 --- a/e2e/plugin-eslint-e2e/project.json +++ b/e2e/plugin-eslint-e2e/project.json @@ -28,6 +28,6 @@ } } }, - "implicitDependencies": ["cli", "plugin-eslint", "eslint-e2e-env"], + "implicitDependencies": ["cli", "plugin-eslint"], "tags": ["scope:plugin", "type:e2e"] } diff --git a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts index 5587090e5..a510876b0 100644 --- a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts @@ -14,10 +14,7 @@ describe('collect report with eslint-plugin NPM package', () => { }); it('should run ESLint plugin and create report.json', async () => { - const outputDir = relative( - envRoot, - join(baseDir, '.code-pushup'), - ); + const outputDir = relative(envRoot, join(baseDir, '.code-pushup')); const { code, stderr } = await executeProcess({ command: 'npx', args: [ diff --git a/e2e/plugin-eslint-e2e/tsconfig.test.json b/e2e/plugin-eslint-e2e/tsconfig.test.json index 419f13bc6..7e4507b8b 100644 --- a/e2e/plugin-eslint-e2e/tsconfig.test.json +++ b/e2e/plugin-eslint-e2e/tsconfig.test.json @@ -5,9 +5,7 @@ "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"], "target": "ES2020" }, - "exclude": [ - "__test-env__" - ], + "exclude": ["__test-env__"], "include": [ "vite.config.e2e.ts", "tests/**/*.e2e.test.ts", From c32e1589e6401802049496bef1eada5f27245c72 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 11 Nov 2024 18:29:40 +0100 Subject: [PATCH 48/80] cleanup --- .../plugin-coverage-e2e/__test-env__}/.gitignore | 0 .../plugin-coverage-e2e/__test-env__}/code-pushup.config.ts | 0 .../__test-env__}/code-pushup.existing-report.config.ts | 0 .../__test-env__}/mocks/fixtures/lcov.info | 0 .../plugin-coverage-e2e/__test-env__}/package.json | 4 ++-- .../plugin-coverage-e2e/__test-env__}/project.json | 2 +- .../plugin-coverage-e2e/__test-env__}/src/index.mjs | 0 .../plugin-coverage-e2e/__test-env__}/src/index.test.mjs | 2 +- .../plugin-coverage-e2e/__test-env__}/vite.config.ts | 0 e2e/plugin-coverage-e2e/project.json | 6 +++--- e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts | 6 +++--- e2e/plugin-coverage-e2e/tsconfig.test.json | 1 + 12 files changed, 11 insertions(+), 10 deletions(-) rename {static-environments/coverage-e2e-env => e2e/plugin-coverage-e2e/__test-env__}/.gitignore (100%) rename {static-environments/coverage-e2e-env => e2e/plugin-coverage-e2e/__test-env__}/code-pushup.config.ts (100%) rename {static-environments/coverage-e2e-env => e2e/plugin-coverage-e2e/__test-env__}/code-pushup.existing-report.config.ts (100%) rename {static-environments/coverage-e2e-env => e2e/plugin-coverage-e2e/__test-env__}/mocks/fixtures/lcov.info (100%) rename {static-environments/coverage-e2e-env => e2e/plugin-coverage-e2e/__test-env__}/package.json (93%) rename {static-environments/coverage-e2e-env => e2e/plugin-coverage-e2e/__test-env__}/project.json (72%) rename {static-environments/coverage-e2e-env => e2e/plugin-coverage-e2e/__test-env__}/src/index.mjs (100%) rename {static-environments/coverage-e2e-env => e2e/plugin-coverage-e2e/__test-env__}/src/index.test.mjs (87%) rename {static-environments/coverage-e2e-env => e2e/plugin-coverage-e2e/__test-env__}/vite.config.ts (100%) diff --git a/static-environments/coverage-e2e-env/.gitignore b/e2e/plugin-coverage-e2e/__test-env__/.gitignore similarity index 100% rename from static-environments/coverage-e2e-env/.gitignore rename to e2e/plugin-coverage-e2e/__test-env__/.gitignore diff --git a/static-environments/coverage-e2e-env/code-pushup.config.ts b/e2e/plugin-coverage-e2e/__test-env__/code-pushup.config.ts similarity index 100% rename from static-environments/coverage-e2e-env/code-pushup.config.ts rename to e2e/plugin-coverage-e2e/__test-env__/code-pushup.config.ts diff --git a/static-environments/coverage-e2e-env/code-pushup.existing-report.config.ts b/e2e/plugin-coverage-e2e/__test-env__/code-pushup.existing-report.config.ts similarity index 100% rename from static-environments/coverage-e2e-env/code-pushup.existing-report.config.ts rename to e2e/plugin-coverage-e2e/__test-env__/code-pushup.existing-report.config.ts diff --git a/static-environments/coverage-e2e-env/mocks/fixtures/lcov.info b/e2e/plugin-coverage-e2e/__test-env__/mocks/fixtures/lcov.info similarity index 100% rename from static-environments/coverage-e2e-env/mocks/fixtures/lcov.info rename to e2e/plugin-coverage-e2e/__test-env__/mocks/fixtures/lcov.info diff --git a/static-environments/coverage-e2e-env/package.json b/e2e/plugin-coverage-e2e/__test-env__/package.json similarity index 93% rename from static-environments/coverage-e2e-env/package.json rename to e2e/plugin-coverage-e2e/__test-env__/package.json index c132d93f1..ac964b1c9 100644 --- a/static-environments/coverage-e2e-env/package.json +++ b/e2e/plugin-coverage-e2e/__test-env__/package.json @@ -8,11 +8,11 @@ "keywords": [], "author": "", "license": "ISC", - "description": "", "dependencies": { "@code-pushup/core": "^0.54.0", "@code-pushup/coverage-plugin": "^0.54.0", "@code-pushup/models": "^0.54.0", "@code-pushup/utils": "^0.54.0" - } + }, + "description": "" } diff --git a/static-environments/coverage-e2e-env/project.json b/e2e/plugin-coverage-e2e/__test-env__/project.json similarity index 72% rename from static-environments/coverage-e2e-env/project.json rename to e2e/plugin-coverage-e2e/__test-env__/project.json index f8d390e28..4a70f3435 100644 --- a/static-environments/coverage-e2e-env/project.json +++ b/e2e/plugin-coverage-e2e/__test-env__/project.json @@ -1,6 +1,6 @@ { "name": "coverage-e2e-env", - "$schema": "../../node_modules/nx/schemas/project-schema.json", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", "sourceRoot": "static-environments/coverage-e2e-env/src", "projectType": "library", "targets": {}, diff --git a/static-environments/coverage-e2e-env/src/index.mjs b/e2e/plugin-coverage-e2e/__test-env__/src/index.mjs similarity index 100% rename from static-environments/coverage-e2e-env/src/index.mjs rename to e2e/plugin-coverage-e2e/__test-env__/src/index.mjs diff --git a/static-environments/coverage-e2e-env/src/index.test.mjs b/e2e/plugin-coverage-e2e/__test-env__/src/index.test.mjs similarity index 87% rename from static-environments/coverage-e2e-env/src/index.test.mjs rename to e2e/plugin-coverage-e2e/__test-env__/src/index.test.mjs index efef0528b..d02988166 100644 --- a/static-environments/coverage-e2e-env/src/index.test.mjs +++ b/e2e/plugin-coverage-e2e/__test-env__/src/index.test.mjs @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { get42, isEven, untested } from './index'; +import { get42, isEven, untested } from './index.mjs'; describe('get42', () => { it('should return 42', async () => { diff --git a/static-environments/coverage-e2e-env/vite.config.ts b/e2e/plugin-coverage-e2e/__test-env__/vite.config.ts similarity index 100% rename from static-environments/coverage-e2e-env/vite.config.ts rename to e2e/plugin-coverage-e2e/__test-env__/vite.config.ts diff --git a/e2e/plugin-coverage-e2e/project.json b/e2e/plugin-coverage-e2e/project.json index 4c4f76881..14dd9ca93 100644 --- a/e2e/plugin-coverage-e2e/project.json +++ b/e2e/plugin-coverage-e2e/project.json @@ -13,12 +13,12 @@ }, "nxv-e2e": { "options": { - "environmentRoot": "static-environments/coverage-e2e-env" + "environmentRoot": "e2e/plugin-coverage-e2e/__test-env__" } }, "nxv-env-setup": { "options": { - "environmentRoot": "static-environments/coverage-e2e-env" + "environmentRoot": "e2e/plugin-coverage-e2e/__test-env__" } }, "e2e": { @@ -28,6 +28,6 @@ } } }, - "implicitDependencies": ["cli", "plugin-coverage", "coverage-e2e-env"], + "implicitDependencies": ["cli", "plugin-coverage"], "tags": ["scope:plugin", "type:e2e"] } diff --git a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts index 747fe0571..dd7081fa5 100644 --- a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts @@ -6,11 +6,11 @@ import { omitVariableReportData } from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; describe('collect report with coverage-plugin NPM package', () => { - const envRoot = 'static-environments/coverage-e2e-env'; - const baseDir = join(envRoot, '__tests__'); + const envRoot = 'e2e/plugin-coverage-e2e/__test-env__'; + const coverageDir = join(envRoot, '.code-pushup'); afterEach(async () => { - await teardownTestFolder(baseDir); + await teardownTestFolder(coverageDir); }); it('should run Code coverage plugin which collects passed results and creates report.json', async () => { diff --git a/e2e/plugin-coverage-e2e/tsconfig.test.json b/e2e/plugin-coverage-e2e/tsconfig.test.json index 10c7f79de..22ad6e52a 100644 --- a/e2e/plugin-coverage-e2e/tsconfig.test.json +++ b/e2e/plugin-coverage-e2e/tsconfig.test.json @@ -5,6 +5,7 @@ "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"], "target": "ES2020" }, + "exclude": [], "include": [ "vite.config.e2e.ts", "tests/**/*.e2e.test.ts", From 6b93d248c7f4013464daa916557df0d240d9ff54 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 11 Nov 2024 19:10:53 +0100 Subject: [PATCH 49/80] wip --- .../__test-env__/.eslintrc.json | 20 ++++++++++++++ .../__test-env__/code-pushup.config.ts | 27 +++++++++++++++++++ .../__test-env__/package.json | 15 +++++++++++ .../__test-env__/project.json | 8 ++++++ .../__test-env__/src/index.js | 7 +++++ 5 files changed, 77 insertions(+) create mode 100644 e2e/plugin-eslint-e2e/__test-env__/.eslintrc.json create mode 100644 e2e/plugin-eslint-e2e/__test-env__/code-pushup.config.ts create mode 100644 e2e/plugin-eslint-e2e/__test-env__/package.json create mode 100644 e2e/plugin-eslint-e2e/__test-env__/project.json create mode 100644 e2e/plugin-eslint-e2e/__test-env__/src/index.js diff --git a/e2e/plugin-eslint-e2e/__test-env__/.eslintrc.json b/e2e/plugin-eslint-e2e/__test-env__/.eslintrc.json new file mode 100644 index 000000000..113136c93 --- /dev/null +++ b/e2e/plugin-eslint-e2e/__test-env__/.eslintrc.json @@ -0,0 +1,20 @@ +{ + "root": true, + "ignorePatterns": ["code-pushup.config.ts"], + "overrides": [ + { + "files": ["*.js"], + "env": { + "node": true + }, + "parserOptions": { + "sourceType": "script" + }, + "rules": { + "no-unused-vars": "error", + "no-console": "warn", + "no-undef": "error" + } + } + ] +} diff --git a/e2e/plugin-eslint-e2e/__test-env__/code-pushup.config.ts b/e2e/plugin-eslint-e2e/__test-env__/code-pushup.config.ts new file mode 100644 index 000000000..01feaf2ff --- /dev/null +++ b/e2e/plugin-eslint-e2e/__test-env__/code-pushup.config.ts @@ -0,0 +1,27 @@ +import eslintPlugin from '@code-pushup/eslint-plugin'; + +export default { + plugins: [ + await eslintPlugin({ + eslintrc: '.eslintrc.json', + patterns: ['src/*.js'], + }), + ], + categories: [ + { + slug: 'bug-prevention', + title: 'Bug prevention', + description: 'Lint rules that find **potential bugs** in your code.', + refs: [{ type: 'group', plugin: 'eslint', slug: 'problems', weight: 1 }], + }, + { + slug: 'code-style', + title: 'Code style', + description: + 'Lint rules that promote **good practices** and consistency in your code.', + refs: [ + { type: 'group', plugin: 'eslint', slug: 'suggestions', weight: 1 }, + ], + }, + ], +}; diff --git a/e2e/plugin-eslint-e2e/__test-env__/package.json b/e2e/plugin-eslint-e2e/__test-env__/package.json new file mode 100644 index 000000000..970508f95 --- /dev/null +++ b/e2e/plugin-eslint-e2e/__test-env__/package.json @@ -0,0 +1,15 @@ +{ + "name": "__test-env__", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@code-pushup/models": "^0.54.0" + } +} diff --git a/e2e/plugin-eslint-e2e/__test-env__/project.json b/e2e/plugin-eslint-e2e/__test-env__/project.json new file mode 100644 index 000000000..e3757a0de --- /dev/null +++ b/e2e/plugin-eslint-e2e/__test-env__/project.json @@ -0,0 +1,8 @@ +{ + "name": "eslint-e2e-env", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "static-environments/eslint-e2e-env/src", + "projectType": "library", + "targets": {}, + "tags": ["scope:internal", "type:feature"] +} diff --git a/e2e/plugin-eslint-e2e/__test-env__/src/index.js b/e2e/plugin-eslint-e2e/__test-env__/src/index.js new file mode 100644 index 000000000..4710a3767 --- /dev/null +++ b/e2e/plugin-eslint-e2e/__test-env__/src/index.js @@ -0,0 +1,7 @@ +function unusedFn() { + return '42'; +} + +module.exports = function consoleLog() { + console.log('No console.log()!'); +}; From 8d8ecc4abb5ebb05f46211731ba9f4b18c65029f Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 11 Nov 2024 19:16:27 +0100 Subject: [PATCH 50/80] wip --- e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts | 10 ++++------ e2e/plugin-eslint-e2e/tsconfig.test.json | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts index a510876b0..228b8a86d 100644 --- a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts @@ -1,4 +1,4 @@ -import { join, relative } from 'node:path'; +import { join } from 'node:path'; import { afterEach } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; import { teardownTestFolder } from '@code-pushup/test-setup'; @@ -7,20 +7,18 @@ import { executeProcess, readJsonFile } from '@code-pushup/utils'; describe('collect report with eslint-plugin NPM package', () => { const envRoot = 'e2e/plugin-eslint-e2e/__test-env__'; - const baseDir = join(envRoot); + const outputDir = join(envRoot, '.code-pushup'); afterEach(async () => { - await teardownTestFolder(baseDir); + await teardownTestFolder(outputDir); }); it('should run ESLint plugin and create report.json', async () => { - const outputDir = relative(envRoot, join(baseDir, '.code-pushup')); const { code, stderr } = await executeProcess({ command: 'npx', args: [ '@code-pushup/cli', 'collect', - `--persist.outputDir=${outputDir}`, '--no-progress', '--onlyPlugins=eslint', ], @@ -30,7 +28,7 @@ describe('collect report with eslint-plugin NPM package', () => { expect(code).toBe(0); expect(stderr).toBe(''); - const report = await readJsonFile(join(envRoot, outputDir, 'report.json')); + const report = await readJsonFile(join(outputDir, 'report.json')); expect(() => reportSchema.parse(report)).not.toThrow(); expect(omitVariableReportData(report as Report)).toMatchSnapshot(); diff --git a/e2e/plugin-eslint-e2e/tsconfig.test.json b/e2e/plugin-eslint-e2e/tsconfig.test.json index 7e4507b8b..34f35e30f 100644 --- a/e2e/plugin-eslint-e2e/tsconfig.test.json +++ b/e2e/plugin-eslint-e2e/tsconfig.test.json @@ -5,7 +5,7 @@ "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"], "target": "ES2020" }, - "exclude": ["__test-env__"], + "exclude": ["__test-env__/**"], "include": [ "vite.config.e2e.ts", "tests/**/*.e2e.test.ts", From 3334e3a1982acfc40304354c1c01ffdd294b1c9a Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 11 Nov 2024 19:26:35 +0100 Subject: [PATCH 51/80] wip --- e2e/plugin-eslint-e2e/__test-env__/package.json | 8 +++++--- nx.json | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/e2e/plugin-eslint-e2e/__test-env__/package.json b/e2e/plugin-eslint-e2e/__test-env__/package.json index 970508f95..999b66434 100644 --- a/e2e/plugin-eslint-e2e/__test-env__/package.json +++ b/e2e/plugin-eslint-e2e/__test-env__/package.json @@ -1,7 +1,6 @@ { "name": "__test-env__", "version": "1.0.0", - "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" @@ -10,6 +9,9 @@ "author": "", "license": "ISC", "dependencies": { - "@code-pushup/models": "^0.54.0" - } + "@code-pushup/eslint-plugin": "^0.54.0", + "@code-pushup/models": "^0.54.0", + "@code-pushup/utils": "^0.54.0" + }, + "description": "" } diff --git a/nx.json b/nx.json index c7603298b..105d57bc2 100644 --- a/nx.json +++ b/nx.json @@ -28,6 +28,9 @@ "e2e": { "dependsOn": ["^build"] }, + "nxv-e2e": { + "executor": "@push-based/nx-verdaccio:env-setup" + }, "nxv-env-setup": { "executor": "@push-based/nx-verdaccio:env-setup" }, From 385f0e370efd81704876eb75aa0d2918c345f70c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Chalk?= Date: Wed, 13 Nov 2024 13:00:00 +0100 Subject: [PATCH 52/80] test(plugin-eslint-e2e): fix tests by separating fixtures from test env folder --- e2e/plugin-eslint-e2e/__test-env__/package.json | 17 ----------------- e2e/plugin-eslint-e2e/__test-env__/project.json | 8 -------- .../fixtures}/.eslintrc.json | 0 .../fixtures}/code-pushup.config.ts | 0 .../fixtures}/src/index.js | 0 e2e/plugin-eslint-e2e/project.json | 4 ++-- .../__snapshots__/collect.e2e.test.ts.snap | 4 ++-- e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts | 12 +++++++++++- 8 files changed, 15 insertions(+), 30 deletions(-) delete mode 100644 e2e/plugin-eslint-e2e/__test-env__/package.json delete mode 100644 e2e/plugin-eslint-e2e/__test-env__/project.json rename e2e/plugin-eslint-e2e/{__test-env__ => mocks/fixtures}/.eslintrc.json (100%) rename e2e/plugin-eslint-e2e/{__test-env__ => mocks/fixtures}/code-pushup.config.ts (100%) rename e2e/plugin-eslint-e2e/{__test-env__ => mocks/fixtures}/src/index.js (100%) diff --git a/e2e/plugin-eslint-e2e/__test-env__/package.json b/e2e/plugin-eslint-e2e/__test-env__/package.json deleted file mode 100644 index 999b66434..000000000 --- a/e2e/plugin-eslint-e2e/__test-env__/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "__test-env__", - "version": "1.0.0", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "@code-pushup/eslint-plugin": "^0.54.0", - "@code-pushup/models": "^0.54.0", - "@code-pushup/utils": "^0.54.0" - }, - "description": "" -} diff --git a/e2e/plugin-eslint-e2e/__test-env__/project.json b/e2e/plugin-eslint-e2e/__test-env__/project.json deleted file mode 100644 index e3757a0de..000000000 --- a/e2e/plugin-eslint-e2e/__test-env__/project.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "eslint-e2e-env", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "static-environments/eslint-e2e-env/src", - "projectType": "library", - "targets": {}, - "tags": ["scope:internal", "type:feature"] -} diff --git a/e2e/plugin-eslint-e2e/__test-env__/.eslintrc.json b/e2e/plugin-eslint-e2e/mocks/fixtures/.eslintrc.json similarity index 100% rename from e2e/plugin-eslint-e2e/__test-env__/.eslintrc.json rename to e2e/plugin-eslint-e2e/mocks/fixtures/.eslintrc.json diff --git a/e2e/plugin-eslint-e2e/__test-env__/code-pushup.config.ts b/e2e/plugin-eslint-e2e/mocks/fixtures/code-pushup.config.ts similarity index 100% rename from e2e/plugin-eslint-e2e/__test-env__/code-pushup.config.ts rename to e2e/plugin-eslint-e2e/mocks/fixtures/code-pushup.config.ts diff --git a/e2e/plugin-eslint-e2e/__test-env__/src/index.js b/e2e/plugin-eslint-e2e/mocks/fixtures/src/index.js similarity index 100% rename from e2e/plugin-eslint-e2e/__test-env__/src/index.js rename to e2e/plugin-eslint-e2e/mocks/fixtures/src/index.js diff --git a/e2e/plugin-eslint-e2e/project.json b/e2e/plugin-eslint-e2e/project.json index 301f6d19a..9705c2b0e 100644 --- a/e2e/plugin-eslint-e2e/project.json +++ b/e2e/plugin-eslint-e2e/project.json @@ -13,12 +13,12 @@ }, "nxv-e2e": { "options": { - "environmentRoot": "e2e/plugin-eslint-e2e/__test-env__" + "environmentRoot": "tmp/plugin-eslint-e2e/__test-env__" } }, "nxv-env-setup": { "options": { - "environmentRoot": "e2e/plugin-eslint-e2e/__test-env__" + "environmentRoot": "tmp/plugin-eslint-e2e/__test-env__" } }, "e2e": { diff --git a/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index 39f169153..c1cfbf75f 100644 --- a/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -42,7 +42,7 @@ exports[`collect report with eslint-plugin NPM package > should run ESLint plugi "message": "'unusedFn' is defined but never used.", "severity": "error", "source": { - "file": "static-environments/eslint-e2e-env/src/index.js", + "file": "tmp/plugin-eslint-e2e/__test-env__/src/index.js", "position": { "endColumn": 18, "endLine": 1, @@ -68,7 +68,7 @@ exports[`collect report with eslint-plugin NPM package > should run ESLint plugi "message": "Unexpected console statement.", "severity": "warning", "source": { - "file": "static-environments/eslint-e2e-env/src/index.js", + "file": "tmp/plugin-eslint-e2e/__test-env__/src/index.js", "position": { "endColumn": 14, "endLine": 6, diff --git a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts index 228b8a86d..c863a1d2a 100644 --- a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts @@ -1,3 +1,4 @@ +import { cp, rm } from 'node:fs/promises'; import { join } from 'node:path'; import { afterEach } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; @@ -6,9 +7,18 @@ import { omitVariableReportData } from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; describe('collect report with eslint-plugin NPM package', () => { - const envRoot = 'e2e/plugin-eslint-e2e/__test-env__'; + const fixturesDir = join('e2e', 'plugin-eslint-e2e', 'mocks', 'fixtures'); + const envRoot = join('tmp', 'plugin-eslint-e2e', '__test-env__'); const outputDir = join(envRoot, '.code-pushup'); + beforeAll(async () => { + await cp(fixturesDir, envRoot, { recursive: true }); + }); + + afterAll(async () => { + await rm(envRoot, { recursive: true, force: true }); + }); + afterEach(async () => { await teardownTestFolder(outputDir); }); From fa90bcd5685ba7fe953ab2e08bf11722e8e47d80 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 18 Nov 2024 18:10:12 +0100 Subject: [PATCH 53/80] refactor e2e env setup --- .../fixtures/{ => old-version}/.eslintrc.json | 0 .../{ => old-version}/code-pushup.config.ts | 0 .../fixtures/{ => old-version}/src/index.js | 0 e2e/plugin-eslint-e2e/project.json | 10 ------ .../__snapshots__/collect.e2e.test.ts.snap | 4 +-- .../tests/collect.e2e.test.ts | 34 ++++++++++--------- nx.json | 3 +- 7 files changed, 22 insertions(+), 29 deletions(-) rename e2e/plugin-eslint-e2e/mocks/fixtures/{ => old-version}/.eslintrc.json (100%) rename e2e/plugin-eslint-e2e/mocks/fixtures/{ => old-version}/code-pushup.config.ts (100%) rename e2e/plugin-eslint-e2e/mocks/fixtures/{ => old-version}/src/index.js (100%) diff --git a/e2e/plugin-eslint-e2e/mocks/fixtures/.eslintrc.json b/e2e/plugin-eslint-e2e/mocks/fixtures/old-version/.eslintrc.json similarity index 100% rename from e2e/plugin-eslint-e2e/mocks/fixtures/.eslintrc.json rename to e2e/plugin-eslint-e2e/mocks/fixtures/old-version/.eslintrc.json diff --git a/e2e/plugin-eslint-e2e/mocks/fixtures/code-pushup.config.ts b/e2e/plugin-eslint-e2e/mocks/fixtures/old-version/code-pushup.config.ts similarity index 100% rename from e2e/plugin-eslint-e2e/mocks/fixtures/code-pushup.config.ts rename to e2e/plugin-eslint-e2e/mocks/fixtures/old-version/code-pushup.config.ts diff --git a/e2e/plugin-eslint-e2e/mocks/fixtures/src/index.js b/e2e/plugin-eslint-e2e/mocks/fixtures/old-version/src/index.js similarity index 100% rename from e2e/plugin-eslint-e2e/mocks/fixtures/src/index.js rename to e2e/plugin-eslint-e2e/mocks/fixtures/old-version/src/index.js diff --git a/e2e/plugin-eslint-e2e/project.json b/e2e/plugin-eslint-e2e/project.json index 9705c2b0e..4a23956d0 100644 --- a/e2e/plugin-eslint-e2e/project.json +++ b/e2e/plugin-eslint-e2e/project.json @@ -11,16 +11,6 @@ "lintFilePatterns": ["e2e/plugin-eslint-e2e/**/*.ts"] } }, - "nxv-e2e": { - "options": { - "environmentRoot": "tmp/plugin-eslint-e2e/__test-env__" - } - }, - "nxv-env-setup": { - "options": { - "environmentRoot": "tmp/plugin-eslint-e2e/__test-env__" - } - }, "e2e": { "executor": "@nx/vite:test", "options": { diff --git a/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index c1cfbf75f..ea1b4434e 100644 --- a/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -42,7 +42,7 @@ exports[`collect report with eslint-plugin NPM package > should run ESLint plugi "message": "'unusedFn' is defined but never used.", "severity": "error", "source": { - "file": "tmp/plugin-eslint-e2e/__test-env__/src/index.js", + "file": "tmp/e2e/plugin-eslint-e2e/old-version/src/index.js", "position": { "endColumn": 18, "endLine": 1, @@ -68,7 +68,7 @@ exports[`collect report with eslint-plugin NPM package > should run ESLint plugi "message": "Unexpected console statement.", "severity": "warning", "source": { - "file": "tmp/plugin-eslint-e2e/__test-env__/src/index.js", + "file": "tmp/e2e/plugin-eslint-e2e/old-version/src/index.js", "position": { "endColumn": 14, "endLine": 6, diff --git a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts index c863a1d2a..784f54056 100644 --- a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts @@ -1,44 +1,46 @@ -import { cp, rm } from 'node:fs/promises'; +import { cp } from 'node:fs/promises'; import { join } from 'node:path'; -import { afterEach } from 'vitest'; +import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; import { teardownTestFolder } from '@code-pushup/test-setup'; import { omitVariableReportData } from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; describe('collect report with eslint-plugin NPM package', () => { - const fixturesDir = join('e2e', 'plugin-eslint-e2e', 'mocks', 'fixtures'); - const envRoot = join('tmp', 'plugin-eslint-e2e', '__test-env__'); - const outputDir = join(envRoot, '.code-pushup'); + const fixturesOldVersionDir = join( + 'e2e', + 'plugin-eslint-e2e', + 'mocks', + 'fixtures', + 'old-version', + ); + const envRoot = join('tmp', 'e2e', 'plugin-eslint-e2e'); + const oldVersionDir = join(envRoot, 'old-version'); + const oldVersionOutputDir = join(oldVersionDir, '.code-pushup'); beforeAll(async () => { - await cp(fixturesDir, envRoot, { recursive: true }); + await cp(fixturesOldVersionDir, oldVersionDir, { recursive: true }); }); afterAll(async () => { - await rm(envRoot, { recursive: true, force: true }); + await teardownTestFolder(oldVersionDir); }); afterEach(async () => { - await teardownTestFolder(outputDir); + await teardownTestFolder(oldVersionOutputDir); }); it('should run ESLint plugin and create report.json', async () => { const { code, stderr } = await executeProcess({ command: 'npx', - args: [ - '@code-pushup/cli', - 'collect', - '--no-progress', - '--onlyPlugins=eslint', - ], - cwd: envRoot, + args: ['@code-pushup/cli', 'collect', '--no-progress'], + cwd: oldVersionDir, }); expect(code).toBe(0); expect(stderr).toBe(''); - const report = await readJsonFile(join(outputDir, 'report.json')); + const report = await readJsonFile(join(oldVersionOutputDir, 'report.json')); expect(() => reportSchema.parse(report)).not.toThrow(); expect(omitVariableReportData(report as Report)).toMatchSnapshot(); diff --git a/nx.json b/nx.json index 105d57bc2..674b3b559 100644 --- a/nx.json +++ b/nx.json @@ -29,9 +29,10 @@ "dependsOn": ["^build"] }, "nxv-e2e": { - "executor": "@push-based/nx-verdaccio:env-setup" + "executor": "@push-based/nx-verdaccio:env-teardown" }, "nxv-env-setup": { + "cache": true, "executor": "@push-based/nx-verdaccio:env-setup" }, "@nx/vite:test": { From ded72c012de5c3c189c4e3a399d680a3bbb756cf Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 18 Nov 2024 18:36:40 +0100 Subject: [PATCH 54/80] refactor e2e env setup --- .../__test-env__/.gitignore | 3 -- .../__test-env__/project.json | 8 ---- .../basic-setup}/code-pushup.config.ts | 0 .../fixtures/basic-setup}/package.json | 4 -- .../fixtures/basic-setup}/src/index.mjs | 0 .../fixtures/basic-setup}/src/index.test.mjs | 0 .../fixtures/basic-setup}/vite.config.ts | 0 .../existing-report/code-pushup.config.ts} | 2 +- .../existing-report/coverage}/lcov.info | 0 e2e/plugin-coverage-e2e/project.json | 10 ----- .../tests/collect.e2e.test.ts | 42 +++++++++---------- 11 files changed, 22 insertions(+), 47 deletions(-) delete mode 100644 e2e/plugin-coverage-e2e/__test-env__/.gitignore delete mode 100644 e2e/plugin-coverage-e2e/__test-env__/project.json rename e2e/plugin-coverage-e2e/{__test-env__ => mocks/fixtures/basic-setup}/code-pushup.config.ts (100%) rename e2e/plugin-coverage-e2e/{__test-env__ => mocks/fixtures/basic-setup}/package.json (60%) rename e2e/plugin-coverage-e2e/{__test-env__ => mocks/fixtures/basic-setup}/src/index.mjs (100%) rename e2e/plugin-coverage-e2e/{__test-env__ => mocks/fixtures/basic-setup}/src/index.test.mjs (100%) rename e2e/plugin-coverage-e2e/{__test-env__ => mocks/fixtures/basic-setup}/vite.config.ts (100%) rename e2e/plugin-coverage-e2e/{__test-env__/code-pushup.existing-report.config.ts => mocks/fixtures/existing-report/code-pushup.config.ts} (89%) rename e2e/plugin-coverage-e2e/{__test-env__/mocks/fixtures => mocks/fixtures/existing-report/coverage}/lcov.info (100%) diff --git a/e2e/plugin-coverage-e2e/__test-env__/.gitignore b/e2e/plugin-coverage-e2e/__test-env__/.gitignore deleted file mode 100644 index 9e76e5c81..000000000 --- a/e2e/plugin-coverage-e2e/__test-env__/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -coverage -node_modules -.code-pushup diff --git a/e2e/plugin-coverage-e2e/__test-env__/project.json b/e2e/plugin-coverage-e2e/__test-env__/project.json deleted file mode 100644 index 4a70f3435..000000000 --- a/e2e/plugin-coverage-e2e/__test-env__/project.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "coverage-e2e-env", - "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "static-environments/coverage-e2e-env/src", - "projectType": "library", - "targets": {}, - "tags": ["scope:internal", "type:feature"] -} diff --git a/e2e/plugin-coverage-e2e/__test-env__/code-pushup.config.ts b/e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/code-pushup.config.ts similarity index 100% rename from e2e/plugin-coverage-e2e/__test-env__/code-pushup.config.ts rename to e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/code-pushup.config.ts diff --git a/e2e/plugin-coverage-e2e/__test-env__/package.json b/e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/package.json similarity index 60% rename from e2e/plugin-coverage-e2e/__test-env__/package.json rename to e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/package.json index ac964b1c9..61a96ca4c 100644 --- a/e2e/plugin-coverage-e2e/__test-env__/package.json +++ b/e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/package.json @@ -9,10 +9,6 @@ "author": "", "license": "ISC", "dependencies": { - "@code-pushup/core": "^0.54.0", - "@code-pushup/coverage-plugin": "^0.54.0", - "@code-pushup/models": "^0.54.0", - "@code-pushup/utils": "^0.54.0" }, "description": "" } diff --git a/e2e/plugin-coverage-e2e/__test-env__/src/index.mjs b/e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/src/index.mjs similarity index 100% rename from e2e/plugin-coverage-e2e/__test-env__/src/index.mjs rename to e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/src/index.mjs diff --git a/e2e/plugin-coverage-e2e/__test-env__/src/index.test.mjs b/e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/src/index.test.mjs similarity index 100% rename from e2e/plugin-coverage-e2e/__test-env__/src/index.test.mjs rename to e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/src/index.test.mjs diff --git a/e2e/plugin-coverage-e2e/__test-env__/vite.config.ts b/e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/vite.config.ts similarity index 100% rename from e2e/plugin-coverage-e2e/__test-env__/vite.config.ts rename to e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/vite.config.ts diff --git a/e2e/plugin-coverage-e2e/__test-env__/code-pushup.existing-report.config.ts b/e2e/plugin-coverage-e2e/mocks/fixtures/existing-report/code-pushup.config.ts similarity index 89% rename from e2e/plugin-coverage-e2e/__test-env__/code-pushup.existing-report.config.ts rename to e2e/plugin-coverage-e2e/mocks/fixtures/existing-report/code-pushup.config.ts index 9f6fffbb8..d955bbba0 100644 --- a/e2e/plugin-coverage-e2e/__test-env__/code-pushup.existing-report.config.ts +++ b/e2e/plugin-coverage-e2e/mocks/fixtures/existing-report/code-pushup.config.ts @@ -5,7 +5,7 @@ import type { CoreConfig } from '@code-pushup/models'; export default { plugins: [ await coveragePlugin({ - reports: [join('mocks', 'fixtures', 'lcov.info')], + reports: [join('coverage', 'lcov.info')], }), ], categories: [ diff --git a/e2e/plugin-coverage-e2e/__test-env__/mocks/fixtures/lcov.info b/e2e/plugin-coverage-e2e/mocks/fixtures/existing-report/coverage/lcov.info similarity index 100% rename from e2e/plugin-coverage-e2e/__test-env__/mocks/fixtures/lcov.info rename to e2e/plugin-coverage-e2e/mocks/fixtures/existing-report/coverage/lcov.info diff --git a/e2e/plugin-coverage-e2e/project.json b/e2e/plugin-coverage-e2e/project.json index 14dd9ca93..8a0932adf 100644 --- a/e2e/plugin-coverage-e2e/project.json +++ b/e2e/plugin-coverage-e2e/project.json @@ -11,16 +11,6 @@ "lintFilePatterns": ["e2e/plugin-coverage-e2e/**/*.ts"] } }, - "nxv-e2e": { - "options": { - "environmentRoot": "e2e/plugin-coverage-e2e/__test-env__" - } - }, - "nxv-env-setup": { - "options": { - "environmentRoot": "e2e/plugin-coverage-e2e/__test-env__" - } - }, "e2e": { "executor": "@nx/vite:test", "options": { diff --git a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts index dd7081fa5..b5c285d44 100644 --- a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts @@ -1,36 +1,41 @@ +import { cp } from 'node:fs/promises'; import { join } from 'node:path'; -import { afterEach } from 'vitest'; +import { afterAll, afterEach, beforeAll } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; import { teardownTestFolder } from '@code-pushup/test-setup'; import { omitVariableReportData } from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; describe('collect report with coverage-plugin NPM package', () => { - const envRoot = 'e2e/plugin-coverage-e2e/__test-env__'; - const coverageDir = join(envRoot, '.code-pushup'); + const envRoot = 'tmp/e2e/plugin-coverage-e2e'; + const fixtureDir = join('e2e', 'plugin-coverage-e2e', 'mocks', 'fixtures'); + const basicDir = join(envRoot, 'basic-setup'); + const existingDir = join(envRoot, 'existing-setup'); + beforeAll(async () => { + await cp(fixtureDir, envRoot, { recursive: true }); + }); + afterAll(async () => { + await teardownTestFolder(join(basicDir)); + await teardownTestFolder(join(existingDir)); + }); afterEach(async () => { - await teardownTestFolder(coverageDir); + await teardownTestFolder(join(basicDir, '.code-pushup')); + await teardownTestFolder(join(existingDir, '.code-pushup')); }); it('should run Code coverage plugin which collects passed results and creates report.json', async () => { const { code, stderr } = await executeProcess({ command: 'npx', - args: [ - '@code-pushup/cli', - 'collect', - '--no-progress', - `--config=code-pushup.existing-report.config.ts`, - '--onlyPlugins=coverage', - ], - cwd: envRoot, + args: ['@code-pushup/cli', 'collect', '--no-progress'], + cwd: basicDir, }); expect(code).toBe(0); expect(stderr).toBe(''); const report = await readJsonFile( - join(envRoot, '.code-pushup', 'report.json'), + join(basicDir, '.code-pushup', 'report.json'), ); expect(() => reportSchema.parse(report)).not.toThrow(); @@ -40,20 +45,15 @@ describe('collect report with coverage-plugin NPM package', () => { it('should run Code coverage plugin that runs coverage tool and creates report.json', async () => { const { code, stderr } = await executeProcess({ command: 'npx', - args: [ - '@code-pushup/cli', - 'collect', - '--no-progress', - '--onlyPlugins=coverage', - ], - cwd: envRoot, + args: ['@code-pushup/cli', 'collect', '--no-progress'], + cwd: existingDir, }); expect(code).toBe(0); expect(stderr).toBe(''); const report = await readJsonFile( - join(envRoot, '.code-pushup/report.json'), + join(existingDir, '.code-pushup', 'report.json'), ); expect(() => reportSchema.parse(report)).not.toThrow(); From cb4e0f903e0160753f4e9be5e0965aa200e9df9a Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 18 Nov 2024 18:40:08 +0100 Subject: [PATCH 55/80] cleanup env setup --- .../__snapshots__/collect.e2e.test.ts.snap | 164 +++++++++--------- .../tests/collect.e2e.test.ts | 2 +- 2 files changed, 83 insertions(+), 83 deletions(-) diff --git a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index 610e3b0a3..d15a8626b 100644 --- a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -25,10 +25,20 @@ exports[`collect report with coverage-plugin NPM package > should run Code cover "details": { "issues": [ { - "message": "Function untested is not called in any test case.", + "message": "Function formatReportScore is not called in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/partly-covered/utils.ts", + "position": { + "startLine": 2, + }, + }, + }, + { + "message": "Function sortReport is not called in any test case.", "severity": "error", "source": { - "file": "static-environments/coverage-e2e-env/src/index.mjs", + "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/not-covered/sorting.ts", "position": { "startLine": 1, }, @@ -36,67 +46,97 @@ exports[`collect report with coverage-plugin NPM package > should run Code cover }, ], }, - "displayValue": "66.7 %", - "score": 0.6667, + "displayValue": "60 %", + "score": 0.6, "slug": "function-coverage", "title": "Function coverage", - "value": 66.66666666666666, + "value": 60, }, { "description": "Measures how many branches were executed after conditional statements in at least one test.", "details": { "issues": [ { - "message": "1st branch is not taken in any test case.", + "message": "2nd branch is not taken in any test case.", "severity": "error", "source": { - "file": "static-environments/coverage-e2e-env/src/index.mjs", + "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/partly-covered/utils.ts", + "position": { + "startLine": 6, + }, + }, + }, + { + "message": "2nd branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/partly-covered/utils.ts", "position": { "startLine": 10, }, }, }, + { + "message": "1st branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/not-covered/sorting.ts", + "position": { + "startLine": 7, + }, + }, + }, + { + "message": "2nd branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/not-covered/sorting.ts", + "position": { + "startLine": 7, + }, + }, + }, ], }, - "displayValue": "66.7 %", - "score": 0.6667, + "displayValue": "76.5 %", + "score": 0.7647, "slug": "branch-coverage", "title": "Branch coverage", - "value": 66.66666666666666, + "value": 76.47058823529412, }, { "description": "Measures how many lines of code were executed in at least one test.", "details": { "issues": [ { - "message": "Lines 2-3 are not covered in any test case.", + "message": "Lines 7-9 are not covered in any test case.", "severity": "warning", "source": { - "file": "static-environments/coverage-e2e-env/src/index.mjs", + "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/partly-covered/utils.ts", "position": { - "endLine": 3, - "startLine": 2, + "endLine": 9, + "startLine": 7, }, }, }, { - "message": "Lines 11-12 are not covered in any test case.", + "message": "Lines 1-5 are not covered in any test case.", "severity": "warning", "source": { - "file": "static-environments/coverage-e2e-env/src/index.mjs", + "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/not-covered/sorting.ts", "position": { - "endLine": 12, - "startLine": 11, + "endLine": 5, + "startLine": 1, }, }, }, ], }, - "displayValue": "73.3 %", - "score": 0.7333, + "displayValue": "68 %", + "score": 0.68, "slug": "line-coverage", "title": "Line coverage", - "value": 73.33333333333333, + "value": 68, }, ], "description": "Official Code PushUp code coverage plugin.", @@ -156,20 +196,10 @@ exports[`collect report with coverage-plugin NPM package > should run Code cover "details": { "issues": [ { - "message": "Function formatReportScore is not called in any test case.", - "severity": "error", - "source": { - "file": "static-environments/coverage-e2e-env/src/lib/partly-covered/utils.ts", - "position": { - "startLine": 2, - }, - }, - }, - { - "message": "Function sortReport is not called in any test case.", + "message": "Function untested is not called in any test case.", "severity": "error", "source": { - "file": "static-environments/coverage-e2e-env/src/lib/not-covered/sorting.ts", + "file": "tmp/e2e/plugin-coverage-e2e/basic-setup/src/index.mjs", "position": { "startLine": 1, }, @@ -177,97 +207,67 @@ exports[`collect report with coverage-plugin NPM package > should run Code cover }, ], }, - "displayValue": "60 %", - "score": 0.6, + "displayValue": "66.7 %", + "score": 0.6667, "slug": "function-coverage", "title": "Function coverage", - "value": 60, + "value": 66.66666666666666, }, { "description": "Measures how many branches were executed after conditional statements in at least one test.", "details": { "issues": [ - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "static-environments/coverage-e2e-env/src/lib/partly-covered/utils.ts", - "position": { - "startLine": 6, - }, - }, - }, - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "static-environments/coverage-e2e-env/src/lib/partly-covered/utils.ts", - "position": { - "startLine": 10, - }, - }, - }, { "message": "1st branch is not taken in any test case.", "severity": "error", "source": { - "file": "static-environments/coverage-e2e-env/src/lib/not-covered/sorting.ts", + "file": "tmp/e2e/plugin-coverage-e2e/basic-setup/src/index.mjs", "position": { - "startLine": 7, - }, - }, - }, - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "static-environments/coverage-e2e-env/src/lib/not-covered/sorting.ts", - "position": { - "startLine": 7, + "startLine": 10, }, }, }, ], }, - "displayValue": "76.5 %", - "score": 0.7647, + "displayValue": "66.7 %", + "score": 0.6667, "slug": "branch-coverage", "title": "Branch coverage", - "value": 76.47058823529412, + "value": 66.66666666666666, }, { "description": "Measures how many lines of code were executed in at least one test.", "details": { "issues": [ { - "message": "Lines 7-9 are not covered in any test case.", + "message": "Lines 2-3 are not covered in any test case.", "severity": "warning", "source": { - "file": "static-environments/coverage-e2e-env/src/lib/partly-covered/utils.ts", + "file": "tmp/e2e/plugin-coverage-e2e/basic-setup/src/index.mjs", "position": { - "endLine": 9, - "startLine": 7, + "endLine": 3, + "startLine": 2, }, }, }, { - "message": "Lines 1-5 are not covered in any test case.", + "message": "Lines 11-12 are not covered in any test case.", "severity": "warning", "source": { - "file": "static-environments/coverage-e2e-env/src/lib/not-covered/sorting.ts", + "file": "tmp/e2e/plugin-coverage-e2e/basic-setup/src/index.mjs", "position": { - "endLine": 5, - "startLine": 1, + "endLine": 12, + "startLine": 11, }, }, }, ], }, - "displayValue": "68 %", - "score": 0.68, + "displayValue": "73.3 %", + "score": 0.7333, "slug": "line-coverage", "title": "Line coverage", - "value": 68, + "value": 73.33333333333333, }, ], "description": "Official Code PushUp code coverage plugin.", diff --git a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts index b5c285d44..2a7fa6a08 100644 --- a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts @@ -10,7 +10,7 @@ describe('collect report with coverage-plugin NPM package', () => { const envRoot = 'tmp/e2e/plugin-coverage-e2e'; const fixtureDir = join('e2e', 'plugin-coverage-e2e', 'mocks', 'fixtures'); const basicDir = join(envRoot, 'basic-setup'); - const existingDir = join(envRoot, 'existing-setup'); + const existingDir = join(envRoot, 'existing-report'); beforeAll(async () => { await cp(fixtureDir, envRoot, { recursive: true }); From 22a6908554090ad5286b33d3add7110af477f04b Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 18 Nov 2024 18:45:17 +0100 Subject: [PATCH 56/80] fix snapshots --- .../__snapshots__/collect.e2e.test.ts.snap | 420 ------------------ 1 file changed, 420 deletions(-) diff --git a/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index 47a9e0f07..35945e037 100644 --- a/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -1,425 +1,5 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`CLI collect > should run Code coverage plugin that runs coverage tool and creates report.json 1`] = ` -{ - "categories": [ - { - "refs": [ - { - "plugin": "coverage", - "slug": "coverage", - "type": "group", - "weight": 1, - }, - ], - "slug": "code-coverage", - "title": "Code coverage", - }, - ], - "packageName": "@code-pushup/core", - "plugins": [ - { - "audits": [ - { - "description": "Measures how many functions were called in at least one test.", - "details": { - "issues": [ - { - "message": "Function onSubmit is not called in any test case.", - "severity": "error", - "source": { - "file": "examples/react-todos-app/src/components/CreateTodo.jsx", - "position": { - "startLine": 13, - }, - }, - }, - { - "message": "Function onInput is not called in any test case.", - "severity": "error", - "source": { - "file": "examples/react-todos-app/src/components/CreateTodo.jsx", - "position": { - "startLine": 21, - }, - }, - }, - { - "message": "Function onInput is not called in any test case.", - "severity": "error", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "startLine": 9, - }, - }, - }, - { - "message": "Function onChange is not called in any test case.", - "severity": "error", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "startLine": 17, - }, - }, - }, - ], - }, - "displayValue": "55.6 %", - "score": 0.5556, - "slug": "function-coverage", - "title": "Function coverage", - "value": 55.55555555555556, - }, - { - "description": "Measures how many branches were executed after conditional statements in at least one test.", - "details": { - "issues": [ - { - "message": "1st branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "examples/react-todos-app/src/index.jsx", - "position": { - "startLine": 1, - }, - }, - }, - ], - }, - "displayValue": "87.5 %", - "score": 0.875, - "slug": "branch-coverage", - "title": "Branch coverage", - "value": 87.5, - }, - { - "description": "Measures how many lines of code were executed in at least one test.", - "details": { - "issues": [ - { - "message": "Lines 1-6 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/index.jsx", - "position": { - "endLine": 6, - "startLine": 1, - }, - }, - }, - { - "message": "Lines 14-17 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/CreateTodo.jsx", - "position": { - "endLine": 17, - "startLine": 14, - }, - }, - }, - { - "message": "Lines 22-23 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/CreateTodo.jsx", - "position": { - "endLine": 23, - "startLine": 22, - }, - }, - }, - { - "message": "Lines 10-11 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "endLine": 11, - "startLine": 10, - }, - }, - }, - { - "message": "Lines 18-19 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoFilter.jsx", - "position": { - "endLine": 19, - "startLine": 18, - }, - }, - }, - { - "message": "Lines 7-28 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/components/TodoList.jsx", - "position": { - "endLine": 28, - "startLine": 7, - }, - }, - }, - { - "message": "Lines 12-13 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endLine": 13, - "startLine": 12, - }, - }, - }, - { - "message": "Lines 18-37 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endLine": 37, - "startLine": 18, - }, - }, - }, - { - "message": "Lines 41-45 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endLine": 45, - "startLine": 41, - }, - }, - }, - { - "message": "Lines 54-60 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "examples/react-todos-app/src/hooks/useTodos.js", - "position": { - "endLine": 60, - "startLine": 54, - }, - }, - }, - ], - }, - "displayValue": "62.1 %", - "score": 0.6211, - "slug": "line-coverage", - "title": "Line coverage", - "value": 62.10526315789474, - }, - ], - "description": "Official Code PushUp code coverage plugin.", - "docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/", - "groups": [ - { - "description": "Group containing all defined coverage types as audits.", - "refs": [ - { - "slug": "function-coverage", - "weight": 6, - }, - { - "slug": "branch-coverage", - "weight": 3, - }, - { - "slug": "line-coverage", - "weight": 1, - }, - ], - "slug": "coverage", - "title": "Code coverage metrics", - }, - ], - "icon": "folder-coverage-open", - "packageName": "@code-pushup/coverage-plugin", - "slug": "coverage", - "title": "Code coverage", - }, - ], -} -`; - -exports[`CLI collect > should run Code coverage plugin which collects passed results and creates report.json 1`] = ` -{ - "categories": [ - { - "refs": [ - { - "plugin": "coverage", - "slug": "coverage", - "type": "group", - "weight": 1, - }, - ], - "slug": "code-coverage", - "title": "Code coverage", - }, - ], - "packageName": "@code-pushup/core", - "plugins": [ - { - "audits": [ - { - "description": "Measures how many functions were called in at least one test.", - "details": { - "issues": [ - { - "message": "Function formatReportScore is not called in any test case.", - "severity": "error", - "source": { - "file": "src/lib/partly-covered/utils.ts", - "position": { - "startLine": 2, - }, - }, - }, - { - "message": "Function sortReport is not called in any test case.", - "severity": "error", - "source": { - "file": "src/lib/not-covered/sorting.ts", - "position": { - "startLine": 1, - }, - }, - }, - ], - }, - "displayValue": "60 %", - "score": 0.6, - "slug": "function-coverage", - "title": "Function coverage", - "value": 60, - }, - { - "description": "Measures how many branches were executed after conditional statements in at least one test.", - "details": { - "issues": [ - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "src/lib/partly-covered/utils.ts", - "position": { - "startLine": 6, - }, - }, - }, - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "src/lib/partly-covered/utils.ts", - "position": { - "startLine": 10, - }, - }, - }, - { - "message": "1st branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "src/lib/not-covered/sorting.ts", - "position": { - "startLine": 7, - }, - }, - }, - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "src/lib/not-covered/sorting.ts", - "position": { - "startLine": 7, - }, - }, - }, - ], - }, - "displayValue": "76.5 %", - "score": 0.7647, - "slug": "branch-coverage", - "title": "Branch coverage", - "value": 76.47058823529412, - }, - { - "description": "Measures how many lines of code were executed in at least one test.", - "details": { - "issues": [ - { - "message": "Lines 7-9 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "src/lib/partly-covered/utils.ts", - "position": { - "endLine": 9, - "startLine": 7, - }, - }, - }, - { - "message": "Lines 1-5 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "src/lib/not-covered/sorting.ts", - "position": { - "endLine": 5, - "startLine": 1, - }, - }, - }, - ], - }, - "displayValue": "68 %", - "score": 0.68, - "slug": "line-coverage", - "title": "Line coverage", - "value": 68, - }, - ], - "description": "Official Code PushUp code coverage plugin.", - "docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/", - "groups": [ - { - "description": "Group containing all defined coverage types as audits.", - "refs": [ - { - "slug": "function-coverage", - "weight": 6, - }, - { - "slug": "branch-coverage", - "weight": 3, - }, - { - "slug": "line-coverage", - "weight": 1, - }, - ], - "slug": "coverage", - "title": "Code coverage metrics", - }, - ], - "icon": "folder-coverage-open", - "packageName": "@code-pushup/coverage-plugin", - "slug": "coverage", - "title": "Code coverage", - }, - ], -} -`; - exports[`CLI collect > should run ESLint plugin and create report.json 1`] = ` { "categories": [ From 0a477cbb6469f316be39eae23b5cedc8a9394d98 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 18 Nov 2024 18:50:25 +0100 Subject: [PATCH 57/80] remove check for warning and error --- e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts index 2a7fa6a08..c4e387910 100644 --- a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts @@ -25,14 +25,13 @@ describe('collect report with coverage-plugin NPM package', () => { }); it('should run Code coverage plugin which collects passed results and creates report.json', async () => { - const { code, stderr } = await executeProcess({ + const { code } = await executeProcess({ command: 'npx', args: ['@code-pushup/cli', 'collect', '--no-progress'], cwd: basicDir, }); expect(code).toBe(0); - expect(stderr).toBe(''); const report = await readJsonFile( join(basicDir, '.code-pushup', 'report.json'), @@ -43,14 +42,13 @@ describe('collect report with coverage-plugin NPM package', () => { }); it('should run Code coverage plugin that runs coverage tool and creates report.json', async () => { - const { code, stderr } = await executeProcess({ + const { code } = await executeProcess({ command: 'npx', args: ['@code-pushup/cli', 'collect', '--no-progress'], cwd: existingDir, }); expect(code).toBe(0); - expect(stderr).toBe(''); const report = await readJsonFile( join(existingDir, '.code-pushup', 'report.json'), From 1b066e0a2f0826fbded3dd459d0856b3c7f351fb Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Mon, 18 Nov 2024 19:18:13 +0100 Subject: [PATCH 58/80] Update .github/workflows/ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a8ad36da1..af4732928 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,7 +120,7 @@ jobs: - name: Install dependencies run: npm ci - name: E2E test affected projects - run: npx nx affected -t nxv-e2e --exclude cli-e2e --parallel=1 --verbose + run: npx nx affected -t nxv-e2e --exclude cli-e2e --parallel=1 - name: E2E test cli-e2e project (due to bugs in the setup it has to run last :( ) run: npx nx run cli-e2e:e2e-old From d165dddb44cd5d32107e984c99803d0641c02744 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Mon, 18 Nov 2024 19:18:26 +0100 Subject: [PATCH 59/80] Update .github/workflows/ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af4732928..845def216 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,7 +120,7 @@ jobs: - name: Install dependencies run: npm ci - name: E2E test affected projects - run: npx nx affected -t nxv-e2e --exclude cli-e2e --parallel=1 + run: npx nx affected -t nxv-e2e --exclude cli-e2e --parallel=1 - name: E2E test cli-e2e project (due to bugs in the setup it has to run last :( ) run: npx nx run cli-e2e:e2e-old From acc59939dd76cf2dad25a628e7508908914762f7 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 18 Nov 2024 21:31:56 +0100 Subject: [PATCH 60/80] clean up merge --- e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap diff --git a/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap deleted file mode 100644 index 7424fd045..000000000 --- a/e2e/cli-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ /dev/null @@ -1,2 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - From d7964e8e3d15fdec72b90fddb4afdebe68edb5e6 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 18 Nov 2024 22:21:50 +0100 Subject: [PATCH 61/80] refactor env setup --- .../dummy-setup}/code-pushup.config.js | 0 .../dummy-setup}/code-pushup.config.mjs | 0 .../dummy-setup}/code-pushup.config.ts | 0 .../fixtures/dummy-setup}/dummy.plugin.ts | 0 .../fixtures/dummy-setup}/src/items.json | 0 e2e/cli-e2e/project.json | 12 +---- e2e/cli-e2e/tests/collect.e2e.test.ts | 36 +++++++++----- e2e/cli-e2e/tests/compare.e2e.test.ts | 47 +++++++++++++------ e2e/cli-e2e/tests/help.e2e.test.ts | 2 +- e2e/cli-e2e/tests/print-config.e2e.test.ts | 33 ++++++++++--- nx.json | 2 +- static-environments/cli-e2e-env/package.json | 16 ++++--- static-environments/cli-e2e-env/project.json | 22 --------- 13 files changed, 96 insertions(+), 74 deletions(-) rename {static-environments/cli-e2e-env => e2e/cli-e2e/mocks/fixtures/dummy-setup}/code-pushup.config.js (100%) rename {static-environments/cli-e2e-env => e2e/cli-e2e/mocks/fixtures/dummy-setup}/code-pushup.config.mjs (100%) rename {static-environments/cli-e2e-env => e2e/cli-e2e/mocks/fixtures/dummy-setup}/code-pushup.config.ts (100%) rename {static-environments/cli-e2e-env => e2e/cli-e2e/mocks/fixtures/dummy-setup}/dummy.plugin.ts (100%) rename {static-environments/cli-e2e-env => e2e/cli-e2e/mocks/fixtures/dummy-setup}/src/items.json (100%) delete mode 100644 static-environments/cli-e2e-env/project.json diff --git a/static-environments/cli-e2e-env/code-pushup.config.js b/e2e/cli-e2e/mocks/fixtures/dummy-setup/code-pushup.config.js similarity index 100% rename from static-environments/cli-e2e-env/code-pushup.config.js rename to e2e/cli-e2e/mocks/fixtures/dummy-setup/code-pushup.config.js diff --git a/static-environments/cli-e2e-env/code-pushup.config.mjs b/e2e/cli-e2e/mocks/fixtures/dummy-setup/code-pushup.config.mjs similarity index 100% rename from static-environments/cli-e2e-env/code-pushup.config.mjs rename to e2e/cli-e2e/mocks/fixtures/dummy-setup/code-pushup.config.mjs diff --git a/static-environments/cli-e2e-env/code-pushup.config.ts b/e2e/cli-e2e/mocks/fixtures/dummy-setup/code-pushup.config.ts similarity index 100% rename from static-environments/cli-e2e-env/code-pushup.config.ts rename to e2e/cli-e2e/mocks/fixtures/dummy-setup/code-pushup.config.ts diff --git a/static-environments/cli-e2e-env/dummy.plugin.ts b/e2e/cli-e2e/mocks/fixtures/dummy-setup/dummy.plugin.ts similarity index 100% rename from static-environments/cli-e2e-env/dummy.plugin.ts rename to e2e/cli-e2e/mocks/fixtures/dummy-setup/dummy.plugin.ts diff --git a/static-environments/cli-e2e-env/src/items.json b/e2e/cli-e2e/mocks/fixtures/dummy-setup/src/items.json similarity index 100% rename from static-environments/cli-e2e-env/src/items.json rename to e2e/cli-e2e/mocks/fixtures/dummy-setup/src/items.json diff --git a/e2e/cli-e2e/project.json b/e2e/cli-e2e/project.json index 964a19f81..d06a9fbea 100644 --- a/e2e/cli-e2e/project.json +++ b/e2e/cli-e2e/project.json @@ -11,16 +11,6 @@ "lintFilePatterns": ["e2e/cli-e2e/**/*.ts"] } }, - "nxv-e2e": { - "options": { - "environmentRoot": "static-environments/cli-e2e-env" - } - }, - "nxv-env-setup": { - "options": { - "environmentRoot": "static-environments/cli-e2e-env" - } - }, "e2e": { "executor": "@nx/vite:test", "options": { @@ -28,6 +18,6 @@ } } }, - "implicitDependencies": ["cli", "cli-e2e-env"], + "implicitDependencies": ["cli"], "tags": ["scope:core", "scope:plugin", "type:e2e"] } diff --git a/e2e/cli-e2e/tests/collect.e2e.test.ts b/e2e/cli-e2e/tests/collect.e2e.test.ts index cabc810be..c66097212 100644 --- a/e2e/cli-e2e/tests/collect.e2e.test.ts +++ b/e2e/cli-e2e/tests/collect.e2e.test.ts @@ -1,20 +1,34 @@ +import { cp } from 'node:fs/promises'; import { join } from 'node:path'; -import { afterEach } from 'vitest'; -import { cleanTestFolder, teardownTestFolder } from '@code-pushup/test-setup'; +import { afterEach, beforeAll, describe, expect, it } from 'vitest'; +import { teardownTestFolder } from '@code-pushup/test-setup'; import { executeProcess, readTextFile } from '@code-pushup/utils'; describe('CLI collect', () => { const dummyPluginTitle = 'Dummy Plugin'; const dummyAuditTitle = 'Dummy Audit'; - const envRoot = join('static-environments', 'cli-e2e-env'); - const baseDir = join(envRoot, '.code-pushup'); + const fixtureDummyDir = join( + 'e2e', + 'cli-e2e', + 'mocks', + 'fixtures', + 'dummy-setup', + ); + const envRoot = join('tmp', 'e2e', 'cli-e2e'); + const testFileDir = join(envRoot, 'collect'); + const dummyDir = join(testFileDir, 'dummy-setup'); + const dummyOutputDir = join(dummyDir, '.code-pushup'); - afterEach(async () => { - await teardownTestFolder(baseDir); + beforeAll(async () => { + await cp(fixtureDummyDir, dummyDir, { recursive: true }); + }); + + afterAll(async () => { + await teardownTestFolder(dummyDir); }); - beforeEach(async () => { - await cleanTestFolder(baseDir); + afterEach(async () => { + await teardownTestFolder(dummyOutputDir); }); it('should create report.md', async () => { @@ -26,13 +40,13 @@ describe('CLI collect', () => { 'collect', '--persist.format=md', ], - cwd: envRoot, + cwd: dummyDir, }); expect(code).toBe(0); expect(stderr).toBe(''); - const md = await readTextFile(join(envRoot, '.code-pushup/report.md')); + const md = await readTextFile(join(dummyOutputDir, 'report.md')); expect(md).toContain('# Code PushUp Report'); expect(md).toContain(dummyPluginTitle); @@ -43,7 +57,7 @@ describe('CLI collect', () => { const { code, stdout, stderr } = await executeProcess({ command: 'npx', args: ['@code-pushup/cli', '--no-progress', 'collect'], - cwd: envRoot, + cwd: dummyDir, }); expect(code).toBe(0); diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index 2e05bec02..512a7b5fc 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -1,38 +1,55 @@ -import { readFile, writeFile } from 'node:fs/promises'; +import { cp, readFile, writeFile } from 'node:fs/promises'; import { join } from 'node:path'; -import { simpleGit } from 'simple-git'; +import { afterEach, beforeAll } from 'vitest'; import type { ReportsDiff } from '@code-pushup/models'; -import { cleanTestFolder } from '@code-pushup/test-setup'; +import { teardownTestFolder } from '@code-pushup/test-setup'; import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; describe('CLI compare', () => { - const envRoot = join('static-environments', 'cli-e2e-env'); - const srcDir = join(envRoot, '.code-pushup'); - const git = simpleGit(); + const fixtureDummyDir = join( + 'e2e', + 'cli-e2e', + 'mocks', + 'fixtures', + 'dummy-setup', + ); + + const envRoot = join('tmp', 'e2e', 'cli-e2e'); + const testFileDir = join(envRoot, 'compare'); + const dummyDir = join(testFileDir, 'dummy-setup'); + const dummyOutputDir = join(dummyDir, '.code-pushup'); + + beforeAll(async () => { + await cp(fixtureDummyDir, dummyDir, { recursive: true }); + }); + + afterAll(async () => { + await teardownTestFolder(dummyDir); + }); beforeEach(async () => { - await cleanTestFolder(srcDir); + // create report before await executeProcess({ command: 'npx', args: ['@code-pushup/cli', 'collect', '--persist.filename=source-report'], - cwd: envRoot, + cwd: dummyDir, }); // adding items to create a report diff - const itemsFile = join(envRoot, 'src', 'items.json'); + const itemsFile = join(dummyDir, 'src', 'items.json'); const items = JSON.parse((await readFile(itemsFile)).toString()); await writeFile(itemsFile, JSON.stringify([...items, 4, 5, 6, 7], null, 2)); await executeProcess({ command: 'npx', args: ['@code-pushup/cli', 'collect', '--persist.filename=target-report'], - cwd: envRoot, + cwd: dummyDir, }); }, 20_000); + // create report after afterEach(async () => { - await git.checkout(['--', envRoot]); - await cleanTestFolder(srcDir); + await teardownTestFolder(dummyOutputDir); }); it('should compare report.json files and create report-diff.json and report-diff.md', async () => { @@ -44,11 +61,11 @@ describe('CLI compare', () => { `--before=${join('.code-pushup', 'source-report.json')}`, `--after=${join('.code-pushup', 'target-report.json')}`, ], - cwd: envRoot, + cwd: dummyDir, }); const reportsDiff = await readJsonFile( - join(envRoot, '.code-pushup', 'report-diff.json'), + join(dummyOutputDir, 'report-diff.json'), ); expect(reportsDiff).toMatchSnapshot({ commits: expect.any(Object), @@ -58,7 +75,7 @@ describe('CLI compare', () => { }); const reportsDiffMd = await readTextFile( - join(envRoot, '.code-pushup', 'report-diff.md'), + join(dummyOutputDir, 'report-diff.md'), ); // commits are variable, replace SHAs with placeholders const sanitizedMd = reportsDiffMd.replace(/[\da-f]{40}/g, '``'); diff --git a/e2e/cli-e2e/tests/help.e2e.test.ts b/e2e/cli-e2e/tests/help.e2e.test.ts index 574bc99c9..c1e02df94 100644 --- a/e2e/cli-e2e/tests/help.e2e.test.ts +++ b/e2e/cli-e2e/tests/help.e2e.test.ts @@ -3,7 +3,7 @@ import { removeColorCodes } from '@code-pushup/test-utils'; import { executeProcess } from '@code-pushup/utils'; describe('CLI help', () => { - const envRoot = join('static-environments', 'cli-e2e-env'); + const envRoot = join('tmp', 'e2e', 'cli-e2e'); it('should print help with help command', async () => { const { code, stdout, stderr } = await executeProcess({ diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index 89738d78d..ab6888e23 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -1,13 +1,32 @@ +import { cp } from 'node:fs/promises'; import { join } from 'node:path'; -import { expect } from 'vitest'; +import { beforeAll, expect } from 'vitest'; +import { teardownTestFolder } from '@code-pushup/test-setup'; import { executeProcess } from '@code-pushup/utils'; -const extensions = ['js', 'mjs', 'ts'] as const; -const envRoot = join('static-environments', 'cli-e2e-env'); -export const configFilePath = (ext: (typeof extensions)[number]) => - join(process.cwd(), envRoot, `code-pushup.config.${ext}`); - describe('CLI print-config', () => { + const extensions = ['js', 'mjs', 'ts'] as const; + const fixtureDummyDir = join( + 'e2e', + 'cli-e2e', + 'mocks', + 'fixtures', + 'dummy-setup', + ); + const envRoot = join('tmp', 'e2e', 'cli-e2e'); + const testFileDir = join(envRoot, 'print-config'); + const testFileDummySetup = join(testFileDir, 'dummy-setup'); + const configFilePath = (ext: (typeof extensions)[number]) => + join(process.cwd(), testFileDummySetup, `code-pushup.config.${ext}`); + + beforeAll(async () => { + await cp(fixtureDummyDir, testFileDummySetup, { recursive: true }); + }); + + afterAll(async () => { + await teardownTestFolder(testFileDummySetup); + }); + it.each(extensions)( 'should load .%s config file with correct arguments', async ext => { @@ -23,7 +42,7 @@ describe('CLI print-config', () => { '--persist.format=md', `--persist.filename=${ext}-report`, ], - cwd: envRoot, + cwd: testFileDummySetup, }); expect(code).toBe(0); diff --git a/nx.json b/nx.json index e66be0332..840ab7d6f 100644 --- a/nx.json +++ b/nx.json @@ -32,7 +32,7 @@ "executor": "@push-based/nx-verdaccio:env-teardown" }, "nxv-env-setup": { - "cache": true, + "cache": false, "executor": "@push-based/nx-verdaccio:env-setup" }, "@nx/vite:test": { diff --git a/static-environments/cli-e2e-env/package.json b/static-environments/cli-e2e-env/package.json index 8788e3a02..d1862c6c8 100644 --- a/static-environments/cli-e2e-env/package.json +++ b/static-environments/cli-e2e-env/package.json @@ -1,14 +1,18 @@ { "name": "cli-e2e-env", - "private": true, - "scripts": { - "collect": "npx @code-pushup/cli collect" - }, "version": "1.0.0", + "description": "", "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, "keywords": [], "author": "", "license": "ISC", - "dependencies": {}, - "description": "" + "dependencies": { + "@code-pushup/cli": "^0.54.0", + "@code-pushup/core": "^0.54.0", + "@code-pushup/models": "^0.54.0", + "@code-pushup/utils": "^0.54.0" + } } diff --git a/static-environments/cli-e2e-env/project.json b/static-environments/cli-e2e-env/project.json deleted file mode 100644 index f92b11d37..000000000 --- a/static-environments/cli-e2e-env/project.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "cli-e2e-env", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "static-environments/cli-e2e-env/src", - "projectType": "application", - "targets": { - "run-collect": { - "executor": "nx:run-commands", - "options": { - "command": "npx @code-pushup/cli collect --no-progress", - "cwd": "static-environments/cli-e2e-env" - }, - "dependsOn": [ - { - "projects": ["cli", "plugin-eslint"], - "target": "build" - } - ] - } - }, - "tags": ["scope:internal", "type:app"] -} From 2c7516d3b6b03a9189ac4ccf192b56341c0a3296 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 18 Nov 2024 22:22:07 +0100 Subject: [PATCH 62/80] add pkg --- .../mocks/fixtures/dummy-setup/package.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 e2e/cli-e2e/mocks/fixtures/dummy-setup/package.json diff --git a/e2e/cli-e2e/mocks/fixtures/dummy-setup/package.json b/e2e/cli-e2e/mocks/fixtures/dummy-setup/package.json new file mode 100644 index 000000000..8788e3a02 --- /dev/null +++ b/e2e/cli-e2e/mocks/fixtures/dummy-setup/package.json @@ -0,0 +1,14 @@ +{ + "name": "cli-e2e-env", + "private": true, + "scripts": { + "collect": "npx @code-pushup/cli collect" + }, + "version": "1.0.0", + "main": "index.js", + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": {}, + "description": "" +} From e27d4b6bee8bd381a3189c3ade07e12c1edb9c71 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 19 Nov 2024 16:03:34 +0100 Subject: [PATCH 63/80] cleanup env files --- .../mocks/fixtures/dummy-setup/package.json | 14 ------ .../existing-reports/code-pushup.config.ts | 6 +++ .../fixtures/existing-reports/dummy.plugin.ts | 50 +++++++++++++++++++ e2e/cli-e2e/tests/compare.e2e.test.ts | 47 ++++------------- 4 files changed, 67 insertions(+), 50 deletions(-) delete mode 100644 e2e/cli-e2e/mocks/fixtures/dummy-setup/package.json create mode 100644 e2e/cli-e2e/mocks/fixtures/existing-reports/code-pushup.config.ts create mode 100644 e2e/cli-e2e/mocks/fixtures/existing-reports/dummy.plugin.ts diff --git a/e2e/cli-e2e/mocks/fixtures/dummy-setup/package.json b/e2e/cli-e2e/mocks/fixtures/dummy-setup/package.json deleted file mode 100644 index 8788e3a02..000000000 --- a/e2e/cli-e2e/mocks/fixtures/dummy-setup/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "cli-e2e-env", - "private": true, - "scripts": { - "collect": "npx @code-pushup/cli collect" - }, - "version": "1.0.0", - "main": "index.js", - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": {}, - "description": "" -} diff --git a/e2e/cli-e2e/mocks/fixtures/existing-reports/code-pushup.config.ts b/e2e/cli-e2e/mocks/fixtures/existing-reports/code-pushup.config.ts new file mode 100644 index 000000000..26928cba2 --- /dev/null +++ b/e2e/cli-e2e/mocks/fixtures/existing-reports/code-pushup.config.ts @@ -0,0 +1,6 @@ +import dummyPlugin, { dummyCategory } from './dummy.plugin'; + +export default { + plugins: [dummyPlugin()], + categories: [dummyCategory], +}; diff --git a/e2e/cli-e2e/mocks/fixtures/existing-reports/dummy.plugin.ts b/e2e/cli-e2e/mocks/fixtures/existing-reports/dummy.plugin.ts new file mode 100644 index 000000000..8ff5ebd18 --- /dev/null +++ b/e2e/cli-e2e/mocks/fixtures/existing-reports/dummy.plugin.ts @@ -0,0 +1,50 @@ +import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import type { PluginConfig } from '@code-pushup/models'; + +export const dummyPluginSlug = 'dummy-plugin'; + +const dummyAuditSlug = 'dummy-audit'; +export const dummyAudit = { + slug: dummyAuditSlug, + title: 'Dummy Audit', + description: 'A dummy audit to test the cli.', +}; + +export const dummyCategory = { + slug: 'dummy-category', + title: 'Dummy Category', + refs: [ + { + type: 'audit', + plugin: dummyPluginSlug, + slug: dummyAuditSlug, + weight: 1, + }, + ], +}; + +export function create(): PluginConfig { + return { + slug: dummyPluginSlug, + title: 'Dummy Plugin', + icon: 'folder-javascript', + description: 'A dummy plugin to test the cli.', + runner: async () => { + const itemCount = JSON.parse( + await readFile(join('src', 'items.json'), 'utf-8'), + ).length; + return [ + { + ...dummyAudit, + slug: dummyAuditSlug, + score: itemCount < 10 ? itemCount / 10 : 1, + value: itemCount, + }, + ]; + }, + audits: [dummyAudit], + }; +} + +export default create; diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index 512a7b5fc..b449cb68a 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -1,6 +1,6 @@ -import { cp, readFile, writeFile } from 'node:fs/promises'; +import { cp } from 'node:fs/promises'; import { join } from 'node:path'; -import { afterEach, beforeAll } from 'vitest'; +import { beforeAll } from 'vitest'; import type { ReportsDiff } from '@code-pushup/models'; import { teardownTestFolder } from '@code-pushup/test-setup'; import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; @@ -11,45 +11,20 @@ describe('CLI compare', () => { 'cli-e2e', 'mocks', 'fixtures', - 'dummy-setup', + 'existing-reports', ); const envRoot = join('tmp', 'e2e', 'cli-e2e'); - const testFileDir = join(envRoot, 'compare'); - const dummyDir = join(testFileDir, 'dummy-setup'); - const dummyOutputDir = join(dummyDir, '.code-pushup'); + const testFileDir = join(envRoot, '__test__', 'compare'); + const existingDir = join(testFileDir, 'existing-reports'); + const existingOutputDir = join(existingDir, '.code-pushup'); beforeAll(async () => { - await cp(fixtureDummyDir, dummyDir, { recursive: true }); + await cp(fixtureDummyDir, existingDir, { recursive: true }); }); afterAll(async () => { - await teardownTestFolder(dummyDir); - }); - - beforeEach(async () => { - // create report before - await executeProcess({ - command: 'npx', - args: ['@code-pushup/cli', 'collect', '--persist.filename=source-report'], - cwd: dummyDir, - }); - - // adding items to create a report diff - const itemsFile = join(dummyDir, 'src', 'items.json'); - const items = JSON.parse((await readFile(itemsFile)).toString()); - await writeFile(itemsFile, JSON.stringify([...items, 4, 5, 6, 7], null, 2)); - - await executeProcess({ - command: 'npx', - args: ['@code-pushup/cli', 'collect', '--persist.filename=target-report'], - cwd: dummyDir, - }); - }, 20_000); - - // create report after - afterEach(async () => { - await teardownTestFolder(dummyOutputDir); + await teardownTestFolder(existingDir); }); it('should compare report.json files and create report-diff.json and report-diff.md', async () => { @@ -61,11 +36,11 @@ describe('CLI compare', () => { `--before=${join('.code-pushup', 'source-report.json')}`, `--after=${join('.code-pushup', 'target-report.json')}`, ], - cwd: dummyDir, + cwd: existingDir, }); const reportsDiff = await readJsonFile( - join(dummyOutputDir, 'report-diff.json'), + join(existingOutputDir, 'report-diff.json'), ); expect(reportsDiff).toMatchSnapshot({ commits: expect.any(Object), @@ -75,7 +50,7 @@ describe('CLI compare', () => { }); const reportsDiffMd = await readTextFile( - join(dummyOutputDir, 'report-diff.md'), + join(existingOutputDir, 'report-diff.md'), ); // commits are variable, replace SHAs with placeholders const sanitizedMd = reportsDiffMd.replace(/[\da-f]{40}/g, '``'); From 966d7b2675c4aae4d671c10c55633c0c7133142b Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:06:47 +0100 Subject: [PATCH 64/80] Update .github/workflows/code-pushup.yml --- .github/workflows/code-pushup.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code-pushup.yml b/.github/workflows/code-pushup.yml index 3c586d84b..cc1351476 100644 --- a/.github/workflows/code-pushup.yml +++ b/.github/workflows/code-pushup.yml @@ -36,4 +36,4 @@ jobs: - name: Run Code PushUp action uses: code-pushup/github-action@v0 with: - bin: npx nx code-pushup -- --verbose + bin: npx nx code-pushup -- From fcd55961b371a2e0dbf917b33647906b2a5059a2 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 19 Nov 2024 19:47:12 +0100 Subject: [PATCH 65/80] wip --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 21c8b0424..0c2bf279a 100644 --- a/.gitignore +++ b/.gitignore @@ -44,7 +44,7 @@ testem.log Thumbs.db # generated Code PushUp reports -**/.code-pushup + # Nx workspace cache .nx/cache From 779a5711059de0023cb84e5f71cf67caa928ecfa Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 19 Nov 2024 19:47:28 +0100 Subject: [PATCH 66/80] wip --- .../existing-reports/.code-pushup/.gitkeep | 0 .../.code-pushup/source-report.json | 45 +++++++++++++++++++ .../.code-pushup/source-report.md | 37 +++++++++++++++ .../.code-pushup/target-report.json | 45 +++++++++++++++++++ .../.code-pushup/target-report.md | 37 +++++++++++++++ 5 files changed, 164 insertions(+) create mode 100644 e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/.gitkeep create mode 100644 e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/source-report.json create mode 100644 e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/source-report.md create mode 100644 e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/target-report.json create mode 100644 e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/target-report.md diff --git a/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/.gitkeep b/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/source-report.json b/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/source-report.json new file mode 100644 index 000000000..173781d06 --- /dev/null +++ b/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/source-report.json @@ -0,0 +1,45 @@ +{ + "commit": { + "hash": "11f3153b8df2f5e651a1c72d3ddde3a0f400b8a2", + "message": "Merge branch 'main' into split-compare-e2e", + "date": "2024-11-19T14:28:43.000Z", + "author": "Michael" + }, + "packageName": "@code-pushup/core", + "version": "0.54.0", + "date": "2024-11-19T14:50:29.040Z", + "duration": 64, + "categories": [ + { + "slug": "dummy-category", + "refs": [ + { + "slug": "dummy-audit", + "weight": 1, + "type": "audit", + "plugin": "dummy-plugin" + } + ], + "title": "Dummy Category" + } + ], + "plugins": [ + { + "title": "Dummy Plugin", + "slug": "dummy-plugin", + "icon": "folder-javascript", + "date": "2024-11-19T14:50:29.080Z", + "duration": 1, + "audits": [ + { + "slug": "dummy-audit", + "value": 3, + "score": 0.3, + "title": "Dummy Audit", + "description": "A dummy audit to test the cli." + } + ], + "description": "A dummy plugin to test the cli." + } + ] +} diff --git a/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/source-report.md b/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/source-report.md new file mode 100644 index 000000000..2cc93822a --- /dev/null +++ b/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/source-report.md @@ -0,0 +1,37 @@ +# Code PushUp Report + +| 🏷 Category | ⭐ Score | 🛡 Audits | +| :-------------------------------- | :-------: | :-------: | +| [Dummy Category](#dummy-category) | 🔴 **30** | 1 | + +## 🏷 Categories + +### Dummy Category + +🔴 Score: **30** + +- 🟥 [Dummy Audit](#dummy-audit-dummy-plugin) (_Dummy Plugin_) - **3** + +## 🛡️ Audits + +### Dummy Audit (Dummy Plugin) + +🟥 **3** (score: 30) + +A dummy audit to test the cli. + +## About + +Report was created by [Code PushUp](https://github.com/code-pushup/cli#readme) on Tue, Nov 19, 2024, 3:50 PM GMT+1. + +| Plugin | Audits | Version | Duration | +| :----------- | :----: | :-----: | -------: | +| Dummy Plugin | 1 | | 1 ms | + +| Commit | Version | Duration | Plugins | Categories | Audits | +| :------------------------------------------------------------------------------------ | :------: | -------: | :-----: | :--------: | :----: | +| Merge branch 'main' into split-compare-e2e (11f3153b8df2f5e651a1c72d3ddde3a0f400b8a2) | `0.54.0` | 64 ms | 1 | 1 | 1 | + +--- + +Made with ❤ by [Code PushUp](https://github.com/code-pushup/cli#readme) diff --git a/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/target-report.json b/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/target-report.json new file mode 100644 index 000000000..2d46055c3 --- /dev/null +++ b/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/target-report.json @@ -0,0 +1,45 @@ +{ + "commit": { + "hash": "11f3153b8df2f5e651a1c72d3ddde3a0f400b8a2", + "message": "Merge branch 'main' into split-compare-e2e", + "date": "2024-11-19T14:28:43.000Z", + "author": "Michael" + }, + "packageName": "@code-pushup/core", + "version": "0.54.0", + "date": "2024-11-19T14:51:03.174Z", + "duration": 63, + "categories": [ + { + "slug": "dummy-category", + "refs": [ + { + "slug": "dummy-audit", + "weight": 1, + "type": "audit", + "plugin": "dummy-plugin" + } + ], + "title": "Dummy Category" + } + ], + "plugins": [ + { + "title": "Dummy Plugin", + "slug": "dummy-plugin", + "icon": "folder-javascript", + "date": "2024-11-19T14:51:03.212Z", + "duration": 1, + "audits": [ + { + "slug": "dummy-audit", + "value": 7, + "score": 0.7, + "title": "Dummy Audit", + "description": "A dummy audit to test the cli." + } + ], + "description": "A dummy plugin to test the cli." + } + ] +} diff --git a/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/target-report.md b/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/target-report.md new file mode 100644 index 000000000..6deba652b --- /dev/null +++ b/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/target-report.md @@ -0,0 +1,37 @@ +# Code PushUp Report + +| 🏷 Category | ⭐ Score | 🛡 Audits | +| :-------------------------------- | :-------: | :-------: | +| [Dummy Category](#dummy-category) | 🟡 **70** | 1 | + +## 🏷 Categories + +### Dummy Category + +🟡 Score: **70** + +- 🟨 [Dummy Audit](#dummy-audit-dummy-plugin) (_Dummy Plugin_) - **7** + +## 🛡️ Audits + +### Dummy Audit (Dummy Plugin) + +🟨 **7** (score: 70) + +A dummy audit to test the cli. + +## About + +Report was created by [Code PushUp](https://github.com/code-pushup/cli#readme) on Tue, Nov 19, 2024, 3:51 PM GMT+1. + +| Plugin | Audits | Version | Duration | +| :----------- | :----: | :-----: | -------: | +| Dummy Plugin | 1 | | 1 ms | + +| Commit | Version | Duration | Plugins | Categories | Audits | +| :------------------------------------------------------------------------------------ | :------: | -------: | :-----: | :--------: | :----: | +| Merge branch 'main' into split-compare-e2e (11f3153b8df2f5e651a1c72d3ddde3a0f400b8a2) | `0.54.0` | 63 ms | 1 | 1 | 1 | + +--- + +Made with ❤ by [Code PushUp](https://github.com/code-pushup/cli#readme) From 4526688828ba293c65ee1e23625f18ae7f64bbb5 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 19 Nov 2024 19:47:36 +0100 Subject: [PATCH 67/80] wip --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0c2bf279a..21c8b0424 100644 --- a/.gitignore +++ b/.gitignore @@ -44,7 +44,7 @@ testem.log Thumbs.db # generated Code PushUp reports - +**/.code-pushup # Nx workspace cache .nx/cache From 10506cff7cf189957d473a50b56072652e78fa1d Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 20 Nov 2024 23:23:28 +0100 Subject: [PATCH 68/80] test: adjust test env paths --- .../{ => ci-test-repo}/code-pushup.config.ts | 0 .../mocks/fixtures/ci-test-repo/index.js | 1 + e2e/ci-e2e/tests/ci.e2e.test.ts | 56 ++-- .../existing-reports/.code-pushup/.gitkeep | 0 e2e/cli-e2e/tests/collect.e2e.test.ts | 12 +- e2e/cli-e2e/tests/compare.e2e.test.ts | 12 +- e2e/cli-e2e/tests/help.e2e.test.ts | 8 +- e2e/cli-e2e/tests/print-config.e2e.test.ts | 13 +- e2e/create-cli-e2e/tests/init.e2e.test.ts | 20 +- .../tests/executor-cli.e2e.test.ts | 23 +- .../tests/generator-configuration.e2e.test.ts | 26 +- .../tests/generator-init.e2e.test.ts | 22 +- .../tests/plugin-create-nodes.e2e.test.ts | 36 ++- .../__snapshots__/collect.e2e.test.ts.snap | 302 ++++++++++++++++++ .../tests/collect.e2e.test.ts | 21 +- .../__snapshots__/collect.e2e.test.ts.snap | 138 ++++++++ .../tests/collect.e2e.test.ts | 24 +- .../code-pushup.config.ts} | 0 .../__snapshots__/collect.e2e.test.ts.snap | 130 ++++++++ .../tests/collect.e2e.test.ts | 41 +-- testing/test-nx-utils/src/index.ts | 1 + .../src/lib/utils/environment.ts | 9 + testing/test-utils/src/lib/constants.ts | 3 + 23 files changed, 788 insertions(+), 110 deletions(-) rename e2e/ci-e2e/mocks/fixtures/{ => ci-test-repo}/code-pushup.config.ts (100%) create mode 100644 e2e/ci-e2e/mocks/fixtures/ci-test-repo/index.js delete mode 100644 e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/.gitkeep rename e2e/plugin-lighthouse-e2e/mocks/fixtures/{code-pushup.config.lh-default.ts => default-setup/code-pushup.config.ts} (100%) create mode 100644 testing/test-nx-utils/src/lib/utils/environment.ts diff --git a/e2e/ci-e2e/mocks/fixtures/code-pushup.config.ts b/e2e/ci-e2e/mocks/fixtures/ci-test-repo/code-pushup.config.ts similarity index 100% rename from e2e/ci-e2e/mocks/fixtures/code-pushup.config.ts rename to e2e/ci-e2e/mocks/fixtures/ci-test-repo/code-pushup.config.ts diff --git a/e2e/ci-e2e/mocks/fixtures/ci-test-repo/index.js b/e2e/ci-e2e/mocks/fixtures/ci-test-repo/index.js new file mode 100644 index 000000000..7f97cd8a0 --- /dev/null +++ b/e2e/ci-e2e/mocks/fixtures/ci-test-repo/index.js @@ -0,0 +1 @@ +console.log("Hello, world!") diff --git a/e2e/ci-e2e/tests/ci.e2e.test.ts b/e2e/ci-e2e/tests/ci.e2e.test.ts index 97e27d922..96d85f9ac 100644 --- a/e2e/ci-e2e/tests/ci.e2e.test.ts +++ b/e2e/ci-e2e/tests/ci.e2e.test.ts @@ -1,11 +1,4 @@ -import { - copyFile, - mkdir, - readFile, - rename, - rm, - writeFile, -} from 'node:fs/promises'; +import { cp, readFile, rename } from 'node:fs/promises'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { @@ -14,6 +7,7 @@ import { type SimpleGit, simpleGit, } from 'simple-git'; +import { afterEach } from 'vitest'; import { type Comment, type GitRefs, @@ -22,7 +16,14 @@ import { type RunResult, runInCI, } from '@code-pushup/ci'; -import { initGitRepo } from '@code-pushup/test-utils'; +import { nxTargetProject } from '@code-pushup/test-nx-utils'; +import { teardownTestFolder } from '@code-pushup/test-setup'; +import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, + TEST_SNAPSHOTS_DIR, + initGitRepo, +} from '@code-pushup/test-utils'; describe('CI package', () => { const fixturesDir = join( @@ -30,33 +31,27 @@ describe('CI package', () => { '..', 'mocks', 'fixtures', + 'ci-test-repo', ); - const workDir = join( + const ciSetupRepoDir = join( process.cwd(), - 'tmp', - 'e2e', - 'ci-e2e', - '__test__', + E2E_ENVIRONMENTS_DIR, + nxTargetProject(), + TEST_OUTPUT_DIR, 'ci-test-repo', ); - const outputDir = join(workDir, '.code-pushup'); + const outputDir = join(ciSetupRepoDir, '.code-pushup'); const options = { - directory: workDir, + directory: ciSetupRepoDir, } satisfies Options; let git: SimpleGit; beforeEach(async () => { - await rm(workDir, { recursive: true, force: true }); - await mkdir(workDir, { recursive: true }); - await copyFile( - join(fixturesDir, 'code-pushup.config.ts'), - join(workDir, 'code-pushup.config.ts'), - ); - await writeFile(join(workDir, 'index.js'), 'console.log("Hello, world!")'); + await cp(fixturesDir, ciSetupRepoDir, { recursive: true }); - git = await initGitRepo(simpleGit, { baseDir: workDir }); + git = await initGitRepo(simpleGit, { baseDir: ciSetupRepoDir }); vi.spyOn(git, 'fetch').mockResolvedValue({} as FetchResult); vi.spyOn(git, 'diffSummary').mockResolvedValue({ @@ -69,8 +64,12 @@ describe('CI package', () => { await git.commit('Initial commit'); }); + afterEach(async () => { + await teardownTestFolder(ciSetupRepoDir); + }); + afterAll(async () => { - await rm(workDir, { recursive: true, force: true }); + await teardownTestFolder(ciSetupRepoDir); }); describe('push event', () => { @@ -138,7 +137,10 @@ describe('CI package', () => { beforeEach(async () => { await git.checkoutLocalBranch('feature-1'); - await rename(join(workDir, 'index.js'), join(workDir, 'index.ts')); + await rename( + join(ciSetupRepoDir, 'index.js'), + join(ciSetupRepoDir, 'index.ts'), + ); await git.add('index.ts'); await git.commit('Convert JS file to TS'); @@ -177,7 +179,7 @@ describe('CI package', () => { const md = await mdPromise; await expect( md.replace(/[\da-f]{40}/g, '``'), - ).toMatchFileSnapshot('__snapshots__/report-diff.md'); + ).toMatchFileSnapshot(join(TEST_SNAPSHOTS_DIR, 'report-diff.md')); }); }); }); diff --git a/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/.gitkeep b/e2e/cli-e2e/mocks/fixtures/existing-reports/.code-pushup/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/e2e/cli-e2e/tests/collect.e2e.test.ts b/e2e/cli-e2e/tests/collect.e2e.test.ts index c66097212..707ae96bc 100644 --- a/e2e/cli-e2e/tests/collect.e2e.test.ts +++ b/e2e/cli-e2e/tests/collect.e2e.test.ts @@ -1,7 +1,9 @@ import { cp } from 'node:fs/promises'; import { join } from 'node:path'; import { afterEach, beforeAll, describe, expect, it } from 'vitest'; +import { nxTargetProject } from '@code-pushup/test-nx-utils'; import { teardownTestFolder } from '@code-pushup/test-setup'; +import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR } from '@code-pushup/test-utils'; import { executeProcess, readTextFile } from '@code-pushup/utils'; describe('CLI collect', () => { @@ -9,13 +11,17 @@ describe('CLI collect', () => { const dummyAuditTitle = 'Dummy Audit'; const fixtureDummyDir = join( 'e2e', - 'cli-e2e', + nxTargetProject(), 'mocks', 'fixtures', 'dummy-setup', ); - const envRoot = join('tmp', 'e2e', 'cli-e2e'); - const testFileDir = join(envRoot, 'collect'); + const testFileDir = join( + E2E_ENVIRONMENTS_DIR, + nxTargetProject(), + TEST_OUTPUT_DIR, + 'collect', + ); const dummyDir = join(testFileDir, 'dummy-setup'); const dummyOutputDir = join(dummyDir, '.code-pushup'); diff --git a/e2e/cli-e2e/tests/compare.e2e.test.ts b/e2e/cli-e2e/tests/compare.e2e.test.ts index b449cb68a..73d08b6b2 100644 --- a/e2e/cli-e2e/tests/compare.e2e.test.ts +++ b/e2e/cli-e2e/tests/compare.e2e.test.ts @@ -2,20 +2,26 @@ import { cp } from 'node:fs/promises'; import { join } from 'node:path'; import { beforeAll } from 'vitest'; import type { ReportsDiff } from '@code-pushup/models'; +import { nxTargetProject } from '@code-pushup/test-nx-utils'; import { teardownTestFolder } from '@code-pushup/test-setup'; +import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR } from '@code-pushup/test-utils'; import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; describe('CLI compare', () => { const fixtureDummyDir = join( 'e2e', - 'cli-e2e', + nxTargetProject(), 'mocks', 'fixtures', 'existing-reports', ); - const envRoot = join('tmp', 'e2e', 'cli-e2e'); - const testFileDir = join(envRoot, '__test__', 'compare'); + const testFileDir = join( + E2E_ENVIRONMENTS_DIR, + nxTargetProject(), + TEST_OUTPUT_DIR, + 'compare', + ); const existingDir = join(testFileDir, 'existing-reports'); const existingOutputDir = join(existingDir, '.code-pushup'); diff --git a/e2e/cli-e2e/tests/help.e2e.test.ts b/e2e/cli-e2e/tests/help.e2e.test.ts index c1e02df94..ec2390c98 100644 --- a/e2e/cli-e2e/tests/help.e2e.test.ts +++ b/e2e/cli-e2e/tests/help.e2e.test.ts @@ -1,9 +1,13 @@ import { join } from 'node:path'; -import { removeColorCodes } from '@code-pushup/test-utils'; +import { nxTargetProject } from '@code-pushup/test-nx-utils'; +import { + E2E_ENVIRONMENTS_DIR, + removeColorCodes, +} from '@code-pushup/test-utils'; import { executeProcess } from '@code-pushup/utils'; describe('CLI help', () => { - const envRoot = join('tmp', 'e2e', 'cli-e2e'); + const envRoot = join(E2E_ENVIRONMENTS_DIR, nxTargetProject()); it('should print help with help command', async () => { const { code, stdout, stderr } = await executeProcess({ diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index ab6888e23..c6443723c 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -1,20 +1,27 @@ import { cp } from 'node:fs/promises'; import { join } from 'node:path'; import { beforeAll, expect } from 'vitest'; +import { nxTargetProject } from '@code-pushup/test-nx-utils'; import { teardownTestFolder } from '@code-pushup/test-setup'; +import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR } from '@code-pushup/test-utils'; import { executeProcess } from '@code-pushup/utils'; describe('CLI print-config', () => { const extensions = ['js', 'mjs', 'ts'] as const; const fixtureDummyDir = join( 'e2e', - 'cli-e2e', + nxTargetProject(), 'mocks', 'fixtures', 'dummy-setup', ); - const envRoot = join('tmp', 'e2e', 'cli-e2e'); - const testFileDir = join(envRoot, 'print-config'); + + const testFileDir = join( + E2E_ENVIRONMENTS_DIR, + nxTargetProject(), + TEST_OUTPUT_DIR, + 'print-config', + ); const testFileDummySetup = join(testFileDir, 'dummy-setup'); const configFilePath = (ext: (typeof extensions)[number]) => join(process.cwd(), testFileDummySetup, `code-pushup.config.${ext}`); diff --git a/e2e/create-cli-e2e/tests/init.e2e.test.ts b/e2e/create-cli-e2e/tests/init.e2e.test.ts index de5dd73e8..ba6d08ff8 100644 --- a/e2e/create-cli-e2e/tests/init.e2e.test.ts +++ b/e2e/create-cli-e2e/tests/init.e2e.test.ts @@ -1,19 +1,25 @@ import { dirname, join, relative } from 'node:path'; import { afterEach, expect } from 'vitest'; +import { nxTargetProject } from '@code-pushup/test-nx-utils'; import { teardownTestFolder } from '@code-pushup/test-setup'; -import { createNpmWorkspace, removeColorCodes } from '@code-pushup/test-utils'; +import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, + createNpmWorkspace, + removeColorCodes, +} from '@code-pushup/test-utils'; import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; describe('create-cli-inti', () => { - const workspaceRoot = 'tmp/e2e/create-cli-e2e'; - const baseDir = 'tmp/e2e/create-cli-e2e/__test__/init'; + const workspaceRoot = join(E2E_ENVIRONMENTS_DIR, nxTargetProject()); + const testFileDir = join(workspaceRoot, TEST_OUTPUT_DIR, 'init'); afterEach(async () => { - await teardownTestFolder(baseDir); + await teardownTestFolder(testFileDir); }); it('should execute package correctly over npm exec', async () => { - const cwd = join(baseDir, 'npm-exec'); + const cwd = join(testFileDir, 'npm-exec'); const userconfig = relative(cwd, join(workspaceRoot, '.npmrc')); await createNpmWorkspace(cwd); const { code, stdout } = await executeProcess({ @@ -53,7 +59,7 @@ describe('create-cli-inti', () => { }); it('should execute package correctly over npm init', async () => { - const cwd = join(baseDir, 'npm-init'); + const cwd = join(testFileDir, 'npm-init'); const userconfig = relative(cwd, join(workspaceRoot, '.npmrc')); await createNpmWorkspace(cwd); @@ -95,7 +101,7 @@ describe('create-cli-inti', () => { }); it('should produce an executable setup when running npm init', async () => { - const cwd = join(baseDir, 'npm-init-executable'); + const cwd = join(testFileDir, 'npm-init-executable'); const userconfig = relative(cwd, join(workspaceRoot, '.npmrc')); await createNpmWorkspace(cwd); diff --git a/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts b/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts index 04b56a2ec..fc19780b0 100644 --- a/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts +++ b/e2e/nx-plugin-e2e/tests/executor-cli.e2e.test.ts @@ -6,9 +6,15 @@ import { generateCodePushupConfig } from '@code-pushup/nx-plugin'; import { generateWorkspaceAndProject, materializeTree, + nxTargetProject, } from '@code-pushup/test-nx-utils'; import { teardownTestFolder } from '@code-pushup/test-setup'; -import { osAgnosticPath, removeColorCodes } from '@code-pushup/test-utils'; +import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, + osAgnosticPath, + removeColorCodes, +} from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; function relativePathToCwd(testDir: string): string { @@ -61,18 +67,23 @@ async function addTargetToWorkspace( describe('executor command', () => { let tree: Tree; const project = 'my-lib'; - const baseDir = 'tmp/e2e/nx-plugin-e2e/__test__/executor/cli'; + const testFileDir = join( + E2E_ENVIRONMENTS_DIR, + nxTargetProject(), + TEST_OUTPUT_DIR, + 'executor-cli', + ); beforeEach(async () => { tree = await generateWorkspaceAndProject(project); }); afterEach(async () => { - await teardownTestFolder(baseDir); + await teardownTestFolder(testFileDir); }); it('should execute no specific command by default', async () => { - const cwd = join(baseDir, 'execute-default-command'); + const cwd = join(testFileDir, 'execute-default-command'); await addTargetToWorkspace(tree, { cwd, project }); const { stdout, code } = await executeProcess({ command: 'npx', @@ -86,7 +97,7 @@ describe('executor command', () => { }); it('should execute print-config executor', async () => { - const cwd = join(baseDir, 'execute-print-config-command'); + const cwd = join(testFileDir, 'execute-print-config-command'); await addTargetToWorkspace(tree, { cwd, project }); const { stdout, code } = await executeProcess({ @@ -105,7 +116,7 @@ describe('executor command', () => { }); it('should execute collect executor and add report to sub folder named by project', async () => { - const cwd = join(baseDir, 'execute-collect-command'); + const cwd = join(testFileDir, 'execute-collect-command'); await addTargetToWorkspace(tree, { cwd, project }); const { stdout, code } = await executeProcess({ diff --git a/e2e/nx-plugin-e2e/tests/generator-configuration.e2e.test.ts b/e2e/nx-plugin-e2e/tests/generator-configuration.e2e.test.ts index bff0ec4b2..4ad65594f 100644 --- a/e2e/nx-plugin-e2e/tests/generator-configuration.e2e.test.ts +++ b/e2e/nx-plugin-e2e/tests/generator-configuration.e2e.test.ts @@ -6,27 +6,37 @@ import { generateCodePushupConfig } from '@code-pushup/nx-plugin'; import { generateWorkspaceAndProject, materializeTree, + nxTargetProject, } from '@code-pushup/test-nx-utils'; import { teardownTestFolder } from '@code-pushup/test-setup'; -import { removeColorCodes } from '@code-pushup/test-utils'; +import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, + removeColorCodes, +} from '@code-pushup/test-utils'; import { executeProcess } from '@code-pushup/utils'; describe('nx-plugin g configuration', () => { let tree: Tree; const project = 'my-lib'; const projectRoot = join('libs', project); - const baseDir = 'tmp/e2e/nx-plugin-e2e/__test__/generators/configuration'; + const testFileDir = join( + E2E_ENVIRONMENTS_DIR, + nxTargetProject(), + TEST_OUTPUT_DIR, + 'generators-configuration', + ); beforeEach(async () => { tree = await generateWorkspaceAndProject(project); }); afterEach(async () => { - await teardownTestFolder(baseDir); + await teardownTestFolder(testFileDir); }); it('should generate code-pushup.config.ts file and add target to project.json', async () => { - const cwd = join(baseDir, 'configure'); + const cwd = join(testFileDir, 'configure'); await materializeTree(tree, cwd); const { code, stdout, stderr } = await executeProcess({ @@ -76,7 +86,7 @@ describe('nx-plugin g configuration', () => { }); it('should NOT create a code-pushup.config.ts file if one already exists', async () => { - const cwd = join(baseDir, 'configure-config-existing'); + const cwd = join(testFileDir, 'configure-config-existing'); generateCodePushupConfig(tree, projectRoot); await materializeTree(tree, cwd); @@ -116,7 +126,7 @@ describe('nx-plugin g configuration', () => { }); it('should NOT create a code-pushup.config.ts file if skipConfig is given', async () => { - const cwd = join(baseDir, 'configure-skip-config'); + const cwd = join(testFileDir, 'configure-skip-config'); await materializeTree(tree, cwd); const { code, stdout } = await executeProcess({ @@ -161,7 +171,7 @@ describe('nx-plugin g configuration', () => { }); it('should NOT add target to project.json if skipTarget is given', async () => { - const cwd = join(baseDir, 'configure-skip-target'); + const cwd = join(testFileDir, 'configure-skip-target'); await materializeTree(tree, cwd); const { code, stdout } = await executeProcess({ @@ -205,7 +215,7 @@ describe('nx-plugin g configuration', () => { }); it('should inform about dry run', async () => { - const cwd = join(baseDir, 'configure'); + const cwd = join(testFileDir, 'configure'); await materializeTree(tree, cwd); const { stderr } = await executeProcess({ diff --git a/e2e/nx-plugin-e2e/tests/generator-init.e2e.test.ts b/e2e/nx-plugin-e2e/tests/generator-init.e2e.test.ts index 9a46080fe..4070fd4d5 100644 --- a/e2e/nx-plugin-e2e/tests/generator-init.e2e.test.ts +++ b/e2e/nx-plugin-e2e/tests/generator-init.e2e.test.ts @@ -5,26 +5,36 @@ import { afterEach, expect } from 'vitest'; import { generateWorkspaceAndProject, materializeTree, + nxTargetProject, } from '@code-pushup/test-nx-utils'; import { teardownTestFolder } from '@code-pushup/test-setup'; -import { removeColorCodes } from '@code-pushup/test-utils'; +import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, + removeColorCodes, +} from '@code-pushup/test-utils'; import { executeProcess } from '@code-pushup/utils'; describe('nx-plugin g init', () => { let tree: Tree; const project = 'my-lib'; - const baseDir = 'tmp/e2e/nx-plugin-e2e/__test__/generators/init'; + const testFileDir = join( + E2E_ENVIRONMENTS_DIR, + nxTargetProject(), + TEST_OUTPUT_DIR, + 'generators-init', + ); beforeEach(async () => { tree = await generateWorkspaceAndProject(project); }); afterEach(async () => { - await teardownTestFolder(baseDir); + await teardownTestFolder(testFileDir); }); it('should inform about dry run when used on init generator', async () => { - const cwd = join(baseDir, 'dry-run'); + const cwd = join(testFileDir, 'dry-run'); await materializeTree(tree, cwd); const { stderr } = await executeProcess({ @@ -40,7 +50,7 @@ describe('nx-plugin g init', () => { }); it('should update packages.json and configure nx.json', async () => { - const cwd = join(baseDir, 'nx-update'); + const cwd = join(testFileDir, 'nx-update'); await materializeTree(tree, cwd); const { code, stdout } = await executeProcess({ @@ -89,7 +99,7 @@ describe('nx-plugin g init', () => { }); it('should skip packages.json update if --skipPackageJson is given', async () => { - const cwd = join(baseDir, 'skip-packages'); + const cwd = join(testFileDir, 'skip-packages'); await materializeTree(tree, cwd); const { code, stdout } = await executeProcess({ diff --git a/e2e/nx-plugin-e2e/tests/plugin-create-nodes.e2e.test.ts b/e2e/nx-plugin-e2e/tests/plugin-create-nodes.e2e.test.ts index 2616ec1da..163ba1a11 100644 --- a/e2e/nx-plugin-e2e/tests/plugin-create-nodes.e2e.test.ts +++ b/e2e/nx-plugin-e2e/tests/plugin-create-nodes.e2e.test.ts @@ -7,28 +7,38 @@ import { generateWorkspaceAndProject, materializeTree, nxShowProjectJson, + nxTargetProject, registerPluginInWorkspace, } from '@code-pushup/test-nx-utils'; import { teardownTestFolder } from '@code-pushup/test-setup'; -import { removeColorCodes } from '@code-pushup/test-utils'; +import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, + removeColorCodes, +} from '@code-pushup/test-utils'; import { executeProcess, readTextFile } from '@code-pushup/utils'; describe('nx-plugin', () => { let tree: Tree; const project = 'my-lib'; const projectRoot = join('libs', project); - const baseDir = 'tmp/e2e/nx-plugin-e2e/__test__/plugin/create-nodes'; + const testFileDir = join( + E2E_ENVIRONMENTS_DIR, + nxTargetProject(), + TEST_OUTPUT_DIR, + 'plugin-create-nodes', + ); beforeEach(async () => { tree = await generateWorkspaceAndProject(project); }); afterEach(async () => { - await teardownTestFolder(baseDir); + await teardownTestFolder(testFileDir); }); it('should add configuration target dynamically', async () => { - const cwd = join(baseDir, 'add-configuration-dynamically'); + const cwd = join(testFileDir, 'add-configuration-dynamically'); registerPluginInWorkspace(tree, '@code-pushup/nx-plugin'); await materializeTree(tree, cwd); @@ -49,7 +59,7 @@ describe('nx-plugin', () => { }); it('should execute dynamic configuration target', async () => { - const cwd = join(baseDir, 'execute-dynamic-configuration'); + const cwd = join(testFileDir, 'execute-dynamic-configuration'); registerPluginInWorkspace(tree, { plugin: '@code-pushup/nx-plugin', }); @@ -73,7 +83,7 @@ describe('nx-plugin', () => { }); it('should consider plugin option targetName in configuration target', async () => { - const cwd = join(baseDir, 'configuration-option-target-name'); + const cwd = join(testFileDir, 'configuration-option-target-name'); registerPluginInWorkspace(tree, { plugin: '@code-pushup/nx-plugin', options: { @@ -92,7 +102,7 @@ describe('nx-plugin', () => { }); it('should consider plugin option bin in configuration target', async () => { - const cwd = join(baseDir, 'configuration-option-bin'); + const cwd = join(testFileDir, 'configuration-option-bin'); registerPluginInWorkspace(tree, { plugin: '@code-pushup/nx-plugin', options: { @@ -115,7 +125,7 @@ describe('nx-plugin', () => { }); it('should NOT add config targets dynamically if the project is configured', async () => { - const cwd = join(baseDir, 'configuration-already-configured'); + const cwd = join(testFileDir, 'configuration-already-configured'); registerPluginInWorkspace(tree, '@code-pushup/nx-plugin'); const { root } = readProjectConfiguration(tree, project); generateCodePushupConfig(tree, root); @@ -134,7 +144,7 @@ describe('nx-plugin', () => { }); it('should add executor target dynamically if the project is configured', async () => { - const cwd = join(baseDir, 'add-executor-dynamically'); + const cwd = join(testFileDir, 'add-executor-dynamically'); registerPluginInWorkspace(tree, '@code-pushup/nx-plugin'); const { root } = readProjectConfiguration(tree, project); generateCodePushupConfig(tree, root); @@ -155,7 +165,7 @@ describe('nx-plugin', () => { }); it('should execute dynamic executor target', async () => { - const cwd = join(baseDir, 'execute-dynamic-executor'); + const cwd = join(testFileDir, 'execute-dynamic-executor'); const pathRelativeToPackage = relative(join(cwd, 'libs', project), cwd); registerPluginInWorkspace(tree, { plugin: '@code-pushup/nx-plugin', @@ -200,7 +210,7 @@ describe('nx-plugin', () => { }); it('should consider plugin option bin in executor target', async () => { - const cwd = join(baseDir, 'configuration-option-bin'); + const cwd = join(testFileDir, 'configuration-option-bin'); registerPluginInWorkspace(tree, { plugin: '@code-pushup/nx-plugin', options: { @@ -223,7 +233,7 @@ describe('nx-plugin', () => { }); it('should consider plugin option projectPrefix in executor target', async () => { - const cwd = join(baseDir, 'configuration-option-bin'); + const cwd = join(testFileDir, 'configuration-option-bin'); registerPluginInWorkspace(tree, { plugin: '@code-pushup/nx-plugin', options: { @@ -249,7 +259,7 @@ describe('nx-plugin', () => { }); it('should NOT add targets dynamically if plugin is not registered', async () => { - const cwd = join(baseDir, 'plugin-not-registered'); + const cwd = join(testFileDir, 'plugin-not-registered'); await materializeTree(tree, cwd); const { code, projectJson } = await nxShowProjectJson(cwd, project); diff --git a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index d15a8626b..100d441fd 100644 --- a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -1,5 +1,307 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`PLUGIN collect report with coverage-plugin NPM package > should run Code coverage plugin that runs coverage tool and creates report.json 1`] = ` +{ + "categories": [ + { + "refs": [ + { + "plugin": "coverage", + "slug": "coverage", + "type": "group", + "weight": 1, + }, + ], + "slug": "code-coverage", + "title": "Code coverage", + }, + ], + "packageName": "@code-pushup/core", + "plugins": [ + { + "audits": [ + { + "description": "Measures how many functions were called in at least one test.", + "details": { + "issues": [ + { + "message": "Function formatReportScore is not called in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/partly-covered/utils.ts", + "position": { + "startLine": 2, + }, + }, + }, + { + "message": "Function sortReport is not called in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/not-covered/sorting.ts", + "position": { + "startLine": 1, + }, + }, + }, + ], + }, + "displayValue": "60 %", + "score": 0.6, + "slug": "function-coverage", + "title": "Function coverage", + "value": 60, + }, + { + "description": "Measures how many branches were executed after conditional statements in at least one test.", + "details": { + "issues": [ + { + "message": "2nd branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/partly-covered/utils.ts", + "position": { + "startLine": 6, + }, + }, + }, + { + "message": "2nd branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/partly-covered/utils.ts", + "position": { + "startLine": 10, + }, + }, + }, + { + "message": "1st branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/not-covered/sorting.ts", + "position": { + "startLine": 7, + }, + }, + }, + { + "message": "2nd branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/not-covered/sorting.ts", + "position": { + "startLine": 7, + }, + }, + }, + ], + }, + "displayValue": "76.5 %", + "score": 0.7647, + "slug": "branch-coverage", + "title": "Branch coverage", + "value": 76.47058823529412, + }, + { + "description": "Measures how many lines of code were executed in at least one test.", + "details": { + "issues": [ + { + "message": "Lines 7-9 are not covered in any test case.", + "severity": "warning", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/partly-covered/utils.ts", + "position": { + "endLine": 9, + "startLine": 7, + }, + }, + }, + { + "message": "Lines 1-5 are not covered in any test case.", + "severity": "warning", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/not-covered/sorting.ts", + "position": { + "endLine": 5, + "startLine": 1, + }, + }, + }, + ], + }, + "displayValue": "68 %", + "score": 0.68, + "slug": "line-coverage", + "title": "Line coverage", + "value": 68, + }, + ], + "description": "Official Code PushUp code coverage plugin.", + "docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/", + "groups": [ + { + "description": "Group containing all defined coverage types as audits.", + "refs": [ + { + "slug": "function-coverage", + "weight": 6, + }, + { + "slug": "branch-coverage", + "weight": 3, + }, + { + "slug": "line-coverage", + "weight": 1, + }, + ], + "slug": "coverage", + "title": "Code coverage metrics", + }, + ], + "icon": "folder-coverage-open", + "packageName": "@code-pushup/coverage-plugin", + "slug": "coverage", + "title": "Code coverage", + }, + ], +} +`; + +exports[`PLUGIN collect report with coverage-plugin NPM package > should run Code coverage plugin which collects passed results and creates report.json 1`] = ` +{ + "categories": [ + { + "refs": [ + { + "plugin": "coverage", + "slug": "coverage", + "type": "group", + "weight": 1, + }, + ], + "slug": "code-coverage", + "title": "Code coverage", + }, + ], + "packageName": "@code-pushup/core", + "plugins": [ + { + "audits": [ + { + "description": "Measures how many functions were called in at least one test.", + "details": { + "issues": [ + { + "message": "Function untested is not called in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/basic-setup/src/index.mjs", + "position": { + "startLine": 1, + }, + }, + }, + ], + }, + "displayValue": "66.7 %", + "score": 0.6667, + "slug": "function-coverage", + "title": "Function coverage", + "value": 66.66666666666666, + }, + { + "description": "Measures how many branches were executed after conditional statements in at least one test.", + "details": { + "issues": [ + { + "message": "1st branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/basic-setup/src/index.mjs", + "position": { + "startLine": 10, + }, + }, + }, + ], + }, + "displayValue": "66.7 %", + "score": 0.6667, + "slug": "branch-coverage", + "title": "Branch coverage", + "value": 66.66666666666666, + }, + { + "description": "Measures how many lines of code were executed in at least one test.", + "details": { + "issues": [ + { + "message": "Lines 2-3 are not covered in any test case.", + "severity": "warning", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/basic-setup/src/index.mjs", + "position": { + "endLine": 3, + "startLine": 2, + }, + }, + }, + { + "message": "Lines 11-12 are not covered in any test case.", + "severity": "warning", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/basic-setup/src/index.mjs", + "position": { + "endLine": 12, + "startLine": 11, + }, + }, + }, + ], + }, + "displayValue": "73.3 %", + "score": 0.7333, + "slug": "line-coverage", + "title": "Line coverage", + "value": 73.33333333333333, + }, + ], + "description": "Official Code PushUp code coverage plugin.", + "docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/", + "groups": [ + { + "description": "Group containing all defined coverage types as audits.", + "refs": [ + { + "slug": "function-coverage", + "weight": 6, + }, + { + "slug": "branch-coverage", + "weight": 3, + }, + { + "slug": "line-coverage", + "weight": 1, + }, + ], + "slug": "coverage", + "title": "Code coverage metrics", + }, + ], + "icon": "folder-coverage-open", + "packageName": "@code-pushup/coverage-plugin", + "slug": "coverage", + "title": "Code coverage", + }, + ], +} +`; + exports[`collect report with coverage-plugin NPM package > should run Code coverage plugin that runs coverage tool and creates report.json 1`] = ` { "categories": [ diff --git a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts index 673c56d63..9dd257adf 100644 --- a/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-coverage-e2e/tests/collect.e2e.test.ts @@ -2,18 +2,25 @@ import { cp } from 'node:fs/promises'; import { join } from 'node:path'; import { afterAll, afterEach, beforeAll } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; +import { nxTargetProject } from '@code-pushup/test-nx-utils'; import { teardownTestFolder } from '@code-pushup/test-setup'; -import { omitVariableReportData } from '@code-pushup/test-utils'; +import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, + omitVariableReportData, +} from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; -describe('collect report with coverage-plugin NPM package', () => { - const envRoot = 'tmp/e2e/plugin-coverage-e2e'; - const fixtureDir = join('e2e', 'plugin-coverage-e2e', 'mocks', 'fixtures'); - const basicDir = join(envRoot, 'basic-setup'); - const existingDir = join(envRoot, 'existing-report'); +describe('PLUGIN collect report with coverage-plugin NPM package', () => { + const envRoot = join(E2E_ENVIRONMENTS_DIR, nxTargetProject()); + const testFileDir = join(envRoot, TEST_OUTPUT_DIR, 'collect'); + const basicDir = join(testFileDir, 'basic-setup'); + const existingDir = join(testFileDir, 'existing-report'); + + const fixtureDir = join('e2e', nxTargetProject(), 'mocks', 'fixtures'); beforeAll(async () => { - await cp(fixtureDir, envRoot, { recursive: true }); + await cp(fixtureDir, testFileDir, { recursive: true }); }); afterAll(async () => { await teardownTestFolder(basicDir); diff --git a/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index ea1b4434e..718d98fa3 100644 --- a/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -1,5 +1,143 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`PLUGIN collect report with eslint-plugin NPM package > should run ESLint plugin and create report.json 1`] = ` +{ + "categories": [ + { + "description": "Lint rules that find **potential bugs** in your code.", + "refs": [ + { + "plugin": "eslint", + "slug": "problems", + "type": "group", + "weight": 1, + }, + ], + "slug": "bug-prevention", + "title": "Bug prevention", + }, + { + "description": "Lint rules that promote **good practices** and consistency in your code.", + "refs": [ + { + "plugin": "eslint", + "slug": "suggestions", + "type": "group", + "weight": 1, + }, + ], + "slug": "code-style", + "title": "Code style", + }, + ], + "packageName": "@code-pushup/core", + "plugins": [ + { + "audits": [ + { + "description": "ESLint rule **no-unused-vars**.", + "details": { + "issues": [ + { + "message": "'unusedFn' is defined but never used.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-eslint-e2e/__test__/collect/old-version/src/index.js", + "position": { + "endColumn": 18, + "endLine": 1, + "startColumn": 10, + "startLine": 1, + }, + }, + }, + ], + }, + "displayValue": "1 error", + "docsUrl": "https://eslint.org/docs/latest/rules/no-unused-vars", + "score": 0, + "slug": "no-unused-vars", + "title": "Disallow unused variables", + "value": 1, + }, + { + "description": "ESLint rule **no-console**.", + "details": { + "issues": [ + { + "message": "Unexpected console statement.", + "severity": "warning", + "source": { + "file": "tmp/e2e/plugin-eslint-e2e/__test__/collect/old-version/src/index.js", + "position": { + "endColumn": 14, + "endLine": 6, + "startColumn": 3, + "startLine": 6, + }, + }, + }, + ], + }, + "displayValue": "1 warning", + "docsUrl": "https://eslint.org/docs/latest/rules/no-console", + "score": 0, + "slug": "no-console", + "title": "Disallow the use of \`console\`", + "value": 1, + }, + { + "description": "ESLint rule **no-undef**.", + "details": { + "issues": [], + }, + "displayValue": "passed", + "docsUrl": "https://eslint.org/docs/latest/rules/no-undef", + "score": 1, + "slug": "no-undef", + "title": "Disallow the use of undeclared variables unless mentioned in \`/*global */\` comments", + "value": 0, + }, + ], + "description": "Official Code PushUp ESLint plugin", + "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", + "groups": [ + { + "description": "Code that either will cause an error or may cause confusing behavior. Developers should consider this a high priority to resolve.", + "refs": [ + { + "slug": "no-unused-vars", + "weight": 1, + }, + { + "slug": "no-undef", + "weight": 1, + }, + ], + "slug": "problems", + "title": "Problems", + }, + { + "description": "Something that could be done in a better way but no errors will occur if the code isn't changed.", + "refs": [ + { + "slug": "no-console", + "weight": 1, + }, + ], + "slug": "suggestions", + "title": "Suggestions", + }, + ], + "icon": "eslint", + "packageName": "@code-pushup/eslint-plugin", + "slug": "eslint", + "title": "ESLint", + }, + ], +} +`; + exports[`collect report with eslint-plugin NPM package > should run ESLint plugin and create report.json 1`] = ` { "categories": [ diff --git a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts index 784f54056..449aa3bcb 100644 --- a/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts @@ -2,22 +2,32 @@ import { cp } from 'node:fs/promises'; import { join } from 'node:path'; import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; +import { nxTargetProject } from '@code-pushup/test-nx-utils'; import { teardownTestFolder } from '@code-pushup/test-setup'; -import { omitVariableReportData } from '@code-pushup/test-utils'; +import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, + omitVariableReportData, +} from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; -describe('collect report with eslint-plugin NPM package', () => { +describe('PLUGIN collect report with eslint-plugin NPM package', () => { + const testFileDir = join( + E2E_ENVIRONMENTS_DIR, + nxTargetProject(), + TEST_OUTPUT_DIR, + 'collect', + ); + const oldVersionDir = join(testFileDir, 'old-version'); + const oldVersionOutputDir = join(oldVersionDir, '.code-pushup'); + const fixturesOldVersionDir = join( 'e2e', - 'plugin-eslint-e2e', + nxTargetProject(), 'mocks', 'fixtures', 'old-version', ); - const envRoot = join('tmp', 'e2e', 'plugin-eslint-e2e'); - const oldVersionDir = join(envRoot, 'old-version'); - const oldVersionOutputDir = join(oldVersionDir, '.code-pushup'); - beforeAll(async () => { await cp(fixturesOldVersionDir, oldVersionDir, { recursive: true }); }); diff --git a/e2e/plugin-lighthouse-e2e/mocks/fixtures/code-pushup.config.lh-default.ts b/e2e/plugin-lighthouse-e2e/mocks/fixtures/default-setup/code-pushup.config.ts similarity index 100% rename from e2e/plugin-lighthouse-e2e/mocks/fixtures/code-pushup.config.lh-default.ts rename to e2e/plugin-lighthouse-e2e/mocks/fixtures/default-setup/code-pushup.config.ts diff --git a/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index af61a29f4..67a721514 100644 --- a/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -1,5 +1,135 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`PLUGIN collect report with lighthouse-plugin NPM package > should run plugin over CLI and creates report.json 1`] = ` +{ + "categories": [ + { + "refs": [ + { + "plugin": "lighthouse", + "slug": "performance", + "type": "group", + "weight": 1, + }, + ], + "slug": "performance", + "title": "Performance", + }, + { + "refs": [ + { + "plugin": "lighthouse", + "slug": "accessibility", + "type": "group", + "weight": 1, + }, + ], + "slug": "a11y", + "title": "Accessibility", + }, + { + "refs": [ + { + "plugin": "lighthouse", + "slug": "best-practices", + "type": "group", + "weight": 1, + }, + ], + "slug": "best-practices", + "title": "Best Practices", + }, + { + "refs": [ + { + "plugin": "lighthouse", + "slug": "seo", + "type": "group", + "weight": 1, + }, + ], + "slug": "seo", + "title": "SEO", + }, + ], + "packageName": "@code-pushup/core", + "plugins": [ + { + "audits": [ + { + "description": "Largest Contentful Paint marks the time at which the largest text or image is painted. [Learn more about the Largest Contentful Paint metric](https://developer.chrome.com/docs/lighthouse/performance/lighthouse-largest-contentful-paint/)", + "slug": "largest-contentful-paint", + "title": "Largest Contentful Paint", + }, + { + "description": "Deprecated APIs will eventually be removed from the browser. [Learn more about deprecated APIs](https://developer.chrome.com/docs/lighthouse/best-practices/deprecations/).", + "slug": "deprecations", + "title": "Avoids deprecated APIs", + }, + { + "description": "Each ARIA \`role\` supports a specific subset of \`aria-*\` attributes. Mismatching these invalidates the \`aria-*\` attributes. [Learn how to match ARIA attributes to their roles](https://dequeuniversity.com/rules/axe/4.10/aria-allowed-attr).", + "slug": "aria-allowed-attr", + "title": "\`[aria-*]\` attributes match their roles", + }, + { + "description": "hreflang links tell search engines what version of a page they should list in search results for a given language or region. [Learn more about \`hreflang\`](https://developer.chrome.com/docs/lighthouse/seo/hreflang/).", + "slug": "hreflang", + "title": "Document has a valid \`hreflang\`", + }, + ], + "groups": [ + { + "refs": [ + { + "slug": "largest-contentful-paint", + "weight": 25, + }, + ], + "slug": "performance", + "title": "Performance", + }, + { + "description": "These checks highlight opportunities to [improve the accessibility of your web app](https://developer.chrome.com/docs/lighthouse/accessibility/). Automatic detection can only detect a subset of issues and does not guarantee the accessibility of your web app, so [manual testing](https://web.dev/articles/how-to-review) is also encouraged.", + "refs": [ + { + "slug": "aria-allowed-attr", + "weight": 10, + }, + ], + "slug": "accessibility", + "title": "Accessibility", + }, + { + "refs": [ + { + "slug": "deprecations", + "weight": 5, + }, + ], + "slug": "best-practices", + "title": "Best Practices", + }, + { + "description": "These checks ensure that your page is following basic search engine optimization advice. There are many additional factors Lighthouse does not score here that may affect your search ranking, including performance on [Core Web Vitals](https://web.dev/explore/vitals). [Learn more about Google Search Essentials](https://support.google.com/webmasters/answer/35769).", + "refs": [ + { + "slug": "hreflang", + "weight": 1, + }, + ], + "slug": "seo", + "title": "SEO", + }, + ], + "icon": "lighthouse", + "packageName": "@code-pushup/lighthouse-plugin", + "slug": "lighthouse", + "title": "Lighthouse", + }, + ], +} +`; + exports[`collect report with lighthouse-plugin NPM package > should run plugin over CLI and creates report.json 1`] = ` { "categories": [ diff --git a/e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts b/e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts index 3f174bbc5..6938f28fe 100644 --- a/e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts @@ -1,45 +1,50 @@ -import { copyFile } from 'node:fs/promises'; +import { cp } from 'node:fs/promises'; import { join } from 'node:path'; -import { afterEach, expect } from 'vitest'; +import { afterAll, beforeAll, expect } from 'vitest'; import { type Report, reportSchema } from '@code-pushup/models'; -import { cleanTestFolder, teardownTestFolder } from '@code-pushup/test-setup'; +import { nxTargetProject } from '@code-pushup/test-nx-utils'; +import { teardownTestFolder } from '@code-pushup/test-setup'; import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, omitVariableReportData, removeColorCodes, } from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; -async function addCodePushupConfig(targetDir: string) { - await cleanTestFolder(targetDir); - await copyFile( - 'e2e/plugin-lighthouse-e2e/mocks/fixtures/code-pushup.config.lh-default.ts', - join(targetDir, 'code-pushup.config.ts'), +describe('PLUGIN collect report with lighthouse-plugin NPM package', () => { + const testFileDir = join( + E2E_ENVIRONMENTS_DIR, + nxTargetProject(), + TEST_OUTPUT_DIR, + 'collect', ); -} + const defaultSetupDir = join(testFileDir, 'default-setup'); -describe('collect report with lighthouse-plugin NPM package', () => { - const baseDir = 'tmp/e2e/plugin-lighthouse-e2e/__test__'; + const fixturesDir = join('e2e', nxTargetProject(), 'mocks/fixtures'); + beforeAll(async () => { + await cp(fixturesDir, testFileDir, { recursive: true }); + }); - afterEach(async () => { - await teardownTestFolder(baseDir); + afterAll(async () => { + // await teardownTestFolder(testFileDir); }); it('should run plugin over CLI and creates report.json', async () => { - const cwd = join(baseDir, 'create-report'); - await addCodePushupConfig(cwd); - const { code, stdout } = await executeProcess({ command: 'npx', // verbose exposes audits with perfect scores that are hidden in the default stdout args: ['@code-pushup/cli', 'collect', '--no-progress', '--verbose'], - cwd, + cwd: defaultSetupDir, }); expect(code).toBe(0); const cleanStdout = removeColorCodes(stdout); expect(cleanStdout).toContain('● Largest Contentful Paint'); - const report = await readJsonFile(join(cwd, '.code-pushup', 'report.json')); + const report = await readJsonFile( + join(defaultSetupDir, '.code-pushup', 'report.json'), + ); expect(() => reportSchema.parse(report)).not.toThrow(); expect( omitVariableReportData(report as Report, { omitAuditData: true }), diff --git a/testing/test-nx-utils/src/index.ts b/testing/test-nx-utils/src/index.ts index 972c232dc..74a844499 100644 --- a/testing/test-nx-utils/src/index.ts +++ b/testing/test-nx-utils/src/index.ts @@ -1,3 +1,4 @@ +export * from './lib/utils/environment'; export * from './lib/utils/nx'; export * from './lib/utils/nx-plugin'; export * from './lib/utils/tree'; diff --git a/testing/test-nx-utils/src/lib/utils/environment.ts b/testing/test-nx-utils/src/lib/utils/environment.ts new file mode 100644 index 000000000..09c2e65c1 --- /dev/null +++ b/testing/test-nx-utils/src/lib/utils/environment.ts @@ -0,0 +1,9 @@ +export const nxTargetProject = () => { + const project = process.env['NX_TASK_TARGET_PROJECT']; + if (project == null) { + throw new Error( + 'Process environment variable NX_TASK_TARGET_PROJECT is undefined.', + ); + } + return project; +}; diff --git a/testing/test-utils/src/lib/constants.ts b/testing/test-utils/src/lib/constants.ts index e6c076dac..dd76c5663 100644 --- a/testing/test-utils/src/lib/constants.ts +++ b/testing/test-utils/src/lib/constants.ts @@ -1,3 +1,6 @@ +export const E2E_ENVIRONMENTS_DIR = 'tmp/e2e'; +export const TEST_OUTPUT_DIR = '__test__'; +export const TEST_SNAPSHOTS_DIR = '__snapshots__'; export const MEMFS_VOLUME = '/test'; export const ISO_STRING_REGEXP = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/; From 2bcdae3e204ac00fbd0a0f91a12fab1165211b3f Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 21 Nov 2024 14:19:16 +0100 Subject: [PATCH 69/80] Update e2e/cli-e2e/tests/print-config.e2e.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- e2e/cli-e2e/tests/print-config.e2e.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/e2e/cli-e2e/tests/print-config.e2e.test.ts b/e2e/cli-e2e/tests/print-config.e2e.test.ts index c6443723c..7f8a06ae1 100644 --- a/e2e/cli-e2e/tests/print-config.e2e.test.ts +++ b/e2e/cli-e2e/tests/print-config.e2e.test.ts @@ -58,7 +58,6 @@ describe('CLI print-config', () => { expect.objectContaining({ config: expect.stringContaining(`code-pushup.config.${ext}`), tsconfig: 'tsconfig.base.json', - // filled by command options plugins: [ expect.objectContaining({ slug: 'dummy-plugin', From 027dfbd2742e09c8d811edbb063533e2c58d4936 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 21 Nov 2024 14:20:27 +0100 Subject: [PATCH 70/80] Update e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts b/e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts index 6938f28fe..22f9ecb73 100644 --- a/e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-lighthouse-e2e/tests/collect.e2e.test.ts @@ -27,7 +27,7 @@ describe('PLUGIN collect report with lighthouse-plugin NPM package', () => { }); afterAll(async () => { - // await teardownTestFolder(testFileDir); + await teardownTestFolder(testFileDir); }); it('should run plugin over CLI and creates report.json', async () => { From b3da1b37e76eeb866d8c6d13091b6a6c0c11701a Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 21 Nov 2024 15:51:52 +0100 Subject: [PATCH 71/80] test: update snapshots --- .../__snapshots__/collect.e2e.test.ts.snap | 473 ------------------ .../__snapshots__/collect.e2e.test.ts.snap | 138 ----- .../__snapshots__/collect.e2e.test.ts.snap | 130 ----- 3 files changed, 741 deletions(-) diff --git a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index 100d441fd..d3aa602e7 100644 --- a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -1,176 +1,5 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`PLUGIN collect report with coverage-plugin NPM package > should run Code coverage plugin that runs coverage tool and creates report.json 1`] = ` -{ - "categories": [ - { - "refs": [ - { - "plugin": "coverage", - "slug": "coverage", - "type": "group", - "weight": 1, - }, - ], - "slug": "code-coverage", - "title": "Code coverage", - }, - ], - "packageName": "@code-pushup/core", - "plugins": [ - { - "audits": [ - { - "description": "Measures how many functions were called in at least one test.", - "details": { - "issues": [ - { - "message": "Function formatReportScore is not called in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/partly-covered/utils.ts", - "position": { - "startLine": 2, - }, - }, - }, - { - "message": "Function sortReport is not called in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/not-covered/sorting.ts", - "position": { - "startLine": 1, - }, - }, - }, - ], - }, - "displayValue": "60 %", - "score": 0.6, - "slug": "function-coverage", - "title": "Function coverage", - "value": 60, - }, - { - "description": "Measures how many branches were executed after conditional statements in at least one test.", - "details": { - "issues": [ - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/partly-covered/utils.ts", - "position": { - "startLine": 6, - }, - }, - }, - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/partly-covered/utils.ts", - "position": { - "startLine": 10, - }, - }, - }, - { - "message": "1st branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/not-covered/sorting.ts", - "position": { - "startLine": 7, - }, - }, - }, - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/not-covered/sorting.ts", - "position": { - "startLine": 7, - }, - }, - }, - ], - }, - "displayValue": "76.5 %", - "score": 0.7647, - "slug": "branch-coverage", - "title": "Branch coverage", - "value": 76.47058823529412, - }, - { - "description": "Measures how many lines of code were executed in at least one test.", - "details": { - "issues": [ - { - "message": "Lines 7-9 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/partly-covered/utils.ts", - "position": { - "endLine": 9, - "startLine": 7, - }, - }, - }, - { - "message": "Lines 1-5 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/not-covered/sorting.ts", - "position": { - "endLine": 5, - "startLine": 1, - }, - }, - }, - ], - }, - "displayValue": "68 %", - "score": 0.68, - "slug": "line-coverage", - "title": "Line coverage", - "value": 68, - }, - ], - "description": "Official Code PushUp code coverage plugin.", - "docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/", - "groups": [ - { - "description": "Group containing all defined coverage types as audits.", - "refs": [ - { - "slug": "function-coverage", - "weight": 6, - }, - { - "slug": "branch-coverage", - "weight": 3, - }, - { - "slug": "line-coverage", - "weight": 1, - }, - ], - "slug": "coverage", - "title": "Code coverage metrics", - }, - ], - "icon": "folder-coverage-open", - "packageName": "@code-pushup/coverage-plugin", - "slug": "coverage", - "title": "Code coverage", - }, - ], -} -`; - exports[`PLUGIN collect report with coverage-plugin NPM package > should run Code coverage plugin which collects passed results and creates report.json 1`] = ` { "categories": [ @@ -301,305 +130,3 @@ exports[`PLUGIN collect report with coverage-plugin NPM package > should run Cod ], } `; - -exports[`collect report with coverage-plugin NPM package > should run Code coverage plugin that runs coverage tool and creates report.json 1`] = ` -{ - "categories": [ - { - "refs": [ - { - "plugin": "coverage", - "slug": "coverage", - "type": "group", - "weight": 1, - }, - ], - "slug": "code-coverage", - "title": "Code coverage", - }, - ], - "packageName": "@code-pushup/core", - "plugins": [ - { - "audits": [ - { - "description": "Measures how many functions were called in at least one test.", - "details": { - "issues": [ - { - "message": "Function formatReportScore is not called in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/partly-covered/utils.ts", - "position": { - "startLine": 2, - }, - }, - }, - { - "message": "Function sortReport is not called in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/not-covered/sorting.ts", - "position": { - "startLine": 1, - }, - }, - }, - ], - }, - "displayValue": "60 %", - "score": 0.6, - "slug": "function-coverage", - "title": "Function coverage", - "value": 60, - }, - { - "description": "Measures how many branches were executed after conditional statements in at least one test.", - "details": { - "issues": [ - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/partly-covered/utils.ts", - "position": { - "startLine": 6, - }, - }, - }, - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/partly-covered/utils.ts", - "position": { - "startLine": 10, - }, - }, - }, - { - "message": "1st branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/not-covered/sorting.ts", - "position": { - "startLine": 7, - }, - }, - }, - { - "message": "2nd branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/not-covered/sorting.ts", - "position": { - "startLine": 7, - }, - }, - }, - ], - }, - "displayValue": "76.5 %", - "score": 0.7647, - "slug": "branch-coverage", - "title": "Branch coverage", - "value": 76.47058823529412, - }, - { - "description": "Measures how many lines of code were executed in at least one test.", - "details": { - "issues": [ - { - "message": "Lines 7-9 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/partly-covered/utils.ts", - "position": { - "endLine": 9, - "startLine": 7, - }, - }, - }, - { - "message": "Lines 1-5 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/existing-report/src/lib/not-covered/sorting.ts", - "position": { - "endLine": 5, - "startLine": 1, - }, - }, - }, - ], - }, - "displayValue": "68 %", - "score": 0.68, - "slug": "line-coverage", - "title": "Line coverage", - "value": 68, - }, - ], - "description": "Official Code PushUp code coverage plugin.", - "docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/", - "groups": [ - { - "description": "Group containing all defined coverage types as audits.", - "refs": [ - { - "slug": "function-coverage", - "weight": 6, - }, - { - "slug": "branch-coverage", - "weight": 3, - }, - { - "slug": "line-coverage", - "weight": 1, - }, - ], - "slug": "coverage", - "title": "Code coverage metrics", - }, - ], - "icon": "folder-coverage-open", - "packageName": "@code-pushup/coverage-plugin", - "slug": "coverage", - "title": "Code coverage", - }, - ], -} -`; - -exports[`collect report with coverage-plugin NPM package > should run Code coverage plugin which collects passed results and creates report.json 1`] = ` -{ - "categories": [ - { - "refs": [ - { - "plugin": "coverage", - "slug": "coverage", - "type": "group", - "weight": 1, - }, - ], - "slug": "code-coverage", - "title": "Code coverage", - }, - ], - "packageName": "@code-pushup/core", - "plugins": [ - { - "audits": [ - { - "description": "Measures how many functions were called in at least one test.", - "details": { - "issues": [ - { - "message": "Function untested is not called in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/basic-setup/src/index.mjs", - "position": { - "startLine": 1, - }, - }, - }, - ], - }, - "displayValue": "66.7 %", - "score": 0.6667, - "slug": "function-coverage", - "title": "Function coverage", - "value": 66.66666666666666, - }, - { - "description": "Measures how many branches were executed after conditional statements in at least one test.", - "details": { - "issues": [ - { - "message": "1st branch is not taken in any test case.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/basic-setup/src/index.mjs", - "position": { - "startLine": 10, - }, - }, - }, - ], - }, - "displayValue": "66.7 %", - "score": 0.6667, - "slug": "branch-coverage", - "title": "Branch coverage", - "value": 66.66666666666666, - }, - { - "description": "Measures how many lines of code were executed in at least one test.", - "details": { - "issues": [ - { - "message": "Lines 2-3 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/basic-setup/src/index.mjs", - "position": { - "endLine": 3, - "startLine": 2, - }, - }, - }, - { - "message": "Lines 11-12 are not covered in any test case.", - "severity": "warning", - "source": { - "file": "tmp/e2e/plugin-coverage-e2e/basic-setup/src/index.mjs", - "position": { - "endLine": 12, - "startLine": 11, - }, - }, - }, - ], - }, - "displayValue": "73.3 %", - "score": 0.7333, - "slug": "line-coverage", - "title": "Line coverage", - "value": 73.33333333333333, - }, - ], - "description": "Official Code PushUp code coverage plugin.", - "docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/", - "groups": [ - { - "description": "Group containing all defined coverage types as audits.", - "refs": [ - { - "slug": "function-coverage", - "weight": 6, - }, - { - "slug": "branch-coverage", - "weight": 3, - }, - { - "slug": "line-coverage", - "weight": 1, - }, - ], - "slug": "coverage", - "title": "Code coverage metrics", - }, - ], - "icon": "folder-coverage-open", - "packageName": "@code-pushup/coverage-plugin", - "slug": "coverage", - "title": "Code coverage", - }, - ], -} -`; diff --git a/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index 718d98fa3..0b971386a 100644 --- a/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -137,141 +137,3 @@ exports[`PLUGIN collect report with eslint-plugin NPM package > should run ESLin ], } `; - -exports[`collect report with eslint-plugin NPM package > should run ESLint plugin and create report.json 1`] = ` -{ - "categories": [ - { - "description": "Lint rules that find **potential bugs** in your code.", - "refs": [ - { - "plugin": "eslint", - "slug": "problems", - "type": "group", - "weight": 1, - }, - ], - "slug": "bug-prevention", - "title": "Bug prevention", - }, - { - "description": "Lint rules that promote **good practices** and consistency in your code.", - "refs": [ - { - "plugin": "eslint", - "slug": "suggestions", - "type": "group", - "weight": 1, - }, - ], - "slug": "code-style", - "title": "Code style", - }, - ], - "packageName": "@code-pushup/core", - "plugins": [ - { - "audits": [ - { - "description": "ESLint rule **no-unused-vars**.", - "details": { - "issues": [ - { - "message": "'unusedFn' is defined but never used.", - "severity": "error", - "source": { - "file": "tmp/e2e/plugin-eslint-e2e/old-version/src/index.js", - "position": { - "endColumn": 18, - "endLine": 1, - "startColumn": 10, - "startLine": 1, - }, - }, - }, - ], - }, - "displayValue": "1 error", - "docsUrl": "https://eslint.org/docs/latest/rules/no-unused-vars", - "score": 0, - "slug": "no-unused-vars", - "title": "Disallow unused variables", - "value": 1, - }, - { - "description": "ESLint rule **no-console**.", - "details": { - "issues": [ - { - "message": "Unexpected console statement.", - "severity": "warning", - "source": { - "file": "tmp/e2e/plugin-eslint-e2e/old-version/src/index.js", - "position": { - "endColumn": 14, - "endLine": 6, - "startColumn": 3, - "startLine": 6, - }, - }, - }, - ], - }, - "displayValue": "1 warning", - "docsUrl": "https://eslint.org/docs/latest/rules/no-console", - "score": 0, - "slug": "no-console", - "title": "Disallow the use of \`console\`", - "value": 1, - }, - { - "description": "ESLint rule **no-undef**.", - "details": { - "issues": [], - }, - "displayValue": "passed", - "docsUrl": "https://eslint.org/docs/latest/rules/no-undef", - "score": 1, - "slug": "no-undef", - "title": "Disallow the use of undeclared variables unless mentioned in \`/*global */\` comments", - "value": 0, - }, - ], - "description": "Official Code PushUp ESLint plugin", - "docsUrl": "https://www.npmjs.com/package/@code-pushup/eslint-plugin", - "groups": [ - { - "description": "Code that either will cause an error or may cause confusing behavior. Developers should consider this a high priority to resolve.", - "refs": [ - { - "slug": "no-unused-vars", - "weight": 1, - }, - { - "slug": "no-undef", - "weight": 1, - }, - ], - "slug": "problems", - "title": "Problems", - }, - { - "description": "Something that could be done in a better way but no errors will occur if the code isn't changed.", - "refs": [ - { - "slug": "no-console", - "weight": 1, - }, - ], - "slug": "suggestions", - "title": "Suggestions", - }, - ], - "icon": "eslint", - "packageName": "@code-pushup/eslint-plugin", - "slug": "eslint", - "title": "ESLint", - }, - ], -} -`; diff --git a/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index 67a721514..ccf448795 100644 --- a/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -129,133 +129,3 @@ exports[`PLUGIN collect report with lighthouse-plugin NPM package > should run p ], } `; - -exports[`collect report with lighthouse-plugin NPM package > should run plugin over CLI and creates report.json 1`] = ` -{ - "categories": [ - { - "refs": [ - { - "plugin": "lighthouse", - "slug": "performance", - "type": "group", - "weight": 1, - }, - ], - "slug": "performance", - "title": "Performance", - }, - { - "refs": [ - { - "plugin": "lighthouse", - "slug": "accessibility", - "type": "group", - "weight": 1, - }, - ], - "slug": "a11y", - "title": "Accessibility", - }, - { - "refs": [ - { - "plugin": "lighthouse", - "slug": "best-practices", - "type": "group", - "weight": 1, - }, - ], - "slug": "best-practices", - "title": "Best Practices", - }, - { - "refs": [ - { - "plugin": "lighthouse", - "slug": "seo", - "type": "group", - "weight": 1, - }, - ], - "slug": "seo", - "title": "SEO", - }, - ], - "packageName": "@code-pushup/core", - "plugins": [ - { - "audits": [ - { - "description": "Largest Contentful Paint marks the time at which the largest text or image is painted. [Learn more about the Largest Contentful Paint metric](https://developer.chrome.com/docs/lighthouse/performance/lighthouse-largest-contentful-paint/)", - "slug": "largest-contentful-paint", - "title": "Largest Contentful Paint", - }, - { - "description": "Deprecated APIs will eventually be removed from the browser. [Learn more about deprecated APIs](https://developer.chrome.com/docs/lighthouse/best-practices/deprecations/).", - "slug": "deprecations", - "title": "Avoids deprecated APIs", - }, - { - "description": "Each ARIA \`role\` supports a specific subset of \`aria-*\` attributes. Mismatching these invalidates the \`aria-*\` attributes. [Learn how to match ARIA attributes to their roles](https://dequeuniversity.com/rules/axe/4.10/aria-allowed-attr).", - "slug": "aria-allowed-attr", - "title": "\`[aria-*]\` attributes match their roles", - }, - { - "description": "hreflang links tell search engines what version of a page they should list in search results for a given language or region. [Learn more about \`hreflang\`](https://developer.chrome.com/docs/lighthouse/seo/hreflang/).", - "slug": "hreflang", - "title": "Document has a valid \`hreflang\`", - }, - ], - "groups": [ - { - "refs": [ - { - "slug": "largest-contentful-paint", - "weight": 25, - }, - ], - "slug": "performance", - "title": "Performance", - }, - { - "description": "These checks highlight opportunities to [improve the accessibility of your web app](https://developer.chrome.com/docs/lighthouse/accessibility/). Automatic detection can only detect a subset of issues and does not guarantee the accessibility of your web app, so [manual testing](https://web.dev/articles/how-to-review) is also encouraged.", - "refs": [ - { - "slug": "aria-allowed-attr", - "weight": 10, - }, - ], - "slug": "accessibility", - "title": "Accessibility", - }, - { - "refs": [ - { - "slug": "deprecations", - "weight": 5, - }, - ], - "slug": "best-practices", - "title": "Best Practices", - }, - { - "description": "These checks ensure that your page is following basic search engine optimization advice. There are many additional factors Lighthouse does not score here that may affect your search ranking, including performance on [Core Web Vitals](https://web.dev/explore/vitals). [Learn more about Google Search Essentials](https://support.google.com/webmasters/answer/35769).", - "refs": [ - { - "slug": "hreflang", - "weight": 1, - }, - ], - "slug": "seo", - "title": "SEO", - }, - ], - "icon": "lighthouse", - "packageName": "@code-pushup/lighthouse-plugin", - "slug": "lighthouse", - "title": "Lighthouse", - }, - ], -} -`; From b99bfea80751a3a3f58c2ef7f508c3ef52051156 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 21 Nov 2024 15:53:02 +0100 Subject: [PATCH 72/80] test: cleanup static env --- static-environments/cli-e2e-env/package.json | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 static-environments/cli-e2e-env/package.json diff --git a/static-environments/cli-e2e-env/package.json b/static-environments/cli-e2e-env/package.json deleted file mode 100644 index d1862c6c8..000000000 --- a/static-environments/cli-e2e-env/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "cli-e2e-env", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "@code-pushup/cli": "^0.54.0", - "@code-pushup/core": "^0.54.0", - "@code-pushup/models": "^0.54.0", - "@code-pushup/utils": "^0.54.0" - } -} From 26d1ac0dacdc667158d9834b51f1ebe556b9e650 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 21 Nov 2024 16:15:12 +0100 Subject: [PATCH 73/80] test: cleanup snapshots --- .../__snapshots__/collect.e2e.test.ts.snap | 131 ------------------ 1 file changed, 131 deletions(-) delete mode 100644 e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap diff --git a/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap deleted file mode 100644 index ccf448795..000000000 --- a/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ /dev/null @@ -1,131 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`PLUGIN collect report with lighthouse-plugin NPM package > should run plugin over CLI and creates report.json 1`] = ` -{ - "categories": [ - { - "refs": [ - { - "plugin": "lighthouse", - "slug": "performance", - "type": "group", - "weight": 1, - }, - ], - "slug": "performance", - "title": "Performance", - }, - { - "refs": [ - { - "plugin": "lighthouse", - "slug": "accessibility", - "type": "group", - "weight": 1, - }, - ], - "slug": "a11y", - "title": "Accessibility", - }, - { - "refs": [ - { - "plugin": "lighthouse", - "slug": "best-practices", - "type": "group", - "weight": 1, - }, - ], - "slug": "best-practices", - "title": "Best Practices", - }, - { - "refs": [ - { - "plugin": "lighthouse", - "slug": "seo", - "type": "group", - "weight": 1, - }, - ], - "slug": "seo", - "title": "SEO", - }, - ], - "packageName": "@code-pushup/core", - "plugins": [ - { - "audits": [ - { - "description": "Largest Contentful Paint marks the time at which the largest text or image is painted. [Learn more about the Largest Contentful Paint metric](https://developer.chrome.com/docs/lighthouse/performance/lighthouse-largest-contentful-paint/)", - "slug": "largest-contentful-paint", - "title": "Largest Contentful Paint", - }, - { - "description": "Deprecated APIs will eventually be removed from the browser. [Learn more about deprecated APIs](https://developer.chrome.com/docs/lighthouse/best-practices/deprecations/).", - "slug": "deprecations", - "title": "Avoids deprecated APIs", - }, - { - "description": "Each ARIA \`role\` supports a specific subset of \`aria-*\` attributes. Mismatching these invalidates the \`aria-*\` attributes. [Learn how to match ARIA attributes to their roles](https://dequeuniversity.com/rules/axe/4.10/aria-allowed-attr).", - "slug": "aria-allowed-attr", - "title": "\`[aria-*]\` attributes match their roles", - }, - { - "description": "hreflang links tell search engines what version of a page they should list in search results for a given language or region. [Learn more about \`hreflang\`](https://developer.chrome.com/docs/lighthouse/seo/hreflang/).", - "slug": "hreflang", - "title": "Document has a valid \`hreflang\`", - }, - ], - "groups": [ - { - "refs": [ - { - "slug": "largest-contentful-paint", - "weight": 25, - }, - ], - "slug": "performance", - "title": "Performance", - }, - { - "description": "These checks highlight opportunities to [improve the accessibility of your web app](https://developer.chrome.com/docs/lighthouse/accessibility/). Automatic detection can only detect a subset of issues and does not guarantee the accessibility of your web app, so [manual testing](https://web.dev/articles/how-to-review) is also encouraged.", - "refs": [ - { - "slug": "aria-allowed-attr", - "weight": 10, - }, - ], - "slug": "accessibility", - "title": "Accessibility", - }, - { - "refs": [ - { - "slug": "deprecations", - "weight": 5, - }, - ], - "slug": "best-practices", - "title": "Best Practices", - }, - { - "description": "These checks ensure that your page is following basic search engine optimization advice. There are many additional factors Lighthouse does not score here that may affect your search ranking, including performance on [Core Web Vitals](https://web.dev/explore/vitals). [Learn more about Google Search Essentials](https://support.google.com/webmasters/answer/35769).", - "refs": [ - { - "slug": "hreflang", - "weight": 1, - }, - ], - "slug": "seo", - "title": "SEO", - }, - ], - "icon": "lighthouse", - "packageName": "@code-pushup/lighthouse-plugin", - "slug": "lighthouse", - "title": "Lighthouse", - }, - ], -} -`; From b20651b82bd45bc3059d27af8b154092f9dde8dc Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 21 Nov 2024 16:22:52 +0100 Subject: [PATCH 74/80] test: cleanup snapshots --- .../__snapshots__/collect.e2e.test.ts.snap | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) diff --git a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index d3aa602e7..bc4f67f68 100644 --- a/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-coverage-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -1,5 +1,176 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`PLUGIN collect report with coverage-plugin NPM package > should run Code coverage plugin that runs coverage tool and creates report.json 1`] = ` +{ + "categories": [ + { + "refs": [ + { + "plugin": "coverage", + "slug": "coverage", + "type": "group", + "weight": 1, + }, + ], + "slug": "code-coverage", + "title": "Code coverage", + }, + ], + "packageName": "@code-pushup/core", + "plugins": [ + { + "audits": [ + { + "description": "Measures how many functions were called in at least one test.", + "details": { + "issues": [ + { + "message": "Function formatReportScore is not called in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/partly-covered/utils.ts", + "position": { + "startLine": 2, + }, + }, + }, + { + "message": "Function sortReport is not called in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/not-covered/sorting.ts", + "position": { + "startLine": 1, + }, + }, + }, + ], + }, + "displayValue": "60 %", + "score": 0.6, + "slug": "function-coverage", + "title": "Function coverage", + "value": 60, + }, + { + "description": "Measures how many branches were executed after conditional statements in at least one test.", + "details": { + "issues": [ + { + "message": "2nd branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/partly-covered/utils.ts", + "position": { + "startLine": 6, + }, + }, + }, + { + "message": "2nd branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/partly-covered/utils.ts", + "position": { + "startLine": 10, + }, + }, + }, + { + "message": "1st branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/not-covered/sorting.ts", + "position": { + "startLine": 7, + }, + }, + }, + { + "message": "2nd branch is not taken in any test case.", + "severity": "error", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/not-covered/sorting.ts", + "position": { + "startLine": 7, + }, + }, + }, + ], + }, + "displayValue": "76.5 %", + "score": 0.7647, + "slug": "branch-coverage", + "title": "Branch coverage", + "value": 76.47058823529412, + }, + { + "description": "Measures how many lines of code were executed in at least one test.", + "details": { + "issues": [ + { + "message": "Lines 7-9 are not covered in any test case.", + "severity": "warning", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/partly-covered/utils.ts", + "position": { + "endLine": 9, + "startLine": 7, + }, + }, + }, + { + "message": "Lines 1-5 are not covered in any test case.", + "severity": "warning", + "source": { + "file": "tmp/e2e/plugin-coverage-e2e/__test__/collect/existing-report/src/lib/not-covered/sorting.ts", + "position": { + "endLine": 5, + "startLine": 1, + }, + }, + }, + ], + }, + "displayValue": "68 %", + "score": 0.68, + "slug": "line-coverage", + "title": "Line coverage", + "value": 68, + }, + ], + "description": "Official Code PushUp code coverage plugin.", + "docsUrl": "https://www.npmjs.com/package/@code-pushup/coverage-plugin/", + "groups": [ + { + "description": "Group containing all defined coverage types as audits.", + "refs": [ + { + "slug": "function-coverage", + "weight": 6, + }, + { + "slug": "branch-coverage", + "weight": 3, + }, + { + "slug": "line-coverage", + "weight": 1, + }, + ], + "slug": "coverage", + "title": "Code coverage metrics", + }, + ], + "icon": "folder-coverage-open", + "packageName": "@code-pushup/coverage-plugin", + "slug": "coverage", + "title": "Code coverage", + }, + ], +} +`; + exports[`PLUGIN collect report with coverage-plugin NPM package > should run Code coverage plugin which collects passed results and creates report.json 1`] = ` { "categories": [ From e73edc2ab1585a2fbae46861a2d04c5765323e1b Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 21 Nov 2024 16:35:18 +0100 Subject: [PATCH 75/80] test: cleanup snapshots --- .../__snapshots__/collect.e2e.test.ts.snap | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap diff --git a/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap new file mode 100644 index 000000000..ccf448795 --- /dev/null +++ b/e2e/plugin-lighthouse-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -0,0 +1,131 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`PLUGIN collect report with lighthouse-plugin NPM package > should run plugin over CLI and creates report.json 1`] = ` +{ + "categories": [ + { + "refs": [ + { + "plugin": "lighthouse", + "slug": "performance", + "type": "group", + "weight": 1, + }, + ], + "slug": "performance", + "title": "Performance", + }, + { + "refs": [ + { + "plugin": "lighthouse", + "slug": "accessibility", + "type": "group", + "weight": 1, + }, + ], + "slug": "a11y", + "title": "Accessibility", + }, + { + "refs": [ + { + "plugin": "lighthouse", + "slug": "best-practices", + "type": "group", + "weight": 1, + }, + ], + "slug": "best-practices", + "title": "Best Practices", + }, + { + "refs": [ + { + "plugin": "lighthouse", + "slug": "seo", + "type": "group", + "weight": 1, + }, + ], + "slug": "seo", + "title": "SEO", + }, + ], + "packageName": "@code-pushup/core", + "plugins": [ + { + "audits": [ + { + "description": "Largest Contentful Paint marks the time at which the largest text or image is painted. [Learn more about the Largest Contentful Paint metric](https://developer.chrome.com/docs/lighthouse/performance/lighthouse-largest-contentful-paint/)", + "slug": "largest-contentful-paint", + "title": "Largest Contentful Paint", + }, + { + "description": "Deprecated APIs will eventually be removed from the browser. [Learn more about deprecated APIs](https://developer.chrome.com/docs/lighthouse/best-practices/deprecations/).", + "slug": "deprecations", + "title": "Avoids deprecated APIs", + }, + { + "description": "Each ARIA \`role\` supports a specific subset of \`aria-*\` attributes. Mismatching these invalidates the \`aria-*\` attributes. [Learn how to match ARIA attributes to their roles](https://dequeuniversity.com/rules/axe/4.10/aria-allowed-attr).", + "slug": "aria-allowed-attr", + "title": "\`[aria-*]\` attributes match their roles", + }, + { + "description": "hreflang links tell search engines what version of a page they should list in search results for a given language or region. [Learn more about \`hreflang\`](https://developer.chrome.com/docs/lighthouse/seo/hreflang/).", + "slug": "hreflang", + "title": "Document has a valid \`hreflang\`", + }, + ], + "groups": [ + { + "refs": [ + { + "slug": "largest-contentful-paint", + "weight": 25, + }, + ], + "slug": "performance", + "title": "Performance", + }, + { + "description": "These checks highlight opportunities to [improve the accessibility of your web app](https://developer.chrome.com/docs/lighthouse/accessibility/). Automatic detection can only detect a subset of issues and does not guarantee the accessibility of your web app, so [manual testing](https://web.dev/articles/how-to-review) is also encouraged.", + "refs": [ + { + "slug": "aria-allowed-attr", + "weight": 10, + }, + ], + "slug": "accessibility", + "title": "Accessibility", + }, + { + "refs": [ + { + "slug": "deprecations", + "weight": 5, + }, + ], + "slug": "best-practices", + "title": "Best Practices", + }, + { + "description": "These checks ensure that your page is following basic search engine optimization advice. There are many additional factors Lighthouse does not score here that may affect your search ranking, including performance on [Core Web Vitals](https://web.dev/explore/vitals). [Learn more about Google Search Essentials](https://support.google.com/webmasters/answer/35769).", + "refs": [ + { + "slug": "hreflang", + "weight": 1, + }, + ], + "slug": "seo", + "title": "SEO", + }, + ], + "icon": "lighthouse", + "packageName": "@code-pushup/lighthouse-plugin", + "slug": "lighthouse", + "title": "Lighthouse", + }, + ], +} +`; From 88bf84cbd8d7715a9d45f4cc76842f58d3dfa66e Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 22 Nov 2024 15:22:42 +0100 Subject: [PATCH 76/80] test: cleanup deps --- e2e/create-cli-e2e/project.json | 9 +------- e2e/create-cli-e2e/tests/init.e2e.test.ts | 28 ++++------------------- testing/test-nx-utils/project.json | 2 +- 3 files changed, 6 insertions(+), 33 deletions(-) diff --git a/e2e/create-cli-e2e/project.json b/e2e/create-cli-e2e/project.json index c216582b8..ecb0d138f 100644 --- a/e2e/create-cli-e2e/project.json +++ b/e2e/create-cli-e2e/project.json @@ -18,13 +18,6 @@ } } }, - "implicitDependencies": [ - "models", - "utils", - "core", - "cli", - "nx-plugin", - "create-cli" - ], + "implicitDependencies": ["create-cli"], "tags": ["scope:tooling", "type:e2e"] } diff --git a/e2e/create-cli-e2e/tests/init.e2e.test.ts b/e2e/create-cli-e2e/tests/init.e2e.test.ts index ba6d08ff8..8f1deb07a 100644 --- a/e2e/create-cli-e2e/tests/init.e2e.test.ts +++ b/e2e/create-cli-e2e/tests/init.e2e.test.ts @@ -20,16 +20,10 @@ describe('create-cli-inti', () => { it('should execute package correctly over npm exec', async () => { const cwd = join(testFileDir, 'npm-exec'); - const userconfig = relative(cwd, join(workspaceRoot, '.npmrc')); await createNpmWorkspace(cwd); const { code, stdout } = await executeProcess({ command: 'npm', - args: [ - 'exec', - '@code-pushup/create-cli', - `--userconfig=${userconfig}`, - `--prefix=${dirname(userconfig)}`, - ], + args: ['exec', '@code-pushup/create-cli'], cwd, }); @@ -60,18 +54,11 @@ describe('create-cli-inti', () => { it('should execute package correctly over npm init', async () => { const cwd = join(testFileDir, 'npm-init'); - const userconfig = relative(cwd, join(workspaceRoot, '.npmrc')); - await createNpmWorkspace(cwd); const { code, stdout } = await executeProcess({ command: 'npm', - args: [ - 'init', - '@code-pushup/cli', - `--userconfig=${userconfig}`, - `--prefix=${dirname(userconfig)}`, - ], + args: ['init', '@code-pushup/cli'], cwd, }); @@ -102,25 +89,18 @@ describe('create-cli-inti', () => { it('should produce an executable setup when running npm init', async () => { const cwd = join(testFileDir, 'npm-init-executable'); - const userconfig = relative(cwd, join(workspaceRoot, '.npmrc')); - await createNpmWorkspace(cwd); await executeProcess({ command: 'npm', - args: [ - 'init', - '@code-pushup/cli', - `--userconfig=${userconfig}`, - `--prefix=${dirname(userconfig)}`, - ], + args: ['init', '@code-pushup/cli'], cwd, }); await expect( executeProcess({ command: 'npx', - args: ['@code-pushup/cli print-config', `--userconfig=${userconfig}`], + args: ['@code-pushup/cli print-config'], cwd, }), ) diff --git a/testing/test-nx-utils/project.json b/testing/test-nx-utils/project.json index 5e60491be..72d84d1c7 100644 --- a/testing/test-nx-utils/project.json +++ b/testing/test-nx-utils/project.json @@ -29,5 +29,5 @@ } } }, - "tags": ["scope:tooling", "type:testing"] + "tags": ["scope:shared", "type:testing"] } From c6d1aeb2bcc011247b08eb4d93da2900547ca4cb Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 22 Nov 2024 16:26:12 +0100 Subject: [PATCH 77/80] refactor: fix lint --- e2e/create-cli-e2e/tests/init.e2e.test.ts | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/e2e/create-cli-e2e/tests/init.e2e.test.ts b/e2e/create-cli-e2e/tests/init.e2e.test.ts index 8f1deb07a..cf52bfd24 100644 --- a/e2e/create-cli-e2e/tests/init.e2e.test.ts +++ b/e2e/create-cli-e2e/tests/init.e2e.test.ts @@ -1,14 +1,9 @@ -import { dirname, join, relative } from 'node:path'; -import { afterEach, expect } from 'vitest'; -import { nxTargetProject } from '@code-pushup/test-nx-utils'; -import { teardownTestFolder } from '@code-pushup/test-setup'; -import { - E2E_ENVIRONMENTS_DIR, - TEST_OUTPUT_DIR, - createNpmWorkspace, - removeColorCodes, -} from '@code-pushup/test-utils'; -import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; +import {join} from 'node:path'; +import {afterEach, expect} from 'vitest'; +import {nxTargetProject} from '@code-pushup/test-nx-utils'; +import {teardownTestFolder} from '@code-pushup/test-setup'; +import {createNpmWorkspace, E2E_ENVIRONMENTS_DIR, removeColorCodes, TEST_OUTPUT_DIR,} from '@code-pushup/test-utils'; +import {executeProcess, readJsonFile, readTextFile} from '@code-pushup/utils'; describe('create-cli-inti', () => { const workspaceRoot = join(E2E_ENVIRONMENTS_DIR, nxTargetProject()); @@ -53,7 +48,7 @@ describe('create-cli-inti', () => { }); it('should execute package correctly over npm init', async () => { - const cwd = join(testFileDir, 'npm-init'); + const cwd = join(testFileDir, 'npm-init-setup'); await createNpmWorkspace(cwd); const { code, stdout } = await executeProcess({ From 93e72fb4c763afdbbf481099a1fbc9a9c1903428 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 22 Nov 2024 16:28:09 +0100 Subject: [PATCH 78/80] refactor: fix format --- e2e/create-cli-e2e/tests/init.e2e.test.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/e2e/create-cli-e2e/tests/init.e2e.test.ts b/e2e/create-cli-e2e/tests/init.e2e.test.ts index cf52bfd24..9077d9b49 100644 --- a/e2e/create-cli-e2e/tests/init.e2e.test.ts +++ b/e2e/create-cli-e2e/tests/init.e2e.test.ts @@ -1,9 +1,14 @@ -import {join} from 'node:path'; -import {afterEach, expect} from 'vitest'; -import {nxTargetProject} from '@code-pushup/test-nx-utils'; -import {teardownTestFolder} from '@code-pushup/test-setup'; -import {createNpmWorkspace, E2E_ENVIRONMENTS_DIR, removeColorCodes, TEST_OUTPUT_DIR,} from '@code-pushup/test-utils'; -import {executeProcess, readJsonFile, readTextFile} from '@code-pushup/utils'; +import { join } from 'node:path'; +import { afterEach, expect } from 'vitest'; +import { nxTargetProject } from '@code-pushup/test-nx-utils'; +import { teardownTestFolder } from '@code-pushup/test-setup'; +import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, + createNpmWorkspace, + removeColorCodes, +} from '@code-pushup/test-utils'; +import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; describe('create-cli-inti', () => { const workspaceRoot = join(E2E_ENVIRONMENTS_DIR, nxTargetProject()); From 80f7708a27bbf75afe3cd14a418ef249358ecd72 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 23 Nov 2024 18:21:21 +0100 Subject: [PATCH 79/80] test: update snapshots --- .../tests/__snapshots__/collect.e2e.test.ts.snap | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index a7f23fd22..b20625b3b 100644 --- a/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-eslint-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`collect report with eslint-plugin NPM package > should run ESLint plugin for flat config and create report.json 1`] = ` +exports[`PLUGIN collect report with eslint-plugin NPM package > should run ESLint plugin for flat config and create report.json 1`] = ` { "packageName": "@code-pushup/core", "plugins": [ @@ -14,7 +14,7 @@ exports[`collect report with eslint-plugin NPM package > should run ESLint plugi "message": "Expected '===' and instead saw '=='.", "severity": "error", "source": { - "file": "tmp/e2e/plugin-eslint-e2e/flat-config/src/index.js", + "file": "tmp/e2e/plugin-eslint-e2e/__test__/flat-config/src/index.js", "position": { "endColumn": 15, "endLine": 6, @@ -58,7 +58,7 @@ Custom options: "message": "'unusedFn' is defined but never used.", "severity": "warning", "source": { - "file": "tmp/e2e/plugin-eslint-e2e/flat-config/src/index.js", + "file": "tmp/e2e/plugin-eslint-e2e/__test__/flat-config/src/index.js", "position": { "endColumn": 18, "endLine": 1, @@ -116,7 +116,7 @@ Custom options: } `; -exports[`collect report with eslint-plugin NPM package > should run ESLint plugin for legacy config and create report.json 1`] = ` +exports[`PLUGIN collect report with eslint-plugin NPM package > should run ESLint plugin for legacy config and create report.json 1`] = ` { "packageName": "@code-pushup/core", "plugins": [ @@ -130,7 +130,7 @@ exports[`collect report with eslint-plugin NPM package > should run ESLint plugi "message": "'unusedFn' is defined but never used.", "severity": "error", "source": { - "file": "tmp/e2e/plugin-eslint-e2e/legacy-config/src/index.js", + "file": "tmp/e2e/plugin-eslint-e2e/__test__/legacy-config/src/index.js", "position": { "endColumn": 18, "endLine": 1, @@ -156,7 +156,7 @@ exports[`collect report with eslint-plugin NPM package > should run ESLint plugi "message": "Unexpected console statement.", "severity": "warning", "source": { - "file": "tmp/e2e/plugin-eslint-e2e/legacy-config/src/index.js", + "file": "tmp/e2e/plugin-eslint-e2e/__test__/legacy-config/src/index.js", "position": { "endColumn": 14, "endLine": 5, From 81784764ae39f9c9948ac00a06f5b0be341eb221 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 23 Nov 2024 18:29:49 +0100 Subject: [PATCH 80/80] test: cleanup old test setup --- global-setup.e2e.ts | 71 --------------------------------------- global-setup.verdaccio.ts | 43 ------------------------ 2 files changed, 114 deletions(-) delete mode 100644 global-setup.e2e.ts delete mode 100644 global-setup.verdaccio.ts diff --git a/global-setup.e2e.ts b/global-setup.e2e.ts deleted file mode 100644 index 2ae31fc30..000000000 --- a/global-setup.e2e.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { rm, writeFile } from 'node:fs/promises'; -import { join } from 'node:path'; -import { setup as globalSetup } from './global-setup'; -import { setupTestFolder, teardownTestFolder } from './testing/test-setup/src'; -import { - nxRunManyNpmInstall, - nxRunManyNpmUninstall, -} from './tools/src/npm/utils'; -import { findLatestVersion, nxRunManyPublish } from './tools/src/publish/utils'; -import { START_VERDACCIO_SERVER_TARGET_NAME } from './tools/src/verdaccio/constants'; -import startLocalRegistry, { - RegistryResult, -} from './tools/src/verdaccio/start-local-registry'; -import stopLocalRegistry from './tools/src/verdaccio/stop-local-registry'; -import { uniquePort } from './tools/src/verdaccio/utils'; - -const e2eDir = join('tmp', 'e2e', 'react-todos-app'); -const uniqueDir = join(e2eDir, `registry-${uniquePort()}`); - -let activeRegistry: RegistryResult; - -export async function setup() { - await globalSetup(); - await setupTestFolder(e2eDir); - - try { - activeRegistry = await startLocalRegistry({ - localRegistryTarget: `@code-pushup/cli-source:${START_VERDACCIO_SERVER_TARGET_NAME}`, - storage: join(uniqueDir, 'storage'), - port: uniquePort(), - }); - } catch (error) { - console.error('Error starting local verdaccio registry:\n' + error.message); - throw error; - } - - // package publish - const { registry } = activeRegistry.registryData; - await writeFile('.npmrc', `@code-pushup:registry=${registry}`); - try { - console.info('Publish packages'); - nxRunManyPublish({ - registry, - nextVersion: findLatestVersion(), - parallel: 1, - }); - } catch (error) { - console.error('Error publishing packages:\n' + error.message); - throw error; - } - - // package install - try { - console.info('Installing packages'); - nxRunManyNpmInstall({ registry, parallel: 1 }); - } catch (error) { - console.error('Error installing packages:\n' + error.message); - throw error; - } -} - -export async function teardown() { - if (activeRegistry && 'registryData' in activeRegistry) { - const { stop } = activeRegistry; - - stopLocalRegistry(stop); - nxRunManyNpmUninstall({ parallel: 1 }); - } - await rm('.npmrc'); - await teardownTestFolder(e2eDir); -} diff --git a/global-setup.verdaccio.ts b/global-setup.verdaccio.ts deleted file mode 100644 index e1aa9f958..000000000 --- a/global-setup.verdaccio.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { setup as globalSetup } from './global-setup'; -import { executeProcess, objectToCliArgs } from './packages/utils/src'; -import { - VerdaccioEnvResult, - nxStartVerdaccioAndSetupEnv, - nxStopVerdaccioAndTeardownEnv, -} from './tools/src/verdaccio/env'; - -let activeRegistry: VerdaccioEnvResult; -const projectName = process.env['NX_TASK_TARGET_PROJECT']; - -export async function setup() { - await globalSetup(); - - try { - activeRegistry = await nxStartVerdaccioAndSetupEnv({ - projectName: projectName, - verbose: true, - }); - } catch (error) { - console.error('Error starting local verdaccio registry:\n' + error.message); - throw error; - } - - const { userconfig, workspaceRoot } = activeRegistry; - await executeProcess({ - command: 'npx', - args: objectToCliArgs({ - _: ['nx', 'setup-deps', projectName], - registry: activeRegistry.registry.url, // publish - userconfig, // publish & install - prefix: workspaceRoot, // install - }), - observer: { onStdout: stdout => console.info(stdout) }, - }); -} - -export async function teardown() { - // NOTICE - Time saving optimization - // We skip uninstalling packages as the folder is deleted anyway - - await nxStopVerdaccioAndTeardownEnv(activeRegistry); -}