@@ -14753,3 +14753,223 @@ func TestOmitZeroWithMaps(t *testing.T) {
14753
14753
Equal (t , err2 , nil ) // No error
14754
14754
})
14755
14755
}
14756
+ func TestRequiredIfWithNilBytesSlice (t * testing.T ) {
14757
+ // Tests the behavior of required_if with nil byte slices
14758
+ type TextOrBytes struct {
14759
+ Text string `validate:"required_if=Bytes nil"`
14760
+ Bytes []byte `validate:"required_if=Text nil"`
14761
+ }
14762
+
14763
+ validate := New (WithRequiredStructEnabled ())
14764
+
14765
+ t .Run ("Text empty, Bytes empty but not nil" , func (t * testing.T ) {
14766
+ // Test 1: Text empty, Bytes empty but not nil
14767
+ obj := TextOrBytes {
14768
+ Text : "" ,
14769
+ Bytes : []byte {},
14770
+ }
14771
+ err := validate .Struct (obj )
14772
+
14773
+ Equal (t , err , nil ) // No error - Bytes is not nil, just empty
14774
+ })
14775
+
14776
+ t .Run ("Text empty, Bytes nil" , func (t * testing.T ) {
14777
+ // Test 2: Text empty, Bytes nil
14778
+ obj := TextOrBytes {
14779
+ Text : "" ,
14780
+ Bytes : nil ,
14781
+ }
14782
+ err := validate .Struct (obj )
14783
+
14784
+ NotEqual (t , err , nil ) // Error - Text is required when Bytes is nil
14785
+ })
14786
+
14787
+ t .Run ("Text populated, Bytes nil" , func (t * testing.T ) {
14788
+ // Test 3: Text populated, Bytes nil
14789
+ obj := TextOrBytes {
14790
+ Text : "Hello" ,
14791
+ Bytes : nil ,
14792
+ }
14793
+ err := validate .Struct (obj )
14794
+
14795
+ Equal (t , err , nil ) // No error - Text has value when Bytes is nil
14796
+ })
14797
+
14798
+ t .Run ("Text populated, Bytes empty but not nil" , func (t * testing.T ) {
14799
+ // Test 4: Text populated, Bytes empty but not nil
14800
+ obj := TextOrBytes {
14801
+ Text : "Hello" ,
14802
+ Bytes : []byte {},
14803
+ }
14804
+ err := validate .Struct (obj )
14805
+
14806
+ Equal (t , err , nil ) // No error - Neither field is nil
14807
+ })
14808
+
14809
+ t .Run ("Text empty, Bytes populated" , func (t * testing.T ) {
14810
+ // Test 5: Text empty, Bytes populated
14811
+ obj := TextOrBytes {
14812
+ Text : "" ,
14813
+ Bytes : []byte ("World" ),
14814
+ }
14815
+ err := validate .Struct (obj )
14816
+
14817
+ Equal (t , err , nil ) // No error - Bytes has value when Text is empty
14818
+ })
14819
+
14820
+ t .Run ("Both fields populated" , func (t * testing.T ) {
14821
+ // Test 6: Both fields populated
14822
+ obj := TextOrBytes {
14823
+ Text : "Hello" ,
14824
+ Bytes : []byte ("World" ),
14825
+ }
14826
+ err := validate .Struct (obj )
14827
+
14828
+ Equal (t , err , nil ) // No error - Both fields have values
14829
+ })
14830
+ }
14831
+ func TestRequiredIfWithMaps (t * testing.T ) {
14832
+ // Tests the behavior of required_if with maps
14833
+ type TextOrMap struct {
14834
+ Text string `validate:"required_if=Data nil"`
14835
+ Data map [string ]interface {} `validate:"required_if=Text nil"`
14836
+ }
14837
+
14838
+ validate := New (WithRequiredStructEnabled ())
14839
+
14840
+ t .Run ("Text empty, Map nil" , func (t * testing.T ) {
14841
+ // Test 1: Text empty, Map nil
14842
+ obj := TextOrMap {
14843
+ Text : "" ,
14844
+ Data : nil ,
14845
+ }
14846
+ err := validate .Struct (obj )
14847
+
14848
+ NotEqual (t , err , nil ) // Error - Text is required when Data is nil
14849
+ })
14850
+
14851
+ t .Run ("Text populated, Map nil" , func (t * testing.T ) {
14852
+ // Test 2: Text populated, Map nil
14853
+ obj := TextOrMap {
14854
+ Text : "Hello" ,
14855
+ Data : nil ,
14856
+ }
14857
+ err := validate .Struct (obj )
14858
+
14859
+ Equal (t , err , nil ) // No error - Text has value when Data is nil
14860
+ })
14861
+
14862
+ t .Run ("Text empty, Map empty but not nil" , func (t * testing.T ) {
14863
+ // Test 3: Text empty, Map empty but not nil
14864
+ obj := TextOrMap {
14865
+ Text : "" ,
14866
+ Data : map [string ]interface {}{},
14867
+ }
14868
+ err := validate .Struct (obj )
14869
+
14870
+ Equal (t , err , nil ) // No error - Data is not nil, just empty
14871
+ })
14872
+
14873
+ t .Run ("Text populated, Map empty but not nil" , func (t * testing.T ) {
14874
+ // Test 4: Text populated, Map empty but not nil
14875
+ obj := TextOrMap {
14876
+ Text : "Hello" ,
14877
+ Data : map [string ]interface {}{},
14878
+ }
14879
+ err := validate .Struct (obj )
14880
+
14881
+ Equal (t , err , nil ) // No error - Neither field is nil
14882
+ })
14883
+
14884
+ t .Run ("Text empty, Map populated" , func (t * testing.T ) {
14885
+ // Test 5: Text empty, Map populated
14886
+ obj := TextOrMap {
14887
+ Text : "" ,
14888
+ Data : map [string ]interface {}{"key" : "value" },
14889
+ }
14890
+ err := validate .Struct (obj )
14891
+
14892
+ Equal (t , err , nil ) // No error - Data has value when Text is empty
14893
+ })
14894
+
14895
+ t .Run ("Both fields populated" , func (t * testing.T ) {
14896
+ // Test 6: Both fields populated
14897
+ obj := TextOrMap {
14898
+ Text : "Hello" ,
14899
+ Data : map [string ]interface {}{"key" : "value" },
14900
+ }
14901
+ err := validate .Struct (obj )
14902
+
14903
+ Equal (t , err , nil ) // No error - Both fields have values
14904
+ })
14905
+ }
14906
+ func TestRequiredIfWithArrays (t * testing.T ) {
14907
+ // Tests the behavior of required_if with arrays
14908
+ type TextOrArray struct {
14909
+ Text string `validate:"required_if=Data 3"` // Check if array length is 3
14910
+ Data [3 ]string `validate:"required_if=Text nil"` // Check if Text is empty
14911
+ }
14912
+
14913
+ // Also test with a different length to verify behavior
14914
+ type TextOrSmallArray struct {
14915
+ Text string `validate:"required_if=Data 2"` // Check if array length is 2 (which it never will be for [3]string)
14916
+ Data [3 ]string `validate:"required_if=Text nil"` // Check if Text is empty
14917
+ }
14918
+
14919
+ validate := New (WithRequiredStructEnabled ())
14920
+
14921
+ t .Run ("Array length always matches declared size" , func (t * testing.T ) {
14922
+ // Test 1: Text empty, Array has length 3
14923
+ obj := TextOrArray {
14924
+ Text : "" ,
14925
+ Data : [3 ]string {}, // Zero values but length is 3
14926
+ }
14927
+ err := validate .Struct (obj )
14928
+
14929
+ NotEqual (t , err , nil ) // Error - Text is required when Data length equals 3
14930
+ })
14931
+
14932
+ t .Run ("Text populated, Array always has declared length" , func (t * testing.T ) {
14933
+ // Test 2: Text populated, Array has length 3
14934
+ obj := TextOrArray {
14935
+ Text : "Hello" ,
14936
+ Data : [3 ]string {},
14937
+ }
14938
+ err := validate .Struct (obj )
14939
+
14940
+ Equal (t , err , nil ) // No error - Text has value
14941
+ })
14942
+
14943
+ t .Run ("Length check that never matches doesn't trigger validation" , func (t * testing.T ) {
14944
+ // Test 3: Text empty, Array has length 3 but we check for length 2
14945
+ obj := TextOrSmallArray {
14946
+ Text : "" ,
14947
+ Data : [3 ]string {},
14948
+ }
14949
+ err := validate .Struct (obj )
14950
+
14951
+ Equal (t , err , nil ) // No error - Data length never equals 2
14952
+ })
14953
+
14954
+ t .Run ("Array values don't affect length check" , func (t * testing.T ) {
14955
+ // Test 4: Text empty, Array partially populated but still length 3
14956
+ obj := TextOrArray {
14957
+ Text : "" ,
14958
+ Data : [3 ]string {"One" , "Two" , "" },
14959
+ }
14960
+ err := validate .Struct (obj )
14961
+
14962
+ NotEqual (t , err , nil ) // Error - Text is required when Data length equals 3
14963
+ })
14964
+
14965
+ t .Run ("Array values with Text populated passes validation" , func (t * testing.T ) {
14966
+ // Test 5: Text populated, Array with values
14967
+ obj := TextOrArray {
14968
+ Text : "Hello" ,
14969
+ Data : [3 ]string {"One" , "Two" , "Three" },
14970
+ }
14971
+ err := validate .Struct (obj )
14972
+
14973
+ Equal (t , err , nil ) // No error - Text has value
14974
+ })
14975
+ }
0 commit comments