bson 4.7.1 → 4.8.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -2
- data.tar.gz.sig +0 -0
- data/README.md +5 -1
- data/ext/bson/bson-native.h +14 -4
- data/ext/bson/init.c +25 -2
- data/ext/bson/read.c +61 -15
- data/ext/bson/util.c +40 -0
- data/ext/bson/write.c +17 -13
- data/lib/bson.rb +3 -0
- data/lib/bson/array.rb +21 -3
- data/lib/bson/binary.rb +41 -3
- data/lib/bson/boolean.rb +3 -1
- data/lib/bson/code.rb +15 -1
- data/lib/bson/code_with_scope.rb +17 -3
- data/lib/bson/db_pointer.rb +104 -0
- data/lib/bson/decimal128.rb +15 -1
- data/lib/bson/error.rb +17 -0
- data/lib/bson/ext_json.rb +374 -0
- data/lib/bson/float.rb +47 -1
- data/lib/bson/hash.rb +23 -3
- data/lib/bson/int32.rb +21 -1
- data/lib/bson/int64.rb +28 -3
- data/lib/bson/integer.rb +34 -0
- data/lib/bson/max_key.rb +12 -0
- data/lib/bson/min_key.rb +12 -0
- data/lib/bson/nil_class.rb +3 -1
- data/lib/bson/object.rb +27 -0
- data/lib/bson/object_id.rb +15 -1
- data/lib/bson/regexp.rb +19 -2
- data/lib/bson/specialized.rb +3 -1
- data/lib/bson/string.rb +3 -1
- data/lib/bson/symbol.rb +92 -3
- data/lib/bson/time.rb +28 -3
- data/lib/bson/timestamp.rb +15 -1
- data/lib/bson/undefined.rb +11 -0
- data/lib/bson/version.rb +1 -1
- data/spec/bson/binary_spec.rb +33 -3
- data/spec/bson/ext_json_parse_spec.rb +276 -0
- data/spec/bson/float_spec.rb +36 -0
- data/spec/bson/hash_spec.rb +70 -0
- data/spec/bson/int32_spec.rb +20 -0
- data/spec/bson/int64_spec.rb +38 -0
- data/spec/bson/integer_spec.rb +26 -0
- data/spec/bson/raw_spec.rb +22 -1
- data/spec/bson/symbol_raw_spec.rb +45 -0
- data/spec/bson/symbol_spec.rb +60 -0
- data/spec/{support → runners}/common_driver.rb +0 -0
- data/spec/runners/corpus.rb +182 -0
- data/spec/{support/corpus.rb → runners/corpus_legacy.rb} +40 -58
- data/spec/spec_helper.rb +9 -2
- data/spec/{bson/driver_bson_spec.rb → spec_tests/common_driver_spec.rb} +1 -0
- data/spec/{bson/corpus_spec.rb → spec_tests/corpus_legacy_spec.rb} +4 -4
- data/spec/spec_tests/corpus_spec.rb +124 -0
- data/spec/spec_tests/data/corpus/README.md +15 -0
- data/spec/spec_tests/data/corpus/array.json +49 -0
- data/spec/spec_tests/data/corpus/binary.json +85 -0
- data/spec/spec_tests/data/corpus/boolean.json +27 -0
- data/spec/spec_tests/data/corpus/code.json +67 -0
- data/spec/spec_tests/data/corpus/code_w_scope.json +78 -0
- data/spec/spec_tests/data/corpus/datetime.json +42 -0
- data/spec/spec_tests/data/corpus/dbpointer.json +56 -0
- data/spec/spec_tests/data/corpus/dbref.json +31 -0
- data/spec/spec_tests/data/corpus/decimal128-1.json +317 -0
- data/spec/spec_tests/data/corpus/decimal128-2.json +793 -0
- data/spec/spec_tests/data/corpus/decimal128-3.json +1771 -0
- data/spec/spec_tests/data/corpus/decimal128-4.json +117 -0
- data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
- data/spec/spec_tests/data/corpus/decimal128-6.json +119 -0
- data/spec/spec_tests/data/corpus/decimal128-7.json +323 -0
- data/spec/spec_tests/data/corpus/document.json +36 -0
- data/spec/spec_tests/data/corpus/double.json +87 -0
- data/spec/spec_tests/data/corpus/int32.json +43 -0
- data/spec/spec_tests/data/corpus/int64.json +43 -0
- data/spec/spec_tests/data/corpus/maxkey.json +12 -0
- data/spec/spec_tests/data/corpus/minkey.json +12 -0
- data/spec/spec_tests/data/corpus/multi-type-deprecated.json +15 -0
- data/spec/spec_tests/data/corpus/multi-type.json +11 -0
- data/spec/spec_tests/data/corpus/null.json +12 -0
- data/spec/spec_tests/data/corpus/oid.json +28 -0
- data/spec/spec_tests/data/corpus/regex.json +65 -0
- data/spec/spec_tests/data/corpus/string.json +72 -0
- data/spec/spec_tests/data/corpus/symbol.json +80 -0
- data/spec/spec_tests/data/corpus/timestamp.json +24 -0
- data/spec/spec_tests/data/corpus/top.json +240 -0
- data/spec/spec_tests/data/corpus/undefined.json +15 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/array.json +0 -0
- data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/binary.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/boolean.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code_w_scope.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/document.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/double.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/datetime.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/dbpointer.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/int64.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/symbol.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/int32.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/maxkey.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/minkey.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/null.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/oid.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/regex.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/string.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/timestamp.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/top.json +0 -0
- data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/undefined.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-1.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-2.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-3.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-4.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-5.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-6.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-7.json +0 -0
- metadata +170 -95
- metadata.gz.sig +2 -4
data/lib/bson/symbol.rb
CHANGED
@@ -89,19 +89,108 @@ module BSON
|
|
89
89
|
to_s
|
90
90
|
end
|
91
91
|
|
92
|
+
# Converts this object to a representation directly serializable to
|
93
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
94
|
+
#
|
95
|
+
# @option options [ true | false ] :relaxed Whether to produce relaxed
|
96
|
+
# extended JSON representation.
|
97
|
+
#
|
98
|
+
# @return [ Hash ] The extended json representation.
|
99
|
+
def as_extended_json(**options)
|
100
|
+
{ "$symbol" => to_s }
|
101
|
+
end
|
102
|
+
|
103
|
+
class Raw
|
104
|
+
# Create a BSON Symbol
|
105
|
+
#
|
106
|
+
# @param [ String | Symbol ] str_or_sym The symbol represented by this
|
107
|
+
# object. Can be specified as a Symbol or a String.
|
108
|
+
#
|
109
|
+
# @see http://bsonspec.org/#/specification
|
110
|
+
def initialize(str_or_sym)
|
111
|
+
unless str_or_sym.is_a?(String) || str_or_sym.is_a?(Symbol)
|
112
|
+
raise ArgumentError, "BSON::Symbol::Raw must be given a symbol or a string, not #{str_or_sym}"
|
113
|
+
end
|
114
|
+
|
115
|
+
@symbol = str_or_sym.to_sym
|
116
|
+
end
|
117
|
+
|
118
|
+
# Get the underlying symbol as a Ruby symbol.
|
119
|
+
#
|
120
|
+
# @return [ Symbol ] The symbol represented by this BSON object.
|
121
|
+
def to_sym
|
122
|
+
@symbol
|
123
|
+
end
|
124
|
+
|
125
|
+
# Get the underlying symbol as a Ruby string.
|
126
|
+
#
|
127
|
+
# @return [ String ] The symbol as a string.
|
128
|
+
def to_s
|
129
|
+
@symbol.to_s
|
130
|
+
end
|
131
|
+
|
132
|
+
# Check equality of the raw bson symbol against another.
|
133
|
+
#
|
134
|
+
# @param [ Object ] other The object to check against.
|
135
|
+
#
|
136
|
+
# @return [ true, false ] If the objects are equal.
|
137
|
+
def ==(other)
|
138
|
+
return false unless other.is_a?(Raw)
|
139
|
+
to_sym == other.to_sym
|
140
|
+
end
|
141
|
+
alias :eql? :==
|
142
|
+
|
143
|
+
# Get the symbol as encoded BSON.
|
144
|
+
#
|
145
|
+
# @raise [ EncodingError ] If the symbol is not UTF-8.
|
146
|
+
#
|
147
|
+
# @return [ BSON::ByteBuffer ] The buffer with the encoded object.
|
148
|
+
#
|
149
|
+
# @see http://bsonspec.org/#/specification
|
150
|
+
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
151
|
+
buffer.put_string(to_s)
|
152
|
+
end
|
153
|
+
|
154
|
+
def bson_type
|
155
|
+
Symbol::BSON_TYPE
|
156
|
+
end
|
157
|
+
|
158
|
+
# Converts this object to a representation directly serializable to
|
159
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
160
|
+
#
|
161
|
+
# This method returns the integer value if relaxed representation is
|
162
|
+
# requested, otherwise a $numberLong hash.
|
163
|
+
#
|
164
|
+
# @option options [ true | false ] :relaxed Whether to produce relaxed
|
165
|
+
# extended JSON representation.
|
166
|
+
#
|
167
|
+
# @return [ Hash | Integer ] The extended json representation.
|
168
|
+
def as_extended_json(**options)
|
169
|
+
{'$symbol' => to_s}
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
92
173
|
module ClassMethods
|
93
174
|
|
94
175
|
# Deserialize a symbol from BSON.
|
95
176
|
#
|
96
177
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
97
178
|
#
|
98
|
-
# @
|
179
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
180
|
+
#
|
181
|
+
# @return [ Symbol | BSON::Symbol::Raw ] The decoded symbol.
|
99
182
|
#
|
100
183
|
# @see http://bsonspec.org/#/specification
|
101
184
|
#
|
102
185
|
# @since 2.0.0
|
103
|
-
def from_bson(buffer)
|
104
|
-
buffer.get_string.intern
|
186
|
+
def from_bson(buffer, **options)
|
187
|
+
sym = buffer.get_string.intern
|
188
|
+
|
189
|
+
if options[:mode] == :bson
|
190
|
+
Raw.new(sym)
|
191
|
+
else
|
192
|
+
sym
|
193
|
+
end
|
105
194
|
end
|
106
195
|
end
|
107
196
|
|
data/lib/bson/time.rb
CHANGED
@@ -38,7 +38,30 @@ module BSON
|
|
38
38
|
#
|
39
39
|
# @since 2.0.0
|
40
40
|
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
41
|
-
|
41
|
+
# A previous version of this method used the following implementation:
|
42
|
+
# buffer.put_int64((to_i * 1000) + (usec / 1000))
|
43
|
+
# Turns out, usec returned incorrect value - 999 for 1 millisecond.
|
44
|
+
buffer.put_int64((to_f * 1000).round)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Converts this object to a representation directly serializable to
|
48
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
49
|
+
#
|
50
|
+
# @option options [ true | false ] :relaxed Whether to produce relaxed
|
51
|
+
# extended JSON representation.
|
52
|
+
#
|
53
|
+
# @return [ Hash ] The extended json representation.
|
54
|
+
def as_extended_json(**options)
|
55
|
+
utc_time = utc
|
56
|
+
if options[:mode] == :relaxed && (1970..9999).include?(utc_time.year)
|
57
|
+
if utc_time.usec != 0
|
58
|
+
{'$date' => utc_time.strftime('%Y-%m-%dT%H:%M:%S.%LZ')}
|
59
|
+
else
|
60
|
+
{'$date' => utc_time.strftime('%Y-%m-%dT%H:%M:%SZ')}
|
61
|
+
end
|
62
|
+
else
|
63
|
+
{'$date' => {'$numberLong' => (utc_time.to_f * 1000).round.to_s}}
|
64
|
+
end
|
42
65
|
end
|
43
66
|
|
44
67
|
module ClassMethods
|
@@ -47,13 +70,15 @@ module BSON
|
|
47
70
|
#
|
48
71
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
49
72
|
#
|
73
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
74
|
+
#
|
50
75
|
# @return [ Time ] The decoded UTC datetime.
|
51
76
|
#
|
52
77
|
# @see http://bsonspec.org/#/specification
|
53
78
|
#
|
54
79
|
# @since 2.0.0
|
55
|
-
def from_bson(buffer)
|
56
|
-
seconds, fragment = Int64.from_bson(buffer).divmod(1000)
|
80
|
+
def from_bson(buffer, **options)
|
81
|
+
seconds, fragment = Int64.from_bson(buffer, mode: nil).divmod(1000)
|
57
82
|
at(seconds, fragment * 1000).utc
|
58
83
|
end
|
59
84
|
end
|
data/lib/bson/timestamp.rb
CHANGED
@@ -84,7 +84,19 @@ module BSON
|
|
84
84
|
# @return [ Hash ] The timestamp as a JSON hash.
|
85
85
|
#
|
86
86
|
# @since 2.0.0
|
87
|
+
# @deprecated Use as_extended_json instead.
|
87
88
|
def as_json(*args)
|
89
|
+
as_extended_json
|
90
|
+
end
|
91
|
+
|
92
|
+
# Converts this object to a representation directly serializable to
|
93
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
94
|
+
#
|
95
|
+
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
96
|
+
# (default is canonical extended JSON)
|
97
|
+
#
|
98
|
+
# @return [ Hash ] The extended json representation.
|
99
|
+
def as_extended_json(**options)
|
88
100
|
{ "$timestamp" => { "t" => seconds, "i" => increment } }
|
89
101
|
end
|
90
102
|
|
@@ -120,12 +132,14 @@ module BSON
|
|
120
132
|
#
|
121
133
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
122
134
|
#
|
135
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
136
|
+
#
|
123
137
|
# @return [ Timestamp ] The decoded timestamp.
|
124
138
|
#
|
125
139
|
# @see http://bsonspec.org/#/specification
|
126
140
|
#
|
127
141
|
# @since 2.0.0
|
128
|
-
def self.from_bson(buffer)
|
142
|
+
def self.from_bson(buffer, **options)
|
129
143
|
increment = buffer.get_int32
|
130
144
|
seconds = buffer.get_int32
|
131
145
|
new(seconds, increment)
|
data/lib/bson/undefined.rb
CHANGED
@@ -41,6 +41,17 @@ module BSON
|
|
41
41
|
self.class == other.class
|
42
42
|
end
|
43
43
|
|
44
|
+
# Converts this object to a representation directly serializable to
|
45
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
46
|
+
#
|
47
|
+
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
48
|
+
# (default is canonical extended JSON)
|
49
|
+
#
|
50
|
+
# @return [ Hash ] The extended json representation.
|
51
|
+
def as_extended_json(**options)
|
52
|
+
{ "$undefined" => true }
|
53
|
+
end
|
54
|
+
|
44
55
|
# Register this type when the module is loaded.
|
45
56
|
#
|
46
57
|
# @since 2.0.0
|
data/lib/bson/version.rb
CHANGED
data/spec/bson/binary_spec.rb
CHANGED
@@ -63,7 +63,7 @@ describe BSON::Binary do
|
|
63
63
|
|
64
64
|
it "returns the binary data plus type" do
|
65
65
|
expect(object.as_json).to eq(
|
66
|
-
{ "$binary" => Base64.encode64("testing"), "
|
66
|
+
{ "$binary" => {'base64' => Base64.encode64("testing").strip, "subType" => '80' }}
|
67
67
|
)
|
68
68
|
end
|
69
69
|
|
@@ -126,12 +126,34 @@ describe BSON::Binary do
|
|
126
126
|
end
|
127
127
|
|
128
128
|
describe '#from_bson' do
|
129
|
-
let(:
|
130
|
-
let(:obj) { described_class.from_bson(
|
129
|
+
let(:buffer) { BSON::ByteBuffer.new(bson) }
|
130
|
+
let(:obj) { described_class.from_bson(buffer) }
|
131
|
+
|
132
|
+
let(:bson) { "#{5.to_bson}#{0.chr}hello".force_encoding('BINARY') }
|
131
133
|
|
132
134
|
it 'sets data encoding to binary' do
|
133
135
|
expect(obj.data.encoding).to eq(Encoding.find('BINARY'))
|
134
136
|
end
|
137
|
+
|
138
|
+
context 'when binary subtype is supported' do
|
139
|
+
let(:bson) { [3, 0, 0, 0, 1].map(&:chr).join.force_encoding('BINARY') + 'foo' }
|
140
|
+
|
141
|
+
it 'works' do
|
142
|
+
obj.should be_a(described_class)
|
143
|
+
obj.type.should be :function
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'when binary subtype is not supported' do
|
148
|
+
let(:bson) { [3, 0, 0, 0, 16].map(&:chr).join.force_encoding('BINARY') + 'foo' }
|
149
|
+
|
150
|
+
it 'raises an exception' do
|
151
|
+
lambda do
|
152
|
+
obj
|
153
|
+
end.should raise_error(BSON::Error::UnsupportedBinarySubtype,
|
154
|
+
/BSON data contains unsupported binary subtype 0x10/)
|
155
|
+
end
|
156
|
+
end
|
135
157
|
end
|
136
158
|
|
137
159
|
describe "#to_bson/#from_bson" do
|
@@ -203,6 +225,14 @@ describe BSON::Binary do
|
|
203
225
|
it_behaves_like "a deserializable bson element"
|
204
226
|
end
|
205
227
|
|
228
|
+
context "when the type is :cyphertext" do
|
229
|
+
let(:obj) { described_class.new("testing", :ciphertext) }
|
230
|
+
let(:bson) { "#{7.to_bson}#{6.chr}testing" }
|
231
|
+
|
232
|
+
it_behaves_like "a serializable bson element"
|
233
|
+
it_behaves_like "a deserializable bson element"
|
234
|
+
end
|
235
|
+
|
206
236
|
context 'when given binary string' do
|
207
237
|
let(:obj) { described_class.new("\x00\xfe\xff".force_encoding('BINARY')) }
|
208
238
|
let(:bson) { "#{3.to_bson}#{0.chr}\x00\xfe\xff".force_encoding('BINARY') }
|
@@ -0,0 +1,276 @@
|
|
1
|
+
# Copyright (C) 2020 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 "BSON::ExtJSON.parse" do
|
18
|
+
|
19
|
+
let(:parsed) { BSON::ExtJSON.parse_obj(input) }
|
20
|
+
|
21
|
+
context 'when input is true' do
|
22
|
+
let(:input) { true }
|
23
|
+
|
24
|
+
it 'returns true' do
|
25
|
+
parsed.should == true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when input is false' do
|
30
|
+
let(:input) { false }
|
31
|
+
|
32
|
+
it 'returns false' do
|
33
|
+
parsed.should == false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when input is nil' do
|
38
|
+
let(:input) { nil }
|
39
|
+
|
40
|
+
it 'returns nil' do
|
41
|
+
parsed.should be nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when input is a string' do
|
46
|
+
let(:input) { 'hello' }
|
47
|
+
|
48
|
+
it 'returns the string' do
|
49
|
+
parsed.should == 'hello'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when input is a timestamp' do
|
54
|
+
let(:input) { {'$timestamp' => {'t' => 12345, 'i' => 42}} }
|
55
|
+
|
56
|
+
it 'returns a timestamp object' do
|
57
|
+
parsed.should == BSON::Timestamp.new(12345, 42)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when input is an int32' do
|
62
|
+
let(:input) do
|
63
|
+
{'$numberInt' => '42'}
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:parsed) { BSON::ExtJSON.parse_obj(input, mode: mode) }
|
67
|
+
|
68
|
+
context 'when :mode is nil' do
|
69
|
+
let(:mode) { nil }
|
70
|
+
|
71
|
+
it 'returns Integer instance' do
|
72
|
+
parsed.should be_a(Integer)
|
73
|
+
parsed.should == 42
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'when :mode is :bson' do
|
78
|
+
let(:mode) { :bson }
|
79
|
+
|
80
|
+
it 'returns Integer instance' do
|
81
|
+
parsed.should be_a(Integer)
|
82
|
+
parsed.should == 42
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when input is an int64' do
|
88
|
+
let(:input) do
|
89
|
+
{'$numberLong' => '42'}
|
90
|
+
end
|
91
|
+
|
92
|
+
let(:parsed) { BSON::ExtJSON.parse_obj(input, mode: mode) }
|
93
|
+
|
94
|
+
context 'when :mode is nil' do
|
95
|
+
let(:mode) { nil }
|
96
|
+
|
97
|
+
it 'returns Integer instance' do
|
98
|
+
parsed.should be_a(Integer)
|
99
|
+
parsed.should == 42
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'when :mode is :bson' do
|
104
|
+
let(:mode) { :bson }
|
105
|
+
|
106
|
+
it 'returns Int64 instance' do
|
107
|
+
parsed.should be_a(BSON::Int64)
|
108
|
+
parsed.value.should == 42
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'when input is a hash' do
|
114
|
+
let(:input) do
|
115
|
+
{}
|
116
|
+
end
|
117
|
+
|
118
|
+
let(:parsed) { BSON::ExtJSON.parse_obj(input, mode: mode) }
|
119
|
+
|
120
|
+
context 'when mode is invalid' do
|
121
|
+
let(:mode) { :foo }
|
122
|
+
|
123
|
+
it 'raises an exception' do
|
124
|
+
lambda do
|
125
|
+
parsed
|
126
|
+
end.should raise_error(ArgumentError, /Invalid value for :mode option/)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'when input is a binary' do
|
132
|
+
let(:data) do
|
133
|
+
Base64.decode64("//8=")
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'in current format' do
|
137
|
+
let(:input) do
|
138
|
+
{ "$binary" => { "base64"=>"//8=", "subType"=>"00" } }
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'when :mode is nil' do
|
142
|
+
let(:mode) { nil }
|
143
|
+
|
144
|
+
it 'returns BSON::Binary instance' do
|
145
|
+
parsed.should be_a(BSON::Binary)
|
146
|
+
parsed.data.should == data
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'when mode is :bson' do
|
151
|
+
let(:mode) { :bson }
|
152
|
+
|
153
|
+
it 'returns BSON::Binary instance' do
|
154
|
+
parsed.should be_a(BSON::Binary)
|
155
|
+
parsed.data.should == data
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'in legacy format' do
|
161
|
+
let(:input) do
|
162
|
+
{ "$binary"=>"//8=", "$type"=>"00" }
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'when :mode is nil' do
|
166
|
+
let(:mode) { nil }
|
167
|
+
|
168
|
+
it 'returns BSON::Binary instance' do
|
169
|
+
parsed.should be_a(BSON::Binary)
|
170
|
+
parsed.data.should == data
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context 'when mode is :bson' do
|
175
|
+
let(:mode) { :bson }
|
176
|
+
|
177
|
+
it 'returns BSON::Binary instance' do
|
178
|
+
parsed.should be_a(BSON::Binary)
|
179
|
+
parsed.data.should == data
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context 'when input is a regex' do
|
186
|
+
let(:pattern) { 'abc' }
|
187
|
+
let(:options) { 'im' }
|
188
|
+
|
189
|
+
context 'in current format' do
|
190
|
+
let(:input) do
|
191
|
+
{ "$regularExpression" => { "pattern" => pattern, "options" => options } }
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'when :mode is nil' do
|
195
|
+
let(:mode) { nil }
|
196
|
+
|
197
|
+
it 'returns a BSON::Regexp::Raw instance' do
|
198
|
+
parsed.should be_a(BSON::Regexp::Raw)
|
199
|
+
parsed.pattern.should == pattern
|
200
|
+
parsed.options.should == options
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'when :mode is :bson' do
|
205
|
+
let(:mode) { :bson }
|
206
|
+
|
207
|
+
it 'returns a BSON::Regexp::Raw instance' do
|
208
|
+
parsed.should be_a(BSON::Regexp::Raw)
|
209
|
+
parsed.pattern.should == pattern
|
210
|
+
parsed.options.should == options
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
context 'in legacy format' do
|
216
|
+
let(:input) do
|
217
|
+
{ "$regex" => pattern, "$options" => options }
|
218
|
+
end
|
219
|
+
|
220
|
+
context 'when :mode is nil' do
|
221
|
+
let(:mode) { nil }
|
222
|
+
|
223
|
+
it 'returns a BSON::Regexp::Raw instance' do
|
224
|
+
parsed.should be_a(BSON::Regexp::Raw)
|
225
|
+
parsed.pattern.should == pattern
|
226
|
+
parsed.options.should == options
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
context 'when :mode is :bson' do
|
231
|
+
let(:mode) { :bson }
|
232
|
+
|
233
|
+
it 'returns a BSON::Regexp::Raw instance' do
|
234
|
+
parsed.should be_a(BSON::Regexp::Raw)
|
235
|
+
parsed.pattern.should == pattern
|
236
|
+
parsed.options.should == options
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
context 'when $regularExpression is nested in $regex' do
|
242
|
+
context 'with options' do
|
243
|
+
let(:input) do
|
244
|
+
{
|
245
|
+
"$regex" => {
|
246
|
+
"$regularExpression" => { "pattern" => "foo*", "options" => "" },
|
247
|
+
},
|
248
|
+
"$options" => "ix",
|
249
|
+
}
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'parses' do
|
253
|
+
parsed.should == {
|
254
|
+
'$regex' => BSON::Regexp::Raw.new('foo*'), '$options' => 'ix'
|
255
|
+
}
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
context 'without options' do
|
260
|
+
let(:input) do
|
261
|
+
{
|
262
|
+
"$regex" => {
|
263
|
+
"$regularExpression" => { "pattern" => "foo*", "options" => "" },
|
264
|
+
},
|
265
|
+
}
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'parses' do
|
269
|
+
parsed.should == {
|
270
|
+
'$regex' => BSON::Regexp::Raw.new('foo*'),
|
271
|
+
}
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|