bson 4.1.1-java → 4.2.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +18 -3
  5. data/lib/bson-ruby.jar +0 -0
  6. data/lib/bson.rb +6 -4
  7. data/lib/bson/array.rb +1 -1
  8. data/lib/bson/binary.rb +4 -2
  9. data/lib/bson/code.rb +1 -1
  10. data/lib/bson/code_with_scope.rb +1 -1
  11. data/lib/bson/config.rb +1 -1
  12. data/lib/bson/date.rb +1 -1
  13. data/lib/bson/date_time.rb +1 -1
  14. data/lib/bson/decimal128.rb +318 -0
  15. data/lib/bson/decimal128/builder.rb +448 -0
  16. data/lib/bson/document.rb +2 -2
  17. data/lib/bson/environment.rb +13 -1
  18. data/lib/bson/false_class.rb +1 -1
  19. data/lib/bson/float.rb +1 -1
  20. data/lib/bson/hash.rb +1 -1
  21. data/lib/bson/int32.rb +46 -0
  22. data/lib/bson/int64.rb +46 -0
  23. data/lib/bson/integer.rb +1 -1
  24. data/lib/bson/max_key.rb +1 -1
  25. data/lib/bson/min_key.rb +1 -1
  26. data/lib/bson/object_id.rb +3 -2
  27. data/lib/bson/open_struct.rb +57 -0
  28. data/lib/bson/regexp.rb +87 -19
  29. data/lib/bson/registry.rb +1 -1
  30. data/lib/bson/specialized.rb +1 -1
  31. data/lib/bson/string.rb +1 -1
  32. data/lib/bson/symbol.rb +1 -1
  33. data/lib/bson/time.rb +1 -1
  34. data/lib/bson/timestamp.rb +2 -2
  35. data/lib/bson/true_class.rb +1 -1
  36. data/lib/bson/version.rb +2 -2
  37. data/spec/bson/array_spec.rb +1 -1
  38. data/spec/bson/binary_spec.rb +2 -1
  39. data/spec/bson/corpus_spec.rb +68 -0
  40. data/spec/bson/decimal128_spec.rb +1583 -0
  41. data/spec/bson/document_spec.rb +1 -1
  42. data/spec/bson/driver_bson_spec.rb +77 -0
  43. data/spec/bson/int32_spec.rb +58 -0
  44. data/spec/bson/int64_spec.rb +58 -0
  45. data/spec/bson/open_struct_spec.rb +144 -0
  46. data/spec/bson/raw_spec.rb +540 -0
  47. data/spec/bson/regexp_spec.rb +7 -7
  48. data/spec/bson/timestamp_spec.rb +1 -1
  49. data/spec/spec_helper.rb +5 -0
  50. data/spec/support/common_driver.rb +347 -0
  51. data/spec/support/corpus-tests/array.json +43 -0
  52. data/spec/support/corpus-tests/boolean.json +27 -0
  53. data/spec/support/corpus-tests/code.json +67 -0
  54. data/spec/support/corpus-tests/code_w_scope.json +78 -0
  55. data/spec/support/corpus-tests/document.json +36 -0
  56. data/spec/support/corpus-tests/double.json +69 -0
  57. data/spec/support/corpus-tests/failures/binary.json +69 -0
  58. data/spec/support/corpus-tests/failures/datetime.json +31 -0
  59. data/spec/support/corpus-tests/failures/dbpointer.json +42 -0
  60. data/spec/support/corpus-tests/failures/int64.json +38 -0
  61. data/spec/support/corpus-tests/failures/symbol.json +62 -0
  62. data/spec/support/corpus-tests/failures/undefined.json +13 -0
  63. data/spec/support/corpus-tests/int32.json +38 -0
  64. data/spec/support/corpus-tests/maxkey.json +12 -0
  65. data/spec/support/corpus-tests/minkey.json +12 -0
  66. data/spec/support/corpus-tests/null.json +12 -0
  67. data/spec/support/corpus-tests/oid.json +28 -0
  68. data/spec/support/corpus-tests/regex.json +37 -0
  69. data/spec/support/corpus-tests/string.json +67 -0
  70. data/spec/support/corpus-tests/timestamp.json +18 -0
  71. data/spec/support/corpus-tests/top.json +62 -0
  72. data/spec/support/corpus.rb +265 -0
  73. data/spec/support/driver-spec-tests/decimal128/decimal128-1.json +363 -0
  74. data/spec/support/driver-spec-tests/decimal128/decimal128-2.json +793 -0
  75. data/spec/support/driver-spec-tests/decimal128/decimal128-3.json +1771 -0
  76. data/spec/support/driver-spec-tests/decimal128/decimal128-4.json +165 -0
  77. data/spec/support/driver-spec-tests/decimal128/decimal128-5.json +402 -0
  78. data/spec/support/driver-spec-tests/decimal128/decimal128-6.json +131 -0
  79. data/spec/support/driver-spec-tests/decimal128/decimal128-7.json +327 -0
  80. data/spec/support/shared_examples.rb +1 -1
  81. metadata +77 -4
  82. metadata.gz.sig +0 -0
@@ -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 !~ /9.0/) do
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
@@ -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
@@ -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