mongoid 5.4.0 → 6.4.8

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 (301) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +3 -3
  4. data/Rakefile +26 -0
  5. data/lib/config/locales/en.yml +40 -0
  6. data/lib/mongoid/atomic/modifiers.rb +2 -2
  7. data/lib/mongoid/atomic.rb +5 -5
  8. data/lib/mongoid/attributes/readonly.rb +22 -0
  9. data/lib/mongoid/attributes.rb +22 -21
  10. data/lib/mongoid/cacheable.rb +36 -0
  11. data/lib/mongoid/changeable.rb +36 -0
  12. data/lib/mongoid/clients/options.rb +55 -250
  13. data/lib/mongoid/clients/sessions.rb +113 -0
  14. data/lib/mongoid/clients/storage_options.rb +2 -69
  15. data/lib/mongoid/clients.rb +10 -63
  16. data/lib/mongoid/composable.rb +29 -2
  17. data/lib/mongoid/config.rb +1 -0
  18. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  19. data/lib/mongoid/contextual/atomic.rb +4 -4
  20. data/lib/mongoid/contextual/map_reduce.rb +7 -3
  21. data/lib/mongoid/contextual/memory.rb +9 -4
  22. data/lib/mongoid/contextual/mongo.rb +65 -30
  23. data/lib/mongoid/contextual/none.rb +12 -0
  24. data/lib/mongoid/copyable.rb +13 -6
  25. data/lib/mongoid/criteria/marshalable.rb +2 -2
  26. data/lib/mongoid/criteria/modifiable.rb +29 -3
  27. data/lib/mongoid/criteria/options.rb +25 -0
  28. data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
  29. data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
  30. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
  31. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
  32. data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
  33. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
  34. data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
  35. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
  36. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
  37. data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
  38. data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
  39. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +79 -0
  40. data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
  41. data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
  42. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
  43. data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
  44. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
  45. data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
  46. data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
  47. data/lib/mongoid/criteria/queryable/key.rb +103 -0
  48. data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
  49. data/lib/mongoid/criteria/queryable/mergeable.rb +273 -0
  50. data/lib/mongoid/criteria/queryable/optional.rb +429 -0
  51. data/lib/mongoid/criteria/queryable/options.rb +153 -0
  52. data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
  53. data/lib/mongoid/criteria/queryable/selectable.rb +689 -0
  54. data/lib/mongoid/criteria/queryable/selector.rb +212 -0
  55. data/lib/mongoid/criteria/queryable/smash.rb +104 -0
  56. data/lib/mongoid/criteria/queryable.rb +87 -0
  57. data/lib/mongoid/criteria.rb +6 -2
  58. data/lib/mongoid/document.rb +34 -41
  59. data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
  60. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -1
  61. data/lib/mongoid/errors/invalid_field.rb +2 -2
  62. data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
  63. data/lib/mongoid/errors/invalid_relation.rb +66 -0
  64. data/lib/mongoid/errors/invalid_session_use.rb +24 -0
  65. data/lib/mongoid/errors.rb +3 -0
  66. data/lib/mongoid/evolvable.rb +1 -1
  67. data/lib/mongoid/extensions/big_decimal.rb +17 -8
  68. data/lib/mongoid/extensions/date.rb +4 -1
  69. data/lib/mongoid/extensions/decimal128.rb +3 -3
  70. data/lib/mongoid/extensions/hash.rb +1 -0
  71. data/lib/mongoid/extensions/regexp.rb +1 -0
  72. data/lib/mongoid/extensions/string.rb +6 -3
  73. data/lib/mongoid/extensions/time.rb +4 -1
  74. data/lib/mongoid/extensions.rb +0 -4
  75. data/lib/mongoid/factory.rb +2 -1
  76. data/lib/mongoid/fields/validators/macro.rb +18 -0
  77. data/lib/mongoid/findable.rb +2 -2
  78. data/lib/mongoid/indexable.rb +16 -14
  79. data/lib/mongoid/interceptable.rb +9 -22
  80. data/lib/mongoid/matchable/all.rb +2 -2
  81. data/lib/mongoid/matchable/and.rb +3 -3
  82. data/lib/mongoid/matchable/default.rb +2 -2
  83. data/lib/mongoid/matchable/elem_match.rb +28 -0
  84. data/lib/mongoid/matchable/exists.rb +2 -2
  85. data/lib/mongoid/matchable/gt.rb +4 -2
  86. data/lib/mongoid/matchable/gte.rb +4 -2
  87. data/lib/mongoid/matchable/in.rb +2 -2
  88. data/lib/mongoid/matchable/lt.rb +4 -2
  89. data/lib/mongoid/matchable/lte.rb +4 -2
  90. data/lib/mongoid/matchable/ne.rb +2 -2
  91. data/lib/mongoid/matchable/nin.rb +2 -2
  92. data/lib/mongoid/matchable/nor.rb +37 -0
  93. data/lib/mongoid/matchable/or.rb +3 -3
  94. data/lib/mongoid/matchable/regexp.rb +3 -3
  95. data/lib/mongoid/matchable/size.rb +2 -2
  96. data/lib/mongoid/matchable.rb +16 -7
  97. data/lib/mongoid/persistable/creatable.rb +5 -3
  98. data/lib/mongoid/persistable/deletable.rb +5 -3
  99. data/lib/mongoid/persistable/destroyable.rb +1 -5
  100. data/lib/mongoid/persistable/settable.rb +5 -5
  101. data/lib/mongoid/persistable/updatable.rb +7 -14
  102. data/lib/mongoid/persistable/upsertable.rb +2 -1
  103. data/lib/mongoid/persistable.rb +4 -6
  104. data/lib/mongoid/persistence_context.rb +220 -0
  105. data/lib/mongoid/query_cache.rb +67 -23
  106. data/lib/mongoid/railtie.rb +17 -1
  107. data/lib/mongoid/railties/controller_runtime.rb +86 -0
  108. data/lib/mongoid/relations/accessors.rb +3 -0
  109. data/lib/mongoid/relations/auto_save.rb +12 -4
  110. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
  111. data/lib/mongoid/relations/counter_cache.rb +15 -5
  112. data/lib/mongoid/relations/eager/base.rb +3 -3
  113. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +2 -2
  114. data/lib/mongoid/relations/eager/has_many.rb +1 -1
  115. data/lib/mongoid/relations/eager.rb +6 -11
  116. data/lib/mongoid/relations/embedded/batchable.rb +20 -18
  117. data/lib/mongoid/relations/embedded/in.rb +13 -1
  118. data/lib/mongoid/relations/embedded/many.rb +51 -10
  119. data/lib/mongoid/relations/embedded/one.rb +14 -1
  120. data/lib/mongoid/relations/macros.rb +9 -1
  121. data/lib/mongoid/relations/many.rb +4 -0
  122. data/lib/mongoid/relations/metadata.rb +3 -3
  123. data/lib/mongoid/relations/options.rb +2 -2
  124. data/lib/mongoid/relations/proxy.rb +1 -31
  125. data/lib/mongoid/relations/referenced/in.rb +19 -10
  126. data/lib/mongoid/relations/referenced/many.rb +30 -26
  127. data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
  128. data/lib/mongoid/relations/referenced/one.rb +15 -1
  129. data/lib/mongoid/relations/synchronization.rb +12 -12
  130. data/lib/mongoid/relations/targets/enumerable.rb +24 -4
  131. data/lib/mongoid/relations/touchable.rb +7 -4
  132. data/lib/mongoid/reloadable.rb +2 -2
  133. data/lib/mongoid/scopable.rb +3 -3
  134. data/lib/mongoid/serializable.rb +1 -1
  135. data/lib/mongoid/stateful.rb +1 -0
  136. data/lib/mongoid/tasks/database.rb +3 -2
  137. data/lib/mongoid/threaded.rb +74 -0
  138. data/lib/mongoid/traversable.rb +1 -1
  139. data/lib/mongoid/validatable/uniqueness.rb +1 -2
  140. data/lib/mongoid/version.rb +1 -1
  141. data/lib/mongoid.rb +6 -6
  142. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +18 -3
  143. data/spec/app/models/agent.rb +2 -0
  144. data/spec/app/models/album.rb +5 -1
  145. data/spec/app/models/array_field.rb +7 -0
  146. data/spec/app/models/artist.rb +21 -0
  147. data/spec/app/models/band.rb +3 -0
  148. data/spec/app/models/book.rb +2 -1
  149. data/spec/app/models/delegating_patient.rb +16 -0
  150. data/spec/app/models/dokument.rb +1 -0
  151. data/spec/app/models/ordered_post.rb +5 -0
  152. data/spec/app/models/oscar.rb +1 -2
  153. data/spec/app/models/page.rb +1 -1
  154. data/spec/app/models/person.rb +3 -3
  155. data/spec/app/models/princess.rb +2 -0
  156. data/spec/app/models/record.rb +1 -0
  157. data/spec/app/models/subscription.rb +1 -0
  158. data/spec/app/models/thing.rb +1 -1
  159. data/spec/config/mongoid.yml +15 -0
  160. data/spec/integration/document_spec.rb +22 -0
  161. data/spec/mongoid/atomic/modifiers_spec.rb +3 -3
  162. data/spec/mongoid/atomic_spec.rb +5 -5
  163. data/spec/mongoid/attributes/nested_spec.rb +18 -14
  164. data/spec/mongoid/attributes/readonly_spec.rb +87 -44
  165. data/spec/mongoid/attributes_spec.rb +90 -5
  166. data/spec/mongoid/cacheable_spec.rb +112 -0
  167. data/spec/mongoid/changeable_spec.rb +58 -0
  168. data/spec/mongoid/clients/factory_spec.rb +80 -28
  169. data/spec/mongoid/clients/options_spec.rb +396 -95
  170. data/spec/mongoid/clients/sessions_spec.rb +334 -0
  171. data/spec/mongoid/clients_spec.rb +243 -101
  172. data/spec/mongoid/composable_spec.rb +7 -0
  173. data/spec/mongoid/config_spec.rb +67 -11
  174. data/spec/mongoid/contextual/atomic_spec.rb +3 -3
  175. data/spec/mongoid/contextual/geo_near_spec.rb +1 -0
  176. data/spec/mongoid/contextual/mongo_spec.rb +275 -22
  177. data/spec/mongoid/contextual/none_spec.rb +15 -0
  178. data/spec/mongoid/copyable_spec.rb +13 -4
  179. data/spec/mongoid/criteria/modifiable_spec.rb +297 -16
  180. data/spec/mongoid/criteria/options_spec.rb +29 -0
  181. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
  182. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
  183. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
  184. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
  185. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
  186. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
  187. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
  188. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
  189. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
  190. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
  191. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
  192. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
  193. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
  194. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
  195. data/spec/mongoid/{extensions/origin → criteria/queryable/extensions}/regexp_raw_spec.rb +2 -2
  196. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +90 -0
  197. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
  198. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
  199. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
  200. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
  201. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
  202. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
  203. data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
  204. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
  205. data/spec/mongoid/criteria/queryable/optional_spec.rb +1799 -0
  206. data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
  207. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
  208. data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
  209. data/spec/mongoid/criteria/queryable/selectable_spec.rb +4242 -0
  210. data/spec/mongoid/criteria/queryable/selector_spec.rb +844 -0
  211. data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
  212. data/spec/mongoid/criteria/scopable_spec.rb +81 -0
  213. data/spec/mongoid/criteria_spec.rb +156 -22
  214. data/spec/mongoid/document_spec.rb +100 -90
  215. data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
  216. data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
  217. data/spec/mongoid/extensions/big_decimal_spec.rb +321 -19
  218. data/spec/mongoid/extensions/boolean_spec.rb +14 -0
  219. data/spec/mongoid/extensions/date_spec.rb +2 -6
  220. data/spec/mongoid/extensions/date_time_spec.rb +2 -6
  221. data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
  222. data/spec/mongoid/extensions/float_spec.rb +8 -1
  223. data/spec/mongoid/extensions/hash_spec.rb +15 -0
  224. data/spec/mongoid/extensions/integer_spec.rb +8 -1
  225. data/spec/mongoid/extensions/object_spec.rb +11 -0
  226. data/spec/mongoid/extensions/regexp_spec.rb +23 -0
  227. data/spec/mongoid/extensions/string_spec.rb +53 -4
  228. data/spec/mongoid/extensions/time_spec.rb +2 -6
  229. data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
  230. data/spec/mongoid/factory_spec.rb +11 -0
  231. data/spec/mongoid/fields_spec.rb +1 -1
  232. data/spec/mongoid/findable_spec.rb +47 -2
  233. data/spec/mongoid/indexable_spec.rb +15 -3
  234. data/spec/mongoid/interceptable_spec.rb +85 -19
  235. data/spec/mongoid/matchable/all_spec.rb +4 -4
  236. data/spec/mongoid/matchable/and_spec.rb +10 -10
  237. data/spec/mongoid/matchable/default_spec.rb +12 -12
  238. data/spec/mongoid/matchable/elem_match_spec.rb +86 -0
  239. data/spec/mongoid/matchable/exists_spec.rb +5 -5
  240. data/spec/mongoid/matchable/gt_spec.rb +18 -7
  241. data/spec/mongoid/matchable/gte_spec.rb +17 -7
  242. data/spec/mongoid/matchable/in_spec.rb +5 -5
  243. data/spec/mongoid/matchable/lt_spec.rb +18 -7
  244. data/spec/mongoid/matchable/lte_spec.rb +18 -7
  245. data/spec/mongoid/matchable/ne_spec.rb +5 -5
  246. data/spec/mongoid/matchable/nin_spec.rb +5 -5
  247. data/spec/mongoid/matchable/nor_spec.rb +209 -0
  248. data/spec/mongoid/matchable/or_spec.rb +7 -7
  249. data/spec/mongoid/matchable/regexp_spec.rb +5 -5
  250. data/spec/mongoid/matchable/size_spec.rb +3 -3
  251. data/spec/mongoid/matchable_spec.rb +199 -54
  252. data/spec/mongoid/persistable/creatable_spec.rb +7 -2
  253. data/spec/mongoid/persistable/deletable_spec.rb +35 -1
  254. data/spec/mongoid/persistable/destroyable_spec.rb +25 -2
  255. data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
  256. data/spec/mongoid/persistable/savable_spec.rb +34 -29
  257. data/spec/mongoid/persistable/settable_spec.rb +77 -27
  258. data/spec/mongoid/persistable/updatable_spec.rb +182 -3
  259. data/spec/mongoid/persistable_spec.rb +16 -16
  260. data/spec/mongoid/persistence_context_spec.rb +694 -0
  261. data/spec/mongoid/positional_spec.rb +1 -1
  262. data/spec/mongoid/query_cache_spec.rb +170 -12
  263. data/spec/mongoid/relations/accessors_spec.rb +1 -1
  264. data/spec/mongoid/relations/auto_save_spec.rb +39 -6
  265. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +4 -4
  266. data/spec/mongoid/relations/builders_spec.rb +37 -10
  267. data/spec/mongoid/relations/counter_cache_spec.rb +64 -3
  268. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +16 -0
  269. data/spec/mongoid/relations/eager_spec.rb +40 -0
  270. data/spec/mongoid/relations/embedded/many_spec.rb +305 -59
  271. data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
  272. data/spec/mongoid/relations/macros_spec.rb +415 -7
  273. data/spec/mongoid/relations/metadata_spec.rb +15 -1
  274. data/spec/mongoid/relations/proxy_spec.rb +27 -1
  275. data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
  276. data/spec/mongoid/relations/referenced/many_spec.rb +35 -25
  277. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +14 -26
  278. data/spec/mongoid/relations/synchronization_spec.rb +48 -2
  279. data/spec/mongoid/relations/targets/enumerable_spec.rb +108 -0
  280. data/spec/mongoid/relations/touchable_spec.rb +40 -0
  281. data/spec/mongoid/reloadable_spec.rb +51 -0
  282. data/spec/mongoid/scopable_spec.rb +13 -0
  283. data/spec/mongoid/serializable_spec.rb +0 -50
  284. data/spec/mongoid/threaded_spec.rb +68 -0
  285. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  286. data/spec/mongoid/validatable/uniqueness_spec.rb +18 -9
  287. data/spec/mongoid/validatable_spec.rb +16 -0
  288. data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
  289. data/spec/spec_helper.rb +101 -8
  290. data/spec/support/cluster_config.rb +158 -0
  291. data/spec/support/constraints.rb +101 -0
  292. data/spec/support/macros.rb +20 -0
  293. data/spec/support/session_registry.rb +50 -0
  294. data/spec/support/spec_config.rb +42 -0
  295. data.tar.gz.sig +0 -0
  296. metadata +163 -61
  297. metadata.gz.sig +0 -0
  298. data/lib/mongoid/clients/thread_options.rb +0 -19
  299. data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
  300. data/lib/mongoid/railties/document.rb +0 -12
  301. data/spec/mongoid/railties/document_spec.rb +0 -24
@@ -428,22 +428,40 @@ describe Mongoid::Relations::Embedded::Many do
428
428
  context "when replacing an existing relation" do
429
429
 
430
430
  let(:person) do
431
- Person.create(addresses: [
431
+ Person.create(addresses: addresses)
432
+ end
433
+
434
+ let(:addresses) do
435
+ [
432
436
  Address.new(street: "1st St"),
433
437
  Address.new(street: "2nd St")
434
- ])
438
+ ]
435
439
  end
436
440
 
437
441
  let(:address) do
438
442
  Address.new(street: "3rd St")
439
443
  end
440
444
 
441
- before do
442
- person.addresses = [ address ]
445
+ context "when the replaced relation is different from the existing relation" do
446
+
447
+ before do
448
+ person.addresses = [ address ]
449
+ end
450
+
451
+ it "deletes the old documents" do
452
+ expect(person.reload.addresses).to eq([ address ])
453
+ end
443
454
  end
444
455
 
445
- it "deletes the old documents" do
446
- expect(person.reload.addresses).to eq([ address ])
456
+ context "when the replaced relation is identical to the existing relation" do
457
+
458
+ before do
459
+ person.addresses = addresses
460
+ end
461
+
462
+ it "does nothing" do
463
+ expect(person.reload.addresses).to eq(addresses)
464
+ end
447
465
  end
448
466
  end
449
467
 
@@ -879,6 +897,36 @@ describe Mongoid::Relations::Embedded::Many do
879
897
  Person.create
880
898
  end
881
899
 
900
+ context 'when a string is used to access an attribute' do
901
+
902
+ let!(:address) do
903
+ person.addresses.create(street: "one")
904
+ end
905
+
906
+ let(:document) do
907
+ person.reload.addresses.as_document.first
908
+ end
909
+
910
+ it "returns the attribute value" do
911
+ expect(document['street']).to eq('one')
912
+ end
913
+ end
914
+
915
+ context 'when a symbol is used to access an attribute' do
916
+
917
+ let!(:address) do
918
+ person.addresses.create(street: "one")
919
+ end
920
+
921
+ let(:document) do
922
+ person.reload.addresses.as_document.first
923
+ end
924
+
925
+ it "returns the attribute value" do
926
+ expect(document[:street]).to eq('one')
927
+ end
928
+ end
929
+
882
930
  context "when the relation has no default scope" do
883
931
 
884
932
  let!(:address) do
@@ -2535,6 +2583,25 @@ describe Mongoid::Relations::Embedded::Many do
2535
2583
  person.addresses.create(street: "hermannstr")
2536
2584
  end
2537
2585
 
2586
+ context "when the number is zero" do
2587
+
2588
+ let!(:popped) do
2589
+ person.addresses.pop(0)
2590
+ end
2591
+
2592
+ it "returns an empty array" do
2593
+ expect(popped).to eq([])
2594
+ end
2595
+
2596
+ it "does not remove the document from the relation" do
2597
+ expect(person.addresses).to eq([ address_one, address_two ])
2598
+ end
2599
+
2600
+ it "does not persist the pop" do
2601
+ expect(person.reload.addresses).to eq([ address_one, address_two ])
2602
+ end
2603
+ end
2604
+
2538
2605
  context "when the number is not larger than the relation" do
2539
2606
 
2540
2607
  let!(:popped) do
@@ -2592,6 +2659,125 @@ describe Mongoid::Relations::Embedded::Many do
2592
2659
  end
2593
2660
  end
2594
2661
 
2662
+ describe "#shift" do
2663
+
2664
+ let(:person) do
2665
+ Person.create
2666
+ end
2667
+
2668
+ context "when no argument is provided" do
2669
+
2670
+ let!(:address_one) do
2671
+ person.addresses.create(street: "sonnenallee")
2672
+ end
2673
+
2674
+ let!(:address_two) do
2675
+ person.addresses.create(street: "hermannstr")
2676
+ end
2677
+
2678
+ let!(:shifted) do
2679
+ person.addresses.shift
2680
+ end
2681
+
2682
+ it "returns the shifted document" do
2683
+ expect(shifted).to eq(address_one)
2684
+ end
2685
+
2686
+ it "removes the document from the relation" do
2687
+ expect(person.addresses).to eq([ address_two ])
2688
+ end
2689
+
2690
+ it "persists the shift" do
2691
+ expect(person.reload.addresses).to eq([ address_two ])
2692
+ end
2693
+ end
2694
+
2695
+ context "when an integer is provided" do
2696
+
2697
+ let!(:address_one) do
2698
+ person.addresses.create(street: "sonnenallee")
2699
+ end
2700
+
2701
+ let!(:address_two) do
2702
+ person.addresses.create(street: "hermannstr")
2703
+ end
2704
+
2705
+ context "when the number is zero" do
2706
+
2707
+ let!(:shifted) do
2708
+ person.addresses.shift(0)
2709
+ end
2710
+
2711
+ it "returns an empty array" do
2712
+ expect(shifted).to eq([])
2713
+ end
2714
+
2715
+ it "does not remove the document from the relation" do
2716
+ expect(person.addresses).to eq([ address_one, address_two ])
2717
+ end
2718
+
2719
+ it "does not persist the shift" do
2720
+ expect(person.reload.addresses).to eq([ address_one, address_two ])
2721
+ end
2722
+ end
2723
+
2724
+ context "when the number is not larger than the relation" do
2725
+
2726
+ let!(:shifted) do
2727
+ person.addresses.shift(2)
2728
+ end
2729
+
2730
+ it "returns the shifted documents" do
2731
+ expect(shifted).to eq([ address_one, address_two ])
2732
+ end
2733
+
2734
+ it "removes the document from the relation" do
2735
+ expect(person.addresses).to be_empty
2736
+ end
2737
+
2738
+ it "persists the shift" do
2739
+ expect(person.reload.addresses).to be_empty
2740
+ end
2741
+ end
2742
+
2743
+ context "when the number is larger than the relation" do
2744
+
2745
+ let!(:shifted) do
2746
+ person.addresses.shift(4)
2747
+ end
2748
+
2749
+ it "returns the shifted documents" do
2750
+ expect(shifted).to eq([ address_one, address_two ])
2751
+ end
2752
+
2753
+ it "removes the document from the relation" do
2754
+ expect(person.addresses).to be_empty
2755
+ end
2756
+
2757
+ it "persists the shift" do
2758
+ expect(person.reload.addresses).to be_empty
2759
+ end
2760
+ end
2761
+ end
2762
+
2763
+ context "when the relation is empty" do
2764
+
2765
+ context "when providing no number" do
2766
+
2767
+ it "returns nil" do
2768
+ expect(person.addresses.shift).to be_nil
2769
+ end
2770
+ end
2771
+
2772
+ context "when providing a number" do
2773
+
2774
+ it "returns nil" do
2775
+ expect(person.addresses.shift(2)).to be_nil
2776
+ end
2777
+ end
2778
+ end
2779
+ end
2780
+
2595
2781
  describe "#scoped" do
2596
2782
 
2597
2783
  let(:person) do
@@ -3761,12 +3947,10 @@ describe Mongoid::Relations::Embedded::Many do
3761
3947
 
3762
3948
  before do
3763
3949
  expect(artist).to receive(:before_add_song).and_raise
3950
+ begin; artist.songs << song; rescue; end
3764
3951
  end
3765
3952
 
3766
3953
  it "does not add the document to the relation" do
3767
- expect {
3768
- artist.songs << song
3769
- }.to raise_error
3770
3954
  expect(artist.songs).to be_empty
3771
3955
  end
3772
3956
  end
@@ -3791,18 +3975,16 @@ describe Mongoid::Relations::Embedded::Many do
3791
3975
 
3792
3976
  before do
3793
3977
  expect(artist).to receive(:after_add_label).and_raise
3978
+ begin; artist.labels << label; rescue; end
3794
3979
  end
3795
3980
 
3796
3981
  it "adds the document to the relation" do
3797
- expect {
3798
- artist.labels << label
3799
- }.to raise_error
3800
3982
  expect(artist.labels).to eq([ label ])
3801
3983
  end
3802
3984
  end
3803
3985
  end
3804
3986
 
3805
- context "#delete or #clear with before_remove callback" do
3987
+ context "#delete, or #clear, or #pop, or #shift with before_remove callback" do
3806
3988
 
3807
3989
  let(:artist) do
3808
3990
  Artist.new
@@ -3848,36 +4030,81 @@ describe Mongoid::Relations::Embedded::Many do
3848
4030
  end
3849
4031
  end
3850
4032
 
3851
- context "when errors are raised" do
4033
+ describe "#pop" do
3852
4034
 
3853
4035
  before do
3854
- expect(artist).to receive(:before_remove_song).and_raise
4036
+ artist.songs.pop
3855
4037
  end
3856
4038
 
3857
- describe "#delete" do
4039
+ it "executes the callback" do
4040
+ artist.songs.pop
4041
+ expect(artist.before_remove_embedded_called).to be true
4042
+ end
4043
+ end
3858
4044
 
3859
- it "does not remove the document from the relation" do
3860
- expect {
3861
- artist.songs.delete(song)
3862
- }.to raise_error
3863
- expect(artist.songs).to eq([ song ])
3864
- end
4045
+ describe "#shift" do
4046
+
4047
+ before do
4048
+ artist.songs.shift
3865
4049
  end
3866
4050
 
3867
- describe "#clear" do
4051
+ it "executes the callback" do
4052
+ artist.songs.shift
4053
+ expect(artist.before_remove_embedded_called).to be true
4054
+ end
4055
+ end
4056
+ end
3868
4057
 
3869
- it "removes the documents from the relation" do
3870
- expect {
3871
- artist.songs.clear
3872
- }.to raise_error
3873
- expect(artist.songs).to eq([ song ])
3874
- end
4058
+ context "when errors are raised" do
4059
+
4060
+ before do
4061
+ expect(artist).to receive(:before_remove_song).and_raise
4062
+ end
4063
+
4064
+ describe "#delete" do
4065
+
4066
+ it "does not remove the document from the relation" do
4067
+ begin; artist.songs.delete(song); rescue; end
4068
+ expect(artist.songs).to eq([ song ])
4069
+ end
4070
+ end
4071
+
4072
+ describe "#clear" do
4073
+
4074
+ before do
4075
+ begin; artist.songs.clear; rescue; end
4076
+ end
4077
+
4078
+ it "removes the documents from the relation" do
4079
+ expect(artist.songs).to eq([ song ])
4080
+ end
4081
+ end
4082
+
4083
+ describe "#pop" do
4084
+
4085
+ before do
4086
+ begin; artist.songs.pop; rescue; end
4087
+ end
4088
+
4089
+ it "should remove from collection" do
4090
+ expect(artist.songs).to eq([ song ])
4091
+ end
4092
+ end
4093
+
4094
+ describe "#shift" do
4095
+
4096
+ before do
4097
+ begin; artist.songs.shift; rescue; end
4098
+ end
4099
+
4100
+ it "should remove from collection" do
4101
+ expect(artist.songs).to eq([ song ])
3875
4102
  end
3876
4103
  end
3877
4104
  end
3878
4105
  end
3879
4106
 
3880
- context "#delete or #clear with after_remove callback" do
4107
+ context "#delete, or #clear, or #pop, or #shift with after_remove callback" do
3881
4108
 
3882
4109
  let(:artist) do
3883
4110
  Artist.new
@@ -3914,6 +4141,30 @@ describe Mongoid::Relations::Embedded::Many do
3914
4141
  expect(artist.after_remove_embedded_called).to be true
3915
4142
  end
3916
4143
  end
4144
+
4145
+ describe "#pop" do
4146
+
4147
+ before do
4148
+ artist.labels.pop
4149
+ end
4150
+
4151
+ it "executes the callback" do
4152
+ artist.labels.pop
4153
+ expect(artist.after_remove_embedded_called).to be true
4154
+ end
4155
+ end
4156
+
4157
+ describe "#shift" do
4158
+
4159
+ before do
4160
+ artist.labels.shift
4161
+ end
4162
+
4163
+ it "executes the callback" do
4164
+ artist.labels.shift
4165
+ expect(artist.after_remove_embedded_called).to be true
4166
+ end
4167
+ end
3917
4168
  end
3918
4169
 
3919
4170
  context "when errors are raised" do
@@ -3925,9 +4176,7 @@ describe Mongoid::Relations::Embedded::Many do
3925
4176
  describe "#delete" do
3926
4177
 
3927
4178
  before do
3928
- expect {
3929
- artist.labels.delete(label)
3930
- }.to raise_error
4179
+ begin; artist.labels.delete(label); rescue; end
3931
4180
  end
3932
4181
 
3933
4182
  it "removes the document from the relation" do
@@ -3938,9 +4187,29 @@ describe Mongoid::Relations::Embedded::Many do
3938
4187
  describe "#clear" do
3939
4188
 
3940
4189
  before do
3941
- expect {
3942
- artist.labels.clear
3943
- }.to raise_error
4190
+ begin; artist.labels.clear; rescue; end
4191
+ end
4192
+
4193
+ it "should remove from collection" do
4194
+ expect(artist.labels).to be_empty
4195
+ end
4196
+ end
4197
+
4198
+ describe "#pop" do
4199
+
4200
+ before do
4201
+ begin; artist.labels.pop; rescue; end
4202
+ end
4203
+
4204
+ it "should remove from collection" do
4205
+ expect(artist.labels).to be_empty
4206
+ end
4207
+ end
4208
+
4209
+ describe "#shift" do
4210
+
4211
+ before do
4212
+ begin; artist.labels.shift; rescue; end
3944
4213
  end
3945
4214
 
3946
4215
  it "should remove from collection" do
@@ -4019,29 +4288,6 @@ describe Mongoid::Relations::Embedded::Many do
4019
4288
  end
4020
4289
  end
4021
4290
 
4022
- context "when embedded documents get marshalled" do
4023
-
4024
- let(:person) do
4025
- Person.create
4026
- end
4027
-
4028
- let!(:addresses) do
4029
- person.addresses
4030
- end
4031
-
4032
- let!(:dumped) do
4033
- Marshal.dump(addresses)
4034
- end
4035
-
4036
- let!(:loaded) do
4037
- Marshal.load(dumped)
4038
- end
4039
-
4040
- it "keeps the proxy extensions when remarshalling" do
4041
- expect(loaded.extension).to eq("Testing")
4042
- end
4043
- end
4044
-
4045
4291
  context "deleting embedded documents" do
4046
4292
 
4047
4293
  it "able to delete embedded documents upon condition" do
@@ -70,7 +70,8 @@ describe Mongoid::Relations::Embedded::One do
70
70
  name_without_default or (self.name = Name.new)
71
71
  end
72
72
  class << person
73
- alias_method_chain :name, :default
73
+ alias_method :name_without_default, :name
74
+ alias_method :name, :name_with_default
74
75
  end
75
76
  end
76
77