bson 4.1.1 → 4.2.0.rc0
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/ext/bson/{native.c → bson_native.c} +48 -8
- data/ext/bson/extconf.rb +1 -1
- data/ext/bson/native-endian.h +1 -1
- data/lib/bson.rb +3 -1
- data/lib/bson/config.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/int32.rb +46 -0
- data/lib/bson/int64.rb +46 -0
- data/lib/bson/max_key.rb +1 -1
- data/lib/bson/min_key.rb +1 -1
- data/lib/bson/object_id.rb +2 -1
- data/lib/bson/open_struct.rb +57 -0
- data/lib/bson/regexp.rb +1 -1
- data/lib/bson/registry.rb +1 -1
- data/lib/bson/version.rb +2 -2
- 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/spec_helper.rb +4 -0
- data/spec/support/common_driver.rb +347 -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
- metadata +29 -4
- metadata.gz.sig +0 -0
data/lib/bson/environment.rb
CHANGED
@@ -30,7 +30,19 @@ module BSON
|
|
30
30
|
#
|
31
31
|
# @since 2.0.0
|
32
32
|
def jruby?
|
33
|
-
defined?(JRUBY_VERSION)
|
33
|
+
@jruby ||= defined?(JRUBY_VERSION)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Determine if we are using Ruby version 1.9.
|
37
|
+
#
|
38
|
+
# @example Are we running with Ruby version 1.9?
|
39
|
+
# Environment.ruby_1_9?
|
40
|
+
#
|
41
|
+
# @return [ true, false ] If the Ruby version is 1.9.
|
42
|
+
#
|
43
|
+
# @since 4.2.0
|
44
|
+
def ruby_1_9?
|
45
|
+
@ruby_1_9 ||= RUBY_VERSION < '2.0.0'
|
34
46
|
end
|
35
47
|
end
|
36
48
|
end
|
data/lib/bson/int32.rb
CHANGED
@@ -50,6 +50,52 @@ module BSON
|
|
50
50
|
buffer.get_int32
|
51
51
|
end
|
52
52
|
|
53
|
+
# Instantiate a BSON Int32.
|
54
|
+
#
|
55
|
+
# @param [ Integer ] integer The 32-bit integer.
|
56
|
+
#
|
57
|
+
# @see http://bsonspec.org/#/specification
|
58
|
+
#
|
59
|
+
# @since 4.2.0
|
60
|
+
def initialize(integer)
|
61
|
+
out_of_range! unless integer.bson_int32?
|
62
|
+
@integer = integer.freeze
|
63
|
+
end
|
64
|
+
|
65
|
+
# Append the integer as encoded BSON to a ByteBuffer.
|
66
|
+
#
|
67
|
+
# @example Encoded the integer and append to a ByteBuffer.
|
68
|
+
# int32.to_bson
|
69
|
+
#
|
70
|
+
# @return [ BSON::ByteBuffer ] The buffer with the encoded integer.
|
71
|
+
#
|
72
|
+
# @see http://bsonspec.org/#/specification
|
73
|
+
#
|
74
|
+
# @since 4.2.0
|
75
|
+
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
76
|
+
buffer.put_int32(@integer)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Convert the integer to a BSON string key.
|
80
|
+
#
|
81
|
+
# @example Convert the integer to a BSON key string.
|
82
|
+
# int.to_bson_key
|
83
|
+
#
|
84
|
+
# @param [ true, false ] validating_keys If BSON should validate the key.
|
85
|
+
#
|
86
|
+
# @return [ String ] The string key.
|
87
|
+
#
|
88
|
+
# @since 4.2.0
|
89
|
+
def to_bson_key(validating_keys = Config.validating_keys?)
|
90
|
+
@integer.to_bson_key(validating_keys)
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def out_of_range!
|
96
|
+
raise RangeError.new("#{self} is not a valid 4 byte integer value.")
|
97
|
+
end
|
98
|
+
|
53
99
|
# Register this type when the module is loaded.
|
54
100
|
#
|
55
101
|
# @since 2.0.0
|
data/lib/bson/int64.rb
CHANGED
@@ -45,6 +45,52 @@ module BSON
|
|
45
45
|
buffer.get_int64
|
46
46
|
end
|
47
47
|
|
48
|
+
# Instantiate a BSON Int64.
|
49
|
+
#
|
50
|
+
# @param [ Integer ] integer The 64-bit integer.
|
51
|
+
#
|
52
|
+
# @see http://bsonspec.org/#/specification
|
53
|
+
#
|
54
|
+
# @since 4.2.0
|
55
|
+
def initialize(integer)
|
56
|
+
out_of_range! unless integer.bson_int64?
|
57
|
+
@integer = integer.freeze
|
58
|
+
end
|
59
|
+
|
60
|
+
# Append the integer as encoded BSON to a ByteBuffer.
|
61
|
+
#
|
62
|
+
# @example Encoded the integer and append to a ByteBuffer.
|
63
|
+
# int64.to_bson
|
64
|
+
#
|
65
|
+
# @return [ BSON::ByteBuffer ] The buffer with the encoded integer.
|
66
|
+
#
|
67
|
+
# @see http://bsonspec.org/#/specification
|
68
|
+
#
|
69
|
+
# @since 4.2.0
|
70
|
+
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
71
|
+
buffer.put_int64(@integer)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Convert the integer to a BSON string key.
|
75
|
+
#
|
76
|
+
# @example Convert the integer to a BSON key string.
|
77
|
+
# int.to_bson_key
|
78
|
+
#
|
79
|
+
# @param [ true, false ] validating_keys If BSON should validate the key.
|
80
|
+
#
|
81
|
+
# @return [ String ] The string key.
|
82
|
+
#
|
83
|
+
# @since 4.2.0
|
84
|
+
def to_bson_key(validating_keys = Config.validating_keys?)
|
85
|
+
@integer.to_bson_key(validating_keys)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def out_of_range!
|
91
|
+
raise RangeError.new("#{self} is not a valid 8 byte integer value.")
|
92
|
+
end
|
93
|
+
|
48
94
|
# Register this type when the module is loaded.
|
49
95
|
#
|
50
96
|
# @since 2.0.0
|
data/lib/bson/max_key.rb
CHANGED
data/lib/bson/min_key.rb
CHANGED
data/lib/bson/object_id.rb
CHANGED
@@ -102,6 +102,7 @@ module BSON
|
|
102
102
|
def generation_time
|
103
103
|
::Time.at(generate_data.unpack("N")[0]).utc
|
104
104
|
end
|
105
|
+
alias :to_time :generation_time
|
105
106
|
|
106
107
|
# Get the hash value for the object id.
|
107
108
|
#
|
@@ -279,7 +280,7 @@ module BSON
|
|
279
280
|
# @example Is the string a legal object id?
|
280
281
|
# BSON::ObjectId.legal?(string)
|
281
282
|
#
|
282
|
-
# @param [ String ] The string to check.
|
283
|
+
# @param [ String ] string The string to check.
|
283
284
|
#
|
284
285
|
# @return [ true, false ] If the string is legal.
|
285
286
|
#
|
@@ -0,0 +1,57 @@
|
|
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
|
+
module BSON
|
16
|
+
|
17
|
+
# Injects behaviour for encoding OpenStruct objects using hashes
|
18
|
+
# to raw bytes as specified by the BSON spec.
|
19
|
+
#
|
20
|
+
# @see http://bsonspec.org/#/specification
|
21
|
+
#
|
22
|
+
# @since 4.2.0
|
23
|
+
module OpenStruct
|
24
|
+
|
25
|
+
# Get the OpenStruct as encoded BSON.
|
26
|
+
#
|
27
|
+
# @example Get the OpenStruct object as encoded BSON.
|
28
|
+
# OpenStruct.new({ "field" => "value" }).to_bson
|
29
|
+
#
|
30
|
+
# @return [ String ] The encoded string.
|
31
|
+
#
|
32
|
+
# @see http://bsonspec.org/#/specification
|
33
|
+
#
|
34
|
+
# @since 4.2.0
|
35
|
+
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
36
|
+
if Environment.ruby_1_9?
|
37
|
+
marshal_dump.dup
|
38
|
+
else
|
39
|
+
to_h
|
40
|
+
end.to_bson(buffer, validating_keys)
|
41
|
+
end
|
42
|
+
|
43
|
+
# The BSON type for OpenStruct objects is the Hash type of 0x03.
|
44
|
+
#
|
45
|
+
# @example Get the bson type.
|
46
|
+
# struct.bson_type
|
47
|
+
#
|
48
|
+
# @return [ String ] The character 0x03.
|
49
|
+
#
|
50
|
+
# @since 4.2.0
|
51
|
+
def bson_type
|
52
|
+
::Hash::BSON_TYPE
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
::OpenStruct.send(:include, OpenStruct) if defined?(::OpenStruct)
|
57
|
+
end
|
data/lib/bson/regexp.rb
CHANGED
data/lib/bson/registry.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.rc0".freeze
|
17
17
|
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
|