1
16
17 package field
18
19 import (
20 "fmt"
21 "strings"
22 "testing"
23 )
24
25 func TestMakeFuncs(t *testing.T) {
26 testCases := []struct {
27 fn func() *Error
28 expected ErrorType
29 }{
30 {
31 func() *Error { return Invalid(NewPath("f"), "v", "d") },
32 ErrorTypeInvalid,
33 },
34 {
35 func() *Error { return NotSupported[string](NewPath("f"), "v", nil) },
36 ErrorTypeNotSupported,
37 },
38 {
39 func() *Error { return Duplicate(NewPath("f"), "v") },
40 ErrorTypeDuplicate,
41 },
42 {
43 func() *Error { return NotFound(NewPath("f"), "v") },
44 ErrorTypeNotFound,
45 },
46 {
47 func() *Error { return Required(NewPath("f"), "d") },
48 ErrorTypeRequired,
49 },
50 {
51 func() *Error { return InternalError(NewPath("f"), fmt.Errorf("e")) },
52 ErrorTypeInternal,
53 },
54 }
55
56 for _, testCase := range testCases {
57 err := testCase.fn()
58 if err.Type != testCase.expected {
59 t.Errorf("expected Type %q, got %q", testCase.expected, err.Type)
60 }
61 }
62 }
63
64 func TestErrorUsefulMessage(t *testing.T) {
65 {
66 s := Invalid(nil, nil, "").Error()
67 t.Logf("message: %v", s)
68 if !strings.Contains(s, "null") {
69 t.Errorf("error message did not contain 'null': %s", s)
70 }
71 }
72
73 s := Invalid(NewPath("foo"), "bar", "deet").Error()
74 t.Logf("message: %v", s)
75 for _, part := range []string{"foo", "bar", "deet", ErrorTypeInvalid.String()} {
76 if !strings.Contains(s, part) {
77 t.Errorf("error message did not contain expected part '%v'", part)
78 }
79 }
80
81 type complicated struct {
82 Baz int
83 Qux string
84 Inner interface{}
85 KV map[string]int
86 }
87 s = Invalid(
88 NewPath("foo"),
89 &complicated{
90 Baz: 1,
91 Qux: "aoeu",
92 Inner: &complicated{Qux: "asdf"},
93 KV: map[string]int{"Billy": 2},
94 },
95 "detail",
96 ).Error()
97 t.Logf("message: %v", s)
98 for _, part := range []string{
99 "foo", ErrorTypeInvalid.String(),
100 "Baz", "Qux", "Inner", "KV", "detail",
101 "1", "aoeu", "Billy", "2",
102
103 } {
104 if !strings.Contains(s, part) {
105 t.Errorf("error message did not contain expected part '%v'", part)
106 }
107 }
108 }
109
110 func TestToAggregate(t *testing.T) {
111 testCases := struct {
112 ErrList []ErrorList
113 NumExpectedErrs []int
114 }{
115 []ErrorList{
116 nil,
117 {},
118 {Invalid(NewPath("f"), "v", "d")},
119 {Invalid(NewPath("f"), "v", "d"), Invalid(NewPath("f"), "v", "d")},
120 {Invalid(NewPath("f"), "v", "d"), InternalError(NewPath(""), fmt.Errorf("e"))},
121 },
122 []int{
123 0,
124 0,
125 1,
126 1,
127 2,
128 },
129 }
130
131 if len(testCases.ErrList) != len(testCases.NumExpectedErrs) {
132 t.Errorf("Mismatch: length of NumExpectedErrs does not match length of ErrList")
133 }
134 for i, tc := range testCases.ErrList {
135 agg := tc.ToAggregate()
136 numErrs := 0
137
138 if agg != nil {
139 numErrs = len(agg.Errors())
140 }
141 if numErrs != testCases.NumExpectedErrs[i] {
142 t.Errorf("[%d] Expected %d, got %d", i, testCases.NumExpectedErrs[i], numErrs)
143 }
144
145 if len(tc) == 0 {
146 if agg != nil {
147 t.Errorf("[%d] Expected nil, got %#v", i, agg)
148 }
149 } else if agg == nil {
150 t.Errorf("[%d] Expected non-nil", i)
151 }
152 }
153 }
154
155 func TestErrListFilter(t *testing.T) {
156 list := ErrorList{
157 Invalid(NewPath("test.field"), "", ""),
158 Invalid(NewPath("field.test"), "", ""),
159 Duplicate(NewPath("test"), "value"),
160 }
161 if len(list.Filter(NewErrorTypeMatcher(ErrorTypeDuplicate))) != 2 {
162 t.Errorf("should not filter")
163 }
164 if len(list.Filter(NewErrorTypeMatcher(ErrorTypeInvalid))) != 1 {
165 t.Errorf("should filter")
166 }
167 }
168
169 func TestNotSupported(t *testing.T) {
170 notSupported := NotSupported(NewPath("f"), "v", []string{"a", "b", "c"})
171 expected := `Unsupported value: "v": supported values: "a", "b", "c"`
172 if notSupported.ErrorBody() != expected {
173 t.Errorf("Expected: %s\n, but got: %s\n", expected, notSupported.ErrorBody())
174 }
175 }
176
View as plain text