@@ -642,3 +642,287 @@ 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 ( 'ajv-formats will not be used with the json-validator' )
760
+ } )
761
+
762
+ test ( 'handles non-array data processing with single document YAML as JSON' , async ( ) => {
763
+ // This test covers the case where data is not initially an array (line 254)
764
+ process . env . INPUT_YAML_AS_JSON = 'true'
765
+ process . env . INPUT_ALLOW_MULTIPLE_DOCUMENTS = 'false' // This makes data not an array initially
766
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/yaml_as_json/valid'
767
+ process . env . INPUT_JSON_SCHEMA = ''
768
+
769
+ const result = await jsonValidator ( excludeMock )
770
+ expect ( result . success ) . toBe ( true )
771
+ expect ( result . passed ) . toBe ( 1 )
772
+
773
+ // This should trigger the Array.isArray check and the debug message
774
+ expect ( debugMock ) . toHaveBeenCalledWith (
775
+ expect . stringMatching ( '1 object\\(s\\) found in file:' )
776
+ )
777
+ } )
778
+
779
+ test ( 'edge case: empty json_exclude_regex with complex file structure' , async ( ) => {
780
+ process . env . INPUT_JSON_EXCLUDE_REGEX = ''
781
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/mixture'
782
+ process . env . INPUT_JSON_SCHEMA = ''
783
+
784
+ const result = await jsonValidator ( excludeMock )
785
+ expect ( result . passed + result . failed ) . toBeGreaterThan ( 0 )
786
+ } )
787
+
788
+ test ( 'edge case: complex file patterns with multiple extensions' , async ( ) => {
789
+ process . env . INPUT_FILES = '__tests__/fixtures/json/valid/*.json\n__tests__/fixtures/yaml_as_json/valid/*.yaml'
790
+ process . env . INPUT_YAML_AS_JSON = 'true'
791
+ process . env . INPUT_BASE_DIR = '.'
792
+ process . env . INPUT_JSON_SCHEMA = ''
793
+
794
+ const result = await jsonValidator ( excludeMock )
795
+ expect ( result . passed ) . toBeGreaterThan ( 0 )
796
+
797
+ expect ( debugMock ) . toHaveBeenCalledWith (
798
+ expect . stringMatching ( 'using files:' )
799
+ )
800
+ } )
801
+
802
+ test ( 'edge case: malformed custom regexp formats with complex patterns' , async ( ) => {
803
+ expect . assertions ( 1 )
804
+ try {
805
+ process . env . INPUT_AJV_CUSTOM_REGEXP_FORMATS = 'valid_format=^[a-z]+$\ninvalid-format'
806
+ await jsonValidator ( excludeMock )
807
+ } catch ( e ) {
808
+ expect ( e . message ) . toContain ( 'is not in expected format "key=regex"' )
809
+ }
810
+ } )
811
+
812
+ test ( 'edge case: schema file skipping logic' , async ( ) => {
813
+ process . env . INPUT_JSON_SCHEMA = '__tests__/fixtures/schemas/schema1.json'
814
+ process . env . INPUT_FILES = '__tests__/fixtures/schemas/schema1.json\n__tests__/fixtures/json/valid/json1.json'
815
+ process . env . INPUT_BASE_DIR = '.'
816
+
817
+ const result = await jsonValidator ( excludeMock )
818
+ expect ( result . passed ) . toBe ( 1 ) // Only json1.json should be processed, schema1.json should be skipped
819
+
820
+ expect ( debugMock ) . toHaveBeenCalledWith (
821
+ expect . stringMatching ( 'skipping json schema file:' )
822
+ )
823
+ } )
824
+
825
+ test ( 'stress test: large number of custom regex formats' , async ( ) => {
826
+ const formats = [ ]
827
+ for ( let i = 0 ; i < 10 ; i ++ ) {
828
+ formats . push ( `format${ i } =^test${ i } .*$` )
829
+ }
830
+
831
+ process . env . INPUT_AJV_CUSTOM_REGEXP_FORMATS = formats . join ( '\n' )
832
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/valid'
833
+ process . env . INPUT_JSON_SCHEMA = ''
834
+
835
+ const result = await jsonValidator ( excludeMock )
836
+ expect ( result . success ) . toBe ( true )
837
+ } )
838
+
839
+ test ( 'edge case: duplicate file processing prevention' , async ( ) => {
840
+ // Test that files are not processed multiple times
841
+ process . env . INPUT_FILES = '__tests__/fixtures/json/valid/json1.json\n__tests__/fixtures/json/valid/json1.json'
842
+ process . env . INPUT_BASE_DIR = '.'
843
+ process . env . INPUT_JSON_SCHEMA = ''
844
+
845
+ const result = await jsonValidator ( excludeMock )
846
+ expect ( result . passed ) . toBe ( 1 ) // Should only process the file once
847
+
848
+ expect ( debugMock ) . toHaveBeenCalledWith (
849
+ expect . stringMatching ( 'skipping duplicate file:' )
850
+ )
851
+ } )
852
+
853
+ test ( 'edge case: baseDir with trailing slash normalization' , async ( ) => {
854
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/json/valid/' // Note trailing slash
855
+ process . env . INPUT_JSON_SCHEMA = ''
856
+
857
+ const result = await jsonValidator ( excludeMock )
858
+ expect ( result . success ) . toBe ( true )
859
+ expect ( result . passed ) . toBe ( 1 )
860
+ } )
861
+
862
+ test ( 'real world scenario: large schema with draft-2019-09' , async ( ) => {
863
+ process . env . INPUT_JSON_SCHEMA_VERSION = 'draft-2019-09'
864
+ process . env . INPUT_JSON_SCHEMA = '__tests__/fixtures/schemas/challenge.json'
865
+ process . env . INPUT_BASE_DIR = '__tests__/fixtures/real_world/challenges'
866
+ process . env . INPUT_YAML_AS_JSON = 'true'
867
+
868
+ const result = await jsonValidator ( excludeMock )
869
+ expect ( result ) . toBeDefined ( )
870
+ expect ( typeof result . success ) . toBe ( 'boolean' )
871
+ } )
872
+
873
+ test ( 'edge case: potential non-array data with complex yaml parsing' , async ( ) => {
874
+ // Create a file with complex YAML that might not result in array
875
+ const fs = require ( 'fs' )
876
+ const tempFile = '/tmp/complex_yaml.yaml'
877
+ fs . writeFileSync ( tempFile , 'scalar_value' )
878
+
879
+ process . env . INPUT_YAML_AS_JSON = 'true'
880
+ process . env . INPUT_ALLOW_MULTIPLE_DOCUMENTS = 'false'
881
+ process . env . INPUT_FILES = tempFile
882
+ process . env . INPUT_BASE_DIR = '.'
883
+ process . env . INPUT_JSON_SCHEMA = ''
884
+
885
+ const result = await jsonValidator ( excludeMock )
886
+ expect ( result . passed ) . toBe ( 1 )
887
+
888
+ // Cleanup
889
+ fs . unlinkSync ( tempFile )
890
+ } )
891
+
892
+ test ( 'edge case: empty document processing' , async ( ) => {
893
+ // Create an empty YAML file
894
+ const fs = require ( 'fs' )
895
+ const tempFile = '/tmp/empty.yaml'
896
+ fs . writeFileSync ( tempFile , '' )
897
+
898
+ process . env . INPUT_YAML_AS_JSON = 'true'
899
+ process . env . INPUT_ALLOW_MULTIPLE_DOCUMENTS = 'false'
900
+ process . env . INPUT_FILES = tempFile
901
+ process . env . INPUT_BASE_DIR = '.'
902
+ process . env . INPUT_JSON_SCHEMA = ''
903
+
904
+ const result = await jsonValidator ( excludeMock )
905
+ expect ( result . passed + result . failed ) . toBeGreaterThan ( 0 )
906
+
907
+ // Cleanup
908
+ fs . unlinkSync ( tempFile )
909
+ } )
910
+
911
+ test ( 'edge case: malformed JSON in real file' , async ( ) => {
912
+ // Create a malformed JSON file
913
+ const fs = require ( 'fs' )
914
+ const tempFile = '/tmp/malformed.json'
915
+ fs . writeFileSync ( tempFile , '{"invalid": json, missing quotes}' )
916
+
917
+ process . env . INPUT_FILES = tempFile
918
+ process . env . INPUT_BASE_DIR = '.'
919
+ process . env . INPUT_JSON_SCHEMA = ''
920
+ process . env . INPUT_YAML_AS_JSON = 'false'
921
+
922
+ const result = await jsonValidator ( excludeMock )
923
+ expect ( result . failed ) . toBe ( 1 )
924
+ expect ( result . success ) . toBe ( false )
925
+
926
+ // Cleanup
927
+ fs . unlinkSync ( tempFile )
928
+ } )
0 commit comments