bson 4.1.1-java → 4.2.0-java
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Rakefile +18 -3
- data/lib/bson-ruby.jar +0 -0
- data/lib/bson.rb +6 -4
- data/lib/bson/array.rb +1 -1
- data/lib/bson/binary.rb +4 -2
- data/lib/bson/code.rb +1 -1
- data/lib/bson/code_with_scope.rb +1 -1
- data/lib/bson/config.rb +1 -1
- data/lib/bson/date.rb +1 -1
- data/lib/bson/date_time.rb +1 -1
- data/lib/bson/decimal128.rb +318 -0
- data/lib/bson/decimal128/builder.rb +448 -0
- data/lib/bson/document.rb +2 -2
- data/lib/bson/environment.rb +13 -1
- data/lib/bson/false_class.rb +1 -1
- data/lib/bson/float.rb +1 -1
- data/lib/bson/hash.rb +1 -1
- data/lib/bson/int32.rb +46 -0
- data/lib/bson/int64.rb +46 -0
- data/lib/bson/integer.rb +1 -1
- data/lib/bson/max_key.rb +1 -1
- data/lib/bson/min_key.rb +1 -1
- data/lib/bson/object_id.rb +3 -2
- data/lib/bson/open_struct.rb +57 -0
- data/lib/bson/regexp.rb +87 -19
- data/lib/bson/registry.rb +1 -1
- data/lib/bson/specialized.rb +1 -1
- data/lib/bson/string.rb +1 -1
- data/lib/bson/symbol.rb +1 -1
- data/lib/bson/time.rb +1 -1
- data/lib/bson/timestamp.rb +2 -2
- data/lib/bson/true_class.rb +1 -1
- data/lib/bson/version.rb +2 -2
- data/spec/bson/array_spec.rb +1 -1
- data/spec/bson/binary_spec.rb +2 -1
- data/spec/bson/corpus_spec.rb +68 -0
- data/spec/bson/decimal128_spec.rb +1583 -0
- data/spec/bson/document_spec.rb +1 -1
- data/spec/bson/driver_bson_spec.rb +77 -0
- data/spec/bson/int32_spec.rb +58 -0
- data/spec/bson/int64_spec.rb +58 -0
- data/spec/bson/open_struct_spec.rb +144 -0
- data/spec/bson/raw_spec.rb +540 -0
- data/spec/bson/regexp_spec.rb +7 -7
- data/spec/bson/timestamp_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -0
- data/spec/support/common_driver.rb +347 -0
- data/spec/support/corpus-tests/array.json +43 -0
- data/spec/support/corpus-tests/boolean.json +27 -0
- data/spec/support/corpus-tests/code.json +67 -0
- data/spec/support/corpus-tests/code_w_scope.json +78 -0
- data/spec/support/corpus-tests/document.json +36 -0
- data/spec/support/corpus-tests/double.json +69 -0
- data/spec/support/corpus-tests/failures/binary.json +69 -0
- data/spec/support/corpus-tests/failures/datetime.json +31 -0
- data/spec/support/corpus-tests/failures/dbpointer.json +42 -0
- data/spec/support/corpus-tests/failures/int64.json +38 -0
- data/spec/support/corpus-tests/failures/symbol.json +62 -0
- data/spec/support/corpus-tests/failures/undefined.json +13 -0
- data/spec/support/corpus-tests/int32.json +38 -0
- data/spec/support/corpus-tests/maxkey.json +12 -0
- data/spec/support/corpus-tests/minkey.json +12 -0
- data/spec/support/corpus-tests/null.json +12 -0
- data/spec/support/corpus-tests/oid.json +28 -0
- data/spec/support/corpus-tests/regex.json +37 -0
- data/spec/support/corpus-tests/string.json +67 -0
- data/spec/support/corpus-tests/timestamp.json +18 -0
- data/spec/support/corpus-tests/top.json +62 -0
- data/spec/support/corpus.rb +265 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-1.json +363 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-2.json +793 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-3.json +1771 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-4.json +165 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-5.json +402 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-6.json +131 -0
- data/spec/support/driver-spec-tests/decimal128/decimal128-7.json +327 -0
- data/spec/support/shared_examples.rb +1 -1
- metadata +77 -4
- metadata.gz.sig +0 -0
data/spec/bson/document_spec.rb
CHANGED
@@ -887,7 +887,7 @@ describe BSON::Document do
|
|
887
887
|
end
|
888
888
|
end
|
889
889
|
|
890
|
-
context "when binary strings with utf-8 values exist", if: BSON::Environment.jruby? && (JRUBY_VERSION
|
890
|
+
context "when binary strings with utf-8 values exist", if: BSON::Environment.jruby? && (JRUBY_VERSION < '9') do
|
891
891
|
|
892
892
|
let(:string) { "europäisch" }
|
893
893
|
let(:document) do
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Driver common bson tests' do
|
4
|
+
|
5
|
+
specs = DRIVER_COMMON_BSON_TESTS.map { |file| BSON::CommonDriver::Spec.new(file) }
|
6
|
+
|
7
|
+
specs.each do |spec|
|
8
|
+
|
9
|
+
context(spec.description) do
|
10
|
+
|
11
|
+
spec.valid_tests.each do |test|
|
12
|
+
|
13
|
+
context(test.description << ' - ' << test.string) do
|
14
|
+
|
15
|
+
it 'decodes the subject and displays as the correct string' do
|
16
|
+
expect(test.object.to_s).to eq(test.expected_to_string)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'encodes the decoded object correctly (roundtrips)' do
|
20
|
+
expect(test.reencoded_hex).to eq(test.subject.upcase)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'creates the correct object from extended json', if: test.from_ext_json? do
|
24
|
+
expect(test.from_json_string).to eq(test.object)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'creates the correct extended json document from the decoded object', if: test.to_ext_json? do
|
28
|
+
expect(test.document_as_json).to eq(test.ext_json)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'parses the string value to the same value as the decoded document', if: test.from_string? do
|
32
|
+
expect(BSON::Decimal128.new(test.string)).to eq(test.object)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'parses the #to_s (match_string) value to the same value as the decoded document', if: test.match_string do
|
36
|
+
expect(BSON::Decimal128.new(test.match_string)).to eq(test.object)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'creates the correct object from a non canonical string and then prints to the correct string', if: test.match_string do
|
40
|
+
expect(BSON::Decimal128.new(test.string).to_s).to eq(test.match_string)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'can be converted to a native type' do
|
44
|
+
expect(test.native_type_conversion).to be_a(test.native_type)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
spec.invalid_tests.each do |test|
|
50
|
+
|
51
|
+
context(test.description << " - " << test.subject ) do
|
52
|
+
|
53
|
+
let(:error) do
|
54
|
+
ex = nil
|
55
|
+
begin
|
56
|
+
test.parse_invalid_string
|
57
|
+
rescue => e
|
58
|
+
ex = e
|
59
|
+
end
|
60
|
+
ex
|
61
|
+
end
|
62
|
+
|
63
|
+
let(:valid_errors) do
|
64
|
+
[
|
65
|
+
BSON::Decimal128::InvalidString,
|
66
|
+
BSON::Decimal128::InvalidRange
|
67
|
+
]
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'raises an exception when parsing' do
|
71
|
+
expect(error.class).to satisfy { |e| valid_errors.include?(e) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/spec/bson/int32_spec.rb
CHANGED
@@ -16,6 +16,42 @@ require "spec_helper"
|
|
16
16
|
|
17
17
|
describe BSON::Int32 do
|
18
18
|
|
19
|
+
describe "#intiialize" do
|
20
|
+
|
21
|
+
let(:obj) { described_class.new(integer) }
|
22
|
+
|
23
|
+
context "when the integer is 32-bit" do
|
24
|
+
|
25
|
+
let(:integer) { Integer::MAX_32BIT }
|
26
|
+
|
27
|
+
it "wraps the integer" do
|
28
|
+
expect(obj.instance_variable_get(:@integer)).to be(integer)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when the integer is too large" do
|
33
|
+
|
34
|
+
let(:integer) { Integer::MAX_32BIT + 1 }
|
35
|
+
|
36
|
+
it "raises an out of range error" do
|
37
|
+
expect {
|
38
|
+
obj
|
39
|
+
}.to raise_error(RangeError)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when the integer is too small" do
|
44
|
+
|
45
|
+
let(:integer) { Integer::MIN_32BIT - 1 }
|
46
|
+
|
47
|
+
it "raises an out of range error" do
|
48
|
+
expect {
|
49
|
+
obj
|
50
|
+
}.to raise_error(RangeError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
19
55
|
describe "#from_bson" do
|
20
56
|
|
21
57
|
let(:type) { 16.chr }
|
@@ -41,4 +77,26 @@ describe BSON::Int32 do
|
|
41
77
|
expect(BSON::Int32.from_bson(encoded_2)).to eq(decoded_2)
|
42
78
|
end
|
43
79
|
end
|
80
|
+
|
81
|
+
describe "#to_bson" do
|
82
|
+
|
83
|
+
context "when the integer is 32 bit" do
|
84
|
+
|
85
|
+
let(:type) { 16.chr }
|
86
|
+
let(:obj) { BSON::Int32.new(Integer::MAX_32BIT - 1) }
|
87
|
+
let(:bson) { [ Integer::MAX_32BIT - 1 ].pack(BSON::Int32::PACK) }
|
88
|
+
|
89
|
+
it_behaves_like "a serializable bson element"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#to_bson_key" do
|
94
|
+
|
95
|
+
let(:obj) { BSON::Int32.new(Integer::MAX_32BIT - 1) }
|
96
|
+
let(:encoded) { (Integer::MAX_32BIT - 1).to_s }
|
97
|
+
|
98
|
+
it "returns the key as a string" do
|
99
|
+
expect(obj.to_bson_key).to eq(encoded)
|
100
|
+
end
|
101
|
+
end
|
44
102
|
end
|
data/spec/bson/int64_spec.rb
CHANGED
@@ -16,6 +16,42 @@ require "spec_helper"
|
|
16
16
|
|
17
17
|
describe BSON::Int64 do
|
18
18
|
|
19
|
+
describe "#intiialize" do
|
20
|
+
|
21
|
+
let(:obj) { described_class.new(integer) }
|
22
|
+
|
23
|
+
context "when the integer is 64-bit" do
|
24
|
+
|
25
|
+
let(:integer) { Integer::MAX_64BIT - 1 }
|
26
|
+
|
27
|
+
it "wraps the integer" do
|
28
|
+
expect(obj.instance_variable_get(:@integer)).to be(integer)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when the integer is too large" do
|
33
|
+
|
34
|
+
let(:integer) { Integer::MAX_64BIT + 1 }
|
35
|
+
|
36
|
+
it "raises an out of range error" do
|
37
|
+
expect {
|
38
|
+
obj
|
39
|
+
}.to raise_error(RangeError)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when the integer is too small" do
|
44
|
+
|
45
|
+
let(:integer) { Integer::MIN_64BIT - 1 }
|
46
|
+
|
47
|
+
it "raises an out of range error" do
|
48
|
+
expect {
|
49
|
+
obj
|
50
|
+
}.to raise_error(RangeError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
19
55
|
describe "#from_bson" do
|
20
56
|
|
21
57
|
let(:type) { 18.chr }
|
@@ -25,4 +61,26 @@ describe BSON::Int64 do
|
|
25
61
|
it_behaves_like "a bson element"
|
26
62
|
it_behaves_like "a deserializable bson element"
|
27
63
|
end
|
64
|
+
|
65
|
+
describe "#to_bson" do
|
66
|
+
|
67
|
+
context "when the integer is 64 bit" do
|
68
|
+
|
69
|
+
let(:type) { 18.chr }
|
70
|
+
let(:obj) { BSON::Int64.new(Integer::MAX_64BIT - 1) }
|
71
|
+
let(:bson) { [ Integer::MAX_64BIT - 1 ].pack(BSON::Int64::PACK) }
|
72
|
+
|
73
|
+
it_behaves_like "a serializable bson element"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#to_bson_key" do
|
78
|
+
|
79
|
+
let(:obj) { BSON::Int64.new(Integer::MAX_64BIT - 1) }
|
80
|
+
let(:encoded) { (Integer::MAX_64BIT - 1).to_s }
|
81
|
+
|
82
|
+
it "returns the key as a string" do
|
83
|
+
expect(obj.to_bson_key).to eq(encoded)
|
84
|
+
end
|
85
|
+
end
|
28
86
|
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# Copyright (C) 2016 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
|
+
describe OpenStruct do
|
18
|
+
|
19
|
+
describe "#to_bson" do
|
20
|
+
|
21
|
+
let(:type) { 3.chr }
|
22
|
+
|
23
|
+
it_behaves_like "a bson element"
|
24
|
+
|
25
|
+
context "when the struct is a single level" do
|
26
|
+
|
27
|
+
let(:obj) do
|
28
|
+
described_class.new({"key" => "value" })
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:bson) do
|
32
|
+
"#{20.to_bson.to_s}#{String::BSON_TYPE}key#{BSON::NULL_BYTE}" +
|
33
|
+
"#{6.to_bson.to_s}value#{BSON::NULL_BYTE}#{BSON::NULL_BYTE}"
|
34
|
+
end
|
35
|
+
|
36
|
+
it_behaves_like "a serializable bson element"
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when the struct has invalid keys" do
|
40
|
+
|
41
|
+
let(:obj) do
|
42
|
+
described_class.new({ "$testing" => "value" })
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when validating keys" do
|
46
|
+
|
47
|
+
context "when validating globally" do
|
48
|
+
|
49
|
+
before do
|
50
|
+
BSON::Config.validating_keys = true
|
51
|
+
end
|
52
|
+
|
53
|
+
after do
|
54
|
+
BSON::Config.validating_keys = false
|
55
|
+
end
|
56
|
+
|
57
|
+
it "raises an error" do
|
58
|
+
expect {
|
59
|
+
obj.to_bson
|
60
|
+
}.to raise_error(BSON::String::IllegalKey)
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when the struct contains an array of documents containing invalid keys" do
|
64
|
+
|
65
|
+
let(:obj) do
|
66
|
+
described_class.new({ "array" => [{ "$testing" => "value" }] })
|
67
|
+
end
|
68
|
+
|
69
|
+
it "raises an error" do
|
70
|
+
expect {
|
71
|
+
obj.to_bson
|
72
|
+
}.to raise_error(BSON::String::IllegalKey)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when validating locally" do
|
78
|
+
|
79
|
+
it "raises an error" do
|
80
|
+
expect {
|
81
|
+
obj.to_bson(BSON::ByteBuffer.new, true)
|
82
|
+
}.to raise_error(BSON::String::IllegalKey)
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when the struct contains an array of documents containing invalid keys" do
|
86
|
+
|
87
|
+
let(:obj) do
|
88
|
+
described_class.new({ "array" => [{ "$testing" => "value" }] })
|
89
|
+
end
|
90
|
+
|
91
|
+
it "raises an error" do
|
92
|
+
expect {
|
93
|
+
obj.to_bson(BSON::ByteBuffer.new, true)
|
94
|
+
}.to raise_error(BSON::String::IllegalKey)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "when not validating keys" do
|
101
|
+
|
102
|
+
let(:bson) do
|
103
|
+
"#{25.to_bson.to_s}#{String::BSON_TYPE}$testing#{BSON::NULL_BYTE}" +
|
104
|
+
"#{6.to_bson.to_s}value#{BSON::NULL_BYTE}#{BSON::NULL_BYTE}"
|
105
|
+
end
|
106
|
+
|
107
|
+
it "serializes the struct" do
|
108
|
+
expect(obj.to_bson.to_s).to eq(bson)
|
109
|
+
end
|
110
|
+
|
111
|
+
context "when the struct contains an array of documents containing invalid keys" do
|
112
|
+
|
113
|
+
let(:obj) do
|
114
|
+
described_class.new({ "array" => [{ "$testing" => "value" }] })
|
115
|
+
end
|
116
|
+
|
117
|
+
let(:bson) do
|
118
|
+
"#{45.to_bson.to_s}#{Array::BSON_TYPE}array#{BSON::NULL_BYTE}" +
|
119
|
+
"#{[{ "$testing" => "value" }].to_bson.to_s}#{BSON::NULL_BYTE}"
|
120
|
+
end
|
121
|
+
|
122
|
+
it "serializes the struct" do
|
123
|
+
expect(obj.to_bson.to_s).to eq(bson)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "when the struct is embedded" do
|
130
|
+
|
131
|
+
let(:obj) do
|
132
|
+
described_class.new({ "field" => OpenStruct.new({ "key" => "value" })})
|
133
|
+
end
|
134
|
+
|
135
|
+
let(:bson) do
|
136
|
+
"#{32.to_bson.to_s}#{Hash::BSON_TYPE}field#{BSON::NULL_BYTE}" +
|
137
|
+
"#{20.to_bson.to_s}#{String::BSON_TYPE}key#{BSON::NULL_BYTE}" +
|
138
|
+
"#{6.to_bson.to_s}value#{BSON::NULL_BYTE}#{BSON::NULL_BYTE}#{BSON::NULL_BYTE}"
|
139
|
+
end
|
140
|
+
|
141
|
+
it_behaves_like "a serializable bson element"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,540 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Regexp::Raw do
|
4
|
+
|
5
|
+
let(:pattern) { '\W+' }
|
6
|
+
let(:options) { '' }
|
7
|
+
let(:bson) { "#{pattern}#{BSON::NULL_BYTE}#{options}#{BSON::NULL_BYTE}" }
|
8
|
+
|
9
|
+
describe "#as_json" do
|
10
|
+
|
11
|
+
let(:object) do
|
12
|
+
described_class.new(pattern, 'im')
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns the regex pattern and options" do
|
16
|
+
expect(object.as_json).to eq({ "$regex" => "\\W+", "$options" => "im" })
|
17
|
+
end
|
18
|
+
|
19
|
+
it_behaves_like "a JSON serializable object"
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#to_bson/#from_bson" do
|
23
|
+
|
24
|
+
let(:options) { 'ilmsux' }
|
25
|
+
let(:obj) { described_class.new(pattern, options) }
|
26
|
+
let(:type) { 11.chr }
|
27
|
+
let(:bson) { "#{pattern}#{BSON::NULL_BYTE}#{options}#{BSON::NULL_BYTE}" }
|
28
|
+
|
29
|
+
let(:klass) { ::Regexp }
|
30
|
+
|
31
|
+
it_behaves_like "a bson element"
|
32
|
+
it_behaves_like "a serializable bson element"
|
33
|
+
it_behaves_like "a deserializable bson element"
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#initialize" do
|
37
|
+
|
38
|
+
let(:object) do
|
39
|
+
described_class.new(pattern, options)
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when options are not passed" do
|
43
|
+
|
44
|
+
it "sets the options on the raw regex" do
|
45
|
+
expect(object.options). to eq(options)
|
46
|
+
end
|
47
|
+
|
48
|
+
context "When the raw regexp is compiled" do
|
49
|
+
|
50
|
+
let(:regexp) do
|
51
|
+
object.compile
|
52
|
+
end
|
53
|
+
|
54
|
+
it "sets the options on the compiled regexp object" do
|
55
|
+
expect(regexp.options).to eq(0)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when options are passed" do
|
61
|
+
|
62
|
+
context "when options are an Integer" do
|
63
|
+
|
64
|
+
let(:options) { ::Regexp::EXTENDED }
|
65
|
+
|
66
|
+
it "sets the options on the raw regex" do
|
67
|
+
expect(object.options). to eq(options)
|
68
|
+
end
|
69
|
+
|
70
|
+
context "When the raw regexp is compiled" do
|
71
|
+
|
72
|
+
let(:regexp) do
|
73
|
+
object.compile
|
74
|
+
end
|
75
|
+
|
76
|
+
it "sets the options on the compiled regexp object" do
|
77
|
+
expect(regexp.options).to eq(options)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "when options are a String" do
|
83
|
+
|
84
|
+
let(:options) { 'x' }
|
85
|
+
|
86
|
+
it "sets the options on the raw regex" do
|
87
|
+
expect(object.options). to eq(options)
|
88
|
+
end
|
89
|
+
|
90
|
+
context "When the raw regexp is compiled" do
|
91
|
+
|
92
|
+
let(:regexp) do
|
93
|
+
object.compile
|
94
|
+
end
|
95
|
+
|
96
|
+
it "sets the options on the compiled regexp object" do
|
97
|
+
expect(regexp.options).to eq(::Regexp::EXTENDED)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#from_bson" do
|
105
|
+
|
106
|
+
let(:obj) { ::Regexp.from_bson(io) }
|
107
|
+
let(:io) { BSON::ByteBuffer.new(bson) }
|
108
|
+
|
109
|
+
it "deserializes to a Regexp::Raw object" do
|
110
|
+
expect(obj).to be_a(Regexp::Raw)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "deserializes the pattern" do
|
114
|
+
expect(obj.pattern).to eq(pattern)
|
115
|
+
end
|
116
|
+
|
117
|
+
context "when there are no options" do
|
118
|
+
|
119
|
+
it "does not set any options on the raw regexp object" do
|
120
|
+
expect(obj.options).to eq(options)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "when there are options" do
|
125
|
+
|
126
|
+
context "when there is the i ignorecase option" do
|
127
|
+
|
128
|
+
let(:options) { 'i' }
|
129
|
+
|
130
|
+
it "deserializes the pattern" do
|
131
|
+
expect(obj.pattern).to eq(pattern)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "sets the i option on the raw regexp object" do
|
135
|
+
expect(obj.options).to eq(options)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "when there is the l locale dependent option" do
|
140
|
+
|
141
|
+
let(:options) { 'l' }
|
142
|
+
|
143
|
+
it "deserializes the pattern" do
|
144
|
+
expect(obj.pattern).to eq(pattern)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "sets the l option on the raw regexp object" do
|
148
|
+
expect(obj.options).to eq(options)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context "when there is the m multiline option" do
|
153
|
+
|
154
|
+
let(:options) { 'm' }
|
155
|
+
|
156
|
+
it "deserializes the pattern" do
|
157
|
+
expect(obj.pattern).to eq(pattern)
|
158
|
+
end
|
159
|
+
|
160
|
+
it "sets the m option on the raw regexp object" do
|
161
|
+
expect(obj.options).to eq(options)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context "when there is the s dotall option" do
|
166
|
+
|
167
|
+
let(:options) { 's' }
|
168
|
+
|
169
|
+
it "deserializes the pattern" do
|
170
|
+
expect(obj.pattern).to eq(pattern)
|
171
|
+
end
|
172
|
+
|
173
|
+
it "sets the s option on the raw regexp object" do
|
174
|
+
expect(obj.options).to eq(options)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context "when there is the u match unicode option" do
|
179
|
+
|
180
|
+
let(:options) { 'u' }
|
181
|
+
|
182
|
+
it "deserializes the pattern" do
|
183
|
+
expect(obj.pattern).to eq(pattern)
|
184
|
+
end
|
185
|
+
|
186
|
+
it "sets the u option on the raw regexp object" do
|
187
|
+
expect(obj.options).to eq(options)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context "when there is the x verbose option" do
|
192
|
+
|
193
|
+
let(:options) { 'x' }
|
194
|
+
|
195
|
+
it "deserializes the pattern" do
|
196
|
+
expect(obj.pattern).to eq(pattern)
|
197
|
+
end
|
198
|
+
|
199
|
+
it "sets the x option on the raw regexp object" do
|
200
|
+
expect(obj.options).to eq(options)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context "when all options are set" do
|
205
|
+
|
206
|
+
let(:options) { 'ilmsux' }
|
207
|
+
|
208
|
+
it "deserializes the pattern" do
|
209
|
+
expect(obj.pattern).to eq(pattern)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "sets all options on the raw regexp object" do
|
213
|
+
expect(obj.options).to eq(options)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context "when a method is called on a Raw regexp object" do
|
220
|
+
|
221
|
+
let(:obj) { ::Regexp.from_bson(io) }
|
222
|
+
let(:io) { BSON::ByteBuffer.new(bson) }
|
223
|
+
|
224
|
+
it "forwards the method call on to the compiled Ruby Regexp object" do
|
225
|
+
expect(obj.source).to eq(pattern)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context "when respond_to? is called on the Raw Regexp object" do
|
230
|
+
|
231
|
+
let(:obj) { Regexp::Raw.new(pattern, options) }
|
232
|
+
|
233
|
+
context "when include_private is false" do
|
234
|
+
|
235
|
+
it "does not consider private methods" do
|
236
|
+
expect(obj.respond_to?(:initialize_copy)).to eq(false)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
context "when include private is true" do
|
241
|
+
|
242
|
+
it "considers private methods" do
|
243
|
+
expect(obj.respond_to?(:initialize_copy, true)).to eq(true)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
context "when include_private is not specified" do
|
248
|
+
|
249
|
+
it "does not consider private methods" do
|
250
|
+
expect(obj.respond_to?(:initialize_copy)).to eq(false)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
context "#to_bson" do
|
256
|
+
|
257
|
+
let(:obj) { Regexp::Raw.new(pattern, options) }
|
258
|
+
let(:options) { '' }
|
259
|
+
let(:bson) { "#{pattern}#{BSON::NULL_BYTE}#{options}#{BSON::NULL_BYTE}" }
|
260
|
+
let(:serialized) { obj.to_bson.to_s }
|
261
|
+
|
262
|
+
it "serializes the pattern" do
|
263
|
+
expect(serialized).to eq(bson)
|
264
|
+
end
|
265
|
+
|
266
|
+
context "where there are no options" do
|
267
|
+
|
268
|
+
it "does not set any options on the bson regex object" do
|
269
|
+
expect(serialized).to eq(bson)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context "when there are options" do
|
274
|
+
|
275
|
+
context "when options are specified as an Integer" do
|
276
|
+
|
277
|
+
let(:options) { ::Regexp::EXTENDED }
|
278
|
+
let(:bson) { "#{pattern}#{BSON::NULL_BYTE}mx#{BSON::NULL_BYTE}" }
|
279
|
+
|
280
|
+
it "sets the option on the serialized bson object" do
|
281
|
+
expect(serialized).to eq(bson)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
context "when there is the i ignorecase option" do
|
286
|
+
|
287
|
+
let(:options) { 'i' }
|
288
|
+
|
289
|
+
it "sets the option on the serialized bson object" do
|
290
|
+
expect(serialized).to eq(bson)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
context "when there is the l locale dependent option" do
|
295
|
+
|
296
|
+
let(:options) { 'l' }
|
297
|
+
|
298
|
+
it "sets the option on the serialized bson object" do
|
299
|
+
expect(serialized).to eq(bson)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
context "when there is the m multiline option" do
|
304
|
+
|
305
|
+
let(:options) { 'm' }
|
306
|
+
|
307
|
+
it "sets the option on the serialized bson object" do
|
308
|
+
expect(serialized).to eq(bson)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
context "when there is the s dotall option" do
|
313
|
+
|
314
|
+
let(:options) { 's' }
|
315
|
+
|
316
|
+
it "sets the option on the serialized bson object" do
|
317
|
+
expect(serialized).to eq(bson)
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
context "when there is the u match unicode option" do
|
322
|
+
|
323
|
+
let(:options) { 'u' }
|
324
|
+
|
325
|
+
it "sets the option on the serialized bson object" do
|
326
|
+
expect(serialized).to eq(bson)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
context "when there is the x verbose option" do
|
331
|
+
|
332
|
+
let(:options) { 'x' }
|
333
|
+
|
334
|
+
it "sets the option on the serialized bson object" do
|
335
|
+
expect(serialized).to eq(bson)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
context "when all options are set" do
|
340
|
+
|
341
|
+
let(:options) { 'ilmsux' }
|
342
|
+
|
343
|
+
it "sets all options on the serialized bson object" do
|
344
|
+
expect(serialized).to eq(bson)
|
345
|
+
end
|
346
|
+
|
347
|
+
context "when the options are not provided in alphabetical order" do
|
348
|
+
|
349
|
+
let(:options) { 'mislxu' }
|
350
|
+
let(:bson) { "#{pattern}#{BSON::NULL_BYTE}ilmsux#{BSON::NULL_BYTE}" }
|
351
|
+
|
352
|
+
it "serializes the options in alphabetical order" do
|
353
|
+
expect(serialized).to eq(bson)
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
describe "#compile" do
|
361
|
+
|
362
|
+
let(:obj) { Regexp.from_bson(io) }
|
363
|
+
let(:io) { BSON::ByteBuffer.new(bson) }
|
364
|
+
let(:ruby_regexp) { obj.compile }
|
365
|
+
|
366
|
+
it "sets the pattern on the Ruby Regexp object" do
|
367
|
+
expect(obj.pattern).to eq(ruby_regexp.source)
|
368
|
+
end
|
369
|
+
|
370
|
+
context "when there are no options set" do
|
371
|
+
|
372
|
+
it "does not set any options on the Ruby Regexp object" do
|
373
|
+
expect(ruby_regexp.options).to eq(0)
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
context "when there are options set" do
|
378
|
+
|
379
|
+
context "when there is the i ignorecase option" do
|
380
|
+
|
381
|
+
let(:options) { 'i' }
|
382
|
+
|
383
|
+
it "sets the i option on the Ruby Regexp object" do
|
384
|
+
expect(ruby_regexp.options).to eq(::Regexp::IGNORECASE)
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
context "when there is the l locale dependent option" do
|
389
|
+
|
390
|
+
let(:options) { 'l' }
|
391
|
+
|
392
|
+
it "does not set an option on the Ruby Regexp object" do
|
393
|
+
expect(ruby_regexp.options).to eq(0)
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
context "when there is the m multiline option" do
|
398
|
+
|
399
|
+
let(:options) { 'm' }
|
400
|
+
|
401
|
+
it "does not set an option on the Ruby Regexp object" do
|
402
|
+
expect(ruby_regexp.options).to eq(0)
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
context "when there is the s dotall option" do
|
407
|
+
|
408
|
+
let(:options) { 's' }
|
409
|
+
|
410
|
+
# s in a bson regex maps to a Ruby Multiline Regexp option
|
411
|
+
it "sets the m option on the Ruby Regexp object" do
|
412
|
+
expect(ruby_regexp.options).to eq(::Regexp::MULTILINE)
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
context "when there is the u match unicode option" do
|
417
|
+
|
418
|
+
let(:options) { 'u' }
|
419
|
+
|
420
|
+
it "does not set an option on the Ruby Regexp object" do
|
421
|
+
expect(ruby_regexp.options).to eq(0)
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
context "when there is the x verbose option" do
|
426
|
+
|
427
|
+
let(:options) { 'x' }
|
428
|
+
|
429
|
+
it "sets the x option on the Ruby Regexp object" do
|
430
|
+
expect(ruby_regexp.options).to eq(::Regexp::EXTENDED)
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
context "when all options are set" do
|
435
|
+
|
436
|
+
let(:options) { 'ilmsux' }
|
437
|
+
|
438
|
+
# s in a bson regex maps to a Ruby Multiline Regexp option
|
439
|
+
it "sets the i, m, and x options on the Ruby Regexp object" do
|
440
|
+
expect(ruby_regexp.options).to eq(::Regexp::IGNORECASE | ::Regexp::MULTILINE | ::Regexp::EXTENDED)
|
441
|
+
end
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
context "when a Regexp::Raw object is roundtripped" do
|
447
|
+
|
448
|
+
let(:obj) { Regexp::Raw.new(pattern, options) }
|
449
|
+
let(:serialized) { obj.to_bson.to_s }
|
450
|
+
let(:roundtripped) { Regexp.from_bson(BSON::ByteBuffer.new(serialized)) }
|
451
|
+
|
452
|
+
it "roundtrips the pattern" do
|
453
|
+
expect(roundtripped.pattern).to eq(pattern)
|
454
|
+
end
|
455
|
+
|
456
|
+
context "when there are no options" do
|
457
|
+
|
458
|
+
let(:options) { '' }
|
459
|
+
|
460
|
+
it "does not set any options on the roundtripped Regexp::Raw object" do
|
461
|
+
expect(roundtripped.options).to eq(options)
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
context "when there are options set" do
|
466
|
+
|
467
|
+
context "when there is the i ignorecase option" do
|
468
|
+
|
469
|
+
let(:options) { 'i' }
|
470
|
+
|
471
|
+
it "sets the i option on the roundtripped Regexp::Raw object" do
|
472
|
+
expect(roundtripped.options).to eq(options)
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
context "when there is the l locale dependent option" do
|
477
|
+
|
478
|
+
let(:options) { 'l' }
|
479
|
+
|
480
|
+
it "sets the l option on the roundtripped Regexp::Raw object" do
|
481
|
+
expect(roundtripped.options).to eq(options)
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
485
|
+
context "when there is the m multiline option" do
|
486
|
+
|
487
|
+
let(:options) { 'm' }
|
488
|
+
|
489
|
+
it "sets the m option on the roundtripped Regexp::Raw object" do
|
490
|
+
expect(roundtripped.options).to eq(options)
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
context "when there is the s dotall option" do
|
495
|
+
|
496
|
+
let(:options) { 's' }
|
497
|
+
|
498
|
+
it "sets the s option on the roundtripped Regexp::Raw object" do
|
499
|
+
expect(roundtripped.options).to eq(options)
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
context "when there is the u match unicode option" do
|
504
|
+
|
505
|
+
let(:options) { 'u' }
|
506
|
+
|
507
|
+
it "sets the u option on the roundtripped Regexp::Raw object" do
|
508
|
+
expect(roundtripped.options).to eq(options)
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
context "when there is the x verbose option" do
|
513
|
+
|
514
|
+
let(:options) { 'x' }
|
515
|
+
|
516
|
+
it "sets the x option on the roundtripped Regexp::Raw object" do
|
517
|
+
expect(roundtripped.options).to eq(options)
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
521
|
+
context "when all options are set" do
|
522
|
+
|
523
|
+
let(:options) { 'ilmsux' }
|
524
|
+
|
525
|
+
it "sets all the options on the roundtripped Regexp::Raw object" do
|
526
|
+
expect(roundtripped.options).to eq(options)
|
527
|
+
end
|
528
|
+
|
529
|
+
context "when the options are passed in not in alphabetical order" do
|
530
|
+
|
531
|
+
let(:options) { 'sumlxi' }
|
532
|
+
|
533
|
+
it "sets all the options on the roundtripped Regexp::Raw object in order" do
|
534
|
+
expect(roundtripped.options).to eq(options.chars.sort.join)
|
535
|
+
end
|
536
|
+
end
|
537
|
+
end
|
538
|
+
end
|
539
|
+
end
|
540
|
+
end
|