bson 4.1.1-java → 4.2.0-java

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 (82) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +18 -3
  5. data/lib/bson-ruby.jar +0 -0
  6. data/lib/bson.rb +6 -4
  7. data/lib/bson/array.rb +1 -1
  8. data/lib/bson/binary.rb +4 -2
  9. data/lib/bson/code.rb +1 -1
  10. data/lib/bson/code_with_scope.rb +1 -1
  11. data/lib/bson/config.rb +1 -1
  12. data/lib/bson/date.rb +1 -1
  13. data/lib/bson/date_time.rb +1 -1
  14. data/lib/bson/decimal128.rb +318 -0
  15. data/lib/bson/decimal128/builder.rb +448 -0
  16. data/lib/bson/document.rb +2 -2
  17. data/lib/bson/environment.rb +13 -1
  18. data/lib/bson/false_class.rb +1 -1
  19. data/lib/bson/float.rb +1 -1
  20. data/lib/bson/hash.rb +1 -1
  21. data/lib/bson/int32.rb +46 -0
  22. data/lib/bson/int64.rb +46 -0
  23. data/lib/bson/integer.rb +1 -1
  24. data/lib/bson/max_key.rb +1 -1
  25. data/lib/bson/min_key.rb +1 -1
  26. data/lib/bson/object_id.rb +3 -2
  27. data/lib/bson/open_struct.rb +57 -0
  28. data/lib/bson/regexp.rb +87 -19
  29. data/lib/bson/registry.rb +1 -1
  30. data/lib/bson/specialized.rb +1 -1
  31. data/lib/bson/string.rb +1 -1
  32. data/lib/bson/symbol.rb +1 -1
  33. data/lib/bson/time.rb +1 -1
  34. data/lib/bson/timestamp.rb +2 -2
  35. data/lib/bson/true_class.rb +1 -1
  36. data/lib/bson/version.rb +2 -2
  37. data/spec/bson/array_spec.rb +1 -1
  38. data/spec/bson/binary_spec.rb +2 -1
  39. data/spec/bson/corpus_spec.rb +68 -0
  40. data/spec/bson/decimal128_spec.rb +1583 -0
  41. data/spec/bson/document_spec.rb +1 -1
  42. data/spec/bson/driver_bson_spec.rb +77 -0
  43. data/spec/bson/int32_spec.rb +58 -0
  44. data/spec/bson/int64_spec.rb +58 -0
  45. data/spec/bson/open_struct_spec.rb +144 -0
  46. data/spec/bson/raw_spec.rb +540 -0
  47. data/spec/bson/regexp_spec.rb +7 -7
  48. data/spec/bson/timestamp_spec.rb +1 -1
  49. data/spec/spec_helper.rb +5 -0
  50. data/spec/support/common_driver.rb +347 -0
  51. data/spec/support/corpus-tests/array.json +43 -0
  52. data/spec/support/corpus-tests/boolean.json +27 -0
  53. data/spec/support/corpus-tests/code.json +67 -0
  54. data/spec/support/corpus-tests/code_w_scope.json +78 -0
  55. data/spec/support/corpus-tests/document.json +36 -0
  56. data/spec/support/corpus-tests/double.json +69 -0
  57. data/spec/support/corpus-tests/failures/binary.json +69 -0
  58. data/spec/support/corpus-tests/failures/datetime.json +31 -0
  59. data/spec/support/corpus-tests/failures/dbpointer.json +42 -0
  60. data/spec/support/corpus-tests/failures/int64.json +38 -0
  61. data/spec/support/corpus-tests/failures/symbol.json +62 -0
  62. data/spec/support/corpus-tests/failures/undefined.json +13 -0
  63. data/spec/support/corpus-tests/int32.json +38 -0
  64. data/spec/support/corpus-tests/maxkey.json +12 -0
  65. data/spec/support/corpus-tests/minkey.json +12 -0
  66. data/spec/support/corpus-tests/null.json +12 -0
  67. data/spec/support/corpus-tests/oid.json +28 -0
  68. data/spec/support/corpus-tests/regex.json +37 -0
  69. data/spec/support/corpus-tests/string.json +67 -0
  70. data/spec/support/corpus-tests/timestamp.json +18 -0
  71. data/spec/support/corpus-tests/top.json +62 -0
  72. data/spec/support/corpus.rb +265 -0
  73. data/spec/support/driver-spec-tests/decimal128/decimal128-1.json +363 -0
  74. data/spec/support/driver-spec-tests/decimal128/decimal128-2.json +793 -0
  75. data/spec/support/driver-spec-tests/decimal128/decimal128-3.json +1771 -0
  76. data/spec/support/driver-spec-tests/decimal128/decimal128-4.json +165 -0
  77. data/spec/support/driver-spec-tests/decimal128/decimal128-5.json +402 -0
  78. data/spec/support/driver-spec-tests/decimal128/decimal128-6.json +131 -0
  79. data/spec/support/driver-spec-tests/decimal128/decimal128-7.json +327 -0
  80. data/spec/support/shared_examples.rb +1 -1
  81. metadata +77 -4
  82. metadata.gz.sig +0 -0
@@ -24,7 +24,7 @@ describe Regexp do
24
24
 
25
25
  it "returns the binary data plus type" do
26
26
  expect(object.as_json).to eq(
27
- { "$regex" => "\\W+", "$options" => "i" }
27
+ { "$regex" => "\\W+", "$options" => "im" }
28
28
  )
29
29
  end
30
30
 
@@ -55,9 +55,7 @@ describe Regexp do
55
55
  /\d+/
56
56
  end
57
57
 
58
- let :bson do
59
- [obj.source, BSON::NULL_BYTE, BSON::NULL_BYTE].join ''
60
- end
58
+ let(:bson) { "#{obj.source}#{BSON::NULL_BYTE}m#{BSON::NULL_BYTE}" }
61
59
 
62
60
  it_behaves_like "a serializable bson element"
63
61
 
@@ -69,7 +67,9 @@ describe Regexp do
69
67
  context "when the regexp has no options" do
70
68
 
71
69
  let(:obj) { /\d+/ }
72
- let(:bson) { "#{obj.source}#{BSON::NULL_BYTE}#{BSON::NULL_BYTE}" }
70
+ # Ruby always has a BSON regex's equivalent of multiline on
71
+ # http://www.regular-expressions.info/modifiers.html
72
+ let(:bson) { "#{obj.source}#{BSON::NULL_BYTE}m#{BSON::NULL_BYTE}" }
73
73
 
74
74
  it_behaves_like "a serializable bson element"
75
75
 
@@ -83,7 +83,7 @@ describe Regexp do
83
83
  context "when ignoring case" do
84
84
 
85
85
  let(:obj) { /\W+/i }
86
- let(:bson) { "#{obj.source}#{BSON::NULL_BYTE}i#{BSON::NULL_BYTE}" }
86
+ let(:bson) { "#{obj.source}#{BSON::NULL_BYTE}im#{BSON::NULL_BYTE}" }
87
87
 
88
88
  it_behaves_like "a serializable bson element"
89
89
 
@@ -107,7 +107,7 @@ describe Regexp do
107
107
  context "when matching extended" do
108
108
 
109
109
  let(:obj) { /\W+/x }
110
- let(:bson) { "#{obj.source}#{BSON::NULL_BYTE}x#{BSON::NULL_BYTE}" }
110
+ let(:bson) { "#{obj.source}#{BSON::NULL_BYTE}mx#{BSON::NULL_BYTE}" }
111
111
 
112
112
  it_behaves_like "a serializable bson element"
113
113
 
@@ -55,7 +55,7 @@ describe BSON::Timestamp do
55
55
  end
56
56
 
57
57
  it "returns the binary data plus type" do
58
- expect(object.as_json).to eq({ "t" => 10, "i" => 50 })
58
+ expect(object.as_json).to eq({"$timestamp" => { "t" => 10, "i" => 50 } })
59
59
  end
60
60
 
61
61
  it_behaves_like "a JSON serializable object"
@@ -12,9 +12,14 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ CURRENT_PATH = File.expand_path(File.dirname(__FILE__))
16
+ DRIVER_COMMON_BSON_TESTS = Dir.glob("#{CURRENT_PATH}/support/driver-spec-tests/**/*.json")
17
+ BSON_CORPUS_TESTS = Dir.glob("#{CURRENT_PATH}/support/corpus-tests/*.json")
18
+
15
19
  $LOAD_PATH.unshift(File.dirname(__FILE__))
16
20
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
17
21
 
22
+ require "ostruct"
18
23
  require "bson"
19
24
  require "json"
20
25
  require "rspec"
@@ -0,0 +1,347 @@
1
+ # Copyright (C) 2016 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 'json'
16
+ require 'bigdecimal'
17
+
18
+ module BSON
19
+ module CommonDriver
20
+
21
+ # Represents a Common Driver specification test.
22
+ #
23
+ # @since 4.2.0
24
+ class Spec
25
+
26
+ # The spec description.
27
+ #
28
+ # @return [ String ] The spec description.
29
+ #
30
+ # @since 4.2.0
31
+ attr_reader :description
32
+
33
+ # The document key of the object to test.
34
+ #
35
+ # @return [ String ] The document key.
36
+ #
37
+ # @since 4.2.0
38
+ attr_reader :test_key
39
+
40
+ # Instantiate the new spec.
41
+ #
42
+ # @example Create the spec.
43
+ # Spec.new(file)
44
+ #
45
+ # @param [ String ] file The name of the yaml file.
46
+ #
47
+ # @since 4.2.0
48
+ def initialize(file)
49
+ @spec = ::JSON.parse(File.read(file))
50
+ @valid = @spec['valid'] || []
51
+ @invalid = @spec['parseErrors'] || []
52
+ @description = @spec['description']
53
+ @test_key = @spec['test_key']
54
+ end
55
+
56
+ # Get a list of tests that don't raise exceptions.
57
+ #
58
+ # @example Get the list of valid tests.
59
+ # spec.valid_tests
60
+ #
61
+ # @return [ Array<BSON::CommonDriver::Test> ] The list of valid Tests.
62
+ #
63
+ # @since 4.2.0
64
+ def valid_tests
65
+ @valid_tests ||=
66
+ @valid.collect do |test|
67
+ BSON::CommonDriver::Test.new(self, test)
68
+ end
69
+ end
70
+
71
+ # Get a list of tests that raise exceptions.
72
+ #
73
+ # @example Get the list of invalid tests.
74
+ # spec.invalid_tests
75
+ #
76
+ # @return [ Array<BSON::CommonDriver::Test> ] The list of invalid Tests.
77
+ #
78
+ # @since 4.2.0
79
+ def invalid_tests
80
+ @invalid_tests ||=
81
+ @invalid.collect do |test|
82
+ BSON::CommonDriver::Test.new(self, test)
83
+ end
84
+ end
85
+
86
+ # The class of the bson object to test.
87
+ #
88
+ # @example Get the class of the object to test.
89
+ # spec.klass
90
+ #
91
+ # @return [ Class ] The object class.
92
+ #
93
+ # @since 4.2.0
94
+ def klass
95
+ @klass ||= BSON.const_get(description)
96
+ end
97
+ end
98
+
99
+ # Represents a single CommonDriver test.
100
+ #
101
+ # @since 4.2.0
102
+ class Test
103
+
104
+ # The test description.
105
+ #
106
+ # @return [ String ] The test description.
107
+ #
108
+ # @since 4.2.0
109
+ attr_reader :description
110
+
111
+ # The test subject.
112
+ #
113
+ # @return [ String ] The test subject.
114
+ #
115
+ # @since 4.2.0
116
+ attr_reader :subject
117
+
118
+ # The string to use to create a Decimal128.
119
+ #
120
+ # @return [ String ] The string to use in creating a Decimal128 object.
121
+ #
122
+ # @since 4.2.0
123
+ attr_reader :string
124
+
125
+ # The expected string representation of the Decimal128 object.
126
+ #
127
+ # @return [ String ] The object as a string.
128
+ #
129
+ # @since 4.2.0
130
+ attr_reader :match_string
131
+
132
+ # The json representation of the object.
133
+ #
134
+ # @return [ Hash ] The json representation of the object.
135
+ #
136
+ # @since 4.2.0
137
+ attr_reader :ext_json
138
+
139
+ # Instantiate the new Test.
140
+ #
141
+ # @example Create the test.
142
+ # Test.new(test)
143
+ #
144
+ # @param [ CommonDriver::Spec ] spec The test specification.
145
+ # @param [ Hash ] test The test specification.
146
+ #
147
+ # @since 4.2.0
148
+ def initialize(spec, test)
149
+ @spec = spec
150
+ @description = test['description']
151
+ @string = test['string']
152
+ @match_string = test['match_string']
153
+ @ext_json = ::JSON.parse(test['extjson']) if test['extjson']
154
+ @from_ext_json = test['from_extjson'].nil? ? true : test['from_extjson']
155
+ @to_ext_json = test['to_extjson'].nil? ? true : test['to_extjson']
156
+ @subject = test['subject']
157
+ @test_key = spec.test_key
158
+ end
159
+
160
+ # Get the reencoded document in hex format.
161
+ #
162
+ # @example Get the reencoded document as hex.
163
+ # test.reencoded_hex
164
+ #
165
+ # @return [ String ] The reencoded document in hex format.
166
+ #
167
+ # @since 4.2.0
168
+ def reencoded_hex
169
+ decoded_document.to_bson.to_s.unpack("H*").first.upcase
170
+ end
171
+
172
+ # The object tested.
173
+ #
174
+ # @example Get the object for this test.
175
+ # test.object
176
+ #
177
+ # @return [ BSON::Object ] The object.
178
+ #
179
+ # @since 4.2.0
180
+ def object
181
+ @object ||= decoded_document[@test_key]
182
+ end
183
+
184
+ # The object as json, in a document with the test key.
185
+ #
186
+ # @example Get a document with the object at the test key.
187
+ # test.document_as_json
188
+ #
189
+ # @return [ BSON::Document ] The json document.
190
+ #
191
+ # @since 4.2.0
192
+ def document_as_json
193
+ { @test_key => object.as_json }
194
+ end
195
+
196
+ # Use the string in the extended json to instantiate the bson object.
197
+ #
198
+ # @example Get a bson object from the string in the extended json.
199
+ # test.from_json
200
+ #
201
+ # @return [ BSON::Object ] The BSON object.
202
+ #
203
+ # @since 4.2.0
204
+ def from_json_string
205
+ klass.from_string(@ext_json[@test_key][klass::EXTENDED_JSON_KEY])
206
+ end
207
+
208
+ # Create an object from the given test string.
209
+ #
210
+ # @example
211
+ # test.parse_string
212
+ #
213
+ # @return [ BSON::Object ] The object.
214
+ #
215
+ # @since 4.2.0
216
+ def parse_string
217
+ klass.from_string(string)
218
+ end
219
+
220
+ # Attempt to create an object from an invalid string.
221
+ #
222
+ # @example
223
+ # test.parse_invalid_string
224
+ #
225
+ # @raise [ Error ] Parsing an invalid string will raise an error.
226
+ #
227
+ # @since 4.2.0
228
+ def parse_invalid_string
229
+ klass.from_string(subject)
230
+ end
231
+
232
+ # The class of the object being tested.
233
+ #
234
+ # @example
235
+ # test.klass
236
+ #
237
+ # @return [ Class ] The object class.
238
+ #
239
+ # @since 4.2.0
240
+ def klass
241
+ @spec.klass
242
+ end
243
+
244
+ # The error class of a parse error.
245
+ #
246
+ # @example
247
+ # test.parse_error
248
+ #
249
+ # @return [ Class ] The parse error class.
250
+ #
251
+ # @since 4.2.0
252
+ def parse_error
253
+ klass::InvalidRange
254
+ end
255
+
256
+ # Whether the object can be instantiated from extended json.
257
+ #
258
+ # @example Check if an object can be instantiated from the extended json.
259
+ # test.from_ex_json?
260
+ #
261
+ # @return [ true, false ] If the object can be instantiated from
262
+ # the provided extended json.
263
+ #
264
+ # @since 4.2.0
265
+ def from_ext_json?
266
+ @ext_json && @from_ext_json
267
+ end
268
+
269
+ # Whether the object can be represented as extended json.
270
+ #
271
+ # @example Check if an object can be represented as extended json.
272
+ # test.to_ext_json?
273
+ #
274
+ # @return [ true, false ] If the object can be represented as
275
+ # extended json.
276
+ #
277
+ # @since 4.2.0
278
+ def to_ext_json?
279
+ @ext_json && @to_ext_json
280
+ end
281
+
282
+ # Whether the object can be instantiated from a string.
283
+ #
284
+ # @example Check if an object can be instantiated from a string.
285
+ # test.from_string?
286
+ #
287
+ # @return [ true, false ] If the object can be instantiated from a string.
288
+ #
289
+ # @since 4.2.0
290
+ def from_string?
291
+ @string && @from_ext_json
292
+ end
293
+
294
+ # The expected string representation of the test object.
295
+ #
296
+ # @example Get the expected String representation of the test object.
297
+ # test.expected_to_string
298
+ #
299
+ # @return [ String ] The expected string representation.
300
+ #
301
+ # @since 4.2.0
302
+ def expected_to_string
303
+ match_string || string
304
+ end
305
+
306
+ # The Ruby class to which this bson object can be converted via a helper.
307
+ #
308
+ # @example Get the native type to which this object can be converted.
309
+ # test.native_type
310
+ #
311
+ # @return [ Class ] The Ruby native type.
312
+ #
313
+ # @since 4.2.0
314
+ def native_type
315
+ klass::NATIVE_TYPE
316
+ end
317
+
318
+ # Get the object converted to an instance of the native Ruby type.
319
+ #
320
+ # @example Get a native Ruby instance.
321
+ # test.native_type_conversion
322
+ #
323
+ # @return [ Object ] An instance of the Ruby native type.
324
+ #
325
+ # @since 4.2.0
326
+ def native_type_conversion
327
+ object.send("to_#{to_snake_case(native_type)}")
328
+ end
329
+
330
+ private
331
+
332
+ def to_snake_case(string)
333
+ string.to_s.gsub(/::/, '/').
334
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
335
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
336
+ tr("-", "_").
337
+ downcase
338
+ end
339
+
340
+ def decoded_document
341
+ @document ||= (data = [ @subject ].pack('H*')
342
+ buffer = BSON::ByteBuffer.new(data)
343
+ BSON::Document.from_bson(buffer))
344
+ end
345
+ end
346
+ end
347
+ end
@@ -0,0 +1,43 @@
1
+ {
2
+ "description": "Array",
3
+ "bson_type": "0x04",
4
+ "test_key": "a",
5
+ "valid": [
6
+ {
7
+ "description": "Empty",
8
+ "bson": "0D000000046100050000000000",
9
+ "extjson": "{\"a\" : []}"
10
+ },
11
+ {
12
+ "description": "Single Element Array",
13
+ "bson": "140000000461000C0000001030000A0000000000",
14
+ "extjson": "{\"a\" : [10]}"
15
+ },
16
+ {
17
+ "description": "Single Element Array with index set incorrectly",
18
+ "bson": "130000000461000B00000010000A0000000000",
19
+ "canonical_bson": "140000000461000C0000001030000A0000000000",
20
+ "extjson": "{\"a\" : [10]}"
21
+ },
22
+ {
23
+ "description": "Single Element Array with index set incorrectly",
24
+ "bson": "150000000461000D000000106162000A0000000000",
25
+ "canonical_bson": "140000000461000C0000001030000A0000000000",
26
+ "extjson": "{\"a\" : [10]}"
27
+ }
28
+ ],
29
+ "decodeErrors": [
30
+ {
31
+ "description": "Array length too long: eats outer terminator",
32
+ "bson": "140000000461000D0000001030000A0000000000"
33
+ },
34
+ {
35
+ "description": "Array length too short: leaks terminator",
36
+ "bson": "140000000461000B0000001030000A0000000000"
37
+ },
38
+ {
39
+ "description": "Invalid Array: bad string length in field",
40
+ "bson": "1A00000004666F6F00100000000230000500000062617A000000"
41
+ }
42
+ ]
43
+ }