1package pgtype_test 2 3import ( 4 "math" 5 "reflect" 6 "testing" 7 8 "github.com/jackc/pgtype" 9 "github.com/jackc/pgtype/testutil" 10) 11 12func TestInt4ArrayTranscode(t *testing.T) { 13 testutil.TestSuccessfulTranscode(t, "int4[]", []interface{}{ 14 &pgtype.Int4Array{ 15 Elements: nil, 16 Dimensions: nil, 17 Status: pgtype.Present, 18 }, 19 &pgtype.Int4Array{ 20 Elements: []pgtype.Int4{ 21 {Int: 1, Status: pgtype.Present}, 22 {Status: pgtype.Null}, 23 }, 24 Dimensions: []pgtype.ArrayDimension{{Length: 2, LowerBound: 1}}, 25 Status: pgtype.Present, 26 }, 27 &pgtype.Int4Array{Status: pgtype.Null}, 28 &pgtype.Int4Array{ 29 Elements: []pgtype.Int4{ 30 {Int: 1, Status: pgtype.Present}, 31 {Int: 2, Status: pgtype.Present}, 32 {Int: 3, Status: pgtype.Present}, 33 {Int: 4, Status: pgtype.Present}, 34 {Status: pgtype.Null}, 35 {Int: 6, Status: pgtype.Present}, 36 }, 37 Dimensions: []pgtype.ArrayDimension{{Length: 3, LowerBound: 1}, {Length: 2, LowerBound: 1}}, 38 Status: pgtype.Present, 39 }, 40 &pgtype.Int4Array{ 41 Elements: []pgtype.Int4{ 42 {Int: 1, Status: pgtype.Present}, 43 {Int: 2, Status: pgtype.Present}, 44 {Int: 3, Status: pgtype.Present}, 45 {Int: 4, Status: pgtype.Present}, 46 }, 47 Dimensions: []pgtype.ArrayDimension{ 48 {Length: 2, LowerBound: 4}, 49 {Length: 2, LowerBound: 2}, 50 }, 51 Status: pgtype.Present, 52 }, 53 }) 54} 55 56func TestInt4ArraySet(t *testing.T) { 57 successfulTests := []struct { 58 source interface{} 59 result pgtype.Int4Array 60 expectedError bool 61 }{ 62 { 63 source: []int64{1}, 64 result: pgtype.Int4Array{ 65 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}}, 66 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}}, 67 Status: pgtype.Present}, 68 }, 69 { 70 source: []int32{1}, 71 result: pgtype.Int4Array{ 72 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}}, 73 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}}, 74 Status: pgtype.Present}, 75 }, 76 { 77 source: []int16{1}, 78 result: pgtype.Int4Array{ 79 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}}, 80 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}}, 81 Status: pgtype.Present}, 82 }, 83 { 84 source: []int{1}, 85 result: pgtype.Int4Array{ 86 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}}, 87 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}}, 88 Status: pgtype.Present}, 89 }, 90 { 91 source: []int{1, math.MaxInt32 + 1, 2}, 92 expectedError: true, 93 }, 94 { 95 source: []uint64{1}, 96 result: pgtype.Int4Array{ 97 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}}, 98 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}}, 99 Status: pgtype.Present}, 100 }, 101 { 102 source: []uint32{1}, 103 result: pgtype.Int4Array{ 104 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}}, 105 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}}, 106 Status: pgtype.Present}, 107 }, 108 { 109 source: []uint16{1}, 110 result: pgtype.Int4Array{ 111 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}}, 112 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}}, 113 Status: pgtype.Present}, 114 }, 115 { 116 source: (([]int32)(nil)), 117 result: pgtype.Int4Array{Status: pgtype.Null}, 118 }, 119 { 120 source: [][]int32{{1}, {2}}, 121 result: pgtype.Int4Array{ 122 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}, {Int: 2, Status: pgtype.Present}}, 123 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}}, 124 Status: pgtype.Present}, 125 }, 126 { 127 source: [][][][]int32{{{{1, 2, 3}}}, {{{4, 5, 6}}}}, 128 result: pgtype.Int4Array{ 129 Elements: []pgtype.Int4{ 130 {Int: 1, Status: pgtype.Present}, 131 {Int: 2, Status: pgtype.Present}, 132 {Int: 3, Status: pgtype.Present}, 133 {Int: 4, Status: pgtype.Present}, 134 {Int: 5, Status: pgtype.Present}, 135 {Int: 6, Status: pgtype.Present}}, 136 Dimensions: []pgtype.ArrayDimension{ 137 {LowerBound: 1, Length: 2}, 138 {LowerBound: 1, Length: 1}, 139 {LowerBound: 1, Length: 1}, 140 {LowerBound: 1, Length: 3}}, 141 Status: pgtype.Present}, 142 }, 143 { 144 source: [2][1]int32{{1}, {2}}, 145 result: pgtype.Int4Array{ 146 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}, {Int: 2, Status: pgtype.Present}}, 147 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}}, 148 Status: pgtype.Present}, 149 }, 150 { 151 source: [2][1][1][3]int32{{{{1, 2, 3}}}, {{{4, 5, 6}}}}, 152 result: pgtype.Int4Array{ 153 Elements: []pgtype.Int4{ 154 {Int: 1, Status: pgtype.Present}, 155 {Int: 2, Status: pgtype.Present}, 156 {Int: 3, Status: pgtype.Present}, 157 {Int: 4, Status: pgtype.Present}, 158 {Int: 5, Status: pgtype.Present}, 159 {Int: 6, Status: pgtype.Present}}, 160 Dimensions: []pgtype.ArrayDimension{ 161 {LowerBound: 1, Length: 2}, 162 {LowerBound: 1, Length: 1}, 163 {LowerBound: 1, Length: 1}, 164 {LowerBound: 1, Length: 3}}, 165 Status: pgtype.Present}, 166 }, 167 } 168 169 for i, tt := range successfulTests { 170 var r pgtype.Int4Array 171 err := r.Set(tt.source) 172 if err != nil { 173 if tt.expectedError { 174 continue 175 } 176 t.Errorf("%d: %v", i, err) 177 } 178 179 if tt.expectedError { 180 t.Errorf("%d: an error was expected, %v", i, tt) 181 continue 182 } 183 184 if !reflect.DeepEqual(r, tt.result) { 185 t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r) 186 } 187 } 188} 189 190func TestInt4ArrayAssignTo(t *testing.T) { 191 var int32Slice []int32 192 var uint32Slice []uint32 193 var namedInt32Slice _int32Slice 194 var int32SliceDim2 [][]int32 195 var int32SliceDim4 [][][][]int32 196 var int32ArrayDim2 [2][1]int32 197 var int32ArrayDim4 [2][1][1][3]int32 198 199 simpleTests := []struct { 200 src pgtype.Int4Array 201 dst interface{} 202 expected interface{} 203 }{ 204 { 205 src: pgtype.Int4Array{ 206 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}}, 207 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}}, 208 Status: pgtype.Present, 209 }, 210 dst: &int32Slice, 211 expected: []int32{1}, 212 }, 213 { 214 src: pgtype.Int4Array{ 215 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}}, 216 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}}, 217 Status: pgtype.Present, 218 }, 219 dst: &uint32Slice, 220 expected: []uint32{1}, 221 }, 222 { 223 src: pgtype.Int4Array{ 224 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}}, 225 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}}, 226 Status: pgtype.Present, 227 }, 228 dst: &namedInt32Slice, 229 expected: _int32Slice{1}, 230 }, 231 { 232 src: pgtype.Int4Array{Status: pgtype.Null}, 233 dst: &int32Slice, 234 expected: (([]int32)(nil)), 235 }, 236 { 237 src: pgtype.Int4Array{Status: pgtype.Present}, 238 dst: &int32Slice, 239 expected: []int32{}, 240 }, 241 { 242 src: pgtype.Int4Array{ 243 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}, {Int: 2, Status: pgtype.Present}}, 244 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}}, 245 Status: pgtype.Present}, 246 expected: [][]int32{{1}, {2}}, 247 dst: &int32SliceDim2, 248 }, 249 { 250 src: pgtype.Int4Array{ 251 Elements: []pgtype.Int4{ 252 {Int: 1, Status: pgtype.Present}, 253 {Int: 2, Status: pgtype.Present}, 254 {Int: 3, Status: pgtype.Present}, 255 {Int: 4, Status: pgtype.Present}, 256 {Int: 5, Status: pgtype.Present}, 257 {Int: 6, Status: pgtype.Present}}, 258 Dimensions: []pgtype.ArrayDimension{ 259 {LowerBound: 1, Length: 2}, 260 {LowerBound: 1, Length: 1}, 261 {LowerBound: 1, Length: 1}, 262 {LowerBound: 1, Length: 3}}, 263 Status: pgtype.Present}, 264 expected: [][][][]int32{{{{1, 2, 3}}}, {{{4, 5, 6}}}}, 265 dst: &int32SliceDim4, 266 }, 267 { 268 src: pgtype.Int4Array{ 269 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}, {Int: 2, Status: pgtype.Present}}, 270 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}}, 271 Status: pgtype.Present}, 272 expected: [2][1]int32{{1}, {2}}, 273 dst: &int32ArrayDim2, 274 }, 275 { 276 src: pgtype.Int4Array{ 277 Elements: []pgtype.Int4{ 278 {Int: 1, Status: pgtype.Present}, 279 {Int: 2, Status: pgtype.Present}, 280 {Int: 3, Status: pgtype.Present}, 281 {Int: 4, Status: pgtype.Present}, 282 {Int: 5, Status: pgtype.Present}, 283 {Int: 6, Status: pgtype.Present}}, 284 Dimensions: []pgtype.ArrayDimension{ 285 {LowerBound: 1, Length: 2}, 286 {LowerBound: 1, Length: 1}, 287 {LowerBound: 1, Length: 1}, 288 {LowerBound: 1, Length: 3}}, 289 Status: pgtype.Present}, 290 expected: [2][1][1][3]int32{{{{1, 2, 3}}}, {{{4, 5, 6}}}}, 291 dst: &int32ArrayDim4, 292 }, 293 } 294 295 for i, tt := range simpleTests { 296 err := tt.src.AssignTo(tt.dst) 297 if err != nil { 298 t.Errorf("%d: %v", i, err) 299 } 300 301 if dst := reflect.ValueOf(tt.dst).Elem().Interface(); !reflect.DeepEqual(dst, tt.expected) { 302 t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst) 303 } 304 } 305 306 errorTests := []struct { 307 src pgtype.Int4Array 308 dst interface{} 309 }{ 310 { 311 src: pgtype.Int4Array{ 312 Elements: []pgtype.Int4{{Status: pgtype.Null}}, 313 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}}, 314 Status: pgtype.Present, 315 }, 316 dst: &int32Slice, 317 }, 318 { 319 src: pgtype.Int4Array{ 320 Elements: []pgtype.Int4{{Int: -1, Status: pgtype.Present}}, 321 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}}, 322 Status: pgtype.Present, 323 }, 324 dst: &uint32Slice, 325 }, 326 { 327 src: pgtype.Int4Array{ 328 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}, {Int: 2, Status: pgtype.Present}}, 329 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}, {LowerBound: 1, Length: 2}}, 330 Status: pgtype.Present}, 331 dst: &int32ArrayDim2, 332 }, 333 { 334 src: pgtype.Int4Array{ 335 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}, {Int: 2, Status: pgtype.Present}}, 336 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}, {LowerBound: 1, Length: 2}}, 337 Status: pgtype.Present}, 338 dst: &int32Slice, 339 }, 340 { 341 src: pgtype.Int4Array{ 342 Elements: []pgtype.Int4{{Int: 1, Status: pgtype.Present}, {Int: 2, Status: pgtype.Present}}, 343 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}}, 344 Status: pgtype.Present}, 345 dst: &int32ArrayDim4, 346 }, 347 } 348 349 for i, tt := range errorTests { 350 err := tt.src.AssignTo(tt.dst) 351 if err == nil { 352 t.Errorf("%d: expected error but none was returned (%v -> %v)", i, tt.src, tt.dst) 353 } 354 } 355 356} 357