@@ -166,3 +166,115 @@ func TestCachingDecodersNotSharedAcrossRegistries(t *testing.T) {
166
166
assert .Equal (t , int32 (- 1 ), * second .X , "expected X value to be -1, got %v" , * second .X )
167
167
})
168
168
}
169
+
170
+ func TestUnmarshalExtJSONWithUndefinedField (t * testing.T ) {
171
+ // When unmarshalling, fields that are undefined in the destination struct are skipped.
172
+ // This process must not skip other, defined fields and must not raise errors.
173
+ type expectedResponse struct {
174
+ DefinedField string
175
+ }
176
+
177
+ unmarshalExpectedResponse := func (t * testing.T , extJSON string ) * expectedResponse {
178
+ t .Helper ()
179
+ responseDoc := expectedResponse {}
180
+ err := UnmarshalExtJSON ([]byte (extJSON ), false , & responseDoc )
181
+ assert .Nil (t , err , "UnmarshalExtJSON error: %v" , err )
182
+ return & responseDoc
183
+ }
184
+
185
+ testCases := []struct {
186
+ name string
187
+ testJSON string
188
+ }{
189
+ {
190
+ "no array" ,
191
+ `{
192
+ "UndefinedField": {"key": 1},
193
+ "DefinedField": "value"
194
+ }` ,
195
+ },
196
+ {
197
+ "outer array" ,
198
+ `{
199
+ "UndefinedField": [{"key": 1}],
200
+ "DefinedField": "value"
201
+ }` ,
202
+ },
203
+ {
204
+ "embedded array" ,
205
+ `{
206
+ "UndefinedField": {"keys": [2]},
207
+ "DefinedField": "value"
208
+ }` ,
209
+ },
210
+ {
211
+ "outer array and embedded array" ,
212
+ `{
213
+ "UndefinedField": [{"keys": [2]}],
214
+ "DefinedField": "value"
215
+ }` ,
216
+ },
217
+ {
218
+ "embedded document" ,
219
+ `{
220
+ "UndefinedField": {"key": {"one": "two"}},
221
+ "DefinedField": "value"
222
+ }` ,
223
+ },
224
+ {
225
+ "doubly embedded document" ,
226
+ `{
227
+ "UndefinedField": {"key": {"one": {"two": "three"}}},
228
+ "DefinedField": "value"
229
+ }` ,
230
+ },
231
+ {
232
+ "embedded document and embedded array" ,
233
+ `{
234
+ "UndefinedField": {"key": {"one": {"two": [3]}}},
235
+ "DefinedField": "value"
236
+ }` ,
237
+ },
238
+ {
239
+ "embedded document and embedded array in outer array" ,
240
+ `{
241
+ "UndefinedField": [{"key": {"one": [3]}}],
242
+ "DefinedField": "value"
243
+ }` ,
244
+ },
245
+ {
246
+ "code with scope" ,
247
+ `{
248
+ "UndefinedField": {"logic": {"$code": "foo", "$scope": {"bar": 1}}},
249
+ "DefinedField": "value"
250
+ }` ,
251
+ },
252
+ {
253
+ "embedded array of code with scope" ,
254
+ `{
255
+ "UndefinedField": {"logic": [{"$code": "foo", "$scope": {"bar": 1}}]},
256
+ "DefinedField": "value"
257
+ }` ,
258
+ },
259
+ {
260
+ "type definition embedded document" ,
261
+ `{
262
+ "UndefinedField": {"myDouble": {"$numberDouble": "1.24"}},
263
+ "DefinedField": "value"
264
+ }` ,
265
+ },
266
+ {
267
+ "empty embedded document" ,
268
+ `{
269
+ "UndefinedField": {"empty": {}},
270
+ "DefinedField": "value"
271
+ }` ,
272
+ },
273
+ }
274
+ for _ , tc := range testCases {
275
+ t .Run (tc .name , func (t * testing.T ) {
276
+ responseDoc := unmarshalExpectedResponse (t , tc .testJSON )
277
+ assert .Equal (t , "value" , responseDoc .DefinedField , "expected DefinedField to be 'value', got %q" , responseDoc .DefinedField )
278
+ })
279
+ }
280
+ }
0 commit comments