angular-cli/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts
Alan Agius 8b96e52d83 fix(@schematics/angular): remove solution style tsconfig from new projects
Following the issues highlighted in https://docs.google.com/document/d/1eB6cGCG_2ircfS5GzpDC9dBgikeYYcMxghVH5sDESHw/edit?usp=sharing and discussions held with the TypeScript team. The best course of action is to rollback this feature.

In future, it is not excluded that solution style tsconfigs are re-introduced..

Closes #18040 and closes #18170
2020-08-12 19:26:12 +01:00

263 lines
9.9 KiB
TypeScript

/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { JsonParseMode, parseJson } from '@angular-devkit/core';
import { EmptyTree } from '@angular-devkit/schematics';
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import { getWorkspaceTargets, updateWorkspaceTargets } from './update-workspace-config_spec';
// tslint:disable-next-line: no-any
function readJsonFile(tree: UnitTestTree, path: string): any {
return parseJson(tree.readContent(path).toString(), JsonParseMode.Loose);
}
function overrideJsonFile(tree: UnitTestTree, path: string, newContent: object) {
tree.overwrite(path, JSON.stringify(newContent, undefined, 2));
}
const defaultTsConfigOptions = {
extends: './tsconfig.json',
compilerOptions: {
module: 'es2015',
outDir: './out-tsc/app',
types: [],
},
exclude: [
'src/test.ts',
'src/**/*.spec.ts',
],
angularCompilerOptions: {
enableIvy: true,
},
};
// tslint:disable:no-big-function
describe('Migration to version 9', () => {
describe('Update applications tsconfig', () => {
const schematicRunner = new SchematicTestRunner(
'migrations',
require.resolve('../migration-collection.json'),
);
let tree: UnitTestTree;
beforeEach(async () => {
tree = new UnitTestTree(new EmptyTree());
tree = await schematicRunner
.runExternalSchematicAsync(
require.resolve('../../collection.json'),
'ng-new',
{
name: 'migration-test',
version: '1.2.3',
directory: '.',
},
tree,
)
.toPromise();
// Pre version 9 - tsconfig.json was the base tsconfig file.
tree.overwrite('tsconfig.json', tree.readContent('tsconfig.json'));
});
it('should update apps tsConfig with stricter files inclusions', async () => {
overrideJsonFile(tree, 'tsconfig.app.json', defaultTsConfigOptions);
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
const { exclude, files, include } = readJsonFile(tree2 , 'tsconfig.app.json');
expect(exclude).toBeUndefined();
expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']);
expect(include).toEqual(['src/**/*.d.ts']);
});
it('should resolve paths correctly even if they are using windows separators', async () => {
const tree2 = await schematicRunner
.runExternalSchematicAsync(
require.resolve('../../collection.json'),
'application',
{
name: 'another-app',
},
tree,
)
.toPromise();
const tsCfgPath = 'projects/another-app/tsconfig.app.json';
overrideJsonFile(tree2, tsCfgPath, defaultTsConfigOptions);
const config = getWorkspaceTargets(tree2, 'another-app');
config.build.options.main = 'projects\\another-app\\src\\main.ts';
config.build.options.polyfills = 'projects\\another-app\\src\\polyfills.ts';
config.build.options.tsConfig = 'projects\\another-app\\tsconfig.app.json';
updateWorkspaceTargets(tree2, config, 'another-app');
const tree3 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree2.branch()).toPromise();
const { exclude, files } = readJsonFile(tree3, tsCfgPath);
expect(exclude).toBeUndefined();
expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']);
});
it('should update apps tsConfig when tsconfig has include', async () => {
const tsConfigContent = {
...defaultTsConfigOptions,
include: ['foo.ts'],
};
overrideJsonFile(tree, 'tsconfig.app.json', tsConfigContent);
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
const { files, include } = readJsonFile(tree2, 'tsconfig.app.json');
expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']);
expect(include).toEqual(['foo.ts']);
});
it(`should update include '**/*.ts' in apps tsConfig to '**/*.d.ts'`, async () => {
const tsConfigContent = {
...defaultTsConfigOptions,
include: ['src/**/*.ts'],
exclude: ['test.ts'],
};
overrideJsonFile(tree, 'tsconfig.app.json', tsConfigContent);
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
const { files, include, exclude } = readJsonFile(tree2, 'tsconfig.app.json');
expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']);
expect(include).toEqual(['src/**/*.d.ts']);
expect(exclude).toBeUndefined();
});
it(`should update include '**/*.ts' in apps tsConfig to '**/*.d.ts' when includes contains multiple elements`, async () => {
const tsConfigContent = {
...defaultTsConfigOptions,
include: ['foo.ts', 'src/**/*.ts'],
};
overrideJsonFile(tree, 'tsconfig.app.json', tsConfigContent);
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
const { files, include, exclude } = readJsonFile(tree2, 'tsconfig.app.json');
expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']);
expect(include).toEqual(['foo.ts', 'src/**/*.d.ts']);
expect(exclude).toBeUndefined();
});
it(`should remove angularCompilerOptions when enableIvy is true and it's the only option`, async () => {
overrideJsonFile(tree, 'tsconfig.app.json', defaultTsConfigOptions);
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
const { angularCompilerOptions } = readJsonFile(tree2, 'tsconfig.app.json');
expect(angularCompilerOptions).toBeUndefined();
});
it('should remove enableIvy only when true and there are other angularCompilerOptions', async () => {
const tsConfigContent = {
...defaultTsConfigOptions,
angularCompilerOptions: {
enableIvy: true,
fullTemplateTypeCheck: true,
},
};
overrideJsonFile(tree, 'tsconfig.app.json', tsConfigContent);
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
const { angularCompilerOptions } = readJsonFile(tree2, 'tsconfig.app.json');
expect(angularCompilerOptions.enableIvy).toBeUndefined();
expect(angularCompilerOptions.fullTemplateTypeCheck).toBe(true);
});
it('should note remove enableIvy is set to false', async () => {
const tsConfigContent = {
...defaultTsConfigOptions,
angularCompilerOptions: {
enableIvy: false,
fullTemplateTypeCheck: true,
},
};
overrideJsonFile(tree, 'tsconfig.app.json', tsConfigContent);
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
const { angularCompilerOptions } = readJsonFile(tree2, 'tsconfig.app.json');
expect(angularCompilerOptions.enableIvy).toBe(false);
expect(angularCompilerOptions.fullTemplateTypeCheck).toBe(true);
});
it(`should remove 'module' if in an extended configuration`, async () => {
const tsConfigContent = {
...defaultTsConfigOptions,
angularCompilerOptions: {
enableIvy: true,
fullTemplateTypeCheck: true,
},
};
overrideJsonFile(tree, 'tsconfig.app.json', tsConfigContent);
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
const { compilerOptions } = readJsonFile(tree2, 'tsconfig.app.json');
expect(compilerOptions.module).toBeUndefined();
const { compilerOptions: workspaceCompilerOptions } = readJsonFile(tree2, 'tsconfig.json');
expect(workspaceCompilerOptions.module).toBe('esnext');
});
it(`should set 'module' to 'esnext' if app tsconfig is not extended`, async () => {
const tsConfigContent = {
...defaultTsConfigOptions,
extends: undefined,
angularCompilerOptions: {
enableIvy: true,
fullTemplateTypeCheck: true,
},
};
overrideJsonFile(tree, 'tsconfig.app.json', tsConfigContent);
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
const { compilerOptions } = readJsonFile(tree2, 'tsconfig.app.json');
expect(compilerOptions.module).toBe('esnext');
});
it(`should set 'module' to 'commonjs' in server tsconfig`, async () => {
const tsConfigContent = {
...defaultTsConfigOptions,
compilerOptions: {
module: 'es2015',
outDir: './out-tsc/server',
},
angularCompilerOptions: {
enableIvy: true,
},
};
tree = await schematicRunner
.runExternalSchematicAsync(
require.resolve('../../collection.json'),
'universal',
{
clientProject: 'migration-test',
},
tree,
)
.toPromise();
overrideJsonFile(tree, 'tsconfig.server.json', tsConfigContent);
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
const { compilerOptions } = readJsonFile(tree2, 'tsconfig.server.json');
expect(compilerOptions.module).toBe('commonjs');
});
it(`should set 'module' to 'esnext' in workspace tsconfig`, async () => {
const tsConfigContent = {
...defaultTsConfigOptions,
extends: undefined,
};
overrideJsonFile(tree, 'tsconfig.json', tsConfigContent);
const tree2 = await schematicRunner.runSchematicAsync('workspace-version-9', {}, tree.branch()).toPromise();
const { compilerOptions } = readJsonFile(tree2, 'tsconfig.json');
expect(compilerOptions.module).toBe('esnext');
});
});
});