bson 4.1.1 → 5.2.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 +5 -5
- data/README.md +106 -7
- data/Rakefile +86 -43
- data/ext/bson/{native-endian.h → bson-endian.h} +14 -107
- data/ext/bson/bson-native.h +135 -0
- data/ext/bson/bytebuf.c +133 -0
- data/ext/bson/endian.c +117 -0
- data/ext/bson/extconf.rb +8 -3
- data/ext/bson/init.c +364 -0
- data/ext/bson/libbson-utf8.c +230 -0
- data/ext/bson/read.c +470 -0
- data/ext/bson/util.c +250 -0
- data/ext/bson/write.c +675 -0
- data/lib/bson/active_support.rb +19 -0
- data/lib/bson/array.rb +97 -30
- data/lib/bson/big_decimal.rb +77 -0
- data/lib/bson/binary.rb +510 -70
- data/lib/bson/boolean.rb +15 -4
- data/lib/bson/code.rb +25 -12
- data/lib/bson/code_with_scope.rb +41 -15
- data/lib/bson/config.rb +3 -28
- data/lib/bson/date.rb +16 -4
- data/lib/bson/date_time.rb +6 -4
- data/lib/bson/db_pointer.rb +110 -0
- data/lib/bson/dbref.rb +154 -0
- data/lib/bson/decimal128/builder.rb +456 -0
- data/lib/bson/decimal128.rb +272 -0
- data/lib/bson/document.rb +177 -7
- data/lib/bson/environment.rb +17 -2
- data/lib/bson/error/bson_decode_error.rb +11 -0
- data/lib/bson/error/ext_json_parse_error.rb +11 -0
- data/lib/bson/error/illegal_key.rb +23 -0
- data/lib/bson/error/invalid_binary_type.rb +37 -0
- data/lib/bson/error/invalid_dbref_argument.rb +12 -0
- data/lib/bson/error/invalid_decimal128_argument.rb +25 -0
- data/lib/bson/error/invalid_decimal128_range.rb +27 -0
- data/lib/bson/error/invalid_decimal128_string.rb +26 -0
- data/lib/bson/error/invalid_key.rb +24 -0
- data/lib/bson/error/invalid_object_id.rb +11 -0
- data/lib/bson/error/invalid_regexp_pattern.rb +13 -0
- data/lib/bson/error/unrepresentable_precision.rb +19 -0
- data/lib/bson/error/unserializable_class.rb +13 -0
- data/lib/bson/error/unsupported_binary_subtype.rb +12 -0
- data/lib/bson/error/unsupported_type.rb +11 -0
- data/lib/bson/error.rb +22 -0
- data/lib/bson/ext_json.rb +389 -0
- data/lib/bson/false_class.rb +6 -4
- data/lib/bson/float.rb +43 -7
- data/lib/bson/hash.rb +152 -37
- data/lib/bson/int32.rb +104 -6
- data/lib/bson/int64.rb +111 -8
- data/lib/bson/integer.rb +43 -9
- data/lib/bson/json.rb +3 -1
- data/lib/bson/max_key.rb +21 -10
- data/lib/bson/min_key.rb +21 -10
- data/lib/bson/nil_class.rb +7 -3
- data/lib/bson/object.rb +25 -17
- data/lib/bson/object_id.rb +98 -113
- data/lib/bson/open_struct.rb +59 -0
- data/lib/bson/regexp.rb +129 -56
- data/lib/bson/registry.rb +7 -10
- data/lib/bson/specialized.rb +8 -4
- data/lib/bson/string.rb +12 -32
- data/lib/bson/symbol.rb +107 -11
- data/lib/bson/time.rb +68 -7
- data/lib/bson/time_with_zone.rb +67 -0
- data/lib/bson/timestamp.rb +50 -10
- data/lib/bson/true_class.rb +6 -4
- data/lib/bson/undefined.rb +28 -2
- data/lib/bson/vector.rb +44 -0
- data/lib/bson/version.rb +6 -14
- data/lib/bson.rb +22 -12
- data/spec/README.md +14 -0
- data/spec/bson/array_spec.rb +38 -62
- data/spec/bson/big_decimal_spec.rb +328 -0
- data/spec/bson/binary_spec.rb +199 -53
- data/spec/bson/binary_uuid_spec.rb +190 -0
- data/spec/bson/boolean_spec.rb +2 -1
- data/spec/bson/byte_buffer_read_spec.rb +198 -0
- data/spec/bson/byte_buffer_spec.rb +122 -381
- data/spec/bson/byte_buffer_write_spec.rb +855 -0
- data/spec/bson/code_spec.rb +6 -4
- data/spec/bson/code_with_scope_spec.rb +6 -4
- data/spec/bson/config_spec.rb +1 -35
- data/spec/bson/date_spec.rb +2 -1
- data/spec/bson/date_time_spec.rb +55 -1
- data/spec/bson/dbref_legacy_spec.rb +186 -0
- data/spec/bson/dbref_spec.rb +487 -0
- data/spec/bson/decimal128_spec.rb +1840 -0
- data/spec/bson/document_as_spec.rb +61 -0
- data/spec/bson/document_spec.rb +205 -32
- data/spec/bson/ext_json_parse_spec.rb +346 -0
- data/spec/bson/false_class_spec.rb +9 -1
- data/spec/bson/float_spec.rb +42 -1
- data/spec/bson/hash_as_spec.rb +58 -0
- data/spec/bson/hash_spec.rb +318 -66
- data/spec/bson/int32_spec.rb +248 -1
- data/spec/bson/int64_spec.rb +308 -1
- data/spec/bson/integer_spec.rb +61 -3
- data/spec/bson/json_spec.rb +2 -1
- data/spec/bson/max_key_spec.rb +6 -4
- data/spec/bson/min_key_spec.rb +6 -4
- data/spec/bson/nil_class_spec.rb +2 -1
- data/spec/bson/object_id_spec.rb +95 -5
- data/spec/bson/object_spec.rb +3 -2
- data/spec/bson/open_struct_spec.rb +87 -0
- data/spec/bson/raw_spec.rb +594 -0
- data/spec/bson/regexp_spec.rb +61 -8
- data/spec/bson/registry_spec.rb +3 -2
- data/spec/bson/string_spec.rb +26 -33
- data/spec/bson/symbol_raw_spec.rb +70 -0
- data/spec/bson/symbol_spec.rb +77 -20
- data/spec/bson/time_spec.rb +206 -2
- data/spec/bson/time_with_zone_spec.rb +69 -0
- data/spec/bson/timestamp_spec.rb +58 -2
- data/spec/bson/true_class_spec.rb +9 -1
- data/spec/bson/undefined_spec.rb +28 -1
- data/spec/bson/vector_spec.rb +33 -0
- data/spec/bson_spec.rb +2 -1
- data/spec/runners/binary_vector.rb +78 -0
- data/spec/runners/common_driver.rb +348 -0
- data/spec/runners/corpus.rb +191 -0
- data/spec/runners/corpus_legacy.rb +248 -0
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/cluster_config.rb +231 -0
- data/spec/shared/lib/mrss/constraints.rb +378 -0
- data/spec/shared/lib/mrss/docker_runner.rb +298 -0
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
- data/spec/shared/lib/mrss/release/candidate.rb +281 -0
- data/spec/shared/lib/mrss/release/product_data.rb +144 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
- data/spec/shared/lib/mrss/session_registry.rb +69 -0
- data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
- data/spec/shared/lib/mrss/utils.rb +37 -0
- data/spec/shared/lib/tasks/candidate.rake +64 -0
- data/spec/shared/share/Dockerfile.erb +251 -0
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/config.sh +27 -0
- data/spec/shared/shlib/distro.sh +84 -0
- data/spec/shared/shlib/server.sh +423 -0
- data/spec/shared/shlib/set_env.sh +110 -0
- data/spec/spec_helper.rb +61 -1
- data/spec/spec_tests/binary_vector_spec.rb +82 -0
- data/spec/spec_tests/common_driver_spec.rb +84 -0
- data/spec/spec_tests/corpus_legacy_spec.rb +72 -0
- data/spec/spec_tests/corpus_spec.rb +134 -0
- data/spec/spec_tests/data/binary_vector/README.md +61 -0
- data/spec/spec_tests/data/binary_vector/float32.json +65 -0
- data/spec/spec_tests/data/binary_vector/int8.json +57 -0
- data/spec/spec_tests/data/binary_vector/packed_bit.json +83 -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 +153 -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 +51 -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 +165 -0
- data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
- data/spec/spec_tests/data/corpus/decimal128-6.json +131 -0
- data/spec/spec_tests/data/corpus/decimal128-7.json +327 -0
- data/spec/spec_tests/data/corpus/document.json +60 -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 +34 -0
- data/spec/spec_tests/data/corpus/top.json +262 -0
- data/spec/spec_tests/data/corpus/undefined.json +15 -0
- data/spec/spec_tests/data/corpus_legacy/array.json +49 -0
- data/spec/spec_tests/data/corpus_legacy/binary.json +69 -0
- data/spec/spec_tests/data/corpus_legacy/boolean.json +27 -0
- data/spec/spec_tests/data/corpus_legacy/code.json +67 -0
- data/spec/spec_tests/data/corpus_legacy/code_w_scope.json +78 -0
- data/spec/spec_tests/data/corpus_legacy/document.json +36 -0
- data/spec/spec_tests/data/corpus_legacy/double.json +69 -0
- data/spec/spec_tests/data/corpus_legacy/failures/datetime.json +31 -0
- data/spec/spec_tests/data/corpus_legacy/failures/dbpointer.json +42 -0
- data/spec/spec_tests/data/corpus_legacy/failures/int64.json +38 -0
- data/spec/spec_tests/data/corpus_legacy/failures/symbol.json +62 -0
- data/spec/spec_tests/data/corpus_legacy/int32.json +38 -0
- data/spec/spec_tests/data/corpus_legacy/maxkey.json +12 -0
- data/spec/spec_tests/data/corpus_legacy/minkey.json +12 -0
- data/spec/spec_tests/data/corpus_legacy/null.json +12 -0
- data/spec/spec_tests/data/corpus_legacy/oid.json +28 -0
- data/spec/spec_tests/data/corpus_legacy/regex.json +37 -0
- data/spec/spec_tests/data/corpus_legacy/string.json +67 -0
- data/spec/spec_tests/data/corpus_legacy/timestamp.json +18 -0
- data/spec/spec_tests/data/corpus_legacy/top.json +62 -0
- data/spec/spec_tests/data/corpus_legacy/undefined.json +13 -0
- data/spec/spec_tests/data/decimal128/decimal128-1.json +363 -0
- data/spec/spec_tests/data/decimal128/decimal128-2.json +793 -0
- data/spec/spec_tests/data/decimal128/decimal128-3.json +1771 -0
- data/spec/spec_tests/data/decimal128/decimal128-4.json +165 -0
- data/spec/spec_tests/data/decimal128/decimal128-5.json +402 -0
- data/spec/spec_tests/data/decimal128/decimal128-6.json +131 -0
- data/spec/spec_tests/data/decimal128/decimal128-7.json +327 -0
- data/spec/support/shared_examples.rb +32 -11
- data/spec/support/spec_config.rb +17 -0
- data/spec/support/utils.rb +58 -0
- metadata +284 -45
- checksums.yaml.gz.sig +0 -3
- data/ext/bson/native.c +0 -722
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
# rubocop:todo all
|
|
2
|
+
# Copyright (C) 2016-2021 MongoDB Inc.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
require "spec_helper"
|
|
17
|
+
|
|
18
|
+
describe BigDecimal do
|
|
19
|
+
|
|
20
|
+
describe '#from_bson' do
|
|
21
|
+
shared_examples_for 'a BSON::BigDecimal deserializer' do
|
|
22
|
+
|
|
23
|
+
let(:decimal128) do
|
|
24
|
+
BSON::Decimal128.new(argument)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
let(:deserialized_big_decimal) do
|
|
28
|
+
BigDecimal.from_bson(decimal128.to_bson)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
let(:deserialized_decimal128) do
|
|
32
|
+
BSON::Decimal128.from_bson(decimal128.to_bson)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'deserializes Decimal128 encoded bson correctly' do
|
|
36
|
+
if deserialized_decimal128.to_s == "NaN"
|
|
37
|
+
expect(deserialized_big_decimal.nan?).to be true
|
|
38
|
+
else
|
|
39
|
+
expect(deserialized_big_decimal).to eq(deserialized_decimal128.to_d)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context 'when Infinity is passed' do
|
|
45
|
+
|
|
46
|
+
let(:argument) { "Infinity" }
|
|
47
|
+
|
|
48
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context 'when -Infinity is passed' do
|
|
52
|
+
|
|
53
|
+
let(:argument) { "-Infinity" }
|
|
54
|
+
|
|
55
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'when NaN is passed' do
|
|
59
|
+
|
|
60
|
+
let(:argument) { "NaN" }
|
|
61
|
+
|
|
62
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'when -NaN is passed' do
|
|
66
|
+
let(:argument) { "-NaN" }
|
|
67
|
+
|
|
68
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'when SNaN is passed' do
|
|
72
|
+
let(:argument) { "SNaN" }
|
|
73
|
+
|
|
74
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'when -SNaN is passed' do
|
|
78
|
+
let(:argument) { "SNaN" }
|
|
79
|
+
|
|
80
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context 'when -0 is passed' do
|
|
84
|
+
let(:argument) { "-0" }
|
|
85
|
+
|
|
86
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context 'when a positive integer is passed' do
|
|
90
|
+
let(:argument) { "12" }
|
|
91
|
+
|
|
92
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context 'when a negative integer is passed' do
|
|
96
|
+
let(:argument) { "-12" }
|
|
97
|
+
|
|
98
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
context 'when a positive float is passed' do
|
|
102
|
+
let(:argument) { "0.12345" }
|
|
103
|
+
|
|
104
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context 'when a negative float is passed' do
|
|
108
|
+
let(:argument) { "-0.12345" }
|
|
109
|
+
|
|
110
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context 'when a large positive integer is passed' do
|
|
114
|
+
let(:argument) { "1234567890123456789012345678901234" }
|
|
115
|
+
|
|
116
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
context 'when a large negative integer is passed' do
|
|
120
|
+
let(:argument) { "-1234567890123456789012345678901234" }
|
|
121
|
+
|
|
122
|
+
it_behaves_like 'a BSON::BigDecimal deserializer'
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
describe "#to_bson" do
|
|
127
|
+
shared_examples_for 'a BSON::BigDecimal serializer' do
|
|
128
|
+
|
|
129
|
+
let(:decimal128) do
|
|
130
|
+
BSON::Decimal128.new(BigDecimal(argument).to_s)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
let(:decimal_128_bson) do
|
|
134
|
+
decimal128.to_bson
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
let(:big_decimal_bson) do
|
|
138
|
+
BigDecimal(argument).to_bson
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it 'serializes BigDecimals correctly' do
|
|
142
|
+
expect(decimal_128_bson.to_s).to eq(big_decimal_bson.to_s)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
context 'when Infinity is passed' do
|
|
147
|
+
|
|
148
|
+
let(:argument) { "Infinity" }
|
|
149
|
+
|
|
150
|
+
it_behaves_like 'a BSON::BigDecimal serializer'
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
context 'when -Infinity is passed' do
|
|
154
|
+
|
|
155
|
+
let(:argument) { "-Infinity" }
|
|
156
|
+
|
|
157
|
+
it_behaves_like 'a BSON::BigDecimal serializer'
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
context 'when NaN is passed' do
|
|
161
|
+
|
|
162
|
+
let(:argument) { "NaN" }
|
|
163
|
+
|
|
164
|
+
it_behaves_like 'a BSON::BigDecimal serializer'
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
context 'when -0 is passed' do
|
|
168
|
+
let(:argument) { "-0" }
|
|
169
|
+
|
|
170
|
+
it_behaves_like 'a BSON::BigDecimal serializer'
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
context 'when a positive integer is passed' do
|
|
174
|
+
let(:argument) { "12" }
|
|
175
|
+
|
|
176
|
+
it_behaves_like 'a BSON::BigDecimal serializer'
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
context 'when a negative integer is passed' do
|
|
180
|
+
let(:argument) { "-12" }
|
|
181
|
+
|
|
182
|
+
it_behaves_like 'a BSON::BigDecimal serializer'
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
context 'when a positive float is passed' do
|
|
186
|
+
let(:argument) { "0.12345" }
|
|
187
|
+
|
|
188
|
+
it_behaves_like 'a BSON::BigDecimal serializer'
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
context 'when a negative float is passed' do
|
|
192
|
+
let(:argument) { "-0.12345" }
|
|
193
|
+
|
|
194
|
+
it_behaves_like 'a BSON::BigDecimal serializer'
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
context 'when a large positive integer is passed' do
|
|
198
|
+
let(:argument) { "1234567890123456789012345678901234" }
|
|
199
|
+
|
|
200
|
+
it_behaves_like 'a BSON::BigDecimal serializer'
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
context 'when a large negative integer is passed' do
|
|
204
|
+
let(:argument) { "-1234567890123456789012345678901234" }
|
|
205
|
+
|
|
206
|
+
it_behaves_like 'a BSON::BigDecimal serializer'
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
context "when passing an out of range Decimal128" do
|
|
210
|
+
let(:argument) { "1E1000000" }
|
|
211
|
+
|
|
212
|
+
it "raises an error" do
|
|
213
|
+
expect do
|
|
214
|
+
BigDecimal(argument).to_bson
|
|
215
|
+
end.to raise_error(BSON::Error::InvalidDecimal128Range)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
context "when passing a number with too much precision for Decimal128" do
|
|
220
|
+
let(:argument) { "1.000000000000000000000000000000000000000000000000001" }
|
|
221
|
+
|
|
222
|
+
it "raises an error" do
|
|
223
|
+
expect do
|
|
224
|
+
BigDecimal(argument).to_bson
|
|
225
|
+
end.to raise_error(BSON::Error::UnrepresentablePrecision)
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
describe "#from_bson/#to_bson" do
|
|
231
|
+
shared_examples_for 'a BSON::BigDecimal round trip' do
|
|
232
|
+
|
|
233
|
+
let(:big_decimal) do
|
|
234
|
+
BigDecimal(argument)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
let(:big_decimal_bson) do
|
|
238
|
+
big_decimal.to_bson
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
let(:deserialized_big_decimal) do
|
|
242
|
+
BigDecimal.from_bson(big_decimal_bson)
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
it 'serializes BigDecimals correctly' do
|
|
246
|
+
if big_decimal.nan?
|
|
247
|
+
expect(deserialized_big_decimal.nan?).to be true
|
|
248
|
+
else
|
|
249
|
+
expect(deserialized_big_decimal).to eq(big_decimal)
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
context 'when Infinity is passed' do
|
|
255
|
+
|
|
256
|
+
let(:argument) { "Infinity" }
|
|
257
|
+
|
|
258
|
+
it_behaves_like 'a BSON::BigDecimal round trip'
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
context 'when -Infinity is passed' do
|
|
262
|
+
|
|
263
|
+
let(:argument) { "-Infinity" }
|
|
264
|
+
|
|
265
|
+
it_behaves_like 'a BSON::BigDecimal round trip'
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
context 'when NaN is passed' do
|
|
269
|
+
|
|
270
|
+
let(:argument) { "NaN" }
|
|
271
|
+
|
|
272
|
+
it_behaves_like 'a BSON::BigDecimal round trip'
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
context 'when -0 is passed' do
|
|
276
|
+
let(:argument) { "-0" }
|
|
277
|
+
|
|
278
|
+
it_behaves_like 'a BSON::BigDecimal round trip'
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
context 'when a positive integer is passed' do
|
|
282
|
+
let(:argument) { "12" }
|
|
283
|
+
|
|
284
|
+
it_behaves_like 'a BSON::BigDecimal round trip'
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
context 'when a negative integer is passed' do
|
|
288
|
+
let(:argument) { "-12" }
|
|
289
|
+
|
|
290
|
+
it_behaves_like 'a BSON::BigDecimal round trip'
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
context 'when a positive float is passed' do
|
|
294
|
+
let(:argument) { "0.12345" }
|
|
295
|
+
|
|
296
|
+
it_behaves_like 'a BSON::BigDecimal round trip'
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
context 'when a negative float is passed' do
|
|
300
|
+
let(:argument) { "-0.12345" }
|
|
301
|
+
|
|
302
|
+
it_behaves_like 'a BSON::BigDecimal round trip'
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
context 'when a large positive integer is passed' do
|
|
306
|
+
let(:argument) { "1234567890123456789012345678901234" }
|
|
307
|
+
|
|
308
|
+
it_behaves_like 'a BSON::BigDecimal round trip'
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
context 'when a large negative integer is passed' do
|
|
312
|
+
let(:argument) { "-1234567890123456789012345678901234" }
|
|
313
|
+
|
|
314
|
+
it_behaves_like 'a BSON::BigDecimal round trip'
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
context "when the class is loaded" do
|
|
319
|
+
|
|
320
|
+
let(:registered) do
|
|
321
|
+
BSON::Registry.get(described_class::BSON_TYPE, 'field')
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "registers the type" do
|
|
325
|
+
expect(registered).to eq(described_class)
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
data/spec/bson/binary_spec.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# rubocop:todo all
|
|
2
|
+
# Copyright (C) 2009-2020 MongoDB Inc.
|
|
2
3
|
#
|
|
3
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
5
|
# you may not use this file except in compliance with the License.
|
|
@@ -13,22 +14,62 @@
|
|
|
13
14
|
# limitations under the License.
|
|
14
15
|
|
|
15
16
|
require "spec_helper"
|
|
17
|
+
require "base64"
|
|
16
18
|
|
|
17
19
|
describe BSON::Binary do
|
|
18
20
|
let(:testing1) { described_class.new("testing") }
|
|
19
21
|
let(:testing2) { described_class.new("testing") }
|
|
20
22
|
let(:not_testing) { described_class.new("not testing") }
|
|
23
|
+
let(:testing3) { described_class.new("testing", :user) }
|
|
24
|
+
|
|
25
|
+
describe "Comparable" do
|
|
26
|
+
describe "#eql?" do
|
|
27
|
+
context "for two equal objects" do
|
|
28
|
+
it "returns true" do
|
|
29
|
+
expect(testing1).to eql(testing2)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
21
32
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
context "for two different objects" do
|
|
34
|
+
it "returns false" do
|
|
35
|
+
expect(testing1).not_to eql(not_testing)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context 'for objects with identical data but different types' do
|
|
40
|
+
it 'returns false' do
|
|
41
|
+
expect(testing1).not_to eql(testing3)
|
|
42
|
+
end
|
|
26
43
|
end
|
|
27
44
|
end
|
|
28
45
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
46
|
+
describe '#<=>' do
|
|
47
|
+
context 'with a non-Binary object' do
|
|
48
|
+
it 'returns nil' do
|
|
49
|
+
expect(testing1 <=> 'bogus').to be_nil
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context 'with identical type and data' do
|
|
54
|
+
it 'returns 0' do
|
|
55
|
+
expect(testing1 <=> testing2).to be == 0
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
context 'with mismatched type' do
|
|
60
|
+
it 'returns nil' do
|
|
61
|
+
expect(testing1 <=> testing3).to be_nil
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'with identical type but mismatched data' do
|
|
66
|
+
it 'returns -1 when a < b' do
|
|
67
|
+
expect(not_testing <=> testing1).to be == -1
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'returns 1 when a > b' do
|
|
71
|
+
expect(testing1 <=> not_testing).to be == 1
|
|
72
|
+
end
|
|
32
73
|
end
|
|
33
74
|
end
|
|
34
75
|
end
|
|
@@ -54,34 +95,52 @@ describe BSON::Binary do
|
|
|
54
95
|
expect(hash[not_testing]).to be_nil
|
|
55
96
|
end
|
|
56
97
|
|
|
57
|
-
describe "#
|
|
98
|
+
describe "#as_extended_json" do
|
|
58
99
|
|
|
59
100
|
let(:object) do
|
|
60
101
|
described_class.new("testing", :user)
|
|
61
102
|
end
|
|
62
103
|
|
|
63
104
|
it "returns the binary data plus type" do
|
|
64
|
-
expect(object.
|
|
65
|
-
{ "$binary" => "testing", "
|
|
105
|
+
expect(object.as_extended_json).to eq(
|
|
106
|
+
{ "$binary" => {'base64' => Base64.encode64("testing").strip, "subType" => '80' }}
|
|
66
107
|
)
|
|
67
108
|
end
|
|
68
109
|
|
|
69
|
-
it_behaves_like
|
|
110
|
+
it_behaves_like 'an Extended JSON serializable object'
|
|
111
|
+
it_behaves_like '#as_json calls #as_extended_json'
|
|
70
112
|
end
|
|
71
113
|
|
|
72
114
|
describe "#initialize" do
|
|
73
115
|
|
|
74
|
-
context
|
|
116
|
+
context 'when type is not given' do
|
|
117
|
+
let(:obj) { described_class.new('foo') }
|
|
118
|
+
|
|
119
|
+
it 'defaults to generic type' do
|
|
120
|
+
expect(obj.type).to eq(:generic)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
context "when the type is invalid" do
|
|
75
125
|
|
|
76
126
|
it "raises an error" do
|
|
77
127
|
expect {
|
|
78
128
|
described_class.new("testing", :error)
|
|
79
129
|
}.to raise_error { |error|
|
|
80
|
-
expect(error).to be_a(BSON::
|
|
130
|
+
expect(error).to be_a(BSON::Error::InvalidBinaryType)
|
|
81
131
|
expect(error.message).to match /is not a valid binary type/
|
|
82
132
|
}
|
|
83
133
|
end
|
|
84
134
|
end
|
|
135
|
+
|
|
136
|
+
context 'when initialized via legacy YAML' do
|
|
137
|
+
let(:yaml) { "--- !ruby/object:BSON::Binary\ndata: hello\ntype: :generic\n" }
|
|
138
|
+
let(:deserialized) { YAML.safe_load(yaml, permitted_classes: [ Symbol, BSON::Binary ]) }
|
|
139
|
+
|
|
140
|
+
it 'correctly sets the raw_type' do
|
|
141
|
+
expect(deserialized.raw_type).to be == BSON::Binary::SUBTYPES[:generic]
|
|
142
|
+
end
|
|
143
|
+
end
|
|
85
144
|
end
|
|
86
145
|
|
|
87
146
|
describe '#inspect' do
|
|
@@ -104,7 +163,11 @@ describe BSON::Binary do
|
|
|
104
163
|
expect(object.inspect).to eq("<BSON::Binary:0x#{object.object_id} type=user data=0x1f8b08000c787055...>")
|
|
105
164
|
end
|
|
106
165
|
|
|
107
|
-
it 'is not
|
|
166
|
+
it 'is not binary' do
|
|
167
|
+
# As long as the default Ruby encoding is not binary, the inspected
|
|
168
|
+
# string should also not be in the binary encoding (it should be
|
|
169
|
+
# in one of the text encodings, but which one could depend on
|
|
170
|
+
# the Ruby runtime environment).
|
|
108
171
|
expect(object.inspect.encoding).not_to eq(Encoding::BINARY)
|
|
109
172
|
end
|
|
110
173
|
|
|
@@ -112,73 +175,156 @@ describe BSON::Binary do
|
|
|
112
175
|
|
|
113
176
|
end
|
|
114
177
|
|
|
115
|
-
describe
|
|
116
|
-
|
|
117
|
-
let(:
|
|
178
|
+
describe '#from_bson' do
|
|
179
|
+
let(:buffer) { BSON::ByteBuffer.new(bson) }
|
|
180
|
+
let(:obj) { described_class.from_bson(buffer) }
|
|
118
181
|
|
|
119
|
-
|
|
182
|
+
let(:bson) { "#{5.to_bson}#{0.chr}hello".force_encoding('BINARY') }
|
|
120
183
|
|
|
121
|
-
|
|
184
|
+
it 'sets data encoding to binary' do
|
|
185
|
+
expect(obj.data.encoding).to eq(Encoding.find('BINARY'))
|
|
186
|
+
end
|
|
122
187
|
|
|
123
|
-
|
|
124
|
-
let(:bson) {
|
|
188
|
+
context 'when binary subtype is supported' do
|
|
189
|
+
let(:bson) { [3, 0, 0, 0, 1].map(&:chr).join.force_encoding('BINARY') + 'foo' }
|
|
125
190
|
|
|
126
|
-
|
|
127
|
-
|
|
191
|
+
it 'works' do
|
|
192
|
+
obj.should be_a(described_class)
|
|
193
|
+
obj.type.should be :function
|
|
194
|
+
end
|
|
128
195
|
end
|
|
129
196
|
|
|
130
|
-
context
|
|
131
|
-
|
|
132
|
-
let(:obj) { described_class.new("testing", :function) }
|
|
133
|
-
let(:bson) { "#{7.to_bson}#{1.chr}testing" }
|
|
197
|
+
context 'when binary subtype is not supported' do
|
|
198
|
+
let(:bson) { [3, 0, 0, 0, 16].map(&:chr).join.force_encoding('BINARY') + 'foo' }
|
|
134
199
|
|
|
135
|
-
|
|
136
|
-
|
|
200
|
+
it 'raises an exception' do
|
|
201
|
+
lambda do
|
|
202
|
+
obj
|
|
203
|
+
end.should raise_error(BSON::Error::UnsupportedBinarySubtype,
|
|
204
|
+
/BSON data contains unsupported binary subtype 0x10/)
|
|
205
|
+
end
|
|
137
206
|
end
|
|
207
|
+
end
|
|
138
208
|
|
|
139
|
-
|
|
209
|
+
describe "#to_bson/#from_bson" do
|
|
140
210
|
|
|
141
|
-
|
|
142
|
-
let(:bson) { "#{11.to_bson}#{2.chr}#{7.to_bson}testing" }
|
|
211
|
+
let(:type) { 5.chr }
|
|
143
212
|
|
|
144
|
-
|
|
145
|
-
it_behaves_like "a deserializable bson element"
|
|
146
|
-
end
|
|
213
|
+
it_behaves_like "a bson element"
|
|
147
214
|
|
|
148
|
-
|
|
215
|
+
[
|
|
216
|
+
{
|
|
217
|
+
types: [ nil, 0, 0.chr, :generic, 'generic' ],
|
|
218
|
+
bson: "#{7.to_bson}#{0.chr}testing",
|
|
219
|
+
type: :generic,
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
types: [ 1, 1.chr, :function, 'function' ],
|
|
223
|
+
bson: "#{7.to_bson}#{1.chr}testing",
|
|
224
|
+
type: :function,
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
types: [ 2, 2.chr, :old, 'old' ],
|
|
228
|
+
bson: "#{11.to_bson}#{2.chr}#{7.to_bson}testing",
|
|
229
|
+
type: :old,
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
types: [ 3, 3.chr, :uuid_old, 'uuid_old' ],
|
|
233
|
+
bson: "#{7.to_bson}#{3.chr}testing",
|
|
234
|
+
type: :uuid_old,
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
types: [ 4, 4.chr, :uuid, 'uuid' ],
|
|
238
|
+
bson: "#{7.to_bson}#{4.chr}testing",
|
|
239
|
+
type: :uuid,
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
types: [ 5, 5.chr, :md5, 'md5' ],
|
|
243
|
+
bson: "#{7.to_bson}#{5.chr}testing",
|
|
244
|
+
type: :md5,
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
types: [ 6, 6.chr, :ciphertext, 'ciphertext' ],
|
|
248
|
+
bson: "#{7.to_bson}#{6.chr}testing",
|
|
249
|
+
type: :ciphertext,
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
types: [ 0x80, 0x80.chr, :user, 'user' ],
|
|
253
|
+
bson: "#{7.to_bson}#{128.chr}testing",
|
|
254
|
+
type: :user,
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
types: [ 0xFF, 0xFF.chr ],
|
|
258
|
+
bson: "#{7.to_bson}#{0xFF.chr}testing",
|
|
259
|
+
type: :user,
|
|
260
|
+
},
|
|
261
|
+
].each do |defn|
|
|
262
|
+
defn[:types].each do |type|
|
|
263
|
+
context "when the type is #{type ? type.inspect : 'not provided'}" do
|
|
264
|
+
let(:obj) do
|
|
265
|
+
if type
|
|
266
|
+
described_class.new("testing", type)
|
|
267
|
+
else
|
|
268
|
+
described_class.new("testing")
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
let(:bson) { defn[:bson] }
|
|
273
|
+
|
|
274
|
+
it_behaves_like "a serializable bson element"
|
|
275
|
+
it_behaves_like "a deserializable bson element"
|
|
276
|
+
|
|
277
|
+
it "reports its type as #{defn[:type].inspect}" do
|
|
278
|
+
expect(obj.type).to be == defn[:type]
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
149
283
|
|
|
150
|
-
|
|
151
|
-
let(:
|
|
284
|
+
context 'when given binary string' do
|
|
285
|
+
let(:obj) { described_class.new("\x00\xfe\xff".force_encoding('BINARY')) }
|
|
286
|
+
let(:bson) { "#{3.to_bson}#{0.chr}\x00\xfe\xff".force_encoding('BINARY') }
|
|
152
287
|
|
|
153
288
|
it_behaves_like "a serializable bson element"
|
|
154
289
|
it_behaves_like "a deserializable bson element"
|
|
155
290
|
end
|
|
156
291
|
|
|
157
|
-
context
|
|
158
|
-
|
|
159
|
-
let(:obj)
|
|
160
|
-
let(:bson) { "#{
|
|
292
|
+
context 'when given a frozen string' do
|
|
293
|
+
let(:str) { "\x00\xfe\xff".force_encoding('BINARY').freeze }
|
|
294
|
+
let(:obj) { described_class.new(str) }
|
|
295
|
+
let(:bson) { "#{3.to_bson}#{0.chr}\x00\xfe\xff".force_encoding('BINARY') }
|
|
161
296
|
|
|
162
297
|
it_behaves_like "a serializable bson element"
|
|
163
298
|
it_behaves_like "a deserializable bson element"
|
|
164
299
|
end
|
|
300
|
+
end
|
|
165
301
|
|
|
166
|
-
|
|
302
|
+
describe '#to_uuid' do
|
|
303
|
+
let(:obj) { described_class.new("\x00" * 16, :uuid) }
|
|
167
304
|
|
|
168
|
-
|
|
169
|
-
|
|
305
|
+
it 'accepts symbol representation' do
|
|
306
|
+
expect(obj.to_uuid(:standard)).to eq('00000000-0000-0000-0000-000000000000')
|
|
307
|
+
end
|
|
170
308
|
|
|
171
|
-
|
|
172
|
-
|
|
309
|
+
it 'rejects string representation' do
|
|
310
|
+
expect do
|
|
311
|
+
obj.to_uuid('standard')
|
|
312
|
+
end.to raise_error(ArgumentError, /Representation must be given as a symbol/)
|
|
173
313
|
end
|
|
314
|
+
end
|
|
174
315
|
|
|
175
|
-
|
|
316
|
+
describe '#from_uuid' do
|
|
317
|
+
let(:uuid) { '00000000-0000-0000-0000000000000000' }
|
|
176
318
|
|
|
177
|
-
|
|
178
|
-
|
|
319
|
+
it 'accepts symbol representation' do
|
|
320
|
+
obj = described_class.from_uuid(uuid, :standard)
|
|
321
|
+
expect(obj.data).to eq("\x00" * 16)
|
|
322
|
+
end
|
|
179
323
|
|
|
180
|
-
|
|
181
|
-
|
|
324
|
+
it 'rejects string representation' do
|
|
325
|
+
expect do
|
|
326
|
+
described_class.from_uuid(uuid, 'standard')
|
|
327
|
+
end.to raise_error(ArgumentError, /Representation must be given as a symbol/)
|
|
182
328
|
end
|
|
183
329
|
end
|
|
184
330
|
end
|