map_test.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package valid
  2. import (
  3. "context"
  4. "testing"
  5. "github.com/stretchr/testify/assert"
  6. )
  7. func TestMap(t *testing.T) {
  8. var m0 map[string]interface{}
  9. m1 := map[string]interface{}{"A": "abc", "B": "xyz", "c": "abc", "D": (*string)(nil), "F": (*String123)(nil), "H": []string{"abc", "abc"}, "I": map[string]string{"foo": "abc"}}
  10. m2 := map[string]interface{}{"E": String123("xyz"), "F": (*String123)(nil)}
  11. m3 := map[string]interface{}{"M3": Model3{}}
  12. m4 := map[string]interface{}{"M3": Model3{A: "abc"}}
  13. m5 := map[string]interface{}{"A": "internal", "B": ""}
  14. m6 := map[int]string{11: "abc", 22: "xyz"}
  15. tests := []struct {
  16. tag string
  17. model interface{}
  18. rules []*KeyRules
  19. err string
  20. }{
  21. // empty rules
  22. {"t1.1", m1, []*KeyRules{}, ""},
  23. {"t1.2", m1, []*KeyRules{Key("A"), Key("B")}, ""},
  24. // normal rules
  25. {"t2.1", m1, []*KeyRules{Key("A", &validateAbc{}), Key("B", &validateXyz{})}, ""},
  26. {"t2.2", m1, []*KeyRules{Key("A", &validateXyz{}), Key("B", &validateAbc{})}, "A: error xyz; B: error abc."},
  27. {"t2.3", m1, []*KeyRules{Key("A", &validateXyz{}), Key("c", &validateXyz{})}, "A: error xyz; c: error xyz."},
  28. {"t2.4", m1, []*KeyRules{Key("D", Length(0, 5))}, ""},
  29. {"t2.5", m1, []*KeyRules{Key("F", Length(0, 5))}, ""},
  30. {"t2.6", m1, []*KeyRules{Key("H", Each(&validateAbc{})), Key("I", Each(&validateAbc{}))}, ""},
  31. {"t2.7", m1, []*KeyRules{Key("H", Each(&validateXyz{})), Key("I", Each(&validateXyz{}))}, "H: (0: error xyz; 1: error xyz.); I: (foo: error xyz.)."},
  32. {"t2.8", m1, []*KeyRules{Key("I", Map(Key("foo", &validateAbc{})))}, ""},
  33. {"t2.9", m1, []*KeyRules{Key("I", Map(Key("foo", &validateXyz{})))}, "I: (foo: error xyz.)."},
  34. // non-map value
  35. {"t3.1", &m1, []*KeyRules{}, ""},
  36. {"t3.2", nil, []*KeyRules{}, ErrNotMap.Error()},
  37. {"t3.3", m0, []*KeyRules{}, ""},
  38. {"t3.4", &m0, []*KeyRules{}, ""},
  39. {"t3.5", 123, []*KeyRules{}, ErrNotMap.Error()},
  40. // invalid key spec
  41. {"t4.1", m1, []*KeyRules{Key(123)}, "123: key not the correct type."},
  42. {"t4.2", m1, []*KeyRules{Key("X")}, "X: required key is missing."},
  43. {"t4.3", m1, []*KeyRules{Key("X").Optional()}, ""},
  44. // non-string keys
  45. {"t5.1", m6, []*KeyRules{Key(11, &validateAbc{}), Key(22, &validateXyz{})}, ""},
  46. {"t5.2", m6, []*KeyRules{Key(11, &validateXyz{}), Key(22, &validateAbc{})}, "11: error xyz; 22: error abc."},
  47. // validatable value
  48. {"t6.1", m2, []*KeyRules{Key("E")}, "E: error 123."},
  49. {"t6.2", m2, []*KeyRules{Key("E", Skip)}, ""},
  50. {"t6.3", m2, []*KeyRules{Key("E", Skip.When(true))}, ""},
  51. {"t6.4", m2, []*KeyRules{Key("E", Skip.When(false))}, "E: error 123."},
  52. // Required, NotNil
  53. {"t7.1", m2, []*KeyRules{Key("F", Required)}, "F: cannot be blank."},
  54. {"t7.2", m2, []*KeyRules{Key("F", NotNil)}, "F: is required."},
  55. {"t7.3", m2, []*KeyRules{Key("F", Skip, Required)}, ""},
  56. {"t7.4", m2, []*KeyRules{Key("F", Skip, NotNil)}, ""},
  57. {"t7.5", m2, []*KeyRules{Key("F", Skip.When(true), Required)}, ""},
  58. {"t7.6", m2, []*KeyRules{Key("F", Skip.When(true), NotNil)}, ""},
  59. {"t7.7", m2, []*KeyRules{Key("F", Skip.When(false), Required)}, "F: cannot be blank."},
  60. {"t7.8", m2, []*KeyRules{Key("F", Skip.When(false), NotNil)}, "F: is required."},
  61. // validatable structs
  62. {"t8.1", m3, []*KeyRules{Key("M3", Skip)}, ""},
  63. {"t8.2", m3, []*KeyRules{Key("M3")}, "M3: (A: error abc.)."},
  64. {"t8.3", m4, []*KeyRules{Key("M3")}, ""},
  65. // internal error
  66. {"t9.1", m5, []*KeyRules{Key("A", &validateAbc{}), Key("B", Required), Key("A", &validateInternalError{})}, "error internal"},
  67. }
  68. for _, test := range tests {
  69. err1 := Validate(test.model, Map(test.rules...).AllowExtraKeys())
  70. err2 := ValidateWithContext(context.Background(), test.model, Map(test.rules...).AllowExtraKeys())
  71. assertError(t, test.err, err1, test.tag)
  72. assertError(t, test.err, err2, test.tag)
  73. }
  74. a := map[string]interface{}{"Name": "name", "Value": "demo", "Extra": true}
  75. err := Validate(a, Map(
  76. Key("Name", Required),
  77. Key("Value", Required, Length(5, 10)),
  78. ))
  79. assert.EqualError(t, err, "Extra: key not expected; Value: the length must be between 5 and 10.")
  80. }
  81. func TestMapWithContext(t *testing.T) {
  82. m1 := map[string]interface{}{"A": "abc", "B": "xyz", "c": "abc", "g": "xyz"}
  83. m2 := map[string]interface{}{"A": "internal", "B": ""}
  84. tests := []struct {
  85. tag string
  86. model interface{}
  87. rules []*KeyRules
  88. err string
  89. }{
  90. // normal rules
  91. {"t1.1", m1, []*KeyRules{Key("A", &validateContextAbc{}), Key("B", &validateContextXyz{})}, ""},
  92. {"t1.2", m1, []*KeyRules{Key("A", &validateContextXyz{}), Key("B", &validateContextAbc{})}, "A: error xyz; B: error abc."},
  93. {"t1.3", m1, []*KeyRules{Key("A", &validateContextXyz{}), Key("c", &validateContextXyz{})}, "A: error xyz; c: error xyz."},
  94. {"t1.4", m1, []*KeyRules{Key("g", &validateContextAbc{})}, "g: error abc."},
  95. // skip rule
  96. {"t2.1", m1, []*KeyRules{Key("g", Skip, &validateContextAbc{})}, ""},
  97. {"t2.2", m1, []*KeyRules{Key("g", &validateContextAbc{}, Skip)}, "g: error abc."},
  98. // internal error
  99. {"t3.1", m2, []*KeyRules{Key("A", &validateContextAbc{}), Key("B", Required), Key("A", &validateInternalError{})}, "error internal"},
  100. }
  101. for _, test := range tests {
  102. err := ValidateWithContext(context.Background(), test.model, Map(test.rules...).AllowExtraKeys())
  103. assertError(t, test.err, err, test.tag)
  104. }
  105. a := map[string]interface{}{"Name": "name", "Value": "demo", "Extra": true}
  106. err := ValidateWithContext(context.Background(), a, Map(
  107. Key("Name", Required),
  108. Key("Value", Required, Length(5, 10)),
  109. ))
  110. if assert.NotNil(t, err) {
  111. assert.Equal(t, "Extra: key not expected; Value: the length must be between 5 and 10.", err.Error())
  112. }
  113. }