bson 4.2.2 → 4.12.1

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 (169) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +25 -7
  5. data/Rakefile +16 -9
  6. data/ext/bson/{native-endian.h → bson-endian.h} +5 -99
  7. data/ext/bson/bson-native.h +125 -0
  8. data/ext/bson/bytebuf.c +133 -0
  9. data/ext/bson/endian.c +117 -0
  10. data/ext/bson/init.c +355 -0
  11. data/ext/bson/libbson-utf8.c +230 -0
  12. data/ext/bson/read.c +411 -0
  13. data/ext/bson/util.c +95 -0
  14. data/ext/bson/write.c +680 -0
  15. data/lib/bson.rb +6 -3
  16. data/lib/bson/active_support.rb +17 -0
  17. data/lib/bson/array.rb +57 -17
  18. data/lib/bson/binary.rb +185 -13
  19. data/lib/bson/boolean.rb +12 -3
  20. data/lib/bson/code.rb +16 -2
  21. data/lib/bson/code_with_scope.rb +32 -5
  22. data/lib/bson/config.rb +1 -1
  23. data/lib/bson/date.rb +12 -2
  24. data/lib/bson/date_time.rb +2 -2
  25. data/lib/bson/db_pointer.rb +110 -0
  26. data/lib/bson/decimal128.rb +17 -3
  27. data/lib/bson/decimal128/builder.rb +1 -1
  28. data/lib/bson/document.rb +152 -5
  29. data/lib/bson/environment.rb +2 -1
  30. data/lib/bson/error.rb +27 -0
  31. data/lib/bson/ext_json.rb +383 -0
  32. data/lib/bson/false_class.rb +1 -1
  33. data/lib/bson/float.rb +48 -2
  34. data/lib/bson/hash.rb +68 -17
  35. data/lib/bson/int32.rb +52 -13
  36. data/lib/bson/int64.rb +59 -15
  37. data/lib/bson/integer.rb +36 -2
  38. data/lib/bson/json.rb +1 -1
  39. data/lib/bson/max_key.rb +13 -1
  40. data/lib/bson/min_key.rb +13 -1
  41. data/lib/bson/nil_class.rb +4 -2
  42. data/lib/bson/object.rb +28 -1
  43. data/lib/bson/object_id.rb +16 -2
  44. data/lib/bson/open_struct.rb +1 -1
  45. data/lib/bson/regexp.rb +27 -4
  46. data/lib/bson/registry.rb +3 -3
  47. data/lib/bson/specialized.rb +4 -2
  48. data/lib/bson/string.rb +5 -3
  49. data/lib/bson/symbol.rb +99 -7
  50. data/lib/bson/time.rb +63 -4
  51. data/lib/bson/time_with_zone.rb +54 -0
  52. data/lib/bson/timestamp.rb +44 -6
  53. data/lib/bson/true_class.rb +1 -1
  54. data/lib/bson/undefined.rb +12 -1
  55. data/lib/bson/version.rb +2 -2
  56. data/spec/bson/array_spec.rb +18 -1
  57. data/spec/bson/binary_spec.rb +100 -3
  58. data/spec/bson/binary_uuid_spec.rb +189 -0
  59. data/spec/bson/boolean_spec.rb +1 -1
  60. data/spec/bson/byte_buffer_read_spec.rb +197 -0
  61. data/spec/bson/byte_buffer_spec.rb +121 -381
  62. data/spec/bson/byte_buffer_write_spec.rb +854 -0
  63. data/spec/bson/code_spec.rb +1 -1
  64. data/spec/bson/code_with_scope_spec.rb +1 -1
  65. data/spec/bson/date_spec.rb +1 -1
  66. data/spec/bson/date_time_spec.rb +54 -1
  67. data/spec/bson/decimal128_spec.rb +35 -35
  68. data/spec/bson/document_as_spec.rb +46 -0
  69. data/spec/bson/document_spec.rb +197 -30
  70. data/spec/bson/ext_json_parse_spec.rb +308 -0
  71. data/spec/bson/false_class_spec.rb +1 -1
  72. data/spec/bson/float_spec.rb +37 -1
  73. data/spec/bson/hash_as_spec.rb +57 -0
  74. data/spec/bson/hash_spec.rb +209 -1
  75. data/spec/bson/int32_spec.rb +180 -6
  76. data/spec/bson/int64_spec.rb +199 -6
  77. data/spec/bson/integer_spec.rb +29 -3
  78. data/spec/bson/json_spec.rb +1 -1
  79. data/spec/bson/max_key_spec.rb +1 -1
  80. data/spec/bson/min_key_spec.rb +1 -1
  81. data/spec/bson/nil_class_spec.rb +1 -1
  82. data/spec/bson/object_id_spec.rb +1 -1
  83. data/spec/bson/object_spec.rb +1 -1
  84. data/spec/bson/open_struct_spec.rb +1 -1
  85. data/spec/bson/raw_spec.rb +34 -2
  86. data/spec/bson/regexp_spec.rb +1 -1
  87. data/spec/bson/registry_spec.rb +1 -1
  88. data/spec/bson/string_spec.rb +19 -1
  89. data/spec/bson/symbol_raw_spec.rb +45 -0
  90. data/spec/bson/symbol_spec.rb +63 -3
  91. data/spec/bson/time_spec.rb +205 -2
  92. data/spec/bson/time_with_zone_spec.rb +68 -0
  93. data/spec/bson/timestamp_spec.rb +56 -1
  94. data/spec/bson/true_class_spec.rb +1 -1
  95. data/spec/bson/undefined_spec.rb +1 -1
  96. data/spec/bson_spec.rb +1 -1
  97. data/spec/{support → runners}/common_driver.rb +1 -1
  98. data/spec/runners/corpus.rb +185 -0
  99. data/spec/{support/corpus.rb → runners/corpus_legacy.rb} +41 -59
  100. data/spec/spec_helper.rb +40 -3
  101. data/spec/{bson/driver_bson_spec.rb → spec_tests/common_driver_spec.rb} +1 -0
  102. data/spec/{bson/corpus_spec.rb → spec_tests/corpus_legacy_spec.rb} +10 -7
  103. data/spec/spec_tests/corpus_spec.rb +124 -0
  104. data/spec/spec_tests/data/corpus/README.md +15 -0
  105. data/spec/spec_tests/data/corpus/array.json +49 -0
  106. data/spec/spec_tests/data/corpus/binary.json +113 -0
  107. data/spec/spec_tests/data/corpus/boolean.json +27 -0
  108. data/spec/spec_tests/data/corpus/code.json +67 -0
  109. data/spec/spec_tests/data/corpus/code_w_scope.json +78 -0
  110. data/spec/spec_tests/data/corpus/datetime.json +42 -0
  111. data/spec/spec_tests/data/corpus/dbpointer.json +56 -0
  112. data/spec/spec_tests/data/corpus/dbref.json +31 -0
  113. data/spec/spec_tests/data/corpus/decimal128-1.json +317 -0
  114. data/spec/spec_tests/data/corpus/decimal128-2.json +793 -0
  115. data/spec/spec_tests/data/corpus/decimal128-3.json +1771 -0
  116. data/spec/spec_tests/data/corpus/decimal128-4.json +117 -0
  117. data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
  118. data/spec/spec_tests/data/corpus/decimal128-6.json +119 -0
  119. data/spec/spec_tests/data/corpus/decimal128-7.json +323 -0
  120. data/spec/spec_tests/data/corpus/document.json +36 -0
  121. data/spec/spec_tests/data/corpus/double.json +87 -0
  122. data/spec/spec_tests/data/corpus/int32.json +43 -0
  123. data/spec/spec_tests/data/corpus/int64.json +43 -0
  124. data/spec/spec_tests/data/corpus/maxkey.json +12 -0
  125. data/spec/spec_tests/data/corpus/minkey.json +12 -0
  126. data/spec/spec_tests/data/corpus/multi-type-deprecated.json +15 -0
  127. data/spec/spec_tests/data/corpus/multi-type.json +11 -0
  128. data/spec/spec_tests/data/corpus/null.json +12 -0
  129. data/spec/spec_tests/data/corpus/oid.json +28 -0
  130. data/spec/spec_tests/data/corpus/regex.json +65 -0
  131. data/spec/spec_tests/data/corpus/string.json +72 -0
  132. data/spec/spec_tests/data/corpus/symbol.json +80 -0
  133. data/spec/spec_tests/data/corpus/timestamp.json +34 -0
  134. data/spec/spec_tests/data/corpus/top.json +236 -0
  135. data/spec/spec_tests/data/corpus/undefined.json +15 -0
  136. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/array.json +8 -2
  137. data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/binary.json +0 -0
  138. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/boolean.json +0 -0
  139. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code.json +1 -1
  140. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code_w_scope.json +1 -1
  141. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/document.json +1 -1
  142. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/double.json +1 -1
  143. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/datetime.json +0 -0
  144. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/dbpointer.json +0 -0
  145. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/int64.json +0 -0
  146. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/symbol.json +0 -0
  147. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/int32.json +1 -1
  148. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/maxkey.json +1 -1
  149. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/minkey.json +1 -1
  150. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/null.json +1 -1
  151. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/oid.json +0 -0
  152. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/regex.json +1 -1
  153. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/string.json +0 -0
  154. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/timestamp.json +1 -1
  155. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/top.json +0 -0
  156. data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/undefined.json +0 -0
  157. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-1.json +0 -0
  158. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-2.json +0 -0
  159. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-3.json +0 -0
  160. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-4.json +0 -0
  161. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-5.json +0 -0
  162. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-6.json +0 -0
  163. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-7.json +0 -0
  164. data/spec/support/shared_examples.rb +3 -5
  165. data/spec/support/spec_config.rb +16 -0
  166. data/spec/support/utils.rb +10 -0
  167. metadata +227 -124
  168. metadata.gz.sig +0 -0
  169. data/ext/bson/bson_native.c +0 -762
@@ -0,0 +1,68 @@
1
+ # Copyright (C) 2018-2020 MongoDB Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require "spec_helper"
16
+
17
+ context 'when ActiveSupport support is enabled' do
18
+ before do
19
+ unless SpecConfig.instance.active_support?
20
+ skip "ActiveSupport support is not enabled"
21
+ end
22
+ end
23
+
24
+ describe 'ActiveSupport::TimeWithZone' do
25
+ let(:cls) { ActiveSupport::TimeWithZone }
26
+
27
+ it "shares BSON type with Time" do
28
+ # ActiveSupport::TimeWithZone#new has no 0-argument version
29
+ obj = Time.now.in_time_zone("UTC")
30
+ expect(obj.bson_type).to eq(Time::BSON_TYPE)
31
+ end
32
+
33
+ shared_examples_for 'deserializes as expected' do
34
+ it 'deserializes to UTC' do
35
+ # Time zone information is lost during serialization - the time
36
+ # is always serialized in UTC.
37
+ rt_obj = Time.from_bson(obj.to_bson)
38
+ expect(rt_obj.zone).to eq('UTC')
39
+ end
40
+
41
+ it 'deserializes to an equal object' do
42
+ rt_obj = Time.from_bson(obj.to_bson)
43
+ expect(rt_obj).to eq(obj)
44
+ end
45
+ end
46
+
47
+ describe "#to_bson" do
48
+
49
+ context "when the TimeWithZone is not in UTC" do
50
+
51
+ let(:obj) { Time.utc(2012, 12, 12, 0, 0, 0).in_time_zone("Pacific Time (US & Canada)") }
52
+ let(:bson) { [ (obj.utc.to_f * 1000).to_i ].pack(BSON::Int64::PACK) }
53
+
54
+ it_behaves_like "a serializable bson element"
55
+ it_behaves_like 'deserializes as expected'
56
+ end
57
+
58
+ context "when the TimeWithZone is in UTC" do
59
+
60
+ let(:obj) { Time.utc(2012, 1, 1, 0, 0, 0).in_time_zone("UTC") }
61
+ let(:bson) { [ (obj.utc.to_f * 1000).to_i ].pack(BSON::Int64::PACK) }
62
+
63
+ it_behaves_like "a serializable bson element"
64
+ it_behaves_like 'deserializes as expected'
65
+ end
66
+ end
67
+ end
68
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -48,6 +48,61 @@ describe BSON::Timestamp do
48
48
  end
49
49
  end
50
50
 
51
+ describe "#<=>" do
52
+
53
+ let(:timestamp) do
54
+ described_class.new(1, 10)
55
+ end
56
+
57
+ context "when the objects are equal" do
58
+
59
+ let(:other) { described_class.new(1, 10) }
60
+
61
+ it "returns 0" do
62
+ expect(timestamp).to eq(other)
63
+ expect(timestamp < other).to be(false)
64
+ expect(timestamp > other).to be(false)
65
+ expect(timestamp >= other).to be(true)
66
+ expect(timestamp <= other).to be(true)
67
+ end
68
+ end
69
+
70
+ context "when the first object is less than the second" do
71
+
72
+ let(:other) { described_class.new(1, 15) }
73
+
74
+ it "returns -1" do
75
+ expect(timestamp <=> other).to be(-1)
76
+ expect(timestamp < other).to be(true)
77
+ expect(timestamp > other).to be(false)
78
+ expect(timestamp >= other).to be(false)
79
+ expect(timestamp <= other).to be(true)
80
+ end
81
+ end
82
+
83
+ context "when the first object is greater than the second" do
84
+
85
+ let(:other) { described_class.new(1, 5) }
86
+
87
+ it "returns 1" do
88
+ expect(timestamp <=> other).to be(1)
89
+ expect(timestamp < other).to be(false)
90
+ expect(timestamp > other).to be(true)
91
+ expect(timestamp >= other).to be(true)
92
+ expect(timestamp <= other).to be(false)
93
+ end
94
+ end
95
+
96
+ context "when the other object is not a timestamp" do
97
+
98
+ it "raises an ArgumentError" do
99
+ expect {
100
+ timestamp < 1
101
+ }.to raise_exception(ArgumentError)
102
+ end
103
+ end
104
+ end
105
+
51
106
  describe "#as_json" do
52
107
 
53
108
  let(:object) do
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
data/spec/bson_spec.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2016 MongoDB, Inc.
1
+ # Copyright (C) 2016-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -0,0 +1,185 @@
1
+ # Copyright (C) 2016-2020 MongoDB Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'json'
16
+ require 'forwardable'
17
+
18
+ module BSON
19
+ module Corpus
20
+
21
+ # Represents a test from the driver BSON Corpus.
22
+ #
23
+ # @since 4.2.0
24
+ class Spec
25
+
26
+ # The spec description.
27
+ #
28
+ # @return [ String ] The spec description.
29
+ #
30
+ # @since 4.2.0
31
+ attr_reader :description
32
+
33
+ # The document key of the object to test.
34
+ #
35
+ # @return [ String ] The document key.
36
+ #
37
+ # @since 4.2.0
38
+ attr_reader :test_key
39
+
40
+ # Instantiate the new spec.
41
+ #
42
+ # @example Create the spec.
43
+ # Spec.new(file)
44
+ #
45
+ # @param [ String ] file The name of the json file.
46
+ #
47
+ # @since 4.2.0
48
+ def initialize(file)
49
+ @spec = ::JSON.parse(File.read(file).force_encoding('utf-8'))
50
+ end
51
+
52
+ def description
53
+ @spec['description']
54
+ end
55
+
56
+ def test_key
57
+ @spec['test_key']
58
+ end
59
+
60
+ def valid_tests
61
+ @valid_tests ||=
62
+ @spec['valid']&.map do |test_spec|
63
+ ValidTest.new(self, test_spec)
64
+ end
65
+ end
66
+
67
+ def decode_error_tests
68
+ @decode_error_tests ||=
69
+ @spec['decodeErrors']&.map do |test_spec|
70
+ DecodeErrorTest.new(self, test_spec)
71
+ end
72
+ end
73
+
74
+ def parse_error_tests
75
+ @parse_error_tests ||=
76
+ @spec['parseErrors']&.map do |test_spec|
77
+ ParseErrorTest.new(self, test_spec)
78
+ end
79
+ end
80
+
81
+ # The class of the bson object to test.
82
+ #
83
+ # @example Get the class of the object to test.
84
+ # spec.klass
85
+ #
86
+ # @return [ Class ] The object class.
87
+ #
88
+ # @since 4.2.0
89
+ def klass
90
+ @klass ||= BSON.const_get(description)
91
+ end
92
+ end
93
+
94
+ class TestBase
95
+
96
+ private
97
+
98
+ def decode_hex(obj)
99
+ [ obj ].pack('H*')
100
+ end
101
+ end
102
+
103
+ # Represents a single BSON Corpus test.
104
+ #
105
+ # @since 4.2.0
106
+ class ValidTest < TestBase
107
+ extend Forwardable
108
+
109
+ # Instantiate the new Test.
110
+ #
111
+ # @example Create the test.
112
+ # Test.new(test)
113
+ #
114
+ # @param [ Corpus::Spec ] spec The test specification.
115
+ # @param [ Hash ] test The test specification.
116
+ #
117
+ # @since 4.2.0
118
+ def initialize(spec, test_params)
119
+ @spec = spec
120
+ test_params = test_params.dup
121
+ %w(
122
+ description canonical_extjson relaxed_extjson
123
+ degenerate_extjson converted_extjson
124
+ lossy
125
+ ).each do |key|
126
+ instance_variable_set("@#{key}", test_params.delete(key))
127
+ end
128
+ %w(
129
+ canonical_bson degenerate_bson converted_bson
130
+ lossy
131
+ ).each do |key|
132
+ if test_params.key?(key)
133
+ instance_variable_set("@#{key}", decode_hex(test_params.delete(key)))
134
+ end
135
+ end
136
+ unless test_params.empty?
137
+ raise "Test params has unprocessed keys: #{test_params}"
138
+ end
139
+ end
140
+
141
+ def_delegators :@spec, :test_key
142
+
143
+ attr_reader :description,
144
+ :canonical_bson,
145
+ :degenerate_bson,
146
+ :converted_bson,
147
+ :canonical_extjson,
148
+ :relaxed_extjson,
149
+ :degenerate_extjson,
150
+ :converted_extjson
151
+
152
+ def lossy?
153
+ !!@lossy
154
+ end
155
+
156
+ def canonical_extjson_doc
157
+ ::JSON.parse(canonical_extjson)
158
+ end
159
+
160
+ def relaxed_extjson_doc
161
+ relaxed_extjson && ::JSON.parse(relaxed_extjson)
162
+ end
163
+ end
164
+
165
+ class DecodeErrorTest < TestBase
166
+ def initialize(spec, test_params)
167
+ @spec = spec
168
+ @description = test_params['description']
169
+ @bson = decode_hex(test_params['bson'])
170
+ end
171
+
172
+ attr_reader :description, :bson
173
+ end
174
+
175
+ class ParseErrorTest
176
+ def initialize(spec, test_params)
177
+ @spec = spec
178
+ @description = test_params['description']
179
+ @string = test_params['string']
180
+ end
181
+
182
+ attr_reader :description, :string
183
+ end
184
+ end
185
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2016 MongoDB, Inc.
1
+ # Copyright (C) 2016-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -15,25 +15,19 @@
15
15
  require 'json'
16
16
 
17
17
  module BSON
18
- module Corpus
18
+ module CorpusLegacy
19
19
 
20
20
  # Represents a test from the driver BSON Corpus.
21
- #
22
- # @since 4.2.0
23
21
  class Spec
24
22
 
25
23
  # The spec description.
26
24
  #
27
25
  # @return [ String ] The spec description.
28
- #
29
- # @since 4.2.0
30
26
  attr_reader :description
31
27
 
32
28
  # The document key of the object to test.
33
29
  #
34
30
  # @return [ String ] The document key.
35
- #
36
- # @since 4.2.0
37
31
  attr_reader :test_key
38
32
 
39
33
  # Instantiate the new spec.
@@ -42,8 +36,6 @@ module BSON
42
36
  # Spec.new(file)
43
37
  #
44
38
  # @param [ String ] file The name of the json file.
45
- #
46
- # @since 4.2.0
47
39
  def initialize(file)
48
40
  @spec = ::JSON.parse(File.read(file))
49
41
  @valid = @spec['valid'] || []
@@ -57,13 +49,11 @@ module BSON
57
49
  # @example Get the list of valid tests.
58
50
  # spec.valid_tests
59
51
  #
60
- # @return [ Array<BSON::Corpus::Test> ] The list of valid Tests.
61
- #
62
- # @since 4.2.0
52
+ # @return [ Array<BSON::CorpusLegacy::Test> ] The list of valid Tests.
63
53
  def valid_tests
64
54
  @valid_tests ||=
65
55
  @valid.collect do |test|
66
- BSON::Corpus::Test.new(self, test)
56
+ BSON::CorpusLegacy::Test.new(self, test)
67
57
  end
68
58
  end
69
59
 
@@ -72,13 +62,11 @@ module BSON
72
62
  # @example Get the list of invalid tests.
73
63
  # spec.invalid_tests
74
64
  #
75
- # @return [ Array<BSON::Corpus::Test> ] The list of invalid Tests.
76
- #
77
- # @since 4.2.0
65
+ # @return [ Array<BSON::CorpusLegacy::Test> ] The list of invalid Tests.
78
66
  def invalid_tests
79
67
  @invalid_tests ||=
80
68
  @invalid.collect do |test|
81
- BSON::Corpus::Test.new(self, test)
69
+ BSON::CorpusLegacy::Test.new(self, test)
82
70
  end
83
71
  end
84
72
 
@@ -88,31 +76,23 @@ module BSON
88
76
  # spec.klass
89
77
  #
90
78
  # @return [ Class ] The object class.
91
- #
92
- # @since 4.2.0
93
79
  def klass
94
80
  @klass ||= BSON.const_get(description)
95
81
  end
96
82
  end
97
83
 
98
84
  # Represents a single BSON Corpus test.
99
- #
100
- # @since 4.2.0
101
85
  class Test
102
86
 
103
87
  # The test description.
104
88
  #
105
89
  # @return [ String ] The test description.
106
- #
107
- # @since 4.2.0
108
90
  attr_reader :description
109
91
 
110
92
  # Name of a field in a valid test case extjson document that should be
111
93
  # checked against the case's string field.
112
94
  #
113
95
  # @return [ String ] The json representation of the object.
114
- #
115
- # @since 4.2.0
116
96
  attr_reader :test_key
117
97
 
118
98
  # Instantiate the new Test.
@@ -122,8 +102,6 @@ module BSON
122
102
  #
123
103
  # @param [ Corpus::Spec ] spec The test specification.
124
104
  # @param [ Hash ] test The test specification.
125
- #
126
- # @since 4.2.0
127
105
  def initialize(spec, test)
128
106
  @spec = spec
129
107
  @description = test['description']
@@ -139,12 +117,29 @@ module BSON
139
117
  # test.correct_bson
140
118
  #
141
119
  # @return [ String ] The correct bson bytes.
142
- #
143
- # @since 4.2.0
144
120
  def correct_bson
145
121
  @correct_bson ||= decode_hex(@canonical_bson || @bson)
146
122
  end
147
123
 
124
+ # Create a BSON::Document object from the test's bson representation
125
+ #
126
+ # @return [ BSON::Document ] The BSON::Document object
127
+ def document_from_bson
128
+ bson_bytes = decode_hex(@bson)
129
+ buffer = BSON::ByteBuffer.new(bson_bytes)
130
+ BSON::Document.from_bson(buffer)
131
+ end
132
+
133
+ # Create a BSON::Document object from the test's canonical bson
134
+ # representation
135
+ #
136
+ # @return [ BSON::Document ] The BSON::Document object
137
+ def document_from_canonical_bson
138
+ bson_bytes = decode_hex(@canonical_bson)
139
+ buffer = BSON::ByteBuffer.new(bson_bytes)
140
+ BSON::Document.from_bson(buffer)
141
+ end
142
+
148
143
  # Given the hex representation of bson, decode it into a Document,
149
144
  # then reencoded it to bson.
150
145
  #
@@ -152,12 +147,8 @@ module BSON
152
147
  # test.reencoded_bson
153
148
  #
154
149
  # @return [ String ] The reencoded bson bytes.
155
- #
156
- # @since 4.2.0
157
150
  def reencoded_bson
158
- bson_bytes = decode_hex(@bson)
159
- buffer = BSON::ByteBuffer.new(bson_bytes)
160
- BSON::Document.from_bson(buffer).to_bson.to_s
151
+ document_from_bson.to_bson.to_s
161
152
  end
162
153
 
163
154
  # Given the hex representation of the canonical bson, decode it into a Document,
@@ -167,12 +158,8 @@ module BSON
167
158
  # test.reencoded_canonical_bson
168
159
  #
169
160
  # @return [ String ] The reencoded canonical bson bytes.
170
- #
171
- # @since 4.2.0
172
161
  def reencoded_canonical_bson
173
- bson_bytes = decode_hex(@canonical_bson)
174
- buffer = BSON::ByteBuffer.new(bson_bytes)
175
- BSON::Document.from_bson(buffer).to_bson.to_s
162
+ document_from_canonical_bson.to_bson.to_s
176
163
  end
177
164
 
178
165
  # Whether the canonical bson should be tested.
@@ -181,8 +168,6 @@ module BSON
181
168
  # test.test_canonical_bson?
182
169
  #
183
170
  # @return [ true, false ] Whether the canonical bson should be tested.
184
- #
185
- # @since 4.2.0
186
171
  def test_canonical_bson?
187
172
  @canonical_bson && (@bson != @canonical_bson)
188
173
  end
@@ -193,8 +178,6 @@ module BSON
193
178
  # test.correct_extjson
194
179
  #
195
180
  # @return [ String ] The correct extended json representation.
196
- #
197
- # @since 4.2.0
198
181
  def correct_extjson
199
182
  @canonical_extjson || @extjson
200
183
  end
@@ -205,8 +188,6 @@ module BSON
205
188
  # test.test_extjson?
206
189
  #
207
190
  # @return [ true, false ] Whether the extended json should be tested.
208
- #
209
- # @since 4.2.0
210
191
  def test_extjson?
211
192
  !!@extjson
212
193
  end
@@ -218,12 +199,8 @@ module BSON
218
199
  # test.extjson_from_encoded_bson
219
200
  #
220
201
  # @return [ Hash ] The extended json representation.
221
- #
222
- # @since 4.2.0
223
202
  def extjson_from_bson
224
- subject = decode_hex(@bson)
225
- buffer = BSON::ByteBuffer.new(subject)
226
- ::JSON.parse(BSON::Document.from_bson(buffer).to_json)
203
+ as_legacy_extended_json(document_from_bson)
227
204
  end
228
205
 
229
206
  # Get the extended json representation of the decoded doc from the provided
@@ -233,12 +210,8 @@ module BSON
233
210
  # test.extjson_from_canonical_bson
234
211
  #
235
212
  # @return [ Hash ] The extended json representation.
236
- #
237
- # @since 4.2.0
238
213
  def extjson_from_canonical_bson
239
- subject = decode_hex(@canonical_bson)
240
- buffer = BSON::ByteBuffer.new(subject)
241
- ::JSON.parse(BSON::Document.from_bson(buffer).to_json)
214
+ as_legacy_extended_json(document_from_canonical_bson)
242
215
  end
243
216
 
244
217
  # Get the extended json representation of the decoded doc from the provided
@@ -248,15 +221,24 @@ module BSON
248
221
  # test.extjson_from_encoded_extjson
249
222
  #
250
223
  # @return [ Hash ] The extended json representation.
251
- #
252
- # @since 4.2.0
253
224
  def extjson_from_encoded_extjson
254
225
  doc = BSON::Document.new(@extjson)
255
- ::JSON.parse(doc.to_json)
226
+ as_legacy_extended_json(doc)
256
227
  end
257
228
 
258
229
  private
259
230
 
231
+ def as_legacy_extended_json(object)
232
+ result = object.as_extended_json(mode: :legacy)
233
+ if object.respond_to?(:as_json)
234
+ old_result = object.as_json
235
+ unless result == old_result
236
+ raise "Serializing #{object} to legacy extended json did not match between new and old APIs"
237
+ end
238
+ end
239
+ result
240
+ end
241
+
260
242
  def decode_hex(obj)
261
243
  [ obj ].pack('H*')
262
244
  end