Skip to content

Commit a87fc03

Browse files
committed
test: add basic e2e
1 parent 61a1623 commit a87fc03

File tree

6 files changed

+110
-32
lines changed

6 files changed

+110
-32
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { cp } from 'node:fs/promises';
2+
import path, { join } from 'node:path';
3+
import { afterAll, beforeAll, expect } from 'vitest';
4+
import { type Report, reportSchema } from '@code-pushup/models';
5+
import { nxTargetProject } from '@code-pushup/test-nx-utils';
6+
import { teardownTestFolder } from '@code-pushup/test-setup';
7+
import {
8+
E2E_ENVIRONMENTS_DIR,
9+
TEST_OUTPUT_DIR,
10+
omitVariableReportData,
11+
removeColorCodes,
12+
} from '@code-pushup/test-utils';
13+
import { executeProcess, readJsonFile } from '@code-pushup/utils';
14+
15+
describe.todo(
16+
'PLUGIN collect report with typescript-plugin NPM package',
17+
() => {
18+
const envRoot = path.join(E2E_ENVIRONMENTS_DIR, nxTargetProject());
19+
const testFileDir = path.join(envRoot, TEST_OUTPUT_DIR, 'collect');
20+
const defaultSetupDir = path.join(testFileDir, 'default-setup');
21+
22+
const fixturesDir = path.join(
23+
'e2e',
24+
nxTargetProject(),
25+
'mocks',
26+
'fixtures',
27+
);
28+
29+
beforeAll(async () => {
30+
await cp(fixturesDir, testFileDir, { recursive: true });
31+
});
32+
33+
afterAll(async () => {
34+
await teardownTestFolder(testFileDir);
35+
});
36+
37+
it('should run plugin over CLI and creates report.json', async () => {
38+
const { code, stdout } = await executeProcess({
39+
command: 'npx',
40+
// verbose exposes audits with perfect scores that are hidden in the default stdout
41+
args: [
42+
'@code-pushup/cli',
43+
'collect',
44+
`--config=${join(TEST_OUTPUT_DIR, 'collect', 'default-setup', 'code-pushup.config.ts')}`,
45+
'--no-progress',
46+
'--verbose',
47+
],
48+
cwd: envRoot,
49+
});
50+
51+
expect(code).toBe(0);
52+
const cleanStdout = removeColorCodes(stdout);
53+
expect(cleanStdout).toContain('● Largest Contentful Paint');
54+
55+
const report = await readJsonFile(
56+
path.join(defaultSetupDir, '.code-pushup', 'report.json'),
57+
);
58+
expect(() => reportSchema.parse(report)).not.toThrow();
59+
expect(
60+
omitVariableReportData(report as Report, { omitAuditData: true }),
61+
).toMatchSnapshot();
62+
});
63+
},
64+
);

e2e/plugin-typescript-e2e/tests/install.e2e.test.ts

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,23 @@
1+
import { readFile } from 'node:fs/promises';
12
import path from 'node:path';
23
import { expect } from 'vitest';
34
import { nxTargetProject } from '@code-pushup/test-nx-utils';
4-
import { E2E_ENVIRONMENTS_DIR, TEST_OUTPUT_DIR } from '@code-pushup/test-utils';
5+
import { E2E_ENVIRONMENTS_DIR } from '@code-pushup/test-utils';
56
import { getCurrentTsVersion } from '@code-pushup/typescript-plugin';
6-
import { readJsonFile } from '@code-pushup/utils';
77

88
describe('PLUGIN install of typescript-plugin NPM package', () => {
9-
const testFileDir = path.join(
10-
E2E_ENVIRONMENTS_DIR,
11-
nxTargetProject(),
12-
TEST_OUTPUT_DIR,
13-
'install',
9+
const envRoot = path.join(E2E_ENVIRONMENTS_DIR, nxTargetProject());
10+
const cacheDir = path.join(
11+
'node_modules',
12+
'.code-pushup',
13+
'typescript-plugin',
14+
'default-ts-configs',
1415
);
1516

1617
it('should have current TS version defaults generated after install', async () => {
1718
await expect(
18-
readJsonFile(
19-
path.join(
20-
testFileDir,
21-
'node_modules',
22-
'.code-pushup',
23-
'plugin-typescript',
24-
'default-ts-configs',
25-
await getCurrentTsVersion(),
26-
),
19+
readFile(
20+
path.join(envRoot, cacheDir, `${await getCurrentTsVersion()}.ts`),
2721
),
2822
).resolves.not.toThrow();
2923
});

packages/plugin-typescript/src/lib/constants.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@ import { camelCaseToKebabCase, kebabCaseToSentence } from '@code-pushup/utils';
55
import { TS_ERROR_CODES } from './runner/ts-error-codes.js';
66
import type { CompilerOptionName } from './runner/types.js';
77

8-
export const TS_PLUGIN_CACHE = join(
9-
'node_modules',
10-
'.code-pushup',
11-
'typescript-plugin',
12-
);
8+
export const TS_PLUGIN_CACHE = join('.code-pushup', 'typescript-plugin');
139
export const TS_CONFIG_DIR = join(TS_PLUGIN_CACHE, 'default-ts-configs');
1410

1511
export const TYPESCRIPT_PLUGIN_SLUG = 'typescript';

packages/plugin-typescript/src/lib/runner/utils.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,12 @@ export async function getCurrentTsVersion(): Promise<SemVerString> {
130130

131131
export async function loadTsConfigDefaultsByVersion() {
132132
const version = await getCurrentTsVersion();
133-
const configPath = join(TS_CONFIG_DIR, `${version}.ts`);
133+
const configPath = join(
134+
process.cwd(),
135+
'node_modules',
136+
TS_CONFIG_DIR,
137+
`${version}.js`,
138+
);
134139
try {
135140
await access(configPath);
136141
} catch {
@@ -144,7 +149,7 @@ export async function loadTsConfigDefaultsByVersion() {
144149
return module.default as { compilerOptions: CompilerOptions };
145150
} catch (error) {
146151
throw new Error(
147-
`Could load default TS config for version ${version}. /n ${(error as Error).message}`,
152+
`Could load default TS config for version ${version} at ${configPath}. The plugin maintainer has to support this version. \n ${(error as Error).message}`,
148153
);
149154
}
150155
}

packages/plugin-typescript/src/postinstall/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ import { generateCurrentTsConfig } from './utils.js';
33
// eslint-disable-next-line unicorn/prefer-top-level-await
44
(async () => {
55
await generateCurrentTsConfig();
6+
console.log('Generated current TS config');
67
})();

packages/plugin-typescript/src/postinstall/utils.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,47 @@
11
// Run typescript init (with a version specified) to generate a tsconfig.json that will have all defaults listed.
22
// store this json per ts version in src/default-configs.ts
33
// get a list of TS version, maybe from npm and somehow filter only versions
4-
import { writeFile } from 'node:fs/promises';
4+
import { rm, writeFile } from 'node:fs/promises';
55
// eslint-disable-next-line unicorn/import-style
6-
import { join } from 'node:path';
6+
import { dirname, join } from 'node:path';
77
import type { CompilerOptions } from 'typescript';
88
import {
99
ensureDirectoryExists,
1010
executeProcess,
1111
readTextFile,
1212
} from '@code-pushup/utils';
13-
import { TS_CONFIG_DIR } from '../lib/constants.js';
1413
import type { SemVerString } from '../lib/runner/types.js';
1514
import { getCurrentTsVersion } from '../lib/runner/utils.js';
1615

17-
export const TMP_TS_CONFIG_DIR = join('tmp', 'plugin-typescript-ts-config');
16+
const normalizedTsConfigFolder = join(
17+
'..',
18+
'..',
19+
'.code-pushup',
20+
'typescript-plugin',
21+
'default-ts-configs',
22+
);
23+
const tmpDir = join(normalizedTsConfigFolder, 'tmp');
1824

1925
export async function generateDefaultTsConfig(version: SemVerString) {
20-
await ensureDirectoryExists(TS_CONFIG_DIR);
26+
await ensureDirectoryExists(normalizedTsConfigFolder);
2127
await generateRawTsConfigFile(version);
2228
const config = await extractTsConfig(version);
29+
await cleanupArtefacts();
2330
await cleanupNpmCache(version);
24-
return writeFile(
25-
join(TS_CONFIG_DIR, `${version}.ts`),
31+
await writeFile(
32+
join(normalizedTsConfigFolder, `${version}.js`),
2633
[
2734
`const config = ${JSON.stringify(config, null, 2)}`,
2835
`export default config;`,
2936
].join('\n'),
3037
);
38+
console.log(
39+
`Generated default TS config for version ${version} under ${normalizedTsConfigFolder}`,
40+
);
3141
}
3242

3343
export async function generateRawTsConfigFile(version: SemVerString) {
34-
const dir = join(TMP_TS_CONFIG_DIR, version);
44+
const dir = join(tmpDir, version);
3545
await ensureDirectoryExists(dir);
3646
await executeProcess({
3747
command: 'npx',
@@ -47,7 +57,7 @@ export async function generateRawTsConfigFile(version: SemVerString) {
4757
export async function extractTsConfig(
4858
version: SemVerString,
4959
): Promise<CompilerOptions> {
50-
const dir = join(TMP_TS_CONFIG_DIR, version);
60+
const dir = join(tmpDir, version);
5161
await ensureDirectoryExists(dir);
5262
try {
5363
return parseTsConfigJson(await readTextFile(join(dir, 'tsconfig.json')));
@@ -69,6 +79,14 @@ export async function cleanupNpmCache(version: SemVerString) {
6979
});
7080
}
7181

82+
/**
83+
* Cleanup artefacts`
84+
* @param version
85+
*/
86+
export async function cleanupArtefacts() {
87+
await rm(tmpDir, { recursive: true });
88+
}
89+
7290
/**
7391
* Parse the tsconfig.json file content into a CompilerOptions object.
7492
* tsconfig.json files can have comments and trailing commas, which are not valid JSON.

0 commit comments

Comments
 (0)