mongoid 7.2.1 → 7.3.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +1 -1
- data/Rakefile +16 -0
- data/lib/config/locales/en.yml +2 -2
- data/lib/mongoid/association/accessors.rb +13 -1
- data/lib/mongoid/association/constrainable.rb +1 -1
- data/lib/mongoid/association/depending.rb +4 -4
- data/lib/mongoid/association/embedded/batchable.rb +1 -1
- data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +10 -3
- data/lib/mongoid/association/nested/many.rb +1 -1
- data/lib/mongoid/association/nested/one.rb +4 -2
- data/lib/mongoid/association/proxy.rb +6 -1
- data/lib/mongoid/association/referenced/auto_save.rb +2 -2
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -495
- data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
- data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
- data/lib/mongoid/attributes.rb +32 -14
- data/lib/mongoid/attributes/projector.rb +120 -0
- data/lib/mongoid/cacheable.rb +2 -2
- data/lib/mongoid/clients.rb +1 -1
- data/lib/mongoid/clients/factory.rb +22 -8
- data/lib/mongoid/config.rb +19 -2
- data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
- data/lib/mongoid/copyable.rb +1 -1
- data/lib/mongoid/criteria.rb +4 -5
- data/lib/mongoid/criteria/findable.rb +1 -1
- data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
- data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
- data/lib/mongoid/criteria/queryable/selectable.rb +8 -8
- data/lib/mongoid/document.rb +1 -15
- data/lib/mongoid/errors/delete_restriction.rb +8 -9
- data/lib/mongoid/errors/mongoid_error.rb +1 -1
- data/lib/mongoid/evolvable.rb +1 -1
- data/lib/mongoid/extensions/boolean.rb +1 -2
- data/lib/mongoid/extensions/false_class.rb +1 -1
- data/lib/mongoid/extensions/hash.rb +2 -2
- data/lib/mongoid/extensions/true_class.rb +1 -1
- data/lib/mongoid/fields.rb +43 -5
- data/lib/mongoid/inspectable.rb +1 -1
- data/lib/mongoid/matcher.rb +26 -43
- data/lib/mongoid/matcher/bits.rb +41 -0
- data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
- data/lib/mongoid/matcher/bits_all_set.rb +20 -0
- data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
- data/lib/mongoid/matcher/bits_any_set.rb +20 -0
- data/lib/mongoid/matcher/elem_match.rb +2 -1
- data/lib/mongoid/matcher/expression.rb +9 -14
- data/lib/mongoid/matcher/field_expression.rb +4 -5
- data/lib/mongoid/matcher/field_operator.rb +6 -0
- data/lib/mongoid/matcher/mod.rb +17 -0
- data/lib/mongoid/matcher/type.rb +99 -0
- data/lib/mongoid/persistable/deletable.rb +1 -2
- data/lib/mongoid/persistable/destroyable.rb +8 -2
- data/lib/mongoid/persistable/updatable.rb +27 -2
- data/lib/mongoid/query_cache.rb +35 -29
- data/lib/mongoid/reloadable.rb +5 -0
- data/lib/mongoid/selectable.rb +5 -7
- data/lib/mongoid/shardable.rb +21 -5
- data/lib/mongoid/touchable.rb +23 -4
- 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 +139 -82
- data/spec/integration/associations/embeds_many_spec.rb +44 -0
- data/spec/integration/associations/has_one_spec.rb +48 -0
- data/spec/integration/criteria/date_field_spec.rb +1 -1
- data/spec/integration/document_spec.rb +30 -0
- data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
- data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
- data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
- data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
- data/spec/integration/matcher_operator_data/comment.yml +22 -0
- data/spec/integration/matcher_operator_data/elem_match.yml +46 -0
- data/spec/integration/matcher_operator_data/implicit_traversal.yml +96 -0
- data/spec/integration/matcher_operator_data/in.yml +16 -0
- data/spec/integration/matcher_operator_data/mod.yml +55 -0
- data/spec/integration/matcher_operator_data/type.yml +70 -0
- data/spec/integration/matcher_operator_data/type_array.yml +16 -0
- data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
- data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
- data/spec/integration/matcher_operator_data/type_code.yml +26 -0
- data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
- data/spec/integration/matcher_operator_data/type_date.yml +39 -0
- data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
- data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
- data/spec/integration/matcher_operator_data/type_double.yml +15 -0
- data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
- data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
- data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
- data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
- data/spec/integration/matcher_operator_data/type_null.yml +23 -0
- data/spec/integration/matcher_operator_data/type_object.yml +23 -0
- data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
- data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
- data/spec/integration/matcher_operator_data/type_string.yml +15 -0
- data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
- data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
- data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
- data/spec/lite_spec_helper.rb +4 -3
- data/spec/mongoid/association/depending_spec.rb +391 -352
- data/spec/mongoid/association/nested/one_spec.rb +18 -14
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -8
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
- data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -1
- data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
- data/spec/mongoid/atomic/paths_spec.rb +64 -12
- data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
- data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
- data/spec/mongoid/attributes/projector_spec.rb +41 -0
- data/spec/mongoid/attributes_spec.rb +333 -0
- data/spec/mongoid/clients/factory_spec.rb +48 -0
- data/spec/mongoid/config_spec.rb +32 -0
- data/spec/mongoid/contextual/atomic_spec.rb +17 -4
- data/spec/mongoid/contextual/mongo_spec.rb +2 -2
- data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
- data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +229 -24
- data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
- data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
- data/spec/mongoid/criteria_projection_spec.rb +411 -0
- data/spec/mongoid/criteria_spec.rb +0 -275
- data/spec/mongoid/document_fields_spec.rb +26 -0
- data/spec/mongoid/document_query_spec.rb +51 -0
- data/spec/mongoid/document_spec.rb +13 -13
- data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
- data/spec/mongoid/errors/mongoid_error_spec.rb +20 -8
- data/spec/mongoid/extensions/false_class_spec.rb +1 -1
- data/spec/mongoid/extensions/string_spec.rb +5 -5
- data/spec/mongoid/extensions/true_class_spec.rb +1 -1
- data/spec/mongoid/fields/localized_spec.rb +4 -4
- data/spec/mongoid/fields_spec.rb +4 -4
- data/spec/mongoid/inspectable_spec.rb +12 -4
- 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/deletable_spec.rb +175 -1
- data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
- data/spec/mongoid/persistable/savable_spec.rb +3 -5
- data/spec/mongoid/persistable/settable_spec.rb +30 -0
- data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
- data/spec/mongoid/persistable_spec.rb +2 -2
- data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
- data/spec/mongoid/reloadable_spec.rb +18 -1
- data/spec/mongoid/shardable_spec.rb +44 -0
- data/spec/mongoid/touchable_spec.rb +104 -16
- data/spec/mongoid/touchable_spec_models.rb +52 -0
- data/spec/mongoid/validatable_spec.rb +1 -1
- 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 +19 -4
- data/spec/shared/lib/mrss/constraints.rb +46 -8
- data/spec/shared/lib/mrss/docker_runner.rb +10 -1
- data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +79 -33
- 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 +122 -29
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/server.sh +58 -11
- data/spec/shared/shlib/set_env.sh +4 -1
- data/spec/spec_helper.rb +7 -3
- data/spec/support/client_registry.rb +9 -0
- data/spec/support/models/bolt.rb +8 -0
- data/spec/support/models/hole.rb +13 -0
- data/spec/support/models/mop.rb +9 -0
- data/spec/support/models/nut.rb +8 -0
- data/spec/support/models/person.rb +6 -0
- data/spec/support/models/sealer.rb +8 -0
- data/spec/support/models/shirt.rb +12 -0
- data/spec/support/models/spacer.rb +8 -0
- data/spec/support/models/threadlocker.rb +8 -0
- data/spec/support/models/washer.rb +8 -0
- data/spec/support/spec_config.rb +8 -0
- metadata +636 -528
- metadata.gz.sig +0 -0
- data/spec/support/cluster_config.rb +0 -158
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)
|
data/lib/mongoid/selectable.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Mongoid
|
|
|
21
21
|
# @since 1.0.0
|
|
22
22
|
def atomic_selector
|
|
23
23
|
@atomic_selector ||=
|
|
24
|
-
(embedded? ? embedded_atomic_selector :
|
|
24
|
+
(embedded? ? embedded_atomic_selector : root_atomic_selector_in_db)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
private
|
|
@@ -44,18 +44,16 @@ module Mongoid
|
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
# Get the atomic selector
|
|
47
|
+
# Get the atomic selector that would match the existing version of the
|
|
48
|
+
# root document.
|
|
48
49
|
#
|
|
49
50
|
# @api private
|
|
50
51
|
#
|
|
51
|
-
# @example Get the root atomic selector.
|
|
52
|
-
# document.root_atomic_selector
|
|
53
|
-
#
|
|
54
52
|
# @return [ Hash ] The root document selector.
|
|
55
53
|
#
|
|
56
54
|
# @since 4.0.0
|
|
57
|
-
def
|
|
58
|
-
{ "_id" => _id }.merge!(
|
|
55
|
+
def root_atomic_selector_in_db
|
|
56
|
+
{ "_id" => _id }.merge!(shard_key_selector_in_db)
|
|
59
57
|
end
|
|
60
58
|
end
|
|
61
59
|
end
|
data/lib/mongoid/shardable.rb
CHANGED
|
@@ -52,15 +52,31 @@ module Mongoid
|
|
|
52
52
|
self.class.shard_key_fields
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
# @example Get the selector for the shard keys.
|
|
58
|
-
# person.shard_key_selector
|
|
55
|
+
# Returns the selector that would match the current version of this
|
|
56
|
+
# document.
|
|
59
57
|
#
|
|
60
58
|
# @return [ Hash ] The shard key selector.
|
|
61
59
|
#
|
|
62
|
-
# @
|
|
60
|
+
# @api private
|
|
63
61
|
def shard_key_selector
|
|
62
|
+
selector = {}
|
|
63
|
+
shard_key_fields.each do |field|
|
|
64
|
+
selector[field.to_s] = send(field)
|
|
65
|
+
end
|
|
66
|
+
selector
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Returns the selector that would match the existing version of this
|
|
70
|
+
# document in the database.
|
|
71
|
+
#
|
|
72
|
+
# If the document is not persisted, this method uses the current values
|
|
73
|
+
# of the shard key fields. If the document is persisted, this method
|
|
74
|
+
# uses the values retrieved from the database.
|
|
75
|
+
#
|
|
76
|
+
# @return [ Hash ] The shard key selector.
|
|
77
|
+
#
|
|
78
|
+
# @api private
|
|
79
|
+
def shard_key_selector_in_db
|
|
64
80
|
selector = {}
|
|
65
81
|
shard_key_fields.each do |field|
|
|
66
82
|
selector[field.to_s] = new_record? ? send(field) : attribute_was(field)
|
data/lib/mongoid/touchable.rb
CHANGED
|
@@ -30,11 +30,30 @@ module Mongoid
|
|
|
30
30
|
write_attribute(:updated_at, current) if respond_to?("updated_at=")
|
|
31
31
|
write_attribute(field, current) if field
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
# If the document being touched is embedded, touch its parents
|
|
34
|
+
# all the way through the composition hierarchy to the root object,
|
|
35
|
+
# because when an embedded document is changed the write is actually
|
|
36
|
+
# performed by the composition root. See MONGOID-3468.
|
|
37
|
+
if _parent
|
|
38
|
+
# This will persist updated_at on this document as well as parents.
|
|
39
|
+
# TODO support passing the field name to the parent's touch method;
|
|
40
|
+
# I believe it should be read out of
|
|
41
|
+
# _association.inverse_association.options but inverse_association
|
|
42
|
+
# seems to not always/ever be set here. See MONGOID-5014.
|
|
43
|
+
_parent.touch
|
|
44
|
+
else
|
|
45
|
+
# If the current document is not embedded, it is composition root
|
|
46
|
+
# and we need to persist the write here.
|
|
47
|
+
touches = touch_atomic_updates(field)
|
|
48
|
+
unless touches["$set"].blank?
|
|
49
|
+
selector = atomic_selector
|
|
50
|
+
_root.collection.find(selector).update_one(positionally(selector, touches), session: _session)
|
|
51
|
+
end
|
|
37
52
|
end
|
|
53
|
+
|
|
54
|
+
# Callbacks are invoked on the composition root first and on the
|
|
55
|
+
# leaf-most embedded document last.
|
|
56
|
+
# TODO add tests, see MONGOID-5015.
|
|
38
57
|
run_callbacks(:touch)
|
|
39
58
|
true
|
|
40
59
|
end
|
|
@@ -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
|
|
|
@@ -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
|
|
|
@@ -226,7 +249,7 @@ describe 'Mongoid application tests' do
|
|
|
226
249
|
end
|
|
227
250
|
end
|
|
228
251
|
|
|
229
|
-
def adjust_app_gemfile(rails_version:
|
|
252
|
+
def adjust_app_gemfile(rails_version: SpecConfig.instance.rails_version)
|
|
230
253
|
remove_bundler_req
|
|
231
254
|
|
|
232
255
|
gemfile_lines = IO.readlines('Gemfile')
|
|
@@ -238,14 +261,45 @@ describe 'Mongoid application tests' do
|
|
|
238
261
|
gemfile_lines.delete_if do |line|
|
|
239
262
|
line =~ /rails/
|
|
240
263
|
end
|
|
241
|
-
|
|
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
|
|
242
269
|
end
|
|
243
270
|
File.open('Gemfile', 'w') do |f|
|
|
244
271
|
f << gemfile_lines.join
|
|
245
272
|
end
|
|
246
273
|
end
|
|
247
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
|
+
|
|
248
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.
|
|
249
303
|
lock_lines = IO.readlines('Gemfile.lock')
|
|
250
304
|
# Get rid of the bundled with line so that whatever bundler is installed
|
|
251
305
|
# on the system is usable with the application.
|
|
@@ -270,7 +324,7 @@ describe 'Mongoid application tests' do
|
|
|
270
324
|
@clean_env ||= Hash[ENV.keys.grep(/BUNDLE|RUBYOPT/).map { |k| [k, nil ] }]
|
|
271
325
|
end
|
|
272
326
|
|
|
273
|
-
def wait_for_port(port, timeout)
|
|
327
|
+
def wait_for_port(port, timeout, process)
|
|
274
328
|
deadline = Time.now + timeout
|
|
275
329
|
loop do
|
|
276
330
|
begin
|
|
@@ -278,6 +332,9 @@ describe 'Mongoid application tests' do
|
|
|
278
332
|
return
|
|
279
333
|
end
|
|
280
334
|
rescue IOError, SystemCallError
|
|
335
|
+
unless process.alive?
|
|
336
|
+
raise "Process #{process} died while waiting for port #{port}"
|
|
337
|
+
end
|
|
281
338
|
if Time.now > deadline
|
|
282
339
|
raise
|
|
283
340
|
end
|