mongoid 7.4.0 → 8.0.3

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 (391) 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 +52 -28
  5. data/lib/mongoid/association/accessors.rb +38 -9
  6. data/lib/mongoid/association/bindable.rb +50 -2
  7. data/lib/mongoid/association/builders.rb +4 -2
  8. data/lib/mongoid/association/constrainable.rb +0 -1
  9. data/lib/mongoid/association/eager_loadable.rb +29 -7
  10. data/lib/mongoid/association/embedded/batchable.rb +53 -13
  11. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  12. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  13. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -2
  14. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  15. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  16. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  17. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +50 -28
  18. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  19. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  20. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +23 -4
  21. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  22. data/lib/mongoid/association/macros.rb +22 -1
  23. data/lib/mongoid/association/many.rb +11 -7
  24. data/lib/mongoid/association/nested/many.rb +5 -4
  25. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  26. data/lib/mongoid/association/nested/one.rb +5 -5
  27. data/lib/mongoid/association/one.rb +2 -2
  28. data/lib/mongoid/association/options.rb +9 -9
  29. data/lib/mongoid/association/proxy.rb +14 -3
  30. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  31. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  32. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  33. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  34. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  35. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  36. data/lib/mongoid/association/referenced/eager.rb +2 -2
  37. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +66 -13
  38. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  39. data/lib/mongoid/association/referenced/has_many/enumerable.rb +20 -24
  40. data/lib/mongoid/association/referenced/has_many/proxy.rb +24 -18
  41. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  42. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  43. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  44. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  45. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  46. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  47. data/lib/mongoid/association/reflections.rb +2 -2
  48. data/lib/mongoid/association/relatable.rb +44 -10
  49. data/lib/mongoid/association.rb +5 -5
  50. data/lib/mongoid/atomic/modifiers.rb +2 -2
  51. data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
  52. data/lib/mongoid/attributes/dynamic.rb +3 -3
  53. data/lib/mongoid/attributes/nested.rb +5 -5
  54. data/lib/mongoid/attributes/processing.rb +10 -3
  55. data/lib/mongoid/attributes/projector.rb +1 -1
  56. data/lib/mongoid/attributes/readonly.rb +2 -2
  57. data/lib/mongoid/attributes.rb +43 -40
  58. data/lib/mongoid/cacheable.rb +2 -2
  59. data/lib/mongoid/changeable.rb +42 -7
  60. data/lib/mongoid/clients/options.rb +5 -1
  61. data/lib/mongoid/clients/sessions.rb +2 -14
  62. data/lib/mongoid/clients/validators/storage.rb +3 -3
  63. data/lib/mongoid/config/environment.rb +20 -4
  64. data/lib/mongoid/config/validators/client.rb +6 -6
  65. data/lib/mongoid/config.rb +32 -17
  66. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  67. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  68. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  69. data/lib/mongoid/contextual/atomic.rb +1 -1
  70. data/lib/mongoid/contextual/geo_near.rb +7 -7
  71. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  72. data/lib/mongoid/contextual/memory.rb +180 -21
  73. data/lib/mongoid/contextual/mongo.rb +237 -217
  74. data/lib/mongoid/contextual/none.rb +67 -5
  75. data/lib/mongoid/contextual/queryable.rb +1 -1
  76. data/lib/mongoid/contextual.rb +2 -2
  77. data/lib/mongoid/copyable.rb +32 -8
  78. data/lib/mongoid/criteria/findable.rb +7 -4
  79. data/lib/mongoid/criteria/includable.rb +24 -20
  80. data/lib/mongoid/criteria/marshalable.rb +10 -2
  81. data/lib/mongoid/criteria/permission.rb +1 -1
  82. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  83. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -13
  84. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  85. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  86. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  87. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  88. data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -14
  89. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  90. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  91. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  92. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  93. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  94. data/lib/mongoid/criteria/queryable/extensions/string.rb +3 -3
  95. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -2
  96. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  97. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  98. data/lib/mongoid/criteria/queryable/key.rb +3 -3
  99. data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
  100. data/lib/mongoid/criteria/queryable/optional.rb +5 -11
  101. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  102. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  103. data/lib/mongoid/criteria/queryable/selectable.rb +31 -37
  104. data/lib/mongoid/criteria/queryable/selector.rb +92 -7
  105. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  106. data/lib/mongoid/criteria/queryable.rb +12 -7
  107. data/lib/mongoid/criteria/scopable.rb +2 -2
  108. data/lib/mongoid/criteria.rb +15 -35
  109. data/lib/mongoid/deprecable.rb +36 -0
  110. data/lib/mongoid/deprecation.rb +25 -0
  111. data/lib/mongoid/document.rb +98 -34
  112. data/lib/mongoid/equality.rb +12 -12
  113. data/lib/mongoid/errors/document_not_found.rb +33 -12
  114. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  115. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  116. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  117. data/lib/mongoid/errors/invalid_field.rb +6 -2
  118. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  119. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  120. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  121. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  122. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  123. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  124. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  125. data/lib/mongoid/errors/no_client_database.rb +1 -1
  126. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  127. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  128. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  129. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  130. data/lib/mongoid/errors.rb +2 -2
  131. data/lib/mongoid/extensions/array.rb +9 -7
  132. data/lib/mongoid/extensions/big_decimal.rb +33 -10
  133. data/lib/mongoid/extensions/binary.rb +42 -0
  134. data/lib/mongoid/extensions/boolean.rb +8 -2
  135. data/lib/mongoid/extensions/date.rb +26 -20
  136. data/lib/mongoid/extensions/date_time.rb +1 -1
  137. data/lib/mongoid/extensions/false_class.rb +1 -1
  138. data/lib/mongoid/extensions/float.rb +7 -4
  139. data/lib/mongoid/extensions/hash.rb +13 -6
  140. data/lib/mongoid/extensions/integer.rb +7 -4
  141. data/lib/mongoid/extensions/module.rb +1 -1
  142. data/lib/mongoid/extensions/object.rb +8 -6
  143. data/lib/mongoid/extensions/range.rb +41 -10
  144. data/lib/mongoid/extensions/regexp.rb +11 -4
  145. data/lib/mongoid/extensions/set.rb +11 -4
  146. data/lib/mongoid/extensions/string.rb +11 -22
  147. data/lib/mongoid/extensions/symbol.rb +4 -15
  148. data/lib/mongoid/extensions/time.rb +27 -16
  149. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  150. data/lib/mongoid/extensions/true_class.rb +1 -1
  151. data/lib/mongoid/extensions.rb +1 -0
  152. data/lib/mongoid/factory.rb +42 -7
  153. data/lib/mongoid/fields/foreign_key.rb +11 -4
  154. data/lib/mongoid/fields/localized.rb +9 -4
  155. data/lib/mongoid/fields/standard.rb +7 -7
  156. data/lib/mongoid/fields/validators/macro.rb +3 -9
  157. data/lib/mongoid/fields.rb +201 -35
  158. data/lib/mongoid/findable.rb +34 -13
  159. data/lib/mongoid/indexable/specification.rb +2 -2
  160. data/lib/mongoid/indexable/validators/options.rb +6 -2
  161. data/lib/mongoid/interceptable.rb +73 -13
  162. data/lib/mongoid/matchable.rb +1 -1
  163. data/lib/mongoid/matcher.rb +12 -7
  164. data/lib/mongoid/persistable/creatable.rb +18 -9
  165. data/lib/mongoid/persistable/deletable.rb +1 -1
  166. data/lib/mongoid/persistable/destroyable.rb +1 -1
  167. data/lib/mongoid/persistable/savable.rb +2 -2
  168. data/lib/mongoid/persistable/unsettable.rb +1 -1
  169. data/lib/mongoid/persistable/updatable.rb +19 -12
  170. data/lib/mongoid/persistable/upsertable.rb +2 -2
  171. data/lib/mongoid/persistable.rb +3 -3
  172. data/lib/mongoid/persistence_context.rb +63 -10
  173. data/lib/mongoid/query_cache.rb +8 -260
  174. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  175. data/lib/mongoid/reloadable.rb +7 -3
  176. data/lib/mongoid/scopable.rb +26 -22
  177. data/lib/mongoid/selectable.rb +1 -2
  178. data/lib/mongoid/serializable.rb +10 -6
  179. data/lib/mongoid/stateful.rb +35 -9
  180. data/lib/mongoid/tasks/database.rb +0 -2
  181. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  182. data/lib/mongoid/threaded.rb +12 -12
  183. data/lib/mongoid/timestamps/created.rb +1 -1
  184. data/lib/mongoid/timestamps/updated.rb +2 -2
  185. data/lib/mongoid/touchable.rb +2 -3
  186. data/lib/mongoid/traversable.rb +8 -4
  187. data/lib/mongoid/validatable/localizable.rb +1 -1
  188. data/lib/mongoid/validatable/macros.rb +0 -2
  189. data/lib/mongoid/validatable/presence.rb +2 -2
  190. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  191. data/lib/mongoid/validatable.rb +6 -6
  192. data/lib/mongoid/version.rb +1 -1
  193. data/lib/mongoid/warnings.rb +28 -0
  194. data/lib/mongoid.rb +2 -0
  195. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +11 -5
  196. data/spec/config/mongoid.yml +16 -0
  197. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  198. data/spec/integration/app_spec.rb +28 -26
  199. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  200. data/spec/integration/associations/embedded_dirty_spec.rb +28 -0
  201. data/spec/integration/associations/embedded_spec.rb +15 -0
  202. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  203. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  204. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  205. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  206. data/spec/integration/associations/has_one_spec.rb +97 -1
  207. data/spec/integration/associations/scope_option_spec.rb +1 -1
  208. data/spec/integration/callbacks_models.rb +95 -1
  209. data/spec/integration/callbacks_spec.rb +226 -4
  210. data/spec/integration/criteria/range_spec.rb +95 -1
  211. data/spec/integration/discriminator_key_spec.rb +115 -76
  212. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  213. data/spec/integration/i18n_fallbacks_spec.rb +1 -17
  214. data/spec/integration/matcher_examples_spec.rb +20 -13
  215. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  216. data/spec/integration/matcher_operator_spec.rb +3 -5
  217. data/spec/integration/persistence/range_field_spec.rb +350 -0
  218. data/spec/lite_spec_helper.rb +1 -1
  219. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  220. data/spec/mongoid/association/depending_spec.rb +9 -9
  221. data/spec/mongoid/association/eager_spec.rb +2 -1
  222. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  223. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  224. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  225. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  226. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +219 -8
  227. data/spec/mongoid/association/embedded/embeds_many_models.rb +157 -0
  228. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  229. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  230. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  231. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  232. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  233. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  234. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  235. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  236. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  237. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  238. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +67 -4
  239. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  240. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  241. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  242. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +8 -8
  243. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +82 -13
  244. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  245. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  246. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  247. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  248. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  249. data/spec/mongoid/association/syncable_spec.rb +14 -0
  250. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  251. data/spec/mongoid/atomic_spec.rb +22 -0
  252. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  253. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  254. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  255. data/spec/mongoid/attributes_spec.rb +524 -27
  256. data/spec/mongoid/cacheable_spec.rb +3 -3
  257. data/spec/mongoid/changeable_spec.rb +130 -13
  258. data/spec/mongoid/clients/factory_spec.rb +34 -42
  259. data/spec/mongoid/clients/options_spec.rb +1 -0
  260. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  261. data/spec/mongoid/clients_spec.rb +57 -2
  262. data/spec/mongoid/config/environment_spec.rb +39 -1
  263. data/spec/mongoid/config_spec.rb +104 -13
  264. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  265. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  266. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  267. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  268. data/spec/mongoid/contextual/memory_spec.rb +1336 -69
  269. data/spec/mongoid/contextual/mongo_spec.rb +1105 -174
  270. data/spec/mongoid/contextual/none_spec.rb +38 -0
  271. data/spec/mongoid/copyable_spec.rb +451 -1
  272. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  273. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  274. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  275. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  276. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  277. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  278. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  279. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  280. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  281. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  282. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  283. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  284. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  285. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
  286. data/spec/mongoid/criteria/queryable/selectable_spec.rb +289 -124
  287. data/spec/mongoid/criteria/queryable/selector_spec.rb +14 -2
  288. data/spec/mongoid/criteria_projection_spec.rb +0 -1
  289. data/spec/mongoid/criteria_spec.rb +475 -1199
  290. data/spec/mongoid/document_fields_spec.rb +173 -24
  291. data/spec/mongoid/document_spec.rb +32 -41
  292. data/spec/mongoid/equality_spec.rb +12 -12
  293. data/spec/mongoid/errors/document_not_found_spec.rb +76 -0
  294. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  295. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  296. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  297. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  298. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  299. data/spec/mongoid/extensions/array_spec.rb +16 -2
  300. data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
  301. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  302. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  303. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  304. data/spec/mongoid/extensions/date_spec.rb +71 -1
  305. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  306. data/spec/mongoid/extensions/float_spec.rb +53 -74
  307. data/spec/mongoid/extensions/hash_spec.rb +30 -0
  308. data/spec/mongoid/extensions/integer_spec.rb +50 -64
  309. data/spec/mongoid/extensions/range_spec.rb +255 -54
  310. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  311. data/spec/mongoid/extensions/set_spec.rb +106 -0
  312. data/spec/mongoid/extensions/string_spec.rb +53 -25
  313. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  314. data/spec/mongoid/extensions/time_spec.rb +634 -66
  315. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  316. data/spec/mongoid/factory_spec.rb +61 -1
  317. data/spec/mongoid/fields/localized_spec.rb +37 -12
  318. data/spec/mongoid/fields_spec.rb +321 -50
  319. data/spec/mongoid/findable_spec.rb +80 -15
  320. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  321. data/spec/mongoid/indexable_spec.rb +39 -20
  322. data/spec/mongoid/interceptable_spec.rb +584 -5
  323. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  324. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  325. data/spec/mongoid/mongoizable_spec.rb +285 -0
  326. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  327. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  328. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  329. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  330. data/spec/mongoid/persistence_context_spec.rb +50 -1
  331. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  332. data/spec/mongoid/query_cache_spec.rb +0 -154
  333. data/spec/mongoid/reloadable_spec.rb +35 -2
  334. data/spec/mongoid/scopable_spec.rb +54 -16
  335. data/spec/mongoid/shardable_spec.rb +14 -0
  336. data/spec/mongoid/stateful_spec.rb +28 -0
  337. data/spec/mongoid/timestamps_spec.rb +390 -0
  338. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  339. data/spec/mongoid/touchable_spec.rb +116 -0
  340. data/spec/mongoid/touchable_spec_models.rb +12 -8
  341. data/spec/mongoid/traversable_spec.rb +4 -11
  342. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  343. data/spec/mongoid/validatable/uniqueness_spec.rb +59 -31
  344. data/spec/mongoid/warnings_spec.rb +35 -0
  345. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  346. data/spec/rails/mongoid_spec.rb +4 -16
  347. data/spec/shared/lib/mrss/constraints.rb +8 -16
  348. data/spec/shared/lib/mrss/docker_runner.rb +23 -3
  349. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  350. data/spec/shared/lib/mrss/lite_constraints.rb +32 -1
  351. data/spec/shared/share/Dockerfile.erb +34 -48
  352. data/spec/shared/shlib/config.sh +27 -0
  353. data/spec/shared/shlib/server.sh +32 -19
  354. data/spec/shared/shlib/set_env.sh +37 -0
  355. data/spec/support/constraints.rb +24 -0
  356. data/spec/support/macros.rb +55 -0
  357. data/spec/support/models/augmentation.rb +12 -0
  358. data/spec/support/models/band.rb +3 -0
  359. data/spec/support/models/catalog.rb +24 -0
  360. data/spec/support/models/circus.rb +3 -0
  361. data/spec/support/models/code.rb +2 -0
  362. data/spec/support/models/fanatic.rb +8 -0
  363. data/spec/support/models/implant.rb +9 -0
  364. data/spec/support/models/label.rb +2 -0
  365. data/spec/support/models/membership.rb +1 -0
  366. data/spec/support/models/passport.rb +9 -0
  367. data/spec/support/models/person.rb +1 -0
  368. data/spec/support/models/player.rb +2 -0
  369. data/spec/support/models/powerup.rb +12 -0
  370. data/spec/support/models/registry.rb +1 -0
  371. data/spec/support/models/school.rb +14 -0
  372. data/spec/support/models/shield.rb +18 -0
  373. data/spec/support/models/student.rb +14 -0
  374. data/spec/support/models/weapon.rb +12 -0
  375. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  376. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  377. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  378. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  379. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  380. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  381. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  382. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  383. data/spec/support/schema_maps/schema_map_local.json +18 -0
  384. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  385. data/spec/support/spec_config.rb +4 -0
  386. data.tar.gz.sig +0 -0
  387. metadata +682 -619
  388. metadata.gz.sig +0 -0
  389. data/lib/mongoid/errors/eager_load.rb +0 -23
  390. data/lib/mongoid/errors/invalid_value.rb +0 -17
  391. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -103,4 +103,116 @@ describe Mongoid::Association::Embedded::EmbedsMany::Buildable do
103
103
  end
104
104
  end
105
105
  end
106
+
107
+ context 'when the object is already associated with another object' do
108
+
109
+ context "when using <<" do
110
+
111
+ let(:person1) do
112
+ Person.new
113
+ end
114
+
115
+ let(:person2) do
116
+ Person.new
117
+ end
118
+
119
+ let(:appointment) do
120
+ Appointment.new
121
+ end
122
+
123
+ before do
124
+ person1.appointments << appointment
125
+ person2.appointments << appointment
126
+ end
127
+
128
+ it 'clears the object of its previous association' do
129
+ expect(person1.appointments).to eq([])
130
+ expect(person2.appointments).to eq([appointment])
131
+ end
132
+ end
133
+
134
+ context "when using concat" do
135
+
136
+ let(:person1) do
137
+ Person.new
138
+ end
139
+
140
+ let(:person2) do
141
+ Person.new
142
+ end
143
+
144
+ let(:appointment) do
145
+ Appointment.new
146
+ end
147
+
148
+ before do
149
+ person1.appointments.concat([appointment])
150
+ person2.appointments.concat([appointment])
151
+ end
152
+
153
+ it 'clears the object of its previous association' do
154
+ expect(person1.appointments).to eq([])
155
+ expect(person2.appointments).to eq([appointment])
156
+ end
157
+ end
158
+
159
+ context "when using =" do
160
+
161
+ let(:person1) do
162
+ Person.new
163
+ end
164
+
165
+ let(:person2) do
166
+ Person.new
167
+ end
168
+
169
+ let(:appointment) do
170
+ Appointment.new
171
+ end
172
+
173
+ let(:apts) { [ appointment ] }
174
+
175
+ before do
176
+ person1.appointments = apts
177
+ person2.appointments = apts
178
+ expect(apts).to eq([ appointment ])
179
+ end
180
+
181
+ it 'clears the object of its previous association' do
182
+ expect(person1.appointments).to eq([])
183
+ expect(person2.appointments).to eq([appointment])
184
+ end
185
+ end
186
+
187
+ context "when using = on the same document twice" do
188
+
189
+ let(:person1) do
190
+ Person.new
191
+ end
192
+
193
+ let(:person2) do
194
+ Person.new
195
+ end
196
+
197
+ let(:appointment1) do
198
+ Appointment.new
199
+ end
200
+
201
+ let(:appointment2) do
202
+ Appointment.new
203
+ end
204
+
205
+ let(:apts) { [ appointment1, appointment2 ] }
206
+
207
+ before do
208
+ person1.appointments = apts
209
+ person1.appointments = person1.appointments.reverse
210
+ expect(apts).to eq([ appointment1, appointment2 ])
211
+ end
212
+
213
+ it 'clears the object of its previous association' do
214
+ expect(person1.appointments).to eq([ appointment2, appointment1 ])
215
+ end
216
+ end
217
+ end
106
218
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
+ require_relative '../embeds_many_models.rb'
4
5
 
5
6
  describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
6
7
 
@@ -2209,6 +2210,79 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2209
2210
  end
2210
2211
  end
2211
2212
  end
2213
+
2214
+ context "when modifying the document beforehand" do
2215
+ let(:parent) { EmmParent.new }
2216
+
2217
+ before do
2218
+
2219
+ parent.blocks << EmmBlock.new(name: 'test', children: [size: 1, order: 1])
2220
+ parent.save!
2221
+
2222
+ parent.blocks[0].children[0].assign_attributes(size: 2)
2223
+
2224
+ parent.blocks.destroy_all(:name => 'test')
2225
+ end
2226
+
2227
+ it "deletes the correct document in the database" do
2228
+ expect(parent.reload.blocks.length).to eq(0)
2229
+ end
2230
+ end
2231
+
2232
+ context "when nil _id" do
2233
+ let(:parent) { EmmParent.new }
2234
+
2235
+ before do
2236
+ parent.blocks << EmmBlock.new(_id: nil, name: 'test', children: [size: 1, order: 1])
2237
+ parent.blocks << EmmBlock.new(_id: nil, name: 'test2', children: [size: 1, order: 1])
2238
+ parent.save!
2239
+
2240
+ parent.blocks.destroy_all(:name => 'test')
2241
+ end
2242
+
2243
+ it "deletes only the matching documents in the database" do
2244
+ expect(parent.reload.blocks.length).to eq(1)
2245
+ end
2246
+ end
2247
+
2248
+ # Since without an _id field we must us a $pullAll with the attributes of
2249
+ # the embedded document, if you modify it beforehand, the query will not
2250
+ # be able to find the correct document to pull.
2251
+ context "when modifying the document with nil _id" do
2252
+ let(:parent) { EmmParent.new }
2253
+
2254
+ before do
2255
+ parent.blocks << EmmBlock.new(_id: nil, name: 'test', children: [size: 1, order: 1])
2256
+ parent.blocks << EmmBlock.new(_id: nil, name: 'test2', children: [size: 1, order: 1])
2257
+ parent.save!
2258
+
2259
+ parent.blocks[0].children[0].assign_attributes(size: 2)
2260
+
2261
+ parent.blocks.destroy_all(:name => 'test')
2262
+ end
2263
+
2264
+ it "does not delete the correct documents" do
2265
+ expect(parent.reload.blocks.length).to eq(2)
2266
+ end
2267
+ end
2268
+
2269
+ context "when documents with and without _id" do
2270
+ let(:parent) { EmmParent.new }
2271
+
2272
+ before do
2273
+ parent.blocks << EmmBlock.new(_id: nil, name: 'test', children: [size: 1, order: 1])
2274
+ parent.blocks << EmmBlock.new(name: 'test', children: [size: 1, order: 1])
2275
+ parent.save!
2276
+
2277
+ parent.blocks[1].children[0].assign_attributes(size: 2)
2278
+
2279
+ parent.blocks.destroy_all(:name => 'test')
2280
+ end
2281
+
2282
+ it "does not delete the correct documents" do
2283
+ expect(parent.reload.blocks.length).to eq(0)
2284
+ end
2285
+ end
2212
2286
  end
2213
2287
  end
2214
2288
 
@@ -2286,7 +2360,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2286
2360
  it "raises an error" do
2287
2361
  expect {
2288
2362
  person.addresses.find(BSON::ObjectId.new)
2289
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
2363
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Address with id\(s\)/)
2290
2364
  end
2291
2365
  end
2292
2366
 
@@ -2335,7 +2409,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
2335
2409
  it "raises an error" do
2336
2410
  expect {
2337
2411
  person.addresses.find([ BSON::ObjectId.new ])
2338
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
2412
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Address with id\(s\)/)
2339
2413
  end
2340
2414
  end
2341
2415
 
@@ -3460,7 +3534,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3460
3534
 
3461
3535
  describe "replacing the entire embedded list" do
3462
3536
 
3463
- context "when an embeds many relationship contains a nil as the first item" do
3537
+ context "when an embeds many relationship contains nil as the first item" do
3464
3538
 
3465
3539
  let(:person) do
3466
3540
  Person.create!
@@ -3481,7 +3555,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3481
3555
  end
3482
3556
  end
3483
3557
 
3484
- context "when an embeds many relationship contains a nil in the middle of the list" do
3558
+ context "when an embeds many relationship contains nil in the middle of the list" do
3485
3559
 
3486
3560
  let(:person) do
3487
3561
  Person.create!
@@ -3502,7 +3576,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3502
3576
  end
3503
3577
  end
3504
3578
 
3505
- context "when an embeds many relationship contains a nil at the end of the list" do
3579
+ context "when an embeds many relationship contains nil at the end of the list" do
3506
3580
 
3507
3581
  let(:person) do
3508
3582
  Person.create!
@@ -3526,7 +3600,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3526
3600
 
3527
3601
  describe "appending to the embedded list" do
3528
3602
 
3529
- context "when appending a nil to the first position in an embedded list" do
3603
+ context "when appending nil to the first position in an embedded list" do
3530
3604
 
3531
3605
  let(:person) do
3532
3606
  Person.create! phone_numbers: []
@@ -3545,7 +3619,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3545
3619
  end
3546
3620
  end
3547
3621
 
3548
- context "when appending a nil into the middle of an embedded list" do
3622
+ context "when appending nil into the middle of an embedded list" do
3549
3623
 
3550
3624
  let(:person) do
3551
3625
  Person.create! phone_numbers: []
@@ -3564,7 +3638,7 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3564
3638
  end
3565
3639
  end
3566
3640
 
3567
- context "when appending a nil to the end of an embedded list" do
3641
+ context "when appending nil to the end of an embedded list" do
3568
3642
 
3569
3643
  let(:person) do
3570
3644
  Person.create! phone_numbers: []
@@ -3959,6 +4033,28 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
3959
4033
  end
3960
4034
  end
3961
4035
 
4036
+ context "when destroying a document with multiple nil _ids" do
4037
+ let(:congress) { EmmCongress.create! }
4038
+
4039
+ before do
4040
+ congress.legislators << EmmLegislator.new(_id: nil, a: 1)
4041
+ congress.legislators << EmmLegislator.new(_id: nil, a: 2)
4042
+
4043
+ congress.legislators[0].destroy
4044
+ end
4045
+
4046
+ it "deletes the correct document locally" do
4047
+ pending "MONGOID-5394"
4048
+ expect(congress.legislators.length).to eq(1)
4049
+ expect(congress.legislators.first.a).to eq(1)
4050
+ end
4051
+
4052
+ it "only deletes the one document" do
4053
+ pending "MONGOID-5394"
4054
+ expect(congress.reload.legislators.length).to eq(1)
4055
+ end
4056
+ end
4057
+
3962
4058
  context "when adding a document" do
3963
4059
 
3964
4060
  let(:person) do
@@ -4649,4 +4745,119 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
4649
4745
  end
4650
4746
  end
4651
4747
  end
4748
+
4749
+ context "when trying to persist the empty list" do
4750
+
4751
+ context "in an embeds_many relation" do
4752
+
4753
+ let(:band) { Band.create! }
4754
+
4755
+ before do
4756
+ band.labels = []
4757
+ band.save!
4758
+ end
4759
+
4760
+ let(:reloaded_band) { Band.collection.find(_id: band._id).first }
4761
+
4762
+ it "persists the empty list" do
4763
+ expect(reloaded_band).to have_key(:labels)
4764
+ expect(reloaded_band[:labels]).to eq []
4765
+ end
4766
+ end
4767
+
4768
+ context "in a nested embeds_many relation" do
4769
+
4770
+ let(:survey) { Survey.create!(questions: [Question.new]) }
4771
+
4772
+ before do
4773
+ survey.questions.first.answers = []
4774
+ survey.save!
4775
+ end
4776
+
4777
+ let(:reloaded_survey) { Survey.collection.find(_id: survey._id).first }
4778
+
4779
+ it "persists the empty list" do
4780
+ expect(reloaded_survey).to have_key(:questions)
4781
+ expect(reloaded_survey[:questions][0]).to have_key(:answers)
4782
+ expect(reloaded_survey[:questions][0][:answers]).to eq []
4783
+ end
4784
+ end
4785
+
4786
+ context "when not setting the embeds_many field" do
4787
+
4788
+ let(:band) { Band.create! }
4789
+
4790
+ let(:reloaded_band) { Band.collection.find(_id: band._id).first }
4791
+
4792
+ it "does not persist the empty list" do
4793
+ expect(reloaded_band).to_not have_key(:labels)
4794
+ end
4795
+ end
4796
+ end
4797
+
4798
+ context "when using assign_attributes with an already populated array" do
4799
+ let(:post) { EmmPost.create! }
4800
+
4801
+ before do
4802
+ post.assign_attributes(company_tags: [{id: BSON::ObjectId.new, title: 'a'}],
4803
+ user_tags: [{id: BSON::ObjectId.new, title: 'b'}])
4804
+ post.save!
4805
+ post.reload
4806
+ post.assign_attributes(company_tags: [{id: BSON::ObjectId.new, title: 'c'}],
4807
+ user_tags: [])
4808
+ post.save!
4809
+ post.reload
4810
+ end
4811
+
4812
+ it "has the correct embedded documents" do
4813
+ expect(post.company_tags.length).to eq(1)
4814
+ expect(post.company_tags.first.title).to eq("c")
4815
+ end
4816
+ end
4817
+
4818
+ context "when the parent fails validation" do
4819
+ let(:school) { EmmSchool.new }
4820
+ let(:student) { school.students.new }
4821
+
4822
+ before do
4823
+ student.save
4824
+ end
4825
+
4826
+ it "does not mark the parent as persisted" do
4827
+ expect(school.persisted?).to be false
4828
+ end
4829
+
4830
+ it "does not mark the child as persisted" do
4831
+ expect(student.persisted?).to be false
4832
+ end
4833
+
4834
+ it "does not persist the parent" do
4835
+ expect(School.count).to eq(0)
4836
+ end
4837
+ end
4838
+
4839
+ context "when doing assign_attributes then assignment" do
4840
+
4841
+ let(:post) do
4842
+ EmmPost.create!(
4843
+ company_tags: [ EmmCompanyTag.new(title: "1"), EmmCompanyTag.new(title: "1") ],
4844
+ user_tags: [ EmmUserTag.new(title: "1"), EmmUserTag.new(title: "1") ]
4845
+ )
4846
+ end
4847
+
4848
+ let(:from_db) { EmmPost.find(post.id) }
4849
+
4850
+ before do
4851
+ post.assign_attributes(
4852
+ company_tags: [ EmmCompanyTag.new(title: '3'), EmmCompanyTag.new(title: '4') ]
4853
+ )
4854
+ post.user_tags = [ EmmUserTag.new(title: '3'), EmmUserTag.new(title: '4') ]
4855
+ post.save!
4856
+ end
4857
+
4858
+ it "persists the associations correctly" do
4859
+ expect(from_db.user_tags.size).to eq(2)
4860
+ expect(from_db.company_tags.size).to eq(2)
4861
+ end
4862
+ end
4652
4863
  end
@@ -67,3 +67,160 @@ class EmmOuter
67
67
 
68
68
  field :level, :type => Integer
69
69
  end
70
+
71
+ class EmmCustomerAddress
72
+ include Mongoid::Document
73
+
74
+ embedded_in :addressable, polymorphic: true, inverse_of: :work_address
75
+ end
76
+
77
+ class EmmFriend
78
+ include Mongoid::Document
79
+
80
+ embedded_in :befriendable, polymorphic: true
81
+ end
82
+
83
+ class EmmCustomer
84
+ include Mongoid::Document
85
+
86
+ embeds_one :home_address, class_name: 'EmmCustomerAddress', as: :addressable
87
+ embeds_one :work_address, class_name: 'EmmCustomerAddress', as: :addressable
88
+
89
+ embeds_many :close_friends, class_name: 'EmmFriend', as: :befriendable
90
+ embeds_many :acquaintances, class_name: 'EmmFriend', as: :befriendable
91
+ end
92
+
93
+ class EmmUser
94
+ include Mongoid::Document
95
+ include Mongoid::Timestamps
96
+
97
+ embeds_many :orders, class_name: 'EmmOrder'
98
+ end
99
+
100
+ class EmmOrder
101
+ include Mongoid::Document
102
+
103
+ field :amount, type: Integer
104
+
105
+ embedded_in :user, class_name: 'EmmUser'
106
+ end
107
+
108
+ module EmmSpec
109
+ # There is also a top-level Car class defined.
110
+ class Car
111
+ include Mongoid::Document
112
+
113
+ embeds_many :doors
114
+ end
115
+
116
+ class Door
117
+ include Mongoid::Document
118
+
119
+ embedded_in :car
120
+ end
121
+
122
+ class Tank
123
+ include Mongoid::Document
124
+
125
+ embeds_many :guns
126
+ embeds_many :emm_turrets
127
+ # This association references a model that is not in our module,
128
+ # and it does not define class_name hence Mongoid will not be able to
129
+ # figure out the inverse for this association.
130
+ embeds_many :emm_hatches
131
+
132
+ # class_name is intentionally unqualified, references a class in the
133
+ # same module. Rails permits class_name to be unqualified like this.
134
+ embeds_many :launchers, class_name: 'Launcher'
135
+ end
136
+
137
+ class Gun
138
+ include Mongoid::Document
139
+
140
+ embedded_in :tank
141
+ end
142
+
143
+ class Launcher
144
+ include Mongoid::Document
145
+
146
+ # class_name is intentionally unqualified.
147
+ embedded_in :tank, class_name: 'Tank'
148
+ end
149
+ end
150
+
151
+ # This is intentionally on top level.
152
+ class EmmTurret
153
+ include Mongoid::Document
154
+
155
+ embedded_in :tank, class_name: 'EmmSpec::Tank'
156
+ end
157
+
158
+ # This is intentionally on top level.
159
+ class EmmHatch
160
+ include Mongoid::Document
161
+
162
+ # No :class_name option on this association intentionally.
163
+ embedded_in :tank
164
+ end
165
+
166
+ class EmmPost
167
+ include Mongoid::Document
168
+
169
+ embeds_many :company_tags, class_name: "EmmCompanyTag"
170
+ embeds_many :user_tags, class_name: "EmmUserTag"
171
+ end
172
+
173
+
174
+ class EmmCompanyTag
175
+ include Mongoid::Document
176
+
177
+ field :title, type: String
178
+
179
+ embedded_in :post, class_name: "EmmPost"
180
+ end
181
+
182
+
183
+ class EmmUserTag
184
+ include Mongoid::Document
185
+
186
+ field :title, type: String
187
+
188
+ embedded_in :post, class_name: "EmmPost"
189
+ end
190
+
191
+ class EmmSchool
192
+ include Mongoid::Document
193
+
194
+ embeds_many :students, class_name: "EmmStudent"
195
+
196
+ field :name, type: :string
197
+
198
+ validates :name, presence: true
199
+ end
200
+
201
+ class EmmStudent
202
+ include Mongoid::Document
203
+
204
+ embedded_in :school, class_name: "EmmSchool"
205
+ end
206
+
207
+ class EmmParent
208
+ include Mongoid::Document
209
+ embeds_many :blocks, class_name: "EmmBlock"
210
+ end
211
+
212
+ class EmmBlock
213
+ include Mongoid::Document
214
+ field :name, type: String
215
+ embeds_many :children, class_name: "EmmChild"
216
+ end
217
+
218
+ class EmmChild
219
+ include Mongoid::Document
220
+ embedded_in :block, class_name: "EmmBlock"
221
+
222
+ field :size, type: Integer
223
+ field :order, type: Integer
224
+ field :t
225
+ end
226
+
@@ -47,5 +47,17 @@ describe Mongoid::Association::Embedded::EmbedsMany do
47
47
  expect(patient.addresses.first.number).to eq(123)
48
48
  end
49
49
  end
50
+
51
+ context "when excluding the relation" do
52
+ let(:congress) do
53
+ EmmCongress.where(name: 'foo').only(:_id).first
54
+ end
55
+
56
+ it 'raises a MissingAttributeError' do
57
+ expect do
58
+ congress.legislators
59
+ end.to raise_error(ActiveModel::MissingAttributeError)
60
+ end
61
+ end
50
62
  end
51
63
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
+ require_relative 'embeds_many_models'
4
5
 
5
6
  describe Mongoid::Association::Embedded::EmbedsMany do
6
7
 
@@ -861,4 +862,71 @@ describe Mongoid::Association::Embedded::EmbedsMany do
861
862
  expect(association.path(double( :_parent => true))).to be_a(Mongoid::Atomic::Paths::Embedded::Many)
862
863
  end
863
864
  end
865
+
866
+ context "when the document and embedded document's klass is in a submodule" do
867
+
868
+ let(:tank) { EmmSpec::Tank.create! }
869
+ let(:gun) { tank.guns.create! }
870
+
871
+ let(:inverse_assoc) { gun._association.inverse_association }
872
+
873
+ it "has the correct inverses" do
874
+ pending 'MONGOID-5080'
875
+
876
+ inverse_assoc.should be_a(Mongoid::Association::Embedded::EmbeddedIn)
877
+ inverse_assoc.name.should == :tank
878
+ end
879
+
880
+ context "when embedded association is not namespaced but has class_name" do
881
+
882
+ let(:turret) { tank.emm_turrets.create! }
883
+
884
+ let(:inverse_assoc) { turret._association.inverse_association }
885
+
886
+ it "has the correct inverses" do
887
+ inverse_assoc.should be_a(Mongoid::Association::Embedded::EmbeddedIn)
888
+ inverse_assoc.name.should == :tank
889
+ end
890
+ end
891
+
892
+ context "when embedded association is not namespaced and lacks class_name" do
893
+
894
+ let(:hatch) { tank.emm_hatches.create! }
895
+
896
+ let(:inverse_assoc) { hatch._association.inverse_association }
897
+
898
+ it "does not find the inverse" do
899
+ inverse_assoc.should be nil
900
+ end
901
+ end
902
+
903
+ context "when the class names exist on top level and namespaced" do
904
+
905
+ let(:car) { EmmSpec::Car.create! }
906
+ let(:door) { car.doors.create! }
907
+
908
+ let(:inverse_assoc) { door._association.inverse_association }
909
+
910
+ it "has the correct inverses" do
911
+ pending 'MONGOID-5080'
912
+
913
+ inverse_assoc.should be_a(Mongoid::Association::Embedded::EmbeddedIn)
914
+ inverse_assoc.name.should == :car
915
+ end
916
+ end
917
+
918
+ context "when the association has an unqualified class_name in same module" do
919
+
920
+ let(:launcher) { tank.launchers.create! }
921
+
922
+ let(:inverse_assoc) { launcher._association.inverse_association }
923
+
924
+ it "has the correct inverses" do
925
+ pending 'unqualified class_name arguments do not work per MONGOID-5080'
926
+
927
+ inverse_assoc.should be_a(Mongoid::Association::Embedded::EmbeddedIn)
928
+ inverse_assoc.name.should == :tank
929
+ end
930
+ end
931
+ end
864
932
  end
@@ -78,4 +78,29 @@ describe Mongoid::Association::Embedded::EmbedsOne::Buildable do
78
78
  end
79
79
  end
80
80
  end
81
+
82
+ context 'when the object is already associated with another object' do
83
+
84
+ let(:owner1) do
85
+ Owner.create!
86
+ end
87
+
88
+ let(:owner2) do
89
+ Owner.create!
90
+ end
91
+
92
+ let(:scribe) do
93
+ Scribe.new
94
+ end
95
+
96
+ before do
97
+ owner1.scribe = scribe
98
+ owner2.scribe = scribe
99
+ end
100
+
101
+ it 'clears the object of its previous association' do
102
+ expect(owner1.scribe).to be_nil
103
+ expect(owner2.scribe).to eq(scribe)
104
+ end
105
+ end
81
106
  end