1- import { CALM_META_SCHEMA_DIRECTORY } from '@finos/calm-shared' ;
2- import { Command } from 'commander' ;
1+ import {
2+ CALM_META_SCHEMA_DIRECTORY ,
3+ Docifier ,
4+ DocifyMode ,
5+ TemplateProcessingMode ,
6+ TemplateProcessor
7+ } from '@finos/calm-shared' ;
8+ import { Command } from 'commander' ;
9+ import { MockInstance } from 'vitest' ;
310
411let calmShared : typeof import ( '@finos/calm-shared' ) ;
512let validateModule : typeof import ( './command-helpers/validate' ) ;
@@ -100,7 +107,19 @@ describe('CLI Commands', () => {
100107 } ) ;
101108
102109 describe ( 'Template Command' , ( ) => {
103- it ( 'should instantiate TemplateProcessor and call processTemplate' , async ( ) => {
110+ let processorConstructorSpy : MockInstance < ( this : TemplateProcessor , inputPath : string , templateBundlePath : string , outputPath : string , urlToLocalPathMapping : Map < string , string > , mode ?: TemplateProcessingMode ) => TemplateProcessor > ;
111+
112+ beforeEach ( ( ) => {
113+ processorConstructorSpy = vi
114+ . spyOn ( calmShared , 'TemplateProcessor' )
115+ . mockImplementation ( ( ) => {
116+ return {
117+ processTemplate : vi . fn ( ) . mockResolvedValue ( undefined ) ,
118+ } as unknown as TemplateProcessor ; //This works to get round any but prob not spying properly (used in other tests)
119+ } ) ;
120+ } ) ;
121+
122+ it ( 'should handle --bundle mode correctly' , async ( ) => {
104123 await program . parseAsync ( [
105124 'node' , 'cli.js' , 'template' ,
106125 '--input' , 'model.json' ,
@@ -109,21 +128,165 @@ describe('CLI Commands', () => {
109128 '--verbose' ,
110129 ] ) ;
111130
112- expect ( calmShared . TemplateProcessor . prototype . processTemplate ) . toHaveBeenCalled ( ) ;
131+ expect ( processorConstructorSpy ) . toHaveBeenCalledWith (
132+ 'model.json' ,
133+ 'templateDir' ,
134+ 'outDir' ,
135+ expect . any ( Map ) ,
136+ 'bundle'
137+ ) ;
138+ } ) ;
139+
140+ it ( 'should handle --template mode correctly' , async ( ) => {
141+ await program . parseAsync ( [
142+ 'node' , 'cli.js' , 'template' ,
143+ '--input' , 'model.json' ,
144+ '--template' , 'template.hbs' ,
145+ '--output' , 'outDir' ,
146+ ] ) ;
147+
148+ expect ( processorConstructorSpy ) . toHaveBeenCalledWith (
149+ 'model.json' ,
150+ 'template.hbs' ,
151+ 'outDir' ,
152+ expect . any ( Map ) ,
153+ 'template'
154+ ) ;
155+ } ) ;
156+
157+ it ( 'should handle --template-dir mode correctly' , async ( ) => {
158+ await program . parseAsync ( [
159+ 'node' , 'cli.js' , 'template' ,
160+ '--input' , 'model.json' ,
161+ '--template-dir' , 'templates/' ,
162+ '--output' , 'outDir' ,
163+ ] ) ;
164+
165+ expect ( processorConstructorSpy ) . toHaveBeenCalledWith (
166+ 'model.json' ,
167+ 'templates/' ,
168+ 'outDir' ,
169+ expect . any ( Map ) ,
170+ 'template-directory'
171+ ) ;
172+ } ) ;
173+
174+ it ( 'should exit if multiple template flags are provided' , async ( ) => {
175+ const exitSpy = vi . spyOn ( process , 'exit' ) . mockImplementationOnce ( ( ) => {
176+ throw new Error ( 'process.exit called' ) ;
177+ } ) ;
178+
179+ const errorSpy = vi . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } ) ;
180+
181+ await expect ( program . parseAsync ( [
182+ 'node' , 'cli.js' , 'template' ,
183+ '--input' , 'model.json' ,
184+ '--template' , 't1.hbs' ,
185+ '--bundle' , 'bundle' ,
186+ '--output' , 'outDir'
187+ ] ) ) . rejects . toThrow ( 'process.exit called' ) ;
188+
189+ expect ( errorSpy ) . toHaveBeenCalledWith ( '❌ Please specify exactly one of --template, --template-dir, or --bundle' ) ;
190+ expect ( exitSpy ) . toHaveBeenCalledWith ( 1 ) ;
191+
192+ exitSpy . mockRestore ( ) ;
193+ errorSpy . mockRestore ( ) ;
113194 } ) ;
114195 } ) ;
115196
197+
116198 describe ( 'Docify Command' , ( ) => {
117- it ( 'should instantiate Docifier and call docify' , async ( ) => {
199+ let docifierConstructorSpy : MockInstance <
200+ ( this : Docifier ,
201+ mode : DocifyMode ,
202+ inputPath : string ,
203+ outputPath : string ,
204+ urlToLocalPathMapping : Map < string , string > ,
205+ templateProcessingMode ?: TemplateProcessingMode ,
206+ templatePath ?: string ) => Docifier
207+ > ;
208+
209+ beforeEach ( ( ) => {
210+ docifierConstructorSpy = vi
211+ . spyOn ( calmShared , 'Docifier' )
212+ . mockImplementation ( ( ) => ( {
213+ docify : vi . fn ( ) . mockResolvedValue ( undefined ) ,
214+ } as unknown as Docifier ) ) ;
215+ } ) ;
216+
217+ it ( 'should default to WEBSITE mode with bundle' , async ( ) => {
118218 await program . parseAsync ( [
119219 'node' , 'cli.js' , 'docify' ,
120220 '--input' , 'model.json' ,
121221 '--output' , 'outDir' ,
122- '--url-to-local-file-mapping' , 'url-to-file-directory.json' ,
123- '--verbose' ,
124222 ] ) ;
125223
126- expect ( calmShared . Docifier . prototype . docify ) . toHaveBeenCalled ( ) ;
224+ expect ( docifierConstructorSpy ) . toHaveBeenCalledWith (
225+ 'WEBSITE' ,
226+ 'model.json' ,
227+ 'outDir' ,
228+ expect . any ( Map ) ,
229+ 'bundle' ,
230+ undefined
231+ ) ;
232+ } ) ;
233+
234+ it ( 'should use template mode if --template is specified' , async ( ) => {
235+ await program . parseAsync ( [
236+ 'node' , 'cli.js' , 'docify' ,
237+ '--input' , 'model.json' ,
238+ '--output' , 'outDir' ,
239+ '--template' , 'template.hbs' ,
240+ ] ) ;
241+
242+ expect ( docifierConstructorSpy ) . toHaveBeenCalledWith (
243+ 'USER_PROVIDED' ,
244+ 'model.json' ,
245+ 'outDir' ,
246+ expect . any ( Map ) ,
247+ 'template' ,
248+ 'template.hbs'
249+ ) ;
250+ } ) ;
251+
252+ it ( 'should use template-directory mode if --template-dir is specified' , async ( ) => {
253+ await program . parseAsync ( [
254+ 'node' , 'cli.js' , 'docify' ,
255+ '--input' , 'model.json' ,
256+ '--output' , 'outDir' ,
257+ '--template-dir' , 'templateDir' ,
258+ ] ) ;
259+
260+ expect ( docifierConstructorSpy ) . toHaveBeenCalledWith (
261+ 'USER_PROVIDED' ,
262+ 'model.json' ,
263+ 'outDir' ,
264+ expect . any ( Map ) ,
265+ 'template-directory' ,
266+ 'templateDir'
267+ ) ;
268+ } ) ;
269+
270+ it ( 'should exit if both --template and --template-dir are specified' , async ( ) => {
271+ const exitSpy = vi . spyOn ( process , 'exit' ) . mockImplementationOnce ( ( ) => {
272+ throw new Error ( 'process.exit called' ) ;
273+ } ) ;
274+ const errorSpy = vi . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } ) ;
275+
276+ await expect ( program . parseAsync ( [
277+ 'node' , 'cli.js' , 'docify' ,
278+ '--input' , 'model.json' ,
279+ '--output' , 'outDir' ,
280+ '--template' , 't1.hbs' ,
281+ '--template-dir' , 'templateDir'
282+ ] ) ) . rejects . toThrow ( 'process.exit called' ) ;
283+
284+ expect ( errorSpy ) . toHaveBeenCalledWith ( '❌ Please specify only one of --template or --template-dir' ) ;
285+ expect ( exitSpy ) . toHaveBeenCalledWith ( 1 ) ;
286+
287+ exitSpy . mockRestore ( ) ;
288+ errorSpy . mockRestore ( ) ;
127289 } ) ;
128290 } ) ;
291+
129292} ) ;
0 commit comments