diff --git a/e2e/cli-e2e/tests/collect.e2e.test.ts b/e2e/cli-e2e/tests/collect.e2e.test.ts index 269fae9fb..912068b58 100644 --- a/e2e/cli-e2e/tests/collect.e2e.test.ts +++ b/e2e/cli-e2e/tests/collect.e2e.test.ts @@ -1,11 +1,6 @@ -import { - type AuditReport, - type PluginReport, - type Report, - reportSchema, -} from '@code-pushup/models'; +import type { AuditReport, PluginReport, Report } from '@code-pushup/models'; import { cleanTestFolder } from '@code-pushup/test-setup'; -import { executeProcess, readJsonFile, readTextFile } from '@code-pushup/utils'; +import { executeProcess, readTextFile } from '@code-pushup/utils'; describe('CLI collect', () => { const exampleCategoryTitle = 'Code style'; @@ -47,22 +42,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 create report.md', async () => { const { code, stderr } = await executeProcess({ command: 'code-pushup', diff --git a/e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/package.json b/e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/package.json index 61a96ca4c..496bd05b4 100644 --- a/e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/package.json +++ b/e2e/plugin-coverage-e2e/mocks/fixtures/basic-setup/package.json @@ -8,7 +8,6 @@ "keywords": [], "author": "", "license": "ISC", - "dependencies": { - }, + "dependencies": {}, "description": "" } 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/mocks/fixtures/old-version/.eslintrc.json b/e2e/plugin-eslint-e2e/mocks/fixtures/old-version/.eslintrc.json new file mode 100644 index 000000000..113136c93 --- /dev/null +++ b/e2e/plugin-eslint-e2e/mocks/fixtures/old-version/.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/mocks/fixtures/old-version/code-pushup.config.ts b/e2e/plugin-eslint-e2e/mocks/fixtures/old-version/code-pushup.config.ts new file mode 100644 index 000000000..01feaf2ff --- /dev/null +++ b/e2e/plugin-eslint-e2e/mocks/fixtures/old-version/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/mocks/fixtures/old-version/src/index.js b/e2e/plugin-eslint-e2e/mocks/fixtures/old-version/src/index.js new file mode 100644 index 000000000..4710a3767 --- /dev/null +++ b/e2e/plugin-eslint-e2e/mocks/fixtures/old-version/src/index.js @@ -0,0 +1,7 @@ +function unusedFn() { + return '42'; +} + +module.exports = function consoleLog() { + console.log('No console.log()!'); +}; diff --git a/e2e/plugin-eslint-e2e/project.json b/e2e/plugin-eslint-e2e/project.json new file mode 100644 index 000000000..4a23956d0 --- /dev/null +++ b/e2e/plugin-eslint-e2e/project.json @@ -0,0 +1,23 @@ +{ + "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"] + } + }, + "e2e": { + "executor": "@nx/vite:test", + "options": { + "configFile": "e2e/plugin-eslint-e2e/vite.config.e2e.ts" + } + } + }, + "implicitDependencies": ["cli", "plugin-eslint"], + "tags": ["scope:plugin", "type: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 new file mode 100644 index 000000000..ea1b4434e --- /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": "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-eslint-e2e/tests/collect.e2e.test.ts b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts new file mode 100644 index 000000000..784f54056 --- /dev/null +++ b/e2e/plugin-eslint-e2e/tests/collect.e2e.test.ts @@ -0,0 +1,48 @@ +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 { 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 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(fixturesOldVersionDir, oldVersionDir, { recursive: true }); + }); + + afterAll(async () => { + await teardownTestFolder(oldVersionDir); + }); + + afterEach(async () => { + 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'], + cwd: oldVersionDir, + }); + + expect(code).toBe(0); + expect(stderr).toBe(''); + + const report = await readJsonFile(join(oldVersionOutputDir, '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..34f35e30f --- /dev/null +++ b/e2e/plugin-eslint-e2e/tsconfig.test.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"], + "target": "ES2020" + }, + "exclude": ["__test-env__/**"], + "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'], + }, +}); diff --git a/nx.json b/nx.json index 299156fe9..e347930b3 100644 --- a/nx.json +++ b/nx.json @@ -28,10 +28,6 @@ "e2e": { "dependsOn": ["^build"] }, - "nxv-e2e": {}, - "nxv-env-setup": { - "executor": "@push-based/nx-verdaccio:env-setup" - }, "@nx/vite:test": { "cache": true, "inputs": ["default", "^production"],