mongoid 5.4.0 → 6.4.8

Sign up to get free protection for your applications and to get access to all the features.
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