1
2
3
4
5
6
7 package bson
8
9 import (
10 "reflect"
11
12 "go.mongodb.org/mongo-driver/bson/bsonrw"
13 "go.mongodb.org/mongo-driver/bson/bsontype"
14 )
15
16 type unmarshalingTestCase struct {
17 name string
18 sType reflect.Type
19 want interface{}
20 data []byte
21 }
22
23 func unmarshalingTestCases() []unmarshalingTestCase {
24 var zeroPtrStruct unmarshalerPtrStruct
25 {
26 i := myInt64(0)
27 m := myMap{}
28 b := myBytes{}
29 s := myString("")
30 zeroPtrStruct = unmarshalerPtrStruct{I: &i, M: &m, B: &b, S: &s}
31 }
32
33 var zeroNonPtrStruct unmarshalerNonPtrStruct
34 {
35 i := myInt64(0)
36 m := myMap{}
37 b := myBytes{}
38 s := myString("")
39 zeroNonPtrStruct = unmarshalerNonPtrStruct{I: i, M: m, B: b, S: s}
40 }
41
42 var valPtrStruct unmarshalerPtrStruct
43 {
44 i := myInt64(5)
45 m := myMap{"key": "value"}
46 b := myBytes{0x00, 0x01}
47 s := myString("test")
48 valPtrStruct = unmarshalerPtrStruct{I: &i, M: &m, B: &b, S: &s}
49 }
50
51 var valNonPtrStruct unmarshalerNonPtrStruct
52 {
53 i := myInt64(5)
54 m := myMap{"key": "value"}
55 b := myBytes{0x00, 0x01}
56 s := myString("test")
57 valNonPtrStruct = unmarshalerNonPtrStruct{I: i, M: m, B: b, S: s}
58 }
59
60 type fooBytes struct {
61 Foo []byte
62 }
63
64 return []unmarshalingTestCase{
65 {
66 name: "small struct",
67 sType: reflect.TypeOf(struct {
68 Foo bool
69 }{}),
70 want: &struct {
71 Foo bool
72 }{Foo: true},
73 data: docToBytes(D{{"foo", true}}),
74 },
75 {
76 name: "nested document",
77 sType: reflect.TypeOf(struct {
78 Foo struct {
79 Bar bool
80 }
81 }{}),
82 want: &struct {
83 Foo struct {
84 Bar bool
85 }
86 }{
87 Foo: struct {
88 Bar bool
89 }{Bar: true},
90 },
91 data: docToBytes(D{{"foo", D{{"bar", true}}}}),
92 },
93 {
94 name: "simple array",
95 sType: reflect.TypeOf(struct {
96 Foo []bool
97 }{}),
98 want: &struct {
99 Foo []bool
100 }{
101 Foo: []bool{true},
102 },
103 data: docToBytes(D{{"foo", A{true}}}),
104 },
105 {
106 name: "struct with mixed case fields",
107 sType: reflect.TypeOf(struct {
108 FooBar int32
109 }{}),
110 want: &struct {
111 FooBar int32
112 }{
113 FooBar: 10,
114 },
115 data: docToBytes(D{{"fooBar", int32(10)}}),
116 },
117
118
119
120 {
121 name: "nil pointer fields with UnmarshalBSON function should marshal and unmarshal to the same values",
122 sType: reflect.TypeOf(unmarshalerPtrStruct{}),
123 want: &unmarshalerPtrStruct{},
124 data: docToBytes(unmarshalerPtrStruct{}),
125 },
126
127
128
129 {
130 name: "zero-value pointer fields with UnmarshalBSON function should marshal and unmarshal to the same values",
131 sType: reflect.TypeOf(unmarshalerPtrStruct{}),
132 want: &zeroPtrStruct,
133 data: docToBytes(zeroPtrStruct),
134 },
135
136
137
138 {
139 name: "non-zero-value pointer fields with UnmarshalBSON function should marshal and unmarshal to the same values",
140 sType: reflect.TypeOf(unmarshalerPtrStruct{}),
141 want: &valPtrStruct,
142 data: docToBytes(valPtrStruct),
143 },
144
145
146
147 {
148 name: "struct with byte slice",
149 sType: reflect.TypeOf(fooBytes{}),
150 want: &fooBytes{
151 Foo: []byte{0, 1, 2, 3, 4, 5},
152 },
153 data: docToBytes(fooBytes{
154 Foo: []byte{0, 1, 2, 3, 4, 5},
155 }),
156 },
157
158
159
160 {
161 name: `zero-value non-pointer fields with pointer UnmarshalBSON function should marshal and unmarshal to
162 the same values`,
163 sType: reflect.TypeOf(unmarshalerNonPtrStruct{}),
164 want: &zeroNonPtrStruct,
165 data: docToBytes(zeroNonPtrStruct),
166 },
167
168
169
170 {
171 name: `non-zero-value non-pointer fields with pointer UnmarshalBSON function should marshal and unmarshal
172 to the same values`,
173 sType: reflect.TypeOf(unmarshalerNonPtrStruct{}),
174 want: &valNonPtrStruct,
175 data: docToBytes(valNonPtrStruct),
176 },
177 }
178 }
179
180
181
182
183 type unmarshalerPtrStruct struct {
184 I *myInt64
185 M *myMap
186 B *myBytes
187 S *myString
188 }
189
190
191
192
193 type unmarshalerNonPtrStruct struct {
194 I myInt64
195 M myMap
196 B myBytes
197 S myString
198 }
199
200 type myInt64 int64
201
202 func (mi *myInt64) UnmarshalBSON(bytes []byte) error {
203 if len(bytes) == 0 {
204 return nil
205 }
206 i, err := bsonrw.NewBSONValueReader(bsontype.Int64, bytes).ReadInt64()
207 if err != nil {
208 return err
209 }
210 *mi = myInt64(i)
211 return nil
212 }
213
214 type myMap map[string]string
215
216 func (mm *myMap) UnmarshalBSON(bytes []byte) error {
217 if len(bytes) == 0 {
218 return nil
219 }
220 var m map[string]string
221 err := Unmarshal(bytes, &m)
222 *mm = myMap(m)
223 return err
224 }
225
226 type myBytes []byte
227
228 func (mb *myBytes) UnmarshalBSON(bytes []byte) error {
229 if len(bytes) == 0 {
230 return nil
231 }
232 b, _, err := bsonrw.NewBSONValueReader(bsontype.Binary, bytes).ReadBinary()
233 if err != nil {
234 return err
235 }
236 *mb = b
237 return nil
238 }
239
240 type myString string
241
242 func (ms *myString) UnmarshalBSON(bytes []byte) error {
243 if len(bytes) == 0 {
244 return nil
245 }
246 s, err := bsonrw.NewBSONValueReader(bsontype.String, bytes).ReadString()
247 if err != nil {
248 return err
249 }
250 *ms = myString(s)
251 return nil
252 }
253
View as plain text