Skip to content

Commit

Permalink
feat(testing): add jest create-nodes plugin (#20045)
Browse files Browse the repository at this point in the history
  • Loading branch information
FrozenPandaz committed Jan 11, 2024
1 parent 595a774 commit 5d9b4c5
Show file tree
Hide file tree
Showing 17 changed files with 535 additions and 359 deletions.
28 changes: 18 additions & 10 deletions e2e/jest/src/jest-root.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,25 @@ describe('Jest root projects', () => {

describe('angular', () => {
beforeAll(() => {
newProject({ packages: ['@nx/angular', '@nx/react'] });
newProject({
packages: ['@nx/angular'],
unsetProjectNameAndRootFormat: false,
});
runCLI(
`generate @nx/angular:app ${myapp} --directory . --rootProject --projectNameAndRootFormat as-provided --no-interactive`
);
});

it('should test root level app projects', async () => {
runCLI(
`generate @nx/angular:app ${myapp} --rootProject=true --no-interactive`
);
const rootProjectTestResults = await runCLIAsync(`test ${myapp}`);
expect(rootProjectTestResults.combinedOutput).toContain(
'Test Suites: 1 passed, 1 total'
);
}, 300_000);

it('should add lib project and tests should still work', async () => {
runCLI(`generate @nx/angular:lib ${mylib} --no-interactive`);
runCLI(
`generate @nx/angular:component ${mylib} --export --standalone --project=${mylib} --no-interactive`
`generate @nx/angular:lib ${mylib} --projectNameAndRootFormat as-provided --no-interactive`
);

const libProjectTestResults = await runCLIAsync(`test ${mylib}`);
Expand All @@ -41,12 +43,16 @@ describe('Jest root projects', () => {

describe('react', () => {
beforeAll(() => {
newProject();
newProject({
packages: ['@nx/react'],
unsetProjectNameAndRootFormat: false,
});
runCLI(
`generate @nx/react:app ${myapp} --directory . --rootProject --projectNameAndRootFormat as-provided`
);
});

it('should test root level app projects', async () => {
runCLI(`generate @nx/react:app ${myapp} --rootProject=true`);

const rootProjectTestResults = await runCLIAsync(`test ${myapp}`);

expect(rootProjectTestResults.combinedOutput).toContain(
Expand All @@ -55,7 +61,9 @@ describe('Jest root projects', () => {
}, 300_000);

it('should add lib project and tests should still work', async () => {
runCLI(`generate @nx/react:lib ${mylib} --unitTestRunner=jest`);
runCLI(
`generate @nx/react:lib ${mylib} --unitTestRunner=jest --projectNameAndRootFormat as-provided`
);

const libProjectTestResults = await runCLIAsync(`test ${mylib}`);

Expand Down
4 changes: 3 additions & 1 deletion e2e/next-core/src/next-pcv3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ describe('@nx/next/plugin', () => {
let appName: string;

beforeAll(() => {
project = newProject();
project = newProject({
packages: ['@nx/next'],
});
appName = uniq('app');
runCLI(
`generate @nx/next:app ${appName} --project-name-and-root-format=as-provided --no-interactive`,
Expand Down
22 changes: 21 additions & 1 deletion e2e/nx-misc/src/workspace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('@nx/workspace:convert-to-monorepo', () => {

afterEach(() => cleanupProject());

it('should convert a standalone project to a monorepo', async () => {
it('should convert a standalone webpack and jest react project to a monorepo', async () => {
const reactApp = uniq('reactapp');
runCLI(
`generate @nx/react:app ${reactApp} --rootProject=true --bundler=webpack --unitTestRunner=jest --e2eTestRunner=cypress --no-interactive`
Expand All @@ -43,6 +43,26 @@ describe('@nx/workspace:convert-to-monorepo', () => {
expect(() => runCLI(`lint e2e`)).not.toThrow();
expect(() => runCLI(`e2e e2e`)).not.toThrow();
});

it('should be convert a standalone vite and playwright react project to a monorepo', async () => {
const reactApp = uniq('reactapp');
runCLI(
`generate @nx/react:app ${reactApp} --rootProject=true --bundler=vite --unitTestRunner vitest --e2eTestRunner=playwright --no-interactive`
);

runCLI('generate @nx/workspace:convert-to-monorepo --no-interactive');

checkFilesExist(
`apps/${reactApp}/src/main.tsx`,
`apps/e2e/playwright.config.ts`
);

expect(() => runCLI(`build ${reactApp}`)).not.toThrow();
expect(() => runCLI(`test ${reactApp}`)).not.toThrow();
expect(() => runCLI(`lint ${reactApp}`)).not.toThrow();
expect(() => runCLI(`lint e2e`)).not.toThrow();
expect(() => runCLI(`e2e e2e`)).not.toThrow();
});
});

describe('Workspace Tests', () => {
Expand Down
19 changes: 15 additions & 4 deletions e2e/webpack/src/webpack.pcv3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,32 @@ describe('Webpack Plugin (PCv3)', () => {
beforeAll(() => {
originalPcv3 = process.env.NX_PCV3;
process.env.NX_PCV3 = 'true';
newProject();
newProject({
packages: ['@nx/react'],
unsetProjectNameAndRootFormat: false,
});
});

afterAll(() => {
process.env.NX_PCV3 = originalPcv3;
cleanupProject();
});

it('should generate, build, and serve React applications', () => {
it('should generate, build, and serve React applications and libraries', () => {
const appName = uniq('app');
const libName = uniq('lib');
runCLI(
`generate @nx/react:app ${appName} --bundler webpack --e2eTestRunner=cypress --no-interactive`
`generate @nx/react:app ${appName} --bundler webpack --e2eTestRunner=cypress --rootProject --no-interactive`
);

expect(true).toBe(true);
expect(() => runCLI(`test ${appName}`)).not.toThrow();

runCLI(
`generate @nx/react:lib ${libName} --unitTestRunner jest --no-interactive`
);

expect(() => runCLI(`test ${appName}`)).not.toThrow();
expect(() => runCLI(`test ${libName}`)).not.toThrow();

// TODO: figure out why this test hangs in CI (maybe down to sudo prompt?)
// expect(() => runCLI(`build ${appName}`)).not.toThrow();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { NormalizedSchema } from './normalized-schema';
export async function addUnitTestRunner(host: Tree, options: NormalizedSchema) {
if (options.unitTestRunner === UnitTestRunner.Jest) {
await configurationGenerator(host, {
...options,
project: options.name,
setupFile: 'angular',
supportTsx: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ describe('Cypress Component Testing Configuration', () => {
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
tree.write('.gitignore', '');
mockedInstalledCypressVersion.mockReturnValue(10);

projectGraph = {
dependencies: {},
nodes: {},
};
});

afterEach(() => {
Expand Down Expand Up @@ -191,6 +196,9 @@ describe('Cypress Component Testing Configuration', () => {
export: true,
skipFormat: true,
});

jest.clearAllMocks();

const appConfig = readProjectConfiguration(tree, 'fancy-app');
appConfig.targets['build'].executor = 'something/else';
updateProjectConfiguration(tree, 'fancy-app', appConfig);
Expand Down
5 changes: 5 additions & 0 deletions packages/angular/src/generators/library/library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ describe('lib', () => {

beforeEach(() => {
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });

projectGraph = {
dependencies: {},
nodes: {},
};
});

it('should run the library generator without erroring if the directory has a trailing slash', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ describe('Jest+Ng - 15.9.0 - tsconfig updates', () => {
beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
tree.write('.gitignore', '');

projectGraph = {
dependencies: {},
nodes: {},
};
});

it('should update tsconfig.spec.json with target es2016', async () => {
Expand Down
1 change: 1 addition & 0 deletions packages/jest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"jest-config": "^29.4.1",
"jest-resolve": "^29.4.1",
"jest-util": "^29.4.1",
"minimatch": "3.0.5",
"resolve.exports": "1.1.0",
"tslib": "^2.3.0",
"@nx/devkit": "file:../devkit",
Expand Down
5 changes: 5 additions & 0 deletions packages/jest/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export {
createNodes,
createDependencies,
JestPluginOptions,
} from './src/plugins/plugin';
12 changes: 11 additions & 1 deletion packages/jest/src/generators/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Tree,
GeneratorCallback,
readProjectConfiguration,
readNxJson,
} from '@nx/devkit';

const schemaDefaults = {
Expand Down Expand Up @@ -65,7 +66,16 @@ export async function configurationGenerator(
checkForTestTarget(tree, options);
createFiles(tree, options);
updateTsConfig(tree, options);
updateWorkspace(tree, options);

const nxJson = readNxJson(tree);
const hasPlugin = nxJson.plugins?.some((p) =>
typeof p === 'string'
? p === '@nx/jest/plugin'
: p.plugin === '@nx/jest/plugin'
);
if (!hasPlugin) {
updateWorkspace(tree, options);
}

if (!schema.skipFormat) {
await formatFiles(tree);
Expand Down
44 changes: 43 additions & 1 deletion packages/jest/src/generators/init/init.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
let projectGraph: ProjectGraph;
jest.mock('@nx/devkit', () => ({
...jest.requireActual<any>('@nx/devkit'),
createProjectGraphAsync: jest.fn().mockImplementation(async () => {
return projectGraph;
}),
}));

import {
addProjectConfiguration,
addProjectConfiguration as _addProjectConfiguration,
NxJsonConfiguration,
ProjectGraph,
readJson,
readProjectConfiguration,
stripIndents,
Expand All @@ -11,11 +20,29 @@ import {
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { jestInitGenerator } from './init';

function addProjectConfiguration(tree, name, project) {
_addProjectConfiguration(tree, name, project);
projectGraph.nodes[name] = {
name: name,
type: 'lib',
data: {
root: project.root,
targets: project.targets,
},
};
}

describe('jest', () => {
let tree: Tree;

beforeEach(() => {
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });

projectGraph = {
nodes: {},
dependencies: {},
externalNodes: {},
};
});

it('should generate files with --js flag', async () => {
Expand Down Expand Up @@ -250,6 +277,21 @@ export default {
);
await jestInitGenerator(tree, { rootProject: false });
expect(tree.exists('jest.config.app.ts')).toBeTruthy();
expect(tree.read('jest.config.app.ts', 'utf-8')).toMatchInlineSnapshot(`
"
/* eslint-disable */
export default {
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
displayName: 'my-project',
testEnvironment: 'node',
preset: './jest.preset.js',
};
"
`);
expect(tree.read('jest.config.ts', 'utf-8'))
.toEqual(`import { getJestProjects } from '@nx/jest';
Expand Down
Loading

0 comments on commit 5d9b4c5

Please sign in to comment.