Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(angular): add vitest option to angular #27311

Merged
merged 34 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
275b86b
test(angular): add tests for vitest option
yjaaidi Aug 2, 2024
d7bb0af
chore(angular): add deps when generating vitest app
yjaaidi Aug 5, 2024
79c479c
chore(angular): fix angular compat deps typing
yjaaidi Aug 5, 2024
d9795d2
chore(angular): generate vite.config.ts
yjaaidi Aug 5, 2024
448dcf7
chore(angular): generate test-setup.ts
yjaaidi Aug 5, 2024
ca80319
chore(angular): generate tsconfig.spec.json
yjaaidi Aug 5, 2024
791f290
chore(angular): add setupFile to vitest config
yjaaidi Aug 6, 2024
342f429
chore(angular): generate vite.config.mts instead of .ts when necessary
yjaaidi Aug 6, 2024
2483acc
chore(angular): exclude test-setup from tsconfig.app.json
yjaaidi Aug 6, 2024
1de92aa
chore(angular): generate vitest configuration for libs
yjaaidi Aug 6, 2024
7b3ad9f
chore(angular): add test-setup.ts to production named input
yjaaidi Aug 6, 2024
fd1f785
feat(angular): add vitest option to app & lib generators
yjaaidi Aug 6, 2024
7fae1bf
feat(angular): prompt for unit test runner for mf apps
yjaaidi Aug 6, 2024
090198e
feat(angular): fix watch not updating by upgrading analog
yjaaidi Aug 6, 2024
dd64dbd
chore(angular): fix vite e2e tests
yjaaidi Aug 6, 2024
f04f8f4
chore(angular): update test snapshots
yjaaidi Aug 6, 2024
76d7d77
chore(angular): avoid empty lines and format in tests
yjaaidi Aug 7, 2024
683e261
chore(angular): fix snapshots following empty line removal
yjaaidi Aug 7, 2024
eb9a3dc
chore(angular): add e2e test for vitest
yjaaidi Aug 21, 2024
0102383
chore(angular): remove useless angular option for uiFramework
yjaaidi Aug 21, 2024
5680710
chore(angular): use range instead of fixed version for analog vitest
yjaaidi Aug 21, 2024
a2f03ee
chore(angular): remove useless legacy peer deps flag
yjaaidi Aug 21, 2024
1e8c6d3
feat(devkit): add findFileInClosestParentFolder util
yjaaidi Aug 22, 2024
ccaabdd
chore(devkit): check if ESM in the closest package.json
yjaaidi Aug 22, 2024
9a2f2b6
chore(devkit): rename to find-file-in-closest-parent-folder.ts
yjaaidi Aug 22, 2024
6d2a996
chore(devkit): switch to ordered parameters to align with other utils
yjaaidi Aug 22, 2024
e4d8cb4
refactor(angular): fix add-vitest
yjaaidi Aug 23, 2024
4711aba
test(angular,workspace): update snapshots
yjaaidi Aug 23, 2024
d5136c4
chore(devkit): fix import
yjaaidi Aug 23, 2024
8262f3c
Merge branch 'master' into feat/add-vitest-option-to-angular
yjaaidi Oct 28, 2024
d56ce97
chore(angular): always generate vite/vitest config with mts extension
yjaaidi Oct 29, 2024
3571d5a
chore(angular): update e2e test to use directory positional arg
Coly010 Oct 29, 2024
46fd341
feat(angular): bump analogViteVersion
Coly010 Oct 29, 2024
80e346e
chore(devkit): remove wallaby config
Coly010 Oct 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "none"],
"enum": ["jest", "vitest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "Which unit test runner would you like to use?",
"default": "jest"
},
"e2eTestRunner": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "none"],
"enum": ["jest", "vitest", "none"],
"description": "Test runner to use for unit tests of the remote if it needs to be created.",
"x-prompt": "Which unit test runner would you like to use?",
"default": "jest"
},
"e2eTestRunner": {
Expand Down
3 changes: 2 additions & 1 deletion docs/generated/packages/angular/generators/host.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,9 @@
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "none"],
"enum": ["jest", "vitest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "Which unit test runner would you like to use?",
"default": "jest"
},
"e2eTestRunner": {
Expand Down
3 changes: 2 additions & 1 deletion docs/generated/packages/angular/generators/library.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "none"],
"enum": ["jest", "vitest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "Which unit test runner would you like to use?",
"default": "jest"
},
"importPath": {
Expand Down
3 changes: 2 additions & 1 deletion docs/generated/packages/angular/generators/remote.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "none"],
"enum": ["jest", "vitest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "Which unit test runner would you like to use?",
"default": "jest"
},
"e2eTestRunner": {
Expand Down
17 changes: 17 additions & 0 deletions e2e/angular/src/projects.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -568,4 +568,21 @@ describe('Angular Projects', () => {
runCLI(`server ${webpackApp} --output-hashing none`)
).toThrow();
}, 500_000);

it('should generate apps and libs with vitest', async () => {
const app = uniq('app');
const lib = uniq('lib');

runCLI(
`generate @nx/angular:app ${app} --unit-test-runner=vitest --no-interactive`
);
runCLI(
`generate @nx/angular:lib ${lib} --unit-test-runner=vitest --no-interactive`
);

// Make sure we are using vitest
checkFilesExist(`${app}/vite.config.mts`, `${lib}/vite.config.mts`);

runCLI(`run-many --target test --projects=${app},${lib} --parallel`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,146 @@ exports[`app --strict should enable strict type checking: e2e tsconfig.json 1`]
}
`;

exports[`app --unit-test-runner vitest should add tsconfig.spec.json 1`] = `
"{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../dist/out-tsc",
"types": [
"vitest/globals",
"vitest/importMeta",
"vite/client",
"node",
"vitest"
]
},
"include": [
"vite.config.ts",
"vitest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.test.tsx",
"src/**/*.spec.tsx",
"src/**/*.test.js",
"src/**/*.spec.js",
"src/**/*.test.jsx",
"src/**/*.spec.jsx",
"src/**/*.d.ts"
],
"files": ["src/test-setup.ts"]
}
"
`;

exports[`app --unit-test-runner vitest should generate src/test-setup.ts 1`] = `
"import '@analogjs/vitest-angular/setup-zone';

import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting,
} from '@angular/platform-browser-dynamic/testing';
import { getTestBed } from '@angular/core/testing';

getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
"
`;

exports[`app --unit-test-runner vitest should generate vite.config.mts 1`] = `
"/// <reference types='vitest' />
import { defineConfig } from 'vite';
import angular from '@analogjs/vite-plugin-angular';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin';

export default defineConfig({
root: __dirname,
cacheDir: '../node_modules/.vite/my-app',
plugins: [angular(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])],
// Uncomment this if you are using workers.
// worker: {
// plugins: [ nxViteTsPaths() ],
// },
test: {
watch: false,
globals: true,
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
setupFiles: ['src/test-setup.ts'],
reporters: ['default'],
coverage: {
reportsDirectory: '../coverage/my-app',
provider: 'v8',
},
},
});
"
`;

exports[`app --unit-test-runner vitest should generate vite.config.mts if package type is module 1`] = `
"/// <reference types='vitest' />
import { defineConfig } from 'vite';
import angular from '@analogjs/vite-plugin-angular';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin';

export default defineConfig({
root: __dirname,
cacheDir: '../node_modules/.vite/my-app',
plugins: [angular(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])],
// Uncomment this if you are using workers.
// worker: {
// plugins: [ nxViteTsPaths() ],
// },
test: {
watch: false,
globals: true,
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
setupFiles: ['src/test-setup.ts'],
reporters: ['default'],
coverage: {
reportsDirectory: '../coverage/my-app',
provider: 'v8',
},
},
});
"
`;

exports[`app --unit-test-runner vitest should generate vite.config.mts if workspace package type is module 1`] = `
"/// <reference types='vitest' />
import { defineConfig } from 'vite';
import angular from '@analogjs/vite-plugin-angular';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin';

export default defineConfig({
root: __dirname,
cacheDir: '../node_modules/.vite/my-app',
plugins: [angular(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])],
// Uncomment this if you are using workers.
// worker: {
// plugins: [ nxViteTsPaths() ],
// },
test: {
watch: false,
globals: true,
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
setupFiles: ['src/test-setup.ts'],
reporters: ['default'],
coverage: {
reportsDirectory: '../coverage/my-app',
provider: 'v8',
},
},
});
"
`;

exports[`app angular compat support should import "ApplicationConfig" from "@angular/platform-browser" 1`] = `
"import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
Expand Down
106 changes: 105 additions & 1 deletion packages/angular/src/generators/application/application.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { installedCypressVersion } from '@nx/cypress/src/utils/cypress-version';
import type { Tree } from '@nx/devkit';
import { Tree, writeJson } from '@nx/devkit';
import * as devkit from '@nx/devkit';
import {
NxJsonConfiguration,
Expand Down Expand Up @@ -698,6 +698,110 @@ describe('app', () => {
});
});

describe('vitest', () => {
it('should generate vite.config.mts', async () => {
await generateApp(appTree, 'my-app', {
skipFormat: false,
unitTestRunner: UnitTestRunner.Vitest,
});

expect(
appTree.read('my-app/vite.config.mts', 'utf-8')
).toMatchSnapshot();
});

it('should generate src/test-setup.ts', async () => {
await generateApp(appTree, 'my-app', {
unitTestRunner: UnitTestRunner.Vitest,
});

expect(
appTree.read('my-app/src/test-setup.ts', 'utf-8')
).toMatchSnapshot();
});

it('should exclude src/test-setup.ts in tsconfig.app.json', async () => {
await generateApp(appTree, 'my-app', {
unitTestRunner: UnitTestRunner.Vitest,
});

const tsConfig = readJson(appTree, 'my-app/tsconfig.app.json');
expect(tsConfig.exclude).toContain('src/test-setup.ts');
});

it('should add tsconfig.spec.json', async () => {
await generateApp(appTree, 'my-app', {
unitTestRunner: UnitTestRunner.Vitest,
});

expect(
appTree.read('my-app/tsconfig.spec.json', 'utf-8')
).toMatchSnapshot();
});

it('should add a reference to tsconfig.spec.json in tsconfig.json', async () => {
await generateApp(appTree, 'my-app', {
unitTestRunner: UnitTestRunner.Vitest,
});

const { references } = readJson(appTree, 'my-app/tsconfig.json');
expect(references).toContainEqual({
path: './tsconfig.spec.json',
});
});

it('should add @nx/vite dependency', async () => {
await generateApp(appTree, 'my-app', {
unitTestRunner: UnitTestRunner.Vitest,
});

const { devDependencies } = readJson(appTree, 'package.json');
expect(devDependencies['@nx/vite']).toBeDefined();
});

it('should add vitest-angular', async () => {
await generateApp(appTree, 'my-app', {
unitTestRunner: UnitTestRunner.Vitest,
});

const { devDependencies } = readJson(appTree, 'package.json');
expect(devDependencies['@analogjs/vite-plugin-angular']).toBeDefined();
expect(devDependencies['@analogjs/vitest-angular']).toBeDefined();
});

it('should generate vite.config.mts if package type is module', async () => {
writeJson(appTree, 'my-app/package.json', {
name: 'my-app',
type: 'module',
});

await generateApp(appTree, 'my-app', {
skipFormat: false,
unitTestRunner: UnitTestRunner.Vitest,
});

expect(
appTree.read('my-app/vite.config.mts', 'utf-8')
).toMatchSnapshot();
});

it('should generate vite.config.mts if workspace package type is module', async () => {
updateJson(appTree, 'package.json', (json) => ({
...json,
type: 'module',
}));

await generateApp(appTree, 'my-app', {
skipFormat: false,
unitTestRunner: UnitTestRunner.Vitest,
});

expect(
appTree.read('my-app/vite.config.mts', 'utf-8')
).toMatchSnapshot();
});
});

describe('none', () => {
it('should not generate test configuration', async () => {
await generateApp(appTree, 'my-app', {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import { Tree } from '@nx/devkit';
import { UnitTestRunner } from '../../../utils/test-runners';
import { addJest } from '../../utils/add-jest';
import { addVitest } from '../../utils/add-vitest';
import type { NormalizedSchema } from './normalized-schema';

export async function addUnitTestRunner(host: Tree, options: NormalizedSchema) {
if (options.unitTestRunner === UnitTestRunner.Jest) {
await addJest(host, {
name: options.name,
projectRoot: options.appProjectRoot,
skipPackageJson: options.skipPackageJson,
strict: options.strict,
});
switch (options.unitTestRunner) {
case UnitTestRunner.Jest:
await addJest(host, {
name: options.name,
projectRoot: options.appProjectRoot,
skipPackageJson: options.skipPackageJson,
strict: options.strict,
});
break;
case UnitTestRunner.Vitest:
await addVitest(host, {
name: options.name,
projectRoot: options.appProjectRoot,
skipPackageJson: options.skipPackageJson,
strict: options.strict,
});
break;
}
}
3 changes: 2 additions & 1 deletion packages/angular/src/generators/application/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "none"],
"enum": ["jest", "vitest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "Which unit test runner would you like to use?",
"default": "jest"
},
"e2eTestRunner": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "none"],
"enum": ["jest", "vitest", "none"],
"description": "Test runner to use for unit tests of the remote if it needs to be created.",
"x-prompt": "Which unit test runner would you like to use?",
"default": "jest"
},
"e2eTestRunner": {
Expand Down
Loading