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