@@ -8,11 +8,16 @@ package mongo
8
8
9
9
import (
10
10
"errors"
11
+ "fmt"
11
12
"testing"
12
13
13
14
"github.com/google/go-cmp/cmp"
14
15
"github.com/mongodb/mongo-go-driver/bson"
16
+ "github.com/mongodb/mongo-go-driver/bson/bsoncodec"
17
+ "github.com/mongodb/mongo-go-driver/bson/bsontype"
18
+ "github.com/mongodb/mongo-go-driver/bson/primitive"
15
19
"github.com/mongodb/mongo-go-driver/x/bsonx"
20
+ "github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore"
16
21
)
17
22
18
23
func TestTransformDocument (t * testing.T ) {
@@ -62,6 +67,161 @@ func TestTransformDocument(t *testing.T) {
62
67
}
63
68
}
64
69
70
+ func TestTransformAggregatePipeline (t * testing.T ) {
71
+ index , arr := bsoncore .AppendArrayStart (nil )
72
+ dindex , arr := bsoncore .AppendDocumentElementStart (arr , "0" )
73
+ arr = bsoncore .AppendInt32Element (arr , "$limit" , 12345 )
74
+ arr , _ = bsoncore .AppendDocumentEnd (arr , dindex )
75
+ arr , _ = bsoncore .AppendArrayEnd (arr , index )
76
+
77
+ testCases := []struct {
78
+ name string
79
+ pipeline interface {}
80
+ arr bsonx.Arr
81
+ err error
82
+ }{
83
+ {"Pipeline/error" , Pipeline {{{"hello" , func () {}}}}, bsonx.Arr {}, MarshalError {Value : primitive.D {}}},
84
+ {
85
+ "Pipeline/success" ,
86
+ Pipeline {{{"hello" , "world" }}, {{"pi" , 3.14159 }}},
87
+ bsonx.Arr {
88
+ bsonx .Document (bsonx.Doc {{"hello" , bsonx .String ("world" )}}),
89
+ bsonx .Document (bsonx.Doc {{"pi" , bsonx .Double (3.14159 )}}),
90
+ },
91
+ nil ,
92
+ },
93
+ {
94
+ "bsonx.Arr" ,
95
+ bsonx.Arr {bsonx .Document (bsonx.Doc {{"$limit" , bsonx .Int32 (12345 )}})},
96
+ bsonx.Arr {bsonx .Document (bsonx.Doc {{"$limit" , bsonx .Int32 (12345 )}})},
97
+ nil ,
98
+ },
99
+ {
100
+ "[]bsonx.Doc" ,
101
+ []bsonx.Doc {{{"$limit" , bsonx .Int32 (12345 )}}},
102
+ bsonx.Arr {bsonx .Document (bsonx.Doc {{"$limit" , bsonx .Int32 (12345 )}})},
103
+ nil ,
104
+ },
105
+ {
106
+ "primitive.A/error" ,
107
+ primitive.A {"5" },
108
+ bsonx.Arr {},
109
+ MarshalError {Value : string ("" )},
110
+ },
111
+ {
112
+ "primitive.A/success" ,
113
+ primitive.A {bson.D {{"$limit" , int32 (12345 )}}, map [string ]interface {}{"$count" : "foobar" }},
114
+ bsonx.Arr {
115
+ bsonx .Document (bsonx.Doc {{"$limit" , bsonx .Int32 (12345 )}}),
116
+ bsonx .Document (bsonx.Doc {{"$count" , bsonx .String ("foobar" )}}),
117
+ },
118
+ nil ,
119
+ },
120
+ {
121
+ "bson.A/error" ,
122
+ bson.A {"5" },
123
+ bsonx.Arr {},
124
+ MarshalError {Value : string ("" )},
125
+ },
126
+ {
127
+ "bson.A/success" ,
128
+ bson.A {bson.D {{"$limit" , int32 (12345 )}}, map [string ]interface {}{"$count" : "foobar" }},
129
+ bsonx.Arr {
130
+ bsonx .Document (bsonx.Doc {{"$limit" , bsonx .Int32 (12345 )}}),
131
+ bsonx .Document (bsonx.Doc {{"$count" , bsonx .String ("foobar" )}}),
132
+ },
133
+ nil ,
134
+ },
135
+ {
136
+ "[]interface{}/error" ,
137
+ []interface {}{"5" },
138
+ bsonx.Arr {},
139
+ MarshalError {Value : string ("" )},
140
+ },
141
+ {
142
+ "[]interface{}/success" ,
143
+ []interface {}{bson.D {{"$limit" , int32 (12345 )}}, map [string ]interface {}{"$count" : "foobar" }},
144
+ bsonx.Arr {
145
+ bsonx .Document (bsonx.Doc {{"$limit" , bsonx .Int32 (12345 )}}),
146
+ bsonx .Document (bsonx.Doc {{"$count" , bsonx .String ("foobar" )}}),
147
+ },
148
+ nil ,
149
+ },
150
+ {
151
+ "bsoncodec.ValueMarshaler/MarshalBSONValue error" ,
152
+ bvMarsh {err : errors .New ("MarshalBSONValue error" )},
153
+ bsonx.Arr {},
154
+ errors .New ("MarshalBSONValue error" ),
155
+ },
156
+ {
157
+ "bsoncodec.ValueMarshaler/not array" ,
158
+ bvMarsh {t : bsontype .String },
159
+ bsonx.Arr {},
160
+ fmt .Errorf ("ValueMarshaler returned a %v, but was expecting %v" , bsontype .String , bsontype .Array ),
161
+ },
162
+ {
163
+ "bsoncodec.ValueMarshaler/UnmarshalBSONValue error" ,
164
+ bvMarsh {t : bsontype .Array },
165
+ bsonx.Arr {},
166
+ bsoncore .NewInsufficientBytesError (nil , nil ),
167
+ },
168
+ {
169
+ "bsoncodec.ValueMarshaler/success" ,
170
+ bvMarsh {t : bsontype .Array , data : arr },
171
+ bsonx.Arr {bsonx .Document (bsonx.Doc {{"$limit" , bsonx .Int32 (12345 )}})},
172
+ nil ,
173
+ },
174
+ {
175
+ "nil" ,
176
+ nil ,
177
+ bsonx.Arr {},
178
+ errors .New ("can only transform slices and arrays into aggregation pipelines, but got invalid" ),
179
+ },
180
+ {
181
+ "not array or slice" ,
182
+ int64 (42 ),
183
+ bsonx.Arr {},
184
+ errors .New ("can only transform slices and arrays into aggregation pipelines, but got int64" ),
185
+ },
186
+ {
187
+ "array/error" ,
188
+ [1 ]interface {}{int64 (42 )},
189
+ bsonx.Arr {},
190
+ MarshalError {Value : int64 (0 )},
191
+ },
192
+ {
193
+ "array/success" ,
194
+ [1 ]interface {}{primitive.D {{"$limit" , int64 (12345 )}}},
195
+ bsonx.Arr {bsonx .Document (bsonx.Doc {{"$limit" , bsonx .Int64 (12345 )}})},
196
+ nil ,
197
+ },
198
+ {
199
+ "slice/error" ,
200
+ []interface {}{int64 (42 )},
201
+ bsonx.Arr {},
202
+ MarshalError {Value : int64 (0 )},
203
+ },
204
+ {
205
+ "slice/success" ,
206
+ []interface {}{primitive.D {{"$limit" , int64 (12345 )}}},
207
+ bsonx.Arr {bsonx .Document (bsonx.Doc {{"$limit" , bsonx .Int64 (12345 )}})},
208
+ nil ,
209
+ },
210
+ }
211
+
212
+ for _ , tc := range testCases {
213
+ t .Run (tc .name , func (t * testing.T ) {
214
+ arr , err := transformAggregatePipeline (bson .NewRegistryBuilder ().Build (), tc .pipeline )
215
+ if ! cmp .Equal (err , tc .err , cmp .Comparer (compareErrors )) {
216
+ t .Errorf ("Error does not match expected error. got %v; want %v" , err , tc .err )
217
+ }
218
+ if ! cmp .Equal (arr , tc .arr , cmp .AllowUnexported (bsonx.Val {})) {
219
+ t .Errorf ("Returned array does not match expected array. got %v; want %v" , arr , tc .arr )
220
+ }
221
+ })
222
+ }
223
+ }
224
+
65
225
func compareErrors (err1 , err2 error ) bool {
66
226
if err1 == nil && err2 == nil {
67
227
return true
@@ -91,3 +251,15 @@ func (b bMarsh) MarshalBSON() ([]byte, error) {
91
251
type reflectStruct struct {
92
252
Foo string
93
253
}
254
+
255
+ var _ bsoncodec.ValueMarshaler = bvMarsh {}
256
+
257
+ type bvMarsh struct {
258
+ t bsontype.Type
259
+ data []byte
260
+ err error
261
+ }
262
+
263
+ func (b bvMarsh ) MarshalBSONValue () (bsontype.Type , []byte , error ) {
264
+ return b .t , b .data , b .err
265
+ }
0 commit comments