+
Skip to content

fix(vitest-angular): add check for nx inside generator #1635

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

Merged
merged 2 commits into from
Mar 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
186 changes: 186 additions & 0 deletions packages/nx-plugin/src/generators/setup-vitest/generator.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import { Tree, addProjectConfiguration, writeJson } from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import setupVitestGenerator from './generator';
import {
V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR,
V19_X_ANALOG_JS_VITEST_ANGULAR,
V19_X_JSDOM,
V19_X_VITE_TSCONFIG_PATHS,
V19_X_VITEST,
V19_X_VITE,
NX_X_LATEST_VITE,
NX_X_LATEST_VITEST,
} from '../../utils/versions/ng_19_X/versions';

describe('setup-vitest generator', () => {
let tree: Tree;

beforeEach(() => {
tree = createTreeWithEmptyWorkspace();

// Setup mock Angular project
addProjectConfiguration(tree, 'test-app', {
root: 'test-app',
sourceRoot: 'test-app/src',
projectType: 'application',
targets: {},
});

// Add package.json with Angular dependencies
writeJson(tree, 'package.json', {
dependencies: {
'@angular/core': '19.0.0',
'@nx/angular': '20.0.0',
nx: '20.0.0',
},
devDependencies: {},
});

// Add Angular project files
writeJson(tree, 'test-app/tsconfig.json', {
compilerOptions: {
types: [],
},
include: [],
});
});

it('should add the correct dev dependencies', async () => {
await setupVitestGenerator(tree, {
project: 'test-app',
});

const packageJson = JSON.parse(tree.read('package.json', 'utf-8'));
expect(packageJson.devDependencies).toMatchObject({
'@analogjs/vite-plugin-angular': V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR,
'@analogjs/vitest-angular': V19_X_ANALOG_JS_VITEST_ANGULAR,
vitest: V19_X_VITEST,
jsdom: V19_X_JSDOM,
vite: V19_X_VITE,
'vite-tsconfig-paths': V19_X_VITE_TSCONFIG_PATHS,
});
});

it('should modify project configuration', async () => {
await setupVitestGenerator(tree, {
project: 'test-app',
});

const projectConfig = JSON.parse(
tree.read('test-app/project.json', 'utf-8'),
);

expect(projectConfig.targets.test).toBeDefined();
expect(projectConfig.targets.test.executor).toBe(
'@analogjs/vitest-angular:test',
);
});

it('should create vite.config.mts with correct content', async () => {
await setupVitestGenerator(tree, {
project: 'test-app',
});

expect(tree.exists('test-app/vite.config.mts')).toBeTruthy();
const vitestConfig = tree.read('test-app/vite.config.mts', 'utf-8');
expect(vitestConfig).toEqual(
[
'/// <reference types="vitest" />',
'',
`import angular from '@analogjs/vite-plugin-angular';`,
'',
`import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';`,
'',
`import { defineConfig } from 'vite';`,
'',
'// https://vitejs.dev/config/',
'export default defineConfig(({ mode }) => {',
' return {',
' plugins: [angular(), nxViteTsPaths()],',
' test: {',
' globals: true,',
" environment: 'jsdom',",
" setupFiles: ['src/test-setup.ts'],",
" include: ['**/*.spec.ts'],",
" reporters: ['default'],",
' },',
' define: {',
" 'import.meta.vitest': mode !== 'production',",
' },',
' };',
'});',
'',
].join('\n'),
);
});

it('should update tsconfig.spec.json', async () => {
// Create initial tsconfig.spec.json without files property
writeJson(tree, 'test-app/tsconfig.spec.json', {
compilerOptions: {
types: ['node'],
module: 'commonjs',
},
});

await setupVitestGenerator(tree, {
project: 'test-app',
});

const tsconfig = JSON.parse(
tree.read('test-app/tsconfig.spec.json', 'utf-8'),
);

// Check all modifications made by updateTsConfig
expect(tsconfig.compilerOptions.module).toBeUndefined();
expect(tsconfig.compilerOptions.target).toBe('es2016');
expect(tsconfig.compilerOptions.types).toEqual(['node', 'vitest/globals']);
expect(tsconfig.files).toEqual(['src/test-setup.ts']);
});

it('should add vite 6 when using nx 20.5', async () => {
// Setup with Nx 20.5
writeJson(tree, 'package.json', {
dependencies: {
'@angular/core': '19.0.0',
'@nx/angular': '20.5.0',
},
devDependencies: {},
});

await setupVitestGenerator(tree, {
project: 'test-app',
});

const packageJson = JSON.parse(tree.read('package.json', 'utf-8'));
expect(packageJson.devDependencies.vite).toBe(NX_X_LATEST_VITE); // '^6.0.0'
expect(packageJson.devDependencies.vitest).toBe(NX_X_LATEST_VITEST); // '^3.0.0'
});

it('should create test-setup.ts with correct content', async () => {
await setupVitestGenerator(tree, {
project: 'test-app',
});

expect(tree.exists('test-app/src/test-setup.ts')).toBeTruthy();

const setupContent = tree.read('test-app/src/test-setup.ts', 'utf-8');
expect(setupContent).toEqual(
[
`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(),',
');',
'',
].join('\n'),
);
});
});
3 changes: 2 additions & 1 deletion packages/nx-plugin/src/generators/setup-vitest/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ export async function setupVitestGenerator(
options: SetupVitestGeneratorSchema,
) {
const angularVersion = getInstalledPackageVersion(tree, '@angular/core');
const nxVersion = getInstalledPackageVersion(tree, 'nx');

addAnalogDependencies(tree, angularVersion);
addAnalogDependencies(tree, angularVersion, nxVersion);
updateTsConfig(tree, options);
updateTestTarget(tree, options);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ import { addDependenciesToPackageJson, Tree } from '@nx/devkit';

import { getAnalogDevDependencies } from '../../../utils/versions/dev-dependencies';

export function addAnalogDependencies(tree: Tree, angularVersion: string) {
const devDependencies = getAnalogDevDependencies(angularVersion);
export function addAnalogDependencies(
tree: Tree,
angularVersion: string,
nxVersion: string,
) {
const devDependencies = getAnalogDevDependencies(angularVersion, nxVersion);

addDependenciesToPackageJson(tree, {}, devDependencies);
}
32 changes: 24 additions & 8 deletions packages/nx-plugin/src/utils/versions/dev-dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import {
V19_X_VITE_TSCONFIG_PATHS,
V19_X_VITEST,
V19_X_VITE,
NX_X_LATEST_VITE,
NX_X_LATEST_VITEST,
} from './ng_19_X/versions';

const devDependencyKeys = [
Expand All @@ -60,21 +62,29 @@ export type AnalogDevDependency = (typeof devDependencyKeys)[number];

export const getAnalogDevDependencies = (
ngVersion: string,
nxVersion?: string,
): Record<AnalogDevDependency, string> => {
const escapedNgVersion = ngVersion.replace(/[~^]/, '');
const escapedNxVersion = nxVersion ? nxVersion.replace(/[~^]/, '') : null;

const devDependencies = getDevDependencies(escapedNgVersion);
const devDependencies = getDevDependencies(
escapedNgVersion,
escapedNxVersion,
);

return { ...devDependencies };
};

const getDevDependencies = (escapedAngularVersion: string) => {
// fail out for versions <15.2.0
const getDevDependencies = (
escapedAngularVersion: string,
escapedNxVersion: string | null,
) => {
// fail out for versions <15.0.0
if (lt(escapedAngularVersion, '15.0.0')) {
throw new Error(stripIndents`Angular v15.0.0 or newer is required.`);
}

// install 15.x deps for versions <15.0.0
// install 15.x deps for versions <16.0.0
if (lt(escapedAngularVersion, '16.0.0')) {
return {
'@analogjs/platform': V15_X_ANALOG_JS_PLATFORM,
Expand Down Expand Up @@ -117,7 +127,7 @@ const getDevDependencies = (escapedAngularVersion: string) => {
}

// install 18.x deps for versions <19.0.0
if (lt(escapedAngularVersion, '18.0.0')) {
if (lt(escapedAngularVersion, '19.0.0')) {
return {
'@analogjs/platform': V18_X_ANALOG_JS_PLATFORM,
'@analogjs/vite-plugin-angular': V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR,
Expand All @@ -130,15 +140,21 @@ const getDevDependencies = (escapedAngularVersion: string) => {
};
}

// return latest 19.x deps for versions >19.0.0
// return latest 19.x deps for versions >=19.0.0
return {
'@analogjs/platform': V19_X_ANALOG_JS_PLATFORM,
'@analogjs/vite-plugin-angular': V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR,
'@analogjs/vitest-angular': V19_X_ANALOG_JS_VITEST_ANGULAR,
'@nx/vite': V19_X_NX_VITE,
jsdom: V19_X_JSDOM,
'vite-tsconfig-paths': V19_X_VITE_TSCONFIG_PATHS,
vite: V19_X_VITE,
vitest: V19_X_VITEST,
vite:
escapedNxVersion && lt(escapedNxVersion, '20.5.0')
? V19_X_VITE
: NX_X_LATEST_VITE,
vitest:
escapedNxVersion && lt(escapedNxVersion, '20.5.0')
? V19_X_VITEST
: NX_X_LATEST_VITEST,
};
};
6 changes: 4 additions & 2 deletions packages/nx-plugin/src/utils/versions/ng_19_X/versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ export const V19_X_NX_ANGULAR = '^20.0.0';
export const V19_X_NX_VITE = '^20.0.0';
export const V19_X_JSDOM = '^22.0.0';
export const V19_X_VITE_TSCONFIG_PATHS = '^4.2.0';
export const V19_X_VITEST = '^3.0.0';
export const V19_X_VITE = '^6.0.0';
export const V19_X_VITEST = '^2.0.0';
export const V19_X_VITE = '^5.0.0';
export const NX_X_LATEST_VITE = '^6.0.0';
export const NX_X_LATEST_VITEST = '^3.0.0';
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载