130 lines
3.5 KiB
TypeScript

import {
Rule,
Tree,
mergeWith,
chain,
url,
apply,
SchematicContext,
move,
template,
schematic
} from '@angular-devkit/schematics';
import {
readJsonInTree,
updateJsonInTree,
offsetFromRoot
} from '@nrwl/schematics';
import { join, normalize } from '@angular-devkit/core';
import { getProjectConfig } from '@nrwl/schematics/src/utils/ast-utils';
export interface KarmaProjectSchema {
project: string;
}
// TODO: @jjean implement skipSetupFile
function generateFiles(options: KarmaProjectSchema): Rule {
return (host, context) => {
const projectConfig = getProjectConfig(host, options.project);
return mergeWith(
apply(url('./files'), [
template({
tmpl: '',
...options,
projectRoot: projectConfig.root,
isLibrary: projectConfig.projectType === 'library',
offsetFromRoot: offsetFromRoot(projectConfig.root)
}),
move(projectConfig.root)
])
)(host, context);
};
}
function updateTsConfig(options: KarmaProjectSchema): Rule {
return (host: Tree) => {
const projectConfig = getProjectConfig(host, options.project);
return updateJsonInTree(join(projectConfig.root, 'tsconfig.json'), json => {
return {
...json,
compilerOptions: {
...json.compilerOptions,
types: Array.from(
new Set([...(json.compilerOptions.types || []), 'jasmine'])
)
}
};
});
};
}
function updateTsSpecConfig(options: KarmaProjectSchema): Rule {
return (host: Tree) => {
const projectConfig = getProjectConfig(host, options.project);
const extraFiles =
projectConfig.projectType === 'library' ? [] : ['src/polyfills.ts'];
return updateJsonInTree(
join(projectConfig.root, 'tsconfig.spec.json'),
json => {
return {
...json,
files: [...json.files, ...extraFiles]
};
}
);
};
}
function updateAngularJson(options: KarmaProjectSchema): Rule {
return updateJsonInTree('angular.json', json => {
const projectConfig = json.projects[options.project];
projectConfig.architect.test = {
builder: '@angular-devkit/build-angular:karma',
options: {
main: join(normalize(projectConfig.sourceRoot), 'test.ts'),
tsConfig: join(normalize(projectConfig.root), 'tsconfig.spec.json'),
karmaConfig: join(normalize(projectConfig.root), 'karma.conf.js')
}
};
if (projectConfig.projectType === 'application') {
projectConfig.architect.test.options = {
...projectConfig.architect.test.options,
polyfills: join(normalize(projectConfig.sourceRoot), 'polyfills.ts'),
styles: [],
scripts: [],
assets: []
};
}
if (projectConfig.architect.lint) {
projectConfig.architect.lint.options.tsConfig = [
...projectConfig.architect.lint.options.tsConfig,
join(normalize(projectConfig.root), 'tsconfig.spec.json')
];
}
return json;
});
}
function check(options: KarmaProjectSchema): Rule {
return (host: Tree) => {
const projectConfig = getProjectConfig(host, options.project);
if (projectConfig.architect.test) {
throw new Error(
`${options.project} already has a test architect option.`
);
}
};
}
export default function(options: KarmaProjectSchema): Rule {
return chain([
check(options),
generateFiles(options),
updateTsConfig(options),
updateTsSpecConfig(options),
updateAngularJson(options)
]);
}