@@ -642,3 +642,291 @@ test('yamlAsJson: failed validation of a multi-document-file', async () => {
642
642
]
643
643
} )
644
644
} )
645
+
646
+ test ( 'successfully skips JSON files that match json_exclude_regex' , async ( ) => {
647
+ process . env . INPUT_JSON_EXCLUDE_REGEX = '.*valid.*\\.json'
648
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/valid'
649
+
650
+ expect ( await jsonValidator ( excludeMock ) ) . toStrictEqual ( {
651
+ failed : 0 ,
652
+ passed : 0 ,
653
+ skipped : 1 ,
654
+ success : true ,
655
+ violations : [ ]
656
+ } )
657
+
658
+ expect ( infoMock ) . toHaveBeenCalledWith (
659
+ expect . stringMatching ( 'skipping due to exclude match:' )
660
+ )
661
+ } )
662
+
663
+ test ( 'handles json_exclude_regex with empty string (no exclusion)' , async ( ) => {
664
+ process . env . INPUT_JSON_EXCLUDE_REGEX = ''
665
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/valid'
666
+
667
+ expect ( await jsonValidator ( excludeMock ) ) . toStrictEqual ( {
668
+ failed : 0 ,
669
+ passed : 1 ,
670
+ skipped : 0 ,
671
+ success : true ,
672
+ violations : [ ]
673
+ } )
674
+ } )
675
+
676
+ test ( 'processes non-array data correctly (covers data validation branch)' , async ( ) => {
677
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/valid'
678
+ process . env . INPUT_JSON_SCHEMA = ''
679
+
680
+ const result = await jsonValidator ( excludeMock )
681
+ expect ( result . success ) . toBe ( true )
682
+ expect ( result . passed ) . toBe ( 1 )
683
+
684
+ expect ( debugMock ) . toHaveBeenCalledWith (
685
+ expect . stringMatching ( '1 object\\(s\\) found in file:' )
686
+ )
687
+ } )
688
+
689
+ test ( 'processes a simple example with DRAFT_2020_12 schema version' , async ( ) => {
690
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/valid'
691
+ process . env . INPUT_JSON_SCHEMA_VERSION = 'draft-2020-12'
692
+
693
+ expect ( await jsonValidator ( excludeMock ) ) . toStrictEqual ( {
694
+ failed : 0 ,
695
+ passed : 1 ,
696
+ skipped : 0 ,
697
+ success : true ,
698
+ violations : [ ]
699
+ } )
700
+
701
+ expect ( debugMock ) . toHaveBeenCalledWith ( 'json_schema_version: draft-2020-12' )
702
+ } )
703
+
704
+ test ( 'processes yaml as json with DRAFT_2020_12 and multiple documents' , async ( ) => {
705
+ process . env . INPUT_YAML_AS_JSON = 'true'
706
+ process . env . INPUT_ALLOW_MULTIPLE_DOCUMENTS = 'true'
707
+ process . env . INPUT_JSON_SCHEMA_VERSION = 'draft-2020-12'
708
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/yaml_as_json/valid_multi'
709
+
710
+ expect ( await jsonValidator ( excludeMock ) ) . toStrictEqual ( {
711
+ failed : 0 ,
712
+ passed : 1 ,
713
+ skipped : 0 ,
714
+ success : true ,
715
+ violations : [ ]
716
+ } )
717
+ } )
718
+
719
+ test ( 'handles invalid ajv strict mode setting' , async ( ) => {
720
+ process . env . INPUT_AJV_STRICT_MODE = 'false'
721
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/valid'
722
+
723
+ expect ( await jsonValidator ( excludeMock ) ) . toStrictEqual ( {
724
+ failed : 0 ,
725
+ passed : 1 ,
726
+ skipped : 0 ,
727
+ success : true ,
728
+ violations : [ ]
729
+ } )
730
+
731
+ expect ( debugMock ) . toHaveBeenCalledWith ( 'strict: false' )
732
+ } )
733
+
734
+ test ( 'handles empty ajv_custom_regexp_formats input' , async ( ) => {
735
+ process . env . INPUT_AJV_CUSTOM_REGEXP_FORMATS = '\n\n'
736
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/valid'
737
+
738
+ expect ( await jsonValidator ( excludeMock ) ) . toStrictEqual ( {
739
+ failed : 0 ,
740
+ passed : 1 ,
741
+ skipped : 0 ,
742
+ success : true ,
743
+ violations : [ ]
744
+ } )
745
+ } )
746
+
747
+ test ( 'handles use_ajv_formats disabled' , async ( ) => {
748
+ process . env . INPUT_USE_AJV_FORMATS = 'false'
749
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/valid'
750
+
751
+ expect ( await jsonValidator ( excludeMock ) ) . toStrictEqual ( {
752
+ failed : 0 ,
753
+ passed : 1 ,
754
+ skipped : 0 ,
755
+ success : true ,
756
+ violations : [ ]
757
+ } )
758
+
759
+ expect ( debugMock ) . toHaveBeenCalledWith (
760
+ 'ajv-formats will not be used with the json-validator'
761
+ )
762
+ } )
763
+
764
+ test ( 'handles non-array data processing with single document YAML as JSON' , async ( ) => {
765
+ // This test covers the case where data is not initially an array (line 254)
766
+ process . env . INPUT_YAML_AS_JSON = 'true'
767
+ process . env . INPUT_ALLOW_MULTIPLE_DOCUMENTS = 'false' // This makes data not an array initially
768
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/yaml_as_json/valid'
769
+ process . env . INPUT_JSON_SCHEMA = ''
770
+
771
+ const result = await jsonValidator ( excludeMock )
772
+ expect ( result . success ) . toBe ( true )
773
+ expect ( result . passed ) . toBe ( 1 )
774
+
775
+ // This should trigger the Array.isArray check and the debug message
776
+ expect ( debugMock ) . toHaveBeenCalledWith (
777
+ expect . stringMatching ( '1 object\\(s\\) found in file:' )
778
+ )
779
+ } )
780
+
781
+ test ( 'edge case: empty json_exclude_regex with complex file structure' , async ( ) => {
782
+ process . env . INPUT_JSON_EXCLUDE_REGEX = ''
783
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/mixture'
784
+ process . env . INPUT_JSON_SCHEMA = ''
785
+
786
+ const result = await jsonValidator ( excludeMock )
787
+ expect ( result . passed + result . failed ) . toBeGreaterThan ( 0 )
788
+ } )
789
+
790
+ test ( 'edge case: complex file patterns with multiple extensions' , async ( ) => {
791
+ process . env . INPUT_FILES =
792
+ '__tests__/fixtures/json/valid/*.json\n__tests__/fixtures/yaml_as_json/valid/*.yaml'
793
+ process . env . INPUT_YAML_AS_JSON = 'true'
794
+ process . env . INPUT_BASE_DIR = '.'
795
+ process . env . INPUT_JSON_SCHEMA = ''
796
+
797
+ const result = await jsonValidator ( excludeMock )
798
+ expect ( result . passed ) . toBeGreaterThan ( 0 )
799
+
800
+ expect ( debugMock ) . toHaveBeenCalledWith ( expect . stringMatching ( 'using files:' ) )
801
+ } )
802
+
803
+ test ( 'edge case: malformed custom regexp formats with complex patterns' , async ( ) => {
804
+ expect . assertions ( 1 )
805
+ try {
806
+ process . env . INPUT_AJV_CUSTOM_REGEXP_FORMATS =
807
+ 'valid_format=^[a-z]+$\ninvalid-format'
808
+ await jsonValidator ( excludeMock )
809
+ } catch ( e ) {
810
+ expect ( e . message ) . toContain ( 'is not in expected format "key=regex"' )
811
+ }
812
+ } )
813
+
814
+ test ( 'edge case: schema file skipping logic' , async ( ) => {
815
+ process . env . INPUT_JSON_SCHEMA = '__tests__/fixtures/schemas/schema1.json'
816
+ process . env . INPUT_FILES =
817
+ '__tests__/fixtures/schemas/schema1.json\n__tests__/fixtures/json/valid/json1.json'
818
+ process . env . INPUT_BASE_DIR = '.'
819
+
820
+ const result = await jsonValidator ( excludeMock )
821
+ expect ( result . passed ) . toBe ( 1 ) // Only json1.json should be processed, schema1.json should be skipped
822
+
823
+ expect ( debugMock ) . toHaveBeenCalledWith (
824
+ expect . stringMatching ( 'skipping json schema file:' )
825
+ )
826
+ } )
827
+
828
+ test ( 'stress test: large number of custom regex formats' , async ( ) => {
829
+ const formats = [ ]
830
+ for ( let i = 0 ; i < 10 ; i ++ ) {
831
+ formats . push ( `format${ i } =^test${ i } .*$` )
832
+ }
833
+
834
+ process . env . INPUT_AJV_CUSTOM_REGEXP_FORMATS = formats . join ( '\n' )
835
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/valid'
836
+ process . env . INPUT_JSON_SCHEMA = ''
837
+
838
+ const result = await jsonValidator ( excludeMock )
839
+ expect ( result . success ) . toBe ( true )
840
+ } )
841
+
842
+ test ( 'edge case: duplicate file processing prevention' , async ( ) => {
843
+ // Test that files are not processed multiple times
844
+ process . env . INPUT_FILES =
845
+ '__tests__/fixtures/json/valid/json1.json\n__tests__/fixtures/json/valid/json1.json'
846
+ process . env . INPUT_BASE_DIR = '.'
847
+ process . env . INPUT_JSON_SCHEMA = ''
848
+
849
+ const result = await jsonValidator ( excludeMock )
850
+ expect ( result . passed ) . toBe ( 1 ) // Should only process the file once
851
+
852
+ expect ( debugMock ) . toHaveBeenCalledWith (
853
+ expect . stringMatching ( 'skipping duplicate file:' )
854
+ )
855
+ } )
856
+
857
+ test ( 'edge case: baseDir with trailing slash normalization' , async ( ) => {
858
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/valid/' // Note trailing slash
859
+ process . env . INPUT_JSON_SCHEMA = ''
860
+
861
+ const result = await jsonValidator ( excludeMock )
862
+ expect ( result . success ) . toBe ( true )
863
+ expect ( result . passed ) . toBe ( 1 )
864
+ } )
865
+
866
+ test ( 'real world scenario: large schema with draft-2019-09' , async ( ) => {
867
+ process . env . INPUT_JSON_SCHEMA_VERSION = 'draft-2019-09'
868
+ process . env . INPUT_JSON_SCHEMA = '__tests__/fixtures/schemas/challenge.json'
869
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/real_world/challenges'
870
+ process . env . INPUT_YAML_AS_JSON = 'true'
871
+
872
+ const result = await jsonValidator ( excludeMock )
873
+ expect ( result ) . toBeDefined ( )
874
+ expect ( typeof result . success ) . toBe ( 'boolean' )
875
+ } )
876
+
877
+ test ( 'edge case: potential non-array data with complex yaml parsing' , async ( ) => {
878
+ // Create a file with complex YAML that might not result in array
879
+ const fs = require ( 'fs' )
880
+ const tempFile = '/tmp/complex_yaml.yaml'
881
+ fs . writeFileSync ( tempFile , 'scalar_value' )
882
+
883
+ process . env . INPUT_YAML_AS_JSON = 'true'
884
+ process . env . INPUT_ALLOW_MULTIPLE_DOCUMENTS = 'false'
885
+ process . env . INPUT_FILES = tempFile
886
+ process . env . INPUT_BASE_DIR = '.'
887
+ process . env . INPUT_JSON_SCHEMA = ''
888
+
889
+ const result = await jsonValidator ( excludeMock )
890
+ expect ( result . passed ) . toBe ( 1 )
891
+
892
+ // Cleanup
893
+ fs . unlinkSync ( tempFile )
894
+ } )
895
+
896
+ test ( 'edge case: empty document processing' , async ( ) => {
897
+ // Create an empty YAML file
898
+ const fs = require ( 'fs' )
899
+ const tempFile = '/tmp/empty.yaml'
900
+ fs . writeFileSync ( tempFile , '' )
901
+
902
+ process . env . INPUT_YAML_AS_JSON = 'true'
903
+ process . env . INPUT_ALLOW_MULTIPLE_DOCUMENTS = 'false'
904
+ process . env . INPUT_FILES = tempFile
905
+ process . env . INPUT_BASE_DIR = '.'
906
+ process . env . INPUT_JSON_SCHEMA = ''
907
+
908
+ const result = await jsonValidator ( excludeMock )
909
+ expect ( result . passed + result . failed ) . toBeGreaterThan ( 0 )
910
+
911
+ // Cleanup
912
+ fs . unlinkSync ( tempFile )
913
+ } )
914
+
915
+ test ( 'edge case: malformed JSON in real file' , async ( ) => {
916
+ // Create a malformed JSON file
917
+ const fs = require ( 'fs' )
918
+ const tempFile = '/tmp/malformed.json'
919
+ fs . writeFileSync ( tempFile , '{"invalid": json, missing quotes}' )
920
+
921
+ process . env . INPUT_FILES = tempFile
922
+ process . env . INPUT_BASE_DIR = '.'
923
+ process . env . INPUT_JSON_SCHEMA = ''
924
+ process . env . INPUT_YAML_AS_JSON = 'false'
925
+
926
+ const result = await jsonValidator ( excludeMock )
927
+ expect ( result . failed ) . toBe ( 1 )
928
+ expect ( result . success ) . toBe ( false )
929
+
930
+ // Cleanup
931
+ fs . unlinkSync ( tempFile )
932
+ } )
0 commit comments