11import { createCollectionContent } from '../createCollectionContent'
22import { getConfig } from '../getConfig'
33import { writeFile } from 'fs/promises'
4- import { existsSync } from 'fs'
4+ import { existsSync , readFileSync } from 'fs'
55
66jest . mock ( '../getConfig' )
77jest . mock ( 'fs/promises' )
@@ -53,18 +53,19 @@ it('should call writeFile with the expected file location and content without th
5353 const mockContent = [
5454 { name : 'test' , base : 'src/docs' , pattern : '**/*.md' }
5555 ]
56- ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
56+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
5757 content : mockContent ,
5858 repoRoot : '.'
5959 } )
60+ ; ( existsSync as jest . Mock ) . mockReturnValue ( false ) // No package.json
6061
6162 const mockConsoleError = jest . fn ( )
6263 jest . spyOn ( console , 'error' ) . mockImplementation ( mockConsoleError )
6364
6465 await createCollectionContent ( '/foo/' , '/config/dir/pf-docs.config.mjs' , false )
6566
6667 const expectedContent = [
67- { name : 'test' , base : '/config/dir/src/docs' , pattern : '**/*.md' }
68+ { name : 'test' , base : '/config/dir/src/docs' , pattern : '**/*.md' , version : null }
6869 ]
6970
7071 expect ( writeFile ) . toHaveBeenCalledWith (
@@ -78,10 +79,11 @@ it('should log error if writeFile throws an error', async () => {
7879 const mockContent = [
7980 { name : 'test' , base : 'src/docs' , pattern : '**/*.md' }
8081 ]
81- ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
82+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
8283 content : mockContent ,
8384 repoRoot : '.'
8485 } )
86+ ; ( existsSync as jest . Mock ) . mockReturnValue ( false ) // No package.json
8587
8688 const mockConsoleError = jest . fn ( )
8789 jest . spyOn ( console , 'error' ) . mockImplementation ( mockConsoleError )
@@ -102,11 +104,12 @@ it('should log all verbose messages when run in verbose mode', async () => {
102104 { name : 'docs' , base : 'src/docs' , pattern : '**/*.md' } ,
103105 { name : 'components' , packageName : '@patternfly/react-core' , pattern : '**/*.md' }
104106 ]
105- ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
107+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
106108 content : mockContent ,
107109 repoRoot : '../'
108110 } )
109111 ; ( existsSync as jest . Mock ) . mockReturnValue ( true )
112+ ; ( readFileSync as jest . Mock ) . mockReturnValue ( JSON . stringify ( { version : '6.2.2' } ) )
110113 ; ( writeFile as jest . Mock ) . mockResolvedValue ( undefined )
111114
112115 const mockConsoleLog = jest . fn ( )
@@ -118,15 +121,19 @@ it('should log all verbose messages when run in verbose mode', async () => {
118121 expect ( mockConsoleLog ) . toHaveBeenCalledWith ( 'configuration content entry: ' , mockContent , '\n' )
119122 expect ( mockConsoleLog ) . toHaveBeenCalledWith ( 'Creating content file' , '/foo/src/content.ts' , '\n' )
120123 expect ( mockConsoleLog ) . toHaveBeenCalledWith ( 'repoRootDir: ' , '/config' , '\n' )
121-
124+
122125 // For the base entry
123126 expect ( mockConsoleLog ) . toHaveBeenCalledWith ( 'relative path: ' , 'src/docs' )
124127 expect ( mockConsoleLog ) . toHaveBeenCalledWith ( 'absolute path: ' , '/config/dir/src/docs' , '\n' )
125-
128+
126129 // For the packageName entry
127130 expect ( mockConsoleLog ) . toHaveBeenCalledWith ( 'looking for package in ' , '/config/dir/node_modules' , '\n' )
128131 expect ( mockConsoleLog ) . toHaveBeenCalledWith ( 'found package at ' , '/config/dir/node_modules/@patternfly/react-core' , '\n' )
129-
132+
133+ // Version extraction logs
134+ expect ( mockConsoleLog ) . toHaveBeenCalledWith ( 'Extracted version v6 from /config/dir/src/docs/package.json\n' )
135+ expect ( mockConsoleLog ) . toHaveBeenCalledWith ( 'Extracted version v6 from /config/dir/node_modules/@patternfly/react-core/package.json\n' )
136+
130137 // Final log
131138 expect ( mockConsoleLog ) . toHaveBeenCalledWith ( 'Content file created' )
132139} )
@@ -177,10 +184,11 @@ it('should not log to the console when not run in verbose mode', async () => {
177184 const mockContent = [
178185 { name : 'test' , base : 'src/docs' , pattern : '**/*.md' }
179186 ]
180- ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
187+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
181188 content : mockContent ,
182189 repoRoot : '.'
183190 } )
191+ ; ( existsSync as jest . Mock ) . mockReturnValue ( false )
184192 ; ( writeFile as jest . Mock ) . mockResolvedValue ( undefined )
185193
186194 const mockConsoleLog = jest . fn ( )
@@ -195,11 +203,12 @@ it('should handle content with packageName by finding package in node_modules',
195203 const mockContent = [
196204 { name : 'test' , packageName : '@patternfly/react-core' , pattern : '**/*.md' }
197205 ]
198- ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
206+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
199207 content : mockContent ,
200208 repoRoot : '.'
201209 } )
202210 ; ( existsSync as jest . Mock ) . mockReturnValue ( true )
211+ ; ( readFileSync as jest . Mock ) . mockReturnValue ( JSON . stringify ( { version : '6.2.2' } ) )
203212 ; ( writeFile as jest . Mock ) . mockResolvedValue ( undefined )
204213
205214 const mockConsoleError = jest . fn ( )
@@ -208,10 +217,11 @@ it('should handle content with packageName by finding package in node_modules',
208217 await createCollectionContent ( '/foo/' , '/config/dir/pf-docs.config.mjs' , false )
209218
210219 const expectedContent = [
211- {
220+ {
212221 base : '/config/dir/node_modules/@patternfly/react-core' ,
213- name : 'test' ,
214- packageName : '@patternfly/react-core' ,
222+ version : 'v6' ,
223+ name : 'test' ,
224+ packageName : '@patternfly/react-core' ,
215225 pattern : '**/*.md'
216226 }
217227 ]
@@ -227,13 +237,15 @@ it('should handle content with packageName when package is not found locally but
227237 const mockContent = [
228238 { name : 'test' , packageName : '@patternfly/react-core' , pattern : '**/*.md' }
229239 ]
230- ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
240+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
231241 content : mockContent ,
232242 repoRoot : '../../'
233243 } )
234244 ; ( existsSync as jest . Mock )
235245 . mockReturnValueOnce ( false ) // not found in /config/dir/node_modules
236- . mockReturnValueOnce ( true ) // found in /config/node_modules
246+ . mockReturnValueOnce ( true ) // found in /config/node_modules/package.json
247+ . mockReturnValueOnce ( true ) // package.json exists for version extraction
248+ ; ( readFileSync as jest . Mock ) . mockReturnValue ( JSON . stringify ( { version : '5.1.0' } ) )
237249 ; ( writeFile as jest . Mock ) . mockResolvedValue ( undefined )
238250
239251 const mockConsoleError = jest . fn ( )
@@ -242,10 +254,11 @@ it('should handle content with packageName when package is not found locally but
242254 await createCollectionContent ( '/foo/' , '/config/dir/pf-docs.config.mjs' , false )
243255
244256 const expectedContent = [
245- {
257+ {
246258 base : '/config/node_modules/@patternfly/react-core' ,
247- name : 'test' ,
248- packageName : '@patternfly/react-core' ,
259+ version : 'v5' ,
260+ name : 'test' ,
261+ packageName : '@patternfly/react-core' ,
249262 pattern : '**/*.md'
250263 }
251264 ]
@@ -261,7 +274,7 @@ it('should handle content with packageName when package is not found anywhere',
261274 const mockContent = [
262275 { name : 'test' , packageName : '@patternfly/react-core' , pattern : '**/*.md' }
263276 ]
264- ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
277+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
265278 content : mockContent ,
266279 repoRoot : '../'
267280 } )
@@ -274,10 +287,11 @@ it('should handle content with packageName when package is not found anywhere',
274287 await createCollectionContent ( '/foo/' , '/config/dir/pf-docs.config.mjs' , false )
275288
276289 const expectedContent = [
277- {
290+ {
278291 base : null ,
279- name : 'test' ,
280- packageName : '@patternfly/react-core' ,
292+ version : null ,
293+ name : 'test' ,
294+ packageName : '@patternfly/react-core' ,
281295 pattern : '**/*.md'
282296 }
283297 ]
@@ -294,11 +308,12 @@ it('should handle mixed content with both base and packageName entries', async (
294308 { name : 'docs' , base : 'src/docs' , pattern : '**/*.md' } ,
295309 { name : 'components' , packageName : '@patternfly/react-core' , pattern : '**/*.md' }
296310 ]
297- ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
311+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
298312 content : mockContent ,
299313 repoRoot : '../'
300314 } )
301315 ; ( existsSync as jest . Mock ) . mockReturnValue ( true )
316+ ; ( readFileSync as jest . Mock ) . mockReturnValue ( JSON . stringify ( { version : '6.2.2' } ) )
302317 ; ( writeFile as jest . Mock ) . mockResolvedValue ( undefined )
303318
304319 const mockConsoleError = jest . fn ( )
@@ -307,11 +322,12 @@ it('should handle mixed content with both base and packageName entries', async (
307322 await createCollectionContent ( '/foo/' , '/config/dir/pf-docs.config.mjs' , false )
308323
309324 const expectedContent = [
310- { name : 'docs' , base : '/config/dir/src/docs' , pattern : '**/*.md' } ,
311- {
325+ { name : 'docs' , base : '/config/dir/src/docs' , pattern : '**/*.md' , version : 'v6' } ,
326+ {
312327 base : '/config/dir/node_modules/@patternfly/react-core' ,
313- name : 'components' ,
314- packageName : '@patternfly/react-core' ,
328+ version : 'v6' ,
329+ name : 'components' ,
330+ packageName : '@patternfly/react-core' ,
315331 pattern : '**/*.md'
316332 }
317333 ]
@@ -322,3 +338,173 @@ it('should handle mixed content with both base and packageName entries', async (
322338 )
323339 expect ( mockConsoleError ) . not . toHaveBeenCalled ( )
324340} )
341+
342+ describe ( 'getPackageVersion function' , ( ) => {
343+ it ( 'should extract major version from valid package.json with version 6.2.2' , async ( ) => {
344+ const mockContent = [
345+ { name : 'test' , base : 'src/docs' , pattern : '**/*.md' }
346+ ]
347+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
348+ content : mockContent ,
349+ repoRoot : '.'
350+ } )
351+ ; ( existsSync as jest . Mock ) . mockReturnValue ( true )
352+ ; ( readFileSync as jest . Mock ) . mockReturnValue ( JSON . stringify ( { version : '6.2.2' } ) )
353+ ; ( writeFile as jest . Mock ) . mockResolvedValue ( undefined )
354+
355+ await createCollectionContent ( '/foo/' , '/config/dir/pf-docs.config.mjs' , false )
356+
357+ const expectedContent = [
358+ { name : 'test' , base : '/config/dir/src/docs' , pattern : '**/*.md' , version : 'v6' }
359+ ]
360+
361+ expect ( writeFile ) . toHaveBeenCalledWith (
362+ '/foo/src/content.ts' ,
363+ `export const content = ${ JSON . stringify ( expectedContent ) } ` ,
364+ )
365+ } )
366+
367+ it ( 'should extract major version from valid package.json with version 5.1.0' , async ( ) => {
368+ const mockContent = [
369+ { name : 'test' , base : 'src/docs' , pattern : '**/*.md' }
370+ ]
371+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
372+ content : mockContent ,
373+ repoRoot : '.'
374+ } )
375+ ; ( existsSync as jest . Mock ) . mockReturnValue ( true )
376+ ; ( readFileSync as jest . Mock ) . mockReturnValue ( JSON . stringify ( { version : '5.1.0' } ) )
377+ ; ( writeFile as jest . Mock ) . mockResolvedValue ( undefined )
378+
379+ await createCollectionContent ( '/foo/' , '/config/dir/pf-docs.config.mjs' , false )
380+
381+ const expectedContent = [
382+ { name : 'test' , base : '/config/dir/src/docs' , pattern : '**/*.md' , version : 'v5' }
383+ ]
384+
385+ expect ( writeFile ) . toHaveBeenCalledWith (
386+ '/foo/src/content.ts' ,
387+ `export const content = ${ JSON . stringify ( expectedContent ) } ` ,
388+ )
389+ } )
390+
391+ it ( 'should return null version when package.json does not exist' , async ( ) => {
392+ const mockContent = [
393+ { name : 'test' , base : 'src/docs' , pattern : '**/*.md' }
394+ ]
395+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
396+ content : mockContent ,
397+ repoRoot : '.'
398+ } )
399+ ; ( existsSync as jest . Mock ) . mockReturnValue ( false )
400+ ; ( writeFile as jest . Mock ) . mockResolvedValue ( undefined )
401+
402+ await createCollectionContent ( '/foo/' , '/config/dir/pf-docs.config.mjs' , false )
403+
404+ const expectedContent = [
405+ { name : 'test' , base : '/config/dir/src/docs' , pattern : '**/*.md' , version : null }
406+ ]
407+
408+ expect ( writeFile ) . toHaveBeenCalledWith (
409+ '/foo/src/content.ts' ,
410+ `export const content = ${ JSON . stringify ( expectedContent ) } ` ,
411+ )
412+ } )
413+
414+ it ( 'should return null version when package.json has no version field' , async ( ) => {
415+ const mockContent = [
416+ { name : 'test' , base : 'src/docs' , pattern : '**/*.md' }
417+ ]
418+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
419+ content : mockContent ,
420+ repoRoot : '.'
421+ } )
422+ ; ( existsSync as jest . Mock ) . mockReturnValue ( true )
423+ ; ( readFileSync as jest . Mock ) . mockReturnValue ( JSON . stringify ( { name : 'test-package' } ) )
424+ ; ( writeFile as jest . Mock ) . mockResolvedValue ( undefined )
425+
426+ await createCollectionContent ( '/foo/' , '/config/dir/pf-docs.config.mjs' , false )
427+
428+ const expectedContent = [
429+ { name : 'test' , base : '/config/dir/src/docs' , pattern : '**/*.md' , version : null }
430+ ]
431+
432+ expect ( writeFile ) . toHaveBeenCalledWith (
433+ '/foo/src/content.ts' ,
434+ `export const content = ${ JSON . stringify ( expectedContent ) } ` ,
435+ )
436+ } )
437+
438+ it ( 'should handle malformed package.json gracefully' , async ( ) => {
439+ const mockContent = [
440+ { name : 'test' , base : 'src/docs' , pattern : '**/*.md' }
441+ ]
442+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
443+ content : mockContent ,
444+ repoRoot : '.'
445+ } )
446+ ; ( existsSync as jest . Mock ) . mockReturnValue ( true )
447+ ; ( readFileSync as jest . Mock ) . mockReturnValue ( '{ invalid json }' )
448+ ; ( writeFile as jest . Mock ) . mockResolvedValue ( undefined )
449+
450+ const mockConsoleError = jest . fn ( )
451+ jest . spyOn ( console , 'error' ) . mockImplementation ( mockConsoleError )
452+
453+ await createCollectionContent ( '/foo/' , '/config/dir/pf-docs.config.mjs' , false )
454+
455+ const expectedContent = [
456+ { name : 'test' , base : '/config/dir/src/docs' , pattern : '**/*.md' , version : null }
457+ ]
458+
459+ expect ( writeFile ) . toHaveBeenCalledWith (
460+ '/foo/src/content.ts' ,
461+ `export const content = ${ JSON . stringify ( expectedContent ) } ` ,
462+ )
463+ } )
464+
465+ it ( 'should handle version with pre-release tags (e.g., 6.0.0-beta.1)' , async ( ) => {
466+ const mockContent = [
467+ { name : 'test' , base : 'src/docs' , pattern : '**/*.md' }
468+ ]
469+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
470+ content : mockContent ,
471+ repoRoot : '.'
472+ } )
473+ ; ( existsSync as jest . Mock ) . mockReturnValue ( true )
474+ ; ( readFileSync as jest . Mock ) . mockReturnValue ( JSON . stringify ( { version : '6.0.0-beta.1' } ) )
475+ ; ( writeFile as jest . Mock ) . mockResolvedValue ( undefined )
476+
477+ await createCollectionContent ( '/foo/' , '/config/dir/pf-docs.config.mjs' , false )
478+
479+ const expectedContent = [
480+ { name : 'test' , base : '/config/dir/src/docs' , pattern : '**/*.md' , version : 'v6' }
481+ ]
482+
483+ expect ( writeFile ) . toHaveBeenCalledWith (
484+ '/foo/src/content.ts' ,
485+ `export const content = ${ JSON . stringify ( expectedContent ) } ` ,
486+ )
487+ } )
488+
489+ it ( 'should log version extraction in verbose mode' , async ( ) => {
490+ const mockContent = [
491+ { name : 'test' , base : 'src/docs' , pattern : '**/*.md' }
492+ ]
493+ ; ( getConfig as jest . Mock ) . mockResolvedValue ( {
494+ content : mockContent ,
495+ repoRoot : '.'
496+ } )
497+ ; ( existsSync as jest . Mock ) . mockReturnValue ( true )
498+ ; ( readFileSync as jest . Mock ) . mockReturnValue ( JSON . stringify ( { version : '6.2.2' } ) )
499+ ; ( writeFile as jest . Mock ) . mockResolvedValue ( undefined )
500+
501+ const mockConsoleLog = jest . fn ( )
502+ jest . spyOn ( console , 'log' ) . mockImplementation ( mockConsoleLog )
503+
504+ await createCollectionContent ( '/foo/' , '/config/dir/pf-docs.config.mjs' , true )
505+
506+ expect ( mockConsoleLog ) . toHaveBeenCalledWith (
507+ 'Extracted version v6 from /config/dir/src/docs/package.json\n'
508+ )
509+ } )
510+ } )
0 commit comments