@@ -561,4 +561,187 @@ describe('generateTranslations', () => {
561561
562562 fs . rmSync ( oldDir , { recursive : true } ) ;
563563 } ) ;
564+
565+ it ( 'translates only specified paths when --paths is provided' , async ( ) => {
566+ fs . writeFileSync (
567+ EN_PATH ,
568+ dedent ( `
569+ const strings = {
570+ greeting: 'Hello',
571+ farewell: 'Goodbye',
572+ common: {
573+ save: 'Save',
574+ cancel: 'Cancel',
575+ },
576+ errors: {
577+ generic: 'An error occurred',
578+ network: 'Network error',
579+ },
580+ };
581+ export default strings;
582+ ` ) ,
583+ 'utf8' ,
584+ ) ;
585+
586+ // Override process.argv to specify only certain paths
587+ process . argv = [ 'ts-node' , 'generateTranslations.ts' , '--dry-run' , '--verbose' , '--locales' , 'it' , '--paths' , 'common.save,errors.generic' ] ;
588+
589+ const translateSpy = jest . spyOn ( Translator . prototype , 'translate' ) ;
590+
591+ await generateTranslations ( ) ;
592+ const itContent = fs . readFileSync ( IT_PATH , 'utf8' ) ;
593+
594+ // Only the specified paths should be translated
595+ expect ( itContent ) . toContain ( '[it] Save' ) ;
596+ expect ( itContent ) . toContain ( '[it] An error occurred' ) ;
597+
598+ // Other paths should not be translated
599+ expect ( itContent ) . not . toContain ( '[it] Hello' ) ;
600+ expect ( itContent ) . not . toContain ( '[it] Goodbye' ) ;
601+ expect ( itContent ) . not . toContain ( '[it] Cancel' ) ;
602+ expect ( itContent ) . not . toContain ( '[it] Network error' ) ;
603+
604+ expect ( translateSpy ) . toHaveBeenCalledTimes ( 2 ) ;
605+ expect ( translateSpy ) . toHaveBeenCalledWith ( 'it' , 'Save' , undefined ) ;
606+ expect ( translateSpy ) . toHaveBeenCalledWith ( 'it' , 'An error occurred' , undefined ) ;
607+ } ) ;
608+
609+ it ( 'translates nested paths when parent path is specified' , async ( ) => {
610+ fs . writeFileSync (
611+ EN_PATH ,
612+ dedent ( `
613+ const strings = {
614+ greeting: 'Hello',
615+ common: {
616+ save: 'Save',
617+ cancel: 'Cancel',
618+ nested: {
619+ deep: 'Deep value',
620+ },
621+ },
622+ errors: {
623+ generic: 'An error occurred',
624+ },
625+ };
626+ export default strings;
627+ ` ) ,
628+ 'utf8' ,
629+ ) ;
630+
631+ // Override process.argv to specify parent path
632+ process . argv = [ 'ts-node' , 'generateTranslations.ts' , '--dry-run' , '--verbose' , '--locales' , 'it' , '--paths' , 'common' ] ;
633+
634+ const translateSpy = jest . spyOn ( Translator . prototype , 'translate' ) ;
635+
636+ await generateTranslations ( ) ;
637+ const itContent = fs . readFileSync ( IT_PATH , 'utf8' ) ;
638+
639+ // All nested paths under 'common' should be translated
640+ expect ( itContent ) . toContain ( '[it] Save' ) ;
641+ expect ( itContent ) . toContain ( '[it] Cancel' ) ;
642+ expect ( itContent ) . toContain ( '[it] Deep value' ) ;
643+
644+ // Other paths should not be translated
645+ expect ( itContent ) . not . toContain ( '[it] Hello' ) ;
646+ expect ( itContent ) . not . toContain ( '[it] An error occurred' ) ;
647+
648+ expect ( translateSpy ) . toHaveBeenCalledTimes ( 3 ) ;
649+ expect ( translateSpy ) . toHaveBeenCalledWith ( 'it' , 'Save' , undefined ) ;
650+ expect ( translateSpy ) . toHaveBeenCalledWith ( 'it' , 'Cancel' , undefined ) ;
651+ expect ( translateSpy ) . toHaveBeenCalledWith ( 'it' , 'Deep value' , undefined ) ;
652+ } ) ;
653+
654+ it ( 'ignores --compare-ref when --paths is provided' , async ( ) => {
655+ fs . writeFileSync (
656+ EN_PATH ,
657+ dedent ( `
658+ const strings = {
659+ greeting: 'Hello',
660+ common: {
661+ save: 'Save',
662+ },
663+ };
664+ export default strings;
665+ ` ) ,
666+ 'utf8' ,
667+ ) ;
668+
669+ // Override process.argv to specify both paths and compare-ref
670+ process . argv = [ 'ts-node' , 'generateTranslations.ts' , '--dry-run' , '--verbose' , '--locales' , 'it' , '--paths' , 'common.save' , '--compare-ref' , 'main' ] ;
671+
672+ const translateSpy = jest . spyOn ( Translator . prototype , 'translate' ) ;
673+ const githubSpy = jest . spyOn ( GitHubUtils , 'getFileContents' ) ;
674+
675+ await generateTranslations ( ) ;
676+ const itContent = fs . readFileSync ( IT_PATH , 'utf8' ) ;
677+
678+ // Only the specified path should be translated
679+ expect ( itContent ) . toContain ( '[it] Save' ) ;
680+ expect ( itContent ) . not . toContain ( '[it] Hello' ) ;
681+
682+ // GitHubUtils.getFileContents should not be called since --compare-ref is ignored
683+ expect ( githubSpy ) . not . toHaveBeenCalled ( ) ;
684+ expect ( translateSpy ) . toHaveBeenCalledTimes ( 1 ) ;
685+ expect ( translateSpy ) . toHaveBeenCalledWith ( 'it' , 'Save' , undefined ) ;
686+ } ) ;
687+
688+ it ( 'throws error for invalid paths' , async ( ) => {
689+ fs . writeFileSync (
690+ EN_PATH ,
691+ dedent ( `
692+ const strings = {
693+ greeting: 'Hello',
694+ common: {
695+ save: 'Save',
696+ },
697+ };
698+ export default strings;
699+ ` ) ,
700+ 'utf8' ,
701+ ) ;
702+
703+ // Override process.argv to specify a non-existent path
704+ process . argv = [ 'ts-node' , 'generateTranslations.ts' , '--dry-run' , '--verbose' , '--locales' , 'it' , '--paths' , 'nonexistent.path' ] ;
705+
706+ // Expect the script to throw an error during CLI parsing
707+ await expect ( generateTranslations ( ) ) . rejects . toThrow ( 'Translation path not found: nonexistent.path' ) ;
708+ } ) ;
709+
710+ it ( 'validates paths against actual translation structure' , async ( ) => {
711+ fs . writeFileSync (
712+ EN_PATH ,
713+ dedent ( `
714+ const strings = {
715+ greeting: 'Hello',
716+ common: {
717+ save: 'Save',
718+ cancel: 'Cancel',
719+ },
720+ errors: {
721+ generic: 'An error occurred',
722+ },
723+ };
724+ export default strings;
725+ ` ) ,
726+ 'utf8' ,
727+ ) ;
728+
729+ // Test that valid paths work
730+ process . argv = [ 'ts-node' , 'generateTranslations.ts' , '--dry-run' , '--verbose' , '--locales' , 'it' , '--paths' , 'greeting,common.save' ] ;
731+
732+ const translateSpy = jest . spyOn ( Translator . prototype , 'translate' ) ;
733+
734+ await generateTranslations ( ) ;
735+ const itContent = fs . readFileSync ( IT_PATH , 'utf8' ) ;
736+
737+ // Should translate the specified paths
738+ expect ( itContent ) . toContain ( '[it] Hello' ) ;
739+ expect ( itContent ) . toContain ( '[it] Save' ) ;
740+
741+ // Should not translate other paths
742+ expect ( itContent ) . not . toContain ( '[it] Cancel' ) ;
743+ expect ( itContent ) . not . toContain ( '[it] An error occurred' ) ;
744+
745+ expect ( translateSpy ) . toHaveBeenCalledTimes ( 2 ) ;
746+ } ) ;
564747} ) ;
0 commit comments