@@ -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-
11977describe ( '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