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
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
1
+ # rubocop:todo all
2
2
 
3
- # Copyright (C) 2009-2014 MongoDB Inc.
3
+ # Copyright (C) 2009-2020 MongoDB Inc.
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@ describe String do
51
51
  it "raises an exception" do
52
52
  expect {
53
53
  "test".to_bson_object_id
54
- }.to raise_error(BSON::ObjectId::Invalid)
54
+ }.to raise_error(BSON::Error::InvalidObjectId)
55
55
  end
56
56
  end
57
57
  end
@@ -90,44 +90,37 @@ describe String do
90
90
 
91
91
  describe "#to_bson_key" do
92
92
 
93
- context "when validating keys" do
94
-
95
- context "when validating globally" do
96
-
97
- before do
98
- BSON::Config.validating_keys = true
99
- end
100
-
101
- after do
102
- BSON::Config.validating_keys = false
103
- end
93
+ let(:string) do
94
+ "$testing.testing"
95
+ end
104
96
 
105
- let(:validated) do
106
- string.to_bson_key
107
- end
97
+ it "allows dots/dollars keys" do
98
+ expect(string.to_bson_key).to eq(string)
99
+ end
100
+ end
108
101
 
109
- it_behaves_like "a validated BSON key"
102
+ describe '#to_bson' do
103
+ context 'when string is not valid utf-8' do
104
+ let(:string) do
105
+ "\xfe\x00\xff".force_encoding('BINARY')
110
106
  end
111
107
 
112
- context "when validating locally" do
113
-
114
- let(:validated) do
115
- string.to_bson_key(true)
116
- end
108
+ let(:expected_message) do
109
+ /from ASCII-8BIT to UTF-8/
110
+ end
117
111
 
118
- it_behaves_like "a validated BSON key"
112
+ it 'raises EncodingError' do
113
+ expect do
114
+ string.to_bson
115
+ end.to raise_error(EncodingError, expected_message)
119
116
  end
120
117
  end
118
+ end
121
119
 
122
- context "when allowing invalid keys" do
123
-
124
- let(:string) do
125
- "$testing.testing"
126
- end
120
+ describe '#as_extended_json' do
121
+ let(:object) { 'Hello world!' }
127
122
 
128
- it "allows invalid keys" do
129
- expect(string.to_bson_key).to eq(string)
130
- end
131
- end
123
+ it_behaves_like '#as_extended_json returns self'
124
+ it_behaves_like 'an Extended JSON serializable object'
132
125
  end
133
126
  end
@@ -0,0 +1,70 @@
1
+ # rubocop:todo all
2
+ # Copyright (C) 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::Symbol::Raw do
19
+ describe '#==' do
20
+ let(:one) { described_class.new('foo') }
21
+ let(:two) { described_class.new('foo') }
22
+ let(:three) { described_class.new('bar') }
23
+
24
+ it 'compares equal' do
25
+ one.should == two
26
+ end
27
+
28
+ it 'compares not equal' do
29
+ one.should_not == three
30
+ end
31
+ end
32
+
33
+ describe '#eql?' do
34
+ let(:one) { described_class.new('foo') }
35
+ let(:two) { described_class.new('foo') }
36
+ let(:three) { described_class.new('bar') }
37
+
38
+ it 'compares equal' do
39
+ one.should be_eql(two)
40
+ end
41
+
42
+ it 'compares not equal' do
43
+ one.should_not be_eql(three)
44
+ end
45
+ end
46
+
47
+ describe '#as_json' do
48
+ let(:object) do
49
+ described_class.new(:foobar)
50
+ end
51
+
52
+ it 'returns a string' do
53
+ expect(object.as_json).to eq('foobar')
54
+ end
55
+
56
+ it_behaves_like 'a JSON serializable object'
57
+ end
58
+
59
+ describe '#as_extended_json' do
60
+ let(:object) do
61
+ described_class.new(:foobar)
62
+ end
63
+
64
+ it 'returns the binary data plus type' do
65
+ expect(object.as_extended_json).to eq({ '$symbol' => 'foobar' })
66
+ end
67
+
68
+ it_behaves_like 'an Extended JSON serializable object'
69
+ end
70
+ end
@@ -1,4 +1,5 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # rubocop:todo all
2
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
4
5
  # you may not use this file except in compliance with the License.
@@ -32,12 +33,72 @@ describe Symbol do
32
33
  it_behaves_like "a bson element"
33
34
  it_behaves_like "a serializable bson element"
34
35
  it_behaves_like "a deserializable bson element"
36
+
37
+ context 'canonical deserialization' do
38
+ let(:bson) do
39
+ BSON::ByteBuffer.new(BSON::Symbol::Raw.new(obj).to_bson.to_s)
40
+ end
41
+
42
+ let(:deserialized) do
43
+ described_class.from_bson(bson, mode: :bson)
44
+ end
45
+
46
+ it 'deserializes to BSON::Symbol::Raw' do
47
+ deserialized.class.should be BSON::Symbol::Raw
48
+ end
49
+
50
+ it 'has the correct value' do
51
+ deserialized.to_sym.should be obj
52
+ end
53
+ end
54
+
55
+ context 'when changing bson_type' do
56
+ def perform_test(bson_type_to_use)
57
+ Symbol.class_eval do
58
+ alias_method :bson_type_orig, :bson_type
59
+ define_method(:bson_type) do
60
+ bson_type_to_use
61
+ end
62
+ end
63
+
64
+ begin
65
+ yield
66
+ ensure
67
+ Symbol.class_eval do
68
+ alias_method :bson_type, :bson_type_orig
69
+ remove_method :bson_type_orig
70
+ end
71
+ end
72
+ end
73
+
74
+ let(:value) { :foo }
75
+
76
+ let(:serialized) do
77
+ value.to_bson.to_s
78
+ end
79
+
80
+ context 'when bson_type is set to symbol' do
81
+ it 'serializes to BSON string' do
82
+ perform_test(BSON::Symbol::BSON_TYPE) do
83
+ serialized
84
+ end.should == "\x04\x00\x00\x00foo\x00".force_encoding('binary')
85
+ end
86
+ end
87
+
88
+ context 'when bson_type is set to string' do
89
+ it 'serializes to BSON string' do
90
+ perform_test(BSON::String::BSON_TYPE) do
91
+ serialized
92
+ end.should == "\x04\x00\x00\x00foo\x00".force_encoding('binary')
93
+ end
94
+ end
95
+ end
35
96
  end
36
97
 
37
98
  describe "#to_bson_key" do
38
99
 
39
100
  let(:symbol) { :test }
40
- let(:encoded) { symbol.to_s }
101
+ let(:encoded) { symbol }
41
102
 
42
103
  it "returns the encoded string" do
43
104
  expect(symbol.to_bson_key).to eq(encoded)
@@ -46,28 +107,24 @@ describe Symbol do
46
107
 
47
108
  describe "#to_bson_key" do
48
109
 
49
- context "when validating keys" do
50
-
51
- let(:symbol) do
52
- :'$testing.testing'
53
- end
54
-
55
- it "raises an exception" do
56
- expect {
57
- symbol.to_bson_key(true)
58
- }.to raise_error(BSON::String::IllegalKey)
59
- end
110
+ let(:symbol) do
111
+ :'$testing.testing'
60
112
  end
61
113
 
62
- context "when not validating keys" do
114
+ it "returns the key" do
115
+ expect(symbol.to_bson_key).to eq(symbol)
116
+ end
117
+ end
63
118
 
64
- let(:symbol) do
65
- :'$testing.testing'
66
- end
119
+ describe '#as_extended_json' do
120
+ let(:object) do
121
+ :foobar
122
+ end
67
123
 
68
- it "allows invalid keys" do
69
- expect(symbol.to_bson_key).to eq(symbol.to_s)
70
- end
124
+ it 'returns the binary data plus type' do
125
+ expect(object.as_extended_json).to eq({ '$symbol' => 'foobar' })
71
126
  end
127
+
128
+ it_behaves_like 'an Extended JSON serializable object'
72
129
  end
73
130
  end
@@ -1,4 +1,5 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # rubocop:todo all
2
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
4
5
  # you may not use this file except in compliance with the License.
@@ -43,7 +44,7 @@ describe Time do
43
44
  end
44
45
  end
45
46
 
46
- context "when the time is pre epoch" do
47
+ context "when the time precedes epoch" do
47
48
 
48
49
  let(:obj) { Time.utc(1969, 1, 1, 0, 0, 0) }
49
50
  let(:bson) { [ (obj.to_f * 1000).to_i ].pack(BSON::Int64::PACK) }
@@ -51,5 +52,208 @@ describe Time do
51
52
  it_behaves_like "a serializable bson element"
52
53
  it_behaves_like "a deserializable bson element"
53
54
  end
55
+
56
+ context 'when value has sub-millisecond precision' do
57
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999) }
58
+
59
+ let(:expected_round_tripped_obj) do
60
+ Time.utc(2012, 1, 1, 0, 0, 0, 999_000)
61
+ end
62
+
63
+ let(:round_tripped_obj) do
64
+ Time.from_bson(obj.to_bson)
65
+ end
66
+
67
+ it 'truncates to milliseconds when round-tripping' do
68
+ round_tripped_obj.should == expected_round_tripped_obj
69
+ end
70
+ end
71
+ end
72
+
73
+ describe '#as_extended_json' do
74
+
75
+ context 'canonical mode' do
76
+ context 'when value has sub-millisecond precision' do
77
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999) }
78
+
79
+ let(:expected_serialization) do
80
+ {'$date' => {'$numberLong' => '1325376000999'}}
81
+ end
82
+
83
+ let(:serialization) do
84
+ obj.as_extended_json
85
+ end
86
+
87
+ shared_examples_for 'truncates to milliseconds when serializing' do
88
+ it 'truncates to milliseconds when serializing' do
89
+ serialization.should == expected_serialization
90
+ end
91
+ end
92
+
93
+ it_behaves_like 'truncates to milliseconds when serializing'
94
+
95
+ context 'when value has sub-microsecond precision' do
96
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999_999/1000r) }
97
+
98
+ it_behaves_like 'truncates to milliseconds when serializing'
99
+ end
100
+
101
+ context "when the time precedes epoch" do
102
+ let(:obj) { Time.utc(1960, 1, 1, 0, 0, 0, 999_999) }
103
+
104
+ let(:expected_serialization) do
105
+ {'$date' => {'$numberLong' => '-315619199001'}}
106
+ end
107
+
108
+ it_behaves_like 'truncates to milliseconds when serializing'
109
+ end
110
+ end
111
+ end
112
+
113
+ context 'relaxed mode' do
114
+ context 'when value has sub-millisecond precision' do
115
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999) }
116
+
117
+ let(:expected_serialization) do
118
+ {'$date' => '2012-01-01T00:00:00.999Z'}
119
+ end
120
+
121
+ let(:serialization) do
122
+ obj.as_extended_json(mode: :relaxed)
123
+ end
124
+
125
+ shared_examples_for 'truncates to milliseconds when serializing' do
126
+ it 'truncates to milliseconds when serializing' do
127
+ serialization.should == expected_serialization
128
+ end
129
+ end
130
+
131
+ it_behaves_like 'truncates to milliseconds when serializing'
132
+
133
+ context 'when value has sub-microsecond precision' do
134
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999_999/1000r) }
135
+
136
+ it_behaves_like 'truncates to milliseconds when serializing'
137
+ end
138
+
139
+ context "when the time precedes epoch" do
140
+ let(:obj) { Time.utc(1960, 1, 1, 0, 0, 0, 999_999) }
141
+
142
+ let(:expected_serialization) do
143
+ {'$date' => {'$numberLong' => '-315619199001'}}
144
+ end
145
+
146
+ it_behaves_like 'truncates to milliseconds when serializing'
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ describe '#to_extended_json' do
153
+
154
+ context 'canonical mode' do
155
+ context 'when value has sub-millisecond precision' do
156
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999) }
157
+
158
+ let(:expected_serialization) do
159
+ %q`{"$date":{"$numberLong":"1325376000999"}}`
160
+ end
161
+
162
+ let(:serialization) do
163
+ obj.to_extended_json
164
+ end
165
+
166
+ shared_examples_for 'truncates to milliseconds when serializing' do
167
+ it 'truncates to milliseconds when serializing' do
168
+ serialization.should == expected_serialization
169
+ end
170
+ end
171
+
172
+ it_behaves_like 'truncates to milliseconds when serializing'
173
+
174
+ context 'when value has sub-microsecond precision' do
175
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999_999/1000r) }
176
+
177
+ it_behaves_like 'truncates to milliseconds when serializing'
178
+ end
179
+
180
+ context "when the time precedes epoch" do
181
+ let(:obj) { Time.utc(1960, 1, 1, 0, 0, 0, 999_999) }
182
+
183
+ let(:expected_serialization) do
184
+ %q`{"$date":{"$numberLong":"-315619199001"}}`
185
+ end
186
+
187
+ it_behaves_like 'truncates to milliseconds when serializing'
188
+ end
189
+ end
190
+ end
191
+
192
+ context 'relaxed mode' do
193
+ context 'when value has sub-millisecond precision' do
194
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999) }
195
+
196
+ let(:expected_serialization) do
197
+ %q`{"$date":"2012-01-01T00:00:00.999Z"}`
198
+ end
199
+
200
+ let(:serialization) do
201
+ obj.to_extended_json(mode: :relaxed)
202
+ end
203
+
204
+ shared_examples_for 'truncates to milliseconds when serializing' do
205
+ it 'truncates to milliseconds when serializing' do
206
+ serialization.should == expected_serialization
207
+ end
208
+ end
209
+
210
+ it_behaves_like 'truncates to milliseconds when serializing'
211
+
212
+ context 'when value has sub-microsecond precision' do
213
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999_999/1000r) }
214
+
215
+ it_behaves_like 'truncates to milliseconds when serializing'
216
+ end
217
+ end
218
+ end
219
+ end
220
+
221
+ describe '#to_json' do
222
+
223
+ context 'when value has sub-millisecond precision' do
224
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999) }
225
+
226
+ let(:expected_serialization) do
227
+ %q`"2012-01-01 00:00:00 UTC"`
228
+ end
229
+
230
+ let(:serialization) do
231
+ obj.to_json
232
+ end
233
+
234
+ shared_examples_for 'truncates to milliseconds when serializing' do
235
+ it 'truncates to milliseconds when serializing' do
236
+ serialization.should == expected_serialization
237
+ end
238
+ end
239
+
240
+ it_behaves_like 'truncates to milliseconds when serializing'
241
+
242
+ context 'when value has sub-microsecond precision' do
243
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0, 999_999_999/1000r) }
244
+
245
+ it_behaves_like 'truncates to milliseconds when serializing'
246
+ end
247
+
248
+ context "when the time precedes epoch" do
249
+ let(:obj) { Time.utc(1960, 1, 1, 0, 0, 0, 999_999) }
250
+
251
+ let(:expected_serialization) do
252
+ %q`"1960-01-01 00:00:00 UTC"`
253
+ end
254
+
255
+ it_behaves_like 'truncates to milliseconds when serializing'
256
+ end
257
+ end
54
258
  end
55
259
  end
@@ -0,0 +1,69 @@
1
+ # rubocop:todo all
2
+ # Copyright (C) 2018-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
+ context 'when ActiveSupport support is enabled' do
19
+ before do
20
+ unless SpecConfig.instance.active_support?
21
+ skip "ActiveSupport support is not enabled"
22
+ end
23
+ end
24
+
25
+ describe 'ActiveSupport::TimeWithZone' do
26
+ let(:cls) { ActiveSupport::TimeWithZone }
27
+
28
+ it "shares BSON type with Time" do
29
+ # ActiveSupport::TimeWithZone#new has no 0-argument version
30
+ obj = Time.now.in_time_zone("UTC")
31
+ expect(obj.bson_type).to eq(Time::BSON_TYPE)
32
+ end
33
+
34
+ shared_examples_for 'deserializes as expected' do
35
+ it 'deserializes to UTC' do
36
+ # Time zone information is lost during serialization - the time
37
+ # is always serialized in UTC.
38
+ rt_obj = Time.from_bson(obj.to_bson)
39
+ expect(rt_obj.zone).to eq('UTC')
40
+ end
41
+
42
+ it 'deserializes to an equal object' do
43
+ rt_obj = Time.from_bson(obj.to_bson)
44
+ expect(rt_obj).to eq(obj)
45
+ end
46
+ end
47
+
48
+ describe "#to_bson" do
49
+
50
+ context "when the TimeWithZone is not in UTC" do
51
+
52
+ let(:obj) { Time.utc(2012, 12, 12, 0, 0, 0).in_time_zone("Pacific Time (US & Canada)") }
53
+ let(:bson) { [ (obj.utc.to_f * 1000).to_i ].pack(BSON::Int64::PACK) }
54
+
55
+ it_behaves_like "a serializable bson element"
56
+ it_behaves_like 'deserializes as expected'
57
+ end
58
+
59
+ context "when the TimeWithZone is in UTC" do
60
+
61
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0).in_time_zone("UTC") }
62
+ let(:bson) { [ (obj.utc.to_f * 1000).to_i ].pack(BSON::Int64::PACK) }
63
+
64
+ it_behaves_like "a serializable bson element"
65
+ it_behaves_like 'deserializes as expected'
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,4 +1,5 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # rubocop:todo all
2
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
4
5
  # you may not use this file except in compliance with the License.
@@ -48,6 +49,61 @@ describe BSON::Timestamp do
48
49
  end
49
50
  end
50
51
 
52
+ describe "#<=>" do
53
+
54
+ let(:timestamp) do
55
+ described_class.new(1, 10)
56
+ end
57
+
58
+ context "when the objects are equal" do
59
+
60
+ let(:other) { described_class.new(1, 10) }
61
+
62
+ it "returns 0" do
63
+ expect(timestamp).to eq(other)
64
+ expect(timestamp < other).to be(false)
65
+ expect(timestamp > other).to be(false)
66
+ expect(timestamp >= other).to be(true)
67
+ expect(timestamp <= other).to be(true)
68
+ end
69
+ end
70
+
71
+ context "when the first object is less than the second" do
72
+
73
+ let(:other) { described_class.new(1, 15) }
74
+
75
+ it "returns -1" do
76
+ expect(timestamp <=> other).to be(-1)
77
+ expect(timestamp < other).to be(true)
78
+ expect(timestamp > other).to be(false)
79
+ expect(timestamp >= other).to be(false)
80
+ expect(timestamp <= other).to be(true)
81
+ end
82
+ end
83
+
84
+ context "when the first object is greater than the second" do
85
+
86
+ let(:other) { described_class.new(1, 5) }
87
+
88
+ it "returns 1" do
89
+ expect(timestamp <=> other).to be(1)
90
+ expect(timestamp < other).to be(false)
91
+ expect(timestamp > other).to be(true)
92
+ expect(timestamp >= other).to be(true)
93
+ expect(timestamp <= other).to be(false)
94
+ end
95
+ end
96
+
97
+ context "when the other object is not a timestamp" do
98
+
99
+ it "raises an ArgumentError" do
100
+ expect {
101
+ timestamp < 1
102
+ }.to raise_exception(ArgumentError)
103
+ end
104
+ end
105
+ end
106
+
51
107
  describe "#as_json" do
52
108
 
53
109
  let(:object) do
@@ -55,7 +111,7 @@ describe BSON::Timestamp do
55
111
  end
56
112
 
57
113
  it "returns the binary data plus type" do
58
- expect(object.as_json).to eq({ "t" => 10, "i" => 50 })
114
+ expect(object.as_json).to eq({"$timestamp" => { "t" => 10, "i" => 50 } })
59
115
  end
60
116
 
61
117
  it_behaves_like "a JSON serializable object"
@@ -1,4 +1,5 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # rubocop:todo all
2
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
4
5
  # you may not use this file except in compliance with the License.
@@ -25,4 +26,11 @@ describe TrueClass do
25
26
  it_behaves_like "a bson element"
26
27
  it_behaves_like "a serializable bson element"
27
28
  end
29
+
30
+ describe '#as_extended_json' do
31
+ let(:object) { true }
32
+
33
+ it_behaves_like '#as_extended_json returns self'
34
+ it_behaves_like 'an Extended JSON serializable object'
35
+ end
28
36
  end