mongoid 7.2.0 → 7.2.4
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/README.md +1 -1
- data/lib/mongoid/attributes.rb +8 -1
- data/lib/mongoid/criteria/queryable/selector.rb +0 -4
- data/lib/mongoid/document.rb +3 -2
- data/lib/mongoid/errors/mongoid_error.rb +1 -1
- data/lib/mongoid/interceptable.rb +3 -1
- data/lib/mongoid/matcher.rb +19 -43
- data/lib/mongoid/matcher/elem_match.rb +2 -1
- data/lib/mongoid/matcher/expression.rb +5 -14
- data/lib/mongoid/matcher/field_expression.rb +4 -5
- data/lib/mongoid/matcher/field_operator.rb +7 -11
- data/lib/mongoid/reloadable.rb +5 -0
- data/lib/mongoid/validatable/associated.rb +1 -1
- data/lib/mongoid/validatable/presence.rb +3 -3
- data/lib/mongoid/validatable/uniqueness.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
- data/spec/integration/app_spec.rb +174 -84
- data/spec/integration/callbacks_models.rb +49 -0
- data/spec/integration/callbacks_spec.rb +216 -0
- data/spec/integration/document_spec.rb +21 -0
- data/spec/integration/matcher_operator_data/elem_match.yml +46 -0
- data/spec/integration/matcher_operator_data/gt_types.yml +63 -0
- data/spec/integration/matcher_operator_data/gte_types.yml +15 -0
- data/spec/integration/matcher_operator_data/implicit_traversal.yml +96 -0
- data/spec/integration/matcher_operator_data/lt_types.yml +15 -0
- data/spec/integration/matcher_operator_data/lte_types.yml +15 -0
- data/spec/integration/matcher_operator_data/ne_types.yml +15 -0
- data/spec/lite_spec_helper.rb +3 -4
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +50 -0
- data/spec/mongoid/atomic/paths_spec.rb +41 -0
- data/spec/mongoid/attributes_spec.rb +241 -0
- data/spec/mongoid/contextual/atomic_spec.rb +17 -4
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +36 -0
- data/spec/mongoid/document_fields_spec.rb +26 -0
- data/spec/mongoid/document_query_spec.rb +51 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +20 -8
- data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
- data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +68 -88
- data/spec/mongoid/matcher/extract_attribute_spec.rb +3 -13
- data/spec/mongoid/persistable/settable_spec.rb +30 -0
- data/spec/mongoid/persistable_spec.rb +2 -2
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/cluster_config.rb +226 -0
- data/spec/shared/lib/mrss/constraints.rb +71 -6
- data/spec/shared/lib/mrss/docker_runner.rb +271 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +115 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +32 -2
- data/spec/shared/lib/mrss/utils.rb +15 -0
- data/spec/shared/share/Dockerfile.erb +322 -0
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/distro.sh +73 -0
- data/spec/shared/shlib/server.sh +317 -0
- data/spec/shared/shlib/set_env.sh +131 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/models/customer.rb +11 -0
- data/spec/support/models/customer_address.rb +12 -0
- data/spec/support/models/dictionary.rb +6 -0
- data/spec/support/models/mop.rb +10 -0
- data/spec/support/spec_config.rb +8 -0
- metadata +554 -508
- metadata.gz.sig +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5841b5911599ef45f1b350592ec4995d2a044e723b14ef03e16cf7508449d396
|
4
|
+
data.tar.gz: c6276353b2e03f57c166c96f7bbcee0362a391f91e19c294a7c76a3c3dad3fe6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 277666610a79f335d47add6f4fb24ecb4a47ea6a245f7d28cec43258876ba469463460a98a1eeeeee5f200a5ab58ed6da7c81dec3be9d617d5ba970194949e09
|
7
|
+
data.tar.gz: a564a89c548c566a230d03ad69f6323280c071a04f3754f7a2abdeb1da883a4fa6856e7b9e091fdfb0325017f160eb81c875169da54bc04c865e2499f4cd31e9
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
data/lib/mongoid/attributes.rb
CHANGED
@@ -160,6 +160,11 @@ module Mongoid
|
|
160
160
|
# @since 1.0.0
|
161
161
|
def write_attribute(name, value)
|
162
162
|
field_name = database_field_name(name)
|
163
|
+
|
164
|
+
if attribute_missing?(field_name)
|
165
|
+
raise ActiveModel::MissingAttributeError, "Missing attribute: '#{name}'"
|
166
|
+
end
|
167
|
+
|
163
168
|
if attribute_writable?(field_name)
|
164
169
|
_assigning do
|
165
170
|
validate_attribute_value(field_name, value)
|
@@ -177,6 +182,8 @@ module Mongoid
|
|
177
182
|
end
|
178
183
|
typed_value
|
179
184
|
end
|
185
|
+
else
|
186
|
+
# TODO: MONGOID-5072
|
180
187
|
end
|
181
188
|
end
|
182
189
|
alias :[]= :write_attribute
|
@@ -294,7 +301,7 @@ module Mongoid
|
|
294
301
|
def read_raw_attribute(name)
|
295
302
|
normalized = database_field_name(name.to_s)
|
296
303
|
if attribute_missing?(normalized)
|
297
|
-
raise ActiveModel::MissingAttributeError, "Missing attribute: '#{name}'
|
304
|
+
raise ActiveModel::MissingAttributeError, "Missing attribute: '#{name}'"
|
298
305
|
end
|
299
306
|
if hash_dot_syntax?(normalized)
|
300
307
|
attributes.__nested__(normalized)
|
@@ -123,10 +123,6 @@ module Mongoid
|
|
123
123
|
# {'foo' => {'$lt' => 5}}. This step should be done after all
|
124
124
|
# value-based processing is complete.
|
125
125
|
if key.is_a?(Key)
|
126
|
-
if serializer && evolved_value != value
|
127
|
-
raise NotImplementedError, "This method is not prepared to handle key being a Key and serializer being not nil"
|
128
|
-
end
|
129
|
-
|
130
126
|
evolved_value = key.transform_value(evolved_value)
|
131
127
|
end
|
132
128
|
|
data/lib/mongoid/document.rb
CHANGED
@@ -229,8 +229,9 @@ module Mongoid
|
|
229
229
|
became = klass.new(clone_document)
|
230
230
|
became._id = _id
|
231
231
|
became.instance_variable_set(:@changed_attributes, changed_attributes)
|
232
|
-
|
233
|
-
|
232
|
+
new_errors = ActiveModel::Errors.new(became)
|
233
|
+
new_errors.copy!(errors)
|
234
|
+
became.instance_variable_set(:@errors, new_errors)
|
234
235
|
became.instance_variable_set(:@new_record, new_record?)
|
235
236
|
became.instance_variable_set(:@destroyed, destroyed?)
|
236
237
|
became.changed_attributes[klass.discriminator_key] = self.class.discriminator_value
|
@@ -234,9 +234,11 @@ module Mongoid
|
|
234
234
|
# document.halted_callback_hook(filter)
|
235
235
|
#
|
236
236
|
# @param [ Symbol ] filter The callback that halted.
|
237
|
+
# @param [ Symbol ] name The name of the callback that was halted
|
238
|
+
# (requires Rails 6.1+)
|
237
239
|
#
|
238
240
|
# @since 3.0.3
|
239
|
-
def halted_callback_hook(filter)
|
241
|
+
def halted_callback_hook(filter, name = nil)
|
240
242
|
@before_callback_halted = true
|
241
243
|
end
|
242
244
|
|
data/lib/mongoid/matcher.rb
CHANGED
@@ -43,60 +43,36 @@ module Mongoid
|
|
43
43
|
document = BSON::Document.new(document.send(:as_attributes))
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
|
-
expanded = false
|
48
|
-
exists = true
|
46
|
+
current = [document]
|
49
47
|
|
50
48
|
key.to_s.split('.').each do |field|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
exists = index < src.length
|
55
|
-
src = src[index]
|
56
|
-
else
|
57
|
-
# Trying to index something that is not an array
|
58
|
-
exists = false
|
59
|
-
src = nil
|
60
|
-
end
|
61
|
-
else
|
62
|
-
case src
|
63
|
-
when nil
|
64
|
-
exists = false
|
49
|
+
new = []
|
50
|
+
current.each do |doc|
|
51
|
+
case doc
|
65
52
|
when Hash
|
66
|
-
|
67
|
-
|
53
|
+
if doc.key?(field)
|
54
|
+
new << doc[field]
|
55
|
+
end
|
68
56
|
when Array
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
when Array
|
79
|
-
new += v
|
80
|
-
else
|
81
|
-
new += [v]
|
82
|
-
end
|
83
|
-
exists = true
|
57
|
+
if (index = field.to_i).to_s == field
|
58
|
+
if doc.length > index
|
59
|
+
new << doc[index]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
doc.each do |subdoc|
|
63
|
+
if Hash === subdoc
|
64
|
+
if subdoc.key?(field)
|
65
|
+
new << subdoc[field]
|
84
66
|
end
|
85
|
-
else
|
86
|
-
# Trying to hash index into a value that is not a hash
|
87
67
|
end
|
88
68
|
end
|
89
|
-
src = new
|
90
|
-
else
|
91
|
-
# Trying to descend into a field that is not a hash using
|
92
|
-
# dot notation.
|
93
|
-
exists = false
|
94
|
-
src = nil
|
95
69
|
end
|
96
70
|
end
|
71
|
+
current = new
|
72
|
+
break if current.empty?
|
97
73
|
end
|
98
74
|
|
99
|
-
|
75
|
+
current
|
100
76
|
end
|
101
77
|
end
|
102
78
|
end
|
@@ -15,7 +15,8 @@ module Mongoid
|
|
15
15
|
# Validate the condition is valid, even though we will never attempt
|
16
16
|
# matching it.
|
17
17
|
condition.each do |k, v|
|
18
|
-
|
18
|
+
k = k.to_s
|
19
|
+
if k.start_with?('$')
|
19
20
|
begin
|
20
21
|
ExpressionOperator.get(k)
|
21
22
|
rescue Mongoid::Errors::InvalidExpressionOperator
|
@@ -15,22 +15,13 @@ module Mongoid
|
|
15
15
|
if k.start_with?('$')
|
16
16
|
ExpressionOperator.get(k).matches?(document, expr_v)
|
17
17
|
else
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
# Do not treat a hash as an array here (both are iterable).
|
23
|
-
if expanded && Array === value
|
24
|
-
if value == []
|
25
|
-
# Empty array is technically equivalent to exists: false.
|
26
|
-
FieldExpression.matches?(false, nil, expr_v)
|
27
|
-
else
|
28
|
-
value.any? do |v|
|
29
|
-
FieldExpression.matches?(true, v, expr_v)
|
30
|
-
end
|
18
|
+
values = Matcher.extract_attribute(document, k)
|
19
|
+
if values.length > 0
|
20
|
+
values.any? do |v|
|
21
|
+
FieldExpression.matches?(true, v, expr_v)
|
31
22
|
end
|
32
23
|
else
|
33
|
-
FieldExpression.matches?(
|
24
|
+
FieldExpression.matches?(false, nil, expr_v)
|
34
25
|
end
|
35
26
|
end
|
36
27
|
end
|
@@ -36,14 +36,13 @@ module Mongoid
|
|
36
36
|
FieldOperator.get(k).matches?(exists, value, cond_v)
|
37
37
|
end
|
38
38
|
elsif Hash === value
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
sub_value.any? do |sub_v|
|
39
|
+
sub_values = Matcher.extract_attribute(value, k)
|
40
|
+
if sub_values.length > 0
|
41
|
+
sub_values.any? do |sub_v|
|
43
42
|
Eq.matches?(true, sub_v, cond_v)
|
44
43
|
end
|
45
44
|
else
|
46
|
-
Eq.matches?(
|
45
|
+
Eq.matches?(false, nil, cond_v)
|
47
46
|
end
|
48
47
|
else
|
49
48
|
false
|
@@ -35,17 +35,13 @@ module Mongoid
|
|
35
35
|
end
|
36
36
|
|
37
37
|
module_function def apply_comparison_operator(operator, left, right)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
else
|
47
|
-
false
|
48
|
-
end
|
38
|
+
left.send(operator, right)
|
39
|
+
rescue ArgumentError, NoMethodError, TypeError
|
40
|
+
# We silence bogus comparison attempts, e.g. number to string
|
41
|
+
# comparisons.
|
42
|
+
# Several different exceptions may be produced depending on the types
|
43
|
+
# involved.
|
44
|
+
false
|
49
45
|
end
|
50
46
|
end
|
51
47
|
end
|
data/lib/mongoid/reloadable.rb
CHANGED
@@ -21,6 +21,11 @@ module Mongoid
|
|
21
21
|
#
|
22
22
|
# @since 1.0.0
|
23
23
|
def reload
|
24
|
+
if @atomic_selector
|
25
|
+
# Clear atomic_selector cache for sharded clusters. MONGOID-5076
|
26
|
+
remove_instance_variable('@atomic_selector')
|
27
|
+
end
|
28
|
+
|
24
29
|
reloaded = _reload
|
25
30
|
if Mongoid.raise_not_found_error && reloaded.empty?
|
26
31
|
raise Errors::DocumentNotFound.new(self.class, _id, _id)
|
@@ -34,15 +34,15 @@ module Mongoid
|
|
34
34
|
document.errors.add(
|
35
35
|
attribute,
|
36
36
|
:blank_in_locale,
|
37
|
-
options.merge(location: _locale)
|
37
|
+
**options.merge(location: _locale)
|
38
38
|
) if not_present?(_value)
|
39
39
|
end
|
40
40
|
elsif document.relations.has_key?(attribute.to_s)
|
41
41
|
if relation_or_fk_missing?(document, attribute, value)
|
42
|
-
document.errors.add(attribute, :blank, options)
|
42
|
+
document.errors.add(attribute, :blank, **options)
|
43
43
|
end
|
44
44
|
else
|
45
|
-
document.errors.add(attribute, :blank, options) if not_present?(value)
|
45
|
+
document.errors.add(attribute, :blank, **options) if not_present?(value)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -68,7 +68,7 @@ module Mongoid
|
|
68
68
|
# @since 2.4.10
|
69
69
|
def add_error(document, attribute, value)
|
70
70
|
document.errors.add(
|
71
|
-
attribute, :taken, options.except(:case_sensitive, :scope).merge(value: value)
|
71
|
+
attribute, :taken, **options.except(:case_sensitive, :scope).merge(value: value)
|
72
72
|
)
|
73
73
|
end
|
74
74
|
|
data/lib/mongoid/version.rb
CHANGED
@@ -15,7 +15,14 @@ module Mongoid
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def app_name
|
18
|
-
Rails
|
18
|
+
app_cls = Rails.application.class
|
19
|
+
parent = begin
|
20
|
+
# Rails 6.1+
|
21
|
+
app_cls.module_parent_name
|
22
|
+
rescue NoMethodError
|
23
|
+
app_cls.parent.to_s
|
24
|
+
end
|
25
|
+
parent.underscore
|
19
26
|
end
|
20
27
|
|
21
28
|
def create_config_file
|
@@ -57,7 +57,7 @@ development:
|
|
57
57
|
# connect: :direct
|
58
58
|
|
59
59
|
# Changes the default time in seconds the server monitors refresh their status
|
60
|
-
# via
|
60
|
+
# via hello commands. (default: 10)
|
61
61
|
# heartbeat_frequency: 10
|
62
62
|
|
63
63
|
# The time in seconds for selecting servers for a near read preference. (default: 0.015)
|
@@ -19,103 +19,125 @@ describe 'Mongoid application tests' do
|
|
19
19
|
FileUtils.mkdir_p(TMP_BASE)
|
20
20
|
end
|
21
21
|
|
22
|
-
context 'demo application
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
process.environment.update(clean_env)
|
31
|
-
process.io.inherit!
|
32
|
-
process.start
|
33
|
-
|
34
|
-
begin
|
22
|
+
context 'demo application' do
|
23
|
+
context 'sinatra' do
|
24
|
+
it 'runs' do
|
25
|
+
clone_application(
|
26
|
+
'https://github.com/mongoid/mongoid-demo',
|
27
|
+
subdir: 'sinatra-minimal',
|
28
|
+
) do
|
29
|
+
|
35
30
|
# JRuby needs a long timeout
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
uri = URI.parse('http://localhost:4567/posts')
|
40
|
-
resp = JSON.parse(uri.open.read)
|
41
|
-
ensure
|
42
|
-
Process.kill('TERM', process.pid)
|
43
|
-
status = process.wait
|
44
|
-
end
|
31
|
+
start_app(%w(bundle exec ruby app.rb), 4567, 40) do |port|
|
32
|
+
uri = URI.parse('http://localhost:4567/posts')
|
33
|
+
resp = JSON.parse(uri.open.read)
|
45
34
|
|
46
|
-
|
35
|
+
resp.should == []
|
47
36
|
|
48
|
-
|
37
|
+
end
|
38
|
+
end
|
49
39
|
end
|
50
40
|
end
|
51
|
-
end
|
52
41
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
subdir: 'rails-api',
|
60
|
-
rails_version: rails_version,
|
61
|
-
) do
|
62
|
-
|
63
|
-
process = ChildProcess.build(*%w(bundle exec rails s))
|
64
|
-
process.environment.update(clean_env)
|
65
|
-
process.io.inherit!
|
66
|
-
process.start
|
67
|
-
|
68
|
-
begin
|
69
|
-
# JRuby needs a long timeout
|
70
|
-
wait_for_port(3000, 30)
|
71
|
-
sleep 1
|
72
|
-
|
73
|
-
uri = URI.parse('http://localhost:3000/posts')
|
74
|
-
resp = JSON.parse(uri.open.read)
|
75
|
-
ensure
|
76
|
-
Process.kill('TERM', process.pid)
|
77
|
-
status = process.wait
|
78
|
-
end
|
42
|
+
context 'rails-api' do
|
43
|
+
it 'runs' do
|
44
|
+
clone_application(
|
45
|
+
'https://github.com/mongoid/mongoid-demo',
|
46
|
+
subdir: 'rails-api',
|
47
|
+
) do
|
79
48
|
|
80
|
-
|
49
|
+
# JRuby needs a long timeout
|
50
|
+
start_app(%w(bundle exec rails s), 3000, 50) do |port|
|
51
|
+
uri = URI.parse('http://localhost:3000/posts')
|
52
|
+
resp = JSON.parse(uri.open.read)
|
81
53
|
|
82
|
-
|
83
|
-
[0, 15, 143].should include(status)
|
54
|
+
resp.should == []
|
84
55
|
end
|
85
56
|
end
|
86
57
|
end
|
87
58
|
end
|
88
59
|
end
|
89
60
|
|
61
|
+
def start_app(cmd, port, timeout)
|
62
|
+
process = ChildProcess.build(*cmd)
|
63
|
+
process.environment.update(clean_env)
|
64
|
+
process.io.inherit!
|
65
|
+
process.start
|
66
|
+
|
67
|
+
begin
|
68
|
+
wait_for_port(port, timeout, process)
|
69
|
+
sleep 1
|
70
|
+
|
71
|
+
rv = yield port
|
72
|
+
ensure
|
73
|
+
# The process may have already died (due to an error exit) -
|
74
|
+
# in this case killing it will raise an exception.
|
75
|
+
Process.kill('TERM', process.pid) rescue nil
|
76
|
+
status = process.wait
|
77
|
+
end
|
78
|
+
|
79
|
+
# Exit should be either success or SIGTERM
|
80
|
+
[0, 15, 128 + 15].should include(status)
|
81
|
+
|
82
|
+
rv
|
83
|
+
end
|
84
|
+
|
90
85
|
context 'new application - rails' do
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
86
|
+
it 'creates' do
|
87
|
+
install_rails
|
88
|
+
|
89
|
+
Dir.chdir(TMP_BASE) do
|
90
|
+
FileUtils.rm_rf('mongoid-test')
|
91
|
+
Mrss::ChildProcessHelper.check_call(%w(rails new mongoid-test --skip-spring --skip-active-record), env: clean_env)
|
92
|
+
|
93
|
+
Dir.chdir('mongoid-test') do
|
94
|
+
adjust_app_gemfile
|
95
|
+
Mrss::ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
|
96
|
+
|
97
|
+
Mrss::ChildProcessHelper.check_call(%w(rails g model post), env: clean_env)
|
98
|
+
Mrss::ChildProcessHelper.check_call(%w(rails g model comment post:belongs_to), env: clean_env)
|
99
|
+
|
100
|
+
# https://jira.mongodb.org/browse/MONGOID-4885
|
101
|
+
comment_text = File.read('app/models/comment.rb')
|
102
|
+
comment_text.should =~ /belongs_to :post/
|
103
|
+
comment_text.should_not =~ /embedded_in :post/
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'generates Mongoid config' do
|
109
|
+
install_rails
|
110
|
+
|
111
|
+
Dir.chdir(TMP_BASE) do
|
112
|
+
FileUtils.rm_rf('mongoid-test-config')
|
113
|
+
Mrss::ChildProcessHelper.check_call(%w(rails new mongoid-test-config --skip-spring --skip-active-record), env: clean_env)
|
114
|
+
|
115
|
+
Dir.chdir('mongoid-test-config') do
|
116
|
+
adjust_app_gemfile
|
117
|
+
Mrss::ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
|
118
|
+
|
119
|
+
mongoid_config_file = File.join(TMP_BASE,'mongoid-test-config/config/mongoid.yml')
|
120
|
+
|
121
|
+
File.exist?(mongoid_config_file).should be false
|
122
|
+
Mrss::ChildProcessHelper.check_call(%w(rails g mongoid:config), env: clean_env)
|
123
|
+
File.exist?(mongoid_config_file).should be true
|
124
|
+
|
125
|
+
config_text = File.read(mongoid_config_file)
|
126
|
+
config_text.should =~ /mongoid_test_config_development/
|
127
|
+
config_text.should =~ /mongoid_test_config_test/
|
114
128
|
end
|
115
129
|
end
|
116
130
|
end
|
117
131
|
end
|
118
132
|
|
133
|
+
def install_rails
|
134
|
+
Mrss::ChildProcessHelper.check_call(%w(gem uni rails -a))
|
135
|
+
if (rails_version = SpecConfig.instance.rails_version) == 'master'
|
136
|
+
else
|
137
|
+
Mrss::ChildProcessHelper.check_call(%w(gem install rails --no-document -v) + [rails_version])
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
119
141
|
context 'local test applications' do
|
120
142
|
let(:client) { Mongoid.default_client }
|
121
143
|
|
@@ -150,7 +172,7 @@ describe 'Mongoid application tests' do
|
|
150
172
|
end
|
151
173
|
index.should be nil
|
152
174
|
|
153
|
-
Mrss::ChildProcessHelper.check_call(%w(rake db:mongoid:create_indexes),
|
175
|
+
Mrss::ChildProcessHelper.check_call(%w(bundle exec rake db:mongoid:create_indexes),
|
154
176
|
cwd: APP_PATH, env: env)
|
155
177
|
|
156
178
|
index = client['posts'].indexes.detect do |index|
|
@@ -165,12 +187,13 @@ describe 'Mongoid application tests' do
|
|
165
187
|
end
|
166
188
|
end
|
167
189
|
|
168
|
-
def clone_application(repo_url, subdir: nil
|
190
|
+
def clone_application(repo_url, subdir: nil)
|
169
191
|
Dir.chdir(TMP_BASE) do
|
170
192
|
FileUtils.rm_rf(File.basename(repo_url))
|
171
193
|
Mrss::ChildProcessHelper.check_call(%w(git clone) + [repo_url])
|
172
194
|
Dir.chdir(File.join(*[File.basename(repo_url), subdir].compact)) do
|
173
|
-
adjust_app_gemfile
|
195
|
+
adjust_app_gemfile
|
196
|
+
adjust_rails_defaults
|
174
197
|
Mrss::ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
|
175
198
|
puts `git diff`
|
176
199
|
|
@@ -181,11 +204,44 @@ describe 'Mongoid application tests' do
|
|
181
204
|
end
|
182
205
|
end
|
183
206
|
|
207
|
+
def parse_mongodb_uri(uri)
|
208
|
+
pre, query = uri.split('?', 2)
|
209
|
+
if pre =~ %r,\A(mongodb(?:.*?))://([^/]+)(?:/(.*))?\z,
|
210
|
+
protocol = $1
|
211
|
+
hosts = $2
|
212
|
+
database = $3
|
213
|
+
if database == ''
|
214
|
+
database = nil
|
215
|
+
end
|
216
|
+
else
|
217
|
+
raise ArgumentError, "Invalid MongoDB URI: #{uri}"
|
218
|
+
end
|
219
|
+
if query == ''
|
220
|
+
query = nil
|
221
|
+
end
|
222
|
+
{
|
223
|
+
protocol: protocol,
|
224
|
+
hosts: hosts,
|
225
|
+
database: database,
|
226
|
+
query: query,
|
227
|
+
}
|
228
|
+
end
|
229
|
+
|
230
|
+
def build_mongodb_uri(parts)
|
231
|
+
"#{parts.fetch(:protocol)}://#{parts.fetch(:hosts)}/#{parts[:database]}?#{parts[:query]}"
|
232
|
+
end
|
233
|
+
|
184
234
|
def write_mongoid_yml
|
235
|
+
# HACK: the driver does not provide a MongoDB URI parser and assembler,
|
236
|
+
# and the Ruby standard library URI module doesn't handle multiple hosts.
|
237
|
+
parts = parse_mongodb_uri(SpecConfig.instance.uri_str)
|
238
|
+
parts[:database] = 'mongoid_test'
|
239
|
+
uri = build_mongodb_uri(parts)
|
240
|
+
p uri
|
185
241
|
env_config = {'clients' => {'default' => {
|
186
242
|
# TODO massive hack, will fail if uri specifies a database name or
|
187
243
|
# any uri options
|
188
|
-
'uri' =>
|
244
|
+
'uri' => uri,
|
189
245
|
}}}
|
190
246
|
config = {'development' => env_config, 'production' => env_config}
|
191
247
|
File.open('config/mongoid.yml', 'w') do |f|
|
@@ -193,7 +249,7 @@ describe 'Mongoid application tests' do
|
|
193
249
|
end
|
194
250
|
end
|
195
251
|
|
196
|
-
def adjust_app_gemfile(rails_version:
|
252
|
+
def adjust_app_gemfile(rails_version: SpecConfig.instance.rails_version)
|
197
253
|
remove_bundler_req
|
198
254
|
|
199
255
|
gemfile_lines = IO.readlines('Gemfile')
|
@@ -205,14 +261,45 @@ describe 'Mongoid application tests' do
|
|
205
261
|
gemfile_lines.delete_if do |line|
|
206
262
|
line =~ /rails/
|
207
263
|
end
|
208
|
-
|
264
|
+
if rails_version == 'master'
|
265
|
+
gemfile_lines << "gem 'rails', git: 'https://github.com/rails/rails'\n"
|
266
|
+
else
|
267
|
+
gemfile_lines << "gem 'rails', '~> #{rails_version}.0'\n"
|
268
|
+
end
|
209
269
|
end
|
210
270
|
File.open('Gemfile', 'w') do |f|
|
211
271
|
f << gemfile_lines.join
|
212
272
|
end
|
213
273
|
end
|
214
274
|
|
275
|
+
def adjust_rails_defaults(rails_version: SpecConfig.instance.rails_version)
|
276
|
+
if File.exist?('config/application.rb')
|
277
|
+
lines = IO.readlines('config/application.rb')
|
278
|
+
lines.each do |line|
|
279
|
+
line.gsub!(/config.load_defaults \d\.\d/, "config.load_defaults #{rails_version}")
|
280
|
+
end
|
281
|
+
File.open('config/application.rb', 'w') do |f|
|
282
|
+
f << lines.join
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
if rails_version == '5.1'
|
287
|
+
secrets = {
|
288
|
+
'development' => {
|
289
|
+
'secret_key_base' => 'abracadabra',
|
290
|
+
'my_secret_token' => 'very_secret',
|
291
|
+
},
|
292
|
+
}
|
293
|
+
File.open('config/secrets.yml', 'w') do |f|
|
294
|
+
f << YAML.dump(secrets)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
215
299
|
def remove_bundler_req
|
300
|
+
return unless File.file?('Gemfile.lock')
|
301
|
+
# TODO: Remove this method completely when we get rid of .lock files in
|
302
|
+
# mongoid-demo apps.
|
216
303
|
lock_lines = IO.readlines('Gemfile.lock')
|
217
304
|
# Get rid of the bundled with line so that whatever bundler is installed
|
218
305
|
# on the system is usable with the application.
|
@@ -237,7 +324,7 @@ describe 'Mongoid application tests' do
|
|
237
324
|
@clean_env ||= Hash[ENV.keys.grep(/BUNDLE|RUBYOPT/).map { |k| [k, nil ] }]
|
238
325
|
end
|
239
326
|
|
240
|
-
def wait_for_port(port, timeout)
|
327
|
+
def wait_for_port(port, timeout, process)
|
241
328
|
deadline = Time.now + timeout
|
242
329
|
loop do
|
243
330
|
begin
|
@@ -245,6 +332,9 @@ describe 'Mongoid application tests' do
|
|
245
332
|
return
|
246
333
|
end
|
247
334
|
rescue IOError, SystemCallError
|
335
|
+
unless process.alive?
|
336
|
+
raise "Process #{process} died while waiting for port #{port}"
|
337
|
+
end
|
248
338
|
if Time.now > deadline
|
249
339
|
raise
|
250
340
|
end
|