UNPKG

@ngneat/spectator

Version:

A powerful tool to simplify your Angular tests

156 lines (134 loc) 4.38 kB
import { normalize, strings } from '@angular-devkit/core'; import { apply, chain, externalSchematic, mergeWith, move, template, url, MergeStrategy, Rule, SchematicContext, Tree, noop, } from '@angular-devkit/schematics'; import { buildDefaultPath, getWorkspace } from '@schematics/angular/utility/workspace'; import { parseName } from '@schematics/angular/utility/parse-name'; import { ComponentOptions, DirectiveOptions, ServiceOptions } from './schema'; export function spectatorComponentSchematic(options: ComponentOptions): Rule { return chain([ externalSchematic('@schematics/angular', 'component', { ...omit(options, ['jest', 'withHost', 'withCustomHost']), skipTests: true, }), async (tree: Tree, _context: SchematicContext): Promise<Rule> => { if (options.skipTests) { return noop; } await _ensurePath(tree, options); const movePath = options.flat ? (options.path as string) : normalize(options.path + '/' + strings.dasherize(options.name) || ''); const specTemplateRule = apply( url(`./files/${options.withHost ? 'component-host' : options.withCustomHost ? 'component-custom-host' : 'component'}`), [ template({ ...strings, ...options, }), move(movePath), ], ); return mergeWith(specTemplateRule, MergeStrategy.Default); }, ]); } export function spectatorServiceSchematic(options: ServiceOptions): Rule { return chain([ externalSchematic('@schematics/angular', 'service', { ...omit(options, ['jest', 'isDataService']), skipTests: true, }), async (tree: Tree, _context: SchematicContext): Promise<Rule> => { if (options.skipTests) { return noop; } await _ensurePath(tree, options); const movePath = normalize(options.path || ''); const specTemplateRule = apply(url(`./files/${options.isDataService ? 'data-service' : `service`}`), [ template({ ...strings, ...options, }), move(movePath), ]); return mergeWith(specTemplateRule, MergeStrategy.Default); }, ]); } export function spectatorDirectiveSchematic(options: DirectiveOptions): Rule { return chain([ externalSchematic('@schematics/angular', 'directive', { ...omit(options, ['jest']), skipTests: true, }), async (tree: Tree, _context: SchematicContext): Promise<Rule> => { if (options.skipTests) { return noop; } await _ensurePath(tree, options); const movePath = normalize(options.path || ''); const specTemplateRule = apply(url(`./files/directive`), [ template({ ...strings, ...options, }), move(movePath), ]); return mergeWith(specTemplateRule, MergeStrategy.Default); }, ]); } export function spectatorPipeSchematic(options: DirectiveOptions): Rule { return chain([ externalSchematic('@schematics/angular', 'pipe', { ...omit(options, ['jest']), skipTests: true, }), async (tree: Tree, _context: SchematicContext): Promise<Rule> => { if (options.skipTests) { return noop; } await _ensurePath(tree, options); const movePath = normalize(options.path || ''); const specTemplateRule = apply(url(`./files/pipe`), [ template({ ...strings, ...options, }), move(movePath), ]); return mergeWith(specTemplateRule, MergeStrategy.Default); }, ]); } async function _ensurePath(tree: Tree, options: any): Promise<void> { const workspace = await getWorkspace(tree); if (!options.project) { options.project = workspace.projects.keys().next().value; } const project = workspace.projects.get(options.project as string); if (options.path === undefined && project) { options.path = buildDefaultPath(project); } const parsedPath = parseName(options.path as string, options.name); options.name = parsedPath.name; options.path = parsedPath.path; } function omit<T extends Record<PropertyKey, any>>(original: T, keys: (keyof T)[]): any { return Object.keys(original) .filter((key) => !keys.includes(key)) .reduce((obj: Record<PropertyKey, any>, key) => { obj[key] = original[key]; return obj; }, {}); }