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.
Files changed (226) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +106 -7
  3. data/Rakefile +86 -43
  4. data/ext/bson/{native-endian.h → bson-endian.h} +14 -107
  5. data/ext/bson/bson-native.h +135 -0
  6. data/ext/bson/bytebuf.c +133 -0
  7. data/ext/bson/endian.c +117 -0
  8. data/ext/bson/extconf.rb +8 -3
  9. data/ext/bson/init.c +364 -0
  10. data/ext/bson/libbson-utf8.c +230 -0
  11. data/ext/bson/read.c +470 -0
  12. data/ext/bson/util.c +250 -0
  13. data/ext/bson/write.c +675 -0
  14. data/lib/bson/active_support.rb +19 -0
  15. data/lib/bson/array.rb +97 -30
  16. data/lib/bson/big_decimal.rb +77 -0
  17. data/lib/bson/binary.rb +510 -70
  18. data/lib/bson/boolean.rb +15 -4
  19. data/lib/bson/code.rb +25 -12
  20. data/lib/bson/code_with_scope.rb +41 -15
  21. data/lib/bson/config.rb +3 -28
  22. data/lib/bson/date.rb +16 -4
  23. data/lib/bson/date_time.rb +6 -4
  24. data/lib/bson/db_pointer.rb +110 -0
  25. data/lib/bson/dbref.rb +154 -0
  26. data/lib/bson/decimal128/builder.rb +456 -0
  27. data/lib/bson/decimal128.rb +272 -0
  28. data/lib/bson/document.rb +177 -7
  29. data/lib/bson/environment.rb +17 -2
  30. data/lib/bson/error/bson_decode_error.rb +11 -0
  31. data/lib/bson/error/ext_json_parse_error.rb +11 -0
  32. data/lib/bson/error/illegal_key.rb +23 -0
  33. data/lib/bson/error/invalid_binary_type.rb +37 -0
  34. data/lib/bson/error/invalid_dbref_argument.rb +12 -0
  35. data/lib/bson/error/invalid_decimal128_argument.rb +25 -0
  36. data/lib/bson/error/invalid_decimal128_range.rb +27 -0
  37. data/lib/bson/error/invalid_decimal128_string.rb +26 -0
  38. data/lib/bson/error/invalid_key.rb +24 -0
  39. data/lib/bson/error/invalid_object_id.rb +11 -0
  40. data/lib/bson/error/invalid_regexp_pattern.rb +13 -0
  41. data/lib/bson/error/unrepresentable_precision.rb +19 -0
  42. data/lib/bson/error/unserializable_class.rb +13 -0
  43. data/lib/bson/error/unsupported_binary_subtype.rb +12 -0
  44. data/lib/bson/error/unsupported_type.rb +11 -0
  45. data/lib/bson/error.rb +22 -0
  46. data/lib/bson/ext_json.rb +389 -0
  47. data/lib/bson/false_class.rb +6 -4
  48. data/lib/bson/float.rb +43 -7
  49. data/lib/bson/hash.rb +152 -37
  50. data/lib/bson/int32.rb +104 -6
  51. data/lib/bson/int64.rb +111 -8
  52. data/lib/bson/integer.rb +43 -9
  53. data/lib/bson/json.rb +3 -1
  54. data/lib/bson/max_key.rb +21 -10
  55. data/lib/bson/min_key.rb +21 -10
  56. data/lib/bson/nil_class.rb +7 -3
  57. data/lib/bson/object.rb +25 -17
  58. data/lib/bson/object_id.rb +98 -113
  59. data/lib/bson/open_struct.rb +59 -0
  60. data/lib/bson/regexp.rb +129 -56
  61. data/lib/bson/registry.rb +7 -10
  62. data/lib/bson/specialized.rb +8 -4
  63. data/lib/bson/string.rb +12 -32
  64. data/lib/bson/symbol.rb +107 -11
  65. data/lib/bson/time.rb +68 -7
  66. data/lib/bson/time_with_zone.rb +67 -0
  67. data/lib/bson/timestamp.rb +50 -10
  68. data/lib/bson/true_class.rb +6 -4
  69. data/lib/bson/undefined.rb +28 -2
  70. data/lib/bson/vector.rb +44 -0
  71. data/lib/bson/version.rb +6 -14
  72. data/lib/bson.rb +22 -12
  73. data/spec/README.md +14 -0
  74. data/spec/bson/array_spec.rb +38 -62
  75. data/spec/bson/big_decimal_spec.rb +328 -0
  76. data/spec/bson/binary_spec.rb +199 -53
  77. data/spec/bson/binary_uuid_spec.rb +190 -0
  78. data/spec/bson/boolean_spec.rb +2 -1
  79. data/spec/bson/byte_buffer_read_spec.rb +198 -0
  80. data/spec/bson/byte_buffer_spec.rb +122 -381
  81. data/spec/bson/byte_buffer_write_spec.rb +855 -0
  82. data/spec/bson/code_spec.rb +6 -4
  83. data/spec/bson/code_with_scope_spec.rb +6 -4
  84. data/spec/bson/config_spec.rb +1 -35
  85. data/spec/bson/date_spec.rb +2 -1
  86. data/spec/bson/date_time_spec.rb +55 -1
  87. data/spec/bson/dbref_legacy_spec.rb +186 -0
  88. data/spec/bson/dbref_spec.rb +487 -0
  89. data/spec/bson/decimal128_spec.rb +1840 -0
  90. data/spec/bson/document_as_spec.rb +61 -0
  91. data/spec/bson/document_spec.rb +205 -32
  92. data/spec/bson/ext_json_parse_spec.rb +346 -0
  93. data/spec/bson/false_class_spec.rb +9 -1
  94. data/spec/bson/float_spec.rb +42 -1
  95. data/spec/bson/hash_as_spec.rb +58 -0
  96. data/spec/bson/hash_spec.rb +318 -66
  97. data/spec/bson/int32_spec.rb +248 -1
  98. data/spec/bson/int64_spec.rb +308 -1
  99. data/spec/bson/integer_spec.rb +61 -3
  100. data/spec/bson/json_spec.rb +2 -1
  101. data/spec/bson/max_key_spec.rb +6 -4
  102. data/spec/bson/min_key_spec.rb +6 -4
  103. data/spec/bson/nil_class_spec.rb +2 -1
  104. data/spec/bson/object_id_spec.rb +95 -5
  105. data/spec/bson/object_spec.rb +3 -2
  106. data/spec/bson/open_struct_spec.rb +87 -0
  107. data/spec/bson/raw_spec.rb +594 -0
  108. data/spec/bson/regexp_spec.rb +61 -8
  109. data/spec/bson/registry_spec.rb +3 -2
  110. data/spec/bson/string_spec.rb +26 -33
  111. data/spec/bson/symbol_raw_spec.rb +70 -0
  112. data/spec/bson/symbol_spec.rb +77 -20
  113. data/spec/bson/time_spec.rb +206 -2
  114. data/spec/bson/time_with_zone_spec.rb +69 -0
  115. data/spec/bson/timestamp_spec.rb +58 -2
  116. data/spec/bson/true_class_spec.rb +9 -1
  117. data/spec/bson/undefined_spec.rb +28 -1
  118. data/spec/bson/vector_spec.rb +33 -0
  119. data/spec/bson_spec.rb +2 -1
  120. data/spec/runners/binary_vector.rb +78 -0
  121. data/spec/runners/common_driver.rb +348 -0
  122. data/spec/runners/corpus.rb +191 -0
  123. data/spec/runners/corpus_legacy.rb +248 -0
  124. data/spec/shared/LICENSE +20 -0
  125. data/spec/shared/bin/get-mongodb-download-url +17 -0
  126. data/spec/shared/bin/s3-copy +45 -0
  127. data/spec/shared/bin/s3-upload +69 -0
  128. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  129. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  130. data/spec/shared/lib/mrss/constraints.rb +378 -0
  131. data/spec/shared/lib/mrss/docker_runner.rb +298 -0
  132. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  133. data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
  134. data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
  135. data/spec/shared/lib/mrss/release/candidate.rb +281 -0
  136. data/spec/shared/lib/mrss/release/product_data.rb +144 -0
  137. data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
  138. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  139. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  140. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  141. data/spec/shared/lib/mrss/utils.rb +37 -0
  142. data/spec/shared/lib/tasks/candidate.rake +64 -0
  143. data/spec/shared/share/Dockerfile.erb +251 -0
  144. data/spec/shared/share/haproxy-1.conf +16 -0
  145. data/spec/shared/share/haproxy-2.conf +17 -0
  146. data/spec/shared/shlib/config.sh +27 -0
  147. data/spec/shared/shlib/distro.sh +84 -0
  148. data/spec/shared/shlib/server.sh +423 -0
  149. data/spec/shared/shlib/set_env.sh +110 -0
  150. data/spec/spec_helper.rb +61 -1
  151. data/spec/spec_tests/binary_vector_spec.rb +82 -0
  152. data/spec/spec_tests/common_driver_spec.rb +84 -0
  153. data/spec/spec_tests/corpus_legacy_spec.rb +72 -0
  154. data/spec/spec_tests/corpus_spec.rb +134 -0
  155. data/spec/spec_tests/data/binary_vector/README.md +61 -0
  156. data/spec/spec_tests/data/binary_vector/float32.json +65 -0
  157. data/spec/spec_tests/data/binary_vector/int8.json +57 -0
  158. data/spec/spec_tests/data/binary_vector/packed_bit.json +83 -0
  159. data/spec/spec_tests/data/corpus/README.md +15 -0
  160. data/spec/spec_tests/data/corpus/array.json +49 -0
  161. data/spec/spec_tests/data/corpus/binary.json +153 -0
  162. data/spec/spec_tests/data/corpus/boolean.json +27 -0
  163. data/spec/spec_tests/data/corpus/code.json +67 -0
  164. data/spec/spec_tests/data/corpus/code_w_scope.json +78 -0
  165. data/spec/spec_tests/data/corpus/datetime.json +42 -0
  166. data/spec/spec_tests/data/corpus/dbpointer.json +56 -0
  167. data/spec/spec_tests/data/corpus/dbref.json +51 -0
  168. data/spec/spec_tests/data/corpus/decimal128-1.json +317 -0
  169. data/spec/spec_tests/data/corpus/decimal128-2.json +793 -0
  170. data/spec/spec_tests/data/corpus/decimal128-3.json +1771 -0
  171. data/spec/spec_tests/data/corpus/decimal128-4.json +165 -0
  172. data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
  173. data/spec/spec_tests/data/corpus/decimal128-6.json +131 -0
  174. data/spec/spec_tests/data/corpus/decimal128-7.json +327 -0
  175. data/spec/spec_tests/data/corpus/document.json +60 -0
  176. data/spec/spec_tests/data/corpus/double.json +87 -0
  177. data/spec/spec_tests/data/corpus/int32.json +43 -0
  178. data/spec/spec_tests/data/corpus/int64.json +43 -0
  179. data/spec/spec_tests/data/corpus/maxkey.json +12 -0
  180. data/spec/spec_tests/data/corpus/minkey.json +12 -0
  181. data/spec/spec_tests/data/corpus/multi-type-deprecated.json +15 -0
  182. data/spec/spec_tests/data/corpus/multi-type.json +11 -0
  183. data/spec/spec_tests/data/corpus/null.json +12 -0
  184. data/spec/spec_tests/data/corpus/oid.json +28 -0
  185. data/spec/spec_tests/data/corpus/regex.json +65 -0
  186. data/spec/spec_tests/data/corpus/string.json +72 -0
  187. data/spec/spec_tests/data/corpus/symbol.json +80 -0
  188. data/spec/spec_tests/data/corpus/timestamp.json +34 -0
  189. data/spec/spec_tests/data/corpus/top.json +262 -0
  190. data/spec/spec_tests/data/corpus/undefined.json +15 -0
  191. data/spec/spec_tests/data/corpus_legacy/array.json +49 -0
  192. data/spec/spec_tests/data/corpus_legacy/binary.json +69 -0
  193. data/spec/spec_tests/data/corpus_legacy/boolean.json +27 -0
  194. data/spec/spec_tests/data/corpus_legacy/code.json +67 -0
  195. data/spec/spec_tests/data/corpus_legacy/code_w_scope.json +78 -0
  196. data/spec/spec_tests/data/corpus_legacy/document.json +36 -0
  197. data/spec/spec_tests/data/corpus_legacy/double.json +69 -0
  198. data/spec/spec_tests/data/corpus_legacy/failures/datetime.json +31 -0
  199. data/spec/spec_tests/data/corpus_legacy/failures/dbpointer.json +42 -0
  200. data/spec/spec_tests/data/corpus_legacy/failures/int64.json +38 -0
  201. data/spec/spec_tests/data/corpus_legacy/failures/symbol.json +62 -0
  202. data/spec/spec_tests/data/corpus_legacy/int32.json +38 -0
  203. data/spec/spec_tests/data/corpus_legacy/maxkey.json +12 -0
  204. data/spec/spec_tests/data/corpus_legacy/minkey.json +12 -0
  205. data/spec/spec_tests/data/corpus_legacy/null.json +12 -0
  206. data/spec/spec_tests/data/corpus_legacy/oid.json +28 -0
  207. data/spec/spec_tests/data/corpus_legacy/regex.json +37 -0
  208. data/spec/spec_tests/data/corpus_legacy/string.json +67 -0
  209. data/spec/spec_tests/data/corpus_legacy/timestamp.json +18 -0
  210. data/spec/spec_tests/data/corpus_legacy/top.json +62 -0
  211. data/spec/spec_tests/data/corpus_legacy/undefined.json +13 -0
  212. data/spec/spec_tests/data/decimal128/decimal128-1.json +363 -0
  213. data/spec/spec_tests/data/decimal128/decimal128-2.json +793 -0
  214. data/spec/spec_tests/data/decimal128/decimal128-3.json +1771 -0
  215. data/spec/spec_tests/data/decimal128/decimal128-4.json +165 -0
  216. data/spec/spec_tests/data/decimal128/decimal128-5.json +402 -0
  217. data/spec/spec_tests/data/decimal128/decimal128-6.json +131 -0
  218. data/spec/spec_tests/data/decimal128/decimal128-7.json +327 -0
  219. data/spec/support/shared_examples.rb +32 -11
  220. data/spec/support/spec_config.rb +17 -0
  221. data/spec/support/utils.rb +58 -0
  222. metadata +284 -45
  223. checksums.yaml.gz.sig +0 -3
  224. data/ext/bson/native.c +0 -722
  225. data.tar.gz.sig +0 -0
  226. 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