bson 4.9.0 → 4.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +15 -6
  4. data/ext/bson/bson-native.h +4 -0
  5. data/ext/bson/init.c +75 -23
  6. data/ext/bson/read.c +63 -11
  7. data/ext/bson/write.c +42 -3
  8. data/lib/bson/active_support.rb +1 -0
  9. data/lib/bson/array.rb +5 -1
  10. data/lib/bson/big_decimal.rb +67 -0
  11. data/lib/bson/binary.rb +8 -5
  12. data/lib/bson/boolean.rb +2 -1
  13. data/lib/bson/code.rb +2 -1
  14. data/lib/bson/code_with_scope.rb +2 -1
  15. data/lib/bson/config.rb +1 -0
  16. data/lib/bson/date.rb +1 -0
  17. data/lib/bson/date_time.rb +2 -1
  18. data/lib/bson/db_pointer.rb +2 -1
  19. data/lib/bson/dbref.rb +152 -0
  20. data/lib/bson/decimal128/builder.rb +27 -20
  21. data/lib/bson/decimal128.rb +39 -14
  22. data/lib/bson/document.rb +61 -18
  23. data/lib/bson/environment.rb +1 -0
  24. data/lib/bson/error.rb +13 -0
  25. data/lib/bson/ext_json.rb +24 -11
  26. data/lib/bson/false_class.rb +2 -1
  27. data/lib/bson/float.rb +21 -32
  28. data/lib/bson/hash.rb +18 -6
  29. data/lib/bson/int32.rb +3 -2
  30. data/lib/bson/int64.rb +3 -2
  31. data/lib/bson/integer.rb +3 -2
  32. data/lib/bson/json.rb +1 -0
  33. data/lib/bson/max_key.rb +3 -2
  34. data/lib/bson/min_key.rb +3 -2
  35. data/lib/bson/nil_class.rb +2 -1
  36. data/lib/bson/object.rb +1 -0
  37. data/lib/bson/object_id.rb +4 -3
  38. data/lib/bson/open_struct.rb +1 -0
  39. data/lib/bson/regexp.rb +24 -7
  40. data/lib/bson/registry.rb +1 -0
  41. data/lib/bson/specialized.rb +1 -0
  42. data/lib/bson/string.rb +3 -2
  43. data/lib/bson/symbol.rb +2 -1
  44. data/lib/bson/time.rb +4 -3
  45. data/lib/bson/time_with_zone.rb +1 -0
  46. data/lib/bson/timestamp.rb +7 -6
  47. data/lib/bson/true_class.rb +2 -1
  48. data/lib/bson/undefined.rb +2 -1
  49. data/lib/bson/version.rb +2 -1
  50. data/lib/bson.rb +8 -5
  51. data/spec/README.md +14 -0
  52. data/spec/bson/array_spec.rb +17 -0
  53. data/spec/bson/big_decimal_spec.rb +316 -0
  54. data/spec/bson/binary_spec.rb +1 -1
  55. data/spec/bson/binary_uuid_spec.rb +12 -0
  56. data/spec/bson/byte_buffer_read_spec.rb +59 -3
  57. data/spec/bson/byte_buffer_spec.rb +129 -6
  58. data/spec/bson/byte_buffer_write_spec.rb +96 -0
  59. data/spec/bson/date_time_spec.rb +53 -0
  60. data/spec/bson/dbref_legacy_spec.rb +169 -0
  61. data/spec/bson/dbref_spec.rb +487 -0
  62. data/spec/bson/decimal128_spec.rb +231 -0
  63. data/spec/bson/document_as_spec.rb +46 -0
  64. data/spec/bson/document_spec.rb +43 -1
  65. data/spec/bson/ext_json_parse_spec.rb +37 -0
  66. data/spec/bson/hash_as_spec.rb +57 -0
  67. data/spec/bson/hash_spec.rb +105 -0
  68. data/spec/bson/int64_spec.rb +4 -24
  69. data/spec/bson/raw_spec.rb +18 -1
  70. data/spec/bson/regexp_spec.rb +52 -0
  71. data/spec/runners/common_driver.rb +1 -1
  72. data/spec/shared/LICENSE +20 -0
  73. data/spec/shared/bin/get-mongodb-download-url +17 -0
  74. data/spec/shared/bin/s3-copy +45 -0
  75. data/spec/shared/bin/s3-upload +69 -0
  76. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  77. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  78. data/spec/shared/lib/mrss/constraints.rb +386 -0
  79. data/spec/shared/lib/mrss/docker_runner.rb +271 -0
  80. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  81. data/spec/shared/lib/mrss/lite_constraints.rb +191 -0
  82. data/spec/shared/lib/mrss/server_version_registry.rb +120 -0
  83. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  84. data/spec/shared/lib/mrss/utils.rb +15 -0
  85. data/spec/shared/share/Dockerfile.erb +338 -0
  86. data/spec/shared/share/haproxy-1.conf +16 -0
  87. data/spec/shared/share/haproxy-2.conf +17 -0
  88. data/spec/shared/shlib/distro.sh +74 -0
  89. data/spec/shared/shlib/server.sh +367 -0
  90. data/spec/shared/shlib/set_env.sh +131 -0
  91. data/spec/spec_helper.rb +31 -0
  92. data/spec/spec_tests/common_driver_spec.rb +2 -1
  93. data/spec/spec_tests/data/corpus/binary.json +33 -0
  94. data/spec/spec_tests/data/corpus/dbref.json +21 -1
  95. data/spec/spec_tests/data/corpus/document.json +4 -0
  96. data/spec/spec_tests/data/corpus/regex.json +2 -2
  97. data/spec/spec_tests/data/corpus/timestamp.json +10 -0
  98. data/spec/spec_tests/data/corpus/top.json +23 -12
  99. data/spec/support/spec_config.rb +8 -1
  100. data.tar.gz.sig +0 -0
  101. metadata +168 -93
  102. metadata.gz.sig +1 -0
@@ -0,0 +1,487 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require 'spec_helper'
5
+ require 'json'
6
+
7
+ describe BSON::DBRef do
8
+
9
+ let(:object_id) do
10
+ BSON::ObjectId.new
11
+ end
12
+
13
+ describe '#as_json' do
14
+
15
+ context 'when the database is not provided' do
16
+
17
+ let(:dbref) do
18
+ described_class.new({ '$ref' => 'users', '$id' => object_id })
19
+ end
20
+
21
+ it 'returns the json document without database' do
22
+ expect(dbref.as_json).to eq({ '$ref' => 'users', '$id' => object_id })
23
+ end
24
+ end
25
+
26
+ context 'when the database is provided' do
27
+
28
+ let(:dbref) do
29
+ described_class.new({ '$ref' => 'users', '$id' => object_id, '$db' => 'database' })
30
+ end
31
+
32
+ it 'returns the json document with database' do
33
+ expect(dbref.as_json).to eq({
34
+ '$ref' => 'users',
35
+ '$id' => object_id,
36
+ '$db' => 'database'
37
+ })
38
+ end
39
+ end
40
+
41
+ context 'when other keys are provided' do
42
+
43
+ let(:dbref) do
44
+ described_class.new({ '$ref' => 'users', '$id' => object_id, '$db' => 'database', 'x' => 'y' })
45
+ end
46
+
47
+ it 'returns the json document with the other keys' do
48
+ expect(dbref.as_json).to eq({
49
+ '$ref' => 'users',
50
+ '$id' => object_id,
51
+ '$db' => 'database',
52
+ 'x' => 'y'
53
+ })
54
+ end
55
+ end
56
+ end
57
+
58
+ describe '#initialize' do
59
+
60
+ let(:dbref) do
61
+ described_class.new(hash)
62
+ end
63
+
64
+ let(:hash) do
65
+ { '$ref' => 'users', '$id' => object_id }
66
+ end
67
+
68
+ it 'sets the collection' do
69
+ expect(dbref.collection).to eq('users')
70
+ end
71
+
72
+ it 'sets the id' do
73
+ expect(dbref.id).to eq(object_id)
74
+ end
75
+
76
+ context 'when first argument is a hash and two arguments are provided' do
77
+
78
+ let(:dbref) do
79
+ described_class.new({:$ref => 'users', :$id => object_id}, object_id)
80
+ end
81
+
82
+ it 'raises ArgumentError' do
83
+ lambda do
84
+ dbref
85
+ end.should raise_error(ArgumentError)
86
+ end
87
+ end
88
+
89
+ context 'when first argument is a hash and three arguments are provided' do
90
+
91
+ let(:dbref) do
92
+ described_class.new({:$ref => 'users', :$id => object_id}, object_id, 'db')
93
+ end
94
+
95
+ it 'raises ArgumentError' do
96
+ lambda do
97
+ dbref
98
+ end.should raise_error(ArgumentError)
99
+ end
100
+ end
101
+
102
+ context 'when a database is provided' do
103
+
104
+ let(:hash) do
105
+ { '$ref' => 'users', '$id' => object_id, '$db' => 'db' }
106
+ end
107
+
108
+ it 'sets the database' do
109
+ expect(dbref.database).to eq('db')
110
+ end
111
+ end
112
+
113
+ context 'when not providing a collection' do
114
+ let(:hash) do
115
+ { '$id' => object_id, '$db' => 'db' }
116
+ end
117
+
118
+ it 'raises an error' do
119
+ expect do
120
+ dbref
121
+ end.to raise_error(ArgumentError, /DBRef must have \$ref/)
122
+ end
123
+ end
124
+
125
+ context 'when not providing an id' do
126
+ let(:hash) do
127
+ { '$ref' => 'users', '$db' => 'db' }
128
+ end
129
+
130
+ it 'raises an error' do
131
+ expect do
132
+ dbref
133
+ end.to raise_error(ArgumentError, /DBRef must have \$id/)
134
+ end
135
+ end
136
+
137
+ context 'when providing an invalid type for ref' do
138
+ let(:hash) do
139
+ { '$ref' => 1, '$id' => object_id }
140
+ end
141
+
142
+ it 'raises an error' do
143
+ expect do
144
+ dbref
145
+ end.to raise_error(ArgumentError, /The value for key \$ref must be a string/)
146
+ end
147
+ end
148
+
149
+ context 'when providing an invalid type for database' do
150
+ let(:hash) do
151
+ { '$ref' => 'users', '$id' => object_id, '$db' => 1 }
152
+ end
153
+
154
+ it 'raises an error' do
155
+ expect do
156
+ dbref
157
+ end.to raise_error(ArgumentError, /The value for key \$db must be a string/)
158
+ end
159
+ end
160
+
161
+ context 'when providing the fieds as symbols' do
162
+ let(:hash) do
163
+ { :$ref => 'users', :$id => object_id, :$db => 'db' }
164
+ end
165
+
166
+ it 'does not raise an error' do
167
+ expect do
168
+ dbref
169
+ end.to_not raise_error
170
+ end
171
+ end
172
+
173
+ context 'when testing the ordering of the fields' do
174
+ context 'when the fields are in order' do
175
+ let(:hash) do
176
+ { '$ref' => 'users', '$id' => object_id, '$db' => 'db' }
177
+ end
178
+
179
+ it 'has the correct order' do
180
+ expect(dbref.keys).to eq(['$ref', '$id', '$db'])
181
+ end
182
+ end
183
+
184
+ context 'when the fields are out of order' do
185
+ let(:hash) do
186
+ { '$db' => 'db', '$id' => object_id, '$ref' => 'users' }
187
+ end
188
+
189
+ it 'has the correct order' do
190
+ expect(dbref.keys).to eq(['$ref', '$id', '$db'])
191
+ end
192
+ end
193
+
194
+ context 'when there is no db' do
195
+ let(:hash) do
196
+ { '$id' => object_id, '$ref' => 'users' }
197
+ end
198
+
199
+ it 'has the correct order' do
200
+ expect(dbref.keys).to eq(['$ref', '$id'])
201
+ end
202
+ end
203
+
204
+ context 'when the there are other fields in order' do
205
+ let(:hash) do
206
+ { '$ref' => 'users', '$id' => object_id, '$db' => 'db', 'x' => 'y', 'y' => 'z' }
207
+ end
208
+
209
+ it 'has the correct order' do
210
+ expect(dbref.keys).to eq(['$ref', '$id', '$db', 'x', 'y'])
211
+ end
212
+ end
213
+
214
+ context 'when the there are other fields out of order' do
215
+ let(:hash) do
216
+ { 'y' => 'z', '$db' => 'db', '$id' => object_id, 'x' => 'y', '$ref' => 'users' }
217
+ end
218
+
219
+ it 'has the correct order' do
220
+ expect(dbref.keys).to eq(['$ref', '$id', '$db', 'y', 'x'])
221
+ end
222
+ end
223
+ end
224
+ end
225
+
226
+ describe '#to_bson' do
227
+
228
+ let(:dbref) do
229
+ described_class.new({ '$ref' => 'users', '$id' => object_id, '$db' => 'database' })
230
+ end
231
+
232
+ it 'converts the underlying document to bson' do
233
+ expect(dbref.to_bson.to_s).to eq(dbref.as_json.to_bson.to_s)
234
+ end
235
+ end
236
+
237
+ describe '#to_json' do
238
+
239
+ context 'when the database is not provided' do
240
+
241
+ let(:dbref) do
242
+ described_class.new({ '$ref' => 'users', '$id' => object_id })
243
+ end
244
+
245
+ it 'returns the json document without database' do
246
+ expect(dbref.to_json).to eq("{\"$ref\":\"users\",\"$id\":#{object_id.to_json}}")
247
+ end
248
+ end
249
+
250
+ context 'when the database is provided' do
251
+
252
+ let(:dbref) do
253
+ described_class.new({ '$ref' => 'users', '$id' => object_id, '$db' => 'database' })
254
+ end
255
+
256
+ it 'returns the json document with database' do
257
+ expect(dbref.to_json).to eq("{\"$ref\":\"users\",\"$id\":#{object_id.to_json},\"$db\":\"database\"}")
258
+ end
259
+ end
260
+
261
+ context 'when other keys are provided' do
262
+
263
+ let(:dbref) do
264
+ described_class.new({ '$ref' => 'users', '$id' => object_id, '$db' => 'database', 'x' => 'y' })
265
+ end
266
+
267
+ it 'returns the json document with the other keys' do
268
+ expect(dbref.to_json).to eq("{\"$ref\":\"users\",\"$id\":#{object_id.to_json},\"$db\":\"database\",\"x\":\"y\"}")
269
+ end
270
+ end
271
+ end
272
+
273
+ describe '#from_bson' do
274
+
275
+ let(:buffer) do
276
+ hash.to_bson
277
+ end
278
+
279
+ let(:decoded) do
280
+ BSON::Document.from_bson(BSON::ByteBuffer.new(buffer.to_s))
281
+ end
282
+
283
+ context 'when a database exists' do
284
+
285
+ let(:hash) do
286
+ { '$ref' => 'users', '$id' => object_id, '$db' => 'database' }
287
+ end
288
+
289
+ it 'decodes the ref' do
290
+ expect(decoded.collection).to eq('users')
291
+ end
292
+
293
+ it 'decodes the id' do
294
+ expect(decoded.id).to eq(object_id)
295
+ end
296
+
297
+ it 'decodes the database' do
298
+ expect(decoded.database).to eq('database')
299
+ end
300
+
301
+ it 'is of class DBRef' do
302
+ expect(decoded).to be_a described_class
303
+ end
304
+ end
305
+
306
+ context 'when no database exists' do
307
+
308
+ let(:hash) do
309
+ { '$ref' => 'users', '$id' => object_id }
310
+ end
311
+
312
+ it 'decodes the ref' do
313
+ expect(decoded.collection).to eq('users')
314
+ end
315
+
316
+ it 'decodes the id' do
317
+ expect(decoded.id).to eq(object_id)
318
+ end
319
+
320
+ it 'sets the database to nil' do
321
+ expect(decoded.database).to be_nil
322
+ end
323
+
324
+ it 'is of class DBRef' do
325
+ expect(decoded).to be_a described_class
326
+ end
327
+ end
328
+
329
+ context 'when other keys exist' do
330
+
331
+ let(:hash) do
332
+ { '$ref' => 'users', '$id' => object_id, 'x' => 'y' }
333
+ end
334
+
335
+ it 'decodes the key' do
336
+ expect(decoded['x']).to eq('y')
337
+ end
338
+
339
+ it 'is of class DBRef' do
340
+ expect(decoded).to be_a described_class
341
+ end
342
+ end
343
+
344
+ context 'when it is an invalid dbref' do
345
+
346
+ shared_examples 'bson document' do
347
+ it 'should not raise' do
348
+ expect do
349
+ decoded
350
+ end.to_not raise_error
351
+ end
352
+
353
+ it 'has the correct class' do
354
+ expect(decoded).to be_a BSON::Document
355
+ expect(decoded).to_not be_a described_class
356
+ end
357
+ end
358
+
359
+ context 'when the hash has invalid collection type' do
360
+ let(:hash) do
361
+ { '$ref' => 1, '$id' => object_id }
362
+ end
363
+ include_examples 'bson document'
364
+ end
365
+
366
+ context 'when the hash has an invalid database type' do
367
+ let(:hash) do
368
+ { '$ref' => 'users', '$id' => object_id, '$db' => 1 }
369
+ end
370
+ include_examples 'bson document'
371
+ end
372
+
373
+ context 'when the hash is missing a collection' do
374
+ let(:hash) do
375
+ { '$id' => object_id }
376
+ end
377
+ include_examples 'bson document'
378
+ end
379
+
380
+ context 'when the hash is missing an id' do
381
+ let(:hash) do
382
+ { '$ref' => 'users' }
383
+ end
384
+ include_examples 'bson document'
385
+ end
386
+ end
387
+
388
+ context 'when nesting the dbref' do
389
+
390
+ context 'when it is a valid dbref' do
391
+ let(:hash) do
392
+ { 'dbref' => { '$ref' => 'users', '$id' => object_id } }
393
+ end
394
+
395
+ it 'should not raise' do
396
+ expect do
397
+ buffer
398
+ end.to_not raise_error
399
+ end
400
+
401
+ it 'has the correct class' do
402
+ expect(decoded['dbref']).to be_a described_class
403
+ end
404
+ end
405
+
406
+ context 'when it is an invalid dbref' do
407
+
408
+ shared_examples 'nested bson document' do
409
+ it 'should not raise' do
410
+ expect do
411
+ decoded
412
+ end.to_not raise_error
413
+ end
414
+
415
+ it 'has the correct class' do
416
+ expect(decoded['dbref']).to be_a BSON::Document
417
+ expect(decoded['dbref']).to_not be_a described_class
418
+ end
419
+ end
420
+
421
+ context 'when the hash has invalid collection type' do
422
+ let(:hash) do
423
+ { 'dbref' => { '$ref' => 1, '$id' => object_id } }
424
+ end
425
+ include_examples 'nested bson document'
426
+ end
427
+
428
+ context 'when the hash has an invalid database type' do
429
+ let(:hash) do
430
+ { 'dbref' => { '$ref' => 'users', '$id' => object_id, '$db' => 1 } }
431
+ end
432
+ include_examples 'nested bson document'
433
+ end
434
+
435
+ context 'when the hash is missing a collection' do
436
+ let(:hash) do
437
+ { 'dbref' => { '$id' => object_id } }
438
+ end
439
+ include_examples 'nested bson document'
440
+ end
441
+
442
+ context 'when the hash is missing an id' do
443
+ let(:hash) do
444
+ { 'dbref' => { '$ref' => 'users' } }
445
+ end
446
+ include_examples 'nested bson document'
447
+ end
448
+ end
449
+ end
450
+
451
+ context 'when nesting a dbref inside a dbref' do
452
+ context 'when it is a valid dbref' do
453
+ let(:hash) do
454
+ { 'dbref1' => { '$ref' => 'users', '$id' => object_id, 'dbref2' => { '$ref' => 'users', '$id' => object_id } } }
455
+ end
456
+
457
+ it 'should not raise' do
458
+ expect do
459
+ buffer
460
+ end.to_not raise_error
461
+ end
462
+
463
+ it 'has the correct class' do
464
+ expect(decoded['dbref1']).to be_a described_class
465
+ expect(decoded['dbref1']['dbref2']).to be_a described_class
466
+ end
467
+ end
468
+
469
+ context 'when it is an invalid dbref' do
470
+ let(:hash) do
471
+ { 'dbref' => { '$ref' => 'users', '$id' => object_id, 'dbref' => { '$ref' => 1, '$id' => object_id } } }
472
+ end
473
+
474
+ it 'should not raise' do
475
+ expect do
476
+ decoded
477
+ end.to_not raise_error
478
+ end
479
+
480
+ it 'has the correct class' do
481
+ expect(decoded['dbref']).to be_a described_class
482
+ expect(decoded['dbref']['dbref']).to be_a BSON::Document
483
+ end
484
+ end
485
+ end
486
+ end
487
+ end