1 package pgtype_test
2
3 import (
4 "context"
5 "reflect"
6 "testing"
7
8 "github.com/jackc/pgtype"
9 "github.com/jackc/pgtype/testutil"
10 )
11
12 func TestEnumArrayTranscode(t *testing.T) {
13 setupConn := testutil.MustConnectPgx(t)
14 defer testutil.MustCloseContext(t, setupConn)
15
16 if _, err := setupConn.Exec(context.Background(), "drop type if exists color"); err != nil {
17 t.Fatal(err)
18 }
19 if _, err := setupConn.Exec(context.Background(), "create type color as enum ('red', 'green', 'blue')"); err != nil {
20 t.Fatal(err)
21 }
22
23 testutil.TestSuccessfulTranscode(t, "color[]", []interface{}{
24 &pgtype.EnumArray{
25 Elements: nil,
26 Dimensions: nil,
27 Status: pgtype.Present,
28 },
29 &pgtype.EnumArray{
30 Elements: []pgtype.GenericText{
31 {String: "red", Status: pgtype.Present},
32 {Status: pgtype.Null},
33 },
34 Dimensions: []pgtype.ArrayDimension{{Length: 2, LowerBound: 1}},
35 Status: pgtype.Present,
36 },
37 &pgtype.EnumArray{Status: pgtype.Null},
38 &pgtype.EnumArray{
39 Elements: []pgtype.GenericText{
40 {String: "red", Status: pgtype.Present},
41 {String: "green", Status: pgtype.Present},
42 {String: "blue", Status: pgtype.Present},
43 {String: "red", Status: pgtype.Present},
44 },
45 Dimensions: []pgtype.ArrayDimension{
46 {Length: 2, LowerBound: 4},
47 {Length: 2, LowerBound: 2},
48 },
49 Status: pgtype.Present,
50 },
51 })
52 }
53
54 func TestEnumArrayArraySet(t *testing.T) {
55 successfulTests := []struct {
56 source interface{}
57 result pgtype.EnumArray
58 }{
59 {
60 source: []string{"foo"},
61 result: pgtype.EnumArray{
62 Elements: []pgtype.GenericText{{String: "foo", Status: pgtype.Present}},
63 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
64 Status: pgtype.Present},
65 },
66 {
67 source: (([]string)(nil)),
68 result: pgtype.EnumArray{Status: pgtype.Null},
69 },
70 {
71 source: [][]string{{"foo"}, {"bar"}},
72 result: pgtype.EnumArray{
73 Elements: []pgtype.GenericText{{String: "foo", Status: pgtype.Present}, {String: "bar", Status: pgtype.Present}},
74 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
75 Status: pgtype.Present},
76 },
77 {
78 source: [][][][]string{{{{"foo", "bar", "baz"}}}, {{{"wibble", "wobble", "wubble"}}}},
79 result: pgtype.EnumArray{
80 Elements: []pgtype.GenericText{
81 {String: "foo", Status: pgtype.Present},
82 {String: "bar", Status: pgtype.Present},
83 {String: "baz", Status: pgtype.Present},
84 {String: "wibble", Status: pgtype.Present},
85 {String: "wobble", Status: pgtype.Present},
86 {String: "wubble", Status: pgtype.Present}},
87 Dimensions: []pgtype.ArrayDimension{
88 {LowerBound: 1, Length: 2},
89 {LowerBound: 1, Length: 1},
90 {LowerBound: 1, Length: 1},
91 {LowerBound: 1, Length: 3}},
92 Status: pgtype.Present},
93 },
94 {
95 source: [2][1]string{{"foo"}, {"bar"}},
96 result: pgtype.EnumArray{
97 Elements: []pgtype.GenericText{{String: "foo", Status: pgtype.Present}, {String: "bar", Status: pgtype.Present}},
98 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
99 Status: pgtype.Present},
100 },
101 {
102 source: [2][1][1][3]string{{{{"foo", "bar", "baz"}}}, {{{"wibble", "wobble", "wubble"}}}},
103 result: pgtype.EnumArray{
104 Elements: []pgtype.GenericText{
105 {String: "foo", Status: pgtype.Present},
106 {String: "bar", Status: pgtype.Present},
107 {String: "baz", Status: pgtype.Present},
108 {String: "wibble", Status: pgtype.Present},
109 {String: "wobble", Status: pgtype.Present},
110 {String: "wubble", Status: pgtype.Present}},
111 Dimensions: []pgtype.ArrayDimension{
112 {LowerBound: 1, Length: 2},
113 {LowerBound: 1, Length: 1},
114 {LowerBound: 1, Length: 1},
115 {LowerBound: 1, Length: 3}},
116 Status: pgtype.Present},
117 },
118 }
119
120 for i, tt := range successfulTests {
121 var r pgtype.EnumArray
122 err := r.Set(tt.source)
123 if err != nil {
124 t.Errorf("%d: %v", i, err)
125 }
126
127 if !reflect.DeepEqual(r, tt.result) {
128 t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r)
129 }
130 }
131 }
132
133 func TestEnumArrayArrayAssignTo(t *testing.T) {
134 var stringSlice []string
135 type _stringSlice []string
136 var namedStringSlice _stringSlice
137 var stringSliceDim2 [][]string
138 var stringSliceDim4 [][][][]string
139 var stringArrayDim2 [2][1]string
140 var stringArrayDim4 [2][1][1][3]string
141
142 simpleTests := []struct {
143 src pgtype.EnumArray
144 dst interface{}
145 expected interface{}
146 }{
147 {
148 src: pgtype.EnumArray{
149 Elements: []pgtype.GenericText{{String: "foo", Status: pgtype.Present}},
150 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
151 Status: pgtype.Present,
152 },
153 dst: &stringSlice,
154 expected: []string{"foo"},
155 },
156 {
157 src: pgtype.EnumArray{
158 Elements: []pgtype.GenericText{{String: "bar", Status: pgtype.Present}},
159 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
160 Status: pgtype.Present,
161 },
162 dst: &namedStringSlice,
163 expected: _stringSlice{"bar"},
164 },
165 {
166 src: pgtype.EnumArray{Status: pgtype.Null},
167 dst: &stringSlice,
168 expected: (([]string)(nil)),
169 },
170 {
171 src: pgtype.EnumArray{Status: pgtype.Present},
172 dst: &stringSlice,
173 expected: []string{},
174 },
175 {
176 src: pgtype.EnumArray{
177 Elements: []pgtype.GenericText{{String: "foo", Status: pgtype.Present}, {String: "bar", Status: pgtype.Present}},
178 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
179 Status: pgtype.Present},
180 dst: &stringSliceDim2,
181 expected: [][]string{{"foo"}, {"bar"}},
182 },
183 {
184 src: pgtype.EnumArray{
185 Elements: []pgtype.GenericText{
186 {String: "foo", Status: pgtype.Present},
187 {String: "bar", Status: pgtype.Present},
188 {String: "baz", Status: pgtype.Present},
189 {String: "wibble", Status: pgtype.Present},
190 {String: "wobble", Status: pgtype.Present},
191 {String: "wubble", Status: pgtype.Present}},
192 Dimensions: []pgtype.ArrayDimension{
193 {LowerBound: 1, Length: 2},
194 {LowerBound: 1, Length: 1},
195 {LowerBound: 1, Length: 1},
196 {LowerBound: 1, Length: 3}},
197 Status: pgtype.Present},
198 dst: &stringSliceDim4,
199 expected: [][][][]string{{{{"foo", "bar", "baz"}}}, {{{"wibble", "wobble", "wubble"}}}},
200 },
201 {
202 src: pgtype.EnumArray{
203 Elements: []pgtype.GenericText{{String: "foo", Status: pgtype.Present}, {String: "bar", Status: pgtype.Present}},
204 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
205 Status: pgtype.Present},
206 dst: &stringArrayDim2,
207 expected: [2][1]string{{"foo"}, {"bar"}},
208 },
209 {
210 src: pgtype.EnumArray{
211 Elements: []pgtype.GenericText{
212 {String: "foo", Status: pgtype.Present},
213 {String: "bar", Status: pgtype.Present},
214 {String: "baz", Status: pgtype.Present},
215 {String: "wibble", Status: pgtype.Present},
216 {String: "wobble", Status: pgtype.Present},
217 {String: "wubble", Status: pgtype.Present}},
218 Dimensions: []pgtype.ArrayDimension{
219 {LowerBound: 1, Length: 2},
220 {LowerBound: 1, Length: 1},
221 {LowerBound: 1, Length: 1},
222 {LowerBound: 1, Length: 3}},
223 Status: pgtype.Present},
224 dst: &stringArrayDim4,
225 expected: [2][1][1][3]string{{{{"foo", "bar", "baz"}}}, {{{"wibble", "wobble", "wubble"}}}},
226 },
227 }
228
229 for i, tt := range simpleTests {
230 err := tt.src.AssignTo(tt.dst)
231 if err != nil {
232 t.Errorf("%d: %v", i, err)
233 }
234
235 if dst := reflect.ValueOf(tt.dst).Elem().Interface(); !reflect.DeepEqual(dst, tt.expected) {
236 t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst)
237 }
238 }
239
240 errorTests := []struct {
241 src pgtype.EnumArray
242 dst interface{}
243 }{
244 {
245 src: pgtype.EnumArray{
246 Elements: []pgtype.GenericText{{Status: pgtype.Null}},
247 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
248 Status: pgtype.Present,
249 },
250 dst: &stringSlice,
251 },
252 {
253 src: pgtype.EnumArray{
254 Elements: []pgtype.GenericText{{String: "foo", Status: pgtype.Present}, {String: "bar", Status: pgtype.Present}},
255 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}, {LowerBound: 1, Length: 2}},
256 Status: pgtype.Present},
257 dst: &stringArrayDim2,
258 },
259 {
260 src: pgtype.EnumArray{
261 Elements: []pgtype.GenericText{{String: "foo", Status: pgtype.Present}, {String: "bar", Status: pgtype.Present}},
262 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}, {LowerBound: 1, Length: 2}},
263 Status: pgtype.Present},
264 dst: &stringSlice,
265 },
266 {
267 src: pgtype.EnumArray{
268 Elements: []pgtype.GenericText{{String: "foo", Status: pgtype.Present}, {String: "bar", Status: pgtype.Present}},
269 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
270 Status: pgtype.Present},
271 dst: &stringArrayDim4,
272 },
273 }
274
275 for i, tt := range errorTests {
276 err := tt.src.AssignTo(tt.dst)
277 if err == nil {
278 t.Errorf("%d: expected error but none was returned (%v -> %v)", i, tt.src, tt.dst)
279 }
280 }
281 }
282
View as plain text