@@ -595,4 +595,106 @@ describe('action', () => {
595595 ) ;
596596 } ) ;
597597 } ) ;
598+
599+ describe ( 'custom error messages' , ( ) => {
600+ it ( 'forces allErrors to true when custom-errors is enabled' , async ( ) => {
601+ mockGetBooleanInput ( { 'custom-errors' : true , 'all-errors' : false } ) ;
602+ mockGetInput ( { schema } ) ;
603+ mockGetMultilineInput ( { files } ) ;
604+
605+ vi . mocked ( fs . readFile )
606+ . mockResolvedValueOnce ( schemaContents )
607+ . mockResolvedValueOnce ( 'invalid content' ) ;
608+ mockGlobGenerator ( [ '/foo/bar/baz/config.yml' ] ) ;
609+
610+ await main . run ( ) ;
611+ expect ( runSpy ) . toHaveReturned ( ) ;
612+ expect ( process . exitCode ) . not . toBeDefined ( ) ;
613+
614+ // Should report multiple errors even though all-errors was false
615+ expect ( core . error ) . toHaveBeenCalledTimes ( 4 ) ;
616+ expect ( core . setOutput ) . toHaveBeenCalledTimes ( 1 ) ;
617+ expect ( core . setOutput ) . toHaveBeenLastCalledWith ( 'valid' , false ) ;
618+ } ) ;
619+
620+ it ( 'provides custom error messages when validation fails' , async ( ) => {
621+ mockGetBooleanInput ( { 'custom-errors' : true , 'fail-on-invalid' : true } ) ;
622+ mockGetInput ( { schema } ) ;
623+ mockGetMultilineInput ( { files } ) ;
624+
625+ // Create a schema with custom error messages
626+ const customErrorSchemaContents = JSON . stringify ( {
627+ title : 'Test schema with custom errors' ,
628+ $schema : 'http://json-schema.org/draft-07/schema#' ,
629+ type : 'object' ,
630+ properties : {
631+ name : { type : 'string' , minLength : 1 }
632+ } ,
633+ required : [ 'name' ] ,
634+ errorMessage : {
635+ properties : {
636+ name : 'Name must be a non-empty string'
637+ }
638+ }
639+ } ) ;
640+
641+ const invalidInstanceContents = JSON . stringify ( { name : '' } ) ;
642+
643+ vi . mocked ( fs . readFile )
644+ . mockResolvedValueOnce ( customErrorSchemaContents )
645+ . mockResolvedValueOnce ( invalidInstanceContents ) ;
646+ mockGlobGenerator ( [ '/foo/bar/baz/config.yml' ] ) ;
647+
648+ await main . run ( ) ;
649+ expect ( runSpy ) . toHaveReturned ( ) ;
650+ expect ( process . exitCode ) . toEqual ( 1 ) ;
651+
652+ expect ( core . error ) . toHaveBeenCalledWith (
653+ 'Error while validating file: /foo/bar/baz/config.yml'
654+ ) ;
655+
656+ // Check that we get our custom error message in the JSON output
657+ const errorCalls = vi . mocked ( core . error ) . mock . calls ;
658+ const hasCustomMessage = errorCalls . some (
659+ call =>
660+ typeof call [ 0 ] === 'string' &&
661+ call [ 0 ] . includes ( 'Name must be a non-empty string' )
662+ ) ;
663+ expect ( hasCustomMessage ) . toBe ( true ) ;
664+
665+ expect ( core . setOutput ) . toHaveBeenCalledTimes ( 1 ) ;
666+ expect ( core . setOutput ) . toHaveBeenLastCalledWith ( 'valid' , false ) ;
667+ } ) ;
668+
669+ it ( 'works without custom-errors when disabled' , async ( ) => {
670+ mockGetBooleanInput ( { 'custom-errors' : false , 'fail-on-invalid' : false } ) ;
671+ mockGetInput ( { schema } ) ;
672+ mockGetMultilineInput ( { files } ) ;
673+
674+ vi . mocked ( fs . readFile )
675+ . mockResolvedValueOnce ( schemaContents )
676+ . mockResolvedValueOnce ( 'invalid content' ) ;
677+ mockGlobGenerator ( [ '/foo/bar/baz/config.yml' ] ) ;
678+
679+ await main . run ( ) ;
680+ expect ( runSpy ) . toHaveReturned ( ) ;
681+ expect ( process . exitCode ) . not . toBeDefined ( ) ;
682+
683+ expect ( core . error ) . toHaveBeenCalledWith (
684+ 'Error while validating file: /foo/bar/baz/config.yml'
685+ ) ;
686+
687+ // Should NOT have any custom error messages (no errorMessage keyword)
688+ const errorCalls = vi . mocked ( core . error ) . mock . calls ;
689+ const hasCustomErrors = errorCalls . some (
690+ call =>
691+ typeof call [ 0 ] === 'string' &&
692+ call [ 0 ] . includes ( '"keyword":"errorMessage"' )
693+ ) ;
694+ expect ( hasCustomErrors ) . toBe ( false ) ;
695+
696+ expect ( core . setOutput ) . toHaveBeenCalledTimes ( 1 ) ;
697+ expect ( core . setOutput ) . toHaveBeenLastCalledWith ( 'valid' , false ) ;
698+ } ) ;
699+ } ) ;
598700} ) ;
0 commit comments