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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Rakefile +18 -3
- data/lib/bson-ruby.jar +0 -0
- data/lib/bson.rb +6 -4
- data/lib/bson/array.rb +1 -1
- data/lib/bson/binary.rb +4 -2
- data/lib/bson/code.rb +1 -1
- data/lib/bson/code_with_scope.rb +1 -1
- data/lib/bson/config.rb +1 -1
- data/lib/bson/date.rb +1 -1
- data/lib/bson/date_time.rb +1 -1
- data/lib/bson/decimal128.rb +318 -0
- data/lib/bson/decimal128/builder.rb +448 -0
- data/lib/bson/document.rb +2 -2
- data/lib/bson/environment.rb +13 -1
- data/lib/bson/false_class.rb +1 -1
- data/lib/bson/float.rb +1 -1
- data/lib/bson/hash.rb +1 -1
- data/lib/bson/int32.rb +46 -0
- data/lib/bson/int64.rb +46 -0
- data/lib/bson/integer.rb +1 -1
- data/lib/bson/max_key.rb +1 -1
- data/lib/bson/min_key.rb +1 -1
- data/lib/bson/object_id.rb +3 -2
- data/lib/bson/open_struct.rb +57 -0
- data/lib/bson/regexp.rb +87 -19
- data/lib/bson/registry.rb +1 -1
- data/lib/bson/specialized.rb +1 -1
- data/lib/bson/string.rb +1 -1
- data/lib/bson/symbol.rb +1 -1
- data/lib/bson/time.rb +1 -1
- data/lib/bson/timestamp.rb +2 -2
- data/lib/bson/true_class.rb +1 -1
- data/lib/bson/version.rb +2 -2
- data/spec/bson/array_spec.rb +1 -1
- data/spec/bson/binary_spec.rb +2 -1
- data/spec/bson/corpus_spec.rb +68 -0
- data/spec/bson/decimal128_spec.rb +1583 -0
- data/spec/bson/document_spec.rb +1 -1
- data/spec/bson/driver_bson_spec.rb +77 -0
- data/spec/bson/int32_spec.rb +58 -0
- data/spec/bson/int64_spec.rb +58 -0
- data/spec/bson/open_struct_spec.rb +144 -0
- data/spec/bson/raw_spec.rb +540 -0
- data/spec/bson/regexp_spec.rb +7 -7
- data/spec/bson/timestamp_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -0
- data/spec/support/common_driver.rb +347 -0
- data/spec/support/corpus-tests/array.json +43 -0
- data/spec/support/corpus-tests/boolean.json +27 -0
- data/spec/support/corpus-tests/code.json +67 -0
- data/spec/support/corpus-tests/code_w_scope.json +78 -0
- data/spec/support/corpus-tests/document.json +36 -0
- data/spec/support/corpus-tests/double.json +69 -0
- data/spec/support/corpus-tests/failures/binary.json +69 -0
- data/spec/support/corpus-tests/failures/datetime.json +31 -0
- data/spec/support/corpus-tests/failures/dbpointer.json +42 -0
- data/spec/support/corpus-tests/failures/int64.json +38 -0
- data/spec/support/corpus-tests/failures/symbol.json +62 -0
- data/spec/support/corpus-tests/failures/undefined.json +13 -0
- data/spec/support/corpus-tests/int32.json +38 -0
- data/spec/support/corpus-tests/maxkey.json +12 -0
- data/spec/support/corpus-tests/minkey.json +12 -0
- data/spec/support/corpus-tests/null.json +12 -0
- data/spec/support/corpus-tests/oid.json +28 -0
- data/spec/support/corpus-tests/regex.json +37 -0
- data/spec/support/corpus-tests/string.json +67 -0
- data/spec/support/corpus-tests/timestamp.json +18 -0
- data/spec/support/corpus-tests/top.json +62 -0
- data/spec/support/corpus.rb +265 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-1.json +363 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-2.json +793 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-3.json +1771 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-4.json +165 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-5.json +402 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-6.json +131 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-7.json +327 -0
- data/spec/support/shared_examples.rb +1 -1
- metadata +77 -4
- metadata.gz.sig +0 -0
data/lib/bson/specialized.rb
CHANGED
@@ -42,7 +42,7 @@ module BSON
|
|
42
42
|
# @example Encode the min key value.
|
43
43
|
# min_key.to_bson
|
44
44
|
#
|
45
|
-
# @return [
|
45
|
+
# @return [ BSON::ByteBuffer ] The buffer with the encoded object.
|
46
46
|
#
|
47
47
|
# @since 2.0.0
|
48
48
|
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
data/lib/bson/string.rb
CHANGED
data/lib/bson/symbol.rb
CHANGED
data/lib/bson/time.rb
CHANGED
@@ -32,7 +32,7 @@ module BSON
|
|
32
32
|
# @example Get the time as encoded BSON.
|
33
33
|
# Time.new(2012, 1, 1, 0, 0, 0).to_bson
|
34
34
|
#
|
35
|
-
# @return [
|
35
|
+
# @return [ BSON::ByteBuffer ] The buffer with the encoded object.
|
36
36
|
#
|
37
37
|
# @see http://bsonspec.org/#/specification
|
38
38
|
#
|
data/lib/bson/timestamp.rb
CHANGED
@@ -61,7 +61,7 @@ module BSON
|
|
61
61
|
#
|
62
62
|
# @since 2.0.0
|
63
63
|
def as_json(*args)
|
64
|
-
{ "t" => seconds, "i" => increment }
|
64
|
+
{ "$timestamp" => { "t" => seconds, "i" => increment } }
|
65
65
|
end
|
66
66
|
|
67
67
|
# Instantiate the new timestamp.
|
@@ -82,7 +82,7 @@ module BSON
|
|
82
82
|
# @example Get the timestamp as BSON.
|
83
83
|
# timestamp.to_bson
|
84
84
|
#
|
85
|
-
# @return [
|
85
|
+
# @return [ BSON::ByteBuffer ] The buffer with the encoded object.
|
86
86
|
#
|
87
87
|
# @see http://bsonspec.org/#/specification
|
88
88
|
#
|
data/lib/bson/true_class.rb
CHANGED
data/lib/bson/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
1
|
+
# Copyright (C) 2009-2016 MongoDB Inc.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -13,5 +13,5 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
module BSON
|
16
|
-
VERSION = "4.
|
16
|
+
VERSION = "4.2.0".freeze
|
17
17
|
end
|
data/spec/bson/array_spec.rb
CHANGED
data/spec/bson/binary_spec.rb
CHANGED
@@ -13,6 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
require "spec_helper"
|
16
|
+
require "base64"
|
16
17
|
|
17
18
|
describe BSON::Binary do
|
18
19
|
let(:testing1) { described_class.new("testing") }
|
@@ -62,7 +63,7 @@ describe BSON::Binary do
|
|
62
63
|
|
63
64
|
it "returns the binary data plus type" do
|
64
65
|
expect(object.as_json).to eq(
|
65
|
-
{ "$binary" => "testing", "$type" => :user }
|
66
|
+
{ "$binary" => Base64.encode64("testing"), "$type" => :user }
|
66
67
|
)
|
67
68
|
end
|
68
69
|
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Driver BSON Corpus spec tests' do
|
4
|
+
|
5
|
+
specs = BSON_CORPUS_TESTS.map { |file| BSON::Corpus::Spec.new(file) }
|
6
|
+
|
7
|
+
specs.each do |spec|
|
8
|
+
|
9
|
+
context(spec.description) do
|
10
|
+
|
11
|
+
spec.valid_tests.each do |test|
|
12
|
+
|
13
|
+
context("VALID CASE: #{test.description}") do
|
14
|
+
|
15
|
+
it 'roundtrips the given bson correctly' do
|
16
|
+
expect(test.reencoded_bson).to eq(test.correct_bson)
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when the canonical bson is roundtripped', if: test.test_canonical_bson? do
|
20
|
+
|
21
|
+
it 'encodes the canonical bson correctly' do
|
22
|
+
expect(test.reencoded_canonical_bson).to eq(test.correct_bson)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when the document can be represented as extended json', if: test.test_extjson? do
|
27
|
+
|
28
|
+
it 'decodes from the given bson, then encodes the document as extended json correctly' do
|
29
|
+
skip 'The extended json in this test case does not match' unless (test.extjson_from_bson == test.correct_extjson)
|
30
|
+
expect(test.extjson_from_bson).to eq(test.correct_extjson)
|
31
|
+
expect(test.extjson_from_bson[test.test_key]).to eq(test.correct_extjson[test.test_key])
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'decodes from extended json, then encodes the document as extended json correctly' do
|
35
|
+
expect(test.extjson_from_encoded_extjson).to eq(test.correct_extjson)
|
36
|
+
expect(test.extjson_from_encoded_extjson[test.test_key]).to eq(test.correct_extjson[test.test_key])
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when the canonical bson can be represented as extended json', if: (test.test_canonical_bson? && test.test_extjson?) do
|
40
|
+
|
41
|
+
it 'encodes the canonical bson correctly as extended json' do
|
42
|
+
expect(test.extjson_from_canonical_bson).to eq(test.correct_extjson)
|
43
|
+
expect(test.extjson_from_canonical_bson[test.test_key]).to eq(test.correct_extjson[test.test_key])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
spec.invalid_tests.each do |test|
|
51
|
+
|
52
|
+
context("INVALID CASE: #{test.description}") do
|
53
|
+
|
54
|
+
let(:error) do
|
55
|
+
begin; test.reencoded_bson; false; rescue => e; e; end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'raises an error' do
|
59
|
+
skip 'This test case does not raise and error but should' unless error
|
60
|
+
expect {
|
61
|
+
test.reencoded_bson
|
62
|
+
}.to raise_error
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,1583 @@
|
|
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 "spec_helper"
|
16
|
+
|
17
|
+
describe BSON::Decimal128 do
|
18
|
+
|
19
|
+
let(:low_bits) do
|
20
|
+
decimal128.instance_variable_get(:@low)
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:high_bits) do
|
24
|
+
decimal128.instance_variable_get(:@high)
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#initialize' do
|
28
|
+
|
29
|
+
context 'when the argument is neither a BigDecimal or String' do
|
30
|
+
|
31
|
+
it 'raises an ArgumentError' do
|
32
|
+
expect {
|
33
|
+
described_class.new(:invalid)
|
34
|
+
}.to raise_exception(ArgumentError)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
shared_examples_for 'an initialized BSON::Decimal128' do
|
39
|
+
|
40
|
+
let(:decimal128) do
|
41
|
+
described_class.new(argument)
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:buffer) do
|
45
|
+
decimal128.to_bson
|
46
|
+
end
|
47
|
+
|
48
|
+
let(:from_bson) do
|
49
|
+
described_class.from_bson(buffer)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'sets the correct high order bits' do
|
53
|
+
expect(high_bits).to eq(expected_high_bits)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'sets the correct low order bits' do
|
57
|
+
expect(low_bits).to eq(expected_low_bits)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'serializes to bson' do
|
61
|
+
expect(buffer.length).to eq(16)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'deserializes to the correct bits' do
|
65
|
+
expect(from_bson.instance_variable_get(:@high)).to eq(expected_high_bits)
|
66
|
+
expect(from_bson.instance_variable_get(:@low)).to eq(expected_low_bits)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when the object represents positive infinity' do
|
71
|
+
|
72
|
+
let(:expected_high_bits) { 0x7800000000000000 }
|
73
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
74
|
+
|
75
|
+
context 'when a BigDecimal is passed' do
|
76
|
+
|
77
|
+
let(:argument) { BigDecimal.new("Infinity") }
|
78
|
+
|
79
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when a String is passed' do
|
83
|
+
|
84
|
+
let(:argument) { "Infinity" }
|
85
|
+
|
86
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when the object represents negative infinity' do
|
91
|
+
|
92
|
+
let(:expected_high_bits) { 0xf800000000000000 }
|
93
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
94
|
+
|
95
|
+
context 'when a BigDecimal is passed' do
|
96
|
+
|
97
|
+
let(:argument) { BigDecimal.new("-Infinity") }
|
98
|
+
|
99
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when a String is passed' do
|
103
|
+
|
104
|
+
let(:argument) { "-Infinity" }
|
105
|
+
|
106
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'when the object represents NaN' do
|
111
|
+
|
112
|
+
let(:expected_high_bits) { 0x7c00000000000000 }
|
113
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
114
|
+
|
115
|
+
context 'when a BigDecimal is passed' do
|
116
|
+
|
117
|
+
let(:argument) { BigDecimal.new("NaN") }
|
118
|
+
|
119
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'when a String is passed' do
|
123
|
+
|
124
|
+
let(:argument) { "NaN" }
|
125
|
+
|
126
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'when the object represents -NaN' do
|
131
|
+
|
132
|
+
let(:expected_high_bits) { 0xfc00000000000000 }
|
133
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
134
|
+
|
135
|
+
context 'when a String is passed' do
|
136
|
+
|
137
|
+
let(:argument) { "-NaN" }
|
138
|
+
|
139
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'when the object represents SNaN' do
|
144
|
+
|
145
|
+
let(:expected_high_bits) { 0x7e00000000000000 }
|
146
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
147
|
+
|
148
|
+
context 'when a String is passed' do
|
149
|
+
|
150
|
+
let(:argument) { "SNaN" }
|
151
|
+
|
152
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'when the object represents -SNaN' do
|
157
|
+
|
158
|
+
let(:expected_high_bits) { 0xfe00000000000000 }
|
159
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
160
|
+
|
161
|
+
context 'when a String is passed' do
|
162
|
+
|
163
|
+
let(:argument) { "-SNaN" }
|
164
|
+
|
165
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'when the object represents -0' do
|
170
|
+
|
171
|
+
let(:expected_high_bits) { 0xb040000000000000 }
|
172
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
173
|
+
|
174
|
+
context 'when a BigDecimal is passed' do
|
175
|
+
|
176
|
+
let(:argument) { BigDecimal.new("-0") }
|
177
|
+
|
178
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
179
|
+
end
|
180
|
+
|
181
|
+
context 'when a String is passed' do
|
182
|
+
|
183
|
+
let(:argument) { "-0" }
|
184
|
+
|
185
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'when the object represents a positive integer' do
|
190
|
+
|
191
|
+
let(:expected_high_bits) { 0x3040000000000000 }
|
192
|
+
let(:expected_low_bits) { 0x000000000000000c }
|
193
|
+
|
194
|
+
context 'when a BigDecimal is passed' do
|
195
|
+
|
196
|
+
let(:argument) { BigDecimal.new(12) }
|
197
|
+
|
198
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'when a String is passed' do
|
202
|
+
|
203
|
+
let(:argument) { "12" }
|
204
|
+
|
205
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'when the object represents a negative integer' do
|
210
|
+
|
211
|
+
let(:expected_high_bits) { 0xb040000000000000 }
|
212
|
+
let(:expected_low_bits) { 0x000000000000000c }
|
213
|
+
|
214
|
+
context 'when a BigDecimal is passed' do
|
215
|
+
|
216
|
+
let(:argument) { BigDecimal.new(-12) }
|
217
|
+
|
218
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
219
|
+
end
|
220
|
+
|
221
|
+
context 'when a String is passed' do
|
222
|
+
|
223
|
+
let(:argument) { "-12" }
|
224
|
+
|
225
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context 'when the object represents a positive float' do
|
230
|
+
|
231
|
+
let(:expected_high_bits) { 0x3036000000000000 }
|
232
|
+
let(:expected_low_bits) { 0x0000000000003039 }
|
233
|
+
|
234
|
+
context 'when a BigDecimal is passed' do
|
235
|
+
|
236
|
+
let(:argument) { BigDecimal.new(0.12345, 5) }
|
237
|
+
|
238
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
239
|
+
end
|
240
|
+
|
241
|
+
context 'when a String is passed' do
|
242
|
+
|
243
|
+
let(:argument) { "0.12345" }
|
244
|
+
|
245
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
context 'when the object represents a negative float' do
|
250
|
+
|
251
|
+
let(:expected_high_bits) { 0xb036000000000000 }
|
252
|
+
let(:expected_low_bits) { 0x0000000000003039 }
|
253
|
+
|
254
|
+
context 'when a BigDecimal is passed' do
|
255
|
+
|
256
|
+
let(:argument) { BigDecimal.new(-0.12345, 5) }
|
257
|
+
|
258
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
259
|
+
end
|
260
|
+
|
261
|
+
context 'when a String is passed' do
|
262
|
+
|
263
|
+
let(:argument) { "-0.12345" }
|
264
|
+
|
265
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
context 'when the object represents a large positive integer' do
|
270
|
+
|
271
|
+
let(:expected_high_bits) { 0x30403cde6fff9732 }
|
272
|
+
let(:expected_low_bits) { 0xde825cd07e96aff2 }
|
273
|
+
|
274
|
+
context 'when a BigDecimal is passed' do
|
275
|
+
|
276
|
+
let(:argument) { BigDecimal.new(1234567890123456789012345678901234) }
|
277
|
+
|
278
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
279
|
+
end
|
280
|
+
|
281
|
+
context 'when a String is passed' do
|
282
|
+
|
283
|
+
let(:argument) { "1234567890123456789012345678901234" }
|
284
|
+
|
285
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
context 'when the object represents a large negative integer' do
|
290
|
+
|
291
|
+
let(:expected_high_bits) { 0xb0403cde6fff9732 }
|
292
|
+
let(:expected_low_bits) { 0xde825cd07e96aff2 }
|
293
|
+
|
294
|
+
context 'when a BigDecimal is passed' do
|
295
|
+
|
296
|
+
let(:argument) { BigDecimal.new(-1234567890123456789012345678901234) }
|
297
|
+
|
298
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
299
|
+
end
|
300
|
+
|
301
|
+
context 'when a String is passed' do
|
302
|
+
|
303
|
+
let(:argument) { "-1234567890123456789012345678901234" }
|
304
|
+
|
305
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
context 'when deserializing' do
|
311
|
+
|
312
|
+
context 'When the value has trailing zeroes' do
|
313
|
+
|
314
|
+
let(:hex) do
|
315
|
+
'18000000136400D0070000000000000000000000003A3000'
|
316
|
+
end
|
317
|
+
|
318
|
+
let(:packed) do
|
319
|
+
[ hex ].pack('H*')
|
320
|
+
end
|
321
|
+
|
322
|
+
let(:buffer) do
|
323
|
+
BSON::ByteBuffer.new(packed)
|
324
|
+
end
|
325
|
+
|
326
|
+
let(:decimal128) do
|
327
|
+
BSON::Document.from_bson(buffer)['d']
|
328
|
+
end
|
329
|
+
|
330
|
+
let(:object_from_string) do
|
331
|
+
BSON::Decimal128.from_string('2.000')
|
332
|
+
end
|
333
|
+
|
334
|
+
it 'has the correct high order' do
|
335
|
+
expect(decimal128.instance_variable_get(:@high)).to eq(3475090062469758976)
|
336
|
+
end
|
337
|
+
|
338
|
+
it 'has the correct low order' do
|
339
|
+
expect(decimal128.instance_variable_get(:@low)).to eq(2000)
|
340
|
+
end
|
341
|
+
|
342
|
+
it 'matches the object created from a string' do
|
343
|
+
expect(object_from_string).to eq(decimal128)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
describe '#from_string' do
|
349
|
+
|
350
|
+
shared_examples_for 'a decimal128 initialized from a string' do
|
351
|
+
|
352
|
+
let(:decimal128) do
|
353
|
+
BSON::Decimal128.from_string(string)
|
354
|
+
end
|
355
|
+
|
356
|
+
let(:low_bits) do
|
357
|
+
decimal128.instance_variable_get(:@low)
|
358
|
+
end
|
359
|
+
|
360
|
+
let(:high_bits) do
|
361
|
+
decimal128.instance_variable_get(:@high)
|
362
|
+
end
|
363
|
+
|
364
|
+
it 'sets the correct high order bits' do
|
365
|
+
expect(high_bits).to eq(expected_high_bits)
|
366
|
+
end
|
367
|
+
|
368
|
+
it 'sets the correct low order bits' do
|
369
|
+
expect(low_bits).to eq(expected_low_bits)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
context 'when the string represents a special type' do
|
374
|
+
|
375
|
+
context "when the string is 'NaN'" do
|
376
|
+
|
377
|
+
let(:string) { 'NaN' }
|
378
|
+
|
379
|
+
let(:expected_high_bits) { 0x7c00000000000000 }
|
380
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
381
|
+
|
382
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
383
|
+
end
|
384
|
+
|
385
|
+
context "when the string is '-NaN'" do
|
386
|
+
|
387
|
+
let(:string) { '-NaN' }
|
388
|
+
|
389
|
+
let(:expected_high_bits) { 0xfc00000000000000 }
|
390
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
391
|
+
|
392
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
393
|
+
end
|
394
|
+
|
395
|
+
context "when the string is 'SNaN'" do
|
396
|
+
|
397
|
+
let(:string) { 'SNaN' }
|
398
|
+
|
399
|
+
let(:expected_high_bits) { 0x7e00000000000000 }
|
400
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
401
|
+
|
402
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
403
|
+
end
|
404
|
+
|
405
|
+
context "when the string is '-SNaN'" do
|
406
|
+
|
407
|
+
let(:string) { '-SNaN' }
|
408
|
+
|
409
|
+
let(:expected_high_bits) { 0xfe00000000000000 }
|
410
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
411
|
+
|
412
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
413
|
+
end
|
414
|
+
|
415
|
+
context "when the string is 'Infinity'" do
|
416
|
+
|
417
|
+
let(:string) { 'Infinity' }
|
418
|
+
|
419
|
+
let(:expected_exponent) { nil }
|
420
|
+
let(:expected_significand) { nil }
|
421
|
+
let(:expected_high_bits) { 0x7800000000000000 }
|
422
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
423
|
+
|
424
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
425
|
+
end
|
426
|
+
|
427
|
+
context "when the string is '-Infinity'" do
|
428
|
+
|
429
|
+
let(:string) { '-Infinity' }
|
430
|
+
|
431
|
+
let(:expected_exponent) { nil }
|
432
|
+
let(:expected_significand) { nil }
|
433
|
+
let(:expected_high_bits) { 0xf800000000000000 }
|
434
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
435
|
+
|
436
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
context 'when the string represents 0' do
|
441
|
+
|
442
|
+
context "when the string is '0'" do
|
443
|
+
|
444
|
+
let(:string) { '0' }
|
445
|
+
|
446
|
+
let(:expected_exponent) { 0 }
|
447
|
+
let(:expected_significand) { 0 }
|
448
|
+
let(:expected_high_bits) { 0x3040000000000000 }
|
449
|
+
let(:expected_low_bits) { 0 }
|
450
|
+
|
451
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
452
|
+
end
|
453
|
+
|
454
|
+
context "when the string is '-0'" do
|
455
|
+
|
456
|
+
let(:string) { '-0' }
|
457
|
+
|
458
|
+
let(:expected_exponent) { 0 }
|
459
|
+
let(:expected_significand) { 0 }
|
460
|
+
let(:expected_high_bits) { 0xb040000000000000 }
|
461
|
+
let(:expected_low_bits) { 0 }
|
462
|
+
|
463
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
464
|
+
end
|
465
|
+
|
466
|
+
context "when the string is '0.0'" do
|
467
|
+
|
468
|
+
let(:string) { '0.0' }
|
469
|
+
|
470
|
+
let(:expected_exponent) { -1 }
|
471
|
+
let(:expected_significand) { 0 }
|
472
|
+
let(:expected_high_bits) { 0x303e000000000000 }
|
473
|
+
let(:expected_low_bits) { 0 }
|
474
|
+
|
475
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
context 'when the string represents an integer' do
|
480
|
+
|
481
|
+
context "when the string is '1'" do
|
482
|
+
|
483
|
+
let(:string) { '1' }
|
484
|
+
|
485
|
+
let(:expected_exponent) { 0 }
|
486
|
+
let(:expected_significand) { 1 }
|
487
|
+
let(:expected_high_bits) { 0x3040000000000000 }
|
488
|
+
let(:expected_low_bits) { 0x1 }
|
489
|
+
|
490
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
491
|
+
end
|
492
|
+
|
493
|
+
context "when the string is '-1'" do
|
494
|
+
|
495
|
+
let(:string) { '-1'}
|
496
|
+
|
497
|
+
let(:expected_exponent) { 0 }
|
498
|
+
let(:expected_significand) { 1 }
|
499
|
+
let(:expected_high_bits) { 0xb040000000000000 }
|
500
|
+
let(:expected_low_bits) { 0x1 }
|
501
|
+
|
502
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
503
|
+
end
|
504
|
+
|
505
|
+
context "when the string is '20'" do
|
506
|
+
|
507
|
+
let(:string) { '20' }
|
508
|
+
|
509
|
+
let(:expected_exponent) { 0 }
|
510
|
+
let(:expected_significand) { 20 }
|
511
|
+
let(:expected_low_bits) { 0x14 }
|
512
|
+
let(:expected_high_bits) { 0x3040000000000000 }
|
513
|
+
|
514
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
515
|
+
end
|
516
|
+
|
517
|
+
context "when the string is '-20'" do
|
518
|
+
|
519
|
+
let(:string) { '-20' }
|
520
|
+
|
521
|
+
let(:expected_exponent) { 0 }
|
522
|
+
let(:expected_significand) { 20 }
|
523
|
+
let(:expected_low_bits) { 0x14 }
|
524
|
+
let(:expected_high_bits) { 0xb040000000000000 }
|
525
|
+
|
526
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
527
|
+
end
|
528
|
+
|
529
|
+
context "when the string is '12345678901234567'" do
|
530
|
+
|
531
|
+
let(:string) { '12345678901234567' }
|
532
|
+
|
533
|
+
let(:expected_exponent) { 0 }
|
534
|
+
let(:expected_significand) { 12345678901234567 }
|
535
|
+
let(:expected_low_bits) { 0x002bdc545d6b4b87 }
|
536
|
+
let(:expected_high_bits) { 0x3040000000000000 }
|
537
|
+
|
538
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
539
|
+
end
|
540
|
+
|
541
|
+
context "when the string is '-12345678901234567'" do
|
542
|
+
|
543
|
+
let(:string) { '-12345678901234567' }
|
544
|
+
|
545
|
+
let(:expected_exponent) { 0 }
|
546
|
+
let(:expected_significand) { 12345678901234567 }
|
547
|
+
let(:expected_low_bits) { 0x002bdc545d6b4b87 }
|
548
|
+
let(:expected_high_bits) { 0xb040000000000000 }
|
549
|
+
|
550
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
551
|
+
end
|
552
|
+
|
553
|
+
context "when the string is '12345689012345789012345'" do
|
554
|
+
|
555
|
+
let(:string) { '12345689012345789012345' }
|
556
|
+
|
557
|
+
let(:expected_exponent) { 0 }
|
558
|
+
let(:expected_significand) { 12345689012345789012345 }
|
559
|
+
let(:expected_low_bits) { 0x42da3a76f9e0d979 }
|
560
|
+
let(:expected_high_bits) { 0x304000000000029d }
|
561
|
+
|
562
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
563
|
+
end
|
564
|
+
|
565
|
+
context "when the string is '-12345689012345789012345'" do
|
566
|
+
|
567
|
+
let(:string) { '-12345689012345789012345' }
|
568
|
+
|
569
|
+
let(:expected_exponent) { 0 }
|
570
|
+
let(:expected_significand) { 12345689012345789012345 }
|
571
|
+
let(:expected_low_bits) { 0x42da3a76f9e0d979 }
|
572
|
+
let(:expected_high_bits) { 0xb04000000000029d }
|
573
|
+
|
574
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
context 'when the string represents a fraction' do
|
579
|
+
|
580
|
+
context "when the string is '0.1'" do
|
581
|
+
|
582
|
+
let(:string) { '0.1' }
|
583
|
+
|
584
|
+
let(:expected_exponent) { -1 }
|
585
|
+
let(:expected_significand) { 1 }
|
586
|
+
let(:expected_low_bits) { 0x1 }
|
587
|
+
let(:expected_high_bits) { 0x303e000000000000 }
|
588
|
+
|
589
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
590
|
+
end
|
591
|
+
|
592
|
+
context "when the string is '-0.1'" do
|
593
|
+
|
594
|
+
let(:string) { '-0.1' }
|
595
|
+
|
596
|
+
let(:expected_exponent) { -1 }
|
597
|
+
let(:expected_significand) { 1 }
|
598
|
+
let(:expected_low_bits) { 0x1 }
|
599
|
+
let(:expected_high_bits) { 0xb03e000000000000 }
|
600
|
+
|
601
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
602
|
+
end
|
603
|
+
|
604
|
+
context "when the string is '0.123'" do
|
605
|
+
|
606
|
+
let(:string) { '0.123' }
|
607
|
+
|
608
|
+
let(:expected_exponent) { -3 }
|
609
|
+
let(:expected_significand) { 123 }
|
610
|
+
let(:expected_low_bits) { 0x7b }
|
611
|
+
let(:expected_high_bits) { 0x303a000000000000 }
|
612
|
+
|
613
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
614
|
+
end
|
615
|
+
|
616
|
+
context "when the string is '-0.123'" do
|
617
|
+
|
618
|
+
let(:string) { '-0.123' }
|
619
|
+
|
620
|
+
let(:expected_exponent) { -3 }
|
621
|
+
let(:expected_significand) { 123 }
|
622
|
+
let(:expected_low_bits) { 0x7b }
|
623
|
+
let(:expected_high_bits) { 0xb03a000000000000 }
|
624
|
+
|
625
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
626
|
+
end
|
627
|
+
|
628
|
+
context "when the string is '0.1234567890123456789012345678901234'" do
|
629
|
+
|
630
|
+
let(:string) { '0.1234567890123456789012345678901234' }
|
631
|
+
|
632
|
+
let(:expected_exponent) { -34 }
|
633
|
+
let(:expected_significand) { 1234567890123456789012345678901234 }
|
634
|
+
let(:expected_low_bits) { 0xde825cd07e96aff2 }
|
635
|
+
let(:expected_high_bits) { 0x2ffc3cde6fff9732 }
|
636
|
+
|
637
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
641
|
+
context 'when the string represents a fraction with a whole number' do
|
642
|
+
|
643
|
+
context "when the string is '1.2'" do
|
644
|
+
|
645
|
+
let(:string) { '1.2' }
|
646
|
+
|
647
|
+
let(:expected_exponent) { -1 }
|
648
|
+
let(:expected_significand) { 12 }
|
649
|
+
let(:expected_low_bits) { 0xc }
|
650
|
+
let(:expected_high_bits) { 0x303e000000000000 }
|
651
|
+
|
652
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
653
|
+
end
|
654
|
+
|
655
|
+
context "when the string is '-1.2'" do
|
656
|
+
|
657
|
+
let(:string) { '-1.2' }
|
658
|
+
|
659
|
+
let(:expected_exponent) { -1 }
|
660
|
+
let(:expected_significand) { 12 }
|
661
|
+
let(:expected_low_bits) { 0xc }
|
662
|
+
let(:expected_high_bits) { 0xb03e000000000000 }
|
663
|
+
|
664
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
665
|
+
end
|
666
|
+
|
667
|
+
context "when the string is '1.234'" do
|
668
|
+
|
669
|
+
let(:string) { '1.234' }
|
670
|
+
|
671
|
+
let(:expected_exponent) { -3 }
|
672
|
+
let(:expected_significand) { 1234 }
|
673
|
+
let(:expected_low_bits) { 0x4d2 }
|
674
|
+
let(:expected_high_bits) { 0x303a000000000000 }
|
675
|
+
|
676
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
677
|
+
end
|
678
|
+
|
679
|
+
context "when the string is '-1.234'" do
|
680
|
+
|
681
|
+
let(:string) { '-1.234' }
|
682
|
+
|
683
|
+
let(:expected_exponent) { -3 }
|
684
|
+
let(:expected_significand) { 1234 }
|
685
|
+
let(:expected_low_bits) { 0x4d2 }
|
686
|
+
let(:expected_high_bits) { 0xb03a000000000000 }
|
687
|
+
|
688
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
689
|
+
end
|
690
|
+
|
691
|
+
context "when the string is '123456789.123456789'" do
|
692
|
+
|
693
|
+
let(:string) { '123456789.123456789' }
|
694
|
+
|
695
|
+
let(:expected_exponent) { -9 }
|
696
|
+
let(:expected_significand) { 123456789123456789 }
|
697
|
+
let(:expected_low_bits) { 0x1b69b4bacd05f15 }
|
698
|
+
let(:expected_high_bits) { 0x302e000000000000 }
|
699
|
+
|
700
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
701
|
+
end
|
702
|
+
|
703
|
+
context "when the string is '-123456789.123456789'" do
|
704
|
+
|
705
|
+
let(:string) { '-123456789.123456789' }
|
706
|
+
|
707
|
+
let(:expected_exponent) { -9 }
|
708
|
+
let(:expected_significand) { 123456789123456789 }
|
709
|
+
let(:expected_low_bits) { 0x1b69b4bacd05f15 }
|
710
|
+
let(:expected_high_bits) { 0xb02e000000000000 }
|
711
|
+
|
712
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
context 'when the string represents a decimal with trailing zeros' do
|
717
|
+
|
718
|
+
context "when the string is '1.000'" do
|
719
|
+
|
720
|
+
let(:string) { '1.000' }
|
721
|
+
|
722
|
+
let(:expected_exponent) { -3 }
|
723
|
+
let(:expected_significand) { 1000 }
|
724
|
+
let(:expected_low_bits) { 0x3e8 }
|
725
|
+
let(:expected_high_bits) { 0x303a000000000000 }
|
726
|
+
|
727
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
728
|
+
end
|
729
|
+
|
730
|
+
context "when the string is '-1.000'" do
|
731
|
+
|
732
|
+
let(:string) { '-1.000' }
|
733
|
+
|
734
|
+
let(:expected_exponent) { -3 }
|
735
|
+
let(:expected_significand) { 1000 }
|
736
|
+
let(:expected_low_bits) { 0x3e8 }
|
737
|
+
let(:expected_high_bits) { 0xb03a000000000000 }
|
738
|
+
|
739
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
740
|
+
end
|
741
|
+
|
742
|
+
context "when the string is '100.000'" do
|
743
|
+
|
744
|
+
let(:string) { '100.000' }
|
745
|
+
|
746
|
+
let(:expected_exponent) { -3 }
|
747
|
+
let(:expected_significand) { 100000 }
|
748
|
+
let(:expected_low_bits) { 0x186a0 }
|
749
|
+
let(:expected_high_bits) { 0x303a000000000000 }
|
750
|
+
|
751
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
752
|
+
end
|
753
|
+
|
754
|
+
context "when the string is '-100.000'" do
|
755
|
+
|
756
|
+
let(:string) { '-100.000' }
|
757
|
+
|
758
|
+
let(:expected_exponent) { -3 }
|
759
|
+
let(:expected_significand) { 100000 }
|
760
|
+
let(:expected_low_bits) { 0x186a0 }
|
761
|
+
let(:expected_high_bits) { 0xb03a000000000000 }
|
762
|
+
|
763
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
764
|
+
end
|
765
|
+
|
766
|
+
context "when the string is '1.234000000'" do
|
767
|
+
|
768
|
+
let(:string) { '1.234000000' }
|
769
|
+
|
770
|
+
let(:expected_exponent) { -9 }
|
771
|
+
let(:expected_significand) { 1234000000 }
|
772
|
+
let(:expected_low_bits) { 0x498d5880 }
|
773
|
+
let(:expected_high_bits) { 0x302e000000000000 }
|
774
|
+
|
775
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
776
|
+
end
|
777
|
+
|
778
|
+
context "when the string is '-1.234000000'" do
|
779
|
+
|
780
|
+
let(:string) { '-1.234000000' }
|
781
|
+
|
782
|
+
let(:expected_exponent) { -9 }
|
783
|
+
let(:expected_significand) { 1234000000 }
|
784
|
+
let(:expected_low_bits) { 0x498d5880 }
|
785
|
+
let(:expected_high_bits) { 0xb02e000000000000 }
|
786
|
+
|
787
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
788
|
+
end
|
789
|
+
|
790
|
+
context 'when there are zeros following the decimal that are not trailing' do
|
791
|
+
|
792
|
+
context "when the string is '0.001234'" do
|
793
|
+
|
794
|
+
let(:string) { '0.001234' }
|
795
|
+
|
796
|
+
let(:expected_exponent) { -6 }
|
797
|
+
let(:expected_significand) { 1234 }
|
798
|
+
let(:expected_low_bits) { 0x4d2 }
|
799
|
+
let(:expected_high_bits) { 0x3034000000000000 }
|
800
|
+
|
801
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
802
|
+
end
|
803
|
+
end
|
804
|
+
|
805
|
+
context 'when there are zeros following the decimal that are not trailing' do
|
806
|
+
|
807
|
+
context "when the string is '0.00123400000'" do
|
808
|
+
|
809
|
+
let(:string) { '0.00123400000' }
|
810
|
+
|
811
|
+
let(:expected_exponent) { -11 }
|
812
|
+
let(:expected_significand) { 123400000 }
|
813
|
+
let(:expected_low_bits) { 0x75aef40 }
|
814
|
+
let(:expected_high_bits) { 0x302a000000000000 }
|
815
|
+
|
816
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
817
|
+
end
|
818
|
+
end
|
819
|
+
end
|
820
|
+
|
821
|
+
context 'when the string uses scientific notation' do
|
822
|
+
|
823
|
+
context 'when the exponent is positive' do
|
824
|
+
|
825
|
+
context 'when the positive exponent is denoted with E' do
|
826
|
+
|
827
|
+
context "when the string is '1.2E4'" do
|
828
|
+
|
829
|
+
let(:string) { '1.2E4' }
|
830
|
+
|
831
|
+
let(:expected_exponent) { 3 }
|
832
|
+
let(:expected_significand) { 12 }
|
833
|
+
let(:expected_low_bits) { 0xc }
|
834
|
+
let(:expected_high_bits) { 0x3046000000000000 }
|
835
|
+
|
836
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
837
|
+
end
|
838
|
+
|
839
|
+
context "when the string is '-1.2E4'" do
|
840
|
+
|
841
|
+
let(:string) { '-1.2E4' }
|
842
|
+
|
843
|
+
let(:expected_exponent) { 3 }
|
844
|
+
let(:expected_significand) { 12 }
|
845
|
+
let(:expected_low_bits) { 0xc }
|
846
|
+
let(:expected_high_bits) { 0xb046000000000000 }
|
847
|
+
|
848
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
849
|
+
end
|
850
|
+
end
|
851
|
+
|
852
|
+
context 'when the positive exponent is denoted with E+' do
|
853
|
+
|
854
|
+
context "when the string is '1.2E+4'" do
|
855
|
+
|
856
|
+
let(:string) { '1.2E4' }
|
857
|
+
|
858
|
+
let(:expected_exponent) { 3 }
|
859
|
+
let(:expected_significand) { 12 }
|
860
|
+
let(:expected_low_bits) { 0xc }
|
861
|
+
let(:expected_high_bits) { 0x3046000000000000 }
|
862
|
+
|
863
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
864
|
+
end
|
865
|
+
|
866
|
+
context "when the string is '-1.2E+4'" do
|
867
|
+
|
868
|
+
let(:string) { '-1.2E4' }
|
869
|
+
|
870
|
+
let(:expected_exponent) { 3 }
|
871
|
+
let(:expected_significand) { 12 }
|
872
|
+
let(:expected_low_bits) { 0xc }
|
873
|
+
let(:expected_high_bits) { 0xb046000000000000 }
|
874
|
+
|
875
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
876
|
+
end
|
877
|
+
end
|
878
|
+
end
|
879
|
+
|
880
|
+
context 'when the exponent is negative' do
|
881
|
+
|
882
|
+
context "when the string is '1.2E-4'" do
|
883
|
+
|
884
|
+
let(:string) { '1.2E-4' }
|
885
|
+
|
886
|
+
let(:expected_exponent) { -5 }
|
887
|
+
let(:expected_significand) { 12 }
|
888
|
+
let(:expected_low_bits) { 0xc }
|
889
|
+
let(:expected_high_bits) { 0x3036000000000000 }
|
890
|
+
|
891
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
892
|
+
end
|
893
|
+
|
894
|
+
context "when the string is '-1.2E-4'" do
|
895
|
+
|
896
|
+
let(:string) { '-1.2E-4' }
|
897
|
+
|
898
|
+
let(:expected_exponent) { -5 }
|
899
|
+
let(:expected_significand) { 12 }
|
900
|
+
let(:expected_low_bits) { 0xc }
|
901
|
+
let(:expected_high_bits) { 0xb036000000000000 }
|
902
|
+
|
903
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
904
|
+
end
|
905
|
+
|
906
|
+
context 'when there are trailing zeros' do
|
907
|
+
|
908
|
+
context "when the string is '1.200E-4'" do
|
909
|
+
|
910
|
+
let(:string) { '1.200E-4' }
|
911
|
+
|
912
|
+
let(:expected_exponent) { -7 }
|
913
|
+
let(:expected_significand) { 1200 }
|
914
|
+
let(:expected_low_bits) { 0x4b0 }
|
915
|
+
let(:expected_high_bits) { 0x3032000000000000 }
|
916
|
+
|
917
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
918
|
+
end
|
919
|
+
|
920
|
+
context "when the string is '-1.200E-4'" do
|
921
|
+
|
922
|
+
let(:string) { '-1.200E-4' }
|
923
|
+
|
924
|
+
let(:expected_exponent) { -7 }
|
925
|
+
let(:expected_significand) { 1200 }
|
926
|
+
let(:expected_low_bits) { 0x4b0 }
|
927
|
+
let(:expected_high_bits) { 0xb032000000000000 }
|
928
|
+
|
929
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
930
|
+
end
|
931
|
+
end
|
932
|
+
end
|
933
|
+
end
|
934
|
+
end
|
935
|
+
|
936
|
+
describe '#to_s' do
|
937
|
+
|
938
|
+
shared_examples_for 'a decimal128 printed to a string' do
|
939
|
+
|
940
|
+
let(:buffer) do
|
941
|
+
buffer = BSON::ByteBuffer.new
|
942
|
+
buffer.put_decimal128(low_bits, high_bits)
|
943
|
+
end
|
944
|
+
let(:decimal) { BSON::Decimal128.from_bson(buffer) }
|
945
|
+
|
946
|
+
it 'prints the correct string' do
|
947
|
+
expect(decimal.to_s).to eq(expected_string)
|
948
|
+
end
|
949
|
+
end
|
950
|
+
|
951
|
+
context 'when the bits represent a special type' do
|
952
|
+
|
953
|
+
context 'when the decimal is NaN' do
|
954
|
+
|
955
|
+
let(:expected_string) { 'NaN' }
|
956
|
+
let(:high_bits) { 0x7c00000000000000 }
|
957
|
+
let(:low_bits) { 0x0 }
|
958
|
+
|
959
|
+
it_behaves_like 'a decimal128 printed to a string'
|
960
|
+
end
|
961
|
+
|
962
|
+
context 'when the decimal is negative NaN' do
|
963
|
+
|
964
|
+
let(:expected_string) { 'NaN' }
|
965
|
+
let(:high_bits) { 0xfc00000000000000 }
|
966
|
+
let(:low_bits) { 0x0000000000000000 }
|
967
|
+
|
968
|
+
it_behaves_like 'a decimal128 printed to a string'
|
969
|
+
end
|
970
|
+
|
971
|
+
context 'when the decimal is SNaN' do
|
972
|
+
|
973
|
+
let(:expected_string) { 'NaN' }
|
974
|
+
let(:high_bits) { 0x7e00000000000000 }
|
975
|
+
let(:low_bits) { 0x0000000000000000 }
|
976
|
+
|
977
|
+
it_behaves_like 'a decimal128 printed to a string'
|
978
|
+
end
|
979
|
+
|
980
|
+
context 'when the decimal is -SNaN' do
|
981
|
+
|
982
|
+
let(:expected_string) { 'NaN' }
|
983
|
+
let(:high_bits) { 0xfe00000000000000 }
|
984
|
+
let(:low_bits) { 0x0000000000000000 }
|
985
|
+
|
986
|
+
it_behaves_like 'a decimal128 printed to a string'
|
987
|
+
end
|
988
|
+
|
989
|
+
context 'when the decimal is NaN with a payload' do
|
990
|
+
|
991
|
+
let(:expected_string) { 'NaN' }
|
992
|
+
let(:high_bits) { 0x7e00000000000000 }
|
993
|
+
let(:low_bits) { 0x0000000000000008 }
|
994
|
+
|
995
|
+
it_behaves_like 'a decimal128 printed to a string'
|
996
|
+
end
|
997
|
+
|
998
|
+
context 'when the decimal is positive Infinity' do
|
999
|
+
|
1000
|
+
let(:expected_string) { 'Infinity' }
|
1001
|
+
let(:high_bits) { 0x7800000000000000 }
|
1002
|
+
let(:low_bits) { 0x0000000000000000 }
|
1003
|
+
|
1004
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
context 'when the decimal is negative Infinity' do
|
1008
|
+
|
1009
|
+
let(:expected_string) { '-Infinity' }
|
1010
|
+
let(:high_bits) { 0xf800000000000000 }
|
1011
|
+
let(:low_bits) { 0x0000000000000000 }
|
1012
|
+
|
1013
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1014
|
+
end
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
context 'when the string represents an integer' do
|
1018
|
+
|
1019
|
+
context 'when the decimal is 1' do
|
1020
|
+
|
1021
|
+
let(:expected_string) { '1' }
|
1022
|
+
let(:high_bits) { 0x3040000000000000 }
|
1023
|
+
let(:low_bits) { 0x0000000000000001 }
|
1024
|
+
|
1025
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
context 'when the decimal is -1' do
|
1029
|
+
|
1030
|
+
let(:expected_string) { '-1' }
|
1031
|
+
let(:high_bits) { 0xb040000000000000 }
|
1032
|
+
let(:low_bits) { 0x0000000000000001 }
|
1033
|
+
|
1034
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
context 'when the decimal is 20' do
|
1038
|
+
|
1039
|
+
let(:expected_string) { '20' }
|
1040
|
+
let(:high_bits) { 0x3040000000000000 }
|
1041
|
+
let(:low_bits) { 0x0000000000000014 }
|
1042
|
+
|
1043
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
context 'when the decimal is -20' do
|
1047
|
+
|
1048
|
+
let(:expected_string) { '-20' }
|
1049
|
+
let(:high_bits) { 0xb040000000000000 }
|
1050
|
+
let(:low_bits) { 0x0000000000000014 }
|
1051
|
+
|
1052
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1053
|
+
end
|
1054
|
+
|
1055
|
+
context 'when the decimal is 12345678901234567' do
|
1056
|
+
|
1057
|
+
let(:expected_string) { '12345678901234567' }
|
1058
|
+
let(:high_bits) { 0x3040000000000000 }
|
1059
|
+
let(:low_bits) { 0x002bdc545d6b4b87 }
|
1060
|
+
|
1061
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1062
|
+
end
|
1063
|
+
|
1064
|
+
context 'when the decimal is -12345678901234567' do
|
1065
|
+
|
1066
|
+
let(:expected_string) { '-12345678901234567' }
|
1067
|
+
let(:high_bits) { 0xb040000000000000 }
|
1068
|
+
let(:low_bits) { 0x002bdc545d6b4b87 }
|
1069
|
+
|
1070
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
context 'when the decimal is 12345689012345789012345' do
|
1074
|
+
|
1075
|
+
let(:expected_string) { '12345689012345789012345' }
|
1076
|
+
let(:high_bits) { 0x304000000000029d }
|
1077
|
+
let(:low_bits) { 0x42da3a76f9e0d979 }
|
1078
|
+
|
1079
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1080
|
+
end
|
1081
|
+
|
1082
|
+
context 'when the decimal is -12345689012345789012345' do
|
1083
|
+
|
1084
|
+
let(:expected_string) { '-12345689012345789012345' }
|
1085
|
+
let(:high_bits) { 0xb04000000000029d }
|
1086
|
+
let(:low_bits) { 0x42da3a76f9e0d979 }
|
1087
|
+
|
1088
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1089
|
+
end
|
1090
|
+
end
|
1091
|
+
|
1092
|
+
context 'when the string represents a fraction' do
|
1093
|
+
|
1094
|
+
context 'when the decimal is 0.1' do
|
1095
|
+
|
1096
|
+
let(:expected_string) { '0.1' }
|
1097
|
+
let(:high_bits) { 0x303e000000000000 }
|
1098
|
+
let(:low_bits) { 0x0000000000000001 }
|
1099
|
+
|
1100
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1101
|
+
end
|
1102
|
+
|
1103
|
+
context 'when the decimal is -0.1' do
|
1104
|
+
|
1105
|
+
let(:expected_string) { '-0.1' }
|
1106
|
+
let(:high_bits) { 0xb03e000000000000 }
|
1107
|
+
let(:low_bits) { 0x0000000000000001 }
|
1108
|
+
|
1109
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1110
|
+
end
|
1111
|
+
|
1112
|
+
context 'when the decimal is 0.123' do
|
1113
|
+
|
1114
|
+
let(:expected_string) { '0.123' }
|
1115
|
+
let(:high_bits) { 0x303a000000000000 }
|
1116
|
+
let(:low_bits) { 0x000000000000007b }
|
1117
|
+
|
1118
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1119
|
+
end
|
1120
|
+
|
1121
|
+
context 'when the decimal is -0.123' do
|
1122
|
+
|
1123
|
+
let(:expected_string) { '-0.123' }
|
1124
|
+
let(:high_bits) { 0xb03a000000000000 }
|
1125
|
+
let(:low_bits) { 0x000000000000007b }
|
1126
|
+
|
1127
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1128
|
+
end
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
context 'when the decimal should have leading zeros' do
|
1132
|
+
|
1133
|
+
let(:expected_string) { '0.001234' }
|
1134
|
+
let(:high_bits) { 0x3034000000000000 }
|
1135
|
+
let(:low_bits) { 0x00000000000004d2 }
|
1136
|
+
|
1137
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1138
|
+
end
|
1139
|
+
|
1140
|
+
context 'when the decimal has trailing zeros' do
|
1141
|
+
|
1142
|
+
let(:expected_string) { '2.000' }
|
1143
|
+
let(:high_bits) { 0x303a000000000000 }
|
1144
|
+
let(:low_bits) { 0x00000000000007d0 }
|
1145
|
+
|
1146
|
+
it_behaves_like 'a decimal128 printed to a string'
|
1147
|
+
end
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
describe "#==" do
|
1151
|
+
|
1152
|
+
context "when the high and low bits are identical" do
|
1153
|
+
|
1154
|
+
let(:string) do
|
1155
|
+
'1.23'
|
1156
|
+
end
|
1157
|
+
|
1158
|
+
let(:decimal128) do
|
1159
|
+
described_class.from_string(string)
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
let(:other_decimal) do
|
1163
|
+
described_class.from_string(string)
|
1164
|
+
end
|
1165
|
+
|
1166
|
+
it "returns true" do
|
1167
|
+
expect(decimal128).to eq(other_decimal)
|
1168
|
+
end
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
context "when the high and low bits are different" do
|
1172
|
+
|
1173
|
+
let(:string) do
|
1174
|
+
'1.23'
|
1175
|
+
end
|
1176
|
+
|
1177
|
+
let(:decimal128) do
|
1178
|
+
described_class.from_string(string)
|
1179
|
+
end
|
1180
|
+
|
1181
|
+
it "returns false" do
|
1182
|
+
expect(decimal128).to_not eq(described_class.new(BigDecimal.new('2.00')))
|
1183
|
+
end
|
1184
|
+
end
|
1185
|
+
|
1186
|
+
context "when other is not a decimal128" do
|
1187
|
+
|
1188
|
+
it "returns false" do
|
1189
|
+
expect(described_class.from_string('1')).to_not eq(nil)
|
1190
|
+
end
|
1191
|
+
end
|
1192
|
+
end
|
1193
|
+
|
1194
|
+
describe "#===" do
|
1195
|
+
|
1196
|
+
let(:decimal128) do
|
1197
|
+
described_class.new(BigDecimal.new('1.23'))
|
1198
|
+
end
|
1199
|
+
|
1200
|
+
context "when comparing with another decimal128" do
|
1201
|
+
|
1202
|
+
context "when the high and low bits are equal" do
|
1203
|
+
|
1204
|
+
let(:other) do
|
1205
|
+
described_class.from_string(decimal128.to_s)
|
1206
|
+
end
|
1207
|
+
|
1208
|
+
it "returns true" do
|
1209
|
+
expect(decimal128 === other).to be true
|
1210
|
+
end
|
1211
|
+
end
|
1212
|
+
|
1213
|
+
context "when the high and low bits are not equal" do
|
1214
|
+
|
1215
|
+
let(:other) do
|
1216
|
+
described_class.new(BigDecimal.new('1000.003'))
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
it "returns false" do
|
1220
|
+
expect(decimal128 === other).to be false
|
1221
|
+
end
|
1222
|
+
end
|
1223
|
+
end
|
1224
|
+
|
1225
|
+
context "when comparing to an decimal128 class" do
|
1226
|
+
|
1227
|
+
it "returns false" do
|
1228
|
+
expect(decimal128 === BSON::Decimal128).to be false
|
1229
|
+
end
|
1230
|
+
end
|
1231
|
+
|
1232
|
+
context "when comparing with a non string or decimal128" do
|
1233
|
+
|
1234
|
+
it "returns false" do
|
1235
|
+
expect(decimal128 === "test").to be false
|
1236
|
+
end
|
1237
|
+
end
|
1238
|
+
|
1239
|
+
context "when comparing with a non decimal128 class" do
|
1240
|
+
|
1241
|
+
it "returns false" do
|
1242
|
+
expect(decimal128 === String).to be false
|
1243
|
+
end
|
1244
|
+
end
|
1245
|
+
end
|
1246
|
+
|
1247
|
+
describe "#as_json" do
|
1248
|
+
|
1249
|
+
let(:object) do
|
1250
|
+
described_class.new(BigDecimal.new('1.23'))
|
1251
|
+
end
|
1252
|
+
|
1253
|
+
it "returns the decimal128 with $numberDecimal key" do
|
1254
|
+
expect(object.as_json).to eq({ "$numberDecimal" => object.to_s })
|
1255
|
+
end
|
1256
|
+
end
|
1257
|
+
|
1258
|
+
describe "::BSON_TYPE" do
|
1259
|
+
|
1260
|
+
it "returns 0x13" do
|
1261
|
+
expect(described_class::BSON_TYPE).to eq(19.chr)
|
1262
|
+
end
|
1263
|
+
end
|
1264
|
+
|
1265
|
+
describe "#bson_type" do
|
1266
|
+
|
1267
|
+
let(:code) do
|
1268
|
+
described_class.new(BigDecimal.new('1.23'))
|
1269
|
+
end
|
1270
|
+
|
1271
|
+
it "returns 0x13" do
|
1272
|
+
expect(code.bson_type).to eq(described_class::BSON_TYPE)
|
1273
|
+
end
|
1274
|
+
end
|
1275
|
+
|
1276
|
+
describe "#eql" do
|
1277
|
+
|
1278
|
+
context "when high and low bits are identical" do
|
1279
|
+
|
1280
|
+
let(:string) do
|
1281
|
+
'2.00'
|
1282
|
+
end
|
1283
|
+
|
1284
|
+
let(:decimal128) do
|
1285
|
+
described_class.from_string(string)
|
1286
|
+
end
|
1287
|
+
|
1288
|
+
let(:other_decimal) do
|
1289
|
+
described_class.from_string(string)
|
1290
|
+
end
|
1291
|
+
|
1292
|
+
it "returns true" do
|
1293
|
+
expect(decimal128).to eql(other_decimal)
|
1294
|
+
end
|
1295
|
+
end
|
1296
|
+
|
1297
|
+
context "when the high and low bit are different" do
|
1298
|
+
|
1299
|
+
let(:string) do
|
1300
|
+
'2.00'
|
1301
|
+
end
|
1302
|
+
|
1303
|
+
let(:decimal128) do
|
1304
|
+
described_class.from_string(string)
|
1305
|
+
end
|
1306
|
+
|
1307
|
+
it "returns false" do
|
1308
|
+
expect(decimal128).to_not eql(described_class.new(BigDecimal.new('2')))
|
1309
|
+
end
|
1310
|
+
end
|
1311
|
+
|
1312
|
+
context "when other is not a Decimal128" do
|
1313
|
+
|
1314
|
+
it "returns false" do
|
1315
|
+
expect(described_class.from_string('2')).to_not eql(nil)
|
1316
|
+
end
|
1317
|
+
end
|
1318
|
+
end
|
1319
|
+
|
1320
|
+
describe "#hash" do
|
1321
|
+
|
1322
|
+
let(:decimal128) do
|
1323
|
+
described_class.new(BigDecimal.new('-1234E+33'))
|
1324
|
+
end
|
1325
|
+
|
1326
|
+
it "returns a hash of the high and low bits" do
|
1327
|
+
expect(decimal128.hash).to eq(BSON::Decimal128.from_bson(decimal128.to_bson).hash)
|
1328
|
+
end
|
1329
|
+
end
|
1330
|
+
|
1331
|
+
describe "#inspect" do
|
1332
|
+
|
1333
|
+
let(:decimal128) do
|
1334
|
+
described_class.new(BigDecimal.new('1.23'))
|
1335
|
+
end
|
1336
|
+
|
1337
|
+
it "returns the inspection with the decimal128 to_s" do
|
1338
|
+
expect(decimal128.inspect).to eq("BSON::Decimal128('#{decimal128.to_s}')")
|
1339
|
+
end
|
1340
|
+
end
|
1341
|
+
|
1342
|
+
describe "#to_big_decimal" do
|
1343
|
+
|
1344
|
+
shared_examples_for 'a decimal128 convertible to a Ruby BigDecimal' do
|
1345
|
+
|
1346
|
+
let(:decimal128) do
|
1347
|
+
described_class.new(big_decimal)
|
1348
|
+
end
|
1349
|
+
|
1350
|
+
it 'properly converts the Decimal128 to a BigDecimal' do
|
1351
|
+
expect(decimal128.to_big_decimal).to eq(expected_big_decimal)
|
1352
|
+
end
|
1353
|
+
end
|
1354
|
+
|
1355
|
+
context 'when the Decimal128 is a special type' do
|
1356
|
+
|
1357
|
+
context 'when the value is Infinity' do
|
1358
|
+
|
1359
|
+
let(:big_decimal) do
|
1360
|
+
BigDecimal.new('Infinity')
|
1361
|
+
end
|
1362
|
+
|
1363
|
+
let(:expected_big_decimal) do
|
1364
|
+
big_decimal
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1368
|
+
end
|
1369
|
+
|
1370
|
+
context 'when the value is -Infinity' do
|
1371
|
+
|
1372
|
+
let(:big_decimal) do
|
1373
|
+
BigDecimal.new('-Infinity')
|
1374
|
+
end
|
1375
|
+
|
1376
|
+
let(:expected_big_decimal) do
|
1377
|
+
big_decimal
|
1378
|
+
end
|
1379
|
+
|
1380
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1381
|
+
end
|
1382
|
+
end
|
1383
|
+
|
1384
|
+
context 'when the value represents an Integer' do
|
1385
|
+
|
1386
|
+
context 'when the value is 1' do
|
1387
|
+
|
1388
|
+
let(:big_decimal) do
|
1389
|
+
BigDecimal.new(1)
|
1390
|
+
end
|
1391
|
+
|
1392
|
+
let(:expected_big_decimal) do
|
1393
|
+
big_decimal
|
1394
|
+
end
|
1395
|
+
|
1396
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1397
|
+
end
|
1398
|
+
|
1399
|
+
context 'when the value is -1' do
|
1400
|
+
|
1401
|
+
let(:big_decimal) do
|
1402
|
+
BigDecimal.new(-1)
|
1403
|
+
end
|
1404
|
+
|
1405
|
+
let(:expected_big_decimal) do
|
1406
|
+
big_decimal
|
1407
|
+
end
|
1408
|
+
|
1409
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
context 'when the value is 20' do
|
1413
|
+
|
1414
|
+
let(:big_decimal) do
|
1415
|
+
BigDecimal.new(20)
|
1416
|
+
end
|
1417
|
+
|
1418
|
+
let(:expected_big_decimal) do
|
1419
|
+
big_decimal
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1423
|
+
end
|
1424
|
+
|
1425
|
+
context 'when the value is -20' do
|
1426
|
+
|
1427
|
+
let(:big_decimal) do
|
1428
|
+
BigDecimal.new(-20)
|
1429
|
+
end
|
1430
|
+
|
1431
|
+
let(:expected_big_decimal) do
|
1432
|
+
big_decimal
|
1433
|
+
end
|
1434
|
+
|
1435
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1436
|
+
end
|
1437
|
+
|
1438
|
+
context 'when the value is 12345678901234567' do
|
1439
|
+
|
1440
|
+
let(:big_decimal) do
|
1441
|
+
BigDecimal.new(12345678901234567)
|
1442
|
+
end
|
1443
|
+
|
1444
|
+
let(:expected_big_decimal) do
|
1445
|
+
big_decimal
|
1446
|
+
end
|
1447
|
+
|
1448
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1449
|
+
end
|
1450
|
+
|
1451
|
+
context 'when the value is -12345678901234567' do
|
1452
|
+
|
1453
|
+
let(:big_decimal) do
|
1454
|
+
BigDecimal.new(-12345678901234567)
|
1455
|
+
end
|
1456
|
+
|
1457
|
+
let(:expected_big_decimal) do
|
1458
|
+
big_decimal
|
1459
|
+
end
|
1460
|
+
|
1461
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1462
|
+
end
|
1463
|
+
|
1464
|
+
context 'when the value is 12345689012345789012345' do
|
1465
|
+
|
1466
|
+
let(:big_decimal) do
|
1467
|
+
BigDecimal.new(12345689012345789012345)
|
1468
|
+
end
|
1469
|
+
|
1470
|
+
let(:expected_big_decimal) do
|
1471
|
+
big_decimal
|
1472
|
+
end
|
1473
|
+
|
1474
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1475
|
+
end
|
1476
|
+
|
1477
|
+
context 'when the value is -12345689012345789012345' do
|
1478
|
+
|
1479
|
+
let(:big_decimal) do
|
1480
|
+
BigDecimal.new(-12345689012345789012345)
|
1481
|
+
end
|
1482
|
+
|
1483
|
+
let(:expected_big_decimal) do
|
1484
|
+
big_decimal
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1488
|
+
end
|
1489
|
+
end
|
1490
|
+
|
1491
|
+
context 'when the value has a fraction' do
|
1492
|
+
|
1493
|
+
context 'when the value is 0.1' do
|
1494
|
+
|
1495
|
+
let(:big_decimal) do
|
1496
|
+
BigDecimal.new(0.1, 1)
|
1497
|
+
end
|
1498
|
+
|
1499
|
+
let(:expected_big_decimal) do
|
1500
|
+
big_decimal
|
1501
|
+
end
|
1502
|
+
|
1503
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1504
|
+
end
|
1505
|
+
|
1506
|
+
context 'when the value is -0.1' do
|
1507
|
+
|
1508
|
+
let(:big_decimal) do
|
1509
|
+
BigDecimal.new(-0.1, 1)
|
1510
|
+
end
|
1511
|
+
|
1512
|
+
let(:expected_big_decimal) do
|
1513
|
+
big_decimal
|
1514
|
+
end
|
1515
|
+
|
1516
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
context 'when the value is 0.123' do
|
1520
|
+
|
1521
|
+
let(:big_decimal) do
|
1522
|
+
BigDecimal.new(0.123, 3)
|
1523
|
+
end
|
1524
|
+
|
1525
|
+
let(:expected_big_decimal) do
|
1526
|
+
big_decimal
|
1527
|
+
end
|
1528
|
+
|
1529
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1530
|
+
end
|
1531
|
+
|
1532
|
+
context 'when the value is -0.123' do
|
1533
|
+
|
1534
|
+
let(:big_decimal) do
|
1535
|
+
BigDecimal.new(-0.123, 3)
|
1536
|
+
end
|
1537
|
+
|
1538
|
+
let(:expected_big_decimal) do
|
1539
|
+
big_decimal
|
1540
|
+
end
|
1541
|
+
|
1542
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1543
|
+
end
|
1544
|
+
end
|
1545
|
+
|
1546
|
+
context 'when the value has leading zeros' do
|
1547
|
+
|
1548
|
+
let(:big_decimal) do
|
1549
|
+
BigDecimal.new(0.001234, 4)
|
1550
|
+
end
|
1551
|
+
|
1552
|
+
let(:expected_big_decimal) do
|
1553
|
+
big_decimal
|
1554
|
+
end
|
1555
|
+
|
1556
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1557
|
+
end
|
1558
|
+
|
1559
|
+
context 'when the value has trailing zeros' do
|
1560
|
+
|
1561
|
+
let(:big_decimal) do
|
1562
|
+
BigDecimal.new(2.000, 4)
|
1563
|
+
end
|
1564
|
+
|
1565
|
+
let(:expected_big_decimal) do
|
1566
|
+
big_decimal
|
1567
|
+
end
|
1568
|
+
|
1569
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
1570
|
+
end
|
1571
|
+
end
|
1572
|
+
|
1573
|
+
context "when the class is loaded" do
|
1574
|
+
|
1575
|
+
let(:registered) do
|
1576
|
+
BSON::Registry.get(described_class::BSON_TYPE, 'field')
|
1577
|
+
end
|
1578
|
+
|
1579
|
+
it "registers the type" do
|
1580
|
+
expect(registered).to eq(described_class)
|
1581
|
+
end
|
1582
|
+
end
|
1583
|
+
end
|