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
@@ -309,6 +309,22 @@ describe BSON::Decimal128 do
309
309
  it_behaves_like 'an initialized BSON::Decimal128'
310
310
  end
311
311
  end
312
+
313
+ context 'when range is exceeded' do
314
+ it 'raises InvalidRange' do
315
+ lambda do
316
+ described_class.new('1e10000')
317
+ end.should raise_error(BSON::Decimal128::InvalidRange, /Value out of range/)
318
+ end
319
+ end
320
+
321
+ context 'when precision is exceeded' do
322
+ it 'raises UnrepresentablePrecision' do
323
+ lambda do
324
+ described_class.new('1.000000000000000000000000000000000000000000000000001')
325
+ end.should raise_error(BSON::Decimal128::UnrepresentablePrecision, /The value contains too much precision/)
326
+ end
327
+ end
312
328
  end
313
329
 
314
330
  context 'when deserializing' do
@@ -1586,4 +1602,219 @@ describe BSON::Decimal128 do
1586
1602
  expect(registered).to eq(described_class)
1587
1603
  end
1588
1604
  end
1605
+
1606
+ %w(== ===).each do |eq_op|
1607
+ let(:lhs) { described_class.new('1.2e12') }
1608
+
1609
+ describe "##{eq_op}" do
1610
+ context 'when rhs is equal to lhs' do
1611
+ context 'when both are Decimal128 instances' do
1612
+ let(:rhs) { described_class.new('1.2e12') }
1613
+
1614
+ it 'is true' do
1615
+ (lhs == rhs).should be true
1616
+ end
1617
+ end
1618
+
1619
+ context 'when rhs is of a different type' do
1620
+ [
1621
+ 1200000000000,
1622
+ 1200000000000.0,
1623
+ BigDecimal('1.2e12'),
1624
+ ].each do |rhs|
1625
+ context "when rhs is #{rhs.class}" do
1626
+ it 'is true' do
1627
+ pending 'RUBY-2952'
1628
+
1629
+ (lhs == rhs).should be true
1630
+ end
1631
+ end
1632
+ end
1633
+ end
1634
+ end
1635
+
1636
+ context 'when rhs is not equal to lhs' do
1637
+ context 'when both are Decimal128 instances' do
1638
+ let(:rhs) { described_class.new('1.21e12') }
1639
+
1640
+ it 'is false' do
1641
+ (lhs == rhs).should be false
1642
+ end
1643
+ end
1644
+
1645
+ context 'when rhs is of a different type' do
1646
+
1647
+ [
1648
+ 1200000000001,
1649
+ 1200000000001.0,
1650
+ BigDecimal('1.21e12'),
1651
+ ].each do |rhs|
1652
+ context "when rhs is #{rhs.class}" do
1653
+ it 'is false' do
1654
+ (lhs == rhs).should be false
1655
+ end
1656
+ end
1657
+ end
1658
+ end
1659
+ end
1660
+ end
1661
+ end
1662
+
1663
+ describe "#<=>" do
1664
+
1665
+ let(:lhs) { described_class.new('1.2e12') }
1666
+
1667
+ context 'when lhs is less than rhs' do
1668
+ context 'when both are Decimal128 instances' do
1669
+ let(:rhs) { described_class.new('1.21e12') }
1670
+
1671
+ it 'is -1' do
1672
+ (lhs <=> rhs).should be -1
1673
+ end
1674
+ end
1675
+
1676
+ context 'when rhs is of a different type' do
1677
+ [
1678
+ 1200000000001,
1679
+ 1200000000001.0,
1680
+ BigDecimal('1.21e12'),
1681
+ ].each do |rhs|
1682
+ context "when rhs is #{rhs.class}" do
1683
+ it 'is -1' do
1684
+ (lhs <=> rhs).should be -1
1685
+ end
1686
+ end
1687
+ end
1688
+ end
1689
+ end
1690
+
1691
+ context 'when rhs is equal to lhs' do
1692
+ context 'when both are Decimal128 instances' do
1693
+ let(:rhs) { described_class.new('1.2e12') }
1694
+
1695
+ it 'is 0' do
1696
+ (lhs <=> rhs).should be 0
1697
+ end
1698
+ end
1699
+
1700
+ context 'when rhs is of a different type' do
1701
+
1702
+ [
1703
+ 1200000000000,
1704
+ 1200000000000.0,
1705
+ BigDecimal('1.2e12'),
1706
+ ].each do |rhs|
1707
+ context "when rhs is #{rhs.class}" do
1708
+ it 'is 0' do
1709
+ (lhs <=> rhs).should be 0
1710
+ end
1711
+ end
1712
+ end
1713
+ end
1714
+ end
1715
+
1716
+ context 'when rhs is greater than lhs' do
1717
+ context 'when both are Decimal128 instances' do
1718
+ let(:rhs) { described_class.new('1.1e12') }
1719
+
1720
+ it 'is 1' do
1721
+ (lhs <=> rhs).should be 1
1722
+ end
1723
+ end
1724
+
1725
+ context 'when rhs is of a different type' do
1726
+
1727
+ [
1728
+ 1100000000000,
1729
+ 1100000000000.0,
1730
+ BigDecimal('1.1e12'),
1731
+ ].each do |rhs|
1732
+ context "when rhs is #{rhs.class}" do
1733
+ it 'is 1' do
1734
+ (lhs <=> rhs).should be 1
1735
+ end
1736
+ end
1737
+ end
1738
+ end
1739
+ end
1740
+ end
1741
+
1742
+ describe "#<" do
1743
+
1744
+ let(:lhs) { described_class.new('1.2e12') }
1745
+
1746
+ context 'when lhs is less than rhs' do
1747
+ context 'when both are Decimal128 instances' do
1748
+ let(:rhs) { described_class.new('1.21e12') }
1749
+
1750
+ it 'is true' do
1751
+ (lhs < rhs).should be true
1752
+ end
1753
+ end
1754
+
1755
+ context 'when rhs is of a different type' do
1756
+ [
1757
+ 1200000000001,
1758
+ 1200000000001.0,
1759
+ BigDecimal('1.21e12'),
1760
+ ].each do |rhs|
1761
+ context "when rhs is #{rhs.class}" do
1762
+ it 'is true' do
1763
+ (lhs < rhs).should be true
1764
+ end
1765
+ end
1766
+ end
1767
+ end
1768
+ end
1769
+
1770
+ context 'when rhs is equal to lhs' do
1771
+ context 'when both are Decimal128 instances' do
1772
+ let(:rhs) { described_class.new('1.2e12') }
1773
+
1774
+ it 'is false' do
1775
+ (lhs < rhs).should be false
1776
+ end
1777
+ end
1778
+
1779
+ context 'when rhs is of a different type' do
1780
+
1781
+ [
1782
+ 1200000000000,
1783
+ 1200000000000.0,
1784
+ BigDecimal('1.2e12'),
1785
+ ].each do |rhs|
1786
+ context "when rhs is #{rhs.class}" do
1787
+ it 'is false' do
1788
+ (lhs < rhs).should be false
1789
+ end
1790
+ end
1791
+ end
1792
+ end
1793
+ end
1794
+
1795
+ context 'when rhs is greater than lhs' do
1796
+ context 'when both are Decimal128 instances' do
1797
+ let(:rhs) { described_class.new('1.1e12') }
1798
+
1799
+ it 'is false' do
1800
+ (lhs < rhs).should be false
1801
+ end
1802
+ end
1803
+
1804
+ context 'when rhs is of a different type' do
1805
+
1806
+ [
1807
+ 1100000000000,
1808
+ 1100000000000.0,
1809
+ BigDecimal('1.1e12'),
1810
+ ].each do |rhs|
1811
+ context "when rhs is #{rhs.class}" do
1812
+ it 'is false' do
1813
+ (lhs < rhs).should be false
1814
+ end
1815
+ end
1816
+ end
1817
+ end
1818
+ end
1819
+ end
1589
1820
  end
@@ -0,0 +1,46 @@
1
+ # Copyright (C) 2021 MongoDB Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require "spec_helper"
16
+
17
+ # BSON::Document ActiveSupport extensions
18
+ describe BSON::Document do
19
+ require_active_support
20
+
21
+ describe '#symbolize_keys' do
22
+ context 'string keys' do
23
+ let(:doc) do
24
+ described_class.new('foo' => 'bar')
25
+ end
26
+
27
+ it 'works correctly' do
28
+ doc.symbolize_keys.should == {foo: 'bar'}
29
+ end
30
+ end
31
+ end
32
+
33
+ describe '#symbolize_keys!' do
34
+ context 'string keys' do
35
+ let(:doc) do
36
+ described_class.new('foo' => 'bar')
37
+ end
38
+
39
+ it 'raises ArgumentError' do
40
+ lambda do
41
+ doc.symbolize_keys!
42
+ end.should raise_error(ArgumentError, /symbolize_keys! is not supported on BSON::Document instances/)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -215,6 +215,10 @@ describe BSON::Document do
215
215
 
216
216
  context "when provided string keys" do
217
217
 
218
+ it "is a BSON Document" do
219
+ expect(document.slice("key1")).to be_a(BSON::Document)
220
+ end
221
+
218
222
  it "returns the partial document" do
219
223
  expect(document.slice("key1")).to contain_exactly(['key1', 'value1'])
220
224
  end
@@ -222,13 +226,45 @@ describe BSON::Document do
222
226
 
223
227
  context "when provided symbol keys" do
224
228
 
229
+ it "is a BSON Document" do
230
+ expect(document.slice(:key1)).to be_a(BSON::Document)
231
+ end
232
+
225
233
  it "returns the partial document" do
226
234
  expect(document.slice(:key1)).to contain_exactly(['key1', 'value1'])
227
235
  end
228
236
  end
237
+
238
+ context "when provided keys that do not exist in the document" do
239
+
240
+ it "returns only the keys that exist in the document" do
241
+ expect(document.slice(:key1, :key3)).to contain_exactly(['key1', 'value1'])
242
+ end
243
+ end
244
+ end
245
+ end
246
+
247
+ describe "#except" do
248
+ let(:document) do
249
+ described_class.new("key1" => "value1", key2: "value2")
250
+ end
251
+
252
+ context "when provided string keys" do
253
+
254
+ it "returns the partial document" do
255
+ expect(document.except("key1")).to contain_exactly(['key2', 'value2'])
256
+ end
257
+ end
258
+
259
+ context "when provided symbol keys" do
260
+
261
+ it "returns the partial document" do
262
+ expect(document.except(:key1)).to contain_exactly(['key2', 'value2'])
263
+ end
229
264
  end
230
265
  end
231
266
 
267
+
232
268
  describe "#delete" do
233
269
 
234
270
  shared_examples_for "a document with deletable pairs" do
@@ -484,7 +520,13 @@ describe BSON::Document do
484
520
  context "when the document has been serialized" do
485
521
 
486
522
  let(:deserialized) do
487
- YAML.load(YAML.dump(doc))
523
+ if YAML.respond_to?(:unsafe_load)
524
+ # In psych >= 4.0.0 `load` is basically an alias to `safe_load`,
525
+ # which will fail here.
526
+ YAML.unsafe_load(YAML.dump(doc))
527
+ else
528
+ YAML.load(YAML.dump(doc))
529
+ end
488
530
  end
489
531
 
490
532
  let!(:enum) do
@@ -148,6 +148,7 @@ describe "BSON::ExtJSON.parse" do
148
148
  end
149
149
 
150
150
  let(:parsed) { BSON::ExtJSON.parse_obj(input, mode: mode) }
151
+ let(:mode) { :bson }
151
152
 
152
153
  context 'when mode is invalid' do
153
154
  let(:mode) { :foo }
@@ -158,6 +159,42 @@ describe "BSON::ExtJSON.parse" do
158
159
  end.should raise_error(ArgumentError, /Invalid value for :mode option/)
159
160
  end
160
161
  end
162
+
163
+ context 'when it contains a string key with a null byte' do
164
+ let(:input) do
165
+ { "key\x00" => 1 }
166
+ end
167
+
168
+ it 'raises an exception' do
169
+ lambda do
170
+ parsed
171
+ end.should raise_error(BSON::Error::ExtJSONParseError, /Hash key cannot contain a null byte/)
172
+ end
173
+ end
174
+
175
+ context 'when it contains a symbol key with a null byte' do
176
+ let(:input) do
177
+ { "key\x00".to_sym => 1 }
178
+ end
179
+
180
+ it 'raises an exception' do
181
+ lambda do
182
+ parsed
183
+ end.should raise_error(BSON::Error::ExtJSONParseError, /Hash key cannot contain a null byte/)
184
+ end
185
+ end
186
+
187
+ context 'when it contains an integer key' do
188
+ let(:input) do
189
+ { 0 => 1 }
190
+ end
191
+
192
+ it 'does not raises an exception' do
193
+ lambda do
194
+ parsed
195
+ end.should_not raise_error
196
+ end
197
+ end
161
198
  end
162
199
 
163
200
  context 'when input is a binary' do
@@ -0,0 +1,57 @@
1
+ # Copyright (C) 2021 MongoDB Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require "spec_helper"
16
+
17
+ describe 'Hash ActiveSupport extensions' do
18
+ require_active_support
19
+
20
+ describe '#symbolize_keys' do
21
+ let(:symbolized) { hash.symbolize_keys }
22
+
23
+ shared_examples 'works correctly' do
24
+ it 'returns a hash' do
25
+ symbolized.class.should be Hash
26
+ end
27
+
28
+ it 'works correctly' do
29
+ hash.symbolize_keys.should == {foo: 'bar'}
30
+ end
31
+ end
32
+
33
+ context 'string keys' do
34
+ let(:hash) do
35
+ {'foo' => 'bar'}
36
+ end
37
+
38
+ include_examples 'works correctly'
39
+ end
40
+
41
+ context 'symbol keys' do
42
+ let(:hash) do
43
+ {foo: 'bar'}
44
+ end
45
+
46
+ include_examples 'works correctly'
47
+ end
48
+
49
+ context 'both string and symbol keys' do
50
+ let(:hash) do
51
+ {'foo' => 42, foo: 'bar'}
52
+ end
53
+
54
+ include_examples 'works correctly'
55
+ end
56
+ end
57
+ end
@@ -227,6 +227,53 @@ describe Hash do
227
227
  end
228
228
  end
229
229
  end
230
+
231
+ context 'when hash contains value of an unserializable class' do
232
+ class HashSpecUnserializableClass
233
+ end
234
+
235
+ let(:obj) do
236
+ {foo: HashSpecUnserializableClass.new}
237
+ end
238
+
239
+ it 'raises UnserializableClass' do
240
+ lambda do
241
+ obj.to_bson
242
+ end.should raise_error(BSON::Error::UnserializableClass,
243
+ # C extension does not provide hash key in the exception message.
244
+ /(Hash value for key 'foo'|Value) does not define its BSON serialized type:.*HashSpecUnserializableClass/)
245
+ end
246
+ end
247
+
248
+ context 'when reading from a byte buffer that was previously written to' do
249
+ let(:buffer) do
250
+ {foo: 42}.to_bson
251
+ end
252
+
253
+ it 'returns the original hash' do
254
+ expect(Hash.from_bson(buffer)).to eq('foo' => 42)
255
+ end
256
+ end
257
+
258
+ context 'when round-tripping a BigDecimal' do
259
+ let(:to_bson) do
260
+ {"x" => BigDecimal('1')}.to_bson
261
+ end
262
+
263
+ let(:from_bson) do
264
+ Hash.from_bson(to_bson)
265
+ end
266
+
267
+ it 'doesn\'t raise on serialization' do
268
+ expect do
269
+ to_bson
270
+ end.to_not raise_error
271
+ end
272
+
273
+ it 'deserializes as a BSON::Decimal128' do
274
+ expect(from_bson).to eq({"x" => BSON::Decimal128.new('1')})
275
+ end
276
+ end
230
277
  end
231
278
 
232
279
  describe '#to_bson' do
@@ -292,5 +339,63 @@ describe Hash do
292
339
  end.not_to raise_error
293
340
  end
294
341
  end
342
+
343
+ context 'when serializing a hash with a BigDecimal' do
344
+ let(:hash) do
345
+ {'foo' => BigDecimal('1')}
346
+ end
347
+
348
+ it 'works' do
349
+ expect do
350
+ hash.to_bson
351
+ end.not_to raise_error
352
+ end
353
+ end
354
+ end
355
+
356
+ describe '#from_bson' do
357
+ context 'when bson document has duplicate keys' do
358
+ let(:buf) do
359
+ buf = BSON::ByteBuffer.new
360
+ buf.put_int32(37)
361
+ buf.put_byte("\x02")
362
+ buf.put_cstring('foo')
363
+ buf.put_string('bar')
364
+ buf.put_byte("\x02")
365
+ buf.put_cstring('foo')
366
+ buf.put_string('overwrite')
367
+ buf.put_byte("\x00")
368
+
369
+ BSON::ByteBuffer.new(buf.to_s)
370
+ end
371
+
372
+ let(:doc) { Hash.from_bson(buf) }
373
+
374
+ it 'overwrites first value with second value' do
375
+ doc.should == {'foo' => 'overwrite'}
376
+ end
377
+ end
378
+
379
+ context 'when bson document has string and symbol keys of the same name' do
380
+ let(:buf) do
381
+ buf = BSON::ByteBuffer.new
382
+ buf.put_int32(31)
383
+ buf.put_byte("\x02")
384
+ buf.put_cstring('foo')
385
+ buf.put_string('bar')
386
+ buf.put_byte("\x0e")
387
+ buf.put_cstring('foo')
388
+ buf.put_string('bar')
389
+ buf.put_byte("\x00")
390
+
391
+ BSON::ByteBuffer.new(buf.to_s)
392
+ end
393
+
394
+ let(:doc) { Hash.from_bson(buf) }
395
+
396
+ it 'overwrites first value with second value' do
397
+ doc.should == {'foo' => :bar}
398
+ end
399
+ end
295
400
  end
296
401
  end
@@ -106,18 +106,8 @@ describe BSON::Int64 do
106
106
  end
107
107
  end
108
108
 
109
- context "when using MRI < 2.4", if: (!BSON::Environment.jruby? && RUBY_VERSION < '2.4') do
110
-
111
- it "deserializes to a Fixnum object" do
112
- expect(described_class.from_bson(bson).class).to be(Fixnum)
113
- end
114
- end
115
-
116
- context "when using MRI >= 2.4", if: (!BSON::Environment.jruby? && RUBY_VERSION >= '2.4') do
117
-
118
- it "deserializes to an Integer object" do
119
- expect(described_class.from_bson(bson).class).to be(Integer)
120
- end
109
+ it "deserializes to an Integer object" do
110
+ expect(described_class.from_bson(bson).class).to be(Integer)
121
111
  end
122
112
  end
123
113
 
@@ -136,18 +126,8 @@ describe BSON::Int64 do
136
126
  end
137
127
  end
138
128
 
139
- context "when using MRI < 2.4", if: (!BSON::Environment.jruby? && RUBY_VERSION < '2.4') do
140
-
141
- it "deserializes to a Bignum object" do
142
- expect(described_class.from_bson(bson).class).to be(Bignum)
143
- end
144
- end
145
-
146
- context "when using MRI >= 2.4", if: (!BSON::Environment.jruby? && RUBY_VERSION >= '2.4') do
147
-
148
- it "deserializes to an Integer object" do
149
- expect(described_class.from_bson(bson).class).to be(Integer)
150
- end
129
+ it "deserializes to an Integer object" do
130
+ expect(described_class.from_bson(bson).class).to be(Integer)
151
131
  end
152
132
  end
153
133
  end
@@ -580,4 +580,21 @@ describe Regexp::Raw do
580
580
  end
581
581
  end
582
582
  end
583
- end
583
+
584
+ describe 'yaml loading' do
585
+ let(:regexp) { described_class.new('hello.world', 's') }
586
+
587
+ it 'round-trips' do
588
+ actual = if YAML.respond_to?(:unsafe_load)
589
+ # In psych >= 4.0.0 `load` is basically an alias to `safe_load`,
590
+ # which will fail here.
591
+ YAML.unsafe_load(regexp.to_yaml)
592
+ else
593
+ YAML.load(regexp.to_yaml)
594
+ end
595
+ actual.pattern.should == 'hello.world'
596
+ actual.options.should == 's'
597
+ actual.compile.should =~ "hello\nworld"
598
+ end
599
+ end
600
+ end