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.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +25 -7
- data/Rakefile +16 -9
- data/ext/bson/{native-endian.h → bson-endian.h} +5 -99
- data/ext/bson/bson-native.h +125 -0
- data/ext/bson/bytebuf.c +133 -0
- data/ext/bson/endian.c +117 -0
- data/ext/bson/init.c +355 -0
- data/ext/bson/libbson-utf8.c +230 -0
- data/ext/bson/read.c +411 -0
- data/ext/bson/util.c +95 -0
- data/ext/bson/write.c +680 -0
- data/lib/bson.rb +6 -3
- data/lib/bson/active_support.rb +17 -0
- data/lib/bson/array.rb +57 -17
- data/lib/bson/binary.rb +185 -13
- data/lib/bson/boolean.rb +12 -3
- data/lib/bson/code.rb +16 -2
- data/lib/bson/code_with_scope.rb +32 -5
- data/lib/bson/config.rb +1 -1
- data/lib/bson/date.rb +12 -2
- data/lib/bson/date_time.rb +2 -2
- data/lib/bson/db_pointer.rb +110 -0
- data/lib/bson/decimal128.rb +17 -3
- data/lib/bson/decimal128/builder.rb +1 -1
- data/lib/bson/document.rb +152 -5
- data/lib/bson/environment.rb +2 -1
- data/lib/bson/error.rb +27 -0
- data/lib/bson/ext_json.rb +383 -0
- data/lib/bson/false_class.rb +1 -1
- data/lib/bson/float.rb +48 -2
- data/lib/bson/hash.rb +68 -17
- data/lib/bson/int32.rb +52 -13
- data/lib/bson/int64.rb +59 -15
- data/lib/bson/integer.rb +36 -2
- data/lib/bson/json.rb +1 -1
- data/lib/bson/max_key.rb +13 -1
- data/lib/bson/min_key.rb +13 -1
- data/lib/bson/nil_class.rb +4 -2
- data/lib/bson/object.rb +28 -1
- data/lib/bson/object_id.rb +16 -2
- data/lib/bson/open_struct.rb +1 -1
- data/lib/bson/regexp.rb +27 -4
- data/lib/bson/registry.rb +3 -3
- data/lib/bson/specialized.rb +4 -2
- data/lib/bson/string.rb +5 -3
- data/lib/bson/symbol.rb +99 -7
- data/lib/bson/time.rb +63 -4
- data/lib/bson/time_with_zone.rb +54 -0
- data/lib/bson/timestamp.rb +44 -6
- data/lib/bson/true_class.rb +1 -1
- data/lib/bson/undefined.rb +12 -1
- data/lib/bson/version.rb +2 -2
- data/spec/bson/array_spec.rb +18 -1
- data/spec/bson/binary_spec.rb +100 -3
- data/spec/bson/binary_uuid_spec.rb +189 -0
- data/spec/bson/boolean_spec.rb +1 -1
- data/spec/bson/byte_buffer_read_spec.rb +197 -0
- data/spec/bson/byte_buffer_spec.rb +121 -381
- data/spec/bson/byte_buffer_write_spec.rb +854 -0
- data/spec/bson/code_spec.rb +1 -1
- data/spec/bson/code_with_scope_spec.rb +1 -1
- data/spec/bson/date_spec.rb +1 -1
- data/spec/bson/date_time_spec.rb +54 -1
- data/spec/bson/decimal128_spec.rb +35 -35
- data/spec/bson/document_as_spec.rb +46 -0
- data/spec/bson/document_spec.rb +197 -30
- data/spec/bson/ext_json_parse_spec.rb +308 -0
- data/spec/bson/false_class_spec.rb +1 -1
- data/spec/bson/float_spec.rb +37 -1
- data/spec/bson/hash_as_spec.rb +57 -0
- data/spec/bson/hash_spec.rb +209 -1
- data/spec/bson/int32_spec.rb +180 -6
- data/spec/bson/int64_spec.rb +199 -6
- data/spec/bson/integer_spec.rb +29 -3
- data/spec/bson/json_spec.rb +1 -1
- data/spec/bson/max_key_spec.rb +1 -1
- data/spec/bson/min_key_spec.rb +1 -1
- data/spec/bson/nil_class_spec.rb +1 -1
- data/spec/bson/object_id_spec.rb +1 -1
- data/spec/bson/object_spec.rb +1 -1
- data/spec/bson/open_struct_spec.rb +1 -1
- data/spec/bson/raw_spec.rb +34 -2
- data/spec/bson/regexp_spec.rb +1 -1
- data/spec/bson/registry_spec.rb +1 -1
- data/spec/bson/string_spec.rb +19 -1
- data/spec/bson/symbol_raw_spec.rb +45 -0
- data/spec/bson/symbol_spec.rb +63 -3
- data/spec/bson/time_spec.rb +205 -2
- data/spec/bson/time_with_zone_spec.rb +68 -0
- data/spec/bson/timestamp_spec.rb +56 -1
- data/spec/bson/true_class_spec.rb +1 -1
- data/spec/bson/undefined_spec.rb +1 -1
- data/spec/bson_spec.rb +1 -1
- data/spec/{support → runners}/common_driver.rb +1 -1
- data/spec/runners/corpus.rb +185 -0
- data/spec/{support/corpus.rb → runners/corpus_legacy.rb} +41 -59
- data/spec/spec_helper.rb +40 -3
- data/spec/{bson/driver_bson_spec.rb → spec_tests/common_driver_spec.rb} +1 -0
- data/spec/{bson/corpus_spec.rb → spec_tests/corpus_legacy_spec.rb} +10 -7
- data/spec/spec_tests/corpus_spec.rb +124 -0
- data/spec/spec_tests/data/corpus/README.md +15 -0
- data/spec/spec_tests/data/corpus/array.json +49 -0
- data/spec/spec_tests/data/corpus/binary.json +113 -0
- data/spec/spec_tests/data/corpus/boolean.json +27 -0
- data/spec/spec_tests/data/corpus/code.json +67 -0
- data/spec/spec_tests/data/corpus/code_w_scope.json +78 -0
- data/spec/spec_tests/data/corpus/datetime.json +42 -0
- data/spec/spec_tests/data/corpus/dbpointer.json +56 -0
- data/spec/spec_tests/data/corpus/dbref.json +31 -0
- data/spec/spec_tests/data/corpus/decimal128-1.json +317 -0
- data/spec/spec_tests/data/corpus/decimal128-2.json +793 -0
- data/spec/spec_tests/data/corpus/decimal128-3.json +1771 -0
- data/spec/spec_tests/data/corpus/decimal128-4.json +117 -0
- data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
- data/spec/spec_tests/data/corpus/decimal128-6.json +119 -0
- data/spec/spec_tests/data/corpus/decimal128-7.json +323 -0
- data/spec/spec_tests/data/corpus/document.json +36 -0
- data/spec/spec_tests/data/corpus/double.json +87 -0
- data/spec/spec_tests/data/corpus/int32.json +43 -0
- data/spec/spec_tests/data/corpus/int64.json +43 -0
- data/spec/spec_tests/data/corpus/maxkey.json +12 -0
- data/spec/spec_tests/data/corpus/minkey.json +12 -0
- data/spec/spec_tests/data/corpus/multi-type-deprecated.json +15 -0
- data/spec/spec_tests/data/corpus/multi-type.json +11 -0
- data/spec/spec_tests/data/corpus/null.json +12 -0
- data/spec/spec_tests/data/corpus/oid.json +28 -0
- data/spec/spec_tests/data/corpus/regex.json +65 -0
- data/spec/spec_tests/data/corpus/string.json +72 -0
- data/spec/spec_tests/data/corpus/symbol.json +80 -0
- data/spec/spec_tests/data/corpus/timestamp.json +34 -0
- data/spec/spec_tests/data/corpus/top.json +236 -0
- data/spec/spec_tests/data/corpus/undefined.json +15 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/array.json +8 -2
- data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/binary.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/boolean.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code_w_scope.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/document.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/double.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/datetime.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/dbpointer.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/int64.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/symbol.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/int32.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/maxkey.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/minkey.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/null.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/oid.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/regex.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/string.json +0 -0
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/timestamp.json +1 -1
- data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/top.json +0 -0
- data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/undefined.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-1.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-2.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-3.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-4.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-5.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-6.json +0 -0
- data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-7.json +0 -0
- data/spec/support/shared_examples.rb +3 -5
- data/spec/support/spec_config.rb +16 -0
- data/spec/support/utils.rb +10 -0
- metadata +227 -124
- metadata.gz.sig +0 -0
- data/ext/bson/bson_native.c +0 -762
@@ -0,0 +1,54 @@
|
|
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 "active_support/time_with_zone"
|
16
|
+
|
17
|
+
module BSON
|
18
|
+
|
19
|
+
# Injects behaviour for encoding ActiveSupport::TimeWithZone values to
|
20
|
+
# raw bytes as specified by the BSON spec for time.
|
21
|
+
#
|
22
|
+
# @see http://bsonspec.org/#/specification
|
23
|
+
#
|
24
|
+
# @since 4.4.0
|
25
|
+
module TimeWithZone
|
26
|
+
|
27
|
+
# Get the ActiveSupport::TimeWithZone as encoded BSON.
|
28
|
+
#
|
29
|
+
# @example Get the ActiveSupport::TimeWithZone as encoded BSON.
|
30
|
+
# Time.utc(2012, 12, 12, 0, 0, 0).in_time_zone("Pacific Time (US & Canada)").to_bson
|
31
|
+
#
|
32
|
+
# @return [ BSON::ByteBuffer ] The buffer with the encoded object.
|
33
|
+
#
|
34
|
+
# @see http://bsonspec.org/#/specification
|
35
|
+
#
|
36
|
+
# @since 4.4.0
|
37
|
+
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
38
|
+
buffer.put_int64((to_i * 1000) + (usec / 1000))
|
39
|
+
end
|
40
|
+
|
41
|
+
# Get the BSON type for the ActiveSupport::TimeWithZone.
|
42
|
+
#
|
43
|
+
# As the ActiveSupport::TimeWithZone is converted to a time, this returns
|
44
|
+
# the BSON type for time.
|
45
|
+
def bson_type
|
46
|
+
::Time::BSON_TYPE
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Enrich the ActiveSupport::TimeWithZone class with this module.
|
51
|
+
#
|
52
|
+
# @since 4.4.0
|
53
|
+
ActiveSupport::TimeWithZone.send(:include, TimeWithZone)
|
54
|
+
end
|
data/lib/bson/timestamp.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
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.
|
@@ -21,12 +21,18 @@ module BSON
|
|
21
21
|
# @since 2.0.0
|
22
22
|
class Timestamp
|
23
23
|
include JSON
|
24
|
+
include Comparable
|
24
25
|
|
25
26
|
# A timestamp is type 0x11 in the BSON spec.
|
26
27
|
#
|
27
28
|
# @since 2.0.0
|
28
29
|
BSON_TYPE = 17.chr.force_encoding(BINARY).freeze
|
29
30
|
|
31
|
+
# Error message if an object other than a Timestamp is compared with this object.
|
32
|
+
#
|
33
|
+
# @since 4.3.0
|
34
|
+
COMPARISON_ERROR_MESSAGE = 'comparison of %s with Timestamp failed'.freeze
|
35
|
+
|
30
36
|
# @!attribute seconds
|
31
37
|
# @return [ Integer ] The number of seconds.
|
32
38
|
# @since 2.0.0
|
@@ -52,6 +58,24 @@ module BSON
|
|
52
58
|
seconds == other.seconds && increment == other.increment
|
53
59
|
end
|
54
60
|
|
61
|
+
# Determine if this timestamp is greater or less than another object.
|
62
|
+
#
|
63
|
+
# @example Compare the timestamp.
|
64
|
+
# timestamp < other
|
65
|
+
#
|
66
|
+
# @param [ Object ] other The object to compare against.
|
67
|
+
#
|
68
|
+
# @return [ true, false ] The result of the comparison.
|
69
|
+
#
|
70
|
+
# @since 4.3.0
|
71
|
+
def <=>(other)
|
72
|
+
raise ArgumentError.new(COMPARISON_ERROR_MESSAGE % other.class) unless other.is_a?(Timestamp)
|
73
|
+
return 0 if self == other
|
74
|
+
a = [ seconds, increment ]
|
75
|
+
b = [ other.seconds, other.increment ]
|
76
|
+
[ a, b ].sort[0] == a ? -1 : 1
|
77
|
+
end
|
78
|
+
|
55
79
|
# Get the timestamp as JSON hash data.
|
56
80
|
#
|
57
81
|
# @example Get the timestamp as a JSON hash.
|
@@ -60,7 +84,19 @@ module BSON
|
|
60
84
|
# @return [ Hash ] The timestamp as a JSON hash.
|
61
85
|
#
|
62
86
|
# @since 2.0.0
|
87
|
+
# @deprecated Use as_extended_json instead.
|
63
88
|
def as_json(*args)
|
89
|
+
as_extended_json
|
90
|
+
end
|
91
|
+
|
92
|
+
# Converts this object to a representation directly serializable to
|
93
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
94
|
+
#
|
95
|
+
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
96
|
+
# (default is canonical extended JSON)
|
97
|
+
#
|
98
|
+
# @return [ Hash ] The extended json representation.
|
99
|
+
def as_extended_json(**options)
|
64
100
|
{ "$timestamp" => { "t" => seconds, "i" => increment } }
|
65
101
|
end
|
66
102
|
|
@@ -88,22 +124,24 @@ module BSON
|
|
88
124
|
#
|
89
125
|
# @since 2.0.0
|
90
126
|
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
|
91
|
-
buffer.
|
92
|
-
buffer.
|
127
|
+
buffer.put_uint32(increment)
|
128
|
+
buffer.put_uint32(seconds)
|
93
129
|
end
|
94
130
|
|
95
131
|
# Deserialize timestamp from BSON.
|
96
132
|
#
|
97
133
|
# @param [ ByteBuffer ] buffer The byte buffer.
|
98
134
|
#
|
135
|
+
# @option options [ nil | :bson ] :mode Decoding mode to use.
|
136
|
+
#
|
99
137
|
# @return [ Timestamp ] The decoded timestamp.
|
100
138
|
#
|
101
139
|
# @see http://bsonspec.org/#/specification
|
102
140
|
#
|
103
141
|
# @since 2.0.0
|
104
|
-
def self.from_bson(buffer)
|
105
|
-
increment = buffer.
|
106
|
-
seconds = buffer.
|
142
|
+
def self.from_bson(buffer, **options)
|
143
|
+
increment = buffer.get_uint32
|
144
|
+
seconds = buffer.get_uint32
|
107
145
|
new(seconds, increment)
|
108
146
|
end
|
109
147
|
|
data/lib/bson/true_class.rb
CHANGED
data/lib/bson/undefined.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
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.
|
@@ -41,6 +41,17 @@ module BSON
|
|
41
41
|
self.class == other.class
|
42
42
|
end
|
43
43
|
|
44
|
+
# Converts this object to a representation directly serializable to
|
45
|
+
# Extended JSON (https://github.com/mongodb/specifications/blob/master/source/extended-json.rst).
|
46
|
+
#
|
47
|
+
# @option opts [ nil | :relaxed | :legacy ] :mode Serialization mode
|
48
|
+
# (default is canonical extended JSON)
|
49
|
+
#
|
50
|
+
# @return [ Hash ] The extended json representation.
|
51
|
+
def as_extended_json(**options)
|
52
|
+
{ "$undefined" => true }
|
53
|
+
end
|
54
|
+
|
44
55
|
# Register this type when the module is loaded.
|
45
56
|
#
|
46
57
|
# @since 2.0.0
|
data/lib/bson/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
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.
|
@@ -13,5 +13,5 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
module BSON
|
16
|
-
VERSION = "4.
|
16
|
+
VERSION = "4.12.1".freeze
|
17
17
|
end
|
data/spec/bson/array_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
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.
|
@@ -132,6 +132,23 @@ describe Array do
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
end
|
135
|
+
|
136
|
+
context 'when array contains value of an unserializable class' do
|
137
|
+
class ArraySpecUnserializableClass
|
138
|
+
end
|
139
|
+
|
140
|
+
let(:obj) do
|
141
|
+
[ArraySpecUnserializableClass.new]
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'raises UnserializableClass' do
|
145
|
+
lambda do
|
146
|
+
obj.to_bson
|
147
|
+
end.should raise_error(BSON::Error::UnserializableClass,
|
148
|
+
# C extension does not provide element position in the exception message.
|
149
|
+
/(Array element at position 0|Value) does not define its BSON serialized type:.*ArraySpecUnserializableClass/)
|
150
|
+
end
|
151
|
+
end
|
135
152
|
end
|
136
153
|
|
137
154
|
describe "#to_bson_normalized_value" do
|
data/spec/bson/binary_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009-
|
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.
|
@@ -63,7 +63,7 @@ describe BSON::Binary do
|
|
63
63
|
|
64
64
|
it "returns the binary data plus type" do
|
65
65
|
expect(object.as_json).to eq(
|
66
|
-
{ "$binary" => Base64.encode64("testing"), "
|
66
|
+
{ "$binary" => {'base64' => Base64.encode64("testing").strip, "subType" => '80' }}
|
67
67
|
)
|
68
68
|
end
|
69
69
|
|
@@ -72,6 +72,14 @@ describe BSON::Binary do
|
|
72
72
|
|
73
73
|
describe "#initialize" do
|
74
74
|
|
75
|
+
context 'when type is not given' do
|
76
|
+
let(:obj) { described_class.new('foo') }
|
77
|
+
|
78
|
+
it 'defaults to generic type' do
|
79
|
+
expect(obj.type).to eq(:generic)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
75
83
|
context "when he type is invalid" do
|
76
84
|
|
77
85
|
it "raises an error" do
|
@@ -105,7 +113,11 @@ describe BSON::Binary do
|
|
105
113
|
expect(object.inspect).to eq("<BSON::Binary:0x#{object.object_id} type=user data=0x1f8b08000c787055...>")
|
106
114
|
end
|
107
115
|
|
108
|
-
it 'is not
|
116
|
+
it 'is not binary' do
|
117
|
+
# As long as the default Ruby encoding is not binary, the inspected
|
118
|
+
# string should also not be in the binary encoding (it should be
|
119
|
+
# in one of the text encodings, but which one could depend on
|
120
|
+
# the Ruby runtime environment).
|
109
121
|
expect(object.inspect.encoding).not_to eq(Encoding::BINARY)
|
110
122
|
end
|
111
123
|
|
@@ -113,6 +125,37 @@ describe BSON::Binary do
|
|
113
125
|
|
114
126
|
end
|
115
127
|
|
128
|
+
describe '#from_bson' do
|
129
|
+
let(:buffer) { BSON::ByteBuffer.new(bson) }
|
130
|
+
let(:obj) { described_class.from_bson(buffer) }
|
131
|
+
|
132
|
+
let(:bson) { "#{5.to_bson}#{0.chr}hello".force_encoding('BINARY') }
|
133
|
+
|
134
|
+
it 'sets data encoding to binary' do
|
135
|
+
expect(obj.data.encoding).to eq(Encoding.find('BINARY'))
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'when binary subtype is supported' do
|
139
|
+
let(:bson) { [3, 0, 0, 0, 1].map(&:chr).join.force_encoding('BINARY') + 'foo' }
|
140
|
+
|
141
|
+
it 'works' do
|
142
|
+
obj.should be_a(described_class)
|
143
|
+
obj.type.should be :function
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'when binary subtype is not supported' do
|
148
|
+
let(:bson) { [3, 0, 0, 0, 16].map(&:chr).join.force_encoding('BINARY') + 'foo' }
|
149
|
+
|
150
|
+
it 'raises an exception' do
|
151
|
+
lambda do
|
152
|
+
obj
|
153
|
+
end.should raise_error(BSON::Error::UnsupportedBinarySubtype,
|
154
|
+
/BSON data contains unsupported binary subtype 0x10/)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
116
159
|
describe "#to_bson/#from_bson" do
|
117
160
|
|
118
161
|
let(:type) { 5.chr }
|
@@ -181,5 +224,59 @@ describe BSON::Binary do
|
|
181
224
|
it_behaves_like "a serializable bson element"
|
182
225
|
it_behaves_like "a deserializable bson element"
|
183
226
|
end
|
227
|
+
|
228
|
+
context "when the type is :cyphertext" do
|
229
|
+
let(:obj) { described_class.new("testing", :ciphertext) }
|
230
|
+
let(:bson) { "#{7.to_bson}#{6.chr}testing" }
|
231
|
+
|
232
|
+
it_behaves_like "a serializable bson element"
|
233
|
+
it_behaves_like "a deserializable bson element"
|
234
|
+
end
|
235
|
+
|
236
|
+
context 'when given binary string' do
|
237
|
+
let(:obj) { described_class.new("\x00\xfe\xff".force_encoding('BINARY')) }
|
238
|
+
let(:bson) { "#{3.to_bson}#{0.chr}\x00\xfe\xff".force_encoding('BINARY') }
|
239
|
+
|
240
|
+
it_behaves_like "a serializable bson element"
|
241
|
+
it_behaves_like "a deserializable bson element"
|
242
|
+
end
|
243
|
+
|
244
|
+
context 'when given a frozen string' do
|
245
|
+
let(:str) { "\x00\xfe\xff".force_encoding('BINARY').freeze }
|
246
|
+
let(:obj) { described_class.new(str) }
|
247
|
+
let(:bson) { "#{3.to_bson}#{0.chr}\x00\xfe\xff".force_encoding('BINARY') }
|
248
|
+
|
249
|
+
it_behaves_like "a serializable bson element"
|
250
|
+
it_behaves_like "a deserializable bson element"
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
describe '#to_uuid' do
|
255
|
+
let(:obj) { described_class.new("\x00" * 16, :uuid) }
|
256
|
+
|
257
|
+
it 'accepts symbol representation' do
|
258
|
+
expect(obj.to_uuid(:standard)).to eq('00000000-0000-0000-0000-000000000000')
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'rejects string representation' do
|
262
|
+
expect do
|
263
|
+
obj.to_uuid('standard')
|
264
|
+
end.to raise_error(ArgumentError, /Representation must be given as a symbol/)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe '#from_uuid' do
|
269
|
+
let(:uuid) { '00000000-0000-0000-0000000000000000' }
|
270
|
+
|
271
|
+
it 'accepts symbol representation' do
|
272
|
+
obj = described_class.from_uuid(uuid, :standard)
|
273
|
+
expect(obj.data).to eq("\x00" * 16)
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'rejects string representation' do
|
277
|
+
expect do
|
278
|
+
described_class.from_uuid(uuid, 'standard')
|
279
|
+
end.to raise_error(ArgumentError, /Representation must be given as a symbol/)
|
280
|
+
end
|
184
281
|
end
|
185
282
|
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
# Copyright (C) 2019-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
|
+
require "base64"
|
17
|
+
|
18
|
+
describe "BSON::Binary - UUID spec tests" do
|
19
|
+
def make_binary(uuid_hex_str, type)
|
20
|
+
uuid_binary_str = uuid_hex_str.scan(/../).map(&:hex).map(&:chr).join
|
21
|
+
BSON::Binary.new(uuid_binary_str, type)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'explicit encoding' do
|
25
|
+
let(:uuid_str) { '00112233-4455-6677-8899-aabbccddeeff' }
|
26
|
+
|
27
|
+
shared_examples_for 'creates binary' do
|
28
|
+
it 'creates subtype 4 binary' do
|
29
|
+
expect(binary.type).to eq(expected_type)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'creates binary with correct value' do
|
33
|
+
expect(binary.data).to eq(expected_hex_value.scan(/../).map(&:hex).map(&:chr).join)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'no representation' do
|
38
|
+
let(:binary) { BSON::Binary.from_uuid(uuid_str) }
|
39
|
+
let(:expected_type) { :uuid }
|
40
|
+
let(:expected_hex_value) { '00112233445566778899AABBCCDDEEFF' }
|
41
|
+
|
42
|
+
it_behaves_like 'creates binary'
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'standard representation' do
|
46
|
+
let(:binary) { BSON::Binary.from_uuid(uuid_str, :standard) }
|
47
|
+
let(:expected_type) { :uuid }
|
48
|
+
let(:expected_hex_value) { '00112233445566778899AABBCCDDEEFF' }
|
49
|
+
|
50
|
+
it_behaves_like 'creates binary'
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'csharp legacy representation' do
|
54
|
+
let(:binary) { BSON::Binary.from_uuid(uuid_str, :csharp_legacy) }
|
55
|
+
let(:expected_type) { :uuid_old }
|
56
|
+
let(:expected_hex_value) { '33221100554477668899AABBCCDDEEFF' }
|
57
|
+
|
58
|
+
it_behaves_like 'creates binary'
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'java legacy representation' do
|
62
|
+
let(:binary) { BSON::Binary.from_uuid(uuid_str, :java_legacy) }
|
63
|
+
let(:expected_type) { :uuid_old }
|
64
|
+
let(:expected_hex_value) { '7766554433221100FFEEDDCCBBAA9988' }
|
65
|
+
|
66
|
+
it_behaves_like 'creates binary'
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'python legacy representation' do
|
70
|
+
let(:binary) { BSON::Binary.from_uuid(uuid_str, :python_legacy) }
|
71
|
+
let(:expected_type) { :uuid_old }
|
72
|
+
let(:expected_hex_value) { '00112233445566778899AABBCCDDEEFF' }
|
73
|
+
|
74
|
+
it_behaves_like 'creates binary'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe 'explicit decoding' do
|
79
|
+
context ':uuid, standard encoded' do
|
80
|
+
let(:binary) { make_binary("00112233445566778899AABBCCDDEEFF", :uuid) }
|
81
|
+
|
82
|
+
it 'decodes without arguments' do
|
83
|
+
expect(binary.to_uuid.gsub('-', '').upcase).to eq("00112233445566778899AABBCCDDEEFF")
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'decodes as standard' do
|
87
|
+
expect(binary.to_uuid(:standard).gsub('-', '').upcase).to eq("00112233445566778899AABBCCDDEEFF")
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'does not decode as csharp legacy' do
|
91
|
+
expect do
|
92
|
+
binary.to_uuid(:csharp_legacy)
|
93
|
+
end.to raise_error(ArgumentError, /Binary of type :uuid can only be stringified to :standard representation/)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'does not decode as java legacy' do
|
97
|
+
expect do
|
98
|
+
binary.to_uuid(:java_legacy)
|
99
|
+
end.to raise_error(ArgumentError, /Binary of type :uuid can only be stringified to :standard representation/)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'does not decode as python legacy' do
|
103
|
+
expect do
|
104
|
+
binary.to_uuid(:python_legacy)
|
105
|
+
end.to raise_error(ArgumentError, /Binary of type :uuid can only be stringified to :standard representation/)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
shared_examples_for 'a legacy uuid' do
|
110
|
+
it 'does not decode without arguments' do
|
111
|
+
expect do
|
112
|
+
binary.to_uuid
|
113
|
+
end.to raise_error(ArgumentError, /Representation must be specified for BSON::Binary objects of type :uuid_old/)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'does not decode as standard' do
|
117
|
+
expect do
|
118
|
+
binary.to_uuid(:standard)
|
119
|
+
end.to raise_error(ArgumentError, /BSON::Binary objects of type :uuid_old cannot be stringified to :standard representation/)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context ':uuid_old, csharp legacy encoded' do
|
124
|
+
let(:binary) { make_binary("33221100554477668899AABBCCDDEEFF", :uuid_old) }
|
125
|
+
|
126
|
+
it_behaves_like 'a legacy uuid'
|
127
|
+
|
128
|
+
it 'decodes as csharp legacy' do
|
129
|
+
expect(binary.to_uuid(:csharp_legacy).gsub('-', '').upcase).to eq("00112233445566778899AABBCCDDEEFF")
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'decodes as java legacy' do
|
133
|
+
expect(binary.to_uuid(:java_legacy).gsub('-', '').upcase).not_to eq("00112233445566778899AABBCCDDEEFF")
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'decodes as python legacy' do
|
137
|
+
expect(binary.to_uuid(:python_legacy).gsub('-', '').upcase).not_to eq("00112233445566778899AABBCCDDEEFF")
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'expects four dashes when output as String' do
|
141
|
+
expect(binary.to_uuid(:csharp_legacy)).to eq("00112233-4455-6677-8899-aabbccddeeff")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context ':uuid_old, java legacy encoded' do
|
146
|
+
let(:binary) { make_binary("7766554433221100FFEEDDCCBBAA9988", :uuid_old) }
|
147
|
+
|
148
|
+
it_behaves_like 'a legacy uuid'
|
149
|
+
|
150
|
+
it 'decodes as csharp legacy' do
|
151
|
+
expect(binary.to_uuid(:csharp_legacy).gsub('-', '').upcase).not_to eq("00112233445566778899AABBCCDDEEFF")
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'decodes as java legacy' do
|
155
|
+
expect(binary.to_uuid(:java_legacy).gsub('-', '').upcase).to eq("00112233445566778899AABBCCDDEEFF")
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'decodes as python legacy' do
|
159
|
+
expect(binary.to_uuid(:python_legacy).gsub('-', '').upcase).not_to eq("00112233445566778899AABBCCDDEEFF")
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'expects four dashes when output as String' do
|
163
|
+
expect(binary.to_uuid(:java_legacy)).to eq("00112233-4455-6677-8899-aabbccddeeff")
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context ':uuid_old, python legacy encoded' do
|
168
|
+
let(:binary) { make_binary("00112233445566778899AABBCCDDEEFF", :uuid_old) }
|
169
|
+
|
170
|
+
it_behaves_like 'a legacy uuid'
|
171
|
+
|
172
|
+
it 'decodes as csharp legacy' do
|
173
|
+
expect(binary.to_uuid(:csharp_legacy).gsub('-', '').upcase).not_to eq("00112233445566778899AABBCCDDEEFF")
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'decodes as java legacy' do
|
177
|
+
expect(binary.to_uuid(:java_legacy).gsub('-', '').upcase).not_to eq("00112233445566778899AABBCCDDEEFF")
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'decodes as python legacy' do
|
181
|
+
expect(binary.to_uuid(:python_legacy).gsub('-', '').upcase).to eq("00112233445566778899AABBCCDDEEFF")
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'expects four dashes when output as String' do
|
185
|
+
expect(binary.to_uuid(:python_legacy)).to eq("00112233-4455-6677-8899-aabbccddeeff")
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|