chore(repo): split angular e2e tests into core and extensions (#6470)
This commit is contained in:
parent
f3b5ffc165
commit
1ca34f9669
3
.github/workflows/e2e-matrix.yml
vendored
3
.github/workflows/e2e-matrix.yml
vendored
@ -36,7 +36,7 @@ jobs:
|
||||
- yarn
|
||||
- pnpm
|
||||
packages:
|
||||
- e2e-angular
|
||||
- e2e-angular-core,e2e-angular-extensions
|
||||
- e2e-cli,e2e-nx-plugin,e2e-jest,e2e-linter
|
||||
- e2e-cypress
|
||||
- e2e-gatsby,e2e-react
|
||||
@ -104,7 +104,6 @@ jobs:
|
||||
NODE_OPTIONS: --max_old_space_size=8192
|
||||
SELECTED_PM: ${{ matrix.package_manager }}
|
||||
YARN_REGISTRY: http://localhost:4872
|
||||
SELECTED_CLI: ${{ matrix.packages == 'e2e-angular' && 'angular' || 'nx' }}
|
||||
|
||||
- name: Setup tmate session
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled && failure() }}
|
||||
|
||||
@ -6,5 +6,5 @@ module.exports = {
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
|
||||
maxWorkers: 1,
|
||||
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
|
||||
displayName: 'e2e-angular',
|
||||
displayName: 'e2e-angular-core',
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"root": "e2e/angular",
|
||||
"sourceRoot": "e2e/angular",
|
||||
"root": "e2e/angular-core",
|
||||
"sourceRoot": "e2e/angular-core",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"e2e": {
|
||||
@ -14,7 +14,7 @@
|
||||
"command": "yarn e2e-build-package-publish"
|
||||
},
|
||||
{
|
||||
"command": "nx run-e2e-tests e2e-angular"
|
||||
"command": "nx run-e2e-tests e2e-angular-core"
|
||||
}
|
||||
],
|
||||
"parallel": false
|
||||
@ -23,11 +23,11 @@
|
||||
"run-e2e-tests": {
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"options": {
|
||||
"jestConfig": "e2e/angular/jest.config.js",
|
||||
"jestConfig": "e2e/angular-core/jest.config.js",
|
||||
"passWithNoTests": true,
|
||||
"runInBand": true
|
||||
},
|
||||
"outputs": ["coverage/e2e/angular"]
|
||||
"outputs": ["coverage/e2e/angular-core"]
|
||||
}
|
||||
},
|
||||
"implicitDependencies": ["angular"]
|
||||
118
e2e/angular-core/src/angular-core.test.ts
Normal file
118
e2e/angular-core/src/angular-core.test.ts
Normal file
@ -0,0 +1,118 @@
|
||||
import {
|
||||
checkFilesExist,
|
||||
expectTestsPass,
|
||||
getSelectedPackageManager,
|
||||
getSize,
|
||||
killPorts,
|
||||
newProject,
|
||||
removeProject,
|
||||
runCLI,
|
||||
runCLIAsync,
|
||||
tmpProjPath,
|
||||
uniq,
|
||||
updateFile,
|
||||
runCypressTests,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
import { names } from '@nrwl/devkit';
|
||||
|
||||
describe('Angular Package', () => {
|
||||
describe('core', () => {
|
||||
let proj: string;
|
||||
|
||||
beforeEach(() => (proj = newProject()));
|
||||
afterEach(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('should work', async () => {
|
||||
// TODO: npm build is failing for Angular because of webpack 4
|
||||
// remove this condition once `node` is migrated to webpack 5
|
||||
if (getSelectedPackageManager() !== 'npm') {
|
||||
const myapp = uniq('myapp');
|
||||
const mylib = uniq('mylib');
|
||||
runCLI(
|
||||
`generate @nrwl/angular:app ${myapp} --directory=myDir --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:lib ${mylib} --directory=myDir --add-module-spec --no-interactive`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`apps/my-dir/${myapp}/src/app/app.module.ts`,
|
||||
`
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { MyDir${
|
||||
names(mylib).className
|
||||
}Module } from '@${proj}/my-dir/${mylib}';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule, MyDir${names(mylib).className}Module],
|
||||
declarations: [AppComponent],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule {}
|
||||
`
|
||||
);
|
||||
runCLI(`build my-dir-${myapp} --prod --output-hashing none`);
|
||||
|
||||
checkFilesExist(`dist/apps/my-dir/${myapp}/main.js`);
|
||||
|
||||
// This is a loose requirement because there are a lot of
|
||||
// influences external from this project that affect this.
|
||||
const es2015BundleSize = getSize(
|
||||
tmpProjPath(`dist/apps/my-dir/${myapp}/main.js`)
|
||||
);
|
||||
console.log(
|
||||
`The current es2015 bundle size is ${es2015BundleSize / 1000} KB`
|
||||
);
|
||||
expect(es2015BundleSize).toBeLessThanOrEqual(160000);
|
||||
|
||||
// running tests for the app
|
||||
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
|
||||
|
||||
// running tests for the lib
|
||||
expectTestsPass(await runCLIAsync(`test my-dir-${mylib} --no-watch`));
|
||||
|
||||
if (runCypressTests()) {
|
||||
const e2eResults = runCLI(
|
||||
`e2e my-dir-${myapp}-e2e --headless --no-watch`
|
||||
);
|
||||
expect(e2eResults).toContain('All specs passed!');
|
||||
expect(await killPorts()).toBeTruthy();
|
||||
}
|
||||
}
|
||||
}, 1000000);
|
||||
|
||||
it('should support building in parallel', () => {
|
||||
// TODO: npm build is failing for Angular because of webpack 4
|
||||
// remove this condition once `node` is migrated to webpack 5
|
||||
if (getSelectedPackageManager() !== 'npm') {
|
||||
if (getSelectedPackageManager() === 'pnpm') {
|
||||
// TODO: This tests fails with pnpm but we should still enable this for other package managers
|
||||
return;
|
||||
}
|
||||
const myapp = uniq('myapp');
|
||||
const myapp2 = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp}`);
|
||||
runCLI(`generate @nrwl/angular:app ${myapp2}`);
|
||||
|
||||
runCLI('run-many --target build --all --parallel');
|
||||
}
|
||||
});
|
||||
|
||||
it('should support Ivy', async () => {
|
||||
// TODO: npm build is failing for Angular because of webpack 4
|
||||
// remove this condition once `node` is migrated to webpack 5
|
||||
if (getSelectedPackageManager() !== 'npm') {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(
|
||||
`generate @nrwl/angular:app ${myapp} --directory=myDir --routing --enable-ivy`
|
||||
);
|
||||
|
||||
runCLI(`build my-dir-${myapp} --aot`);
|
||||
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
|
||||
}
|
||||
}, 1000000);
|
||||
});
|
||||
});
|
||||
70
e2e/angular-core/src/angular-linting.test.ts
Normal file
70
e2e/angular-core/src/angular-linting.test.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import {
|
||||
newProject,
|
||||
removeProject,
|
||||
runCLI,
|
||||
uniq,
|
||||
updateFile,
|
||||
} from '@nrwl/e2e/utils';
|
||||
import * as path from 'path';
|
||||
|
||||
describe('Angular Package', () => {
|
||||
describe('linting', () => {
|
||||
beforeEach(() => newProject());
|
||||
afterEach(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('should support eslint and pass linting on the standard generated code', async () => {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --linter=eslint`);
|
||||
expect(runCLI(`lint ${myapp}`)).toContain('All files pass linting.');
|
||||
|
||||
const mylib = uniq('mylib');
|
||||
runCLI(`generate @nrwl/angular:lib ${mylib} --linter=eslint`);
|
||||
expect(runCLI(`lint ${mylib}`)).toContain('All files pass linting.');
|
||||
});
|
||||
|
||||
it('should support eslint and successfully lint external HTML files and inline templates', async () => {
|
||||
const myapp = uniq('myapp');
|
||||
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --linter=eslint`);
|
||||
|
||||
const templateWhichFailsBananaInBoxLintCheck = `<div ([foo])="bar"></div>`;
|
||||
const wrappedAsInlineTemplate = `
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'inline-template-component',
|
||||
template: \`
|
||||
${templateWhichFailsBananaInBoxLintCheck}
|
||||
\`,
|
||||
})
|
||||
export class InlineTemplateComponent {}
|
||||
`;
|
||||
|
||||
// External HTML template file
|
||||
updateFile(
|
||||
`apps/${myapp}/src/app/app.component.html`,
|
||||
templateWhichFailsBananaInBoxLintCheck
|
||||
);
|
||||
|
||||
// Inline template within component.ts file
|
||||
updateFile(
|
||||
`apps/${myapp}/src/app/inline-template.component.ts`,
|
||||
wrappedAsInlineTemplate
|
||||
);
|
||||
|
||||
const appLintStdOut = runCLI(`lint ${myapp}`, { silenceError: true });
|
||||
expect(appLintStdOut).toContain(
|
||||
path.normalize(`apps/${myapp}/src/app/app.component.html`)
|
||||
);
|
||||
expect(appLintStdOut).toContain(`1:6`);
|
||||
expect(appLintStdOut).toContain(`Invalid binding syntax`);
|
||||
expect(appLintStdOut).toContain(
|
||||
path.normalize(`apps/${myapp}/src/app/inline-template.component.ts`)
|
||||
);
|
||||
expect(appLintStdOut).toContain(
|
||||
`The selector should start with one of these prefixes`
|
||||
);
|
||||
expect(appLintStdOut).toContain(`7:18`);
|
||||
});
|
||||
});
|
||||
});
|
||||
48
e2e/angular-core/src/config-compat.test.ts
Normal file
48
e2e/angular-core/src/config-compat.test.ts
Normal file
@ -0,0 +1,48 @@
|
||||
process.env.SELECTED_CLI = 'angular';
|
||||
|
||||
import {
|
||||
expectTestsPass,
|
||||
newProject,
|
||||
readJson,
|
||||
removeProject,
|
||||
runCLI,
|
||||
runCLIAsync,
|
||||
uniq,
|
||||
updateFile,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
describe('Angular Package', () => {
|
||||
describe('config compat', () => {
|
||||
beforeEach(() => newProject());
|
||||
afterEach(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('should work', async () => {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --no-interactive`);
|
||||
|
||||
// update the angular.json
|
||||
const workspaceJson = readJson(`angular.json`);
|
||||
workspaceJson.version = 2;
|
||||
workspaceJson.projects[myapp].targets = updateConfig(
|
||||
workspaceJson.projects[myapp].architect
|
||||
);
|
||||
workspaceJson.generators = workspaceJson.schematics;
|
||||
delete workspaceJson.schematics;
|
||||
updateFile('angular.json', JSON.stringify(workspaceJson, null, 2));
|
||||
|
||||
const myapp2 = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp2} --no-interactive`);
|
||||
expectTestsPass(await runCLIAsync(`test ${myapp2} --no-watch`));
|
||||
}, 1000000);
|
||||
});
|
||||
});
|
||||
|
||||
function updateConfig(targets: any) {
|
||||
const res = {};
|
||||
Object.entries(targets).forEach(([name, t]: any) => {
|
||||
t.executor = t.builder;
|
||||
delete t.builder;
|
||||
res[name] = t;
|
||||
});
|
||||
return res;
|
||||
}
|
||||
366
e2e/angular-core/src/ng-add.test.ts
Normal file
366
e2e/angular-core/src/ng-add.test.ts
Normal file
@ -0,0 +1,366 @@
|
||||
process.env.SELECTED_CLI = 'angular';
|
||||
|
||||
import {
|
||||
checkFilesExist,
|
||||
readJson,
|
||||
removeProject,
|
||||
runCLI,
|
||||
runCommand,
|
||||
runNgAdd,
|
||||
runNgNew,
|
||||
uniq,
|
||||
updateFile,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
// TODO: Check why generated angular app is different
|
||||
xdescribe('Angular Package', () => {
|
||||
describe('convert to Nx workspace', () => {
|
||||
let proj;
|
||||
|
||||
afterEach(() => {
|
||||
removeProject({ onlyOnCI: true });
|
||||
});
|
||||
|
||||
it('should generate a workspace', () => {
|
||||
proj = uniq('proj');
|
||||
runNgNew(proj);
|
||||
|
||||
// update package.json
|
||||
const packageJson = readJson('package.json');
|
||||
packageJson.description = 'some description';
|
||||
updateFile('package.json', JSON.stringify(packageJson, null, 2));
|
||||
// confirm that @nrwl and @ngrx dependencies do not exist yet
|
||||
expect(packageJson.devDependencies['@nrwl/workspace']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/store']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/effects']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/router-store']).not.toBeDefined();
|
||||
expect(
|
||||
packageJson.devDependencies['@ngrx/store-devtools']
|
||||
).not.toBeDefined();
|
||||
|
||||
// update tsconfig.json
|
||||
const tsconfigJson = readJson('tsconfig.json');
|
||||
tsconfigJson.compilerOptions.paths = { a: ['b'] };
|
||||
updateFile('tsconfig.json', JSON.stringify(tsconfigJson, null, 2));
|
||||
|
||||
updateFile('src/scripts.ts', '');
|
||||
|
||||
// update angular-cli.json
|
||||
const angularCLIJson = readJson('angular.json');
|
||||
angularCLIJson.projects[proj].architect.build.options.scripts =
|
||||
angularCLIJson.projects[proj].architect.test.options.scripts = [
|
||||
'src/scripts.ts',
|
||||
];
|
||||
angularCLIJson.projects[proj].architect.test.options.styles = [
|
||||
'src/styles.css',
|
||||
];
|
||||
updateFile('angular.json', JSON.stringify(angularCLIJson, null, 2));
|
||||
|
||||
// run the command
|
||||
runNgAdd('--npm-scope projscope');
|
||||
|
||||
// check that prettier config exits and that files have been moved!
|
||||
checkFilesExist(
|
||||
'.vscode/extensions.json',
|
||||
'.prettierrc',
|
||||
`apps/${proj}/src/main.ts`,
|
||||
`apps/${proj}/src/app/app.module.ts`
|
||||
);
|
||||
|
||||
expect(readJson('.vscode/extensions.json').recommendations).toEqual([
|
||||
'nrwl.angular-console',
|
||||
'angular.ng-template',
|
||||
'dbaeumer.vscode-eslint',
|
||||
'esbenp.prettier-vscode',
|
||||
]);
|
||||
|
||||
// check that package.json got merged
|
||||
const updatedPackageJson = readJson('package.json');
|
||||
expect(updatedPackageJson.description).toEqual('some description');
|
||||
expect(updatedPackageJson.scripts).toEqual({
|
||||
ng: 'nx',
|
||||
nx: 'nx',
|
||||
start: 'ng serve',
|
||||
build: 'ng build',
|
||||
test: 'ng test',
|
||||
lint: 'nx workspace-lint && ng lint',
|
||||
e2e: 'ng e2e',
|
||||
'affected:apps': 'nx affected:apps',
|
||||
'affected:libs': 'nx affected:libs',
|
||||
'affected:build': 'nx affected:build',
|
||||
'affected:e2e': 'nx affected:e2e',
|
||||
'affected:test': 'nx affected:test',
|
||||
'affected:lint': 'nx affected:lint',
|
||||
'affected:dep-graph': 'nx affected:dep-graph',
|
||||
affected: 'nx affected',
|
||||
format: 'nx format:write',
|
||||
'format:write': 'nx format:write',
|
||||
'format:check': 'nx format:check',
|
||||
update: 'ng update @nrwl/workspace',
|
||||
'update:check': 'ng update',
|
||||
postinstall: 'node ./decorate-angular-cli.js',
|
||||
'dep-graph': 'nx dep-graph',
|
||||
'workspace-generator': 'nx workspace-generator',
|
||||
help: 'nx help',
|
||||
});
|
||||
expect(
|
||||
updatedPackageJson.devDependencies['@nrwl/workspace']
|
||||
).toBeDefined();
|
||||
expect(updatedPackageJson.devDependencies['@angular/cli']).toBeDefined();
|
||||
|
||||
const nxJson = readJson('nx.json');
|
||||
expect(nxJson).toEqual({
|
||||
npmScope: 'projscope',
|
||||
implicitDependencies: {
|
||||
'angular.json': '*',
|
||||
'package.json': '*',
|
||||
'tslint.json': '*',
|
||||
'.eslintrc.json': '*',
|
||||
'tsconfig.base.json': '*',
|
||||
'nx.json': '*',
|
||||
},
|
||||
projects: {
|
||||
[`${proj}`]: {
|
||||
tags: [],
|
||||
},
|
||||
[`${proj}-e2e`]: {
|
||||
tags: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// check if angular-cli.json get merged
|
||||
const updatedAngularCLIJson = readJson('angular.json');
|
||||
expect(updatedAngularCLIJson.projects[proj].root).toEqual(`apps/${proj}`);
|
||||
expect(updatedAngularCLIJson.projects[proj].sourceRoot).toEqual(
|
||||
`apps/${proj}/src`
|
||||
);
|
||||
|
||||
expect(updatedAngularCLIJson.projects[proj].architect.build).toEqual({
|
||||
builder: '@angular-devkit/build-angular:browser',
|
||||
options: {
|
||||
aot: true,
|
||||
outputPath: `dist/apps/${proj}`,
|
||||
index: `apps/${proj}/src/index.html`,
|
||||
main: `apps/${proj}/src/main.ts`,
|
||||
polyfills: `apps/${proj}/src/polyfills.ts`,
|
||||
tsConfig: `apps/${proj}/tsconfig.app.json`,
|
||||
assets: [`apps/${proj}/src/favicon.ico`, `apps/${proj}/src/assets`],
|
||||
styles: [`apps/${proj}/src/styles.css`],
|
||||
scripts: [`apps/${proj}/src/scripts.ts`],
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
fileReplacements: [
|
||||
{
|
||||
replace: `apps/${proj}/src/environments/environment.ts`,
|
||||
with: `apps/${proj}/src/environments/environment.prod.ts`,
|
||||
},
|
||||
],
|
||||
budgets: [
|
||||
{
|
||||
maximumError: '5mb',
|
||||
maximumWarning: '2mb',
|
||||
type: 'initial',
|
||||
},
|
||||
{
|
||||
maximumError: '10kb',
|
||||
maximumWarning: '6kb',
|
||||
type: 'anyComponentStyle',
|
||||
},
|
||||
],
|
||||
optimization: true,
|
||||
outputHashing: 'all',
|
||||
sourceMap: false,
|
||||
extractCss: true,
|
||||
namedChunks: false,
|
||||
extractLicenses: true,
|
||||
vendorChunk: false,
|
||||
buildOptimizer: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(updatedAngularCLIJson.projects[proj].architect.serve).toEqual({
|
||||
builder: '@angular-devkit/build-angular:dev-server',
|
||||
options: {
|
||||
browserTarget: 'proj:build',
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
browserTarget: 'proj:build:production',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects[proj].architect.test).toEqual({
|
||||
builder: '@angular-devkit/build-angular:karma',
|
||||
options: {
|
||||
main: `apps/${proj}/src/test.ts`,
|
||||
polyfills: `apps/${proj}/src/polyfills.ts`,
|
||||
tsConfig: `apps/${proj}/tsconfig.spec.json`,
|
||||
karmaConfig: `apps/${proj}/karma.conf.js`,
|
||||
styles: [`apps/${proj}/src/styles.css`],
|
||||
scripts: [`apps/${proj}/src/scripts.ts`],
|
||||
assets: [`apps/${proj}/src/favicon.ico`, `apps/${proj}/src/assets`],
|
||||
},
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects[proj].architect.lint).toEqual({
|
||||
builder: '@angular-devkit/build-angular:tslint',
|
||||
options: {
|
||||
tsConfig: [
|
||||
`apps/${proj}/tsconfig.app.json`,
|
||||
`apps/${proj}/tsconfig.spec.json`,
|
||||
],
|
||||
exclude: ['**/node_modules/**'],
|
||||
},
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects[`${proj}-e2e`].root).toEqual(
|
||||
`apps/${proj}-e2e`
|
||||
);
|
||||
expect(
|
||||
updatedAngularCLIJson.projects[`${proj}-e2e`].architect.e2e
|
||||
).toEqual({
|
||||
builder: '@angular-devkit/build-angular:protractor',
|
||||
configurations: {
|
||||
production: {
|
||||
devServerTarget: `${proj}:serve:production`,
|
||||
},
|
||||
},
|
||||
options: {
|
||||
protractorConfig: `apps/${proj}-e2e/protractor.conf.js`,
|
||||
devServerTarget: `${proj}:serve`,
|
||||
},
|
||||
});
|
||||
expect(
|
||||
updatedAngularCLIJson.projects[`${proj}-e2e`].architect.lint
|
||||
).toEqual({
|
||||
builder: '@angular-devkit/build-angular:tslint',
|
||||
options: {
|
||||
tsConfig: `apps/${proj}-e2e/tsconfig.json`,
|
||||
exclude: ['**/node_modules/**'],
|
||||
},
|
||||
});
|
||||
|
||||
const updatedTslint = readJson('tslint.json');
|
||||
expect(updatedTslint.rules['nx-enforce-module-boundaries']).toEqual([
|
||||
true,
|
||||
{
|
||||
allow: [],
|
||||
depConstraints: [{ sourceTag: '*', onlyDependOnLibsWithTags: ['*'] }],
|
||||
},
|
||||
]);
|
||||
|
||||
runCLI('build --prod --outputHashing none');
|
||||
checkFilesExist(`dist/apps/${proj}/main-es2015.js`);
|
||||
});
|
||||
|
||||
it('should generate a workspace and not change dependencies, devDependencies, or vscode extensions if they already exist', () => {
|
||||
// create a new AngularCLI app
|
||||
proj = uniq('proj');
|
||||
runNgNew(proj);
|
||||
const schematicsVersion = '12.0.0';
|
||||
const ngrxVersion = '12.0.0';
|
||||
// update package.json
|
||||
const existingPackageJson = readJson('package.json');
|
||||
existingPackageJson.devDependencies['@nrwl/workspace'] =
|
||||
schematicsVersion;
|
||||
existingPackageJson.dependencies['@ngrx/store'] = ngrxVersion;
|
||||
existingPackageJson.dependencies['@ngrx/effects'] = ngrxVersion;
|
||||
existingPackageJson.dependencies['@ngrx/router-store'] = ngrxVersion;
|
||||
existingPackageJson.devDependencies['@ngrx/store-devtools'] = ngrxVersion;
|
||||
updateFile('package.json', JSON.stringify(existingPackageJson, null, 2));
|
||||
|
||||
updateFile(
|
||||
'.vscode/extensions.json',
|
||||
JSON.stringify({
|
||||
recommendations: ['eamodio.gitlens', 'angular.ng-template'],
|
||||
})
|
||||
);
|
||||
// run the command
|
||||
runNgAdd('--npm-scope projscope --skip-install');
|
||||
|
||||
// check that dependencies and devDependencies remained the same
|
||||
const packageJson = readJson('package.json');
|
||||
expect(packageJson.devDependencies['@nrwl/workspace']).toEqual(
|
||||
schematicsVersion
|
||||
);
|
||||
expect(packageJson.dependencies['@ngrx/store']).toEqual(ngrxVersion);
|
||||
expect(packageJson.dependencies['@ngrx/effects']).toEqual(ngrxVersion);
|
||||
expect(packageJson.dependencies['@ngrx/router-store']).toEqual(
|
||||
ngrxVersion
|
||||
);
|
||||
expect(packageJson.devDependencies['@ngrx/store-devtools']).toEqual(
|
||||
ngrxVersion
|
||||
);
|
||||
|
||||
expect(readJson('.vscode/extensions.json').recommendations).toEqual([
|
||||
'eamodio.gitlens',
|
||||
'angular.ng-template',
|
||||
'nrwl.angular-console',
|
||||
'dbaeumer.vscode-eslint',
|
||||
'esbenp.prettier-vscode',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should handle different types of errors', () => {
|
||||
// create a new AngularCLI app
|
||||
proj = uniq('proj');
|
||||
runNgNew(proj);
|
||||
|
||||
// Only remove e2e directory
|
||||
runCommand('mv e2e e2e-bak');
|
||||
try {
|
||||
runNgAdd('--npm-scope projscope --skip-install');
|
||||
fail('Did not handle not having a e2e directory');
|
||||
} catch (e) {
|
||||
expect(e.stderr.toString()).toContain(
|
||||
'Your workspace could not be converted into an Nx Workspace because of the above error.'
|
||||
);
|
||||
}
|
||||
|
||||
// Put e2e back
|
||||
runCommand('mv e2e-bak e2e');
|
||||
|
||||
// Remove package.json
|
||||
runCommand('mv package.json package.json.bak');
|
||||
try {
|
||||
runNgAdd('--npm-scope projscope --skip-install');
|
||||
fail('Did not handle not having a package.json');
|
||||
} catch (e) {
|
||||
expect(e.stderr.toString()).toContain(
|
||||
'Your workspace could not be converted into an Nx Workspace because of the above error.'
|
||||
);
|
||||
}
|
||||
|
||||
// Put package.json back
|
||||
runCommand('mv package.json.bak package.json');
|
||||
|
||||
// Remove src
|
||||
runCommand('mv src src-bak');
|
||||
try {
|
||||
runNgAdd('--npm-scope projscope --skip-install');
|
||||
fail('Did not handle not having a src directory');
|
||||
} catch (e) {
|
||||
expect(e.stderr.toString()).toContain('Path: src does not exist');
|
||||
}
|
||||
|
||||
// Put src back
|
||||
runCommand('mv src-bak src');
|
||||
});
|
||||
|
||||
it('should support preserveAngularCLILayout', () => {
|
||||
proj = uniq('proj');
|
||||
runNgNew(proj);
|
||||
runNgAdd('--preserveAngularCLILayout');
|
||||
|
||||
const updatedAngularCLIJson = readJson('angular.json');
|
||||
expect(updatedAngularCLIJson.projects[proj].root).toEqual('');
|
||||
expect(updatedAngularCLIJson.projects[proj].sourceRoot).toEqual('src');
|
||||
|
||||
const output = runCLI('build');
|
||||
expect(output).toContain(`> ng run ${proj}:build`);
|
||||
});
|
||||
});
|
||||
});
|
||||
10
e2e/angular-extensions/jest.config.js
Normal file
10
e2e/angular-extensions/jest.config.js
Normal file
@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
preset: '../../jest.preset.js',
|
||||
transform: {
|
||||
'^.+\\.[tj]sx?$': 'ts-jest',
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
|
||||
maxWorkers: 1,
|
||||
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
|
||||
displayName: 'e2e-angular-extensions',
|
||||
};
|
||||
34
e2e/angular-extensions/project.json
Normal file
34
e2e/angular-extensions/project.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"root": "e2e/angular-extensions",
|
||||
"sourceRoot": "e2e/angular-extensions",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"e2e": {
|
||||
"executor": "@nrwl/workspace:run-commands",
|
||||
"options": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "yarn e2e-start-local-registry"
|
||||
},
|
||||
{
|
||||
"command": "yarn e2e-build-package-publish"
|
||||
},
|
||||
{
|
||||
"command": "nx run-e2e-tests e2e-angular-extensions"
|
||||
}
|
||||
],
|
||||
"parallel": false
|
||||
}
|
||||
},
|
||||
"run-e2e-tests": {
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"options": {
|
||||
"jestConfig": "e2e/angular-extensions/jest.config.js",
|
||||
"passWithNoTests": true,
|
||||
"runInBand": true
|
||||
},
|
||||
"outputs": ["coverage/e2e/angular-extensions"]
|
||||
}
|
||||
},
|
||||
"implicitDependencies": ["angular"]
|
||||
}
|
||||
88
e2e/angular-extensions/src/angular-app.test.ts
Normal file
88
e2e/angular-extensions/src/angular-app.test.ts
Normal file
@ -0,0 +1,88 @@
|
||||
process.env.SELECTED_CLI = 'angular';
|
||||
|
||||
import {
|
||||
getSelectedPackageManager,
|
||||
newProject,
|
||||
readFile,
|
||||
readJson,
|
||||
removeProject,
|
||||
runCLI,
|
||||
uniq,
|
||||
updateFile,
|
||||
} from '@nrwl/e2e/utils';
|
||||
import { names } from '@nrwl/devkit';
|
||||
|
||||
// TODO: Check why this fails on yarn and npm
|
||||
describe('Angular Package', () => {
|
||||
describe('app builder', () => {
|
||||
let app;
|
||||
let buildableLib;
|
||||
let proj: string;
|
||||
|
||||
// This fails with pnpm due to incompatibilities with ngcc.
|
||||
// Since this suite has a single test, we wrap everything to avoid the hooks to run and
|
||||
// waste time.
|
||||
if (getSelectedPackageManager() !== 'pnpm') {
|
||||
beforeEach(() => {
|
||||
app = uniq('app');
|
||||
buildableLib = uniq('buildlib1');
|
||||
|
||||
proj = newProject();
|
||||
|
||||
runCLI(
|
||||
`generate @nrwl/angular:app ${app} --style=css --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${buildableLib} --buildable=true --no-interactive`
|
||||
);
|
||||
|
||||
// update the app module to include a ref to the buildable lib
|
||||
updateFile(
|
||||
`apps/${app}/src/app/app.module.ts`,
|
||||
`
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import {${
|
||||
names(buildableLib).className
|
||||
}Module} from '@${proj}/${buildableLib}';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
imports: [BrowserModule, ${names(buildableLib).className}Module],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {}
|
||||
`
|
||||
);
|
||||
|
||||
// update the angular.json
|
||||
const workspaceJson = readJson(`angular.json`);
|
||||
workspaceJson.projects[app].architect.build.builder =
|
||||
'@nrwl/angular:webpack-browser';
|
||||
updateFile('angular.json', JSON.stringify(workspaceJson, null, 2));
|
||||
});
|
||||
|
||||
afterEach(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('should build the dependent buildable lib as well as the app', () => {
|
||||
const libOutput = runCLI(
|
||||
`build ${app} --with-deps --configuration=development`
|
||||
);
|
||||
expect(libOutput).toContain(
|
||||
`Building entry point '@${proj}/${buildableLib}'`
|
||||
);
|
||||
expect(libOutput).toContain(`nx run ${app}:build:development`);
|
||||
|
||||
// to proof it has been built from source the "main.js" should actually contain
|
||||
// the path to dist
|
||||
const mainBundle = readFile(`dist/apps/${app}/main.js`);
|
||||
expect(mainBundle).toContain(`dist/libs/${buildableLib}`);
|
||||
});
|
||||
} else {
|
||||
it('Skip tests with pnpm', () => {});
|
||||
}
|
||||
});
|
||||
});
|
||||
178
e2e/angular-extensions/src/angular-library.test.ts
Normal file
178
e2e/angular-extensions/src/angular-library.test.ts
Normal file
@ -0,0 +1,178 @@
|
||||
process.env.SELECTED_CLI = 'angular';
|
||||
|
||||
import {
|
||||
checkFilesExist,
|
||||
getSelectedPackageManager,
|
||||
newProject,
|
||||
readJson,
|
||||
removeProject,
|
||||
runCLI,
|
||||
uniq,
|
||||
updateFile,
|
||||
} from '@nrwl/e2e/utils';
|
||||
import { names } from '@nrwl/devkit';
|
||||
|
||||
describe('Angular Package', () => {
|
||||
['publishable', 'buildable'].forEach((testConfig) => {
|
||||
describe(`library builder - ${testConfig}`, () => {
|
||||
/**
|
||||
* Graph:
|
||||
*
|
||||
* childLib
|
||||
* /
|
||||
* parentLib =>
|
||||
* \
|
||||
* \
|
||||
* childLib2
|
||||
*
|
||||
*/
|
||||
let parentLib: string;
|
||||
let childLib: string;
|
||||
let childLib2: string;
|
||||
let proj: string;
|
||||
|
||||
beforeEach(() => {
|
||||
parentLib = uniq('parentlib');
|
||||
childLib = uniq('childlib');
|
||||
childLib2 = uniq('childlib2');
|
||||
|
||||
proj = newProject();
|
||||
|
||||
if (testConfig === 'buildable') {
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${parentLib} --buildable=true --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${childLib} --buildable=true --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${childLib2} --buildable=true --no-interactive`
|
||||
);
|
||||
} else {
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${parentLib} --publishable=true --importPath=@${proj}/${parentLib} --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${childLib} --publishable=true --importPath=@${proj}/${childLib} --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${childLib2} --publishable=true --importPath=@${proj}/${childLib2} --no-interactive`
|
||||
);
|
||||
|
||||
// create secondary entrypoint
|
||||
updateFile(
|
||||
`libs/${childLib}/sub/package.json`,
|
||||
`
|
||||
{
|
||||
"ngPackage": {}
|
||||
}
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
`libs/${childLib}/sub/src/lib/sub.module.ts`,
|
||||
`
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
@NgModule({ imports: [CommonModule] })
|
||||
export class SubModule {}
|
||||
`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`libs/${childLib}/sub/src/public_api.ts`,
|
||||
`export * from './lib/sub.module';`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`libs/${childLib}/sub/src/index.ts`,
|
||||
`export * from './public_api';`
|
||||
);
|
||||
|
||||
updateFile(`tsconfig.base.json`, (s) => {
|
||||
return s.replace(
|
||||
`"@${proj}/${childLib}": ["libs/${childLib}/src/index.ts"],`,
|
||||
`"@${proj}/${childLib}": ["libs/${childLib}/src/index.ts"],
|
||||
"@${proj}/${childLib}/sub": ["libs/${childLib}/sub/src/index.ts"],
|
||||
`
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// create dependencies by importing
|
||||
const createDep = (parent, children: string[]) => {
|
||||
let moduleContent = `
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
${children
|
||||
.map(
|
||||
(entry) =>
|
||||
`import { ${
|
||||
names(entry).className
|
||||
}Module } from '@${proj}/${entry}';`
|
||||
)
|
||||
.join('\n')}
|
||||
`;
|
||||
|
||||
if (testConfig === 'publishable') {
|
||||
moduleContent += `
|
||||
import { SubModule } from '@${proj}/${childLib}/sub';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, ${children
|
||||
.map((entry) => `${names(entry).className}Module`)
|
||||
.join(',')}, SubModule]
|
||||
})
|
||||
export class ${names(parent).className}Module {}`;
|
||||
}
|
||||
|
||||
updateFile(
|
||||
`libs/${parent}/src/lib/${parent}.module.ts`,
|
||||
moduleContent
|
||||
);
|
||||
};
|
||||
|
||||
createDep(parentLib, [childLib, childLib2]);
|
||||
});
|
||||
|
||||
afterEach(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('empty test to make jest happy', () => {});
|
||||
|
||||
// These fail with pnpm due to incompatibilities with ngcc for buildable libraries.
|
||||
if (
|
||||
getSelectedPackageManager() !== 'pnpm' ||
|
||||
testConfig === 'publishable'
|
||||
) {
|
||||
it('should build the library when it does not have any deps', () => {
|
||||
runCLI(`build ${childLib}`);
|
||||
|
||||
checkFilesExist(`dist/libs/${childLib}/package.json`);
|
||||
});
|
||||
|
||||
it('should properly add references to any dependency into the parent package.json', () => {
|
||||
runCLI(`build ${childLib}`);
|
||||
runCLI(`build ${childLib2}`);
|
||||
runCLI(`build ${parentLib}`);
|
||||
|
||||
checkFilesExist(
|
||||
`dist/libs/${childLib}/package.json`,
|
||||
`dist/libs/${childLib2}/package.json`,
|
||||
`dist/libs/${parentLib}/package.json`
|
||||
);
|
||||
|
||||
const jsonFile = readJson(`dist/libs/${parentLib}/package.json`);
|
||||
|
||||
expect(jsonFile.dependencies['tslib']).toMatch(/\^2\.\d+\.\d+/); // match any ^2.x.x
|
||||
expect(
|
||||
jsonFile.peerDependencies[`@${proj}/${childLib}`]
|
||||
).toBeDefined();
|
||||
expect(
|
||||
jsonFile.peerDependencies[`@${proj}/${childLib2}`]
|
||||
).toBeDefined();
|
||||
expect(jsonFile.peerDependencies['@angular/common']).toBeDefined();
|
||||
expect(jsonFile.peerDependencies['@angular/core']).toBeDefined();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
50
e2e/angular-extensions/src/angular-router-config.test.ts
Normal file
50
e2e/angular-extensions/src/angular-router-config.test.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import {
|
||||
expectTestsPass,
|
||||
getSelectedPackageManager,
|
||||
newProject,
|
||||
removeProject,
|
||||
runCLI,
|
||||
runCLIAsync,
|
||||
uniq,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
describe('Angular Package', () => {
|
||||
describe('router config', () => {
|
||||
beforeEach(() => newProject());
|
||||
afterEach(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('should support router config generation (lazy)', async () => {
|
||||
if (getSelectedPackageManager() !== 'npm') {
|
||||
const myapp = uniq('myapp');
|
||||
const mylib = uniq('mylib');
|
||||
runCLI(
|
||||
`generate @nrwl/angular:app ${myapp} --directory=myDir --routing`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:lib ${mylib} --directory=myDir --routing --lazy --parentModule=apps/my-dir/${myapp}/src/app/app.module.ts`
|
||||
);
|
||||
|
||||
runCLI(`build my-dir-${myapp} --aot`);
|
||||
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
|
||||
}
|
||||
}, 1000000);
|
||||
|
||||
it('should support router config generation (eager)', async () => {
|
||||
// TODO: npm build is failing for Angular because of webpack 4
|
||||
// remove this condition once `node` is migrated to webpack 5
|
||||
if (getSelectedPackageManager() !== 'npm') {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(
|
||||
`generate @nrwl/angular:app ${myapp} --directory=myDir --routing`
|
||||
);
|
||||
const mylib = uniq('mylib');
|
||||
runCLI(
|
||||
`generate @nrwl/angular:lib ${mylib} --directory=myDir --routing --parentModule=apps/my-dir/${myapp}/src/app/app.module.ts`
|
||||
);
|
||||
|
||||
runCLI(`build my-dir-${myapp} --aot`);
|
||||
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
|
||||
}
|
||||
}, 1000000);
|
||||
});
|
||||
});
|
||||
72
e2e/angular-extensions/src/ngrx.test.ts
Normal file
72
e2e/angular-extensions/src/ngrx.test.ts
Normal file
@ -0,0 +1,72 @@
|
||||
import {
|
||||
expectTestsPass,
|
||||
newProject,
|
||||
readJson,
|
||||
removeProject,
|
||||
runCLI,
|
||||
runCLIAsync,
|
||||
uniq,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
describe('Angular Package', () => {
|
||||
describe('ngrx', () => {
|
||||
beforeEach(() => newProject());
|
||||
afterAll(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('should work', async () => {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --no-interactive`);
|
||||
|
||||
// Generate root ngrx state management
|
||||
runCLI(
|
||||
`generate @nrwl/angular:ngrx users --module=apps/${myapp}/src/app/app.module.ts --root --minimal=false --syntax=classes --useDataPersistence=true`
|
||||
);
|
||||
const packageJson = readJson('package.json');
|
||||
expect(packageJson.dependencies['@ngrx/store']).toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/effects']).toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/router-store']).toBeDefined();
|
||||
expect(packageJson.devDependencies['@ngrx/store-devtools']).toBeDefined();
|
||||
|
||||
const mylib = uniq('mylib');
|
||||
// Generate feature library and ngrx state within that library
|
||||
runCLI(`g @nrwl/angular:lib ${mylib} --prefix=fl`);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:ngrx flights --module=libs/${mylib}/src/lib/${mylib}.module.ts --facade --syntax=classes`
|
||||
);
|
||||
|
||||
expect(runCLI(`build ${myapp}`)).toMatch(/main\.[a-z0-9]+\.js/);
|
||||
expectTestsPass(await runCLIAsync(`test ${myapp} --no-watch`));
|
||||
expectTestsPass(await runCLIAsync(`test ${mylib} --no-watch`));
|
||||
}, 1000000);
|
||||
|
||||
it('should work with creators', async () => {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --routing --no-interactive`);
|
||||
|
||||
// Generate root ngrx state management
|
||||
runCLI(
|
||||
`generate @nrwl/angular:ngrx users --module=apps/${myapp}/src/app/app.module.ts --root`
|
||||
);
|
||||
const packageJson = readJson('package.json');
|
||||
expect(packageJson.dependencies['@ngrx/entity']).toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/store']).toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/effects']).toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/router-store']).toBeDefined();
|
||||
expect(packageJson.devDependencies['@ngrx/schematics']).toBeDefined();
|
||||
expect(packageJson.devDependencies['@ngrx/store-devtools']).toBeDefined();
|
||||
|
||||
const mylib = uniq('mylib');
|
||||
// Generate feature library and ngrx state within that library
|
||||
runCLI(`g @nrwl/angular:lib ${mylib} --prefix=fl`);
|
||||
|
||||
const flags = `--facade --barrels`;
|
||||
runCLI(
|
||||
`generate @nrwl/angular:ngrx flights --module=libs/${mylib}/src/lib/${mylib}.module.ts ${flags}`
|
||||
);
|
||||
|
||||
expect(runCLI(`build ${myapp}`)).toMatch(/main\.[a-z0-9]+\.js/);
|
||||
expectTestsPass(await runCLIAsync(`test ${myapp} --no-watch`));
|
||||
expectTestsPass(await runCLIAsync(`test ${mylib} --no-watch`));
|
||||
}, 1000000);
|
||||
});
|
||||
});
|
||||
@ -14,25 +14,26 @@ import {
|
||||
} from '@nrwl/e2e/utils';
|
||||
import { writeFileSync } from 'fs';
|
||||
|
||||
describe('Storybook schematics', () => {
|
||||
let proj: string;
|
||||
describe('Angular Package', () => {
|
||||
describe('storybook schematics', () => {
|
||||
let proj: string;
|
||||
|
||||
beforeEach(() => (proj = newProject()));
|
||||
afterAll(() => removeProject({ onlyOnCI: true }));
|
||||
beforeEach(() => (proj = newProject()));
|
||||
afterAll(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('should not overwrite global storybook config files', () => {
|
||||
const angularStorybookLib = uniq('test-ui-lib-angular');
|
||||
runCLI(
|
||||
`generate @nrwl/angular:lib ${angularStorybookLib} --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:storybook-configuration ${angularStorybookLib} --generateStories --no-interactive`
|
||||
);
|
||||
it('should not overwrite global storybook config files', () => {
|
||||
const angularStorybookLib = uniq('test-ui-lib-angular');
|
||||
runCLI(
|
||||
`generate @nrwl/angular:lib ${angularStorybookLib} --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:storybook-configuration ${angularStorybookLib} --generateStories --no-interactive`
|
||||
);
|
||||
|
||||
checkFilesExist(`.storybook/main.js`);
|
||||
writeFileSync(
|
||||
tmpProjPath(`.storybook/main.js`),
|
||||
`
|
||||
checkFilesExist(`.storybook/main.js`);
|
||||
writeFileSync(
|
||||
tmpProjPath(`.storybook/main.js`),
|
||||
`
|
||||
module.exports = {
|
||||
stories: [],
|
||||
addons: ['@storybook/addon-essentials'],
|
||||
@ -40,38 +41,38 @@ describe('Storybook schematics', () => {
|
||||
|
||||
console.log('hi there');
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
// generate another lib with storybook config
|
||||
const anotherAngularStorybookLib = uniq('test-ui-lib-angular2');
|
||||
runCLI(
|
||||
`generate @nrwl/angular:lib ${anotherAngularStorybookLib} --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:storybook-configuration ${anotherAngularStorybookLib} --generateStories --no-interactive`
|
||||
);
|
||||
// generate another lib with storybook config
|
||||
const anotherAngularStorybookLib = uniq('test-ui-lib-angular2');
|
||||
runCLI(
|
||||
`generate @nrwl/angular:lib ${anotherAngularStorybookLib} --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:storybook-configuration ${anotherAngularStorybookLib} --generateStories --no-interactive`
|
||||
);
|
||||
|
||||
expect(readFile(`.storybook/main.js`)).toContain(
|
||||
`console.log('hi there');`
|
||||
);
|
||||
});
|
||||
expect(readFile(`.storybook/main.js`)).toContain(
|
||||
`console.log('hi there');`
|
||||
);
|
||||
});
|
||||
|
||||
describe('build storybook', () => {
|
||||
it('should execute e2e tests using Cypress running against Storybook', async () => {
|
||||
if (isNotWindows()) {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --no-interactive`);
|
||||
describe('build storybook', () => {
|
||||
it('should execute e2e tests using Cypress running against Storybook', async () => {
|
||||
if (isNotWindows()) {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --no-interactive`);
|
||||
|
||||
const myAngularLib = uniq('test-ui-lib');
|
||||
createTestUILib(myAngularLib);
|
||||
const myReactLib = uniq('test-ui-lib-react');
|
||||
runCLI(`generate @nrwl/react:lib ${myReactLib} --no-interactive`);
|
||||
runCLI(
|
||||
`generate @nrwl/react:component Button --project=${myReactLib} --no-interactive`
|
||||
);
|
||||
writeFileSync(
|
||||
tmpProjPath(`libs/${myReactLib}/src/lib/button.tsx`),
|
||||
`
|
||||
const myAngularLib = uniq('test-ui-lib');
|
||||
createTestUILib(myAngularLib);
|
||||
const myReactLib = uniq('test-ui-lib-react');
|
||||
runCLI(`generate @nrwl/react:lib ${myReactLib} --no-interactive`);
|
||||
runCLI(
|
||||
`generate @nrwl/react:component Button --project=${myReactLib} --no-interactive`
|
||||
);
|
||||
writeFileSync(
|
||||
tmpProjPath(`libs/${myReactLib}/src/lib/button.tsx`),
|
||||
`
|
||||
import React from 'react';
|
||||
|
||||
import './button.css';
|
||||
@ -95,10 +96,10 @@ describe('Storybook schematics', () => {
|
||||
|
||||
export default Button;
|
||||
`
|
||||
);
|
||||
writeFileSync(
|
||||
tmpProjPath(`libs/${myReactLib}/src/lib/button.stories.tsx`),
|
||||
`
|
||||
);
|
||||
writeFileSync(
|
||||
tmpProjPath(`libs/${myReactLib}/src/lib/button.stories.tsx`),
|
||||
`
|
||||
import { Story, Meta } from '@storybook/react';
|
||||
import { Button, ButtonProps } from './button';
|
||||
|
||||
@ -116,20 +117,20 @@ describe('Storybook schematics', () => {
|
||||
style: 'default',
|
||||
};
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
runCLI(
|
||||
`generate @nrwl/angular:storybook-configuration ${myAngularLib} --configureCypress --generateStories --generateCypressSpecs --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:stories ${myAngularLib} --generateCypressSpecs --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:storybook-configuration ${myAngularLib} --configureCypress --generateStories --generateCypressSpecs --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:stories ${myAngularLib} --generateCypressSpecs --no-interactive`
|
||||
);
|
||||
|
||||
writeFileSync(
|
||||
tmpProjPath(
|
||||
`apps/${myAngularLib}-e2e/src/integration/test-button/test-button.component.spec.ts`
|
||||
),
|
||||
`
|
||||
writeFileSync(
|
||||
tmpProjPath(
|
||||
`apps/${myAngularLib}-e2e/src/integration/test-button/test-button.component.spec.ts`
|
||||
),
|
||||
`
|
||||
describe('${myAngularLib}', () => {
|
||||
|
||||
it('should render the component', () => {
|
||||
@ -147,21 +148,23 @@ describe('Storybook schematics', () => {
|
||||
});
|
||||
});
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
runCLI(
|
||||
`generate @nrwl/react:storybook-configuration ${myReactLib} --configureCypress --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/react:storybook-configuration ${myReactLib} --configureCypress --no-interactive`
|
||||
);
|
||||
|
||||
// The following line (mkdirSync...) is not needed,
|
||||
// since the above schematic creates this directory.
|
||||
// So, if we leave it there, there's an error saying the directory exists.
|
||||
// I am not sure how it worked as it was :/
|
||||
// The following line (mkdirSync...) is not needed,
|
||||
// since the above schematic creates this directory.
|
||||
// So, if we leave it there, there's an error saying the directory exists.
|
||||
// I am not sure how it worked as it was :/
|
||||
|
||||
// mkdirSync(tmpProjPath(`apps/${myReactLib}-e2e/src/integration`));
|
||||
writeFileSync(
|
||||
tmpProjPath(`apps/${myReactLib}-e2e/src/integration/button.spec.ts`),
|
||||
`
|
||||
// mkdirSync(tmpProjPath(`apps/${myReactLib}-e2e/src/integration`));
|
||||
writeFileSync(
|
||||
tmpProjPath(
|
||||
`apps/${myReactLib}-e2e/src/integration/button.spec.ts`
|
||||
),
|
||||
`
|
||||
describe('react-ui', () => {
|
||||
it('should render the component', () => {
|
||||
cy.visit(
|
||||
@ -178,68 +181,68 @@ describe('Storybook schematics', () => {
|
||||
});
|
||||
});
|
||||
`
|
||||
);
|
||||
|
||||
if (runCypressTests()) {
|
||||
const e2eResults = runCLI(
|
||||
`e2e ${myAngularLib}-e2e --headless --no-watch`
|
||||
);
|
||||
expect(e2eResults).toContain('All specs passed!');
|
||||
expect(await killPorts()).toBeTruthy();
|
||||
|
||||
if (runCypressTests()) {
|
||||
const e2eResults = runCLI(
|
||||
`e2e ${myAngularLib}-e2e --headless --no-watch`
|
||||
);
|
||||
expect(e2eResults).toContain('All specs passed!');
|
||||
expect(await killPorts()).toBeTruthy();
|
||||
}
|
||||
|
||||
runCLI(`run ${myAngularLib}:build-storybook`);
|
||||
|
||||
checkFilesExist(`dist/storybook/${myAngularLib}/index.html`);
|
||||
expect(
|
||||
readFile(`dist/storybook/${myAngularLib}/index.html`)
|
||||
).toContain(`<title>Storybook</title>`);
|
||||
}
|
||||
}, 1000000);
|
||||
|
||||
runCLI(`run ${myAngularLib}:build-storybook`);
|
||||
|
||||
checkFilesExist(`dist/storybook/${myAngularLib}/index.html`);
|
||||
expect(readFile(`dist/storybook/${myAngularLib}/index.html`)).toContain(
|
||||
`<title>Storybook</title>`
|
||||
xit('should build an Angular based storybook', () => {
|
||||
const angularStorybookLib = uniq('test-ui-lib');
|
||||
createTestUILib(angularStorybookLib);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:storybook-configuration ${angularStorybookLib} --generateStories --no-interactive`
|
||||
);
|
||||
}
|
||||
}, 1000000);
|
||||
|
||||
xit('should build an Angular based storybook', () => {
|
||||
const angularStorybookLib = uniq('test-ui-lib');
|
||||
createTestUILib(angularStorybookLib);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:storybook-configuration ${angularStorybookLib} --generateStories --no-interactive`
|
||||
);
|
||||
// build Angular lib
|
||||
runCLI(`run ${angularStorybookLib}:build-storybook`);
|
||||
checkFilesExist(`dist/storybook/${angularStorybookLib}/index.html`);
|
||||
expect(
|
||||
readFile(`dist/storybook/${angularStorybookLib}/index.html`)
|
||||
).toContain(`<title>Storybook</title>`);
|
||||
}, 1000000);
|
||||
|
||||
// build Angular lib
|
||||
runCLI(`run ${angularStorybookLib}:build-storybook`);
|
||||
checkFilesExist(`dist/storybook/${angularStorybookLib}/index.html`);
|
||||
expect(
|
||||
readFile(`dist/storybook/${angularStorybookLib}/index.html`)
|
||||
).toContain(`<title>Storybook</title>`);
|
||||
}, 1000000);
|
||||
xit('should build an Angular based storybook that references another lib', () => {
|
||||
const angularStorybookLib = uniq('test-ui-lib');
|
||||
createTestUILib(angularStorybookLib);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:storybook-configuration ${angularStorybookLib} --generateStories --no-interactive`
|
||||
);
|
||||
|
||||
xit('should build an Angular based storybook that references another lib', () => {
|
||||
const angularStorybookLib = uniq('test-ui-lib');
|
||||
createTestUILib(angularStorybookLib);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:storybook-configuration ${angularStorybookLib} --generateStories --no-interactive`
|
||||
);
|
||||
// create another lib with a component
|
||||
const anotherTestLib = uniq('test-another-lib');
|
||||
runCLI(`g @nrwl/angular:library ${anotherTestLib} --no-interactive`);
|
||||
runCLI(
|
||||
`g @nrwl/angular:component my-test-cmp --project=${anotherTestLib} --no-interactive`
|
||||
);
|
||||
|
||||
// create another lib with a component
|
||||
const anotherTestLib = uniq('test-another-lib');
|
||||
runCLI(`g @nrwl/angular:library ${anotherTestLib} --no-interactive`);
|
||||
runCLI(
|
||||
`g @nrwl/angular:component my-test-cmp --project=${anotherTestLib} --no-interactive`
|
||||
);
|
||||
|
||||
// update index.ts and export it
|
||||
writeFileSync(
|
||||
tmpProjPath(`libs/${anotherTestLib}/src/index.ts`),
|
||||
`
|
||||
// update index.ts and export it
|
||||
writeFileSync(
|
||||
tmpProjPath(`libs/${anotherTestLib}/src/index.ts`),
|
||||
`
|
||||
export * from './lib/my-test-cmp/my-test-cmp.component';
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
// create a story in the first lib to reference the cmp from the 2nd lib
|
||||
writeFileSync(
|
||||
tmpProjPath(
|
||||
`libs/${angularStorybookLib}/src/lib/myteststory.stories.ts`
|
||||
),
|
||||
`
|
||||
// create a story in the first lib to reference the cmp from the 2nd lib
|
||||
writeFileSync(
|
||||
tmpProjPath(
|
||||
`libs/${angularStorybookLib}/src/lib/myteststory.stories.ts`
|
||||
),
|
||||
`
|
||||
import { moduleMetadata, Story, Meta } from '@storybook/angular';
|
||||
import { MyTestCmpComponent } from '@${proj}/${anotherTestLib}';
|
||||
|
||||
@ -263,15 +266,16 @@ describe('Storybook schematics', () => {
|
||||
Primary.args = {
|
||||
}
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
// build Angular lib
|
||||
runCLI(`run ${angularStorybookLib}:build-storybook`);
|
||||
checkFilesExist(`dist/storybook/${angularStorybookLib}/index.html`);
|
||||
expect(
|
||||
readFile(`dist/storybook/${angularStorybookLib}/index.html`)
|
||||
).toContain(`<title>Storybook</title>`);
|
||||
}, 1000000);
|
||||
// build Angular lib
|
||||
runCLI(`run ${angularStorybookLib}:build-storybook`);
|
||||
checkFilesExist(`dist/storybook/${angularStorybookLib}/index.html`);
|
||||
expect(
|
||||
readFile(`dist/storybook/${angularStorybookLib}/index.html`)
|
||||
).toContain(`<title>Storybook</title>`);
|
||||
}, 1000000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
13
e2e/angular-extensions/tsconfig.json
Normal file
13
e2e/angular-extensions/tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"types": ["node", "jest"]
|
||||
},
|
||||
"include": [],
|
||||
"files": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
16
e2e/angular-extensions/tsconfig.spec.json
Normal file
16
e2e/angular-extensions/tsconfig.spec.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": [
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
@ -1,82 +0,0 @@
|
||||
process.env.SELECTED_CLI = 'angular';
|
||||
|
||||
import {
|
||||
getSelectedPackageManager,
|
||||
newProject,
|
||||
readFile,
|
||||
readJson,
|
||||
removeProject,
|
||||
runCLI,
|
||||
uniq,
|
||||
updateFile,
|
||||
} from '@nrwl/e2e/utils';
|
||||
import { names } from '@nrwl/devkit';
|
||||
|
||||
// TODO: Check why this fails on yarn and npm
|
||||
xdescribe('Angular Nrwl app builder', () => {
|
||||
let app;
|
||||
let buildableLib;
|
||||
let proj: string;
|
||||
|
||||
// This fails with pnpm due to incompatibilities with ngcc.
|
||||
// Since this suite has a single test, we wrap everything to avoid the hooks to run and
|
||||
// waste time.
|
||||
if (getSelectedPackageManager() !== 'pnpm') {
|
||||
beforeEach(() => {
|
||||
app = uniq('app');
|
||||
buildableLib = uniq('buildlib1');
|
||||
|
||||
proj = newProject();
|
||||
|
||||
runCLI(`generate @nrwl/angular:app ${app} --style=css --no-interactive`);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${buildableLib} --buildable=true --no-interactive`
|
||||
);
|
||||
|
||||
// update the app module to include a ref to the buildable lib
|
||||
updateFile(
|
||||
`apps/${app}/src/app/app.module.ts`,
|
||||
`
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import {${
|
||||
names(buildableLib).className
|
||||
}Module} from '@${proj}/${buildableLib}';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
imports: [BrowserModule, ${names(buildableLib).className}Module],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {}
|
||||
`
|
||||
);
|
||||
|
||||
// update the angular.json
|
||||
const workspaceJson = readJson(`angular.json`);
|
||||
workspaceJson.projects[app].architect.build.builder =
|
||||
'@nrwl/angular:webpack-browser';
|
||||
updateFile('angular.json', JSON.stringify(workspaceJson, null, 2));
|
||||
});
|
||||
|
||||
afterEach(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('should build the dependent buildable lib as well as the app', () => {
|
||||
const libOutput = runCLI(`build ${app} --with-deps`);
|
||||
expect(libOutput).toContain(
|
||||
`Building entry point '@${proj}/${buildableLib}'`
|
||||
);
|
||||
expect(libOutput).toContain(`nx run ${app}:build`);
|
||||
|
||||
// to proof it has been built from source the "main.js" should actually contain
|
||||
// the path to dist
|
||||
const mainBundle = readFile(`dist/apps/${app}/main.js`);
|
||||
expect(mainBundle).toContain(`dist/libs/${buildableLib}`);
|
||||
});
|
||||
} else {
|
||||
it('Skip tests with pnpm', () => {});
|
||||
}
|
||||
});
|
||||
@ -1,202 +0,0 @@
|
||||
import * as path from 'path';
|
||||
import {
|
||||
checkFilesExist,
|
||||
expectTestsPass,
|
||||
getSelectedPackageManager,
|
||||
getSize,
|
||||
killPorts,
|
||||
newProject,
|
||||
removeProject,
|
||||
runCLI,
|
||||
runCLIAsync,
|
||||
tmpProjPath,
|
||||
uniq,
|
||||
updateFile,
|
||||
runCypressTests,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
import { names } from '@nrwl/devkit';
|
||||
|
||||
describe('Angular Package', () => {
|
||||
let proj: string;
|
||||
|
||||
beforeEach(() => (proj = newProject()));
|
||||
afterEach(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('should work', async () => {
|
||||
// TODO: npm build is failing for Angular because of webpack 4
|
||||
// remove this condition once `node` is migrated to webpack 5
|
||||
if (getSelectedPackageManager() !== 'npm') {
|
||||
const myapp = uniq('myapp');
|
||||
const mylib = uniq('mylib');
|
||||
runCLI(
|
||||
`generate @nrwl/angular:app ${myapp} --directory=myDir --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:lib ${mylib} --directory=myDir --add-module-spec --no-interactive`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`apps/my-dir/${myapp}/src/app/app.module.ts`,
|
||||
`
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { MyDir${
|
||||
names(mylib).className
|
||||
}Module } from '@${proj}/my-dir/${mylib}';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule, MyDir${names(mylib).className}Module],
|
||||
declarations: [AppComponent],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule {}
|
||||
`
|
||||
);
|
||||
runCLI(`build my-dir-${myapp} --prod --output-hashing none`);
|
||||
|
||||
checkFilesExist(`dist/apps/my-dir/${myapp}/main.js`);
|
||||
|
||||
// This is a loose requirement because there are a lot of
|
||||
// influences external from this project that affect this.
|
||||
const es2015BundleSize = getSize(
|
||||
tmpProjPath(`dist/apps/my-dir/${myapp}/main.js`)
|
||||
);
|
||||
console.log(
|
||||
`The current es2015 bundle size is ${es2015BundleSize / 1000} KB`
|
||||
);
|
||||
expect(es2015BundleSize).toBeLessThanOrEqual(160000);
|
||||
|
||||
// running tests for the app
|
||||
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
|
||||
|
||||
// running tests for the lib
|
||||
expectTestsPass(await runCLIAsync(`test my-dir-${mylib} --no-watch`));
|
||||
|
||||
if (runCypressTests()) {
|
||||
const e2eResults = runCLI(
|
||||
`e2e my-dir-${myapp}-e2e --headless --no-watch`
|
||||
);
|
||||
expect(e2eResults).toContain('All specs passed!');
|
||||
expect(await killPorts()).toBeTruthy();
|
||||
}
|
||||
}
|
||||
}, 1000000);
|
||||
|
||||
it('should support router config generation (lazy)', async () => {
|
||||
if (getSelectedPackageManager() !== 'npm') {
|
||||
const myapp = uniq('myapp');
|
||||
const mylib = uniq('mylib');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --directory=myDir --routing`);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:lib ${mylib} --directory=myDir --routing --lazy --parentModule=apps/my-dir/${myapp}/src/app/app.module.ts`
|
||||
);
|
||||
|
||||
runCLI(`build my-dir-${myapp} --aot`);
|
||||
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
|
||||
}
|
||||
}, 1000000);
|
||||
|
||||
it('should support router config generation (eager)', async () => {
|
||||
// TODO: npm build is failing for Angular because of webpack 4
|
||||
// remove this condition once `node` is migrated to webpack 5
|
||||
if (getSelectedPackageManager() !== 'npm') {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --directory=myDir --routing`);
|
||||
const mylib = uniq('mylib');
|
||||
runCLI(
|
||||
`generate @nrwl/angular:lib ${mylib} --directory=myDir --routing --parentModule=apps/my-dir/${myapp}/src/app/app.module.ts`
|
||||
);
|
||||
|
||||
runCLI(`build my-dir-${myapp} --aot`);
|
||||
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
|
||||
}
|
||||
}, 1000000);
|
||||
|
||||
it('should support Ivy', async () => {
|
||||
// TODO: npm build is failing for Angular because of webpack 4
|
||||
// remove this condition once `node` is migrated to webpack 5
|
||||
if (getSelectedPackageManager() !== 'npm') {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(
|
||||
`generate @nrwl/angular:app ${myapp} --directory=myDir --routing --enable-ivy`
|
||||
);
|
||||
|
||||
runCLI(`build my-dir-${myapp} --aot`);
|
||||
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
|
||||
}
|
||||
}, 1000000);
|
||||
|
||||
it('should support building in parallel', () => {
|
||||
// TODO: npm build is failing for Angular because of webpack 4
|
||||
// remove this condition once `node` is migrated to webpack 5
|
||||
if (getSelectedPackageManager() !== 'npm') {
|
||||
if (getSelectedPackageManager() === 'pnpm') {
|
||||
// TODO: This tests fails with pnpm but we should still enable this for other package managers
|
||||
return;
|
||||
}
|
||||
const myapp = uniq('myapp');
|
||||
const myapp2 = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp}`);
|
||||
runCLI(`generate @nrwl/angular:app ${myapp2}`);
|
||||
|
||||
runCLI('run-many --target build --all --parallel');
|
||||
}
|
||||
});
|
||||
|
||||
it('should support eslint and pass linting on the standard generated code', async () => {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --linter=eslint`);
|
||||
expect(runCLI(`lint ${myapp}`)).toContain('All files pass linting.');
|
||||
|
||||
const mylib = uniq('mylib');
|
||||
runCLI(`generate @nrwl/angular:lib ${mylib} --linter=eslint`);
|
||||
expect(runCLI(`lint ${mylib}`)).toContain('All files pass linting.');
|
||||
});
|
||||
|
||||
it('should support eslint and successfully lint external HTML files and inline templates', async () => {
|
||||
const myapp = uniq('myapp');
|
||||
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --linter=eslint`);
|
||||
|
||||
const templateWhichFailsBananaInBoxLintCheck = `<div ([foo])="bar"></div>`;
|
||||
const wrappedAsInlineTemplate = `
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'inline-template-component',
|
||||
template: \`
|
||||
${templateWhichFailsBananaInBoxLintCheck}
|
||||
\`,
|
||||
})
|
||||
export class InlineTemplateComponent {}
|
||||
`;
|
||||
|
||||
// External HTML template file
|
||||
updateFile(
|
||||
`apps/${myapp}/src/app/app.component.html`,
|
||||
templateWhichFailsBananaInBoxLintCheck
|
||||
);
|
||||
|
||||
// Inline template within component.ts file
|
||||
updateFile(
|
||||
`apps/${myapp}/src/app/inline-template.component.ts`,
|
||||
wrappedAsInlineTemplate
|
||||
);
|
||||
|
||||
const appLintStdOut = runCLI(`lint ${myapp}`, { silenceError: true });
|
||||
expect(appLintStdOut).toContain(
|
||||
path.normalize(`apps/${myapp}/src/app/app.component.html`)
|
||||
);
|
||||
expect(appLintStdOut).toContain(`1:6`);
|
||||
expect(appLintStdOut).toContain(`Invalid binding syntax`);
|
||||
expect(appLintStdOut).toContain(
|
||||
path.normalize(`apps/${myapp}/src/app/inline-template.component.ts`)
|
||||
);
|
||||
expect(appLintStdOut).toContain(
|
||||
`The selector should start with one of these prefixes`
|
||||
);
|
||||
expect(appLintStdOut).toContain(`7:18`);
|
||||
});
|
||||
});
|
||||
@ -1,171 +0,0 @@
|
||||
process.env.SELECTED_CLI = 'angular';
|
||||
|
||||
import {
|
||||
checkFilesExist,
|
||||
getSelectedPackageManager,
|
||||
newProject,
|
||||
readJson,
|
||||
removeProject,
|
||||
runCLI,
|
||||
uniq,
|
||||
updateFile,
|
||||
} from '@nrwl/e2e/utils';
|
||||
import { names } from '@nrwl/devkit';
|
||||
|
||||
['publishable', 'buildable'].forEach((testConfig) => {
|
||||
describe('Build Angular library', () => {
|
||||
/**
|
||||
* Graph:
|
||||
*
|
||||
* childLib
|
||||
* /
|
||||
* parentLib =>
|
||||
* \
|
||||
* \
|
||||
* childLib2
|
||||
*
|
||||
*/
|
||||
let parentLib: string;
|
||||
let childLib: string;
|
||||
let childLib2: string;
|
||||
let proj: string;
|
||||
|
||||
beforeEach(() => {
|
||||
parentLib = uniq('parentlib');
|
||||
childLib = uniq('childlib');
|
||||
childLib2 = uniq('childlib2');
|
||||
|
||||
proj = newProject();
|
||||
|
||||
if (testConfig === 'buildable') {
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${parentLib} --buildable=true --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${childLib} --buildable=true --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${childLib2} --buildable=true --no-interactive`
|
||||
);
|
||||
} else {
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${parentLib} --publishable=true --importPath=@${proj}/${parentLib} --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${childLib} --publishable=true --importPath=@${proj}/${childLib} --no-interactive`
|
||||
);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:library ${childLib2} --publishable=true --importPath=@${proj}/${childLib2} --no-interactive`
|
||||
);
|
||||
|
||||
// create secondary entrypoint
|
||||
updateFile(
|
||||
`libs/${childLib}/sub/package.json`,
|
||||
`
|
||||
{
|
||||
"ngPackage": {}
|
||||
}
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
`libs/${childLib}/sub/src/lib/sub.module.ts`,
|
||||
`
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
@NgModule({ imports: [CommonModule] })
|
||||
export class SubModule {}
|
||||
`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`libs/${childLib}/sub/src/public_api.ts`,
|
||||
`export * from './lib/sub.module';`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
`libs/${childLib}/sub/src/index.ts`,
|
||||
`export * from './public_api';`
|
||||
);
|
||||
|
||||
updateFile(`tsconfig.base.json`, (s) => {
|
||||
return s.replace(
|
||||
`"@${proj}/${childLib}": ["libs/${childLib}/src/index.ts"],`,
|
||||
`"@${proj}/${childLib}": ["libs/${childLib}/src/index.ts"],
|
||||
"@${proj}/${childLib}/sub": ["libs/${childLib}/sub/src/index.ts"],
|
||||
`
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// create dependencies by importing
|
||||
const createDep = (parent, children: string[]) => {
|
||||
let moduleContent = `
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
${children
|
||||
.map(
|
||||
(entry) =>
|
||||
`import { ${
|
||||
names(entry).className
|
||||
}Module } from '@${proj}/${entry}';`
|
||||
)
|
||||
.join('\n')}
|
||||
`;
|
||||
|
||||
if (testConfig === 'publishable') {
|
||||
moduleContent += `
|
||||
import { SubModule } from '@${proj}/${childLib}/sub';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, ${children
|
||||
.map((entry) => `${names(entry).className}Module`)
|
||||
.join(',')}, SubModule]
|
||||
})
|
||||
export class ${names(parent).className}Module {}`;
|
||||
}
|
||||
|
||||
updateFile(`libs/${parent}/src/lib/${parent}.module.ts`, moduleContent);
|
||||
};
|
||||
|
||||
createDep(parentLib, [childLib, childLib2]);
|
||||
});
|
||||
|
||||
afterEach(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('empty test to make jest happy', () => {});
|
||||
|
||||
// These fail with pnpm due to incompatibilities with ngcc for buildable libraries.
|
||||
if (
|
||||
getSelectedPackageManager() !== 'pnpm' ||
|
||||
testConfig === 'publishable'
|
||||
) {
|
||||
it('should build the library when it does not have any deps', () => {
|
||||
runCLI(`build ${childLib}`);
|
||||
|
||||
checkFilesExist(`dist/libs/${childLib}/package.json`);
|
||||
});
|
||||
|
||||
it('should properly add references to any dependency into the parent package.json', () => {
|
||||
runCLI(`build ${childLib}`);
|
||||
runCLI(`build ${childLib2}`);
|
||||
runCLI(`build ${parentLib}`);
|
||||
|
||||
checkFilesExist(
|
||||
`dist/libs/${childLib}/package.json`,
|
||||
`dist/libs/${childLib2}/package.json`,
|
||||
`dist/libs/${parentLib}/package.json`
|
||||
);
|
||||
|
||||
const jsonFile = readJson(`dist/libs/${parentLib}/package.json`);
|
||||
|
||||
expect(jsonFile.dependencies['tslib']).toMatch(/\^2\.\d+\.\d+/); // match any ^2.x.x
|
||||
expect(jsonFile.peerDependencies[`@${proj}/${childLib}`]).toBeDefined();
|
||||
expect(
|
||||
jsonFile.peerDependencies[`@${proj}/${childLib2}`]
|
||||
).toBeDefined();
|
||||
expect(jsonFile.peerDependencies['@angular/common']).toBeDefined();
|
||||
expect(jsonFile.peerDependencies['@angular/core']).toBeDefined();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1,46 +0,0 @@
|
||||
process.env.SELECTED_CLI = 'angular';
|
||||
|
||||
import {
|
||||
expectTestsPass,
|
||||
newProject,
|
||||
readJson,
|
||||
removeProject,
|
||||
runCLI,
|
||||
runCLIAsync,
|
||||
uniq,
|
||||
updateFile,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
describe('new config format', () => {
|
||||
beforeEach(() => newProject());
|
||||
afterEach(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('should work', async () => {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --no-interactive`);
|
||||
|
||||
// update the angular.json
|
||||
const workspaceJson = readJson(`angular.json`);
|
||||
workspaceJson.version = 2;
|
||||
workspaceJson.projects[myapp].targets = updateConfig(
|
||||
workspaceJson.projects[myapp].architect
|
||||
);
|
||||
workspaceJson.generators = workspaceJson.schematics;
|
||||
delete workspaceJson.schematics;
|
||||
updateFile('angular.json', JSON.stringify(workspaceJson, null, 2));
|
||||
|
||||
const myapp2 = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp2} --no-interactive`);
|
||||
expectTestsPass(await runCLIAsync(`test ${myapp2} --no-watch`));
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
function updateConfig(targets: any) {
|
||||
const res = {};
|
||||
Object.entries(targets).forEach(([name, t]: any) => {
|
||||
t.executor = t.builder;
|
||||
delete t.builder;
|
||||
res[name] = t;
|
||||
});
|
||||
return res;
|
||||
}
|
||||
@ -1,359 +0,0 @@
|
||||
process.env.SELECTED_CLI = 'angular';
|
||||
|
||||
import {
|
||||
checkFilesExist,
|
||||
readJson,
|
||||
removeProject,
|
||||
runCLI,
|
||||
runCommand,
|
||||
runNgAdd,
|
||||
runNgNew,
|
||||
uniq,
|
||||
updateFile,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
// TODO: Check why generated angular app is different
|
||||
xdescribe('Nrwl Convert to Nx Workspace', () => {
|
||||
let proj;
|
||||
|
||||
afterEach(() => {
|
||||
removeProject({ onlyOnCI: true });
|
||||
});
|
||||
|
||||
it('should generate a workspace', () => {
|
||||
proj = uniq('proj');
|
||||
runNgNew(proj);
|
||||
|
||||
// update package.json
|
||||
const packageJson = readJson('package.json');
|
||||
packageJson.description = 'some description';
|
||||
updateFile('package.json', JSON.stringify(packageJson, null, 2));
|
||||
// confirm that @nrwl and @ngrx dependencies do not exist yet
|
||||
expect(packageJson.devDependencies['@nrwl/workspace']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/store']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/effects']).not.toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/router-store']).not.toBeDefined();
|
||||
expect(
|
||||
packageJson.devDependencies['@ngrx/store-devtools']
|
||||
).not.toBeDefined();
|
||||
|
||||
// update tsconfig.json
|
||||
const tsconfigJson = readJson('tsconfig.json');
|
||||
tsconfigJson.compilerOptions.paths = { a: ['b'] };
|
||||
updateFile('tsconfig.json', JSON.stringify(tsconfigJson, null, 2));
|
||||
|
||||
updateFile('src/scripts.ts', '');
|
||||
|
||||
// update angular-cli.json
|
||||
const angularCLIJson = readJson('angular.json');
|
||||
angularCLIJson.projects[proj].architect.build.options.scripts =
|
||||
angularCLIJson.projects[proj].architect.test.options.scripts = [
|
||||
'src/scripts.ts',
|
||||
];
|
||||
angularCLIJson.projects[proj].architect.test.options.styles = [
|
||||
'src/styles.css',
|
||||
];
|
||||
updateFile('angular.json', JSON.stringify(angularCLIJson, null, 2));
|
||||
|
||||
// run the command
|
||||
runNgAdd('--npm-scope projscope');
|
||||
|
||||
// check that prettier config exits and that files have been moved!
|
||||
checkFilesExist(
|
||||
'.vscode/extensions.json',
|
||||
'.prettierrc',
|
||||
`apps/${proj}/src/main.ts`,
|
||||
`apps/${proj}/src/app/app.module.ts`
|
||||
);
|
||||
|
||||
expect(readJson('.vscode/extensions.json').recommendations).toEqual([
|
||||
'nrwl.angular-console',
|
||||
'angular.ng-template',
|
||||
'dbaeumer.vscode-eslint',
|
||||
'esbenp.prettier-vscode',
|
||||
]);
|
||||
|
||||
// check that package.json got merged
|
||||
const updatedPackageJson = readJson('package.json');
|
||||
expect(updatedPackageJson.description).toEqual('some description');
|
||||
expect(updatedPackageJson.scripts).toEqual({
|
||||
ng: 'nx',
|
||||
nx: 'nx',
|
||||
start: 'ng serve',
|
||||
build: 'ng build',
|
||||
test: 'ng test',
|
||||
lint: 'nx workspace-lint && ng lint',
|
||||
e2e: 'ng e2e',
|
||||
'affected:apps': 'nx affected:apps',
|
||||
'affected:libs': 'nx affected:libs',
|
||||
'affected:build': 'nx affected:build',
|
||||
'affected:e2e': 'nx affected:e2e',
|
||||
'affected:test': 'nx affected:test',
|
||||
'affected:lint': 'nx affected:lint',
|
||||
'affected:dep-graph': 'nx affected:dep-graph',
|
||||
affected: 'nx affected',
|
||||
format: 'nx format:write',
|
||||
'format:write': 'nx format:write',
|
||||
'format:check': 'nx format:check',
|
||||
update: 'ng update @nrwl/workspace',
|
||||
'update:check': 'ng update',
|
||||
postinstall: 'node ./decorate-angular-cli.js',
|
||||
'dep-graph': 'nx dep-graph',
|
||||
'workspace-generator': 'nx workspace-generator',
|
||||
help: 'nx help',
|
||||
});
|
||||
expect(updatedPackageJson.devDependencies['@nrwl/workspace']).toBeDefined();
|
||||
expect(updatedPackageJson.devDependencies['@angular/cli']).toBeDefined();
|
||||
|
||||
const nxJson = readJson('nx.json');
|
||||
expect(nxJson).toEqual({
|
||||
npmScope: 'projscope',
|
||||
implicitDependencies: {
|
||||
'angular.json': '*',
|
||||
'package.json': '*',
|
||||
'tslint.json': '*',
|
||||
'.eslintrc.json': '*',
|
||||
'tsconfig.base.json': '*',
|
||||
'nx.json': '*',
|
||||
},
|
||||
projects: {
|
||||
[`${proj}`]: {
|
||||
tags: [],
|
||||
},
|
||||
[`${proj}-e2e`]: {
|
||||
tags: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// check if angular-cli.json get merged
|
||||
const updatedAngularCLIJson = readJson('angular.json');
|
||||
expect(updatedAngularCLIJson.projects[proj].root).toEqual(`apps/${proj}`);
|
||||
expect(updatedAngularCLIJson.projects[proj].sourceRoot).toEqual(
|
||||
`apps/${proj}/src`
|
||||
);
|
||||
|
||||
expect(updatedAngularCLIJson.projects[proj].architect.build).toEqual({
|
||||
builder: '@angular-devkit/build-angular:browser',
|
||||
options: {
|
||||
aot: true,
|
||||
outputPath: `dist/apps/${proj}`,
|
||||
index: `apps/${proj}/src/index.html`,
|
||||
main: `apps/${proj}/src/main.ts`,
|
||||
polyfills: `apps/${proj}/src/polyfills.ts`,
|
||||
tsConfig: `apps/${proj}/tsconfig.app.json`,
|
||||
assets: [`apps/${proj}/src/favicon.ico`, `apps/${proj}/src/assets`],
|
||||
styles: [`apps/${proj}/src/styles.css`],
|
||||
scripts: [`apps/${proj}/src/scripts.ts`],
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
fileReplacements: [
|
||||
{
|
||||
replace: `apps/${proj}/src/environments/environment.ts`,
|
||||
with: `apps/${proj}/src/environments/environment.prod.ts`,
|
||||
},
|
||||
],
|
||||
budgets: [
|
||||
{
|
||||
maximumError: '5mb',
|
||||
maximumWarning: '2mb',
|
||||
type: 'initial',
|
||||
},
|
||||
{
|
||||
maximumError: '10kb',
|
||||
maximumWarning: '6kb',
|
||||
type: 'anyComponentStyle',
|
||||
},
|
||||
],
|
||||
optimization: true,
|
||||
outputHashing: 'all',
|
||||
sourceMap: false,
|
||||
extractCss: true,
|
||||
namedChunks: false,
|
||||
extractLicenses: true,
|
||||
vendorChunk: false,
|
||||
buildOptimizer: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(updatedAngularCLIJson.projects[proj].architect.serve).toEqual({
|
||||
builder: '@angular-devkit/build-angular:dev-server',
|
||||
options: {
|
||||
browserTarget: 'proj:build',
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
browserTarget: 'proj:build:production',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects[proj].architect.test).toEqual({
|
||||
builder: '@angular-devkit/build-angular:karma',
|
||||
options: {
|
||||
main: `apps/${proj}/src/test.ts`,
|
||||
polyfills: `apps/${proj}/src/polyfills.ts`,
|
||||
tsConfig: `apps/${proj}/tsconfig.spec.json`,
|
||||
karmaConfig: `apps/${proj}/karma.conf.js`,
|
||||
styles: [`apps/${proj}/src/styles.css`],
|
||||
scripts: [`apps/${proj}/src/scripts.ts`],
|
||||
assets: [`apps/${proj}/src/favicon.ico`, `apps/${proj}/src/assets`],
|
||||
},
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects[proj].architect.lint).toEqual({
|
||||
builder: '@angular-devkit/build-angular:tslint',
|
||||
options: {
|
||||
tsConfig: [
|
||||
`apps/${proj}/tsconfig.app.json`,
|
||||
`apps/${proj}/tsconfig.spec.json`,
|
||||
],
|
||||
exclude: ['**/node_modules/**'],
|
||||
},
|
||||
});
|
||||
|
||||
expect(updatedAngularCLIJson.projects[`${proj}-e2e`].root).toEqual(
|
||||
`apps/${proj}-e2e`
|
||||
);
|
||||
expect(updatedAngularCLIJson.projects[`${proj}-e2e`].architect.e2e).toEqual(
|
||||
{
|
||||
builder: '@angular-devkit/build-angular:protractor',
|
||||
configurations: {
|
||||
production: {
|
||||
devServerTarget: `${proj}:serve:production`,
|
||||
},
|
||||
},
|
||||
options: {
|
||||
protractorConfig: `apps/${proj}-e2e/protractor.conf.js`,
|
||||
devServerTarget: `${proj}:serve`,
|
||||
},
|
||||
}
|
||||
);
|
||||
expect(
|
||||
updatedAngularCLIJson.projects[`${proj}-e2e`].architect.lint
|
||||
).toEqual({
|
||||
builder: '@angular-devkit/build-angular:tslint',
|
||||
options: {
|
||||
tsConfig: `apps/${proj}-e2e/tsconfig.json`,
|
||||
exclude: ['**/node_modules/**'],
|
||||
},
|
||||
});
|
||||
|
||||
const updatedTslint = readJson('tslint.json');
|
||||
expect(updatedTslint.rules['nx-enforce-module-boundaries']).toEqual([
|
||||
true,
|
||||
{
|
||||
allow: [],
|
||||
depConstraints: [{ sourceTag: '*', onlyDependOnLibsWithTags: ['*'] }],
|
||||
},
|
||||
]);
|
||||
|
||||
runCLI('build --prod --outputHashing none');
|
||||
checkFilesExist(`dist/apps/${proj}/main-es2015.js`);
|
||||
});
|
||||
|
||||
it('should generate a workspace and not change dependencies, devDependencies, or vscode extensions if they already exist', () => {
|
||||
// create a new AngularCLI app
|
||||
proj = uniq('proj');
|
||||
runNgNew(proj);
|
||||
const schematicsVersion = '12.0.0';
|
||||
const ngrxVersion = '12.0.0';
|
||||
// update package.json
|
||||
const existingPackageJson = readJson('package.json');
|
||||
existingPackageJson.devDependencies['@nrwl/workspace'] = schematicsVersion;
|
||||
existingPackageJson.dependencies['@ngrx/store'] = ngrxVersion;
|
||||
existingPackageJson.dependencies['@ngrx/effects'] = ngrxVersion;
|
||||
existingPackageJson.dependencies['@ngrx/router-store'] = ngrxVersion;
|
||||
existingPackageJson.devDependencies['@ngrx/store-devtools'] = ngrxVersion;
|
||||
updateFile('package.json', JSON.stringify(existingPackageJson, null, 2));
|
||||
|
||||
updateFile(
|
||||
'.vscode/extensions.json',
|
||||
JSON.stringify({
|
||||
recommendations: ['eamodio.gitlens', 'angular.ng-template'],
|
||||
})
|
||||
);
|
||||
// run the command
|
||||
runNgAdd('--npm-scope projscope --skip-install');
|
||||
|
||||
// check that dependencies and devDependencies remained the same
|
||||
const packageJson = readJson('package.json');
|
||||
expect(packageJson.devDependencies['@nrwl/workspace']).toEqual(
|
||||
schematicsVersion
|
||||
);
|
||||
expect(packageJson.dependencies['@ngrx/store']).toEqual(ngrxVersion);
|
||||
expect(packageJson.dependencies['@ngrx/effects']).toEqual(ngrxVersion);
|
||||
expect(packageJson.dependencies['@ngrx/router-store']).toEqual(ngrxVersion);
|
||||
expect(packageJson.devDependencies['@ngrx/store-devtools']).toEqual(
|
||||
ngrxVersion
|
||||
);
|
||||
|
||||
expect(readJson('.vscode/extensions.json').recommendations).toEqual([
|
||||
'eamodio.gitlens',
|
||||
'angular.ng-template',
|
||||
'nrwl.angular-console',
|
||||
'dbaeumer.vscode-eslint',
|
||||
'esbenp.prettier-vscode',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should handle different types of errors', () => {
|
||||
// create a new AngularCLI app
|
||||
proj = uniq('proj');
|
||||
runNgNew(proj);
|
||||
|
||||
// Only remove e2e directory
|
||||
runCommand('mv e2e e2e-bak');
|
||||
try {
|
||||
runNgAdd('--npm-scope projscope --skip-install');
|
||||
fail('Did not handle not having a e2e directory');
|
||||
} catch (e) {
|
||||
expect(e.stderr.toString()).toContain(
|
||||
'Your workspace could not be converted into an Nx Workspace because of the above error.'
|
||||
);
|
||||
}
|
||||
|
||||
// Put e2e back
|
||||
runCommand('mv e2e-bak e2e');
|
||||
|
||||
// Remove package.json
|
||||
runCommand('mv package.json package.json.bak');
|
||||
try {
|
||||
runNgAdd('--npm-scope projscope --skip-install');
|
||||
fail('Did not handle not having a package.json');
|
||||
} catch (e) {
|
||||
expect(e.stderr.toString()).toContain(
|
||||
'Your workspace could not be converted into an Nx Workspace because of the above error.'
|
||||
);
|
||||
}
|
||||
|
||||
// Put package.json back
|
||||
runCommand('mv package.json.bak package.json');
|
||||
|
||||
// Remove src
|
||||
runCommand('mv src src-bak');
|
||||
try {
|
||||
runNgAdd('--npm-scope projscope --skip-install');
|
||||
fail('Did not handle not having a src directory');
|
||||
} catch (e) {
|
||||
expect(e.stderr.toString()).toContain('Path: src does not exist');
|
||||
}
|
||||
|
||||
// Put src back
|
||||
runCommand('mv src-bak src');
|
||||
});
|
||||
|
||||
it('should support preserveAngularCLILayout', () => {
|
||||
proj = uniq('proj');
|
||||
runNgNew(proj);
|
||||
runNgAdd('--preserveAngularCLILayout');
|
||||
|
||||
const updatedAngularCLIJson = readJson('angular.json');
|
||||
expect(updatedAngularCLIJson.projects[proj].root).toEqual('');
|
||||
expect(updatedAngularCLIJson.projects[proj].sourceRoot).toEqual('src');
|
||||
|
||||
const output = runCLI('build');
|
||||
expect(output).toContain(`> ng run ${proj}:build`);
|
||||
});
|
||||
});
|
||||
@ -1,71 +0,0 @@
|
||||
import {
|
||||
expectTestsPass,
|
||||
newProject,
|
||||
readJson,
|
||||
removeProject,
|
||||
runCLI,
|
||||
runCLIAsync,
|
||||
uniq,
|
||||
} from '@nrwl/e2e/utils';
|
||||
|
||||
// TODO: Uncomment when the node is migrated to webpack 5
|
||||
xdescribe('ngrx', () => {
|
||||
beforeEach(() => newProject());
|
||||
afterAll(() => removeProject({ onlyOnCI: true }));
|
||||
|
||||
it('should work', async () => {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --no-interactive`);
|
||||
|
||||
// Generate root ngrx state management
|
||||
runCLI(
|
||||
`generate @nrwl/angular:ngrx users --module=apps/${myapp}/src/app/app.module.ts --root --minimal=false --syntax=classes --useDataPersistence=true`
|
||||
);
|
||||
const packageJson = readJson('package.json');
|
||||
expect(packageJson.dependencies['@ngrx/store']).toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/effects']).toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/router-store']).toBeDefined();
|
||||
expect(packageJson.devDependencies['@ngrx/store-devtools']).toBeDefined();
|
||||
|
||||
const mylib = uniq('mylib');
|
||||
// Generate feature library and ngrx state within that library
|
||||
runCLI(`g @nrwl/angular:lib ${mylib} --prefix=fl`);
|
||||
runCLI(
|
||||
`generate @nrwl/angular:ngrx flights --module=libs/${mylib}/src/lib/${mylib}.module.ts --facade --syntax=classes`
|
||||
);
|
||||
|
||||
expect(runCLI(`build ${myapp}`)).toMatch(/main\.[a-z0-9]+\.js/);
|
||||
expectTestsPass(await runCLIAsync(`test ${myapp} --no-watch`));
|
||||
expectTestsPass(await runCLIAsync(`test ${mylib} --no-watch`));
|
||||
}, 1000000);
|
||||
|
||||
it('should work with creators', async () => {
|
||||
const myapp = uniq('myapp');
|
||||
runCLI(`generate @nrwl/angular:app ${myapp} --routing --no-interactive`);
|
||||
|
||||
// Generate root ngrx state management
|
||||
runCLI(
|
||||
`generate @nrwl/angular:ngrx users --module=apps/${myapp}/src/app/app.module.ts --root`
|
||||
);
|
||||
const packageJson = readJson('package.json');
|
||||
expect(packageJson.dependencies['@ngrx/entity']).toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/store']).toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/effects']).toBeDefined();
|
||||
expect(packageJson.dependencies['@ngrx/router-store']).toBeDefined();
|
||||
expect(packageJson.devDependencies['@ngrx/schematics']).toBeDefined();
|
||||
expect(packageJson.devDependencies['@ngrx/store-devtools']).toBeDefined();
|
||||
|
||||
const mylib = uniq('mylib');
|
||||
// Generate feature library and ngrx state within that library
|
||||
runCLI(`g @nrwl/angular:lib ${mylib} --prefix=fl`);
|
||||
|
||||
const flags = `--facade --barrels`;
|
||||
runCLI(
|
||||
`generate @nrwl/angular:ngrx flights --module=libs/${mylib}/src/lib/${mylib}.module.ts ${flags}`
|
||||
);
|
||||
|
||||
expect(runCLI(`build ${myapp}`)).toMatch(/main\.[a-z0-9]+\.js/);
|
||||
expectTestsPass(await runCLIAsync(`test ${myapp} --no-watch`));
|
||||
expectTestsPass(await runCLIAsync(`test ${mylib} --no-watch`));
|
||||
}, 1000000);
|
||||
});
|
||||
@ -20,7 +20,8 @@
|
||||
"dep-graph-dep-graph-e2e": "dep-graph/dep-graph-e2e",
|
||||
"devkit": "packages/devkit",
|
||||
"docs": "docs",
|
||||
"e2e-angular": "e2e/angular",
|
||||
"e2e-angular-core": "e2e/angular-core",
|
||||
"e2e-angular-extensions": "e2e/angular-extensions",
|
||||
"e2e-cli": "e2e/cli",
|
||||
"e2e-cypress": "e2e/cypress",
|
||||
"e2e-gatsby": "e2e/gatsby",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user