mongoid 7.5.3 → 8.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (295) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +3 -3
  4. data/lib/config/locales/en.yml +46 -30
  5. data/lib/mongoid/association/accessors.rb +32 -3
  6. data/lib/mongoid/association/bindable.rb +48 -0
  7. data/lib/mongoid/association/builders.rb +4 -2
  8. data/lib/mongoid/association/eager_loadable.rb +29 -7
  9. data/lib/mongoid/association/embedded/batchable.rb +28 -5
  10. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  11. data/lib/mongoid/association/embedded/embedded_in.rb +2 -1
  12. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  13. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  14. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +40 -18
  15. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  16. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +21 -2
  17. data/lib/mongoid/association/macros.rb +2 -1
  18. data/lib/mongoid/association/many.rb +5 -0
  19. data/lib/mongoid/association/nested/many.rb +2 -1
  20. data/lib/mongoid/association/proxy.rb +12 -0
  21. data/lib/mongoid/association/referenced/auto_save.rb +3 -2
  22. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  23. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  24. data/lib/mongoid/association/referenced/belongs_to.rb +1 -1
  25. data/lib/mongoid/association/referenced/counter_cache.rb +8 -8
  26. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +64 -11
  27. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +4 -1
  28. data/lib/mongoid/association/referenced/has_many/enumerable.rb +10 -18
  29. data/lib/mongoid/association/referenced/has_many/proxy.rb +12 -9
  30. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  31. data/lib/mongoid/association/referenced/has_one/proxy.rb +8 -11
  32. data/lib/mongoid/association/referenced/syncable.rb +2 -2
  33. data/lib/mongoid/association/relatable.rb +38 -4
  34. data/lib/mongoid/attributes/processing.rb +9 -2
  35. data/lib/mongoid/attributes.rb +30 -27
  36. data/lib/mongoid/cacheable.rb +2 -2
  37. data/lib/mongoid/changeable.rb +37 -2
  38. data/lib/mongoid/clients/options.rb +4 -0
  39. data/lib/mongoid/clients/sessions.rb +2 -14
  40. data/lib/mongoid/config.rb +15 -11
  41. data/lib/mongoid/contextual/aggregable/memory.rb +23 -15
  42. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  43. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  44. data/lib/mongoid/contextual/memory.rb +55 -28
  45. data/lib/mongoid/contextual/mongo.rb +173 -262
  46. data/lib/mongoid/contextual/none.rb +33 -15
  47. data/lib/mongoid/copyable.rb +32 -8
  48. data/lib/mongoid/criteria/includable.rb +24 -20
  49. data/lib/mongoid/criteria/marshalable.rb +10 -2
  50. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -15
  51. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  52. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  53. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  54. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  55. data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -16
  56. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  57. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  58. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  59. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +1 -1
  60. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
  61. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  62. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  63. data/lib/mongoid/criteria/queryable/optional.rb +3 -9
  64. data/lib/mongoid/criteria/queryable/options.rb +1 -1
  65. data/lib/mongoid/criteria/queryable/selectable.rb +2 -24
  66. data/lib/mongoid/criteria/queryable/selector.rb +89 -4
  67. data/lib/mongoid/criteria/queryable/smash.rb +39 -6
  68. data/lib/mongoid/criteria/queryable.rb +11 -6
  69. data/lib/mongoid/criteria.rb +1 -28
  70. data/lib/mongoid/deprecable.rb +36 -0
  71. data/lib/mongoid/deprecation.rb +25 -0
  72. data/lib/mongoid/document.rb +88 -33
  73. data/lib/mongoid/equality.rb +4 -4
  74. data/lib/mongoid/errors/document_not_found.rb +6 -2
  75. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  76. data/lib/mongoid/errors/invalid_field.rb +5 -1
  77. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  78. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  79. data/lib/mongoid/errors.rb +2 -2
  80. data/lib/mongoid/extensions/array.rb +8 -6
  81. data/lib/mongoid/extensions/big_decimal.rb +29 -10
  82. data/lib/mongoid/extensions/binary.rb +42 -0
  83. data/lib/mongoid/extensions/boolean.rb +8 -2
  84. data/lib/mongoid/extensions/date.rb +26 -20
  85. data/lib/mongoid/extensions/date_time.rb +1 -1
  86. data/lib/mongoid/extensions/float.rb +4 -5
  87. data/lib/mongoid/extensions/hash.rb +12 -5
  88. data/lib/mongoid/extensions/integer.rb +4 -5
  89. data/lib/mongoid/extensions/object.rb +2 -0
  90. data/lib/mongoid/extensions/range.rb +41 -10
  91. data/lib/mongoid/extensions/regexp.rb +11 -4
  92. data/lib/mongoid/extensions/set.rb +11 -4
  93. data/lib/mongoid/extensions/string.rb +2 -13
  94. data/lib/mongoid/extensions/symbol.rb +3 -14
  95. data/lib/mongoid/extensions/time.rb +27 -16
  96. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  97. data/lib/mongoid/extensions.rb +1 -0
  98. data/lib/mongoid/factory.rb +42 -7
  99. data/lib/mongoid/fields/foreign_key.rb +7 -0
  100. data/lib/mongoid/fields/validators/macro.rb +3 -9
  101. data/lib/mongoid/fields.rb +49 -7
  102. data/lib/mongoid/findable.rb +21 -16
  103. data/lib/mongoid/indexable/specification.rb +1 -1
  104. data/lib/mongoid/indexable/validators/options.rb +4 -1
  105. data/lib/mongoid/interceptable.rb +69 -9
  106. data/lib/mongoid/persistable/creatable.rb +14 -5
  107. data/lib/mongoid/persistable/updatable.rb +12 -5
  108. data/lib/mongoid/persistence_context.rb +8 -42
  109. data/lib/mongoid/query_cache.rb +6 -258
  110. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  111. data/lib/mongoid/reloadable.rb +7 -3
  112. data/lib/mongoid/scopable.rb +9 -11
  113. data/lib/mongoid/selectable.rb +1 -2
  114. data/lib/mongoid/shardable.rb +11 -35
  115. data/lib/mongoid/stateful.rb +27 -1
  116. data/lib/mongoid/timestamps/created.rb +1 -1
  117. data/lib/mongoid/timestamps/updated.rb +1 -1
  118. data/lib/mongoid/touchable.rb +2 -3
  119. data/lib/mongoid/traversable.rb +1 -0
  120. data/lib/mongoid/validatable/uniqueness.rb +2 -1
  121. data/lib/mongoid/version.rb +1 -1
  122. data/lib/mongoid/warnings.rb +3 -4
  123. data/lib/mongoid.rb +1 -0
  124. data/spec/config/mongoid.yml +16 -0
  125. data/spec/integration/app_spec.rb +8 -12
  126. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  127. data/spec/integration/associations/embedded_spec.rb +15 -0
  128. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  129. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  130. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  131. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  132. data/spec/integration/associations/has_one_spec.rb +97 -1
  133. data/spec/integration/associations/scope_option_spec.rb +1 -1
  134. data/spec/integration/callbacks_models.rb +95 -1
  135. data/spec/integration/callbacks_spec.rb +226 -4
  136. data/spec/integration/criteria/range_spec.rb +95 -1
  137. data/spec/integration/discriminator_key_spec.rb +115 -76
  138. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  139. data/spec/integration/i18n_fallbacks_spec.rb +1 -15
  140. data/spec/integration/matcher_examples_spec.rb +20 -13
  141. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  142. data/spec/integration/matcher_operator_spec.rb +3 -5
  143. data/spec/integration/persistence/range_field_spec.rb +350 -0
  144. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  145. data/spec/mongoid/association/depending_spec.rb +9 -9
  146. data/spec/mongoid/association/eager_spec.rb +2 -1
  147. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  148. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  149. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  150. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  151. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +198 -8
  152. data/spec/mongoid/association/embedded/embeds_many_models.rb +36 -0
  153. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  154. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  155. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  156. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  157. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  158. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  159. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  160. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  161. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  162. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  163. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +38 -5
  164. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  165. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  166. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  167. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  168. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +62 -13
  169. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  170. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  171. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  172. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  173. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  174. data/spec/mongoid/association/syncable_spec.rb +14 -0
  175. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  176. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  177. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  178. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  179. data/spec/mongoid/attributes_spec.rb +480 -27
  180. data/spec/mongoid/cacheable_spec.rb +3 -3
  181. data/spec/mongoid/changeable_spec.rb +130 -13
  182. data/spec/mongoid/clients/factory_spec.rb +23 -30
  183. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  184. data/spec/mongoid/clients_spec.rb +2 -2
  185. data/spec/mongoid/config_spec.rb +52 -14
  186. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  187. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  188. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  189. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  190. data/spec/mongoid/contextual/memory_spec.rb +521 -14
  191. data/spec/mongoid/contextual/mongo_spec.rb +566 -416
  192. data/spec/mongoid/contextual/none_spec.rb +11 -19
  193. data/spec/mongoid/copyable_spec.rb +451 -1
  194. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  195. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  196. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  197. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  198. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  199. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  200. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  201. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  202. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  203. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  204. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  205. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  206. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  207. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
  208. data/spec/mongoid/criteria/queryable/selectable_spec.rb +77 -85
  209. data/spec/mongoid/criteria/queryable/selector_spec.rb +14 -2
  210. data/spec/mongoid/criteria_spec.rb +469 -1201
  211. data/spec/mongoid/document_fields_spec.rb +173 -24
  212. data/spec/mongoid/document_spec.rb +32 -41
  213. data/spec/mongoid/equality_spec.rb +12 -12
  214. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  215. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  216. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  217. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  218. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  219. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  220. data/spec/mongoid/extensions/array_spec.rb +16 -2
  221. data/spec/mongoid/extensions/big_decimal_spec.rb +697 -212
  222. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  223. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  224. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  225. data/spec/mongoid/extensions/date_spec.rb +71 -1
  226. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  227. data/spec/mongoid/extensions/float_spec.rb +48 -76
  228. data/spec/mongoid/extensions/hash_spec.rb +30 -0
  229. data/spec/mongoid/extensions/integer_spec.rb +45 -66
  230. data/spec/mongoid/extensions/range_spec.rb +255 -54
  231. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  232. data/spec/mongoid/extensions/set_spec.rb +106 -0
  233. data/spec/mongoid/extensions/string_spec.rb +53 -25
  234. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  235. data/spec/mongoid/extensions/time_spec.rb +634 -66
  236. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  237. data/spec/mongoid/factory_spec.rb +61 -1
  238. data/spec/mongoid/fields_spec.rb +321 -50
  239. data/spec/mongoid/findable_spec.rb +64 -29
  240. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  241. data/spec/mongoid/indexable_spec.rb +16 -19
  242. data/spec/mongoid/interceptable_spec.rb +584 -5
  243. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  244. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  245. data/spec/mongoid/mongoizable_spec.rb +285 -0
  246. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  247. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  248. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  249. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  250. data/spec/mongoid/persistence_context_spec.rb +24 -0
  251. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  252. data/spec/mongoid/query_cache_spec.rb +0 -154
  253. data/spec/mongoid/reloadable_spec.rb +35 -2
  254. data/spec/mongoid/scopable_spec.rb +36 -34
  255. data/spec/mongoid/shardable_models.rb +0 -14
  256. data/spec/mongoid/shardable_spec.rb +61 -153
  257. data/spec/mongoid/stateful_spec.rb +28 -0
  258. data/spec/mongoid/timestamps_spec.rb +390 -0
  259. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  260. data/spec/mongoid/touchable_spec.rb +116 -0
  261. data/spec/mongoid/touchable_spec_models.rb +12 -8
  262. data/spec/mongoid/traversable_spec.rb +4 -11
  263. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  264. data/spec/mongoid/validatable/uniqueness_spec.rb +60 -31
  265. data/spec/mongoid/warnings_spec.rb +35 -0
  266. data/spec/mongoid_spec.rb +1 -7
  267. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  268. data/spec/rails/mongoid_spec.rb +4 -16
  269. data/spec/shared/lib/mrss/event_subscriber.rb +5 -15
  270. data/spec/shared/lib/mrss/lite_constraints.rb +0 -8
  271. data/spec/shared/shlib/server.sh +5 -5
  272. data/spec/support/constraints.rb +24 -0
  273. data/spec/support/macros.rb +30 -0
  274. data/spec/support/models/augmentation.rb +12 -0
  275. data/spec/support/models/band.rb +3 -0
  276. data/spec/support/models/catalog.rb +24 -0
  277. data/spec/support/models/circus.rb +3 -0
  278. data/spec/support/models/fanatic.rb +8 -0
  279. data/spec/support/models/implant.rb +9 -0
  280. data/spec/support/models/label.rb +2 -0
  281. data/spec/support/models/passport.rb +9 -0
  282. data/spec/support/models/person.rb +1 -0
  283. data/spec/support/models/player.rb +2 -0
  284. data/spec/support/models/powerup.rb +12 -0
  285. data/spec/support/models/registry.rb +1 -0
  286. data/spec/support/models/school.rb +14 -0
  287. data/spec/support/models/shield.rb +18 -0
  288. data/spec/support/models/student.rb +14 -0
  289. data/spec/support/models/weapon.rb +12 -0
  290. data.tar.gz.sig +0 -0
  291. metadata +669 -638
  292. metadata.gz.sig +0 -0
  293. data/lib/mongoid/errors/eager_load.rb +0 -23
  294. data/lib/mongoid/errors/invalid_value.rb +0 -17
  295. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -393,6 +393,22 @@ describe Mongoid::Fields do
393
393
  it "converts :time to Time" do
394
394
  expect(klass.field(:test, type: :time).type).to be(Time)
395
395
  end
396
+
397
+ context 'when using an unknown symbol' do
398
+ it 'raises InvalidFieldType' do
399
+ lambda do
400
+ klass.field(:test, type: :bogus)
401
+ end.should raise_error(Mongoid::Errors::InvalidFieldType, /defines a field 'test' with an unknown type value :bogus/)
402
+ end
403
+ end
404
+
405
+ context 'when using an unknown string' do
406
+ it 'raises InvalidFieldType' do
407
+ lambda do
408
+ klass.field(:test, type: 'bogus')
409
+ end.should raise_error(Mongoid::Errors::InvalidFieldType, /defines a field 'test' with an unknown type value "bogus"/)
410
+ end
411
+ end
396
412
  end
397
413
 
398
414
  context "when the options are valid" do
@@ -427,25 +443,25 @@ describe Mongoid::Fields do
427
443
  context "when the Symbol type is used" do
428
444
 
429
445
  before do
430
- Mongoid::Fields::Validators::Macro.class_eval do
431
- @field_type_is_symbol_warned = false
446
+ Mongoid::Warnings.class_eval do
447
+ @symbol_type_deprecated = false
432
448
  end
433
449
  end
434
450
 
435
451
  after do
436
- Band.fields.delete("should_warn")
452
+ Label.fields.delete("should_warn")
437
453
  end
438
454
 
439
455
  it "warns that the BSON symbol type is deprecated" do
440
456
  expect(Mongoid.logger).to receive(:warn)
441
457
 
442
- Band.field :should_warn, type: Symbol
458
+ Label.field :should_warn, type: Symbol
443
459
  end
444
460
 
445
461
  it "warns on first use of Symbol type only" do
446
462
  expect(Mongoid.logger).to receive(:warn).once
447
463
 
448
- Band.field :should_warn, type: Symbol
464
+ Label.field :should_warn, type: Symbol
449
465
  end
450
466
 
451
467
  context 'when using Symbol field type in multiple classes' do
@@ -456,7 +472,7 @@ describe Mongoid::Fields do
456
472
  it "warns on first use of Symbol type only" do
457
473
  expect(Mongoid.logger).to receive(:warn).once
458
474
 
459
- Band.field :should_warn, type: Symbol
475
+ Label.field :should_warn, type: Symbol
460
476
  Truck.field :should_warn, type: Symbol
461
477
  end
462
478
  end
@@ -466,7 +482,7 @@ describe Mongoid::Fields do
466
482
 
467
483
  it "raises an error" do
468
484
  expect {
469
- Band.field :unacceptable, bad: true
485
+ Label.field :unacceptable, bad: true
470
486
  }.to raise_error(Mongoid::Errors::InvalidFieldOption)
471
487
  end
472
488
  end
@@ -568,8 +584,144 @@ describe Mongoid::Fields do
568
584
  context "when the attribute has been assigned" do
569
585
 
570
586
  it "returns the attribute before type cast" do
571
- person.age = "old"
572
- expect(person.age_before_type_cast).to eq("old")
587
+ person.age = "42"
588
+ expect(person.age_before_type_cast).to eq("42")
589
+ end
590
+ end
591
+
592
+ context "when reloading" do
593
+
594
+ let(:product) do
595
+ Product.create!(price: '1')
596
+ end
597
+
598
+ before do
599
+ product.reload
600
+ end
601
+
602
+ it "resets the attributes_before_type_cast to the attributes hash" do
603
+ expect(product.attributes_before_type_cast).to eq(product.attributes)
604
+ end
605
+
606
+ it "the *_before_type_cast method returns the demongoized value" do
607
+ expect(product.price_before_type_cast).to eq(1)
608
+ end
609
+ end
610
+
611
+ context "when reloading and writing a demongoizable value" do
612
+
613
+ let(:product) do
614
+ Product.create!.tap do |product|
615
+ Product.collection.update_one({ _id: product.id }, { :$set => { price: '1' }})
616
+ end
617
+ end
618
+
619
+ before do
620
+ product.reload
621
+ end
622
+
623
+ it "resets the attributes_before_type_cast to the attributes hash" do
624
+ expect(product.attributes_before_type_cast).to eq(product.attributes)
625
+ end
626
+
627
+ it "the *_before_type_cast method returns the mongoized value" do
628
+ expect(product.price_before_type_cast).to eq('1')
629
+ end
630
+ end
631
+
632
+ context "when reading from the db" do
633
+
634
+ let(:product) do
635
+ Product.create!(price: '1')
636
+ end
637
+
638
+ let(:from_db) do
639
+ Product.find(product.id)
640
+ end
641
+
642
+ it "resets the attributes_before_type_cast to the attributes hash" do
643
+ expect(from_db.attributes_before_type_cast).to eq(from_db.attributes)
644
+ end
645
+
646
+ it "the *_before_type_cast method returns the demongoized value" do
647
+ expect(from_db.price_before_type_cast).to eq(1)
648
+ end
649
+ end
650
+
651
+ context "when reading from the db after writing a demongoizable value" do
652
+
653
+ let(:product) do
654
+ Product.create!.tap do |product|
655
+ Product.collection.update_one({ _id: product.id }, { :$set => { price: '1' }})
656
+ end
657
+ end
658
+
659
+ let(:from_db) do
660
+ Product.find(product.id)
661
+ end
662
+
663
+ it "resets the attributes_before_type_cast to the attributes hash" do
664
+ expect(from_db.attributes_before_type_cast).to eq(from_db.attributes)
665
+ end
666
+
667
+ it "the *_before_type_cast method returns the mongoized value" do
668
+ expect(from_db.price_before_type_cast).to eq('1')
669
+ end
670
+ end
671
+
672
+ context "when making a new model" do
673
+
674
+ context "when using new with no options" do
675
+ let(:product) { Product.new }
676
+
677
+ it "sets the attributes_before_type_cast to the attributes hash" do
678
+ expect(product.attributes_before_type_cast).to eq(product.attributes)
679
+ end
680
+ end
681
+
682
+ context "when using new with options" do
683
+ let(:product) { Product.new(price: '1') }
684
+
685
+ let(:abtc) do
686
+ product.attributes.merge('price' => '1')
687
+ end
688
+
689
+ it "has the attributes before type cast" do
690
+ expect(product.attributes_before_type_cast).to eq(abtc)
691
+ end
692
+ end
693
+
694
+ context "when persisting the model" do
695
+ let(:product) { Product.new(price: '1') }
696
+
697
+ let(:abtc) do
698
+ product.attributes.merge('price' => '1')
699
+ end
700
+
701
+ before do
702
+ expect(product.attributes_before_type_cast).to eq(abtc)
703
+ product.save!
704
+ end
705
+
706
+ it "resets the attributes_before_type_cast to the attributes" do
707
+ expect(product.attributes_before_type_cast).to eq(product.attributes)
708
+ end
709
+ end
710
+
711
+ context "when using create! without options" do
712
+ let(:product) { Product.create! }
713
+
714
+ it "resets the attributes_before_type_cast to the attributes" do
715
+ expect(product.attributes_before_type_cast).to eq(product.attributes)
716
+ end
717
+ end
718
+
719
+ context "when using create! with options" do
720
+ let(:product) { Product.create!(price: '1') }
721
+
722
+ it "resets the attributes_before_type_cast to the attributes" do
723
+ expect(product.attributes_before_type_cast).to eq(product.attributes)
724
+ end
573
725
  end
574
726
  end
575
727
  end
@@ -725,6 +877,22 @@ describe Mongoid::Fields do
725
877
  end
726
878
  end
727
879
  end
880
+
881
+ context "when the field needs to be mongoized" do
882
+
883
+ before do
884
+ product.price = "1"
885
+ product.save!
886
+ end
887
+
888
+ it "mongoizes the value" do
889
+ expect(product.price).to eq(1)
890
+ end
891
+
892
+ it "stores the value in the mongoized form" do
893
+ expect(product.attributes_before_type_cast["price"]).to eq(1)
894
+ end
895
+ end
728
896
  end
729
897
 
730
898
  describe "#defaults" do
@@ -861,7 +1029,7 @@ describe Mongoid::Fields do
861
1029
  it "raises an error" do
862
1030
  expect {
863
1031
  Person.field(meth)
864
- }.to raise_error(Mongoid::Errors::InvalidField)
1032
+ }.to raise_error(Mongoid::Errors::InvalidField, /Defining a field named '#{meth}' is not allowed/)
865
1033
  end
866
1034
  end
867
1035
  end
@@ -988,7 +1156,7 @@ describe Mongoid::Fields do
988
1156
  end
989
1157
 
990
1158
  it "uses the alias to write the attribute" do
991
- (person.alias = expect(true)).to be true
1159
+ expect(person.alias = true).to be true
992
1160
  end
993
1161
 
994
1162
  it "uses the alias to read the attribute" do
@@ -1000,7 +1168,7 @@ describe Mongoid::Fields do
1000
1168
  end
1001
1169
 
1002
1170
  it "uses the name to write the attribute" do
1003
- (person.aliased = expect(true)).to be true
1171
+ expect(person.aliased = true).to be true
1004
1172
  end
1005
1173
 
1006
1174
  it "uses the name to read the attribute" do
@@ -1229,71 +1397,147 @@ describe Mongoid::Fields do
1229
1397
 
1230
1398
  context "when a field is defined as a big decimal" do
1231
1399
 
1232
- let(:band) do
1233
- Band.new(name: "Tool")
1234
- end
1235
-
1236
- let(:decimal) do
1237
- BigDecimal("1000000.00")
1238
- end
1239
-
1240
- context "when setting to a big decimal" do
1400
+ context 'when Mongoid.map_big_decimal_to_decimal128 is false' do
1401
+ config_override :map_big_decimal_to_decimal128, false
1241
1402
 
1242
- before do
1243
- band.sales = decimal
1403
+ let(:band) do
1404
+ Band.new(name: "Tool")
1244
1405
  end
1245
1406
 
1246
- it "properly persists as a string" do
1247
- expect(band.attributes["sales"]).to eq(decimal.to_s)
1407
+ let(:decimal) do
1408
+ BigDecimal("1000000.00")
1248
1409
  end
1249
1410
 
1250
- it "returns the proper big decimal" do
1251
- expect(band.sales).to eq(decimal)
1411
+ context "when setting to a big decimal" do
1412
+
1413
+ before do
1414
+ band.sales = decimal
1415
+ end
1416
+
1417
+ it "properly persists as a string" do
1418
+ expect(band.attributes["sales"]).to eq(decimal.to_s)
1419
+ end
1420
+
1421
+ it "returns the proper big decimal" do
1422
+ expect(band.sales).to eq(decimal)
1423
+ end
1252
1424
  end
1253
- end
1254
1425
 
1255
- context "when setting to a string" do
1426
+ context "when setting to a string" do
1256
1427
 
1257
- before do
1258
- band.sales = decimal.to_s
1428
+ before do
1429
+ band.sales = decimal.to_s
1430
+ end
1431
+
1432
+ it "properly persists as a string" do
1433
+ expect(band.attributes["sales"]).to eq(decimal.to_s)
1434
+ end
1435
+
1436
+ it "returns the proper big decimal" do
1437
+ expect(band.sales).to eq(decimal)
1438
+ end
1259
1439
  end
1260
1440
 
1261
- it "properly persists as a string" do
1262
- expect(band.attributes["sales"]).to eq(decimal.to_s)
1441
+ context "when setting to an integer" do
1442
+
1443
+ before do
1444
+ band.sales = decimal.to_i
1445
+ end
1446
+
1447
+ it "properly persists as a string" do
1448
+ expect(band.attributes["sales"]).to eq("1000000")
1449
+ end
1450
+
1451
+ it "returns the proper big decimal" do
1452
+ expect(band.sales).to eq(decimal)
1453
+ end
1263
1454
  end
1264
1455
 
1265
- it "returns the proper big decimal" do
1266
- expect(band.sales).to eq(decimal)
1456
+ context "when setting to a float" do
1457
+
1458
+ before do
1459
+ band.sales = decimal.to_f
1460
+ end
1461
+
1462
+ it "properly persists as a string" do
1463
+ expect(band.attributes["sales"]).to eq(decimal.to_s)
1464
+ end
1465
+
1466
+ it "returns the proper big decimal" do
1467
+ expect(band.sales).to eq(decimal)
1468
+ end
1267
1469
  end
1268
1470
  end
1269
1471
 
1270
- context "when setting to an integer" do
1472
+ context 'when Mongoid.map_big_decimal_to_decimal128 is true' do
1473
+ config_override :map_big_decimal_to_decimal128, true
1271
1474
 
1272
- before do
1273
- band.sales = decimal.to_i
1475
+ let(:band) do
1476
+ Band.new(name: "Tool")
1274
1477
  end
1275
1478
 
1276
- it "properly persists as a string" do
1277
- expect(band.attributes["sales"]).to eq("1000000")
1479
+ let(:decimal) do
1480
+ BigDecimal("1000000.00")
1278
1481
  end
1279
1482
 
1280
- it "returns the proper big decimal" do
1281
- expect(band.sales).to eq(decimal)
1483
+ context "when setting to a big decimal" do
1484
+
1485
+ before do
1486
+ band.sales = decimal
1487
+ end
1488
+
1489
+ it "properly persists as a BSON::Decimal128" do
1490
+ expect(band.attributes["sales"]).to eq(BSON::Decimal128.new(decimal))
1491
+ end
1492
+
1493
+ it "returns the proper big decimal" do
1494
+ expect(band.sales).to eq(decimal)
1495
+ end
1282
1496
  end
1283
- end
1284
1497
 
1285
- context "when setting to a float" do
1498
+ context "when setting to a string" do
1286
1499
 
1287
- before do
1288
- band.sales = decimal.to_f
1500
+ before do
1501
+ band.sales = decimal.to_s
1502
+ end
1503
+
1504
+ it "persists as a BSON::Decimal128" do
1505
+ expect(band.attributes["sales"]).to eq(BSON::Decimal128.new(decimal.to_s))
1506
+ end
1507
+
1508
+ it "returns the proper big decimal" do
1509
+ expect(band.sales).to eq(decimal)
1510
+ end
1289
1511
  end
1290
1512
 
1291
- it "properly persists as a string" do
1292
- expect(band.attributes["sales"]).to eq(decimal.to_s)
1513
+ context "when setting to an integer" do
1514
+
1515
+ before do
1516
+ band.sales = decimal.to_i
1517
+ end
1518
+
1519
+ it "persists as a BSON::Decimal128" do
1520
+ expect(band.attributes["sales"]).to eq(BSON::Decimal128.new(decimal.to_i.to_s))
1521
+ end
1522
+
1523
+ it "returns the proper big decimal" do
1524
+ expect(band.sales).to eq(decimal)
1525
+ end
1293
1526
  end
1294
1527
 
1295
- it "returns the proper big decimal" do
1296
- expect(band.sales).to eq(decimal)
1528
+ context "when setting to a float" do
1529
+
1530
+ before do
1531
+ band.sales = decimal.to_f
1532
+ end
1533
+
1534
+ it "properly persists as a BSON::Decimal128" do
1535
+ expect(band.attributes["sales"]).to eq(BSON::Decimal128.new(decimal.to_f.to_s))
1536
+ end
1537
+
1538
+ it "returns the proper big decimal" do
1539
+ expect(band.sales).to eq(decimal)
1540
+ end
1297
1541
  end
1298
1542
  end
1299
1543
  end
@@ -1620,6 +1864,33 @@ describe Mongoid::Fields do
1620
1864
  it_behaves_like 'pre-fix database_field_name'
1621
1865
  end
1622
1866
  end
1867
+
1868
+ context 'when getting the database field name of a belongs_to associations' do
1869
+ # These tests only apply when the flag is not set
1870
+ config_override :broken_alias_handling, false
1871
+
1872
+ context "when the broken_alias_handling is not set" do
1873
+ context "when the association is the last item" do
1874
+ let(:name) do
1875
+ Game.database_field_name("person")
1876
+ end
1877
+
1878
+ it "gets the alias" do
1879
+ expect(name).to eq("person_id")
1880
+ end
1881
+ end
1882
+
1883
+ context "when the association is not the last item" do
1884
+ let(:name) do
1885
+ Game.database_field_name("person.name")
1886
+ end
1887
+
1888
+ it "gets the alias" do
1889
+ expect(name).to eq("person.name")
1890
+ end
1891
+ end
1892
+ end
1893
+ end
1623
1894
  end
1624
1895
 
1625
1896
  describe "#get_field" do
@@ -85,7 +85,7 @@ describe Mongoid::Findable do
85
85
  it "raises an error" do
86
86
  expect {
87
87
  person.messages.find_by(body: 'bar')
88
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
88
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class Message with attributes/)
89
89
  end
90
90
  end
91
91
 
@@ -144,7 +144,7 @@ describe Mongoid::Findable do
144
144
  it "raises an error" do
145
145
  expect {
146
146
  Person.find_by(ssn: "333-22-1111")
147
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
147
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class Person with attributes/)
148
148
  end
149
149
  end
150
150
 
@@ -213,7 +213,7 @@ describe Mongoid::Findable do
213
213
  it "raises an error" do
214
214
  expect {
215
215
  Person.find_by!(ssn: "333-22-1111")
216
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
216
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class Person with attributes/)
217
217
  end
218
218
  end
219
219
  end
@@ -230,14 +230,8 @@ describe Mongoid::Findable do
230
230
  expect(Person.send(method)).to eq(person)
231
231
  end
232
232
 
233
- it "doen't raise when passing options" do
234
- expect do
235
- Person.first(id_sort: :none)
236
- end.to_not raise_error
237
- end
238
-
239
233
  it "passes the limit through" do
240
- Person.first(1).length.should == 1
234
+ expect(Person.last(1)).to eq([ person ])
241
235
  end
242
236
  end
243
237
  end
@@ -251,14 +245,8 @@ describe Mongoid::Findable do
251
245
  expect(Person.last).to eq(person)
252
246
  end
253
247
 
254
- it "doen't raise when passing options" do
255
- expect do
256
- Person.last(id_sort: :none)
257
- end.to_not raise_error
258
- end
259
-
260
248
  it "passes the limit through" do
261
- Person.last(1).length.should == 1
249
+ expect(Person.last(1)).to eq([ person ])
262
250
  end
263
251
  end
264
252
 
@@ -502,7 +490,7 @@ describe Mongoid::Findable do
502
490
  Band.pluck(:follows)
503
491
  end
504
492
 
505
- it "returns a array with nil values" do
493
+ it "returns an array with nil values" do
506
494
  expect(plucked).to eq([nil, nil, nil])
507
495
  end
508
496
  end
@@ -551,10 +539,10 @@ describe Mongoid::Findable do
551
539
  end
552
540
 
553
541
  context 'when Mongoid is configured to use activesupport time zone' do
542
+ config_override :use_utc, false
543
+ config_override :use_activesupport_time_zone, true
554
544
 
555
545
  before do
556
- Mongoid.use_utc = false
557
- Mongoid.use_activesupport_time_zone = true
558
546
  Time.zone = "Asia/Kolkata"
559
547
  end
560
548
 
@@ -564,8 +552,33 @@ describe Mongoid::Findable do
564
552
  end
565
553
  end
566
554
 
567
- it 'uses activesupport time zone' do
568
- expect(User.distinct(:last_login).first.to_s).to eql(time.in_time_zone('Asia/Kolkata').to_s)
555
+ context 'when distinct does not demongoize' do
556
+ config_override :legacy_pluck_distinct, true
557
+
558
+ let(:distinct) do
559
+ User.distinct(:last_login).first
560
+ end
561
+
562
+ it 'uses activesupport time zone' do
563
+ distinct.should be_a(ActiveSupport::TimeWithZone)
564
+ expect(distinct.to_s).to eql(time.in_time_zone('Asia/Kolkata').to_s)
565
+ end
566
+ end
567
+
568
+ context 'when distinct demongoizes' do
569
+ config_override :legacy_pluck_distinct, false
570
+
571
+ let(:distinct) do
572
+ User.distinct(:last_login).first
573
+ end
574
+
575
+ it 'uses activesupport time zone' do
576
+ distinct.should be_a(DateTime)
577
+ # Time and DateTime have different stringifications:
578
+ # 2022-03-16T21:12:32+00:00
579
+ # 2022-03-16 21:12:32 UTC
580
+ expect(distinct.to_s).to eql(time.in_time_zone('Asia/Kolkata').to_datetime.to_s)
581
+ end
569
582
  end
570
583
 
571
584
  it 'loads other fields accurately' do
@@ -574,11 +587,8 @@ describe Mongoid::Findable do
574
587
  end
575
588
 
576
589
  context 'when Mongoid is not configured to use activesupport time zone' do
577
-
578
- before do
579
- Mongoid.use_utc = true
580
- Mongoid.use_activesupport_time_zone = false
581
- end
590
+ config_override :use_utc, true
591
+ config_override :use_activesupport_time_zone, false
582
592
 
583
593
  let!(:time) do
584
594
  Time.now.tap do |t|
@@ -586,8 +596,33 @@ describe Mongoid::Findable do
586
596
  end
587
597
  end
588
598
 
589
- it 'uses utc' do
590
- expect(User.distinct(:last_login).first.to_s).to eql(time.utc.to_s)
599
+ context 'when distinct does not demongoize' do
600
+ config_override :legacy_pluck_distinct, true
601
+
602
+ let(:distinct) do
603
+ User.distinct(:last_login).first
604
+ end
605
+
606
+ it 'uses utc' do
607
+ distinct.should be_a(Time)
608
+ expect(distinct.to_s).to eql(time.utc.to_s)
609
+ end
610
+ end
611
+
612
+ context 'when distinct demongoizes' do
613
+ config_override :legacy_pluck_distinct, false
614
+
615
+ let(:distinct) do
616
+ User.distinct(:last_login).first
617
+ end
618
+
619
+ it 'uses utc' do
620
+ distinct.should be_a(DateTime)
621
+ # Time and DateTime have different stringifications:
622
+ # 2022-03-16T21:12:32+00:00
623
+ # 2022-03-16 21:12:32 UTC
624
+ expect(distinct.to_s).to eql(time.utc.to_datetime.to_s)
625
+ end
591
626
  end
592
627
 
593
628
  it 'loads other fields accurately' do
@@ -85,7 +85,7 @@ describe Mongoid::Indexable::Specification do
85
85
  Band,
86
86
  { name: 1, title: 1, years: -1 },
87
87
  background: true,
88
- drop_dups: true
88
+ unique: true
89
89
  )
90
90
  end
91
91
 
@@ -98,7 +98,7 @@ describe Mongoid::Indexable::Specification do
98
98
  end
99
99
 
100
100
  it "normalizes the options" do
101
- expect(spec.options).to eq(background: true, drop_dups: true)
101
+ expect(spec.options).to eq(background: true, unique: true)
102
102
  end
103
103
  end
104
104