bson 4.1.1 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +106 -7
- data/Rakefile +86 -43
- data/ext/bson/{native-endian.h → bson-endian.h} +14 -107
- data/ext/bson/bson-native.h +135 -0
- data/ext/bson/bytebuf.c +133 -0
- data/ext/bson/endian.c +117 -0
- data/ext/bson/extconf.rb +8 -3
- data/ext/bson/init.c +364 -0
- data/ext/bson/libbson-utf8.c +230 -0
- data/ext/bson/read.c +470 -0
- data/ext/bson/util.c +250 -0
- data/ext/bson/write.c +675 -0
- data/lib/bson/active_support.rb +19 -0
- data/lib/bson/array.rb +97 -30
- data/lib/bson/big_decimal.rb +77 -0
- data/lib/bson/binary.rb +510 -70
- data/lib/bson/boolean.rb +15 -4
- data/lib/bson/code.rb +25 -12
- data/lib/bson/code_with_scope.rb +41 -15
- data/lib/bson/config.rb +3 -28
- data/lib/bson/date.rb +16 -4
- data/lib/bson/date_time.rb +6 -4
- data/lib/bson/db_pointer.rb +110 -0
- data/lib/bson/dbref.rb +154 -0
- data/lib/bson/decimal128/builder.rb +456 -0
- data/lib/bson/decimal128.rb +272 -0
- data/lib/bson/document.rb +177 -7
- data/lib/bson/environment.rb +17 -2
- data/lib/bson/error/bson_decode_error.rb +11 -0
- data/lib/bson/error/ext_json_parse_error.rb +11 -0
- data/lib/bson/error/illegal_key.rb +23 -0
- data/lib/bson/error/invalid_binary_type.rb +37 -0
- data/lib/bson/error/invalid_dbref_argument.rb +12 -0
- data/lib/bson/error/invalid_decimal128_argument.rb +25 -0
- data/lib/bson/error/invalid_decimal128_range.rb +27 -0
- data/lib/bson/error/invalid_decimal128_string.rb +26 -0
- data/lib/bson/error/invalid_key.rb +24 -0
- data/lib/bson/error/invalid_object_id.rb +11 -0
- data/lib/bson/error/invalid_regexp_pattern.rb +13 -0
- data/lib/bson/error/unrepresentable_precision.rb +19 -0
- data/lib/bson/error/unserializable_class.rb +13 -0
- data/lib/bson/error/unsupported_binary_subtype.rb +12 -0
- data/lib/bson/error/unsupported_type.rb +11 -0
- data/lib/bson/error.rb +22 -0
- data/lib/bson/ext_json.rb +389 -0
- data/lib/bson/false_class.rb +6 -4
- data/lib/bson/float.rb +43 -7
- data/lib/bson/hash.rb +152 -37
- data/lib/bson/int32.rb +104 -6
- data/lib/bson/int64.rb +111 -8
- data/lib/bson/integer.rb +43 -9
- data/lib/bson/json.rb +3 -1
- data/lib/bson/max_key.rb +21 -10
- data/lib/bson/min_key.rb +21 -10
- data/lib/bson/nil_class.rb +7 -3
- data/lib/bson/object.rb +25 -17
- data/lib/bson/object_id.rb +98 -113
- data/lib/bson/open_struct.rb +59 -0
- data/lib/bson/regexp.rb +129 -56
- data/lib/bson/registry.rb +7 -10
- data/lib/bson/specialized.rb +8 -4
- data/lib/bson/string.rb +12 -32
- data/lib/bson/symbol.rb +107 -11
- data/lib/bson/time.rb +68 -7
- data/lib/bson/time_with_zone.rb +67 -0
- data/lib/bson/timestamp.rb +50 -10
- data/lib/bson/true_class.rb +6 -4
- data/lib/bson/undefined.rb +28 -2
- data/lib/bson/vector.rb +44 -0
- data/lib/bson/version.rb +6 -14
- data/lib/bson.rb +22 -12
- data/spec/README.md +14 -0
- data/spec/bson/array_spec.rb +38 -62
- data/spec/bson/big_decimal_spec.rb +328 -0
- data/spec/bson/binary_spec.rb +199 -53
- data/spec/bson/binary_uuid_spec.rb +190 -0
- data/spec/bson/boolean_spec.rb +2 -1
- data/spec/bson/byte_buffer_read_spec.rb +198 -0
- data/spec/bson/byte_buffer_spec.rb +122 -381
- data/spec/bson/byte_buffer_write_spec.rb +855 -0
- data/spec/bson/code_spec.rb +6 -4
- data/spec/bson/code_with_scope_spec.rb +6 -4
- data/spec/bson/config_spec.rb +1 -35
- data/spec/bson/date_spec.rb +2 -1
- data/spec/bson/date_time_spec.rb +55 -1
- data/spec/bson/dbref_legacy_spec.rb +186 -0
- data/spec/bson/dbref_spec.rb +487 -0
- data/spec/bson/decimal128_spec.rb +1840 -0
- data/spec/bson/document_as_spec.rb +61 -0
- data/spec/bson/document_spec.rb +205 -32
- data/spec/bson/ext_json_parse_spec.rb +346 -0
- data/spec/bson/false_class_spec.rb +9 -1
- data/spec/bson/float_spec.rb +42 -1
- data/spec/bson/hash_as_spec.rb +58 -0
- data/spec/bson/hash_spec.rb +318 -66
- data/spec/bson/int32_spec.rb +248 -1
- data/spec/bson/int64_spec.rb +308 -1
- data/spec/bson/integer_spec.rb +61 -3
- data/spec/bson/json_spec.rb +2 -1
- data/spec/bson/max_key_spec.rb +6 -4
- data/spec/bson/min_key_spec.rb +6 -4
- data/spec/bson/nil_class_spec.rb +2 -1
- data/spec/bson/object_id_spec.rb +95 -5
- data/spec/bson/object_spec.rb +3 -2
- data/spec/bson/open_struct_spec.rb +87 -0
- data/spec/bson/raw_spec.rb +594 -0
- data/spec/bson/regexp_spec.rb +61 -8
- data/spec/bson/registry_spec.rb +3 -2
- data/spec/bson/string_spec.rb +26 -33
- data/spec/bson/symbol_raw_spec.rb +70 -0
- data/spec/bson/symbol_spec.rb +77 -20
- data/spec/bson/time_spec.rb +206 -2
- data/spec/bson/time_with_zone_spec.rb +69 -0
- data/spec/bson/timestamp_spec.rb +58 -2
- data/spec/bson/true_class_spec.rb +9 -1
- data/spec/bson/undefined_spec.rb +28 -1
- data/spec/bson/vector_spec.rb +33 -0
- data/spec/bson_spec.rb +2 -1
- data/spec/runners/binary_vector.rb +78 -0
- data/spec/runners/common_driver.rb +348 -0
- data/spec/runners/corpus.rb +191 -0
- data/spec/runners/corpus_legacy.rb +248 -0
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/cluster_config.rb +231 -0
- data/spec/shared/lib/mrss/constraints.rb +378 -0
- data/spec/shared/lib/mrss/docker_runner.rb +298 -0
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
- data/spec/shared/lib/mrss/release/candidate.rb +281 -0
- data/spec/shared/lib/mrss/release/product_data.rb +144 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
- data/spec/shared/lib/mrss/session_registry.rb +69 -0
- data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
- data/spec/shared/lib/mrss/utils.rb +37 -0
- data/spec/shared/lib/tasks/candidate.rake +64 -0
- data/spec/shared/share/Dockerfile.erb +251 -0
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/config.sh +27 -0
- data/spec/shared/shlib/distro.sh +84 -0
- data/spec/shared/shlib/server.sh +423 -0
- data/spec/shared/shlib/set_env.sh +110 -0
- data/spec/spec_helper.rb +61 -1
- data/spec/spec_tests/binary_vector_spec.rb +82 -0
- data/spec/spec_tests/common_driver_spec.rb +84 -0
- data/spec/spec_tests/corpus_legacy_spec.rb +72 -0
- data/spec/spec_tests/corpus_spec.rb +134 -0
- data/spec/spec_tests/data/binary_vector/README.md +61 -0
- data/spec/spec_tests/data/binary_vector/float32.json +65 -0
- data/spec/spec_tests/data/binary_vector/int8.json +57 -0
- data/spec/spec_tests/data/binary_vector/packed_bit.json +83 -0
- data/spec/spec_tests/data/corpus/README.md +15 -0
- data/spec/spec_tests/data/corpus/array.json +49 -0
- data/spec/spec_tests/data/corpus/binary.json +153 -0
- data/spec/spec_tests/data/corpus/boolean.json +27 -0
- data/spec/spec_tests/data/corpus/code.json +67 -0
- data/spec/spec_tests/data/corpus/code_w_scope.json +78 -0
- data/spec/spec_tests/data/corpus/datetime.json +42 -0
- data/spec/spec_tests/data/corpus/dbpointer.json +56 -0
- data/spec/spec_tests/data/corpus/dbref.json +51 -0
- data/spec/spec_tests/data/corpus/decimal128-1.json +317 -0
- data/spec/spec_tests/data/corpus/decimal128-2.json +793 -0
- data/spec/spec_tests/data/corpus/decimal128-3.json +1771 -0
- data/spec/spec_tests/data/corpus/decimal128-4.json +165 -0
- data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
- data/spec/spec_tests/data/corpus/decimal128-6.json +131 -0
- data/spec/spec_tests/data/corpus/decimal128-7.json +327 -0
- data/spec/spec_tests/data/corpus/document.json +60 -0
- data/spec/spec_tests/data/corpus/double.json +87 -0
- data/spec/spec_tests/data/corpus/int32.json +43 -0
- data/spec/spec_tests/data/corpus/int64.json +43 -0
- data/spec/spec_tests/data/corpus/maxkey.json +12 -0
- data/spec/spec_tests/data/corpus/minkey.json +12 -0
- data/spec/spec_tests/data/corpus/multi-type-deprecated.json +15 -0
- data/spec/spec_tests/data/corpus/multi-type.json +11 -0
- data/spec/spec_tests/data/corpus/null.json +12 -0
- data/spec/spec_tests/data/corpus/oid.json +28 -0
- data/spec/spec_tests/data/corpus/regex.json +65 -0
- data/spec/spec_tests/data/corpus/string.json +72 -0
- data/spec/spec_tests/data/corpus/symbol.json +80 -0
- data/spec/spec_tests/data/corpus/timestamp.json +34 -0
- data/spec/spec_tests/data/corpus/top.json +262 -0
- data/spec/spec_tests/data/corpus/undefined.json +15 -0
- data/spec/spec_tests/data/corpus_legacy/array.json +49 -0
- data/spec/spec_tests/data/corpus_legacy/binary.json +69 -0
- data/spec/spec_tests/data/corpus_legacy/boolean.json +27 -0
- data/spec/spec_tests/data/corpus_legacy/code.json +67 -0
- data/spec/spec_tests/data/corpus_legacy/code_w_scope.json +78 -0
- data/spec/spec_tests/data/corpus_legacy/document.json +36 -0
- data/spec/spec_tests/data/corpus_legacy/double.json +69 -0
- data/spec/spec_tests/data/corpus_legacy/failures/datetime.json +31 -0
- data/spec/spec_tests/data/corpus_legacy/failures/dbpointer.json +42 -0
- data/spec/spec_tests/data/corpus_legacy/failures/int64.json +38 -0
- data/spec/spec_tests/data/corpus_legacy/failures/symbol.json +62 -0
- data/spec/spec_tests/data/corpus_legacy/int32.json +38 -0
- data/spec/spec_tests/data/corpus_legacy/maxkey.json +12 -0
- data/spec/spec_tests/data/corpus_legacy/minkey.json +12 -0
- data/spec/spec_tests/data/corpus_legacy/null.json +12 -0
- data/spec/spec_tests/data/corpus_legacy/oid.json +28 -0
- data/spec/spec_tests/data/corpus_legacy/regex.json +37 -0
- data/spec/spec_tests/data/corpus_legacy/string.json +67 -0
- data/spec/spec_tests/data/corpus_legacy/timestamp.json +18 -0
- data/spec/spec_tests/data/corpus_legacy/top.json +62 -0
- data/spec/spec_tests/data/corpus_legacy/undefined.json +13 -0
- data/spec/spec_tests/data/decimal128/decimal128-1.json +363 -0
- data/spec/spec_tests/data/decimal128/decimal128-2.json +793 -0
- data/spec/spec_tests/data/decimal128/decimal128-3.json +1771 -0
- data/spec/spec_tests/data/decimal128/decimal128-4.json +165 -0
- data/spec/spec_tests/data/decimal128/decimal128-5.json +402 -0
- data/spec/spec_tests/data/decimal128/decimal128-6.json +131 -0
- data/spec/spec_tests/data/decimal128/decimal128-7.json +327 -0
- data/spec/support/shared_examples.rb +32 -11
- data/spec/support/spec_config.rb +17 -0
- data/spec/support/utils.rb +58 -0
- metadata +284 -45
- checksums.yaml.gz.sig +0 -3
- data/ext/bson/native.c +0 -722
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,1840 @@
|
|
|
1
|
+
# rubocop:todo all
|
|
2
|
+
# Copyright (C) 2016-2020 MongoDB Inc.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
require "spec_helper"
|
|
17
|
+
|
|
18
|
+
describe BSON::Decimal128 do
|
|
19
|
+
|
|
20
|
+
let(:low_bits) do
|
|
21
|
+
decimal128.instance_variable_get(:@low)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
let(:high_bits) do
|
|
25
|
+
decimal128.instance_variable_get(:@high)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe '#initialize' do
|
|
29
|
+
|
|
30
|
+
context 'when the argument is neither a BigDecimal or String' do
|
|
31
|
+
|
|
32
|
+
it 'raises an InvalidDecimal128Argument error' do
|
|
33
|
+
expect {
|
|
34
|
+
described_class.new(:invalid)
|
|
35
|
+
}.to raise_exception(BSON::Error::InvalidDecimal128Argument, /A Decimal128 can only be created from a String or BigDecimal./ )
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
shared_examples_for 'an initialized BSON::Decimal128' do
|
|
40
|
+
|
|
41
|
+
let(:decimal128) do
|
|
42
|
+
described_class.new(argument)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
let(:buffer) do
|
|
46
|
+
decimal128.to_bson
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
let(:from_bson) do
|
|
50
|
+
described_class.from_bson(buffer, mode: :bson)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
let(:expected_bson) do
|
|
54
|
+
[expected_low_bits].pack(BSON::Int64::PACK) + [expected_high_bits].pack(BSON::Int64::PACK)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'sets the correct high order bits' do
|
|
58
|
+
expect(high_bits).to eq(expected_high_bits)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'sets the correct low order bits' do
|
|
62
|
+
expect(low_bits).to eq(expected_low_bits)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'serializes to bson' do
|
|
66
|
+
expect(buffer.to_s).to eq(expected_bson)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'deserializes to the correct bits' do
|
|
70
|
+
expect(from_bson.instance_variable_get(:@high)).to eq(expected_high_bits)
|
|
71
|
+
expect(from_bson.instance_variable_get(:@low)).to eq(expected_low_bits)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context 'when the object represents positive infinity' do
|
|
76
|
+
|
|
77
|
+
let(:expected_high_bits) { 0x7800000000000000 }
|
|
78
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
79
|
+
|
|
80
|
+
context 'when a BigDecimal is passed' do
|
|
81
|
+
|
|
82
|
+
let(:argument) { BigDecimal("Infinity") }
|
|
83
|
+
|
|
84
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context 'when a String is passed' do
|
|
88
|
+
|
|
89
|
+
let(:argument) { "Infinity" }
|
|
90
|
+
|
|
91
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context 'when the object represents negative infinity' do
|
|
96
|
+
|
|
97
|
+
let(:expected_high_bits) { 0xf800000000000000 }
|
|
98
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
99
|
+
|
|
100
|
+
context 'when a BigDecimal is passed' do
|
|
101
|
+
|
|
102
|
+
let(:argument) { BigDecimal("-Infinity") }
|
|
103
|
+
|
|
104
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context 'when a String is passed' do
|
|
108
|
+
|
|
109
|
+
let(:argument) { "-Infinity" }
|
|
110
|
+
|
|
111
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
context 'when the object represents NaN' do
|
|
116
|
+
|
|
117
|
+
let(:expected_high_bits) { 0x7c00000000000000 }
|
|
118
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
119
|
+
|
|
120
|
+
context 'when a BigDecimal is passed' do
|
|
121
|
+
|
|
122
|
+
let(:argument) { BigDecimal("NaN") }
|
|
123
|
+
|
|
124
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
context 'when a String is passed' do
|
|
128
|
+
|
|
129
|
+
let(:argument) { "NaN" }
|
|
130
|
+
|
|
131
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
context 'when the object represents -NaN' do
|
|
136
|
+
|
|
137
|
+
let(:expected_high_bits) { 0xfc00000000000000 }
|
|
138
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
139
|
+
|
|
140
|
+
context 'when a String is passed' do
|
|
141
|
+
|
|
142
|
+
let(:argument) { "-NaN" }
|
|
143
|
+
|
|
144
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
context 'when the object represents SNaN' do
|
|
149
|
+
|
|
150
|
+
let(:expected_high_bits) { 0x7e00000000000000 }
|
|
151
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
152
|
+
|
|
153
|
+
context 'when a String is passed' do
|
|
154
|
+
|
|
155
|
+
let(:argument) { "SNaN" }
|
|
156
|
+
|
|
157
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
context 'when the object represents -SNaN' do
|
|
162
|
+
|
|
163
|
+
let(:expected_high_bits) { 0xfe00000000000000 }
|
|
164
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
165
|
+
|
|
166
|
+
context 'when a String is passed' do
|
|
167
|
+
|
|
168
|
+
let(:argument) { "-SNaN" }
|
|
169
|
+
|
|
170
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
context 'when the object represents -0' do
|
|
175
|
+
|
|
176
|
+
let(:expected_high_bits) { 0xb040000000000000 }
|
|
177
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
178
|
+
|
|
179
|
+
context 'when a BigDecimal is passed' do
|
|
180
|
+
|
|
181
|
+
let(:argument) { BigDecimal("-0") }
|
|
182
|
+
|
|
183
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
context 'when a String is passed' do
|
|
187
|
+
|
|
188
|
+
let(:argument) { "-0" }
|
|
189
|
+
|
|
190
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
context 'when the object represents a positive integer' do
|
|
195
|
+
|
|
196
|
+
let(:expected_high_bits) { 0x3040000000000000 }
|
|
197
|
+
let(:expected_low_bits) { 0x000000000000000c }
|
|
198
|
+
|
|
199
|
+
context 'when a BigDecimal is passed' do
|
|
200
|
+
|
|
201
|
+
let(:argument) { BigDecimal(12) }
|
|
202
|
+
|
|
203
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
context 'when a String is passed' do
|
|
207
|
+
|
|
208
|
+
let(:argument) { "12" }
|
|
209
|
+
|
|
210
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
context 'when the object represents a negative integer' do
|
|
215
|
+
|
|
216
|
+
let(:expected_high_bits) { 0xb040000000000000 }
|
|
217
|
+
let(:expected_low_bits) { 0x000000000000000c }
|
|
218
|
+
|
|
219
|
+
context 'when a BigDecimal is passed' do
|
|
220
|
+
|
|
221
|
+
let(:argument) { BigDecimal(-12) }
|
|
222
|
+
|
|
223
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
context 'when a String is passed' do
|
|
227
|
+
|
|
228
|
+
let(:argument) { "-12" }
|
|
229
|
+
|
|
230
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
context 'when the object represents a positive float' do
|
|
235
|
+
|
|
236
|
+
let(:expected_high_bits) { 0x3036000000000000 }
|
|
237
|
+
let(:expected_low_bits) { 0x0000000000003039 }
|
|
238
|
+
|
|
239
|
+
context 'when a BigDecimal is passed' do
|
|
240
|
+
|
|
241
|
+
let(:argument) { BigDecimal(0.12345, 5) }
|
|
242
|
+
|
|
243
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
context 'when a String is passed' do
|
|
247
|
+
|
|
248
|
+
let(:argument) { "0.12345" }
|
|
249
|
+
|
|
250
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
context 'when the object represents a negative float' do
|
|
255
|
+
|
|
256
|
+
let(:expected_high_bits) { 0xb036000000000000 }
|
|
257
|
+
let(:expected_low_bits) { 0x0000000000003039 }
|
|
258
|
+
|
|
259
|
+
context 'when a BigDecimal is passed' do
|
|
260
|
+
|
|
261
|
+
let(:argument) { BigDecimal(-0.12345, 5) }
|
|
262
|
+
|
|
263
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
context 'when a String is passed' do
|
|
267
|
+
|
|
268
|
+
let(:argument) { "-0.12345" }
|
|
269
|
+
|
|
270
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
context 'when the object represents a large positive integer' do
|
|
275
|
+
|
|
276
|
+
let(:expected_high_bits) { 0x30403cde6fff9732 }
|
|
277
|
+
let(:expected_low_bits) { 0xde825cd07e96aff2 }
|
|
278
|
+
|
|
279
|
+
context 'when a BigDecimal is passed' do
|
|
280
|
+
|
|
281
|
+
let(:argument) { BigDecimal(1234567890123456789012345678901234) }
|
|
282
|
+
|
|
283
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
context 'when a String is passed' do
|
|
287
|
+
|
|
288
|
+
let(:argument) { "1234567890123456789012345678901234" }
|
|
289
|
+
|
|
290
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
context 'when the object represents a large negative integer' do
|
|
295
|
+
|
|
296
|
+
let(:expected_high_bits) { 0xb0403cde6fff9732 }
|
|
297
|
+
let(:expected_low_bits) { 0xde825cd07e96aff2 }
|
|
298
|
+
|
|
299
|
+
context 'when a BigDecimal is passed' do
|
|
300
|
+
|
|
301
|
+
let(:argument) { BigDecimal(-1234567890123456789012345678901234) }
|
|
302
|
+
|
|
303
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
context 'when a String is passed' do
|
|
307
|
+
|
|
308
|
+
let(:argument) { "-1234567890123456789012345678901234" }
|
|
309
|
+
|
|
310
|
+
it_behaves_like 'an initialized BSON::Decimal128'
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
context 'when range is exceeded' do
|
|
315
|
+
it 'raises InvalidRange' do
|
|
316
|
+
lambda do
|
|
317
|
+
described_class.new('1e10000')
|
|
318
|
+
end.should raise_error(BSON::Error::InvalidDecimal128Range, /Value out of range/)
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
context 'when precision is exceeded' do
|
|
323
|
+
it 'raises UnrepresentablePrecision' do
|
|
324
|
+
lambda do
|
|
325
|
+
described_class.new('1.000000000000000000000000000000000000000000000000001')
|
|
326
|
+
end.should raise_error(BSON::Error::UnrepresentablePrecision, /The value contains too much precision/)
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
context 'when deserializing' do
|
|
332
|
+
|
|
333
|
+
context 'When the value has trailing zeroes' do
|
|
334
|
+
|
|
335
|
+
let(:hex) do
|
|
336
|
+
'18000000136400D0070000000000000000000000003A3000'
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
let(:packed) do
|
|
340
|
+
[ hex ].pack('H*')
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
let(:buffer) do
|
|
344
|
+
BSON::ByteBuffer.new(packed)
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
let(:decimal128) do
|
|
348
|
+
BSON::Document.from_bson(buffer, mode: :bson)['d']
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
let(:object_from_string) do
|
|
352
|
+
BSON::Decimal128.from_string('2.000')
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
it 'has the correct high order' do
|
|
356
|
+
expect(decimal128.instance_variable_get(:@high)).to eq(3475090062469758976)
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
it 'has the correct low order' do
|
|
360
|
+
expect(decimal128.instance_variable_get(:@low)).to eq(2000)
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
it 'matches the object created from a string' do
|
|
364
|
+
expect(object_from_string).to eq(decimal128)
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
describe '#from_string' do
|
|
370
|
+
|
|
371
|
+
shared_examples_for 'a decimal128 initialized from a string' do
|
|
372
|
+
|
|
373
|
+
let(:decimal128) do
|
|
374
|
+
BSON::Decimal128.from_string(string)
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
let(:low_bits) do
|
|
378
|
+
decimal128.instance_variable_get(:@low)
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
let(:high_bits) do
|
|
382
|
+
decimal128.instance_variable_get(:@high)
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
it 'sets the correct high order bits' do
|
|
386
|
+
expect(high_bits).to eq(expected_high_bits)
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
it 'sets the correct low order bits' do
|
|
390
|
+
expect(low_bits).to eq(expected_low_bits)
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
context 'when the string represents a special type' do
|
|
395
|
+
|
|
396
|
+
context "when the string is 'NaN'" do
|
|
397
|
+
|
|
398
|
+
let(:string) { 'NaN' }
|
|
399
|
+
|
|
400
|
+
let(:expected_high_bits) { 0x7c00000000000000 }
|
|
401
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
402
|
+
|
|
403
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
context "when the string is '-NaN'" do
|
|
407
|
+
|
|
408
|
+
let(:string) { '-NaN' }
|
|
409
|
+
|
|
410
|
+
let(:expected_high_bits) { 0xfc00000000000000 }
|
|
411
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
412
|
+
|
|
413
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
context "when the string is 'SNaN'" do
|
|
417
|
+
|
|
418
|
+
let(:string) { 'SNaN' }
|
|
419
|
+
|
|
420
|
+
let(:expected_high_bits) { 0x7e00000000000000 }
|
|
421
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
422
|
+
|
|
423
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
context "when the string is '-SNaN'" do
|
|
427
|
+
|
|
428
|
+
let(:string) { '-SNaN' }
|
|
429
|
+
|
|
430
|
+
let(:expected_high_bits) { 0xfe00000000000000 }
|
|
431
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
432
|
+
|
|
433
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
context "when the string is 'Infinity'" do
|
|
437
|
+
|
|
438
|
+
let(:string) { 'Infinity' }
|
|
439
|
+
|
|
440
|
+
let(:expected_exponent) { nil }
|
|
441
|
+
let(:expected_significand) { nil }
|
|
442
|
+
let(:expected_high_bits) { 0x7800000000000000 }
|
|
443
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
444
|
+
|
|
445
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
context "when the string is '-Infinity'" do
|
|
449
|
+
|
|
450
|
+
let(:string) { '-Infinity' }
|
|
451
|
+
|
|
452
|
+
let(:expected_exponent) { nil }
|
|
453
|
+
let(:expected_significand) { nil }
|
|
454
|
+
let(:expected_high_bits) { 0xf800000000000000 }
|
|
455
|
+
let(:expected_low_bits) { 0x0000000000000000 }
|
|
456
|
+
|
|
457
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
context 'when the string represents 0' do
|
|
462
|
+
|
|
463
|
+
context "when the string is '0'" do
|
|
464
|
+
|
|
465
|
+
let(:string) { '0' }
|
|
466
|
+
|
|
467
|
+
let(:expected_exponent) { 0 }
|
|
468
|
+
let(:expected_significand) { 0 }
|
|
469
|
+
let(:expected_high_bits) { 0x3040000000000000 }
|
|
470
|
+
let(:expected_low_bits) { 0 }
|
|
471
|
+
|
|
472
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
context "when the string is '-0'" do
|
|
476
|
+
|
|
477
|
+
let(:string) { '-0' }
|
|
478
|
+
|
|
479
|
+
let(:expected_exponent) { 0 }
|
|
480
|
+
let(:expected_significand) { 0 }
|
|
481
|
+
let(:expected_high_bits) { 0xb040000000000000 }
|
|
482
|
+
let(:expected_low_bits) { 0 }
|
|
483
|
+
|
|
484
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
context "when the string is '0.0'" do
|
|
488
|
+
|
|
489
|
+
let(:string) { '0.0' }
|
|
490
|
+
|
|
491
|
+
let(:expected_exponent) { -1 }
|
|
492
|
+
let(:expected_significand) { 0 }
|
|
493
|
+
let(:expected_high_bits) { 0x303e000000000000 }
|
|
494
|
+
let(:expected_low_bits) { 0 }
|
|
495
|
+
|
|
496
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
context 'when the string represents an integer' do
|
|
501
|
+
|
|
502
|
+
context "when the string is '1'" do
|
|
503
|
+
|
|
504
|
+
let(:string) { '1' }
|
|
505
|
+
|
|
506
|
+
let(:expected_exponent) { 0 }
|
|
507
|
+
let(:expected_significand) { 1 }
|
|
508
|
+
let(:expected_high_bits) { 0x3040000000000000 }
|
|
509
|
+
let(:expected_low_bits) { 0x1 }
|
|
510
|
+
|
|
511
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
context "when the string is '-1'" do
|
|
515
|
+
|
|
516
|
+
let(:string) { '-1'}
|
|
517
|
+
|
|
518
|
+
let(:expected_exponent) { 0 }
|
|
519
|
+
let(:expected_significand) { 1 }
|
|
520
|
+
let(:expected_high_bits) { 0xb040000000000000 }
|
|
521
|
+
let(:expected_low_bits) { 0x1 }
|
|
522
|
+
|
|
523
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
context "when the string is '20'" do
|
|
527
|
+
|
|
528
|
+
let(:string) { '20' }
|
|
529
|
+
|
|
530
|
+
let(:expected_exponent) { 0 }
|
|
531
|
+
let(:expected_significand) { 20 }
|
|
532
|
+
let(:expected_low_bits) { 0x14 }
|
|
533
|
+
let(:expected_high_bits) { 0x3040000000000000 }
|
|
534
|
+
|
|
535
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
context "when the string is '-20'" do
|
|
539
|
+
|
|
540
|
+
let(:string) { '-20' }
|
|
541
|
+
|
|
542
|
+
let(:expected_exponent) { 0 }
|
|
543
|
+
let(:expected_significand) { 20 }
|
|
544
|
+
let(:expected_low_bits) { 0x14 }
|
|
545
|
+
let(:expected_high_bits) { 0xb040000000000000 }
|
|
546
|
+
|
|
547
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
context "when the string is '12345678901234567'" do
|
|
551
|
+
|
|
552
|
+
let(:string) { '12345678901234567' }
|
|
553
|
+
|
|
554
|
+
let(:expected_exponent) { 0 }
|
|
555
|
+
let(:expected_significand) { 12345678901234567 }
|
|
556
|
+
let(:expected_low_bits) { 0x002bdc545d6b4b87 }
|
|
557
|
+
let(:expected_high_bits) { 0x3040000000000000 }
|
|
558
|
+
|
|
559
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
context "when the string is '-12345678901234567'" do
|
|
563
|
+
|
|
564
|
+
let(:string) { '-12345678901234567' }
|
|
565
|
+
|
|
566
|
+
let(:expected_exponent) { 0 }
|
|
567
|
+
let(:expected_significand) { 12345678901234567 }
|
|
568
|
+
let(:expected_low_bits) { 0x002bdc545d6b4b87 }
|
|
569
|
+
let(:expected_high_bits) { 0xb040000000000000 }
|
|
570
|
+
|
|
571
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
context "when the string is '12345689012345789012345'" do
|
|
575
|
+
|
|
576
|
+
let(:string) { '12345689012345789012345' }
|
|
577
|
+
|
|
578
|
+
let(:expected_exponent) { 0 }
|
|
579
|
+
let(:expected_significand) { 12345689012345789012345 }
|
|
580
|
+
let(:expected_low_bits) { 0x42da3a76f9e0d979 }
|
|
581
|
+
let(:expected_high_bits) { 0x304000000000029d }
|
|
582
|
+
|
|
583
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
context "when the string is '-12345689012345789012345'" do
|
|
587
|
+
|
|
588
|
+
let(:string) { '-12345689012345789012345' }
|
|
589
|
+
|
|
590
|
+
let(:expected_exponent) { 0 }
|
|
591
|
+
let(:expected_significand) { 12345689012345789012345 }
|
|
592
|
+
let(:expected_low_bits) { 0x42da3a76f9e0d979 }
|
|
593
|
+
let(:expected_high_bits) { 0xb04000000000029d }
|
|
594
|
+
|
|
595
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
596
|
+
end
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
context 'when the string represents a fraction' do
|
|
600
|
+
|
|
601
|
+
context "when the string is '0.1'" do
|
|
602
|
+
|
|
603
|
+
let(:string) { '0.1' }
|
|
604
|
+
|
|
605
|
+
let(:expected_exponent) { -1 }
|
|
606
|
+
let(:expected_significand) { 1 }
|
|
607
|
+
let(:expected_low_bits) { 0x1 }
|
|
608
|
+
let(:expected_high_bits) { 0x303e000000000000 }
|
|
609
|
+
|
|
610
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
context "when the string is '-0.1'" do
|
|
614
|
+
|
|
615
|
+
let(:string) { '-0.1' }
|
|
616
|
+
|
|
617
|
+
let(:expected_exponent) { -1 }
|
|
618
|
+
let(:expected_significand) { 1 }
|
|
619
|
+
let(:expected_low_bits) { 0x1 }
|
|
620
|
+
let(:expected_high_bits) { 0xb03e000000000000 }
|
|
621
|
+
|
|
622
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
context "when the string is '0.123'" do
|
|
626
|
+
|
|
627
|
+
let(:string) { '0.123' }
|
|
628
|
+
|
|
629
|
+
let(:expected_exponent) { -3 }
|
|
630
|
+
let(:expected_significand) { 123 }
|
|
631
|
+
let(:expected_low_bits) { 0x7b }
|
|
632
|
+
let(:expected_high_bits) { 0x303a000000000000 }
|
|
633
|
+
|
|
634
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
context "when the string is '-0.123'" do
|
|
638
|
+
|
|
639
|
+
let(:string) { '-0.123' }
|
|
640
|
+
|
|
641
|
+
let(:expected_exponent) { -3 }
|
|
642
|
+
let(:expected_significand) { 123 }
|
|
643
|
+
let(:expected_low_bits) { 0x7b }
|
|
644
|
+
let(:expected_high_bits) { 0xb03a000000000000 }
|
|
645
|
+
|
|
646
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
context "when the string is '0.1234567890123456789012345678901234'" do
|
|
650
|
+
|
|
651
|
+
let(:string) { '0.1234567890123456789012345678901234' }
|
|
652
|
+
|
|
653
|
+
let(:expected_exponent) { -34 }
|
|
654
|
+
let(:expected_significand) { 1234567890123456789012345678901234 }
|
|
655
|
+
let(:expected_low_bits) { 0xde825cd07e96aff2 }
|
|
656
|
+
let(:expected_high_bits) { 0x2ffc3cde6fff9732 }
|
|
657
|
+
|
|
658
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
659
|
+
end
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
context 'when the string represents a fraction with a whole number' do
|
|
663
|
+
|
|
664
|
+
context "when the string is '1.2'" do
|
|
665
|
+
|
|
666
|
+
let(:string) { '1.2' }
|
|
667
|
+
|
|
668
|
+
let(:expected_exponent) { -1 }
|
|
669
|
+
let(:expected_significand) { 12 }
|
|
670
|
+
let(:expected_low_bits) { 0xc }
|
|
671
|
+
let(:expected_high_bits) { 0x303e000000000000 }
|
|
672
|
+
|
|
673
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
context "when the string is '-1.2'" do
|
|
677
|
+
|
|
678
|
+
let(:string) { '-1.2' }
|
|
679
|
+
|
|
680
|
+
let(:expected_exponent) { -1 }
|
|
681
|
+
let(:expected_significand) { 12 }
|
|
682
|
+
let(:expected_low_bits) { 0xc }
|
|
683
|
+
let(:expected_high_bits) { 0xb03e000000000000 }
|
|
684
|
+
|
|
685
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
context "when the string is '1.234'" do
|
|
689
|
+
|
|
690
|
+
let(:string) { '1.234' }
|
|
691
|
+
|
|
692
|
+
let(:expected_exponent) { -3 }
|
|
693
|
+
let(:expected_significand) { 1234 }
|
|
694
|
+
let(:expected_low_bits) { 0x4d2 }
|
|
695
|
+
let(:expected_high_bits) { 0x303a000000000000 }
|
|
696
|
+
|
|
697
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
698
|
+
end
|
|
699
|
+
|
|
700
|
+
context "when the string is '-1.234'" do
|
|
701
|
+
|
|
702
|
+
let(:string) { '-1.234' }
|
|
703
|
+
|
|
704
|
+
let(:expected_exponent) { -3 }
|
|
705
|
+
let(:expected_significand) { 1234 }
|
|
706
|
+
let(:expected_low_bits) { 0x4d2 }
|
|
707
|
+
let(:expected_high_bits) { 0xb03a000000000000 }
|
|
708
|
+
|
|
709
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
710
|
+
end
|
|
711
|
+
|
|
712
|
+
context "when the string is '123456789.123456789'" do
|
|
713
|
+
|
|
714
|
+
let(:string) { '123456789.123456789' }
|
|
715
|
+
|
|
716
|
+
let(:expected_exponent) { -9 }
|
|
717
|
+
let(:expected_significand) { 123456789123456789 }
|
|
718
|
+
let(:expected_low_bits) { 0x1b69b4bacd05f15 }
|
|
719
|
+
let(:expected_high_bits) { 0x302e000000000000 }
|
|
720
|
+
|
|
721
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
context "when the string is '-123456789.123456789'" do
|
|
725
|
+
|
|
726
|
+
let(:string) { '-123456789.123456789' }
|
|
727
|
+
|
|
728
|
+
let(:expected_exponent) { -9 }
|
|
729
|
+
let(:expected_significand) { 123456789123456789 }
|
|
730
|
+
let(:expected_low_bits) { 0x1b69b4bacd05f15 }
|
|
731
|
+
let(:expected_high_bits) { 0xb02e000000000000 }
|
|
732
|
+
|
|
733
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
734
|
+
end
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
context 'when the string represents a decimal with trailing zeros' do
|
|
738
|
+
|
|
739
|
+
context "when the string is '1.000'" do
|
|
740
|
+
|
|
741
|
+
let(:string) { '1.000' }
|
|
742
|
+
|
|
743
|
+
let(:expected_exponent) { -3 }
|
|
744
|
+
let(:expected_significand) { 1000 }
|
|
745
|
+
let(:expected_low_bits) { 0x3e8 }
|
|
746
|
+
let(:expected_high_bits) { 0x303a000000000000 }
|
|
747
|
+
|
|
748
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
context "when the string is '-1.000'" do
|
|
752
|
+
|
|
753
|
+
let(:string) { '-1.000' }
|
|
754
|
+
|
|
755
|
+
let(:expected_exponent) { -3 }
|
|
756
|
+
let(:expected_significand) { 1000 }
|
|
757
|
+
let(:expected_low_bits) { 0x3e8 }
|
|
758
|
+
let(:expected_high_bits) { 0xb03a000000000000 }
|
|
759
|
+
|
|
760
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
context "when the string is '100.000'" do
|
|
764
|
+
|
|
765
|
+
let(:string) { '100.000' }
|
|
766
|
+
|
|
767
|
+
let(:expected_exponent) { -3 }
|
|
768
|
+
let(:expected_significand) { 100000 }
|
|
769
|
+
let(:expected_low_bits) { 0x186a0 }
|
|
770
|
+
let(:expected_high_bits) { 0x303a000000000000 }
|
|
771
|
+
|
|
772
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
context "when the string is '-100.000'" do
|
|
776
|
+
|
|
777
|
+
let(:string) { '-100.000' }
|
|
778
|
+
|
|
779
|
+
let(:expected_exponent) { -3 }
|
|
780
|
+
let(:expected_significand) { 100000 }
|
|
781
|
+
let(:expected_low_bits) { 0x186a0 }
|
|
782
|
+
let(:expected_high_bits) { 0xb03a000000000000 }
|
|
783
|
+
|
|
784
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
785
|
+
end
|
|
786
|
+
|
|
787
|
+
context "when the string is '1.234000000'" do
|
|
788
|
+
|
|
789
|
+
let(:string) { '1.234000000' }
|
|
790
|
+
|
|
791
|
+
let(:expected_exponent) { -9 }
|
|
792
|
+
let(:expected_significand) { 1234000000 }
|
|
793
|
+
let(:expected_low_bits) { 0x498d5880 }
|
|
794
|
+
let(:expected_high_bits) { 0x302e000000000000 }
|
|
795
|
+
|
|
796
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
797
|
+
end
|
|
798
|
+
|
|
799
|
+
context "when the string is '-1.234000000'" do
|
|
800
|
+
|
|
801
|
+
let(:string) { '-1.234000000' }
|
|
802
|
+
|
|
803
|
+
let(:expected_exponent) { -9 }
|
|
804
|
+
let(:expected_significand) { 1234000000 }
|
|
805
|
+
let(:expected_low_bits) { 0x498d5880 }
|
|
806
|
+
let(:expected_high_bits) { 0xb02e000000000000 }
|
|
807
|
+
|
|
808
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
809
|
+
end
|
|
810
|
+
|
|
811
|
+
context 'when there are zeros following the decimal that are not trailing' do
|
|
812
|
+
|
|
813
|
+
context "when the string is '0.001234'" do
|
|
814
|
+
|
|
815
|
+
let(:string) { '0.001234' }
|
|
816
|
+
|
|
817
|
+
let(:expected_exponent) { -6 }
|
|
818
|
+
let(:expected_significand) { 1234 }
|
|
819
|
+
let(:expected_low_bits) { 0x4d2 }
|
|
820
|
+
let(:expected_high_bits) { 0x3034000000000000 }
|
|
821
|
+
|
|
822
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
823
|
+
end
|
|
824
|
+
end
|
|
825
|
+
|
|
826
|
+
context 'when there are zeros following the decimal that are not trailing' do
|
|
827
|
+
|
|
828
|
+
context "when the string is '0.00123400000'" do
|
|
829
|
+
|
|
830
|
+
let(:string) { '0.00123400000' }
|
|
831
|
+
|
|
832
|
+
let(:expected_exponent) { -11 }
|
|
833
|
+
let(:expected_significand) { 123400000 }
|
|
834
|
+
let(:expected_low_bits) { 0x75aef40 }
|
|
835
|
+
let(:expected_high_bits) { 0x302a000000000000 }
|
|
836
|
+
|
|
837
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
838
|
+
end
|
|
839
|
+
end
|
|
840
|
+
end
|
|
841
|
+
|
|
842
|
+
context 'when the string uses scientific notation' do
|
|
843
|
+
|
|
844
|
+
context 'when the exponent is positive' do
|
|
845
|
+
|
|
846
|
+
context 'when the positive exponent is denoted with E' do
|
|
847
|
+
|
|
848
|
+
context "when the string is '1.2E4'" do
|
|
849
|
+
|
|
850
|
+
let(:string) { '1.2E4' }
|
|
851
|
+
|
|
852
|
+
let(:expected_exponent) { 3 }
|
|
853
|
+
let(:expected_significand) { 12 }
|
|
854
|
+
let(:expected_low_bits) { 0xc }
|
|
855
|
+
let(:expected_high_bits) { 0x3046000000000000 }
|
|
856
|
+
|
|
857
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
858
|
+
end
|
|
859
|
+
|
|
860
|
+
context "when the string is '-1.2E4'" do
|
|
861
|
+
|
|
862
|
+
let(:string) { '-1.2E4' }
|
|
863
|
+
|
|
864
|
+
let(:expected_exponent) { 3 }
|
|
865
|
+
let(:expected_significand) { 12 }
|
|
866
|
+
let(:expected_low_bits) { 0xc }
|
|
867
|
+
let(:expected_high_bits) { 0xb046000000000000 }
|
|
868
|
+
|
|
869
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
870
|
+
end
|
|
871
|
+
end
|
|
872
|
+
|
|
873
|
+
context 'when the positive exponent is denoted with E+' do
|
|
874
|
+
|
|
875
|
+
context "when the string is '1.2E+4'" do
|
|
876
|
+
|
|
877
|
+
let(:string) { '1.2E4' }
|
|
878
|
+
|
|
879
|
+
let(:expected_exponent) { 3 }
|
|
880
|
+
let(:expected_significand) { 12 }
|
|
881
|
+
let(:expected_low_bits) { 0xc }
|
|
882
|
+
let(:expected_high_bits) { 0x3046000000000000 }
|
|
883
|
+
|
|
884
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
885
|
+
end
|
|
886
|
+
|
|
887
|
+
context "when the string is '-1.2E+4'" do
|
|
888
|
+
|
|
889
|
+
let(:string) { '-1.2E4' }
|
|
890
|
+
|
|
891
|
+
let(:expected_exponent) { 3 }
|
|
892
|
+
let(:expected_significand) { 12 }
|
|
893
|
+
let(:expected_low_bits) { 0xc }
|
|
894
|
+
let(:expected_high_bits) { 0xb046000000000000 }
|
|
895
|
+
|
|
896
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
897
|
+
end
|
|
898
|
+
end
|
|
899
|
+
end
|
|
900
|
+
|
|
901
|
+
context 'when the exponent is negative' do
|
|
902
|
+
|
|
903
|
+
context "when the string is '1.2E-4'" do
|
|
904
|
+
|
|
905
|
+
let(:string) { '1.2E-4' }
|
|
906
|
+
|
|
907
|
+
let(:expected_exponent) { -5 }
|
|
908
|
+
let(:expected_significand) { 12 }
|
|
909
|
+
let(:expected_low_bits) { 0xc }
|
|
910
|
+
let(:expected_high_bits) { 0x3036000000000000 }
|
|
911
|
+
|
|
912
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
913
|
+
end
|
|
914
|
+
|
|
915
|
+
context "when the string is '-1.2E-4'" do
|
|
916
|
+
|
|
917
|
+
let(:string) { '-1.2E-4' }
|
|
918
|
+
|
|
919
|
+
let(:expected_exponent) { -5 }
|
|
920
|
+
let(:expected_significand) { 12 }
|
|
921
|
+
let(:expected_low_bits) { 0xc }
|
|
922
|
+
let(:expected_high_bits) { 0xb036000000000000 }
|
|
923
|
+
|
|
924
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
925
|
+
end
|
|
926
|
+
|
|
927
|
+
context 'when there are trailing zeros' do
|
|
928
|
+
|
|
929
|
+
context "when the string is '1.200E-4'" do
|
|
930
|
+
|
|
931
|
+
let(:string) { '1.200E-4' }
|
|
932
|
+
|
|
933
|
+
let(:expected_exponent) { -7 }
|
|
934
|
+
let(:expected_significand) { 1200 }
|
|
935
|
+
let(:expected_low_bits) { 0x4b0 }
|
|
936
|
+
let(:expected_high_bits) { 0x3032000000000000 }
|
|
937
|
+
|
|
938
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
939
|
+
end
|
|
940
|
+
|
|
941
|
+
context "when the string is '-1.200E-4'" do
|
|
942
|
+
|
|
943
|
+
let(:string) { '-1.200E-4' }
|
|
944
|
+
|
|
945
|
+
let(:expected_exponent) { -7 }
|
|
946
|
+
let(:expected_significand) { 1200 }
|
|
947
|
+
let(:expected_low_bits) { 0x4b0 }
|
|
948
|
+
let(:expected_high_bits) { 0xb032000000000000 }
|
|
949
|
+
|
|
950
|
+
it_behaves_like 'a decimal128 initialized from a string'
|
|
951
|
+
end
|
|
952
|
+
end
|
|
953
|
+
end
|
|
954
|
+
end
|
|
955
|
+
end
|
|
956
|
+
|
|
957
|
+
describe '#to_s' do
|
|
958
|
+
|
|
959
|
+
shared_examples_for 'a decimal128 printed to a string' do
|
|
960
|
+
|
|
961
|
+
let(:buffer) do
|
|
962
|
+
buffer = BSON::ByteBuffer.new
|
|
963
|
+
buffer.put_decimal128(low_bits, high_bits)
|
|
964
|
+
end
|
|
965
|
+
let(:decimal) { BSON::Decimal128.from_bson(buffer) }
|
|
966
|
+
|
|
967
|
+
it 'prints the correct string' do
|
|
968
|
+
expect(decimal.to_s).to eq(expected_string)
|
|
969
|
+
end
|
|
970
|
+
end
|
|
971
|
+
|
|
972
|
+
context 'when the bits represent a special type' do
|
|
973
|
+
|
|
974
|
+
context 'when the decimal is NaN' do
|
|
975
|
+
|
|
976
|
+
let(:expected_string) { 'NaN' }
|
|
977
|
+
let(:high_bits) { 0x7c00000000000000 }
|
|
978
|
+
let(:low_bits) { 0x0 }
|
|
979
|
+
|
|
980
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
981
|
+
end
|
|
982
|
+
|
|
983
|
+
context 'when the decimal is negative NaN' do
|
|
984
|
+
|
|
985
|
+
let(:expected_string) { 'NaN' }
|
|
986
|
+
let(:high_bits) { 0xfc00000000000000 }
|
|
987
|
+
let(:low_bits) { 0x0000000000000000 }
|
|
988
|
+
|
|
989
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
990
|
+
end
|
|
991
|
+
|
|
992
|
+
context 'when the decimal is SNaN' do
|
|
993
|
+
|
|
994
|
+
let(:expected_string) { 'NaN' }
|
|
995
|
+
let(:high_bits) { 0x7e00000000000000 }
|
|
996
|
+
let(:low_bits) { 0x0000000000000000 }
|
|
997
|
+
|
|
998
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
999
|
+
end
|
|
1000
|
+
|
|
1001
|
+
context 'when the decimal is -SNaN' do
|
|
1002
|
+
|
|
1003
|
+
let(:expected_string) { 'NaN' }
|
|
1004
|
+
let(:high_bits) { 0xfe00000000000000 }
|
|
1005
|
+
let(:low_bits) { 0x0000000000000000 }
|
|
1006
|
+
|
|
1007
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1008
|
+
end
|
|
1009
|
+
|
|
1010
|
+
context 'when the decimal is NaN with a payload' do
|
|
1011
|
+
|
|
1012
|
+
let(:expected_string) { 'NaN' }
|
|
1013
|
+
let(:high_bits) { 0x7e00000000000000 }
|
|
1014
|
+
let(:low_bits) { 0x0000000000000008 }
|
|
1015
|
+
|
|
1016
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1017
|
+
end
|
|
1018
|
+
|
|
1019
|
+
context 'when the decimal is positive Infinity' do
|
|
1020
|
+
|
|
1021
|
+
let(:expected_string) { 'Infinity' }
|
|
1022
|
+
let(:high_bits) { 0x7800000000000000 }
|
|
1023
|
+
let(:low_bits) { 0x0000000000000000 }
|
|
1024
|
+
|
|
1025
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1026
|
+
end
|
|
1027
|
+
|
|
1028
|
+
context 'when the decimal is negative Infinity' do
|
|
1029
|
+
|
|
1030
|
+
let(:expected_string) { '-Infinity' }
|
|
1031
|
+
let(:high_bits) { 0xf800000000000000 }
|
|
1032
|
+
let(:low_bits) { 0x0000000000000000 }
|
|
1033
|
+
|
|
1034
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1035
|
+
end
|
|
1036
|
+
end
|
|
1037
|
+
|
|
1038
|
+
context 'when the string represents an integer' do
|
|
1039
|
+
|
|
1040
|
+
context 'when the decimal is 1' do
|
|
1041
|
+
|
|
1042
|
+
let(:expected_string) { '1' }
|
|
1043
|
+
let(:high_bits) { 0x3040000000000000 }
|
|
1044
|
+
let(:low_bits) { 0x0000000000000001 }
|
|
1045
|
+
|
|
1046
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1047
|
+
end
|
|
1048
|
+
|
|
1049
|
+
context 'when the decimal is -1' do
|
|
1050
|
+
|
|
1051
|
+
let(:expected_string) { '-1' }
|
|
1052
|
+
let(:high_bits) { 0xb040000000000000 }
|
|
1053
|
+
let(:low_bits) { 0x0000000000000001 }
|
|
1054
|
+
|
|
1055
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1056
|
+
end
|
|
1057
|
+
|
|
1058
|
+
context 'when the decimal is 20' do
|
|
1059
|
+
|
|
1060
|
+
let(:expected_string) { '20' }
|
|
1061
|
+
let(:high_bits) { 0x3040000000000000 }
|
|
1062
|
+
let(:low_bits) { 0x0000000000000014 }
|
|
1063
|
+
|
|
1064
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1065
|
+
end
|
|
1066
|
+
|
|
1067
|
+
context 'when the decimal is -20' do
|
|
1068
|
+
|
|
1069
|
+
let(:expected_string) { '-20' }
|
|
1070
|
+
let(:high_bits) { 0xb040000000000000 }
|
|
1071
|
+
let(:low_bits) { 0x0000000000000014 }
|
|
1072
|
+
|
|
1073
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1074
|
+
end
|
|
1075
|
+
|
|
1076
|
+
context 'when the decimal is 12345678901234567' do
|
|
1077
|
+
|
|
1078
|
+
let(:expected_string) { '12345678901234567' }
|
|
1079
|
+
let(:high_bits) { 0x3040000000000000 }
|
|
1080
|
+
let(:low_bits) { 0x002bdc545d6b4b87 }
|
|
1081
|
+
|
|
1082
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1083
|
+
end
|
|
1084
|
+
|
|
1085
|
+
context 'when the decimal is -12345678901234567' do
|
|
1086
|
+
|
|
1087
|
+
let(:expected_string) { '-12345678901234567' }
|
|
1088
|
+
let(:high_bits) { 0xb040000000000000 }
|
|
1089
|
+
let(:low_bits) { 0x002bdc545d6b4b87 }
|
|
1090
|
+
|
|
1091
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1092
|
+
end
|
|
1093
|
+
|
|
1094
|
+
context 'when the decimal is 12345689012345789012345' do
|
|
1095
|
+
|
|
1096
|
+
let(:expected_string) { '12345689012345789012345' }
|
|
1097
|
+
let(:high_bits) { 0x304000000000029d }
|
|
1098
|
+
let(:low_bits) { 0x42da3a76f9e0d979 }
|
|
1099
|
+
|
|
1100
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1101
|
+
end
|
|
1102
|
+
|
|
1103
|
+
context 'when the decimal is -12345689012345789012345' do
|
|
1104
|
+
|
|
1105
|
+
let(:expected_string) { '-12345689012345789012345' }
|
|
1106
|
+
let(:high_bits) { 0xb04000000000029d }
|
|
1107
|
+
let(:low_bits) { 0x42da3a76f9e0d979 }
|
|
1108
|
+
|
|
1109
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1110
|
+
end
|
|
1111
|
+
end
|
|
1112
|
+
|
|
1113
|
+
context 'when the string represents a fraction' do
|
|
1114
|
+
|
|
1115
|
+
context 'when the decimal is 0.1' do
|
|
1116
|
+
|
|
1117
|
+
let(:expected_string) { '0.1' }
|
|
1118
|
+
let(:high_bits) { 0x303e000000000000 }
|
|
1119
|
+
let(:low_bits) { 0x0000000000000001 }
|
|
1120
|
+
|
|
1121
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1122
|
+
end
|
|
1123
|
+
|
|
1124
|
+
context 'when the decimal is -0.1' do
|
|
1125
|
+
|
|
1126
|
+
let(:expected_string) { '-0.1' }
|
|
1127
|
+
let(:high_bits) { 0xb03e000000000000 }
|
|
1128
|
+
let(:low_bits) { 0x0000000000000001 }
|
|
1129
|
+
|
|
1130
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1131
|
+
end
|
|
1132
|
+
|
|
1133
|
+
context 'when the decimal is 0.123' do
|
|
1134
|
+
|
|
1135
|
+
let(:expected_string) { '0.123' }
|
|
1136
|
+
let(:high_bits) { 0x303a000000000000 }
|
|
1137
|
+
let(:low_bits) { 0x000000000000007b }
|
|
1138
|
+
|
|
1139
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1140
|
+
end
|
|
1141
|
+
|
|
1142
|
+
context 'when the decimal is -0.123' do
|
|
1143
|
+
|
|
1144
|
+
let(:expected_string) { '-0.123' }
|
|
1145
|
+
let(:high_bits) { 0xb03a000000000000 }
|
|
1146
|
+
let(:low_bits) { 0x000000000000007b }
|
|
1147
|
+
|
|
1148
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1149
|
+
end
|
|
1150
|
+
end
|
|
1151
|
+
|
|
1152
|
+
context 'when the decimal should have leading zeros' do
|
|
1153
|
+
|
|
1154
|
+
let(:expected_string) { '0.001234' }
|
|
1155
|
+
let(:high_bits) { 0x3034000000000000 }
|
|
1156
|
+
let(:low_bits) { 0x00000000000004d2 }
|
|
1157
|
+
|
|
1158
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1159
|
+
end
|
|
1160
|
+
|
|
1161
|
+
context 'when the decimal has trailing zeros' do
|
|
1162
|
+
|
|
1163
|
+
let(:expected_string) { '2.000' }
|
|
1164
|
+
let(:high_bits) { 0x303a000000000000 }
|
|
1165
|
+
let(:low_bits) { 0x00000000000007d0 }
|
|
1166
|
+
|
|
1167
|
+
it_behaves_like 'a decimal128 printed to a string'
|
|
1168
|
+
end
|
|
1169
|
+
end
|
|
1170
|
+
|
|
1171
|
+
describe "#==" do
|
|
1172
|
+
|
|
1173
|
+
context "when the high and low bits are identical" do
|
|
1174
|
+
|
|
1175
|
+
let(:string) do
|
|
1176
|
+
'1.23'
|
|
1177
|
+
end
|
|
1178
|
+
|
|
1179
|
+
let(:decimal128) do
|
|
1180
|
+
described_class.from_string(string)
|
|
1181
|
+
end
|
|
1182
|
+
|
|
1183
|
+
let(:other_decimal) do
|
|
1184
|
+
described_class.from_string(string)
|
|
1185
|
+
end
|
|
1186
|
+
|
|
1187
|
+
it "returns true" do
|
|
1188
|
+
expect(decimal128).to eq(other_decimal)
|
|
1189
|
+
end
|
|
1190
|
+
end
|
|
1191
|
+
|
|
1192
|
+
context "when the high and low bits are different" do
|
|
1193
|
+
|
|
1194
|
+
let(:string) do
|
|
1195
|
+
'1.23'
|
|
1196
|
+
end
|
|
1197
|
+
|
|
1198
|
+
let(:decimal128) do
|
|
1199
|
+
described_class.from_string(string)
|
|
1200
|
+
end
|
|
1201
|
+
|
|
1202
|
+
it "returns false" do
|
|
1203
|
+
expect(decimal128).to_not eq(described_class.new(BigDecimal('2.00')))
|
|
1204
|
+
end
|
|
1205
|
+
end
|
|
1206
|
+
|
|
1207
|
+
context "when other is not a decimal128" do
|
|
1208
|
+
|
|
1209
|
+
it "returns false" do
|
|
1210
|
+
expect(described_class.from_string('1')).to_not eq(nil)
|
|
1211
|
+
end
|
|
1212
|
+
end
|
|
1213
|
+
end
|
|
1214
|
+
|
|
1215
|
+
describe "#===" do
|
|
1216
|
+
|
|
1217
|
+
let(:decimal128) do
|
|
1218
|
+
described_class.new(BigDecimal('1.23'))
|
|
1219
|
+
end
|
|
1220
|
+
|
|
1221
|
+
context "when comparing with another decimal128" do
|
|
1222
|
+
|
|
1223
|
+
context "when the high and low bits are equal" do
|
|
1224
|
+
|
|
1225
|
+
let(:other) do
|
|
1226
|
+
described_class.from_string(decimal128.to_s)
|
|
1227
|
+
end
|
|
1228
|
+
|
|
1229
|
+
it "returns true" do
|
|
1230
|
+
expect(decimal128 === other).to be true
|
|
1231
|
+
end
|
|
1232
|
+
end
|
|
1233
|
+
|
|
1234
|
+
context "when the high and low bits are not equal" do
|
|
1235
|
+
|
|
1236
|
+
let(:other) do
|
|
1237
|
+
described_class.new(BigDecimal('1000.003'))
|
|
1238
|
+
end
|
|
1239
|
+
|
|
1240
|
+
it "returns false" do
|
|
1241
|
+
expect(decimal128 === other).to be false
|
|
1242
|
+
end
|
|
1243
|
+
end
|
|
1244
|
+
end
|
|
1245
|
+
|
|
1246
|
+
context "when comparing to an decimal128 class" do
|
|
1247
|
+
|
|
1248
|
+
it "returns false" do
|
|
1249
|
+
expect(decimal128 === BSON::Decimal128).to be false
|
|
1250
|
+
end
|
|
1251
|
+
end
|
|
1252
|
+
|
|
1253
|
+
context "when comparing with a non string or decimal128" do
|
|
1254
|
+
|
|
1255
|
+
it "returns false" do
|
|
1256
|
+
expect(decimal128 === "test").to be false
|
|
1257
|
+
end
|
|
1258
|
+
end
|
|
1259
|
+
|
|
1260
|
+
context "when comparing with a non decimal128 class" do
|
|
1261
|
+
|
|
1262
|
+
it "returns false" do
|
|
1263
|
+
expect(decimal128 === String).to be false
|
|
1264
|
+
end
|
|
1265
|
+
end
|
|
1266
|
+
end
|
|
1267
|
+
|
|
1268
|
+
describe "#as_json" do
|
|
1269
|
+
|
|
1270
|
+
let(:object) do
|
|
1271
|
+
described_class.new(BigDecimal('1.23'))
|
|
1272
|
+
end
|
|
1273
|
+
|
|
1274
|
+
it "returns the decimal128 as a string" do
|
|
1275
|
+
expect(object.as_json).to eq('1.23')
|
|
1276
|
+
end
|
|
1277
|
+
|
|
1278
|
+
%w[NaN -NaN SNaN -SNaN Infinity -Infinity].each do |value|
|
|
1279
|
+
context "when special value #{value}" do
|
|
1280
|
+
|
|
1281
|
+
let(:object) do
|
|
1282
|
+
described_class.new(value)
|
|
1283
|
+
end
|
|
1284
|
+
|
|
1285
|
+
it "returns nil to be consistent with ActiveSupport" do
|
|
1286
|
+
expect(object.as_json).to eq(nil)
|
|
1287
|
+
end
|
|
1288
|
+
end
|
|
1289
|
+
end
|
|
1290
|
+
|
|
1291
|
+
it_behaves_like "a JSON serializable object"
|
|
1292
|
+
end
|
|
1293
|
+
|
|
1294
|
+
describe "#as_extended_json" do
|
|
1295
|
+
|
|
1296
|
+
let(:object) do
|
|
1297
|
+
described_class.new(BigDecimal('1.23'))
|
|
1298
|
+
end
|
|
1299
|
+
|
|
1300
|
+
it "returns the decimal128 with $numberDecimal key" do
|
|
1301
|
+
expect(object.as_extended_json).to eq({ "$numberDecimal" => '1.23' })
|
|
1302
|
+
end
|
|
1303
|
+
|
|
1304
|
+
it_behaves_like "an Extended JSON serializable object"
|
|
1305
|
+
end
|
|
1306
|
+
|
|
1307
|
+
describe "::BSON_TYPE" do
|
|
1308
|
+
|
|
1309
|
+
it "returns 0x13" do
|
|
1310
|
+
expect(described_class::BSON_TYPE).to eq(19.chr)
|
|
1311
|
+
end
|
|
1312
|
+
end
|
|
1313
|
+
|
|
1314
|
+
describe "#bson_type" do
|
|
1315
|
+
|
|
1316
|
+
let(:code) do
|
|
1317
|
+
described_class.new(BigDecimal('1.23'))
|
|
1318
|
+
end
|
|
1319
|
+
|
|
1320
|
+
it "returns 0x13" do
|
|
1321
|
+
expect(code.bson_type).to eq(described_class::BSON_TYPE)
|
|
1322
|
+
end
|
|
1323
|
+
end
|
|
1324
|
+
|
|
1325
|
+
describe "#eql" do
|
|
1326
|
+
|
|
1327
|
+
context "when high and low bits are identical" do
|
|
1328
|
+
|
|
1329
|
+
let(:string) do
|
|
1330
|
+
'2.00'
|
|
1331
|
+
end
|
|
1332
|
+
|
|
1333
|
+
let(:decimal128) do
|
|
1334
|
+
described_class.from_string(string)
|
|
1335
|
+
end
|
|
1336
|
+
|
|
1337
|
+
let(:other_decimal) do
|
|
1338
|
+
described_class.from_string(string)
|
|
1339
|
+
end
|
|
1340
|
+
|
|
1341
|
+
it "returns true" do
|
|
1342
|
+
expect(decimal128).to eql(other_decimal)
|
|
1343
|
+
end
|
|
1344
|
+
end
|
|
1345
|
+
|
|
1346
|
+
context "when the high and low bit are different" do
|
|
1347
|
+
|
|
1348
|
+
let(:string) do
|
|
1349
|
+
'2.00'
|
|
1350
|
+
end
|
|
1351
|
+
|
|
1352
|
+
let(:decimal128) do
|
|
1353
|
+
described_class.from_string(string)
|
|
1354
|
+
end
|
|
1355
|
+
|
|
1356
|
+
it "returns false" do
|
|
1357
|
+
expect(decimal128).to_not eql(described_class.new(BigDecimal('2')))
|
|
1358
|
+
end
|
|
1359
|
+
end
|
|
1360
|
+
|
|
1361
|
+
context "when other is not a Decimal128" do
|
|
1362
|
+
|
|
1363
|
+
it "returns false" do
|
|
1364
|
+
expect(described_class.from_string('2')).to_not eql(nil)
|
|
1365
|
+
end
|
|
1366
|
+
end
|
|
1367
|
+
end
|
|
1368
|
+
|
|
1369
|
+
describe "#hash" do
|
|
1370
|
+
|
|
1371
|
+
let(:decimal128) do
|
|
1372
|
+
described_class.new(BigDecimal('-1234E+33'))
|
|
1373
|
+
end
|
|
1374
|
+
|
|
1375
|
+
it "returns a hash of the high and low bits" do
|
|
1376
|
+
expect(decimal128.hash).to eq(BSON::Decimal128.from_bson(decimal128.to_bson).hash)
|
|
1377
|
+
end
|
|
1378
|
+
end
|
|
1379
|
+
|
|
1380
|
+
describe "#inspect" do
|
|
1381
|
+
|
|
1382
|
+
let(:decimal128) do
|
|
1383
|
+
described_class.new(BigDecimal('1.23'))
|
|
1384
|
+
end
|
|
1385
|
+
|
|
1386
|
+
it "returns the inspection with the decimal128 to_s" do
|
|
1387
|
+
expect(decimal128.inspect).to eq("BSON::Decimal128('#{decimal128.to_s}')")
|
|
1388
|
+
end
|
|
1389
|
+
end
|
|
1390
|
+
|
|
1391
|
+
describe "#to_d" do
|
|
1392
|
+
|
|
1393
|
+
shared_examples_for 'a decimal128 convertible to a Ruby BigDecimal' do
|
|
1394
|
+
|
|
1395
|
+
let(:decimal128) do
|
|
1396
|
+
described_class.new(big_decimal)
|
|
1397
|
+
end
|
|
1398
|
+
|
|
1399
|
+
it 'properly converts the Decimal128 to a BigDecimal' do
|
|
1400
|
+
expect(decimal128.to_d).to eq(expected_big_decimal)
|
|
1401
|
+
end
|
|
1402
|
+
|
|
1403
|
+
it 'permits the alias #to_big_decimal' do
|
|
1404
|
+
expect(decimal128.to_big_decimal).to eq(expected_big_decimal)
|
|
1405
|
+
end
|
|
1406
|
+
end
|
|
1407
|
+
|
|
1408
|
+
context 'when the Decimal128 is a special type' do
|
|
1409
|
+
|
|
1410
|
+
context 'when the value is Infinity' do
|
|
1411
|
+
|
|
1412
|
+
let(:big_decimal) do
|
|
1413
|
+
BigDecimal('Infinity')
|
|
1414
|
+
end
|
|
1415
|
+
|
|
1416
|
+
let(:expected_big_decimal) do
|
|
1417
|
+
big_decimal
|
|
1418
|
+
end
|
|
1419
|
+
|
|
1420
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1421
|
+
end
|
|
1422
|
+
|
|
1423
|
+
context 'when the value is -Infinity' do
|
|
1424
|
+
|
|
1425
|
+
let(:big_decimal) do
|
|
1426
|
+
BigDecimal('-Infinity')
|
|
1427
|
+
end
|
|
1428
|
+
|
|
1429
|
+
let(:expected_big_decimal) do
|
|
1430
|
+
big_decimal
|
|
1431
|
+
end
|
|
1432
|
+
|
|
1433
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1434
|
+
end
|
|
1435
|
+
end
|
|
1436
|
+
|
|
1437
|
+
context 'when the value represents an Integer' do
|
|
1438
|
+
|
|
1439
|
+
context 'when the value is 1' do
|
|
1440
|
+
|
|
1441
|
+
let(:big_decimal) do
|
|
1442
|
+
BigDecimal(1)
|
|
1443
|
+
end
|
|
1444
|
+
|
|
1445
|
+
let(:expected_big_decimal) do
|
|
1446
|
+
big_decimal
|
|
1447
|
+
end
|
|
1448
|
+
|
|
1449
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1450
|
+
end
|
|
1451
|
+
|
|
1452
|
+
context 'when the value is -1' do
|
|
1453
|
+
|
|
1454
|
+
let(:big_decimal) do
|
|
1455
|
+
BigDecimal(-1)
|
|
1456
|
+
end
|
|
1457
|
+
|
|
1458
|
+
let(:expected_big_decimal) do
|
|
1459
|
+
big_decimal
|
|
1460
|
+
end
|
|
1461
|
+
|
|
1462
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1463
|
+
end
|
|
1464
|
+
|
|
1465
|
+
context 'when the value is 20' do
|
|
1466
|
+
|
|
1467
|
+
let(:big_decimal) do
|
|
1468
|
+
BigDecimal(20)
|
|
1469
|
+
end
|
|
1470
|
+
|
|
1471
|
+
let(:expected_big_decimal) do
|
|
1472
|
+
big_decimal
|
|
1473
|
+
end
|
|
1474
|
+
|
|
1475
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1476
|
+
end
|
|
1477
|
+
|
|
1478
|
+
context 'when the value is -20' do
|
|
1479
|
+
|
|
1480
|
+
let(:big_decimal) do
|
|
1481
|
+
BigDecimal(-20)
|
|
1482
|
+
end
|
|
1483
|
+
|
|
1484
|
+
let(:expected_big_decimal) do
|
|
1485
|
+
big_decimal
|
|
1486
|
+
end
|
|
1487
|
+
|
|
1488
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1489
|
+
end
|
|
1490
|
+
|
|
1491
|
+
context 'when the value is 12345678901234567' do
|
|
1492
|
+
|
|
1493
|
+
let(:big_decimal) do
|
|
1494
|
+
BigDecimal(12345678901234567)
|
|
1495
|
+
end
|
|
1496
|
+
|
|
1497
|
+
let(:expected_big_decimal) do
|
|
1498
|
+
big_decimal
|
|
1499
|
+
end
|
|
1500
|
+
|
|
1501
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1502
|
+
end
|
|
1503
|
+
|
|
1504
|
+
context 'when the value is -12345678901234567' do
|
|
1505
|
+
|
|
1506
|
+
let(:big_decimal) do
|
|
1507
|
+
BigDecimal(-12345678901234567)
|
|
1508
|
+
end
|
|
1509
|
+
|
|
1510
|
+
let(:expected_big_decimal) do
|
|
1511
|
+
big_decimal
|
|
1512
|
+
end
|
|
1513
|
+
|
|
1514
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1515
|
+
end
|
|
1516
|
+
|
|
1517
|
+
context 'when the value is 12345689012345789012345' do
|
|
1518
|
+
|
|
1519
|
+
let(:big_decimal) do
|
|
1520
|
+
BigDecimal(12345689012345789012345)
|
|
1521
|
+
end
|
|
1522
|
+
|
|
1523
|
+
let(:expected_big_decimal) do
|
|
1524
|
+
big_decimal
|
|
1525
|
+
end
|
|
1526
|
+
|
|
1527
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1528
|
+
end
|
|
1529
|
+
|
|
1530
|
+
context 'when the value is -12345689012345789012345' do
|
|
1531
|
+
|
|
1532
|
+
let(:big_decimal) do
|
|
1533
|
+
BigDecimal(-12345689012345789012345)
|
|
1534
|
+
end
|
|
1535
|
+
|
|
1536
|
+
let(:expected_big_decimal) do
|
|
1537
|
+
big_decimal
|
|
1538
|
+
end
|
|
1539
|
+
|
|
1540
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1541
|
+
end
|
|
1542
|
+
end
|
|
1543
|
+
|
|
1544
|
+
context 'when the value has a fraction' do
|
|
1545
|
+
|
|
1546
|
+
context 'when the value is 0.1' do
|
|
1547
|
+
|
|
1548
|
+
let(:big_decimal) do
|
|
1549
|
+
BigDecimal(0.1, 1)
|
|
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 is -0.1' do
|
|
1560
|
+
|
|
1561
|
+
let(:big_decimal) do
|
|
1562
|
+
BigDecimal(-0.1, 1)
|
|
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
|
+
|
|
1572
|
+
context 'when the value is 0.123' do
|
|
1573
|
+
|
|
1574
|
+
let(:big_decimal) do
|
|
1575
|
+
BigDecimal(0.123, 3)
|
|
1576
|
+
end
|
|
1577
|
+
|
|
1578
|
+
let(:expected_big_decimal) do
|
|
1579
|
+
big_decimal
|
|
1580
|
+
end
|
|
1581
|
+
|
|
1582
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1583
|
+
end
|
|
1584
|
+
|
|
1585
|
+
context 'when the value is -0.123' do
|
|
1586
|
+
|
|
1587
|
+
let(:big_decimal) do
|
|
1588
|
+
BigDecimal(-0.123, 3)
|
|
1589
|
+
end
|
|
1590
|
+
|
|
1591
|
+
let(:expected_big_decimal) do
|
|
1592
|
+
big_decimal
|
|
1593
|
+
end
|
|
1594
|
+
|
|
1595
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1596
|
+
end
|
|
1597
|
+
end
|
|
1598
|
+
|
|
1599
|
+
context 'when the value has leading zeros' do
|
|
1600
|
+
|
|
1601
|
+
let(:big_decimal) do
|
|
1602
|
+
BigDecimal(0.001234, 4)
|
|
1603
|
+
end
|
|
1604
|
+
|
|
1605
|
+
let(:expected_big_decimal) do
|
|
1606
|
+
big_decimal
|
|
1607
|
+
end
|
|
1608
|
+
|
|
1609
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1610
|
+
end
|
|
1611
|
+
|
|
1612
|
+
context 'when the value has trailing zeros' do
|
|
1613
|
+
|
|
1614
|
+
let(:big_decimal) do
|
|
1615
|
+
BigDecimal(2.000, 4)
|
|
1616
|
+
end
|
|
1617
|
+
|
|
1618
|
+
let(:expected_big_decimal) do
|
|
1619
|
+
big_decimal
|
|
1620
|
+
end
|
|
1621
|
+
|
|
1622
|
+
it_behaves_like 'a decimal128 convertible to a Ruby BigDecimal'
|
|
1623
|
+
end
|
|
1624
|
+
end
|
|
1625
|
+
|
|
1626
|
+
%w(== ===).each do |eq_op|
|
|
1627
|
+
let(:lhs) { described_class.new('1.2e12') }
|
|
1628
|
+
|
|
1629
|
+
describe "##{eq_op}" do
|
|
1630
|
+
context 'when rhs is equal to lhs' do
|
|
1631
|
+
context 'when both are Decimal128 instances' do
|
|
1632
|
+
let(:rhs) { described_class.new('1.2e12') }
|
|
1633
|
+
|
|
1634
|
+
it 'is true' do
|
|
1635
|
+
(lhs == rhs).should be true
|
|
1636
|
+
end
|
|
1637
|
+
end
|
|
1638
|
+
|
|
1639
|
+
context 'when rhs is of a different type' do
|
|
1640
|
+
[
|
|
1641
|
+
1200000000000,
|
|
1642
|
+
1200000000000.0,
|
|
1643
|
+
BigDecimal('1.2e12'),
|
|
1644
|
+
].each do |rhs|
|
|
1645
|
+
context "when rhs is #{rhs.class}" do
|
|
1646
|
+
it 'is true' do
|
|
1647
|
+
pending 'RUBY-2952'
|
|
1648
|
+
|
|
1649
|
+
(lhs == rhs).should be true
|
|
1650
|
+
end
|
|
1651
|
+
end
|
|
1652
|
+
end
|
|
1653
|
+
end
|
|
1654
|
+
end
|
|
1655
|
+
|
|
1656
|
+
context 'when rhs is not equal to lhs' do
|
|
1657
|
+
context 'when both are Decimal128 instances' do
|
|
1658
|
+
let(:rhs) { described_class.new('1.21e12') }
|
|
1659
|
+
|
|
1660
|
+
it 'is false' do
|
|
1661
|
+
(lhs == rhs).should be false
|
|
1662
|
+
end
|
|
1663
|
+
end
|
|
1664
|
+
|
|
1665
|
+
context 'when rhs is of a different type' do
|
|
1666
|
+
|
|
1667
|
+
[
|
|
1668
|
+
1200000000001,
|
|
1669
|
+
1200000000001.0,
|
|
1670
|
+
BigDecimal('1.21e12'),
|
|
1671
|
+
].each do |rhs|
|
|
1672
|
+
context "when rhs is #{rhs.class}" do
|
|
1673
|
+
it 'is false' do
|
|
1674
|
+
(lhs == rhs).should be false
|
|
1675
|
+
end
|
|
1676
|
+
end
|
|
1677
|
+
end
|
|
1678
|
+
end
|
|
1679
|
+
end
|
|
1680
|
+
end
|
|
1681
|
+
end
|
|
1682
|
+
|
|
1683
|
+
describe "#<=>" do
|
|
1684
|
+
|
|
1685
|
+
let(:lhs) { described_class.new('1.2e12') }
|
|
1686
|
+
|
|
1687
|
+
context 'when lhs is less than rhs' do
|
|
1688
|
+
context 'when both are Decimal128 instances' do
|
|
1689
|
+
let(:rhs) { described_class.new('1.21e12') }
|
|
1690
|
+
|
|
1691
|
+
it 'is -1' do
|
|
1692
|
+
(lhs <=> rhs).should be -1
|
|
1693
|
+
end
|
|
1694
|
+
end
|
|
1695
|
+
|
|
1696
|
+
context 'when rhs is of a different type' do
|
|
1697
|
+
[
|
|
1698
|
+
1200000000001,
|
|
1699
|
+
1200000000001.0,
|
|
1700
|
+
BigDecimal('1.21e12'),
|
|
1701
|
+
].each do |rhs|
|
|
1702
|
+
context "when rhs is #{rhs.class}" do
|
|
1703
|
+
it 'is -1' do
|
|
1704
|
+
(lhs <=> rhs).should be -1
|
|
1705
|
+
end
|
|
1706
|
+
end
|
|
1707
|
+
end
|
|
1708
|
+
end
|
|
1709
|
+
end
|
|
1710
|
+
|
|
1711
|
+
context 'when rhs is equal to lhs' do
|
|
1712
|
+
context 'when both are Decimal128 instances' do
|
|
1713
|
+
let(:rhs) { described_class.new('1.2e12') }
|
|
1714
|
+
|
|
1715
|
+
it 'is 0' do
|
|
1716
|
+
(lhs <=> rhs).should be 0
|
|
1717
|
+
end
|
|
1718
|
+
end
|
|
1719
|
+
|
|
1720
|
+
context 'when rhs is of a different type' do
|
|
1721
|
+
|
|
1722
|
+
[
|
|
1723
|
+
1200000000000,
|
|
1724
|
+
1200000000000.0,
|
|
1725
|
+
BigDecimal('1.2e12'),
|
|
1726
|
+
].each do |rhs|
|
|
1727
|
+
context "when rhs is #{rhs.class}" do
|
|
1728
|
+
it 'is 0' do
|
|
1729
|
+
(lhs <=> rhs).should be 0
|
|
1730
|
+
end
|
|
1731
|
+
end
|
|
1732
|
+
end
|
|
1733
|
+
end
|
|
1734
|
+
end
|
|
1735
|
+
|
|
1736
|
+
context 'when rhs is greater than lhs' do
|
|
1737
|
+
context 'when both are Decimal128 instances' do
|
|
1738
|
+
let(:rhs) { described_class.new('1.1e12') }
|
|
1739
|
+
|
|
1740
|
+
it 'is 1' do
|
|
1741
|
+
(lhs <=> rhs).should be 1
|
|
1742
|
+
end
|
|
1743
|
+
end
|
|
1744
|
+
|
|
1745
|
+
context 'when rhs is of a different type' do
|
|
1746
|
+
|
|
1747
|
+
[
|
|
1748
|
+
1100000000000,
|
|
1749
|
+
1100000000000.0,
|
|
1750
|
+
BigDecimal('1.1e12'),
|
|
1751
|
+
].each do |rhs|
|
|
1752
|
+
context "when rhs is #{rhs.class}" do
|
|
1753
|
+
it 'is 1' do
|
|
1754
|
+
(lhs <=> rhs).should be 1
|
|
1755
|
+
end
|
|
1756
|
+
end
|
|
1757
|
+
end
|
|
1758
|
+
end
|
|
1759
|
+
end
|
|
1760
|
+
end
|
|
1761
|
+
|
|
1762
|
+
describe "#<" do
|
|
1763
|
+
|
|
1764
|
+
let(:lhs) { described_class.new('1.2e12') }
|
|
1765
|
+
|
|
1766
|
+
context 'when lhs is less than rhs' do
|
|
1767
|
+
context 'when both are Decimal128 instances' do
|
|
1768
|
+
let(:rhs) { described_class.new('1.21e12') }
|
|
1769
|
+
|
|
1770
|
+
it 'is true' do
|
|
1771
|
+
(lhs < rhs).should be true
|
|
1772
|
+
end
|
|
1773
|
+
end
|
|
1774
|
+
|
|
1775
|
+
context 'when rhs is of a different type' do
|
|
1776
|
+
[
|
|
1777
|
+
1200000000001,
|
|
1778
|
+
1200000000001.0,
|
|
1779
|
+
BigDecimal('1.21e12'),
|
|
1780
|
+
].each do |rhs|
|
|
1781
|
+
context "when rhs is #{rhs.class}" do
|
|
1782
|
+
it 'is true' do
|
|
1783
|
+
(lhs < rhs).should be true
|
|
1784
|
+
end
|
|
1785
|
+
end
|
|
1786
|
+
end
|
|
1787
|
+
end
|
|
1788
|
+
end
|
|
1789
|
+
|
|
1790
|
+
context 'when rhs is equal to lhs' do
|
|
1791
|
+
context 'when both are Decimal128 instances' do
|
|
1792
|
+
let(:rhs) { described_class.new('1.2e12') }
|
|
1793
|
+
|
|
1794
|
+
it 'is false' do
|
|
1795
|
+
(lhs < rhs).should be false
|
|
1796
|
+
end
|
|
1797
|
+
end
|
|
1798
|
+
|
|
1799
|
+
context 'when rhs is of a different type' do
|
|
1800
|
+
|
|
1801
|
+
[
|
|
1802
|
+
1200000000000,
|
|
1803
|
+
1200000000000.0,
|
|
1804
|
+
BigDecimal('1.2e12'),
|
|
1805
|
+
].each do |rhs|
|
|
1806
|
+
context "when rhs is #{rhs.class}" do
|
|
1807
|
+
it 'is false' do
|
|
1808
|
+
(lhs < rhs).should be false
|
|
1809
|
+
end
|
|
1810
|
+
end
|
|
1811
|
+
end
|
|
1812
|
+
end
|
|
1813
|
+
end
|
|
1814
|
+
|
|
1815
|
+
context 'when rhs is greater than lhs' do
|
|
1816
|
+
context 'when both are Decimal128 instances' do
|
|
1817
|
+
let(:rhs) { described_class.new('1.1e12') }
|
|
1818
|
+
|
|
1819
|
+
it 'is false' do
|
|
1820
|
+
(lhs < rhs).should be false
|
|
1821
|
+
end
|
|
1822
|
+
end
|
|
1823
|
+
|
|
1824
|
+
context 'when rhs is of a different type' do
|
|
1825
|
+
|
|
1826
|
+
[
|
|
1827
|
+
1100000000000,
|
|
1828
|
+
1100000000000.0,
|
|
1829
|
+
BigDecimal('1.1e12'),
|
|
1830
|
+
].each do |rhs|
|
|
1831
|
+
context "when rhs is #{rhs.class}" do
|
|
1832
|
+
it 'is false' do
|
|
1833
|
+
(lhs < rhs).should be false
|
|
1834
|
+
end
|
|
1835
|
+
end
|
|
1836
|
+
end
|
|
1837
|
+
end
|
|
1838
|
+
end
|
|
1839
|
+
end
|
|
1840
|
+
end
|