From 3f168481c8d5a06aa083cfce7c4e85d3e3947360 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 02:51:19 +0200 Subject: [PATCH 01/24] fix(plugin-typescript): include extended options --- .../basic-setup/tsconfig.extends-base.json | 7 +++ .../tsconfig.extends-extending.json | 8 +++ .../src/lib/runner/ts-runner.ts | 2 +- .../src/lib/runner/utils.int.test.ts | 56 +++++++++++-------- .../plugin-typescript/src/lib/runner/utils.ts | 27 +++++---- 5 files changed, 66 insertions(+), 34 deletions(-) create mode 100644 packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-base.json create mode 100644 packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-extending.json diff --git a/packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-base.json b/packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-base.json new file mode 100644 index 000000000..1f21b8145 --- /dev/null +++ b/packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-base.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "rootDir": "./src", + "verbatimModuleSyntax": false + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-extending.json b/packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-extending.json new file mode 100644 index 000000000..f1b970c13 --- /dev/null +++ b/packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-extending.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.extends-base.json", + "compilerOptions": { + "verbatimModuleSyntax": true, + "module": "CommonJS" + }, + "exclude": ["src/*-errors/**/*.ts"] +} diff --git a/packages/plugin-typescript/src/lib/runner/ts-runner.ts b/packages/plugin-typescript/src/lib/runner/ts-runner.ts index 147d15e72..46e9ea9df 100644 --- a/packages/plugin-typescript/src/lib/runner/ts-runner.ts +++ b/packages/plugin-typescript/src/lib/runner/ts-runner.ts @@ -13,7 +13,7 @@ export type DiagnosticsOptions = { export async function getTypeScriptDiagnostics({ tsconfig, }: DiagnosticsOptions): Promise { - const { fileNames, options } = await loadTargetConfig(tsconfig); + const { fileNames, options } = loadTargetConfig(tsconfig); try { const program = createProgram(fileNames, options); return getPreEmitDiagnostics(program); diff --git a/packages/plugin-typescript/src/lib/runner/utils.int.test.ts b/packages/plugin-typescript/src/lib/runner/utils.int.test.ts index 63b1f0a2f..fba8e5991 100644 --- a/packages/plugin-typescript/src/lib/runner/utils.int.test.ts +++ b/packages/plugin-typescript/src/lib/runner/utils.int.test.ts @@ -3,26 +3,23 @@ import { describe, expect } from 'vitest'; import { loadTargetConfig } from './utils.js'; describe('loadTargetConfig', () => { - const parseConfigFileTextToJsonSpy = vi.spyOn( - tsModule, - 'parseConfigFileTextToJson', - ); + const readConfigFileSpy = vi.spyOn(tsModule, 'readConfigFile'); const parseJsonConfigFileContentSpy = vi.spyOn( tsModule, 'parseJsonConfigFileContent', ); - it('should return the parsed content of a tsconfig file and ist TypeScript helper to parse it', async () => { - await expect( + it('should return the parsed content of a tsconfig file and ist TypeScript helper to parse it', () => { + expect( loadTargetConfig( 'packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.init.json', ), - ).resolves.toStrictEqual( + ).toStrictEqual( expect.objectContaining({ fileNames: expect.any(Array), options: { module: 1, - configFilePath: undefined, + configFilePath: expect.stringContaining('tsconfig.init.json'), esModuleInterop: true, forceConsistentCasingInFileNames: true, skipLibCheck: true, @@ -31,25 +28,40 @@ describe('loadTargetConfig', () => { }, }), ); - expect(parseConfigFileTextToJsonSpy).toHaveBeenCalledTimes(1); - expect(parseConfigFileTextToJsonSpy).toHaveBeenCalledWith( - 'packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.init.json', - expect.stringContaining('/* Projects */'), + expect(readConfigFileSpy).toHaveBeenCalledTimes(1); + expect(readConfigFileSpy).toHaveBeenCalledWith( + expect.stringContaining('tsconfig.init.json'), + expect.any(Function), ); expect(parseJsonConfigFileContentSpy).toHaveBeenCalledTimes(1); - expect(parseJsonConfigFileContentSpy).toHaveBeenCalledWith( + // parseJsonConfigFileContent is called with complex internal objects + }); + + it('should return the parsed content of a tsconfig file that extends another config', () => { + expect( + loadTargetConfig( + 'packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-extending.json', + ), + ).toStrictEqual( expect.objectContaining({ - compilerOptions: expect.objectContaining({ - esModuleInterop: true, - forceConsistentCasingInFileNames: true, - module: 'commonjs', - skipLibCheck: true, - strict: true, - target: 'es2016', + fileNames: expect.arrayContaining([ + // from tsconfig.extends-base.json#includes and tsconfig.extends-extending.json#excludes + expect.stringContaining('src/0-no-diagnostics/'), + ]), + options: expect.objectContaining({ + // Options from tsconfig.extends-base.json + rootDir: expect.stringContaining('src'), + // Options from tsconfig.extends-extending.json + module: 1, + configFilePath: expect.stringContaining( + 'tsconfig.extends-extending.json', + ), + verbatimModuleSyntax: true, // Overrides base config's false }), }), - expect.any(Object), - expect.any(String), ); + + expect(readConfigFileSpy).toHaveBeenCalledTimes(1); + expect(parseJsonConfigFileContentSpy).toHaveBeenCalledTimes(1); }); }); diff --git a/packages/plugin-typescript/src/lib/runner/utils.ts b/packages/plugin-typescript/src/lib/runner/utils.ts index da87f2327..c5471e99a 100644 --- a/packages/plugin-typescript/src/lib/runner/utils.ts +++ b/packages/plugin-typescript/src/lib/runner/utils.ts @@ -1,15 +1,14 @@ -// eslint-disable-next-line unicorn/import-style -import { dirname } from 'node:path'; +import path from 'node:path'; import { type Diagnostic, DiagnosticCategory, flattenDiagnosticMessageText, - parseConfigFileTextToJson, parseJsonConfigFileContent, + readConfigFile, sys, } from 'typescript'; import type { Issue } from '@code-pushup/models'; -import { readTextFile, truncateIssueMessage } from '@code-pushup/utils'; +import { truncateIssueMessage } from '@code-pushup/utils'; import { TS_CODE_RANGE_NAMES } from './ts-error-codes.js'; import type { CodeRangeName } from './types.js'; @@ -84,7 +83,7 @@ export function getIssueFromDiagnostic(diag: Diagnostic) { return { ...issue, source: { - file: diag.file.fileName, + file: path.relative(process.cwd(), diag.file.fileName), ...(startLine ? { position: { @@ -96,16 +95,22 @@ export function getIssueFromDiagnostic(diag: Diagnostic) { } satisfies Issue; } -export async function loadTargetConfig(tsConfigPath: string) { - const { config } = parseConfigFileTextToJson( - tsConfigPath, - await readTextFile(tsConfigPath), - ); +export function loadTargetConfig(tsConfigPath: string) { + const resolvedConfigPath = path.resolve(tsConfigPath); + const { config, error } = readConfigFile(resolvedConfigPath, sys.readFile); + + if (error) { + throw new Error( + `Error reading TypeScript config file: \n${error.messageText}`, + ); + } const parsedConfig = parseJsonConfigFileContent( config, sys, - dirname(tsConfigPath), + path.dirname(resolvedConfigPath), + {}, + resolvedConfigPath, ); if (parsedConfig.fileNames.length === 0) { From 51c755b7b1e556f3eeef80f088f675b5985cf5d3 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 03:03:52 +0200 Subject: [PATCH 02/24] test(plugin-typescript): fix path for windows --- packages/plugin-typescript/src/lib/runner/utils.int.test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/plugin-typescript/src/lib/runner/utils.int.test.ts b/packages/plugin-typescript/src/lib/runner/utils.int.test.ts index fba8e5991..23334e15d 100644 --- a/packages/plugin-typescript/src/lib/runner/utils.int.test.ts +++ b/packages/plugin-typescript/src/lib/runner/utils.int.test.ts @@ -1,5 +1,6 @@ import * as tsModule from 'typescript'; import { describe, expect } from 'vitest'; +import { osAgnosticPath } from '@code-pushup/test-utils'; import { loadTargetConfig } from './utils.js'; describe('loadTargetConfig', () => { @@ -12,7 +13,9 @@ describe('loadTargetConfig', () => { it('should return the parsed content of a tsconfig file and ist TypeScript helper to parse it', () => { expect( loadTargetConfig( - 'packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.init.json', + osAgnosticPath( + 'packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.init.json', + ), ), ).toStrictEqual( expect.objectContaining({ From 16eab1f538bd5b4055fda0ff90d256c138c11574 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 03:06:43 +0200 Subject: [PATCH 03/24] test(plugin-typescript-e2e): update snapshot --- .../tests/__snapshots__/collect.e2e.test.ts.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index 09799e984..adb471f4a 100644 --- a/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -121,7 +121,7 @@ exports[`PLUGIN collect report with typescript-plugin NPM package > should run p "details": { "issues": [ { - "message": "TS6059: File './exclude/utils.ts' is not under 'rootDir' 'src'. 'rootDir' is expected to contain all source files.", + "message": "TS6059: File './exclude/utils.ts' is not under 'rootDir' './src'. 'rootDir' is expected to contain all source files.", "severity": "error", "source": { "file": "tmp/e2e/plugin-typescript-e2e/src/6-configuration-errors.ts", From a440788706ca28a73bd30af632ec1b58e3ce7459 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 03:18:14 +0200 Subject: [PATCH 04/24] test(plugin-typescript-e2e): update test config --- packages/plugin-typescript/vitest.int.config.ts | 7 ++++++- packages/plugin-typescript/vitest.unit.config.ts | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/plugin-typescript/vitest.int.config.ts b/packages/plugin-typescript/vitest.int.config.ts index 42d047592..87ad2157a 100644 --- a/packages/plugin-typescript/vitest.int.config.ts +++ b/packages/plugin-typescript/vitest.int.config.ts @@ -16,7 +16,12 @@ export default defineConfig({ coverage: { reporter: ['text', 'lcov'], reportsDirectory: '../../coverage/plugin-typescript/int-tests', - exclude: ['mocks/**', '**/types.ts'], + exclude: [ + 'mocks/**', + '**/types.ts', + '**/index.ts', + 'vitest.{unit,int}.config.ts', + ], }, environment: 'node', include: ['src/**/*.int.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], diff --git a/packages/plugin-typescript/vitest.unit.config.ts b/packages/plugin-typescript/vitest.unit.config.ts index f4b1337f9..7046393e3 100644 --- a/packages/plugin-typescript/vitest.unit.config.ts +++ b/packages/plugin-typescript/vitest.unit.config.ts @@ -16,7 +16,12 @@ export default defineConfig({ coverage: { reporter: ['text', 'lcov'], reportsDirectory: '../../coverage/plugin-typescript/unit-tests', - exclude: ['mocks/**', '**/types.ts'], + exclude: [ + 'mocks/**', + '**/types.ts', + '**/index.ts', + 'vitest.{unit,int}.config.ts', + ], }, environment: 'node', include: ['src/**/*.unit.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], From 38c09e6e376d9ca01605f0f8306377bf984ff8dc Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 03:37:53 +0200 Subject: [PATCH 05/24] test(plugin-typescript): fix path for windows --- .../src/lib/runner/runner.int.test.ts | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/packages/plugin-typescript/src/lib/runner/runner.int.test.ts b/packages/plugin-typescript/src/lib/runner/runner.int.test.ts index d68fc82bb..4055f8ebd 100644 --- a/packages/plugin-typescript/src/lib/runner/runner.int.test.ts +++ b/packages/plugin-typescript/src/lib/runner/runner.int.test.ts @@ -1,15 +1,36 @@ import { describe, expect } from 'vitest'; +import { osAgnosticPath } from '@code-pushup/test-utils'; import { getAudits } from '../utils.js'; import { createRunnerFunction } from './runner.js'; describe('createRunnerFunction', () => { it('should create valid audit outputs when called', async () => { - await expect( - createRunnerFunction({ - tsconfig: - 'packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.all-audits.json', - expectedAudits: getAudits(), - })(() => void 0), - ).resolves.toMatchSnapshot(); + const runnerFunction = createRunnerFunction({ + tsconfig: + 'packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.all-audits.json', + expectedAudits: getAudits(), + }); + + const result = await runnerFunction(); + + const sanitizedResult = result.map(audit => ({ + ...audit, + ...(audit.details && { + details: { + ...audit.details, + issues: audit.details.issues?.map(issue => ({ + ...issue, + ...(issue.source && { + source: { + ...issue.source, + file: osAgnosticPath(issue.source.file), + }, + }), + })), + }, + }), + })); + + await expect(sanitizedResult).toMatchSnapshot(); }, 35_000); }); From bd6e0035a4749baf75ffd3557d898fcca3a2ac22 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 03:38:00 +0200 Subject: [PATCH 06/24] test(plugin-typescript-e2e): fix path for windows --- .../tests/collect.e2e.test.ts | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts index 648d56a07..a57c6c71b 100644 --- a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts @@ -7,10 +7,47 @@ import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR, omitVariableReportData, + osAgnosticPath, teardownTestFolder, } from '@code-pushup/test-utils'; import { executeProcess, readJsonFile } from '@code-pushup/utils'; +function sanitizeReportPaths(report: Report): Report { + return { + ...report, + plugins: report.plugins.map(plugin => ({ + ...plugin, + audits: plugin.audits.map(audit => ({ + ...audit, + ...(audit.details && { + details: { + ...audit.details, + issues: audit.details.issues?.map(issue => ({ + ...issue, + ...(issue.source && { + source: { + ...issue.source, + file: osAgnosticPath(issue.source.file), + }, + }), + message: issue.message.replace( + /['"]([^'"]*[\/\\][^'"]*)['"]/g, + (match, filePath) => { + try { + return `'${osAgnosticPath(filePath)}'`; + } catch { + return match; + } + }, + ), + })), + }, + }), + })), + })), + }; +} + describe('PLUGIN collect report with typescript-plugin NPM package', () => { const envRoot = path.join(E2E_ENVIRONMENTS_DIR, nxTargetProject()); const distRoot = path.join(envRoot, TEST_OUTPUT_DIR); @@ -57,6 +94,9 @@ describe('PLUGIN collect report with typescript-plugin NPM package', () => { path.join(envRoot, outputDir, 'report.json'), ); expect(() => reportSchema.parse(reportJson)).not.toThrow(); - expect(omitVariableReportData(reportJson)).toMatchSnapshot(); + + expect( + omitVariableReportData(sanitizeReportPaths(reportJson)), + ).toMatchSnapshot(); }); }); From 686ab9176671b11a049cf3ce28f1ff14b7b6c53e Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 03:40:23 +0200 Subject: [PATCH 07/24] fix(plugin-typescript-e2e): fix lint --- e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts index a57c6c71b..f243d72ac 100644 --- a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts @@ -31,7 +31,7 @@ function sanitizeReportPaths(report: Report): Report { }, }), message: issue.message.replace( - /['"]([^'"]*[\/\\][^'"]*)['"]/g, + /['"]([^'"]*[/\\][^'"]*)['"]/g, (match, filePath) => { try { return `'${osAgnosticPath(filePath)}'`; From 062d9be1565bd0976b7d6534bd2e71c1e4e055c5 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 03:48:28 +0200 Subject: [PATCH 08/24] test(plugin-typescript-e2e): fix path for windows robust variant --- e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts index f243d72ac..ddb3835f4 100644 --- a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts @@ -31,10 +31,11 @@ function sanitizeReportPaths(report: Report): Report { }, }), message: issue.message.replace( - /['"]([^'"]*[/\\][^'"]*)['"]/g, + /['"]([^'"]*\\[^'"]*)['"]/g, (match, filePath) => { try { - return `'${osAgnosticPath(filePath)}'`; + const lastSegment = filePath.split(/[/\\]/).pop() || ''; + return `'/${lastSegment}'`; } catch { return match; } From f8220d99153417956342862a0f83bb89b950412c Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 03:54:18 +0200 Subject: [PATCH 09/24] test(plugin-typescript-e2e): fix path for windows robust variant 2 --- e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts index ddb3835f4..ccd6bb876 100644 --- a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts @@ -31,7 +31,7 @@ function sanitizeReportPaths(report: Report): Report { }, }), message: issue.message.replace( - /['"]([^'"]*\\[^'"]*)['"]/g, + /['"]([A-Z]:[/\\][^'"]*|[^'"]*[/\\][^'"]*[/\\][^'"]*)['"]/g, (match, filePath) => { try { const lastSegment = filePath.split(/[/\\]/).pop() || ''; From 18f397c946b87f98bed75f05831d222de84b57cf Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 03:58:15 +0200 Subject: [PATCH 10/24] test(plugin-typescript-e2e): fix path for windows robust variant 3 --- .../tests/__snapshots__/collect.e2e.test.ts.snap | 2 +- e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index adb471f4a..a51d3a224 100644 --- a/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -121,7 +121,7 @@ exports[`PLUGIN collect report with typescript-plugin NPM package > should run p "details": { "issues": [ { - "message": "TS6059: File './exclude/utils.ts' is not under 'rootDir' './src'. 'rootDir' is expected to contain all source files.", + "message": "TS6059: File '' is not under 'rootDir' ''. 'rootDir' is expected to contain all source files.", "severity": "error", "source": { "file": "tmp/e2e/plugin-typescript-e2e/src/6-configuration-errors.ts", diff --git a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts index ccd6bb876..e70ad0f61 100644 --- a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts @@ -31,15 +31,8 @@ function sanitizeReportPaths(report: Report): Report { }, }), message: issue.message.replace( - /['"]([A-Z]:[/\\][^'"]*|[^'"]*[/\\][^'"]*[/\\][^'"]*)['"]/g, - (match, filePath) => { - try { - const lastSegment = filePath.split(/[/\\]/).pop() || ''; - return `'/${lastSegment}'`; - } catch { - return match; - } - }, + /['"]([^'"]*[/\\][^'"]*)['"]/g, + "''", ), })), }, From 82105627be34d045dfb5b8cb2c26c262168244b5 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 04:04:57 +0200 Subject: [PATCH 11/24] test(plugin-typescript-e2e): remove comments --- packages/plugin-typescript/src/lib/runner/utils.int.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/plugin-typescript/src/lib/runner/utils.int.test.ts b/packages/plugin-typescript/src/lib/runner/utils.int.test.ts index 23334e15d..22c66078c 100644 --- a/packages/plugin-typescript/src/lib/runner/utils.int.test.ts +++ b/packages/plugin-typescript/src/lib/runner/utils.int.test.ts @@ -37,7 +37,6 @@ describe('loadTargetConfig', () => { expect.any(Function), ); expect(parseJsonConfigFileContentSpy).toHaveBeenCalledTimes(1); - // parseJsonConfigFileContent is called with complex internal objects }); it('should return the parsed content of a tsconfig file that extends another config', () => { From 8a63794672c022aee8bd2579b3636462df373807 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Wed, 20 Aug 2025 14:28:12 +0200 Subject: [PATCH 12/24] Update e2e/plugin-typescript-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-typescript-e2e/tests/collect.e2e.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts index e70ad0f61..5366eb4fe 100644 --- a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts @@ -32,7 +32,7 @@ function sanitizeReportPaths(report: Report): Report { }), message: issue.message.replace( /['"]([^'"]*[/\\][^'"]*)['"]/g, - "''", + osAgnosticPath, ), })), }, From 25d636d5e3e0469fdef9bf4c167fe6e4eac11289 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Wed, 20 Aug 2025 14:29:20 +0200 Subject: [PATCH 13/24] Update packages/plugin-typescript/src/lib/runner/utils.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> --- packages/plugin-typescript/src/lib/runner/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-typescript/src/lib/runner/utils.ts b/packages/plugin-typescript/src/lib/runner/utils.ts index c5471e99a..52dfed704 100644 --- a/packages/plugin-typescript/src/lib/runner/utils.ts +++ b/packages/plugin-typescript/src/lib/runner/utils.ts @@ -101,7 +101,7 @@ export function loadTargetConfig(tsConfigPath: string) { if (error) { throw new Error( - `Error reading TypeScript config file: \n${error.messageText}`, + `Error reading TypeScript config file at ${tsConfigPath}:\n${error.messageText}`, ); } From c03338f250e8cb3d923e692046020cf6910628bf Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 15:58:39 +0200 Subject: [PATCH 14/24] test: adjust test helper for message transform --- .../tests/collect.e2e.test.ts | 25 +++---------------- .../src/lib/runner/runner.int.test.ts | 25 ++++--------------- .../src/lib/utils/os-agnostic-paths.ts | 17 +++++++------ 3 files changed, 19 insertions(+), 48 deletions(-) diff --git a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts index 5366eb4fe..7d690b047 100644 --- a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts @@ -7,6 +7,7 @@ import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR, omitVariableReportData, + osAgnosticAuditOutputs, osAgnosticPath, teardownTestFolder, } from '@code-pushup/test-utils'; @@ -17,27 +18,9 @@ function sanitizeReportPaths(report: Report): Report { ...report, plugins: report.plugins.map(plugin => ({ ...plugin, - audits: plugin.audits.map(audit => ({ - ...audit, - ...(audit.details && { - details: { - ...audit.details, - issues: audit.details.issues?.map(issue => ({ - ...issue, - ...(issue.source && { - source: { - ...issue.source, - file: osAgnosticPath(issue.source.file), - }, - }), - message: issue.message.replace( - /['"]([^'"]*[/\\][^'"]*)['"]/g, - osAgnosticPath, - ), - })), - }, - }), - })), + audits: osAgnosticAuditOutputs(plugin.audits, message => + message.replace(/['"]([^'"]*[/\\][^'"]*)['"]/g, osAgnosticPath), + ), })), }; } diff --git a/packages/plugin-typescript/src/lib/runner/runner.int.test.ts b/packages/plugin-typescript/src/lib/runner/runner.int.test.ts index 4055f8ebd..db07e829e 100644 --- a/packages/plugin-typescript/src/lib/runner/runner.int.test.ts +++ b/packages/plugin-typescript/src/lib/runner/runner.int.test.ts @@ -1,5 +1,6 @@ import { describe, expect } from 'vitest'; -import { osAgnosticPath } from '@code-pushup/test-utils'; +import type { AuditOutputs } from '@code-pushup/models'; +import { osAgnosticAuditOutputs } from '@code-pushup/test-utils'; import { getAudits } from '../utils.js'; import { createRunnerFunction } from './runner.js'; @@ -13,24 +14,8 @@ describe('createRunnerFunction', () => { const result = await runnerFunction(); - const sanitizedResult = result.map(audit => ({ - ...audit, - ...(audit.details && { - details: { - ...audit.details, - issues: audit.details.issues?.map(issue => ({ - ...issue, - ...(issue.source && { - source: { - ...issue.source, - file: osAgnosticPath(issue.source.file), - }, - }), - })), - }, - }), - })); - - await expect(sanitizedResult).toMatchSnapshot(); + await expect( + osAgnosticAuditOutputs(result as AuditOutputs), + ).toMatchSnapshot(); }, 35_000); }); diff --git a/testing/test-utils/src/lib/utils/os-agnostic-paths.ts b/testing/test-utils/src/lib/utils/os-agnostic-paths.ts index 4c2def392..9dd00fb5e 100644 --- a/testing/test-utils/src/lib/utils/os-agnostic-paths.ts +++ b/testing/test-utils/src/lib/utils/os-agnostic-paths.ts @@ -1,8 +1,4 @@ -import type { - AuditOutput, - AuditOutputs, - AuditReport, -} from '@code-pushup/models'; +import type { AuditOutput, AuditReport } from '@code-pushup/models'; const AGNOSTIC_PATH_SEP_REGEX = /[/\\]/g; const OS_AGNOSTIC_PATH_SEP = '/'; @@ -102,6 +98,7 @@ export function osAgnosticPath(filePath?: string): string | undefined { export function osAgnosticAudit( audit: T, + transformMessage: (message: string) => string = s => s, ): T { const { issues = [] } = audit.details ?? {}; if (issues.every(({ source }) => source == null)) { @@ -119,12 +116,18 @@ export function osAgnosticAudit( ...issue.source, file: osAgnosticPath(issue.source.file), }, + message: transformMessage(issue.message), }, ), }, }; } -export function osAgnosticAuditOutputs(audits: AuditOutputs): AuditOutputs { - return audits.map(osAgnosticAudit); +export function osAgnosticAuditOutputs( + audits: T[], + transformAuditIssueMessage?: (message: string) => string, +): T[] { + return audits.map(audit => + osAgnosticAudit(audit, transformAuditIssueMessage), + ); } From 7e1e45ca86a17168aca80764bc8d091d519b9da1 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 17:38:48 +0200 Subject: [PATCH 15/24] test(plugin-typescript): adjust checks --- .../mocks/fixtures/default-setup/tsconfig.json | 2 +- .../mocks/fixtures/basic-setup/tsconfig.extends-base.json | 2 +- packages/plugin-typescript/src/lib/runner/utils.int.test.ts | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/e2e/plugin-typescript-e2e/mocks/fixtures/default-setup/tsconfig.json b/e2e/plugin-typescript-e2e/mocks/fixtures/default-setup/tsconfig.json index b9dd367e9..400df8816 100644 --- a/e2e/plugin-typescript-e2e/mocks/fixtures/default-setup/tsconfig.json +++ b/e2e/plugin-typescript-e2e/mocks/fixtures/default-setup/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "rootDir": "./src", + "rootDir": "${configDir}/src", "target": "ES6", "module": "CommonJS", "strict": true, diff --git a/packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-base.json b/packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-base.json index 1f21b8145..d98091ca6 100644 --- a/packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-base.json +++ b/packages/plugin-typescript/mocks/fixtures/basic-setup/tsconfig.extends-base.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "rootDir": "./src", + "rootDir": "${configDir}", "verbatimModuleSyntax": false }, "include": ["src/**/*.ts"] diff --git a/packages/plugin-typescript/src/lib/runner/utils.int.test.ts b/packages/plugin-typescript/src/lib/runner/utils.int.test.ts index 22c66078c..c202d59be 100644 --- a/packages/plugin-typescript/src/lib/runner/utils.int.test.ts +++ b/packages/plugin-typescript/src/lib/runner/utils.int.test.ts @@ -1,5 +1,5 @@ import * as tsModule from 'typescript'; -import { describe, expect } from 'vitest'; +import { describe, expect, vi } from 'vitest'; import { osAgnosticPath } from '@code-pushup/test-utils'; import { loadTargetConfig } from './utils.js'; @@ -48,11 +48,11 @@ describe('loadTargetConfig', () => { expect.objectContaining({ fileNames: expect.arrayContaining([ // from tsconfig.extends-base.json#includes and tsconfig.extends-extending.json#excludes - expect.stringContaining('src/0-no-diagnostics/'), + expect.stringMatching(/src[/\\]0-no-diagnostics[/\\]/), ]), options: expect.objectContaining({ // Options from tsconfig.extends-base.json - rootDir: expect.stringContaining('src'), + rootDir: expect.stringMatching(/basic-setup$/), // Options from tsconfig.extends-extending.json module: 1, configFilePath: expect.stringContaining( From 87851bb992f2d5bed63f5b75755b81f713756645 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 17:58:30 +0200 Subject: [PATCH 16/24] test(plugin-typescript-e2e): adjust checks --- .../tests/__snapshots__/collect.e2e.test.ts.snap | 2 +- e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index a51d3a224..b445d3189 100644 --- a/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -121,7 +121,7 @@ exports[`PLUGIN collect report with typescript-plugin NPM package > should run p "details": { "issues": [ { - "message": "TS6059: File '' is not under 'rootDir' ''. 'rootDir' is expected to contain all source files.", + "message": "TS6059: File exclude/utils.ts' is not under 'rootDir' './src'. 'rootDir' is expected to contain all source files.", "severity": "error", "source": { "file": "tmp/e2e/plugin-typescript-e2e/src/6-configuration-errors.ts", diff --git a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts index 7d690b047..f8becbc6a 100644 --- a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts @@ -19,7 +19,13 @@ function sanitizeReportPaths(report: Report): Report { plugins: report.plugins.map(plugin => ({ ...plugin, audits: osAgnosticAuditOutputs(plugin.audits, message => - message.replace(/['"]([^'"]*[/\\][^'"]*)['"]/g, osAgnosticPath), + message.replace(/['"]([^'"]*[/\\][^'"]*)['"]/g, (p: string) => { + const osAgnostic = osAgnosticPath(p); + if (osAgnostic.endsWith('.ts')) { + return osAgnostic; + } + return osAgnostic.split('/').slice(-2).join('/'); + }), ), })), }; From 6ec8df31db5252c43bf990cbf5e0a054c271dcfe Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 19:12:11 +0200 Subject: [PATCH 17/24] test(plugin-typescript-e2e): adjust checks 2 --- e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts index f8becbc6a..1afca29a3 100644 --- a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts @@ -19,12 +19,12 @@ function sanitizeReportPaths(report: Report): Report { plugins: report.plugins.map(plugin => ({ ...plugin, audits: osAgnosticAuditOutputs(plugin.audits, message => - message.replace(/['"]([^'"]*[/\\][^'"]*)['"]/g, (p: string) => { + message.replaceAll(/['"]([^'"]*[/\\][^'"]*)['"]/g, (p: string) => { const osAgnostic = osAgnosticPath(p); if (osAgnostic.endsWith('.ts')) { return osAgnostic; } - return osAgnostic.split('/').slice(-2).join('/'); + return osAgnostic.split('/').slice(-1).join('/'); }), ), })), From a0b58149fa9816930b97dd49f3785f6cab790932 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 19:23:35 +0200 Subject: [PATCH 18/24] chore: add cloud-id --- nx.json | 1 + 1 file changed, 1 insertion(+) diff --git a/nx.json b/nx.json index 99e48af53..abc36787e 100644 --- a/nx.json +++ b/nx.json @@ -1,5 +1,6 @@ { "$schema": "./node_modules/nx/schemas/nx-schema.json", + "nxCloudId": "65d4d862d2adb16a45a4bc7c", "targetDefaults": { "build": { "dependsOn": ["^build"], From 574beaaba97c1166cc016947f1a17836371d7139 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 19:49:28 +0200 Subject: [PATCH 19/24] chore(plugin-typescript-e2e): adjust checks for windows --- .../__snapshots__/collect.e2e.test.ts.snap | 2 +- .../tests/collect.e2e.test.ts | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index b445d3189..adb471f4a 100644 --- a/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-typescript-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -121,7 +121,7 @@ exports[`PLUGIN collect report with typescript-plugin NPM package > should run p "details": { "issues": [ { - "message": "TS6059: File exclude/utils.ts' is not under 'rootDir' './src'. 'rootDir' is expected to contain all source files.", + "message": "TS6059: File './exclude/utils.ts' is not under 'rootDir' './src'. 'rootDir' is expected to contain all source files.", "severity": "error", "source": { "file": "tmp/e2e/plugin-typescript-e2e/src/6-configuration-errors.ts", diff --git a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts index 1afca29a3..c475933d5 100644 --- a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts @@ -19,13 +19,18 @@ function sanitizeReportPaths(report: Report): Report { plugins: report.plugins.map(plugin => ({ ...plugin, audits: osAgnosticAuditOutputs(plugin.audits, message => - message.replaceAll(/['"]([^'"]*[/\\][^'"]*)['"]/g, (p: string) => { - const osAgnostic = osAgnosticPath(p); - if (osAgnostic.endsWith('.ts')) { - return osAgnostic; - } - return osAgnostic.split('/').slice(-1).join('/'); - }), + message.replace( + /['"]([^'"]*[/\\][^'"]*)['"]/g, + (fullMatch: string, capturedPath: string) => { + const osAgnostic = osAgnosticPath(capturedPath); + // Only replace directory paths, not .ts file paths + if (capturedPath.endsWith('.ts')) { + return `'${osAgnostic}'`; + } + // on Windows the path starts from "D/" not "./". This normalizes it to "./" + return `'${['.'].concat(osAgnostic.split('/').slice(-1)).join('/')}'`; + }, + ), ), })), }; From 2e1f646f4cf425059c637c491ef4a9b99aa06327 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 20:00:13 +0200 Subject: [PATCH 20/24] chore(plugin-typescript-e2e): adjust checks for windows 3 --- e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts index c475933d5..1d3766c37 100644 --- a/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-typescript-e2e/tests/collect.e2e.test.ts @@ -27,8 +27,8 @@ function sanitizeReportPaths(report: Report): Report { if (capturedPath.endsWith('.ts')) { return `'${osAgnostic}'`; } - // on Windows the path starts from "D/" not "./". This normalizes it to "./" - return `'${['.'].concat(osAgnostic.split('/').slice(-1)).join('/')}'`; + // on Windows the path starts from "plugin-typescript-e2e/src" not "./". This normalizes it to "./" + return `'${['.', osAgnostic.split('/').slice(-1)].join('/')}'`; }, ), ), From 5b22c5803a1d955a471ec333bb2b8657f9c4d692 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 20:41:06 +0200 Subject: [PATCH 21/24] chore: remove nx cloud id --- nx.json | 1 - 1 file changed, 1 deletion(-) diff --git a/nx.json b/nx.json index abc36787e..99e48af53 100644 --- a/nx.json +++ b/nx.json @@ -1,6 +1,5 @@ { "$schema": "./node_modules/nx/schemas/nx-schema.json", - "nxCloudId": "65d4d862d2adb16a45a4bc7c", "targetDefaults": { "build": { "dependsOn": ["^build"], From e96b71870b97e6f0473aa39838e11c34c66d545e Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 20 Aug 2025 20:54:44 +0200 Subject: [PATCH 22/24] fix: adjust targets --- code-pushup.config.ts | 2 +- project.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code-pushup.config.ts b/code-pushup.config.ts index 51aa2b33b..b9234bacd 100644 --- a/code-pushup.config.ts +++ b/code-pushup.config.ts @@ -26,7 +26,7 @@ const config: CoreConfig = { server: env.CP_SERVER, apiKey: env.CP_API_KEY, organization: env.CP_ORGANIZATION, - project: env.CP_PROJECT, + project: 'cli-workspace', }, }), diff --git a/project.json b/project.json index a4c550bfb..1f19a828e 100644 --- a/project.json +++ b/project.json @@ -1,5 +1,5 @@ { - "name": "@code-pushup/cli-source", + "name": "cli-workspace", "$schema": "node_modules/nx/schemas/project-schema.json", "targets": { "code-pushup": { From af8634d5fe7729568a5a2d7eef0e7c1deaa4af67 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 21 Aug 2025 13:22:50 +0200 Subject: [PATCH 23/24] Update packages/plugin-typescript/src/lib/runner/runner.int.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> --- packages/plugin-typescript/src/lib/runner/runner.int.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-typescript/src/lib/runner/runner.int.test.ts b/packages/plugin-typescript/src/lib/runner/runner.int.test.ts index db07e829e..485b570a8 100644 --- a/packages/plugin-typescript/src/lib/runner/runner.int.test.ts +++ b/packages/plugin-typescript/src/lib/runner/runner.int.test.ts @@ -14,7 +14,7 @@ describe('createRunnerFunction', () => { const result = await runnerFunction(); - await expect( + expect( osAgnosticAuditOutputs(result as AuditOutputs), ).toMatchSnapshot(); }, 35_000); From 68350d8f1149396fc3b95490825739b8a1e795e9 Mon Sep 17 00:00:00 2001 From: John Doe Date: Thu, 21 Aug 2025 13:29:10 +0200 Subject: [PATCH 24/24] fix: format --- packages/plugin-typescript/src/lib/runner/runner.int.test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/plugin-typescript/src/lib/runner/runner.int.test.ts b/packages/plugin-typescript/src/lib/runner/runner.int.test.ts index 485b570a8..eb4e41683 100644 --- a/packages/plugin-typescript/src/lib/runner/runner.int.test.ts +++ b/packages/plugin-typescript/src/lib/runner/runner.int.test.ts @@ -14,8 +14,6 @@ describe('createRunnerFunction', () => { const result = await runnerFunction(); - expect( - osAgnosticAuditOutputs(result as AuditOutputs), - ).toMatchSnapshot(); + expect(osAgnosticAuditOutputs(result as AuditOutputs)).toMatchSnapshot(); }, 35_000); });