feat(angular): add isStandalone util to check for standalone decorators (#14129)

This commit is contained in:
Colum Ferry 2023-01-04 11:04:53 +00:00 committed by GitHub
parent 58b1c40e52
commit 762c9ee50d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 126 additions and 1 deletions

View File

@ -3,6 +3,7 @@ import {
addImportToDirective,
addImportToModule,
addImportToPipe,
isStandalone,
} from './ast-utils';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { createSourceFile, ScriptTarget } from 'typescript';
@ -151,4 +152,112 @@ describe('Angular AST Utils', () => {
"
`);
});
it('should allow checking if a component is standalone and return true if so', () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
const pathToFile = `my.component.ts`;
const originalContents = `import { Component } from '@angular/core';
@Component({
standalone: true
})
export class MyComponent {}
`;
tree.write(pathToFile, originalContents);
const sourceText = tree.read(pathToFile, 'utf-8');
const tsSourceFile = createSourceFile(
pathToFile,
sourceText,
ScriptTarget.Latest,
true
);
// ACT
// ASSERT
expect(isStandalone(tsSourceFile, 'Component')).toBeTruthy();
});
it('should allow checking if a component is standalone and return false if not', () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
const pathToFile = `my.component.ts`;
const originalContents = `import { Component } from '@angular/core';
@Component({
standalone: false
})
export class MyComponent {}
`;
tree.write(pathToFile, originalContents);
const sourceText = tree.read(pathToFile, 'utf-8');
const tsSourceFile = createSourceFile(
pathToFile,
sourceText,
ScriptTarget.Latest,
true
);
// ACT
// ASSERT
expect(isStandalone(tsSourceFile, 'Component')).not.toBeTruthy();
});
it('should allow checking if a directive is standalone and return true if so', () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
const pathToFile = `my.directive.ts`;
const originalContents = `import { Directive } from '@angular/core';
@Directive({
standalone: true
})
export class MyDirective {}
`;
tree.write(pathToFile, originalContents);
const sourceText = tree.read(pathToFile, 'utf-8');
const tsSourceFile = createSourceFile(
pathToFile,
sourceText,
ScriptTarget.Latest,
true
);
// ACT
// ASSERT
expect(isStandalone(tsSourceFile, 'Directive')).toBeTruthy();
});
it('should allow checking if a pipe is standalone and return true if so', () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
const pathToFile = `my.pipe.ts`;
const originalContents = `import { Pipe } from '@angular/core';
@Pipe({
standalone: true
})
export class MyPipe {}
`;
tree.write(pathToFile, originalContents);
const sourceText = tree.read(pathToFile, 'utf-8');
const tsSourceFile = createSourceFile(
pathToFile,
sourceText,
ScriptTarget.Latest,
true
);
// ACT
// ASSERT
expect(isStandalone(tsSourceFile, 'Pipe')).toBeTruthy();
});
});

View File

@ -10,6 +10,8 @@ import {
replaceChange,
} from '@nrwl/workspace/src/utilities/ast-utils';
type DecoratorName = 'Component' | 'Directive' | 'NgModule' | 'Pipe';
function _angularImportsFromNode(
node: ts.ImportDeclaration,
_sourceFile: ts.SourceFile
@ -62,6 +64,20 @@ function _angularImportsFromNode(
}
}
export function isStandalone(
sourceFile: ts.SourceFile,
decoratorName: DecoratorName
) {
const decoratorMetadata = getDecoratorMetadata(
sourceFile,
decoratorName,
'@angular/core'
);
return decoratorMetadata.some((node) =>
node.getText().includes('standalone: true')
);
}
export function getDecoratorMetadata(
source: ts.SourceFile,
identifier: string,
@ -134,7 +150,7 @@ function _addSymbolToDecoratorMetadata(
filePath: string,
metadataField: string,
expression: string,
decoratorName: 'Component' | 'Directive' | 'NgModule' | 'Pipe'
decoratorName: DecoratorName
): ts.SourceFile {
const nodes = getDecoratorMetadata(source, decoratorName, '@angular/core');
let node: any = nodes[0]; // tslint:disable-line:no-any