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.
Files changed (190) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +1 -1
  5. data/Rakefile +16 -0
  6. data/lib/config/locales/en.yml +2 -2
  7. data/lib/mongoid/association/accessors.rb +13 -1
  8. data/lib/mongoid/association/constrainable.rb +1 -1
  9. data/lib/mongoid/association/depending.rb +4 -4
  10. data/lib/mongoid/association/embedded/batchable.rb +1 -1
  11. data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
  12. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +10 -3
  13. data/lib/mongoid/association/nested/many.rb +1 -1
  14. data/lib/mongoid/association/nested/one.rb +4 -2
  15. data/lib/mongoid/association/proxy.rb +6 -1
  16. data/lib/mongoid/association/referenced/auto_save.rb +2 -2
  17. data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -495
  18. data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
  19. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
  20. data/lib/mongoid/attributes.rb +32 -14
  21. data/lib/mongoid/attributes/projector.rb +120 -0
  22. data/lib/mongoid/cacheable.rb +2 -2
  23. data/lib/mongoid/clients.rb +1 -1
  24. data/lib/mongoid/clients/factory.rb +22 -8
  25. data/lib/mongoid/config.rb +19 -2
  26. data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
  27. data/lib/mongoid/copyable.rb +1 -1
  28. data/lib/mongoid/criteria.rb +4 -5
  29. data/lib/mongoid/criteria/findable.rb +1 -1
  30. data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
  31. data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
  32. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  33. data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
  34. data/lib/mongoid/criteria/queryable/selectable.rb +8 -8
  35. data/lib/mongoid/document.rb +1 -15
  36. data/lib/mongoid/errors/delete_restriction.rb +8 -9
  37. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  38. data/lib/mongoid/evolvable.rb +1 -1
  39. data/lib/mongoid/extensions/boolean.rb +1 -2
  40. data/lib/mongoid/extensions/false_class.rb +1 -1
  41. data/lib/mongoid/extensions/hash.rb +2 -2
  42. data/lib/mongoid/extensions/true_class.rb +1 -1
  43. data/lib/mongoid/fields.rb +43 -5
  44. data/lib/mongoid/inspectable.rb +1 -1
  45. data/lib/mongoid/matcher.rb +26 -43
  46. data/lib/mongoid/matcher/bits.rb +41 -0
  47. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  48. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  49. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  50. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  51. data/lib/mongoid/matcher/elem_match.rb +2 -1
  52. data/lib/mongoid/matcher/expression.rb +9 -14
  53. data/lib/mongoid/matcher/field_expression.rb +4 -5
  54. data/lib/mongoid/matcher/field_operator.rb +6 -0
  55. data/lib/mongoid/matcher/mod.rb +17 -0
  56. data/lib/mongoid/matcher/type.rb +99 -0
  57. data/lib/mongoid/persistable/deletable.rb +1 -2
  58. data/lib/mongoid/persistable/destroyable.rb +8 -2
  59. data/lib/mongoid/persistable/updatable.rb +27 -2
  60. data/lib/mongoid/query_cache.rb +35 -29
  61. data/lib/mongoid/reloadable.rb +5 -0
  62. data/lib/mongoid/selectable.rb +5 -7
  63. data/lib/mongoid/shardable.rb +21 -5
  64. data/lib/mongoid/touchable.rb +23 -4
  65. data/lib/mongoid/validatable/associated.rb +1 -1
  66. data/lib/mongoid/validatable/presence.rb +3 -3
  67. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  68. data/lib/mongoid/version.rb +1 -1
  69. data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
  70. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
  71. data/spec/integration/app_spec.rb +139 -82
  72. data/spec/integration/associations/embeds_many_spec.rb +44 -0
  73. data/spec/integration/associations/has_one_spec.rb +48 -0
  74. data/spec/integration/criteria/date_field_spec.rb +1 -1
  75. data/spec/integration/document_spec.rb +30 -0
  76. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  77. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  78. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  79. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  80. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  81. data/spec/integration/matcher_operator_data/elem_match.yml +46 -0
  82. data/spec/integration/matcher_operator_data/implicit_traversal.yml +96 -0
  83. data/spec/integration/matcher_operator_data/in.yml +16 -0
  84. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  85. data/spec/integration/matcher_operator_data/type.yml +70 -0
  86. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  87. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  88. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  89. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  90. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  91. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  92. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  93. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  94. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  95. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  96. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  97. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  98. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  99. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  100. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  101. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  102. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  103. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  104. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  105. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  106. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  107. data/spec/lite_spec_helper.rb +4 -3
  108. data/spec/mongoid/association/depending_spec.rb +391 -352
  109. data/spec/mongoid/association/nested/one_spec.rb +18 -14
  110. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -8
  111. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
  112. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
  113. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -1
  114. data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
  115. data/spec/mongoid/atomic/paths_spec.rb +64 -12
  116. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  117. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  118. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  119. data/spec/mongoid/attributes_spec.rb +333 -0
  120. data/spec/mongoid/clients/factory_spec.rb +48 -0
  121. data/spec/mongoid/config_spec.rb +32 -0
  122. data/spec/mongoid/contextual/atomic_spec.rb +17 -4
  123. data/spec/mongoid/contextual/mongo_spec.rb +2 -2
  124. data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
  125. data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
  126. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
  127. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
  128. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +229 -24
  129. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  130. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
  131. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  132. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  133. data/spec/mongoid/criteria_spec.rb +0 -275
  134. data/spec/mongoid/document_fields_spec.rb +26 -0
  135. data/spec/mongoid/document_query_spec.rb +51 -0
  136. data/spec/mongoid/document_spec.rb +13 -13
  137. data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
  138. data/spec/mongoid/errors/mongoid_error_spec.rb +20 -8
  139. data/spec/mongoid/extensions/false_class_spec.rb +1 -1
  140. data/spec/mongoid/extensions/string_spec.rb +5 -5
  141. data/spec/mongoid/extensions/true_class_spec.rb +1 -1
  142. data/spec/mongoid/fields/localized_spec.rb +4 -4
  143. data/spec/mongoid/fields_spec.rb +4 -4
  144. data/spec/mongoid/inspectable_spec.rb +12 -4
  145. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  146. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +68 -88
  147. data/spec/mongoid/matcher/extract_attribute_spec.rb +3 -13
  148. data/spec/mongoid/persistable/deletable_spec.rb +175 -1
  149. data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
  150. data/spec/mongoid/persistable/savable_spec.rb +3 -5
  151. data/spec/mongoid/persistable/settable_spec.rb +30 -0
  152. data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
  153. data/spec/mongoid/persistable_spec.rb +2 -2
  154. data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
  155. data/spec/mongoid/reloadable_spec.rb +18 -1
  156. data/spec/mongoid/shardable_spec.rb +44 -0
  157. data/spec/mongoid/touchable_spec.rb +104 -16
  158. data/spec/mongoid/touchable_spec_models.rb +52 -0
  159. data/spec/mongoid/validatable_spec.rb +1 -1
  160. data/spec/shared/bin/get-mongodb-download-url +17 -0
  161. data/spec/shared/bin/s3-copy +45 -0
  162. data/spec/shared/bin/s3-upload +69 -0
  163. data/spec/shared/lib/mrss/cluster_config.rb +19 -4
  164. data/spec/shared/lib/mrss/constraints.rb +46 -8
  165. data/spec/shared/lib/mrss/docker_runner.rb +10 -1
  166. data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
  167. data/spec/shared/lib/mrss/server_version_registry.rb +79 -33
  168. data/spec/shared/lib/mrss/spec_organizer.rb +32 -2
  169. data/spec/shared/lib/mrss/utils.rb +15 -0
  170. data/spec/shared/share/Dockerfile.erb +122 -29
  171. data/spec/shared/share/haproxy-1.conf +16 -0
  172. data/spec/shared/share/haproxy-2.conf +17 -0
  173. data/spec/shared/shlib/server.sh +58 -11
  174. data/spec/shared/shlib/set_env.sh +4 -1
  175. data/spec/spec_helper.rb +7 -3
  176. data/spec/support/client_registry.rb +9 -0
  177. data/spec/support/models/bolt.rb +8 -0
  178. data/spec/support/models/hole.rb +13 -0
  179. data/spec/support/models/mop.rb +9 -0
  180. data/spec/support/models/nut.rb +8 -0
  181. data/spec/support/models/person.rb +6 -0
  182. data/spec/support/models/sealer.rb +8 -0
  183. data/spec/support/models/shirt.rb +12 -0
  184. data/spec/support/models/spacer.rb +8 -0
  185. data/spec/support/models/threadlocker.rb +8 -0
  186. data/spec/support/models/washer.rb +8 -0
  187. data/spec/support/spec_config.rb +8 -0
  188. metadata +636 -528
  189. metadata.gz.sig +0 -0
  190. data/spec/support/cluster_config.rb +0 -158
@@ -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)
@@ -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 : root_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 for a root document.
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 root_atomic_selector
58
- { "_id" => _id }.merge!(shard_key_selector)
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
@@ -52,15 +52,31 @@ module Mongoid
52
52
  self.class.shard_key_fields
53
53
  end
54
54
 
55
- # Get the document selector with the defined shard keys.
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
- # @since 2.0.0
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)
@@ -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
- touches = touch_atomic_updates(field)
34
- unless touches["$set"].blank?
35
- selector = atomic_selector
36
- _root.collection.find(selector).update_one(positionally(selector, touches), session: _session)
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
@@ -43,7 +43,7 @@ module Mongoid
43
43
  ensure
44
44
  document.exit_validate
45
45
  end
46
- document.errors.add(attribute, :invalid, options) unless valid
46
+ document.errors.add(attribute, :invalid, **options) unless valid
47
47
  end
48
48
  end
49
49
  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
 
@@ -2,5 +2,5 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  module Mongoid
5
- VERSION = "7.2.1"
5
+ VERSION = "7.3.1"
6
6
  end
@@ -15,7 +15,14 @@ module Mongoid
15
15
  end
16
16
 
17
17
  def app_name
18
- Rails::Application.subclasses.first.parent.to_s.underscore
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 ismaster commands. (default: 10)
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 - sinatra' do
23
- it 'runs' do
24
- clone_application(
25
- 'https://github.com/mongoid/mongoid-demo',
26
- subdir: 'sinatra-minimal',
27
- ) do
28
-
29
- process = ChildProcess.build(*%w(bundle exec ruby app.rb))
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
- wait_for_port(4567, 20)
37
- sleep 1
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
- resp.should == []
35
+ resp.should == []
47
36
 
48
- status.should == 0
37
+ end
38
+ end
49
39
  end
50
40
  end
51
- end
52
41
 
53
- context 'demo application - rails-api' do
54
- ['~> 6.0.0'].each do |rails_version|
55
- context "with rails #{rails_version}" do
56
- it 'runs' do
57
- clone_application(
58
- 'https://github.com/mongoid/mongoid-demo',
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
- resp.should == []
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
- # 143 = 128 + 15
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
- ['~> 5.1.0', '~> 5.2.0', '~> 6.0.0'].each do |rails_version|
92
- context "with rails #{rails_version}" do
93
- it 'creates' do
94
- Mrss::ChildProcessHelper.check_call(%w(gem uni rails -a))
95
- Mrss::ChildProcessHelper.check_call(%w(gem install rails --no-document -v) + [rails_version])
96
-
97
- Dir.chdir(TMP_BASE) do
98
- FileUtils.rm_rf('mongoid-test')
99
- Mrss::ChildProcessHelper.check_call(%w(rails new mongoid-test --skip-spring --skip-active-record), env: clean_env)
100
-
101
- Dir.chdir('mongoid-test') do
102
- adjust_app_gemfile
103
- Mrss::ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
104
-
105
- Mrss::ChildProcessHelper.check_call(%w(rails g model post), env: clean_env)
106
- Mrss::ChildProcessHelper.check_call(%w(rails g model comment post:belongs_to), env: clean_env)
107
-
108
- # https://jira.mongodb.org/browse/MONGOID-4885
109
- comment_text = File.read('app/models/comment.rb')
110
- comment_text.should =~ /belongs_to :post/
111
- comment_text.should_not =~ /embedded_in :post/
112
- end
113
- end
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, rails_version: 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(rails_version: rails_version)
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: nil)
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
- gemfile_lines << "gem 'rails', '#{rails_version}'\n"
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