* feat(angular): add an option to add strict type checking Adding support for strict type checking to Angular application and library generate schematics. E.g. `nx generate application myapp --strict` `nx generate lib mylib --strict` Closes #3383. Performs the following configuration changes: - Enables strict mode in TypeScript, as well as other strictness flags recommended by the TypeScript team. Specifically, forceConsistentCasingInFileNames, noImplicitReturns, noFallthroughCasesInSwitch. - Turns on strict Angular compiler flags strictTemplates and strictInjectionParameters These match the flags used in the standard CLI strict mode. * cleanup(misc): updating import path Co-authored-by: Ashley Hunter <ashley.hunter@hotmail.co.uk>
599 lines
20 KiB
TypeScript
599 lines
20 KiB
TypeScript
import { Tree } from '@angular-devkit/schematics';
|
|
import { createEmptyWorkspace, getFileContent } from '@nrwl/workspace/testing';
|
|
import * as stripJsonComments from 'strip-json-comments';
|
|
import { readJsonInTree, updateJsonInTree, NxJson } from '@nrwl/workspace';
|
|
import { runSchematic, callRule } from '../../utils/testing';
|
|
|
|
describe('app', () => {
|
|
let appTree: Tree;
|
|
|
|
beforeEach(() => {
|
|
appTree = Tree.empty();
|
|
appTree = createEmptyWorkspace(appTree);
|
|
});
|
|
|
|
describe('not nested', () => {
|
|
it('should update workspace.json', async () => {
|
|
const tree = await runSchematic('app', { name: 'myApp' }, appTree);
|
|
const workspaceJson = readJsonInTree(tree, '/workspace.json');
|
|
|
|
expect(workspaceJson.projects['my-app'].root).toEqual('apps/my-app');
|
|
expect(workspaceJson.projects['my-app-e2e'].root).toEqual(
|
|
'apps/my-app-e2e'
|
|
);
|
|
|
|
expect(
|
|
workspaceJson.projects['my-app'].architect.lint.options.exclude
|
|
).toEqual(['**/node_modules/**', '!apps/my-app/**/*']);
|
|
expect(
|
|
workspaceJson.projects['my-app-e2e'].architect.lint.options.exclude
|
|
).toEqual(['**/node_modules/**', '!apps/my-app-e2e/**/*']);
|
|
});
|
|
|
|
it('should remove the e2e target on the application', async () => {
|
|
const tree = await runSchematic('app', { name: 'myApp' }, appTree);
|
|
const workspaceJson = readJsonInTree(tree, '/workspace.json');
|
|
expect(workspaceJson.projects['my-app'].architect.e2e).not.toBeDefined();
|
|
});
|
|
|
|
it('should update nx.json', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', tags: 'one,two' },
|
|
appTree
|
|
);
|
|
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
|
expect(nxJson.projects).toEqual({
|
|
'my-app': {
|
|
tags: ['one', 'two'],
|
|
},
|
|
'my-app-e2e': {
|
|
implicitDependencies: ['my-app'],
|
|
tags: [],
|
|
},
|
|
});
|
|
});
|
|
|
|
it('should generate files', async () => {
|
|
const tree = await runSchematic('app', { name: 'myApp' }, appTree);
|
|
expect(tree.exists(`apps/my-app/jest.config.js`)).toBeTruthy();
|
|
expect(tree.exists('apps/my-app/src/main.ts')).toBeTruthy();
|
|
expect(tree.exists('apps/my-app/src/app/app.module.ts')).toBeTruthy();
|
|
expect(tree.exists('apps/my-app/src/app/app.component.ts')).toBeTruthy();
|
|
expect(
|
|
getFileContent(tree, 'apps/my-app/src/app/app.module.ts')
|
|
).toContain('class AppModule');
|
|
|
|
const tsconfig = readJsonInTree(tree, 'apps/my-app/tsconfig.json');
|
|
expect(tsconfig.references).toContainEqual({
|
|
path: './tsconfig.app.json',
|
|
});
|
|
expect(tsconfig.references).toContainEqual({
|
|
path: './tsconfig.spec.json',
|
|
});
|
|
|
|
const tsconfigApp = JSON.parse(
|
|
stripJsonComments(getFileContent(tree, 'apps/my-app/tsconfig.app.json'))
|
|
);
|
|
expect(tsconfigApp.compilerOptions.outDir).toEqual('../../dist/out-tsc');
|
|
expect(tsconfigApp.extends).toEqual('./tsconfig.json');
|
|
|
|
const tslintJson = JSON.parse(
|
|
stripJsonComments(getFileContent(tree, 'apps/my-app/tslint.json'))
|
|
);
|
|
expect(tslintJson.extends).toEqual('../../tslint.json');
|
|
|
|
expect(tree.exists('apps/my-app-e2e/cypress.json')).toBeTruthy();
|
|
const tsconfigE2E = JSON.parse(
|
|
stripJsonComments(
|
|
getFileContent(tree, 'apps/my-app-e2e/tsconfig.e2e.json')
|
|
)
|
|
);
|
|
expect(tsconfigE2E.extends).toEqual('./tsconfig.json');
|
|
});
|
|
|
|
it('should setup jest with serializers', async () => {
|
|
const tree = await runSchematic('app', { name: 'myApp' }, appTree);
|
|
|
|
expect(tree.readContent('apps/my-app/jest.config.js')).toContain(
|
|
`'jest-preset-angular/build/AngularSnapshotSerializer.js'`
|
|
);
|
|
expect(tree.readContent('apps/my-app/jest.config.js')).toContain(
|
|
`'jest-preset-angular/build/HTMLCommentSerializer.js'`
|
|
);
|
|
});
|
|
|
|
it('should default the prefix to npmScope', async () => {
|
|
const noPrefix = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', e2eTestRunner: 'protractor' },
|
|
appTree
|
|
);
|
|
const withPrefix = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', prefix: 'custom', e2eTestRunner: 'protractor' },
|
|
appTree
|
|
);
|
|
|
|
// Testing without prefix
|
|
|
|
let appE2eSpec = noPrefix
|
|
.read('apps/my-app-e2e/src/app.e2e-spec.ts')
|
|
.toString();
|
|
let workspaceJson = JSON.parse(
|
|
noPrefix.read('workspace.json').toString()
|
|
);
|
|
let myAppPrefix = workspaceJson.projects['my-app'].prefix;
|
|
|
|
expect(myAppPrefix).toEqual('proj');
|
|
expect(appE2eSpec).toContain('Welcome to my-app!');
|
|
|
|
// Testing WITH prefix
|
|
|
|
appE2eSpec = withPrefix
|
|
.read('apps/my-app-e2e/src/app.e2e-spec.ts')
|
|
.toString();
|
|
workspaceJson = JSON.parse(withPrefix.read('workspace.json').toString());
|
|
myAppPrefix = workspaceJson.projects['my-app'].prefix;
|
|
|
|
expect(myAppPrefix).toEqual('custom');
|
|
expect(appE2eSpec).toContain('Welcome to my-app!');
|
|
});
|
|
|
|
xit('should work if the new project root is changed', async () => {
|
|
appTree = await callRule(
|
|
updateJsonInTree('/workspace.json', (json) => ({
|
|
...json,
|
|
newProjectRoot: 'newProjectRoot',
|
|
})),
|
|
appTree
|
|
);
|
|
|
|
const result = await runSchematic('app', { name: 'myApp' }, appTree);
|
|
expect(result.exists('apps/my-app/src/main.ts')).toEqual(true);
|
|
expect(result.exists('apps/my-app-e2e/protractor.conf.js')).toEqual(true);
|
|
});
|
|
|
|
it('should set projectType to application', async () => {
|
|
const tree = await runSchematic('app', { name: 'app' }, appTree);
|
|
const workspaceJson = readJsonInTree(tree, '/workspace.json');
|
|
expect(workspaceJson.projects['app'].projectType).toEqual('application');
|
|
});
|
|
});
|
|
|
|
describe('nested', () => {
|
|
it('should update workspace.json', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', directory: 'myDir' },
|
|
appTree
|
|
);
|
|
const workspaceJson = readJsonInTree(tree, '/workspace.json');
|
|
|
|
expect(workspaceJson.projects['my-dir-my-app'].root).toEqual(
|
|
'apps/my-dir/my-app'
|
|
);
|
|
expect(workspaceJson.projects['my-dir-my-app-e2e'].root).toEqual(
|
|
'apps/my-dir/my-app-e2e'
|
|
);
|
|
|
|
expect(
|
|
workspaceJson.projects['my-dir-my-app'].architect.lint.options.exclude
|
|
).toEqual(['**/node_modules/**', '!apps/my-dir/my-app/**/*']);
|
|
expect(
|
|
workspaceJson.projects['my-dir-my-app-e2e'].architect.lint.options
|
|
.exclude
|
|
).toEqual(['**/node_modules/**', '!apps/my-dir/my-app-e2e/**/*']);
|
|
});
|
|
|
|
it('should update nx.json', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', directory: 'myDir', tags: 'one,two' },
|
|
appTree
|
|
);
|
|
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
|
expect(nxJson.projects).toEqual({
|
|
'my-dir-my-app': {
|
|
tags: ['one', 'two'],
|
|
},
|
|
'my-dir-my-app-e2e': {
|
|
implicitDependencies: ['my-dir-my-app'],
|
|
tags: [],
|
|
},
|
|
});
|
|
});
|
|
|
|
it('should generate files', async () => {
|
|
const hasJsonValue = ({ path, expectedValue, lookupFn }) => {
|
|
const content = getFileContent(tree, path);
|
|
const config = JSON.parse(stripJsonComments(content));
|
|
|
|
expect(lookupFn(config)).toEqual(expectedValue);
|
|
};
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', directory: 'myDir' },
|
|
appTree
|
|
);
|
|
|
|
const appModulePath = 'apps/my-dir/my-app/src/app/app.module.ts';
|
|
expect(getFileContent(tree, appModulePath)).toContain('class AppModule');
|
|
|
|
// Make sure these exist
|
|
[
|
|
`apps/my-dir/my-app/jest.config.js`,
|
|
'apps/my-dir/my-app/src/main.ts',
|
|
'apps/my-dir/my-app/src/app/app.module.ts',
|
|
'apps/my-dir/my-app/src/app/app.component.ts',
|
|
'apps/my-dir/my-app-e2e/cypress.json',
|
|
].forEach((path) => {
|
|
expect(tree.exists(path)).toBeTruthy();
|
|
});
|
|
|
|
// Make sure these have properties
|
|
[
|
|
{
|
|
path: 'apps/my-dir/my-app/tsconfig.app.json',
|
|
lookupFn: (json) => json.compilerOptions.outDir,
|
|
expectedValue: '../../../dist/out-tsc',
|
|
},
|
|
{
|
|
path: 'apps/my-dir/my-app/tslint.json',
|
|
lookupFn: (json) => json.extends,
|
|
expectedValue: '../../../tslint.json',
|
|
},
|
|
].forEach(hasJsonValue);
|
|
});
|
|
});
|
|
|
|
describe('routing', () => {
|
|
it('should include RouterTestingModule', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', directory: 'myDir', routing: true },
|
|
appTree
|
|
);
|
|
expect(
|
|
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.module.ts')
|
|
).toContain('RouterModule.forRoot');
|
|
expect(
|
|
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.spec.ts')
|
|
).toContain('imports: [RouterTestingModule]');
|
|
});
|
|
|
|
it('should not modify tests when --skip-tests is set', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', directory: 'myDir', routing: true, skipTests: true },
|
|
appTree
|
|
);
|
|
expect(
|
|
tree.exists('apps/my-dir/my-app/src/app/app.component.spec.ts')
|
|
).toBeFalsy();
|
|
});
|
|
});
|
|
|
|
describe('template generation mode', () => {
|
|
it('should create Nx specific `app.component.html` template', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', directory: 'myDir' },
|
|
appTree
|
|
);
|
|
expect(
|
|
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.html')
|
|
).toBeTruthy();
|
|
expect(
|
|
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.html')
|
|
).toContain('Thank you for using and showing some ♥ for Nx.');
|
|
});
|
|
|
|
it("should update `template`'s property of AppComponent with Nx content", async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', directory: 'myDir', inlineTemplate: true },
|
|
appTree
|
|
);
|
|
expect(
|
|
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.ts')
|
|
).toContain('Thank you for using and showing some ♥ for Nx.');
|
|
});
|
|
|
|
it('should update the AppComponent spec to target Nx content', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', directory: 'myDir', inlineTemplate: true },
|
|
appTree
|
|
);
|
|
const testFileContent = getFileContent(
|
|
tree,
|
|
'apps/my-dir/my-app/src/app/app.component.spec.ts'
|
|
);
|
|
|
|
expect(testFileContent).toContain(`querySelector('h1')`);
|
|
expect(testFileContent).toContain('Welcome to my-dir-my-app!');
|
|
});
|
|
});
|
|
|
|
describe('--style scss', () => {
|
|
it('should generate scss styles', async () => {
|
|
const result = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', style: 'scss' },
|
|
appTree
|
|
);
|
|
expect(result.exists('apps/my-app/src/app/app.component.scss')).toEqual(
|
|
true
|
|
);
|
|
});
|
|
|
|
it('should set it as default', async () => {
|
|
const result = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', style: 'scss' },
|
|
appTree
|
|
);
|
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
|
|
|
expect(workspaceJson.projects['my-app'].schematics).toEqual({
|
|
'@nrwl/angular:component': {
|
|
style: 'scss',
|
|
},
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('--unit-test-runner', () => {
|
|
describe('default (jest)', () => {
|
|
it('should generate jest.config.js with serializers', async () => {
|
|
const tree = await runSchematic('app', { name: 'myApp' }, appTree);
|
|
|
|
expect(tree.readContent('apps/my-app/jest.config.js')).toContain(
|
|
`'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js'`
|
|
);
|
|
expect(tree.readContent('apps/my-app/jest.config.js')).toContain(
|
|
`'jest-preset-angular/build/AngularSnapshotSerializer.js'`
|
|
);
|
|
expect(tree.readContent('apps/my-app/jest.config.js')).toContain(
|
|
`'jest-preset-angular/build/HTMLCommentSerializer.js'`
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('karma', () => {
|
|
it('should generate a karma config', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', unitTestRunner: 'karma' },
|
|
appTree
|
|
);
|
|
|
|
expect(tree.exists('apps/my-app/tsconfig.spec.json')).toBeTruthy();
|
|
expect(tree.exists('apps/my-app/karma.conf.js')).toBeTruthy();
|
|
const workspaceJson = readJsonInTree(tree, 'workspace.json');
|
|
expect(workspaceJson.projects['my-app'].architect.test.builder).toEqual(
|
|
'@angular-devkit/build-angular:karma'
|
|
);
|
|
expect(
|
|
workspaceJson.projects['my-app'].architect.lint.options.tsConfig
|
|
).toEqual([
|
|
'apps/my-app/tsconfig.app.json',
|
|
'apps/my-app/tsconfig.spec.json',
|
|
]);
|
|
const tsconfigAppJson = readJsonInTree(
|
|
tree,
|
|
'apps/my-app/tsconfig.app.json'
|
|
);
|
|
expect(tsconfigAppJson.compilerOptions.outDir).toEqual(
|
|
'../../dist/out-tsc'
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('none', () => {
|
|
it('should not generate test configuration', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', unitTestRunner: 'none' },
|
|
appTree
|
|
);
|
|
expect(tree.exists('apps/my-app/src/test-setup.ts')).toBeFalsy();
|
|
expect(tree.exists('apps/my-app/src/test.ts')).toBeFalsy();
|
|
expect(tree.exists('apps/my-app/tsconfig.spec.json')).toBeFalsy();
|
|
expect(tree.exists('apps/my-app/jest.config.js')).toBeFalsy();
|
|
expect(tree.exists('apps/my-app/karma.config.js')).toBeFalsy();
|
|
const workspaceJson = readJsonInTree(tree, 'workspace.json');
|
|
expect(workspaceJson.projects['my-app'].architect.test).toBeUndefined();
|
|
expect(
|
|
workspaceJson.projects['my-app'].architect.lint.options.tsConfig
|
|
).toEqual(['apps/my-app/tsconfig.app.json']);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('--e2e-test-runner', () => {
|
|
describe('protractor', () => {
|
|
it('should update workspace.json', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', e2eTestRunner: 'protractor' },
|
|
appTree
|
|
);
|
|
expect(tree.exists('apps/my-app-e2e')).toBeFalsy();
|
|
const workspaceJson = readJsonInTree(tree, 'workspace.json');
|
|
expect(
|
|
workspaceJson.projects['my-app'].architect.e2e
|
|
).not.toBeDefined();
|
|
expect(workspaceJson.projects['my-app-e2e']).toEqual({
|
|
root: 'apps/my-app-e2e',
|
|
projectType: 'application',
|
|
architect: {
|
|
e2e: {
|
|
builder: '@angular-devkit/build-angular:protractor',
|
|
options: {
|
|
devServerTarget: 'my-app:serve',
|
|
protractorConfig: 'apps/my-app-e2e/protractor.conf.js',
|
|
},
|
|
configurations: {
|
|
production: {
|
|
devServerTarget: 'my-app:serve:production',
|
|
},
|
|
},
|
|
},
|
|
lint: {
|
|
builder: '@angular-devkit/build-angular:tslint',
|
|
options: {
|
|
tsConfig: 'apps/my-app-e2e/tsconfig.e2e.json',
|
|
exclude: ['**/node_modules/**', '!apps/my-app-e2e/**/*'],
|
|
},
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
it('should update E2E spec files to match the app name', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', e2eTestRunner: 'protractor' },
|
|
appTree
|
|
);
|
|
|
|
expect(
|
|
tree.readContent('apps/my-app-e2e/src/app.e2e-spec.ts')
|
|
).toContain(`'Welcome to my-app!'`);
|
|
expect(tree.readContent('apps/my-app-e2e/src/app.po.ts')).toContain(
|
|
`'proj-root header h1'`
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('none', () => {
|
|
it('should not generate test configuration', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'myApp', e2eTestRunner: 'none' },
|
|
appTree
|
|
);
|
|
expect(tree.exists('apps/my-app-e2e')).toBeFalsy();
|
|
const workspaceJson = readJsonInTree(tree, 'workspace.json');
|
|
expect(workspaceJson.projects['my-app-e2e']).toBeUndefined();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('replaceAppNameWithPath', () => {
|
|
it('should protect `workspace.json` commands and properties', async () => {
|
|
const tree = await runSchematic('app', { name: 'ui' }, appTree);
|
|
const workspaceJson = readJsonInTree(tree, 'workspace.json');
|
|
expect(workspaceJson.projects['ui']).toBeDefined();
|
|
expect(
|
|
workspaceJson.projects['ui']['architect']['build']['builder']
|
|
).toEqual('@angular-devkit/build-angular:browser');
|
|
});
|
|
|
|
it('should protect `workspace.json` sensible properties value to be renamed', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'ui', prefix: 'ui' },
|
|
appTree
|
|
);
|
|
const workspaceJson = readJsonInTree(tree, 'workspace.json');
|
|
expect(workspaceJson.projects['ui'].prefix).toEqual('ui');
|
|
});
|
|
});
|
|
|
|
describe('--backend-project', () => {
|
|
describe('with a backend project', () => {
|
|
it('should add a proxy.conf.json to app', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'customer-ui', backendProject: 'customer-api' },
|
|
appTree
|
|
);
|
|
|
|
const proxyConfContent = JSON.stringify(
|
|
{
|
|
'/customer-api': {
|
|
target: 'http://localhost:3333',
|
|
secure: false,
|
|
},
|
|
},
|
|
null,
|
|
2
|
|
);
|
|
|
|
expect(tree.exists('apps/customer-ui/proxy.conf.json')).toBeTruthy();
|
|
expect(tree.readContent('apps/customer-ui/proxy.conf.json')).toContain(
|
|
proxyConfContent
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('with no backend project', () => {
|
|
it('should not generate a proxy.conf.json', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'customer-ui' },
|
|
appTree
|
|
);
|
|
|
|
expect(tree.exists('apps/customer-ui/proxy.conf.json')).toBeFalsy();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('--enable-ivy', () => {
|
|
it('should not exclude files in the tsconfig.app.json', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'my-app', enableIvy: true },
|
|
appTree
|
|
);
|
|
|
|
expect(tree.readContent('apps/my-app/tsconfig.app.json')).not.toContain(
|
|
'exclude'
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('--strict', () => {
|
|
it('should enable strict type checking', async () => {
|
|
const tree = await runSchematic(
|
|
'app',
|
|
{ name: 'my-app', strict: true },
|
|
appTree
|
|
);
|
|
|
|
// define all the tsconfig files to update
|
|
const configFiles = [
|
|
'apps/my-app/tsconfig.json',
|
|
'apps/my-app-e2e/tsconfig.e2e.json',
|
|
];
|
|
|
|
for (const configFile of configFiles) {
|
|
const { compilerOptions, angularCompilerOptions } = JSON.parse(
|
|
tree.readContent(configFile)
|
|
);
|
|
|
|
// check that the TypeScript compiler options have been updated
|
|
expect(compilerOptions.forceConsistentCasingInFileNames).toBe(true);
|
|
expect(compilerOptions.strict).toBe(true);
|
|
expect(compilerOptions.noImplicitReturns).toBe(true);
|
|
expect(compilerOptions.noFallthroughCasesInSwitch).toBe(true);
|
|
|
|
// check that the Angular Template options have been updated
|
|
expect(angularCompilerOptions.strictInjectionParameters).toBe(true);
|
|
expect(angularCompilerOptions.strictTemplates).toBe(true);
|
|
}
|
|
|
|
// check to see if the workspace configuration has been updated to use strict
|
|
// mode by default in future applications
|
|
const workspaceJson = readJsonInTree(tree, 'workspace.json');
|
|
expect(workspaceJson.schematics['@nrwl/angular:application'].strict).toBe(
|
|
true
|
|
);
|
|
});
|
|
});
|
|
});
|