Skip to content

Commit 778de01

Browse files
committed
fixup! fix(ivy): run annotations handlers' resolve() in ngcc
1 parent 0a2a003 commit 778de01

File tree

1 file changed

+64
-61
lines changed

1 file changed

+64
-61
lines changed

packages/compiler-cli/src/ngcc/test/analysis/decoration_analyzer_spec.ts

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -74,56 +74,61 @@ type DecoratorHandlerWithResolve = DecoratorHandler<any, any>& {
7474
resolve: NonNullable<DecoratorHandler<any, any>['resolve']>;
7575
};
7676

77-
function createTestHandler() {
78-
const handler = jasmine.createSpyObj<DecoratorHandlerWithResolve>('TestDecoratorHandler', [
79-
'detect',
80-
'analyze',
81-
'resolve',
82-
'compile',
83-
]);
84-
// Only detect the Component and Directive decorators
85-
handler.detect.and.callFake(
86-
(node: ts.Declaration, decorators: Decorator[]): DetectResult<any>| undefined => {
87-
if (!decorators) {
88-
return undefined;
89-
}
90-
const metadata = decorators.find(d => d.name === 'Component' || d.name === 'Directive');
91-
if (metadata === undefined) {
92-
return undefined;
93-
} else {
94-
return {
95-
metadata,
96-
trigger: metadata.node,
97-
};
98-
}
99-
});
100-
// The "test" analysis is an object with the name of the decorator being analyzed
101-
handler.analyze.and.callFake((decl: ts.Declaration, dec: Decorator) => {
102-
expect(handler.resolve).not.toHaveBeenCalled();
103-
return {analysis: {decoratorName: dec.name}, diagnostics: undefined};
104-
});
105-
// The "test" resolution is just setting `resolved: true` on the analysis
106-
handler.resolve.and.callFake((decl: ts.Declaration, analysis: any) => {
107-
expect(handler.compile).not.toHaveBeenCalled();
108-
analysis.resolved = true;
109-
});
110-
// The "test" compilation result is just the name of the decorator being compiled (suffixed with
111-
// `(compiled)`), as long as it has already passed through `resolve()`
112-
handler.compile.and.callFake((decl: ts.Declaration, analysis: any) => {
113-
expect(handler.resolve).toHaveBeenCalledWith(decl, analysis);
114-
return analysis.resolved && `@${analysis.decoratorName} (compiled)`;
115-
});
116-
return handler;
117-
}
118-
11977
describe('DecorationAnalyzer', () => {
12078
describe('analyzeProgram()', () => {
79+
let logs: string[];
12180
let program: ts.Program;
12281
let testHandler: jasmine.SpyObj<DecoratorHandlerWithResolve>;
12382
let result: DecorationAnalyses;
12483

12584
// Helpers
85+
const createTestHandler = () => {
86+
const handler = jasmine.createSpyObj<DecoratorHandlerWithResolve>('TestDecoratorHandler', [
87+
'detect',
88+
'analyze',
89+
'resolve',
90+
'compile',
91+
]);
92+
// Only detect the Component and Directive decorators
93+
handler.detect.and.callFake(
94+
(node: ts.Declaration, decorators: Decorator[]): DetectResult<any>| undefined => {
95+
logs.push(`detect: ${(node as any).name.text}@${decorators.map(d => d.name)}`);
96+
if (!decorators) {
97+
return undefined;
98+
}
99+
const metadata = decorators.find(d => d.name === 'Component' || d.name === 'Directive');
100+
if (metadata === undefined) {
101+
return undefined;
102+
} else {
103+
return {
104+
metadata,
105+
trigger: metadata.node,
106+
};
107+
}
108+
});
109+
// The "test" analysis is an object with the name of the decorator being analyzed
110+
handler.analyze.and.callFake((decl: ts.Declaration, dec: Decorator) => {
111+
logs.push(`analyze: ${(decl as any).name.text}@${dec.name}`);
112+
return {analysis: {decoratorName: dec.name}, diagnostics: undefined};
113+
});
114+
// The "test" resolution is just setting `resolved: true` on the analysis
115+
handler.resolve.and.callFake((decl: ts.Declaration, analysis: any) => {
116+
logs.push(`resolve: ${(decl as any).name.text}@${analysis.decoratorName}`);
117+
analysis.resolved = true;
118+
});
119+
// The "test" compilation result is just the name of the decorator being compiled
120+
// (suffixed with `(compiled)`)
121+
handler.compile.and.callFake((decl: ts.Declaration, analysis: any) => {
122+
logs.push(
123+
`compile: ${(decl as any).name.text}@${analysis.decoratorName} (resolved: ${analysis.resolved})`);
124+
return `@${analysis.decoratorName} (compiled)`;
125+
});
126+
return handler;
127+
};
128+
126129
const setUpAndAnalyzeProgram = (...progArgs: Parameters<typeof makeTestBundleProgram>) => {
130+
logs = [];
131+
127132
const {options, host, ...bundle} = makeTestBundleProgram(...progArgs);
128133
program = bundle.program;
129134

@@ -178,25 +183,23 @@ describe('DecorationAnalyzer', () => {
178183
});
179184

180185
it('should analyze, resolve and compile the classes that are detected', () => {
181-
expect(testHandler.analyze).toHaveBeenCalledTimes(3);
182-
expect(testHandler.analyze.calls.allArgs().map(args => args[1])).toEqual([
183-
jasmine.objectContaining({name: 'Component'}),
184-
jasmine.objectContaining({name: 'Directive'}),
185-
jasmine.objectContaining({name: 'Component'}),
186-
]);
187-
188-
expect(testHandler.resolve).toHaveBeenCalledTimes(3);
189-
expect(testHandler.resolve.calls.allArgs().map(args => args[1])).toEqual([
190-
{decoratorName: 'Component', resolved: true},
191-
{decoratorName: 'Directive', resolved: true},
192-
{decoratorName: 'Component', resolved: true},
193-
]);
194-
195-
expect(testHandler.compile).toHaveBeenCalledTimes(3);
196-
expect(testHandler.compile.calls.allArgs().map(args => args[1])).toEqual([
197-
{decoratorName: 'Component', resolved: true},
198-
{decoratorName: 'Directive', resolved: true},
199-
{decoratorName: 'Component', resolved: true},
186+
expect(logs).toEqual([
187+
// First detect and (potentially) analyze.
188+
'detect: MyComponent@Component',
189+
'analyze: MyComponent@Component',
190+
'detect: MyDirective@Directive',
191+
'analyze: MyDirective@Directive',
192+
'detect: MyService@Injectable',
193+
'detect: MyOtherComponent@Component',
194+
'analyze: MyOtherComponent@Component',
195+
// The resolve.
196+
'resolve: MyComponent@Component',
197+
'resolve: MyDirective@Directive',
198+
'resolve: MyOtherComponent@Component',
199+
// Finally compile.
200+
'compile: MyComponent@Component (resolved: true)',
201+
'compile: MyDirective@Directive (resolved: true)',
202+
'compile: MyOtherComponent@Component (resolved: true)',
200203
]);
201204
});
202205
});

0 commit comments

Comments
 (0)