test(ivy): expand `ngcc` `DecorationAnalyzer` tests to cover more cases (#28963)

PR Close #28963
This commit is contained in:
George Kalpakas 2019-03-18 16:24:56 +02:00 committed by Matias Niemelä
parent c439e14d39
commit e79f57a6b8
1 changed files with 66 additions and 32 deletions

View File

@ -15,18 +15,32 @@ import {NgccReferencesRegistry} from '../../src/analysis/ngcc_references_registr
import {Esm2015ReflectionHost} from '../../src/host/esm2015_host'; import {Esm2015ReflectionHost} from '../../src/host/esm2015_host';
import {makeTestBundleProgram} from '../helpers/utils'; import {makeTestBundleProgram} from '../helpers/utils';
const TEST_PROGRAM = { const TEST_PROGRAM = [
{
name: 'test.js', name: 'test.js',
contents: ` contents: `
import {Component, Injectable} from '@angular/core'; import {Component, Directive, Injectable} from '@angular/core';
export class MyComponent {} export class MyComponent {}
MyComponent.decorators = [{type: Component}]; MyComponent.decorators = [{type: Component}];
export class MyDirective {}
MyDirective.decorators = [{type: Directive}];
export class MyService {} export class MyService {}
MyService.decorators = [{type: Injectable}]; MyService.decorators = [{type: Injectable}];
` `,
}; },
{
name: 'other.js',
contents: `
import {Component} from '@angular/core';
export class MyOtherComponent {}
MyOtherComponent.decorators = [{type: Component}];
`,
},
];
const INTERNAL_COMPONENT_PROGRAM = [ const INTERNAL_COMPONENT_PROGRAM = [
{ {
@ -62,13 +76,13 @@ function createTestHandler() {
'analyze', 'analyze',
'compile', 'compile',
]); ]);
// Only detect the Component decorator // Only detect the Component and Directive decorators
handler.detect.and.callFake( handler.detect.and.callFake(
(node: ts.Declaration, decorators: Decorator[]): DetectResult<any>| undefined => { (node: ts.Declaration, decorators: Decorator[]): DetectResult<any>| undefined => {
if (!decorators) { if (!decorators) {
return undefined; return undefined;
} }
const metadata = decorators.find(d => d.name === 'Component'); const metadata = decorators.find(d => d.name === 'Component' || d.name === 'Directive');
if (metadata === undefined) { if (metadata === undefined) {
return undefined; return undefined;
} else { } else {
@ -78,11 +92,13 @@ function createTestHandler() {
}; };
} }
}); });
// The "test" analysis is just the name of the decorator being analyzed // The "test" analysis is an object with the name of the decorator being analyzed
handler.analyze.and.callFake( handler.analyze.and.callFake((decl: ts.Declaration, dec: Decorator) => {
((decl: ts.Declaration, dec: Decorator) => ({analysis: dec.name, diagnostics: undefined}))); expect(handler.compile).not.toHaveBeenCalled();
return {analysis: {decoratorName: dec.name}, diagnostics: undefined};
});
// The "test" compilation result is just the name of the decorator being compiled // The "test" compilation result is just the name of the decorator being compiled
handler.compile.and.callFake(((decl: ts.Declaration, analysis: any) => ({analysis}))); handler.compile.and.callFake((decl: ts.Declaration, analysis: any) => ({analysis}));
return handler; return handler;
} }
@ -108,35 +124,53 @@ describe('DecorationAnalyzer', () => {
}; };
describe('basic usage', () => { describe('basic usage', () => {
beforeEach(() => setUpAndAnalyzeProgram([TEST_PROGRAM])); beforeEach(() => setUpAndAnalyzeProgram(TEST_PROGRAM));
it('should return an object containing a reference to the original source file', () => { it('should return an object containing a reference to the original source file', () => {
const file = program.getSourceFile(TEST_PROGRAM.name) !; TEST_PROGRAM.forEach(({name}) => {
const file = program.getSourceFile(name) !;
expect(result.get(file) !.sourceFile).toBe(file); expect(result.get(file) !.sourceFile).toBe(file);
}); });
});
it('should call detect on the decorator handlers with each class from the parsed file', it('should call detect on the decorator handlers with each class from the parsed file',
() => { () => {
expect(testHandler.detect).toHaveBeenCalledTimes(2); expect(testHandler.detect).toHaveBeenCalledTimes(4);
expect(testHandler.detect.calls.allArgs()[0][1]).toEqual([jasmine.objectContaining( expect(testHandler.detect.calls.allArgs().map(args => args[1][0])).toEqual([
{name: 'Component'})]); jasmine.objectContaining({name: 'Component'}),
expect(testHandler.detect.calls.allArgs()[1][1]).toEqual([jasmine.objectContaining( jasmine.objectContaining({name: 'Directive'}),
{name: 'Injectable'})]); jasmine.objectContaining({name: 'Injectable'}),
jasmine.objectContaining({name: 'Component'}),
]);
}); });
it('should return an object containing the classes that were analyzed', () => { it('should return an object containing the classes that were analyzed', () => {
const file = program.getSourceFile(TEST_PROGRAM.name) !; const file1 = program.getSourceFile(TEST_PROGRAM[0].name) !;
const compiledFile = result.get(file) !; const compiledFile1 = result.get(file1) !;
expect(compiledFile.compiledClasses.length).toEqual(1); expect(compiledFile1.compiledClasses.length).toEqual(2);
expect(compiledFile.compiledClasses[0].name).toEqual('MyComponent'); expect(compiledFile1.compiledClasses[0].name).toEqual('MyComponent');
expect(compiledFile1.compiledClasses[1].name).toEqual('MyDirective');
const file2 = program.getSourceFile(TEST_PROGRAM[1].name) !;
const compiledFile2 = result.get(file2) !;
expect(compiledFile2.compiledClasses.length).toEqual(1);
expect(compiledFile2.compiledClasses[0].name).toEqual('MyOtherComponent');
}); });
it('should analyze and compile the classes that are detected', () => { it('should analyze and compile the classes that are detected', () => {
expect(testHandler.analyze).toHaveBeenCalledTimes(1); expect(testHandler.analyze).toHaveBeenCalledTimes(3);
expect(testHandler.analyze.calls.allArgs()[0][1].name).toEqual('Component'); expect(testHandler.analyze.calls.allArgs().map(args => args[1])).toEqual([
jasmine.objectContaining({name: 'Component'}),
jasmine.objectContaining({name: 'Directive'}),
jasmine.objectContaining({name: 'Component'}),
]);
expect(testHandler.compile).toHaveBeenCalledTimes(1); expect(testHandler.compile).toHaveBeenCalledTimes(3);
expect(testHandler.compile.calls.allArgs()[0][1]).toEqual('Component'); expect(testHandler.compile.calls.allArgs().map(args => args[1])).toEqual([
{decoratorName: 'Component'},
{decoratorName: 'Directive'},
{decoratorName: 'Component'},
]);
}); });
}); });