1
2
3
4
5
6
7 package bson
8
9 import (
10 "io"
11 "testing"
12
13 "go.mongodb.org/mongo-driver/bson/bsontype"
14 "go.mongodb.org/mongo-driver/bson/primitive"
15 "go.mongodb.org/mongo-driver/internal/assert"
16 "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
17 )
18
19
20 type marshalValueInterfaceInner struct {
21 Foo int
22 }
23
24 var _ io.Reader = marshalValueInterfaceInner{}
25
26 func (marshalValueInterfaceInner) Read([]byte) (int, error) {
27 return 0, nil
28 }
29
30
31 type marshalValueInterfaceOuter struct {
32 Reader io.Reader
33 }
34
35
36 type marshalValueMarshaler struct {
37 Foo int
38 }
39
40 var _ ValueMarshaler = marshalValueMarshaler{}
41
42 func (mvi marshalValueMarshaler) MarshalBSONValue() (bsontype.Type, []byte, error) {
43 return bsontype.Int32, bsoncore.AppendInt32(nil, int32(mvi.Foo)), nil
44 }
45
46 var _ ValueUnmarshaler = &marshalValueMarshaler{}
47
48 func (mvi *marshalValueMarshaler) UnmarshalBSONValue(_ bsontype.Type, b []byte) error {
49 v, _, _ := bsoncore.ReadInt32(b)
50 mvi.Foo = int(v)
51 return nil
52 }
53
54 type marshalValueStruct struct {
55 Foo int
56 }
57
58 type marshalValueTestCase struct {
59 name string
60 val interface{}
61 bsontype bsontype.Type
62 bytes []byte
63 }
64
65 func newMarshalValueTestCases(t *testing.T) []marshalValueTestCase {
66 t.Helper()
67
68 var (
69 oid = primitive.NewObjectID()
70 regex = primitive.Regex{Pattern: "pattern", Options: "imx"}
71 dbPointer = primitive.DBPointer{DB: "db", Pointer: primitive.NewObjectID()}
72 codeWithScope = primitive.CodeWithScope{Code: "code", Scope: D{{"a", "b"}}}
73 decimal128 = primitive.NewDecimal128(5, 10)
74 structTest = marshalValueStruct{Foo: 10}
75 )
76 idx, scopeCore := bsoncore.AppendDocumentStart(nil)
77 scopeCore = bsoncore.AppendStringElement(scopeCore, "a", "b")
78 scopeCore, err := bsoncore.AppendDocumentEnd(scopeCore, idx)
79 assert.Nil(t, err, "Document error: %v", err)
80 structCore, err := Marshal(structTest)
81 assert.Nil(t, err, "Marshal error: %v", err)
82
83 return []marshalValueTestCase{
84 {"double", 3.14, bsontype.Double, bsoncore.AppendDouble(nil, 3.14)},
85 {"string", "hello world", bsontype.String, bsoncore.AppendString(nil, "hello world")},
86 {"binary", primitive.Binary{1, []byte{1, 2}}, bsontype.Binary, bsoncore.AppendBinary(nil, 1, []byte{1, 2})},
87 {"undefined", primitive.Undefined{}, bsontype.Undefined, []byte{}},
88 {"object id", oid, bsontype.ObjectID, bsoncore.AppendObjectID(nil, oid)},
89 {"boolean", true, bsontype.Boolean, bsoncore.AppendBoolean(nil, true)},
90 {"datetime", primitive.DateTime(5), bsontype.DateTime, bsoncore.AppendDateTime(nil, 5)},
91 {"null", primitive.Null{}, bsontype.Null, []byte{}},
92 {"regex", regex, bsontype.Regex, bsoncore.AppendRegex(nil, regex.Pattern, regex.Options)},
93 {"dbpointer", dbPointer, bsontype.DBPointer, bsoncore.AppendDBPointer(nil, dbPointer.DB, dbPointer.Pointer)},
94 {"javascript", primitive.JavaScript("js"), bsontype.JavaScript, bsoncore.AppendJavaScript(nil, "js")},
95 {"symbol", primitive.Symbol("symbol"), bsontype.Symbol, bsoncore.AppendSymbol(nil, "symbol")},
96 {"code with scope", codeWithScope, bsontype.CodeWithScope, bsoncore.AppendCodeWithScope(nil, "code", scopeCore)},
97 {"int32", 5, bsontype.Int32, bsoncore.AppendInt32(nil, 5)},
98 {"int64", int64(5), bsontype.Int64, bsoncore.AppendInt64(nil, 5)},
99 {"timestamp", primitive.Timestamp{T: 1, I: 5}, bsontype.Timestamp, bsoncore.AppendTimestamp(nil, 1, 5)},
100 {"decimal128", decimal128, bsontype.Decimal128, bsoncore.AppendDecimal128(nil, decimal128)},
101 {"min key", primitive.MinKey{}, bsontype.MinKey, []byte{}},
102 {"max key", primitive.MaxKey{}, bsontype.MaxKey, []byte{}},
103 {"struct", structTest, bsontype.EmbeddedDocument, structCore},
104 {"D", D{{"foo", int32(10)}}, bsontype.EmbeddedDocument, structCore},
105 {"M", M{"foo": int32(10)}, bsontype.EmbeddedDocument, structCore},
106 {"ValueMarshaler", marshalValueMarshaler{Foo: 10}, bsontype.Int32, bsoncore.AppendInt32(nil, 10)},
107 }
108
109 }
110
111 func newMarshalValueTestCasesWithInterfaceCore(t *testing.T) []marshalValueTestCase {
112 t.Helper()
113
114 marshalValueTestCases := newMarshalValueTestCases(t)
115
116 interfaceTest := marshalValueInterfaceOuter{
117 Reader: marshalValueInterfaceInner{
118 Foo: 10,
119 },
120 }
121 interfaceCore, err := Marshal(interfaceTest)
122 assert.Nil(t, err, "Marshal error: %v", err)
123
124 marshalValueTestCases = append(
125 marshalValueTestCases,
126 marshalValueTestCase{"interface", interfaceTest, bsontype.EmbeddedDocument, interfaceCore},
127 )
128
129 return marshalValueTestCases
130 }
131
View as plain text