mongoid 8.0.9 → 8.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +3 -3
  4. data/README.md +3 -3
  5. data/Rakefile +18 -67
  6. data/lib/config/locales/en.yml +46 -14
  7. data/lib/mongoid/association/accessors.rb +3 -7
  8. data/lib/mongoid/association/builders.rb +1 -1
  9. data/lib/mongoid/association/eager_loadable.rb +0 -3
  10. data/lib/mongoid/association/embedded/batchable.rb +2 -2
  11. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  12. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
  13. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
  14. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +6 -6
  15. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
  16. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +1 -1
  17. data/lib/mongoid/association/macros.rb +0 -6
  18. data/lib/mongoid/association/nested/one.rb +40 -2
  19. data/lib/mongoid/association/proxy.rb +1 -1
  20. data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
  21. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +1 -1
  22. data/lib/mongoid/association/referenced/has_many/enumerable.rb +2 -2
  23. data/lib/mongoid/association/referenced/has_many/proxy.rb +3 -3
  24. data/lib/mongoid/association/reflections.rb +2 -2
  25. data/lib/mongoid/atomic.rb +7 -16
  26. data/lib/mongoid/attributes/dynamic.rb +1 -1
  27. data/lib/mongoid/attributes/nested.rb +2 -2
  28. data/lib/mongoid/attributes/processing.rb +5 -29
  29. data/lib/mongoid/attributes/projector.rb +1 -1
  30. data/lib/mongoid/attributes/readonly.rb +1 -1
  31. data/lib/mongoid/attributes.rb +8 -2
  32. data/lib/mongoid/changeable.rb +107 -5
  33. data/lib/mongoid/clients/storage_options.rb +2 -5
  34. data/lib/mongoid/clients/validators/storage.rb +1 -13
  35. data/lib/mongoid/collection_configurable.rb +58 -0
  36. data/lib/mongoid/composable.rb +2 -0
  37. data/lib/mongoid/config/defaults.rb +60 -0
  38. data/lib/mongoid/config/options.rb +0 -3
  39. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  40. data/lib/mongoid/config/validators.rb +1 -0
  41. data/lib/mongoid/config.rb +88 -27
  42. data/lib/mongoid/contextual/atomic.rb +1 -1
  43. data/lib/mongoid/contextual/memory.rb +233 -33
  44. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  45. data/lib/mongoid/contextual/mongo.rb +370 -133
  46. data/lib/mongoid/contextual/none.rb +162 -7
  47. data/lib/mongoid/contextual.rb +12 -0
  48. data/lib/mongoid/criteria/findable.rb +2 -2
  49. data/lib/mongoid/criteria/includable.rb +4 -3
  50. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -15
  51. data/lib/mongoid/criteria/queryable/key.rb +1 -1
  52. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  53. data/lib/mongoid/criteria/queryable/optional.rb +8 -8
  54. data/lib/mongoid/criteria/queryable/selectable.rb +43 -12
  55. data/lib/mongoid/criteria/queryable/selector.rb +1 -1
  56. data/lib/mongoid/criteria/queryable/storable.rb +1 -1
  57. data/lib/mongoid/criteria.rb +6 -5
  58. data/lib/mongoid/deprecable.rb +1 -2
  59. data/lib/mongoid/deprecation.rb +3 -3
  60. data/lib/mongoid/document.rb +1 -8
  61. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  62. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  63. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  64. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  65. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  66. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  67. data/lib/mongoid/errors.rb +4 -1
  68. data/lib/mongoid/extensions/hash.rb +2 -24
  69. data/lib/mongoid/extensions/object.rb +2 -2
  70. data/lib/mongoid/extensions/time.rb +2 -0
  71. data/lib/mongoid/fields/localized.rb +10 -0
  72. data/lib/mongoid/fields/standard.rb +10 -0
  73. data/lib/mongoid/fields.rb +59 -35
  74. data/lib/mongoid/findable.rb +27 -3
  75. data/lib/mongoid/interceptable.rb +6 -116
  76. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  77. data/lib/mongoid/matcher/type.rb +1 -1
  78. data/lib/mongoid/persistable/creatable.rb +1 -0
  79. data/lib/mongoid/persistable/deletable.rb +1 -1
  80. data/lib/mongoid/persistable/savable.rb +13 -1
  81. data/lib/mongoid/persistable/unsettable.rb +2 -2
  82. data/lib/mongoid/persistable/updatable.rb +51 -1
  83. data/lib/mongoid/persistable/upsertable.rb +20 -1
  84. data/lib/mongoid/persistable.rb +3 -0
  85. data/lib/mongoid/query_cache.rb +5 -1
  86. data/lib/mongoid/railties/database.rake +7 -2
  87. data/lib/mongoid/reloadable.rb +5 -3
  88. data/lib/mongoid/stateful.rb +22 -1
  89. data/lib/mongoid/tasks/database.rake +12 -0
  90. data/lib/mongoid/tasks/database.rb +20 -0
  91. data/lib/mongoid/timestamps/created.rb +1 -8
  92. data/lib/mongoid/traversable.rb +0 -12
  93. data/lib/mongoid/utils.rb +22 -0
  94. data/lib/mongoid/validatable/associated.rb +17 -98
  95. data/lib/mongoid/validatable/macros.rb +5 -5
  96. data/lib/mongoid/validatable.rb +4 -9
  97. data/lib/mongoid/version.rb +1 -1
  98. data/lib/mongoid/warnings.rb +17 -1
  99. data/lib/mongoid.rb +16 -3
  100. data/spec/integration/app_spec.rb +2 -2
  101. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +0 -40
  102. data/spec/integration/callbacks_spec.rb +99 -12
  103. data/spec/integration/discriminator_key_spec.rb +4 -5
  104. data/spec/integration/i18n_fallbacks_spec.rb +3 -2
  105. data/spec/mongoid/association/eager_spec.rb +2 -24
  106. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
  107. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +20 -25
  108. data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
  109. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +0 -4
  110. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  111. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
  112. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +5 -27
  113. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +9 -50
  114. data/spec/mongoid/association/syncable_spec.rb +1 -1
  115. data/spec/mongoid/association_spec.rb +0 -60
  116. data/spec/mongoid/attributes_spec.rb +3 -33
  117. data/spec/mongoid/changeable_spec.rb +299 -24
  118. data/spec/mongoid/clients_spec.rb +122 -13
  119. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  120. data/spec/mongoid/config/defaults_spec.rb +160 -0
  121. data/spec/mongoid/config_spec.rb +154 -27
  122. data/spec/mongoid/contextual/memory_spec.rb +332 -76
  123. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  124. data/spec/mongoid/contextual/mongo_spec.rb +1009 -125
  125. data/spec/mongoid/contextual/none_spec.rb +49 -2
  126. data/spec/mongoid/copyable_spec.rb +2 -10
  127. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -10
  128. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  129. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -0
  130. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
  131. data/spec/mongoid/criteria/queryable/selector_spec.rb +3 -76
  132. data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
  133. data/spec/mongoid/criteria_projection_spec.rb +1 -4
  134. data/spec/mongoid/criteria_spec.rb +5 -9
  135. data/spec/mongoid/document_spec.rb +0 -27
  136. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  137. data/spec/mongoid/extensions/hash_spec.rb +3 -3
  138. data/spec/mongoid/extensions/time_spec.rb +8 -43
  139. data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
  140. data/spec/mongoid/fields/localized_spec.rb +46 -28
  141. data/spec/mongoid/fields_spec.rb +136 -77
  142. data/spec/mongoid/findable_spec.rb +391 -34
  143. data/spec/mongoid/indexable_spec.rb +16 -10
  144. data/spec/mongoid/interceptable_spec.rb +153 -442
  145. data/spec/mongoid/interceptable_spec_models.rb +111 -51
  146. data/spec/mongoid/persistable/deletable_spec.rb +26 -6
  147. data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
  148. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  149. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  150. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  151. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  152. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  153. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  154. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  155. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  156. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  157. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  158. data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
  159. data/spec/mongoid/persistence_context_spec.rb +7 -57
  160. data/spec/mongoid/query_cache_spec.rb +56 -61
  161. data/spec/mongoid/reloadable_spec.rb +24 -28
  162. data/spec/mongoid/scopable_spec.rb +70 -0
  163. data/spec/mongoid/serializable_spec.rb +23 -44
  164. data/spec/mongoid/stateful_spec.rb +122 -8
  165. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  166. data/spec/mongoid/tasks/database_spec.rb +127 -0
  167. data/spec/mongoid/timestamps/created_spec.rb +0 -23
  168. data/spec/mongoid/timestamps_spec.rb +9 -11
  169. data/spec/mongoid/touchable_spec.rb +277 -5
  170. data/spec/mongoid/touchable_spec_models.rb +3 -1
  171. data/spec/mongoid/traversable_spec.rb +9 -24
  172. data/spec/mongoid/validatable/associated_spec.rb +34 -27
  173. data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
  174. data/spec/mongoid_spec.rb +36 -10
  175. data/spec/shared/LICENSE +20 -0
  176. data/spec/shared/bin/get-mongodb-download-url +17 -0
  177. data/spec/shared/bin/s3-copy +45 -0
  178. data/spec/shared/bin/s3-upload +69 -0
  179. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  180. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  181. data/spec/shared/lib/mrss/constraints.rb +378 -0
  182. data/spec/shared/lib/mrss/docker_runner.rb +298 -0
  183. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  184. data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
  185. data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
  186. data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
  187. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  188. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  189. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  190. data/spec/shared/lib/mrss/utils.rb +37 -0
  191. data/spec/shared/share/Dockerfile.erb +321 -0
  192. data/spec/shared/share/haproxy-1.conf +16 -0
  193. data/spec/shared/share/haproxy-2.conf +17 -0
  194. data/spec/shared/shlib/config.sh +27 -0
  195. data/spec/shared/shlib/distro.sh +74 -0
  196. data/spec/shared/shlib/server.sh +416 -0
  197. data/spec/shared/shlib/set_env.sh +169 -0
  198. data/spec/spec_helper.rb +5 -0
  199. data/spec/support/immutable_ids.rb +118 -0
  200. data/spec/support/macros.rb +47 -15
  201. data/spec/support/models/artist.rb +0 -1
  202. data/spec/support/models/band.rb +1 -0
  203. data/spec/support/models/book.rb +1 -0
  204. data/spec/support/models/building.rb +2 -0
  205. data/spec/support/models/cover.rb +10 -0
  206. data/spec/support/models/name.rb +0 -10
  207. data/spec/support/models/person.rb +0 -1
  208. data/spec/support/models/product.rb +1 -0
  209. data.tar.gz.sig +0 -0
  210. metadata +746 -636
  211. metadata.gz.sig +2 -0
  212. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  213. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
  214. data/spec/support/models/purse.rb +0 -9
@@ -1,19 +1,13 @@
1
1
  module InterceptableSpec
2
2
  class CallbackRegistry
3
- def initialize(only: [])
3
+ def initialize
4
4
  @calls = []
5
- @only = only
6
5
  end
7
6
 
8
7
  def record_call(cls, cb)
9
- return unless @only.empty? || @only.any? { |pat| pat == cb }
10
8
  @calls << [cls, cb]
11
9
  end
12
10
 
13
- def reset!
14
- @calls.clear
15
- end
16
-
17
11
  attr_reader :calls
18
12
  end
19
13
 
@@ -21,8 +15,6 @@ module InterceptableSpec
21
15
  extend ActiveSupport::Concern
22
16
 
23
17
  included do
24
- field :name, type: String
25
-
26
18
  %i(
27
19
  validation save create update
28
20
  ).each do |what|
@@ -42,128 +34,196 @@ module InterceptableSpec
42
34
  end
43
35
  end
44
36
  end
37
+ end
45
38
 
46
- attr_accessor :callback_registry
39
+ class CbHasOneParent
40
+ include Mongoid::Document
47
41
 
48
- def initialize(callback_registry, *args, **kwargs)
42
+ has_one :child, autosave: true, class_name: "CbHasOneChild", inverse_of: :parent
43
+
44
+ def initialize(callback_registry)
49
45
  @callback_registry = callback_registry
50
- super(*args, **kwargs)
46
+ super()
51
47
  end
52
- end
53
48
 
54
- module RootInsertable
49
+ attr_accessor :callback_registry
50
+
55
51
  def insert_as_root
56
52
  @callback_registry&.record_call(self.class, :insert_into_database)
57
53
  super
58
54
  end
59
- end
60
55
 
61
- class CbHasOneParent
62
- include Mongoid::Document
63
56
  include CallbackTracking
64
- include RootInsertable
65
-
66
- has_one :child, autosave: true, class_name: "CbHasOneChild", inverse_of: :parent
67
57
  end
68
58
 
69
59
  class CbHasOneChild
70
60
  include Mongoid::Document
71
- include CallbackTracking
72
61
 
73
62
  belongs_to :parent, class_name: "CbHasOneParent", inverse_of: :child
63
+
64
+ def initialize(callback_registry)
65
+ @callback_registry = callback_registry
66
+ super()
67
+ end
68
+
69
+ attr_accessor :callback_registry
70
+
71
+ include CallbackTracking
74
72
  end
75
73
 
76
74
  class CbHasManyParent
77
75
  include Mongoid::Document
78
- include CallbackTracking
79
- include RootInsertable
80
76
 
81
77
  has_many :children, autosave: true, class_name: "CbHasManyChild", inverse_of: :parent
78
+
79
+ def initialize(callback_registry)
80
+ @callback_registry = callback_registry
81
+ super()
82
+ end
83
+
84
+ attr_accessor :callback_registry
85
+
86
+ def insert_as_root
87
+ @callback_registry&.record_call(self.class, :insert_into_database)
88
+ super
89
+ end
90
+
91
+ include CallbackTracking
82
92
  end
83
93
 
84
94
  class CbHasManyChild
85
95
  include Mongoid::Document
86
- include CallbackTracking
87
96
 
88
97
  belongs_to :parent, class_name: "CbHasManyParent", inverse_of: :children
98
+
99
+ def initialize(callback_registry)
100
+ @callback_registry = callback_registry
101
+ super()
102
+ end
103
+
104
+ attr_accessor :callback_registry
105
+
106
+ include CallbackTracking
89
107
  end
90
108
 
91
109
  class CbEmbedsOneParent
92
110
  include Mongoid::Document
93
- include CallbackTracking
94
- include RootInsertable
95
111
 
96
112
  field :name
97
113
 
98
114
  embeds_one :child, cascade_callbacks: true, class_name: "CbEmbedsOneChild", inverse_of: :parent
115
+
116
+ def initialize(callback_registry)
117
+ @callback_registry = callback_registry
118
+ super()
119
+ end
120
+
121
+ attr_accessor :callback_registry
122
+
123
+ def insert_as_root
124
+ @callback_registry&.record_call(self.class, :insert_into_database)
125
+ super
126
+ end
127
+
128
+ include CallbackTracking
99
129
  end
100
130
 
101
131
  class CbEmbedsOneChild
102
132
  include Mongoid::Document
103
- include CallbackTracking
104
133
 
105
134
  field :age
106
135
 
107
136
  embedded_in :parent, class_name: "CbEmbedsOneParent", inverse_of: :child
137
+
138
+ def initialize(callback_registry)
139
+ @callback_registry = callback_registry
140
+ super()
141
+ end
142
+
143
+ attr_accessor :callback_registry
144
+
145
+ include CallbackTracking
108
146
  end
109
147
 
110
148
  class CbEmbedsManyParent
111
149
  include Mongoid::Document
112
- include CallbackTracking
113
- include RootInsertable
114
150
 
115
151
  embeds_many :children, cascade_callbacks: true, class_name: "CbEmbedsManyChild", inverse_of: :parent
152
+
153
+ def initialize(callback_registry)
154
+ @callback_registry = callback_registry
155
+ super()
156
+ end
157
+
158
+ attr_accessor :callback_registry
159
+
160
+ def insert_as_root
161
+ @callback_registry&.record_call(self.class, :insert_into_database)
162
+ super
163
+ end
164
+
165
+ include CallbackTracking
116
166
  end
117
167
 
118
168
  class CbEmbedsManyChild
119
169
  include Mongoid::Document
120
- include CallbackTracking
121
170
 
122
171
  embedded_in :parent, class_name: "CbEmbedsManyParent", inverse_of: :children
172
+
173
+ def initialize(callback_registry)
174
+ @callback_registry = callback_registry
175
+ super()
176
+ end
177
+
178
+ attr_accessor :callback_registry
179
+
180
+ include CallbackTracking
123
181
  end
124
182
 
125
183
  class CbParent
126
184
  include Mongoid::Document
127
- include CallbackTracking
185
+
186
+ def initialize(callback_registry)
187
+ @callback_registry = callback_registry
188
+ super()
189
+ end
190
+
191
+ attr_accessor :callback_registry
128
192
 
129
193
  embeds_many :cb_children
130
194
  embeds_many :cb_cascaded_children, cascade_callbacks: true
131
- embeds_many :cb_cascaded_nodes, cascade_callbacks: true, as: :parent
195
+
196
+ include CallbackTracking
132
197
  end
133
198
 
134
199
  class CbChild
135
200
  include Mongoid::Document
136
- include CallbackTracking
137
201
 
138
202
  embedded_in :cb_parent
203
+
204
+ def initialize(callback_registry, options)
205
+ @callback_registry = callback_registry
206
+ super(options)
207
+ end
208
+
209
+ attr_accessor :callback_registry
210
+
211
+ include CallbackTracking
139
212
  end
140
213
 
141
214
  class CbCascadedChild
142
215
  include Mongoid::Document
143
- include CallbackTracking
144
216
 
145
217
  embedded_in :cb_parent
146
218
 
147
- before_save :test_mongoid_state
148
-
149
- private
150
-
151
- # Helps test that cascading child callbacks have access to the Mongoid
152
- # state objects; if the implementation uses fiber-local (instead of truly
153
- # thread-local) variables, the related tests will fail because the
154
- # cascading child callbacks use fibers to linearize the recursion.
155
- def test_mongoid_state
156
- Mongoid::Threaded.stack('interceptable').push(self)
219
+ def initialize(callback_registry, options)
220
+ @callback_registry = callback_registry
221
+ super(options)
157
222
  end
158
- end
159
223
 
160
- class CbCascadedNode
161
- include Mongoid::Document
162
- include CallbackTracking
163
-
164
- embedded_in :parent, polymorphic: true
224
+ attr_accessor :callback_registry
165
225
 
166
- embeds_many :cb_cascaded_nodes, cascade_callbacks: true, as: :parent
226
+ include CallbackTracking
167
227
  end
168
228
  end
169
229
 
@@ -12,14 +12,34 @@ describe Mongoid::Persistable::Deletable do
12
12
 
13
13
  context "when deleting a readonly document" do
14
14
 
15
- let(:from_db) do
16
- Person.only(:_id).first
15
+ context "when legacy_attributes is true" do
16
+ config_override :legacy_readonly, true
17
+
18
+ let(:from_db) do
19
+ Person.only(:_id).first
20
+ end
21
+
22
+ it "raises an error" do
23
+ expect(from_db.readonly?).to be true
24
+ expect {
25
+ from_db.delete
26
+ }.to raise_error(Mongoid::Errors::ReadonlyDocument)
27
+ end
17
28
  end
18
29
 
19
- it "raises an error" do
20
- expect {
21
- from_db.delete
22
- }.to raise_error(Mongoid::Errors::ReadonlyDocument)
30
+ context "when legacy_attributes is false" do
31
+ config_override :legacy_readonly, false
32
+
33
+ let(:from_db) do
34
+ Person.first.tap(&:readonly!)
35
+ end
36
+
37
+ it "raises an error" do
38
+ expect(from_db.readonly?).to be true
39
+ expect {
40
+ from_db.delete
41
+ }.to raise_error(Mongoid::Errors::ReadonlyDocument)
42
+ end
23
43
  end
24
44
  end
25
45
 
@@ -12,14 +12,34 @@ describe Mongoid::Persistable::Destroyable do
12
12
 
13
13
  context "when destroying a readonly document" do
14
14
 
15
- let(:from_db) do
16
- Person.only(:_id).first
15
+ context "when legacy_attributes is true" do
16
+ config_override :legacy_readonly, true
17
+
18
+ let(:from_db) do
19
+ Person.only(:_id).first
20
+ end
21
+
22
+ it "raises an error" do
23
+ expect(from_db.readonly?).to be true
24
+ expect {
25
+ from_db.destroy
26
+ }.to raise_error(Mongoid::Errors::ReadonlyDocument)
27
+ end
17
28
  end
18
29
 
19
- it "raises an error" do
20
- expect {
21
- from_db.destroy
22
- }.to raise_error(Mongoid::Errors::ReadonlyDocument)
30
+ context "when legacy_attributes is false" do
31
+ config_override :legacy_readonly, false
32
+
33
+ let(:from_db) do
34
+ Person.first.tap(&:readonly!)
35
+ end
36
+
37
+ it "raises an error" do
38
+ expect(from_db.readonly?).to be true
39
+ expect {
40
+ from_db.destroy
41
+ }.to raise_error(Mongoid::Errors::ReadonlyDocument)
42
+ end
23
43
  end
24
44
  end
25
45
 
@@ -237,5 +237,42 @@ describe Mongoid::Persistable::Incrementable do
237
237
  end
238
238
  end
239
239
  end
240
+
241
+ context "when executing on a readonly document" do
242
+
243
+ let(:person) do
244
+ Person.create!(age: 10, score: 100)
245
+ end
246
+
247
+ context "when legacy_readonly is true" do
248
+ config_override :legacy_readonly, true
249
+
250
+ before do
251
+ person.__selected_fields = { "age" => 1, "score" => 1 }
252
+ end
253
+
254
+ it "persists the changes" do
255
+ expect(person).to be_readonly
256
+ person.inc(age: 15, score: 2)
257
+ expect(person.age).to eq(25)
258
+ expect(person.score).to eq(102)
259
+ end
260
+ end
261
+
262
+ context "when legacy_readonly is false" do
263
+ config_override :legacy_readonly, false
264
+
265
+ before do
266
+ person.readonly!
267
+ end
268
+
269
+ it "raises a ReadonlyDocument error" do
270
+ expect(person).to be_readonly
271
+ expect do
272
+ person.inc(age: 15, score: 2)
273
+ end.to raise_error(Mongoid::Errors::ReadonlyDocument)
274
+ end
275
+ end
276
+ end
240
277
  end
241
278
  end
@@ -155,5 +155,42 @@ describe Mongoid::Persistable::Logical do
155
155
  end
156
156
  end
157
157
  end
158
+
159
+ context "when executing on a readonly document" do
160
+
161
+ let(:person) do
162
+ Person.create!(age: 10, score: 100)
163
+ end
164
+
165
+ context "when legacy_readonly is true" do
166
+ config_override :legacy_readonly, true
167
+
168
+ before do
169
+ person.__selected_fields = { "age" => 1, "score" => 1 }
170
+ end
171
+
172
+ it "persists the changes" do
173
+ expect(person).to be_readonly
174
+ person.bit(age: { and: 6 }, score: { or: 122 })
175
+ expect(person.age).to eq(2)
176
+ expect(person.score).to eq(126)
177
+ end
178
+ end
179
+
180
+ context "when legacy_readonly is false" do
181
+ config_override :legacy_readonly, false
182
+
183
+ before do
184
+ person.readonly!
185
+ end
186
+
187
+ it "raises a ReadonlyDocument error" do
188
+ expect(person).to be_readonly
189
+ expect do
190
+ person.bit(age: { and: 6 }, score: { or: 122 })
191
+ end.to raise_error(Mongoid::Errors::ReadonlyDocument)
192
+ end
193
+ end
194
+ end
158
195
  end
159
196
  end
@@ -127,5 +127,41 @@ describe Mongoid::Persistable::Poppable do
127
127
  end
128
128
  end
129
129
  end
130
+
131
+ context "when executing on a readonly document" do
132
+
133
+ let(:person) do
134
+ Person.create!(test_array: [1, 2, 3])
135
+ end
136
+
137
+ context "when legacy_readonly is true" do
138
+ config_override :legacy_readonly, true
139
+
140
+ before do
141
+ person.__selected_fields = { "test_array" => 1 }
142
+ end
143
+
144
+ it "persists the changes" do
145
+ expect(person).to be_readonly
146
+ person.pop(test_array: 1)
147
+ expect(person.test_array).to eq([ 1, 2 ])
148
+ end
149
+ end
150
+
151
+ context "when legacy_readonly is false" do
152
+ config_override :legacy_readonly, false
153
+
154
+ before do
155
+ person.readonly!
156
+ end
157
+
158
+ it "raises a ReadonlyDocument error" do
159
+ expect(person).to be_readonly
160
+ expect do
161
+ person.pop(test_array: 1)
162
+ end.to raise_error(Mongoid::Errors::ReadonlyDocument)
163
+ end
164
+ end
165
+ end
130
166
  end
131
167
  end
@@ -127,6 +127,42 @@ describe Mongoid::Persistable::Pullable do
127
127
  end
128
128
  end
129
129
  end
130
+
131
+ context "when executing on a readonly document" do
132
+
133
+ let(:person) do
134
+ Person.create!(test_array: [ 1, 1, 2, 3 ])
135
+ end
136
+
137
+ context "when legacy_readonly is true" do
138
+ config_override :legacy_readonly, true
139
+
140
+ before do
141
+ person.__selected_fields = { "test_array" => 1 }
142
+ end
143
+
144
+ it "persists the changes" do
145
+ expect(person).to be_readonly
146
+ person.pull(test_array: 1)
147
+ expect(person.test_array).to eq([ 2, 3 ])
148
+ end
149
+ end
150
+
151
+ context "when legacy_readonly is false" do
152
+ config_override :legacy_readonly, false
153
+
154
+ before do
155
+ person.readonly!
156
+ end
157
+
158
+ it "raises a ReadonlyDocument error" do
159
+ expect(person).to be_readonly
160
+ expect do
161
+ person.pull(test_array: 1)
162
+ end.to raise_error(Mongoid::Errors::ReadonlyDocument)
163
+ end
164
+ end
165
+ end
130
166
  end
131
167
 
132
168
  describe "#pull_all" do
@@ -254,5 +290,41 @@ describe Mongoid::Persistable::Pullable do
254
290
  end
255
291
  end
256
292
  end
293
+
294
+ context "when executing on a readonly document" do
295
+
296
+ let(:person) do
297
+ Person.create!(test_array: [ 1, 1, 2, 3, 4 ])
298
+ end
299
+
300
+ context "when legacy_readonly is true" do
301
+ config_override :legacy_readonly, true
302
+
303
+ before do
304
+ person.__selected_fields = { "test_array" => 1 }
305
+ end
306
+
307
+ it "persists the changes" do
308
+ expect(person).to be_readonly
309
+ person.pull_all(test_array: [ 1, 2 ])
310
+ expect(person.test_array).to eq([ 3, 4 ])
311
+ end
312
+ end
313
+
314
+ context "when legacy_readonly is false" do
315
+ config_override :legacy_readonly, false
316
+
317
+ before do
318
+ person.readonly!
319
+ end
320
+
321
+ it "raises a ReadonlyDocument error" do
322
+ expect(person).to be_readonly
323
+ expect do
324
+ person.pull_all(test_array: [ 1, 2 ])
325
+ end.to raise_error(Mongoid::Errors::ReadonlyDocument)
326
+ end
327
+ end
328
+ end
257
329
  end
258
330
  end
@@ -204,6 +204,42 @@ describe Mongoid::Persistable::Pushable do
204
204
  end
205
205
  end
206
206
  end
207
+
208
+ context "when executing on a readonly document" do
209
+
210
+ let(:person) do
211
+ Person.create!(test_array: [ 1, 2, 3 ])
212
+ end
213
+
214
+ context "when legacy_readonly is true" do
215
+ config_override :legacy_readonly, true
216
+
217
+ before do
218
+ person.__selected_fields = { "test_array" => 1 }
219
+ end
220
+
221
+ it "persists the changes" do
222
+ expect(person).to be_readonly
223
+ person.add_to_set(test_array: [ 1, 4 ])
224
+ expect(person.test_array).to eq([ 1, 2, 3, 4 ])
225
+ end
226
+ end
227
+
228
+ context "when legacy_readonly is false" do
229
+ config_override :legacy_readonly, false
230
+
231
+ before do
232
+ person.readonly!
233
+ end
234
+
235
+ it "raises a ReadonlyDocument error" do
236
+ expect(person).to be_readonly
237
+ expect do
238
+ person.add_to_set(test_array: [ 1, 4 ])
239
+ end.to raise_error(Mongoid::Errors::ReadonlyDocument)
240
+ end
241
+ end
242
+ end
207
243
  end
208
244
 
209
245
  describe "#push" do
@@ -349,5 +385,41 @@ describe Mongoid::Persistable::Pushable do
349
385
  end
350
386
  end
351
387
  end
388
+
389
+ context "when executing on a readonly document" do
390
+
391
+ let(:person) do
392
+ Person.create!(test_array: [ 1, 2, 3 ])
393
+ end
394
+
395
+ context "when legacy_readonly is true" do
396
+ config_override :legacy_readonly, true
397
+
398
+ before do
399
+ person.__selected_fields = { "test_array" => 1 }
400
+ end
401
+
402
+ it "persists the changes" do
403
+ expect(person).to be_readonly
404
+ person.push(test_array: [ 1, 4 ])
405
+ expect(person.test_array).to eq([ 1, 2, 3, 1, 4 ])
406
+ end
407
+ end
408
+
409
+ context "when legacy_readonly is false" do
410
+ config_override :legacy_readonly, false
411
+
412
+ before do
413
+ person.readonly!
414
+ end
415
+
416
+ it "raises a ReadonlyDocument error" do
417
+ expect(person).to be_readonly
418
+ expect do
419
+ person.push(test_array: [ 1, 4 ])
420
+ end.to raise_error(Mongoid::Errors::ReadonlyDocument)
421
+ end
422
+ end
423
+ end
352
424
  end
353
425
  end
@@ -147,5 +147,41 @@ describe Mongoid::Persistable::Renamable do
147
147
  end
148
148
  end
149
149
  end
150
+
151
+ context "when executing on a readonly document" do
152
+
153
+ let(:person) do
154
+ Person.create!(title: "sir")
155
+ end
156
+
157
+ context "when legacy_readonly is true" do
158
+ config_override :legacy_readonly, true
159
+
160
+ before do
161
+ person.__selected_fields = { "test_array" => 1 }
162
+ end
163
+
164
+ it "persists the changes" do
165
+ expect(person).to be_readonly
166
+ person.rename title: :salutation
167
+ expect(person.reload.salutation).to eq("sir")
168
+ end
169
+ end
170
+
171
+ context "when legacy_readonly is false" do
172
+ config_override :legacy_readonly, false
173
+
174
+ before do
175
+ person.readonly!
176
+ end
177
+
178
+ it "raises a ReadonlyDocument error" do
179
+ expect(person).to be_readonly
180
+ expect do
181
+ person.rename(title: :salutation)
182
+ end.to raise_error(Mongoid::Errors::ReadonlyDocument)
183
+ end
184
+ end
185
+ end
150
186
  end
151
187
  end