1
2
3
4
5
6
7 package bsonrw
8
9 import (
10 "bytes"
11 "errors"
12 "fmt"
13 "testing"
14
15 "go.mongodb.org/mongo-driver/bson/bsontype"
16 "go.mongodb.org/mongo-driver/bson/primitive"
17 "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
18 )
19
20 func TestCopier(t *testing.T) {
21 t.Run("CopyDocument", func(t *testing.T) {
22 t.Run("ReadDocument Error", func(t *testing.T) {
23 want := errors.New("ReadDocumentError")
24 src := &TestValueReaderWriter{t: t, err: want, errAfter: llvrwReadDocument}
25 got := Copier{}.CopyDocument(nil, src)
26 if !compareErrors(got, want) {
27 t.Errorf("Did not receive correct error. got %v; want %v", got, want)
28 }
29 })
30 t.Run("WriteDocument Error", func(t *testing.T) {
31 want := errors.New("WriteDocumentError")
32 src := &TestValueReaderWriter{}
33 dst := &TestValueReaderWriter{t: t, err: want, errAfter: llvrwWriteDocument}
34 got := Copier{}.CopyDocument(dst, src)
35 if !compareErrors(got, want) {
36 t.Errorf("Did not receive correct error. got %v; want %v", got, want)
37 }
38 })
39 t.Run("success", func(t *testing.T) {
40 idx, doc := bsoncore.AppendDocumentStart(nil)
41 doc = bsoncore.AppendStringElement(doc, "Hello", "world")
42 doc, err := bsoncore.AppendDocumentEnd(doc, idx)
43 noerr(t, err)
44 src := newValueReader(doc)
45 dst := newValueWriterFromSlice(make([]byte, 0))
46 want := doc
47 err = Copier{}.CopyDocument(dst, src)
48 noerr(t, err)
49 got := dst.buf
50 if !bytes.Equal(got, want) {
51 t.Errorf("Bytes are not equal. got %v; want %v", got, want)
52 }
53 })
54 })
55 t.Run("copyArray", func(t *testing.T) {
56 t.Run("ReadArray Error", func(t *testing.T) {
57 want := errors.New("ReadArrayError")
58 src := &TestValueReaderWriter{t: t, err: want, errAfter: llvrwReadArray}
59 got := Copier{}.copyArray(nil, src)
60 if !compareErrors(got, want) {
61 t.Errorf("Did not receive correct error. got %v; want %v", got, want)
62 }
63 })
64 t.Run("WriteArray Error", func(t *testing.T) {
65 want := errors.New("WriteArrayError")
66 src := &TestValueReaderWriter{}
67 dst := &TestValueReaderWriter{t: t, err: want, errAfter: llvrwWriteArray}
68 got := Copier{}.copyArray(dst, src)
69 if !compareErrors(got, want) {
70 t.Errorf("Did not receive correct error. got %v; want %v", got, want)
71 }
72 })
73 t.Run("success", func(t *testing.T) {
74 idx, doc := bsoncore.AppendDocumentStart(nil)
75 aidx, doc := bsoncore.AppendArrayElementStart(doc, "foo")
76 doc = bsoncore.AppendStringElement(doc, "0", "Hello, world!")
77 doc, err := bsoncore.AppendArrayEnd(doc, aidx)
78 noerr(t, err)
79 doc, err = bsoncore.AppendDocumentEnd(doc, idx)
80 noerr(t, err)
81 src := newValueReader(doc)
82
83 _, err = src.ReadDocument()
84 noerr(t, err)
85 _, _, err = src.ReadElement()
86 noerr(t, err)
87
88 dst := newValueWriterFromSlice(make([]byte, 0))
89 _, err = dst.WriteDocument()
90 noerr(t, err)
91 _, err = dst.WriteDocumentElement("foo")
92 noerr(t, err)
93 want := doc
94
95 err = Copier{}.copyArray(dst, src)
96 noerr(t, err)
97
98 err = dst.WriteDocumentEnd()
99 noerr(t, err)
100
101 got := dst.buf
102 if !bytes.Equal(got, want) {
103 t.Errorf("Bytes are not equal. got %v; want %v", got, want)
104 }
105 })
106 })
107 t.Run("CopyValue", func(t *testing.T) {
108 testCases := []struct {
109 name string
110 dst *TestValueReaderWriter
111 src *TestValueReaderWriter
112 err error
113 }{
114 {
115 "Double/src/error",
116 &TestValueReaderWriter{},
117 &TestValueReaderWriter{bsontype: bsontype.Double, err: errors.New("1"), errAfter: llvrwReadDouble},
118 errors.New("1"),
119 },
120 {
121 "Double/dst/error",
122 &TestValueReaderWriter{bsontype: bsontype.Double, err: errors.New("2"), errAfter: llvrwWriteDouble},
123 &TestValueReaderWriter{bsontype: bsontype.Double, readval: float64(3.14159)},
124 errors.New("2"),
125 },
126 {
127 "String/src/error",
128 &TestValueReaderWriter{},
129 &TestValueReaderWriter{bsontype: bsontype.String, err: errors.New("1"), errAfter: llvrwReadString},
130 errors.New("1"),
131 },
132 {
133 "String/dst/error",
134 &TestValueReaderWriter{bsontype: bsontype.String, err: errors.New("2"), errAfter: llvrwWriteString},
135 &TestValueReaderWriter{bsontype: bsontype.String, readval: "hello, world"},
136 errors.New("2"),
137 },
138 {
139 "Document/src/error",
140 &TestValueReaderWriter{},
141 &TestValueReaderWriter{bsontype: bsontype.EmbeddedDocument, err: errors.New("1"), errAfter: llvrwReadDocument},
142 errors.New("1"),
143 },
144 {
145 "Array/dst/error",
146 &TestValueReaderWriter{},
147 &TestValueReaderWriter{bsontype: bsontype.Array, err: errors.New("2"), errAfter: llvrwReadArray},
148 errors.New("2"),
149 },
150 {
151 "Binary/src/error",
152 &TestValueReaderWriter{},
153 &TestValueReaderWriter{bsontype: bsontype.Binary, err: errors.New("1"), errAfter: llvrwReadBinary},
154 errors.New("1"),
155 },
156 {
157 "Binary/dst/error",
158 &TestValueReaderWriter{bsontype: bsontype.Binary, err: errors.New("2"), errAfter: llvrwWriteBinaryWithSubtype},
159 &TestValueReaderWriter{
160 bsontype: bsontype.Binary,
161 readval: bsoncore.Value{
162 Type: bsontype.Binary,
163 Data: []byte{0x03, 0x00, 0x00, 0x00, 0xFF, 0x01, 0x02, 0x03},
164 },
165 },
166 errors.New("2"),
167 },
168 {
169 "Undefined/src/error",
170 &TestValueReaderWriter{},
171 &TestValueReaderWriter{bsontype: bsontype.Undefined, err: errors.New("1"), errAfter: llvrwReadUndefined},
172 errors.New("1"),
173 },
174 {
175 "Undefined/dst/error",
176 &TestValueReaderWriter{bsontype: bsontype.Undefined, err: errors.New("2"), errAfter: llvrwWriteUndefined},
177 &TestValueReaderWriter{bsontype: bsontype.Undefined},
178 errors.New("2"),
179 },
180 {
181 "ObjectID/src/error",
182 &TestValueReaderWriter{},
183 &TestValueReaderWriter{bsontype: bsontype.ObjectID, err: errors.New("1"), errAfter: llvrwReadObjectID},
184 errors.New("1"),
185 },
186 {
187 "ObjectID/dst/error",
188 &TestValueReaderWriter{bsontype: bsontype.ObjectID, err: errors.New("2"), errAfter: llvrwWriteObjectID},
189 &TestValueReaderWriter{bsontype: bsontype.ObjectID, readval: primitive.ObjectID{0x01, 0x02, 0x03}},
190 errors.New("2"),
191 },
192 {
193 "Boolean/src/error",
194 &TestValueReaderWriter{},
195 &TestValueReaderWriter{bsontype: bsontype.Boolean, err: errors.New("1"), errAfter: llvrwReadBoolean},
196 errors.New("1"),
197 },
198 {
199 "Boolean/dst/error",
200 &TestValueReaderWriter{bsontype: bsontype.Boolean, err: errors.New("2"), errAfter: llvrwWriteBoolean},
201 &TestValueReaderWriter{bsontype: bsontype.Boolean, readval: bool(true)},
202 errors.New("2"),
203 },
204 {
205 "DateTime/src/error",
206 &TestValueReaderWriter{},
207 &TestValueReaderWriter{bsontype: bsontype.DateTime, err: errors.New("1"), errAfter: llvrwReadDateTime},
208 errors.New("1"),
209 },
210 {
211 "DateTime/dst/error",
212 &TestValueReaderWriter{bsontype: bsontype.DateTime, err: errors.New("2"), errAfter: llvrwWriteDateTime},
213 &TestValueReaderWriter{bsontype: bsontype.DateTime, readval: int64(1234567890)},
214 errors.New("2"),
215 },
216 {
217 "Null/src/error",
218 &TestValueReaderWriter{},
219 &TestValueReaderWriter{bsontype: bsontype.Null, err: errors.New("1"), errAfter: llvrwReadNull},
220 errors.New("1"),
221 },
222 {
223 "Null/dst/error",
224 &TestValueReaderWriter{bsontype: bsontype.Null, err: errors.New("2"), errAfter: llvrwWriteNull},
225 &TestValueReaderWriter{bsontype: bsontype.Null},
226 errors.New("2"),
227 },
228 {
229 "Regex/src/error",
230 &TestValueReaderWriter{},
231 &TestValueReaderWriter{bsontype: bsontype.Regex, err: errors.New("1"), errAfter: llvrwReadRegex},
232 errors.New("1"),
233 },
234 {
235 "Regex/dst/error",
236 &TestValueReaderWriter{bsontype: bsontype.Regex, err: errors.New("2"), errAfter: llvrwWriteRegex},
237 &TestValueReaderWriter{
238 bsontype: bsontype.Regex,
239 readval: bsoncore.Value{
240 Type: bsontype.Regex,
241 Data: bsoncore.AppendRegex(nil, "hello", "world"),
242 },
243 },
244 errors.New("2"),
245 },
246 {
247 "DBPointer/src/error",
248 &TestValueReaderWriter{},
249 &TestValueReaderWriter{bsontype: bsontype.DBPointer, err: errors.New("1"), errAfter: llvrwReadDBPointer},
250 errors.New("1"),
251 },
252 {
253 "DBPointer/dst/error",
254 &TestValueReaderWriter{bsontype: bsontype.DBPointer, err: errors.New("2"), errAfter: llvrwWriteDBPointer},
255 &TestValueReaderWriter{
256 bsontype: bsontype.DBPointer,
257 readval: bsoncore.Value{
258 Type: bsontype.DBPointer,
259 Data: bsoncore.AppendDBPointer(nil, "foo", primitive.ObjectID{0x01, 0x02, 0x03}),
260 },
261 },
262 errors.New("2"),
263 },
264 {
265 "Javascript/src/error",
266 &TestValueReaderWriter{},
267 &TestValueReaderWriter{bsontype: bsontype.JavaScript, err: errors.New("1"), errAfter: llvrwReadJavascript},
268 errors.New("1"),
269 },
270 {
271 "Javascript/dst/error",
272 &TestValueReaderWriter{bsontype: bsontype.JavaScript, err: errors.New("2"), errAfter: llvrwWriteJavascript},
273 &TestValueReaderWriter{bsontype: bsontype.JavaScript, readval: "hello, world"},
274 errors.New("2"),
275 },
276 {
277 "Symbol/src/error",
278 &TestValueReaderWriter{},
279 &TestValueReaderWriter{bsontype: bsontype.Symbol, err: errors.New("1"), errAfter: llvrwReadSymbol},
280 errors.New("1"),
281 },
282 {
283 "Symbol/dst/error",
284 &TestValueReaderWriter{bsontype: bsontype.Symbol, err: errors.New("2"), errAfter: llvrwWriteSymbol},
285 &TestValueReaderWriter{
286 bsontype: bsontype.Symbol,
287 readval: bsoncore.Value{
288 Type: bsontype.Symbol,
289 Data: bsoncore.AppendSymbol(nil, "hello, world"),
290 },
291 },
292 errors.New("2"),
293 },
294 {
295 "CodeWithScope/src/error",
296 &TestValueReaderWriter{},
297 &TestValueReaderWriter{bsontype: bsontype.CodeWithScope, err: errors.New("1"), errAfter: llvrwReadCodeWithScope},
298 errors.New("1"),
299 },
300 {
301 "CodeWithScope/dst/error",
302 &TestValueReaderWriter{bsontype: bsontype.CodeWithScope, err: errors.New("2"), errAfter: llvrwWriteCodeWithScope},
303 &TestValueReaderWriter{bsontype: bsontype.CodeWithScope},
304 errors.New("2"),
305 },
306 {
307 "CodeWithScope/dst/copyDocumentCore error",
308 &TestValueReaderWriter{err: errors.New("3"), errAfter: llvrwWriteDocumentElement},
309 &TestValueReaderWriter{bsontype: bsontype.CodeWithScope},
310 errors.New("3"),
311 },
312 {
313 "Int32/src/error",
314 &TestValueReaderWriter{},
315 &TestValueReaderWriter{bsontype: bsontype.Int32, err: errors.New("1"), errAfter: llvrwReadInt32},
316 errors.New("1"),
317 },
318 {
319 "Int32/dst/error",
320 &TestValueReaderWriter{bsontype: bsontype.Int32, err: errors.New("2"), errAfter: llvrwWriteInt32},
321 &TestValueReaderWriter{bsontype: bsontype.Int32, readval: int32(12345)},
322 errors.New("2"),
323 },
324 {
325 "Timestamp/src/error",
326 &TestValueReaderWriter{},
327 &TestValueReaderWriter{bsontype: bsontype.Timestamp, err: errors.New("1"), errAfter: llvrwReadTimestamp},
328 errors.New("1"),
329 },
330 {
331 "Timestamp/dst/error",
332 &TestValueReaderWriter{bsontype: bsontype.Timestamp, err: errors.New("2"), errAfter: llvrwWriteTimestamp},
333 &TestValueReaderWriter{
334 bsontype: bsontype.Timestamp,
335 readval: bsoncore.Value{
336 Type: bsontype.Timestamp,
337 Data: bsoncore.AppendTimestamp(nil, 12345, 67890),
338 },
339 },
340 errors.New("2"),
341 },
342 {
343 "Int64/src/error",
344 &TestValueReaderWriter{},
345 &TestValueReaderWriter{bsontype: bsontype.Int64, err: errors.New("1"), errAfter: llvrwReadInt64},
346 errors.New("1"),
347 },
348 {
349 "Int64/dst/error",
350 &TestValueReaderWriter{bsontype: bsontype.Int64, err: errors.New("2"), errAfter: llvrwWriteInt64},
351 &TestValueReaderWriter{bsontype: bsontype.Int64, readval: int64(1234567890)},
352 errors.New("2"),
353 },
354 {
355 "Decimal128/src/error",
356 &TestValueReaderWriter{},
357 &TestValueReaderWriter{bsontype: bsontype.Decimal128, err: errors.New("1"), errAfter: llvrwReadDecimal128},
358 errors.New("1"),
359 },
360 {
361 "Decimal128/dst/error",
362 &TestValueReaderWriter{bsontype: bsontype.Decimal128, err: errors.New("2"), errAfter: llvrwWriteDecimal128},
363 &TestValueReaderWriter{bsontype: bsontype.Decimal128, readval: primitive.NewDecimal128(12345, 67890)},
364 errors.New("2"),
365 },
366 {
367 "MinKey/src/error",
368 &TestValueReaderWriter{},
369 &TestValueReaderWriter{bsontype: bsontype.MinKey, err: errors.New("1"), errAfter: llvrwReadMinKey},
370 errors.New("1"),
371 },
372 {
373 "MinKey/dst/error",
374 &TestValueReaderWriter{bsontype: bsontype.MinKey, err: errors.New("2"), errAfter: llvrwWriteMinKey},
375 &TestValueReaderWriter{bsontype: bsontype.MinKey},
376 errors.New("2"),
377 },
378 {
379 "MaxKey/src/error",
380 &TestValueReaderWriter{},
381 &TestValueReaderWriter{bsontype: bsontype.MaxKey, err: errors.New("1"), errAfter: llvrwReadMaxKey},
382 errors.New("1"),
383 },
384 {
385 "MaxKey/dst/error",
386 &TestValueReaderWriter{bsontype: bsontype.MaxKey, err: errors.New("2"), errAfter: llvrwWriteMaxKey},
387 &TestValueReaderWriter{bsontype: bsontype.MaxKey},
388 errors.New("2"),
389 },
390 {
391 "Unknown BSON type error",
392 &TestValueReaderWriter{},
393 &TestValueReaderWriter{},
394 fmt.Errorf("Cannot copy unknown BSON type %s", bsontype.Type(0)),
395 },
396 }
397
398 for _, tc := range testCases {
399 t.Run(tc.name, func(t *testing.T) {
400 tc.dst.t, tc.src.t = t, t
401 err := Copier{}.CopyValue(tc.dst, tc.src)
402 if !compareErrors(err, tc.err) {
403 t.Errorf("Did not receive expected error. got %v; want %v", err, tc.err)
404 }
405 })
406 }
407 })
408 t.Run("CopyValueFromBytes", func(t *testing.T) {
409 t.Run("BytesWriter", func(t *testing.T) {
410 vw := newValueWriterFromSlice(make([]byte, 0))
411 _, err := vw.WriteDocument()
412 noerr(t, err)
413 _, err = vw.WriteDocumentElement("foo")
414 noerr(t, err)
415 err = Copier{}.CopyValueFromBytes(vw, bsontype.String, bsoncore.AppendString(nil, "bar"))
416 noerr(t, err)
417 err = vw.WriteDocumentEnd()
418 noerr(t, err)
419 var idx int32
420 want, err := bsoncore.AppendDocumentEnd(
421 bsoncore.AppendStringElement(
422 bsoncore.AppendDocumentStartInline(nil, &idx),
423 "foo", "bar",
424 ),
425 idx,
426 )
427 noerr(t, err)
428 got := vw.buf
429 if !bytes.Equal(got, want) {
430 t.Errorf("Bytes are not equal. got %v; want %v", got, want)
431 }
432 })
433 t.Run("Non BytesWriter", func(t *testing.T) {
434 llvrw := &TestValueReaderWriter{t: t}
435 err := Copier{}.CopyValueFromBytes(llvrw, bsontype.String, bsoncore.AppendString(nil, "bar"))
436 noerr(t, err)
437 got, want := llvrw.invoked, llvrwWriteString
438 if got != want {
439 t.Errorf("Incorrect method invoked on llvrw. got %v; want %v", got, want)
440 }
441 })
442 })
443 t.Run("CopyValueToBytes", func(t *testing.T) {
444 t.Run("BytesReader", func(t *testing.T) {
445 var idx int32
446 b, err := bsoncore.AppendDocumentEnd(
447 bsoncore.AppendStringElement(
448 bsoncore.AppendDocumentStartInline(nil, &idx),
449 "hello", "world",
450 ),
451 idx,
452 )
453 noerr(t, err)
454 vr := newValueReader(b)
455 _, err = vr.ReadDocument()
456 noerr(t, err)
457 _, _, err = vr.ReadElement()
458 noerr(t, err)
459 btype, got, err := Copier{}.CopyValueToBytes(vr)
460 noerr(t, err)
461 want := bsoncore.AppendString(nil, "world")
462 if btype != bsontype.String {
463 t.Errorf("Incorrect type returned. got %v; want %v", btype, bsontype.String)
464 }
465 if !bytes.Equal(got, want) {
466 t.Errorf("Bytes do not match. got %v; want %v", got, want)
467 }
468 })
469 t.Run("Non BytesReader", func(t *testing.T) {
470 llvrw := &TestValueReaderWriter{t: t, bsontype: bsontype.String, readval: "Hello, world!"}
471 btype, got, err := Copier{}.CopyValueToBytes(llvrw)
472 noerr(t, err)
473 want := bsoncore.AppendString(nil, "Hello, world!")
474 if btype != bsontype.String {
475 t.Errorf("Incorrect type returned. got %v; want %v", btype, bsontype.String)
476 }
477 if !bytes.Equal(got, want) {
478 t.Errorf("Bytes do not match. got %v; want %v", got, want)
479 }
480 })
481 })
482 t.Run("AppendValueBytes", func(t *testing.T) {
483 t.Run("BytesReader", func(t *testing.T) {
484 var idx int32
485 b, err := bsoncore.AppendDocumentEnd(
486 bsoncore.AppendStringElement(
487 bsoncore.AppendDocumentStartInline(nil, &idx),
488 "hello", "world",
489 ),
490 idx,
491 )
492 noerr(t, err)
493 vr := newValueReader(b)
494 _, err = vr.ReadDocument()
495 noerr(t, err)
496 _, _, err = vr.ReadElement()
497 noerr(t, err)
498 btype, got, err := Copier{}.AppendValueBytes(nil, vr)
499 noerr(t, err)
500 want := bsoncore.AppendString(nil, "world")
501 if btype != bsontype.String {
502 t.Errorf("Incorrect type returned. got %v; want %v", btype, bsontype.String)
503 }
504 if !bytes.Equal(got, want) {
505 t.Errorf("Bytes do not match. got %v; want %v", got, want)
506 }
507 })
508 t.Run("Non BytesReader", func(t *testing.T) {
509 llvrw := &TestValueReaderWriter{t: t, bsontype: bsontype.String, readval: "Hello, world!"}
510 btype, got, err := Copier{}.AppendValueBytes(nil, llvrw)
511 noerr(t, err)
512 want := bsoncore.AppendString(nil, "Hello, world!")
513 if btype != bsontype.String {
514 t.Errorf("Incorrect type returned. got %v; want %v", btype, bsontype.String)
515 }
516 if !bytes.Equal(got, want) {
517 t.Errorf("Bytes do not match. got %v; want %v", got, want)
518 }
519 })
520 t.Run("CopyValue error", func(t *testing.T) {
521 want := errors.New("CopyValue error")
522 llvrw := &TestValueReaderWriter{t: t, bsontype: bsontype.String, err: want, errAfter: llvrwReadString}
523 _, _, got := Copier{}.AppendValueBytes(make([]byte, 0), llvrw)
524 if !compareErrors(got, want) {
525 t.Errorf("Errors do not match. got %v; want %v", got, want)
526 }
527 })
528 })
529 }
530
View as plain text