mongoid 6.4.2 → 7.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 (318) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/config/locales/en.yml +17 -0
  4. data/lib/mongoid/association/accessors.rb +339 -0
  5. data/lib/mongoid/{relations/binding.rb → association/bindable.rb} +32 -52
  6. data/lib/mongoid/association/builders.rb +92 -0
  7. data/lib/mongoid/{relations/constraint.rb → association/constrainable.rb} +11 -22
  8. data/lib/mongoid/association/depending.rb +137 -0
  9. data/lib/mongoid/{relations/eager.rb → association/eager_loadable.rb} +11 -11
  10. data/lib/mongoid/{relations → association}/embedded/batchable.rb +19 -19
  11. data/lib/mongoid/association/embedded/cyclic.rb +109 -0
  12. data/lib/mongoid/association/embedded/embedded_in/binding.rb +56 -0
  13. data/lib/mongoid/{relations/builders/embedded/in.rb → association/embedded/embedded_in/buildable.rb} +12 -6
  14. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +121 -0
  15. data/lib/mongoid/association/embedded/embedded_in.rb +154 -0
  16. data/lib/mongoid/{relations/bindings/embedded/many.rb → association/embedded/embeds_many/binding.rb} +11 -9
  17. data/lib/mongoid/{relations/builders/embedded/many.rb → association/embedded/embeds_many/buildable.rb} +13 -7
  18. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +552 -0
  19. data/lib/mongoid/association/embedded/embeds_many.rb +210 -0
  20. data/lib/mongoid/{relations/bindings/embedded/one.rb → association/embedded/embeds_one/binding.rb} +12 -10
  21. data/lib/mongoid/{relations/builders/embedded/one.rb → association/embedded/embeds_one/buildable.rb} +13 -7
  22. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +130 -0
  23. data/lib/mongoid/association/embedded/embeds_one.rb +173 -0
  24. data/lib/mongoid/association/embedded.rb +4 -0
  25. data/lib/mongoid/association/macros.rb +204 -0
  26. data/lib/mongoid/{relations → association}/many.rb +19 -49
  27. data/lib/mongoid/{relations → association}/marshalable.rb +6 -4
  28. data/lib/mongoid/association/nested/many.rb +200 -0
  29. data/lib/mongoid/association/nested/nested_buildable.rb +72 -0
  30. data/lib/mongoid/association/nested/one.rb +127 -0
  31. data/lib/mongoid/association/nested.rb +15 -0
  32. data/lib/mongoid/{relations → association}/one.rb +6 -6
  33. data/lib/mongoid/association/options.rb +152 -0
  34. data/lib/mongoid/{relations → association}/proxy.rb +31 -58
  35. data/lib/mongoid/association/referenced/auto_save.rb +79 -0
  36. data/lib/mongoid/association/referenced/belongs_to/binding.rb +87 -0
  37. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +46 -0
  38. data/lib/mongoid/association/referenced/belongs_to/eager.rb +36 -0
  39. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +136 -0
  40. data/lib/mongoid/association/referenced/belongs_to.rb +248 -0
  41. data/lib/mongoid/association/referenced/counter_cache.rb +163 -0
  42. data/lib/mongoid/association/referenced/eager.rb +162 -0
  43. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +71 -0
  44. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +40 -0
  45. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +52 -0
  46. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +312 -0
  47. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +290 -0
  48. data/lib/mongoid/{relations/bindings/referenced/many.rb → association/referenced/has_many/binding.rb} +6 -5
  49. data/lib/mongoid/association/referenced/has_many/buildable.rb +38 -0
  50. data/lib/mongoid/association/referenced/has_many/eager.rb +43 -0
  51. data/lib/mongoid/association/referenced/has_many/enumerable.rb +510 -0
  52. data/lib/mongoid/association/referenced/has_many/proxy.rb +578 -0
  53. data/lib/mongoid/association/referenced/has_many.rb +275 -0
  54. data/lib/mongoid/{relations/bindings/referenced/one.rb → association/referenced/has_one/binding.rb} +11 -8
  55. data/lib/mongoid/association/referenced/has_one/buildable.rb +60 -0
  56. data/lib/mongoid/association/referenced/has_one/eager.rb +35 -0
  57. data/lib/mongoid/{relations/builders/nested_attributes/one.rb → association/referenced/has_one/nested_builder.rb} +9 -9
  58. data/lib/mongoid/association/referenced/has_one/proxy.rb +113 -0
  59. data/lib/mongoid/association/referenced/has_one.rb +204 -0
  60. data/lib/mongoid/association/referenced/syncable.rb +170 -0
  61. data/lib/mongoid/association/referenced.rb +7 -0
  62. data/lib/mongoid/{relations → association}/reflections.rb +21 -17
  63. data/lib/mongoid/association/relatable.rb +509 -0
  64. data/lib/mongoid/{relations.rb → association.rb} +57 -56
  65. data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
  66. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
  67. data/lib/mongoid/atomic.rb +4 -4
  68. data/lib/mongoid/attributes/dynamic.rb +2 -2
  69. data/lib/mongoid/attributes/nested.rb +22 -11
  70. data/lib/mongoid/attributes/processing.rb +2 -2
  71. data/lib/mongoid/attributes/readonly.rb +2 -4
  72. data/lib/mongoid/attributes.rb +22 -13
  73. data/lib/mongoid/changeable.rb +1 -1
  74. data/lib/mongoid/clients/options.rb +7 -5
  75. data/lib/mongoid/composable.rb +4 -4
  76. data/lib/mongoid/config.rb +1 -0
  77. data/lib/mongoid/contextual/atomic.rb +1 -1
  78. data/lib/mongoid/contextual/geo_near.rb +1 -1
  79. data/lib/mongoid/contextual/memory.rb +21 -3
  80. data/lib/mongoid/contextual/mongo.rb +10 -8
  81. data/lib/mongoid/copyable.rb +7 -6
  82. data/lib/mongoid/criteria/includable.rb +14 -14
  83. data/lib/mongoid/criteria/modifiable.rb +8 -14
  84. data/lib/mongoid/criteria/options.rb +2 -2
  85. data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -1
  86. data/lib/mongoid/criteria/queryable/pipeline.rb +10 -5
  87. data/lib/mongoid/criteria/queryable/selectable.rb +37 -7
  88. data/lib/mongoid/criteria.rb +2 -2
  89. data/lib/mongoid/document.rb +15 -6
  90. data/lib/mongoid/errors/invalid_dependent_strategy.rb +32 -0
  91. data/lib/mongoid/errors/invalid_relation_option.rb +29 -0
  92. data/lib/mongoid/errors/unknown_model.rb +25 -0
  93. data/lib/mongoid/errors.rb +3 -0
  94. data/lib/mongoid/extensions/array.rb +5 -5
  95. data/lib/mongoid/extensions/big_decimal.rb +1 -1
  96. data/lib/mongoid/extensions/hash.rb +5 -2
  97. data/lib/mongoid/extensions/object.rb +4 -4
  98. data/lib/mongoid/extensions/range.rb +1 -0
  99. data/lib/mongoid/extensions/regexp.rb +1 -0
  100. data/lib/mongoid/extensions.rb +0 -4
  101. data/lib/mongoid/factory.rb +13 -3
  102. data/lib/mongoid/fields/foreign_key.rb +5 -5
  103. data/lib/mongoid/fields/standard.rb +2 -14
  104. data/lib/mongoid/fields/validators/macro.rb +1 -1
  105. data/lib/mongoid/fields.rb +3 -3
  106. data/lib/mongoid/indexable.rb +4 -1
  107. data/lib/mongoid/interceptable.rb +5 -5
  108. data/lib/mongoid/matchable/and.rb +1 -1
  109. data/lib/mongoid/matchable/elem_match.rb +9 -3
  110. data/lib/mongoid/matchable/eq.rb +22 -0
  111. data/lib/mongoid/matchable/ne.rb +1 -1
  112. data/lib/mongoid/matchable.rb +3 -1
  113. data/lib/mongoid/persistable/deletable.rb +7 -6
  114. data/lib/mongoid/persistable/incrementable.rb +1 -1
  115. data/lib/mongoid/persistable/logical.rb +1 -1
  116. data/lib/mongoid/persistable/settable.rb +57 -12
  117. data/lib/mongoid/persistable.rb +4 -5
  118. data/lib/mongoid/persistence_context.rb +20 -5
  119. data/lib/mongoid/query_cache.rb +8 -4
  120. data/lib/mongoid/railtie.rb +17 -0
  121. data/lib/mongoid/railties/controller_runtime.rb +86 -0
  122. data/lib/mongoid/scopable.rb +3 -3
  123. data/lib/mongoid/serializable.rb +4 -4
  124. data/lib/mongoid/shardable.rb +1 -1
  125. data/lib/mongoid/threaded.rb +36 -0
  126. data/lib/mongoid/touchable.rb +102 -0
  127. data/lib/mongoid/traversable.rb +3 -3
  128. data/lib/mongoid/validatable/presence.rb +2 -2
  129. data/lib/mongoid/validatable/uniqueness.rb +4 -4
  130. data/lib/mongoid/validatable.rb +8 -8
  131. data/lib/mongoid/version.rb +1 -1
  132. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +3 -0
  133. data/spec/app/models/animal.rb +2 -1
  134. data/spec/app/models/bomb.rb +1 -1
  135. data/spec/app/models/message.rb +1 -1
  136. data/spec/app/models/minim.rb +7 -0
  137. data/spec/app/models/person.rb +5 -2
  138. data/spec/app/models/shipment_address.rb +1 -0
  139. data/spec/app/models/store_as_dup_test3.rb +7 -0
  140. data/spec/app/models/store_as_dup_test4.rb +7 -0
  141. data/spec/app/models/updatable.rb +7 -0
  142. data/spec/app/models/vertex.rb +6 -0
  143. data/spec/app/models/wiki_page.rb +1 -1
  144. data/spec/config/mongoid.yml +13 -3
  145. data/spec/integration/associations/belongs_to_spec.rb +13 -0
  146. data/spec/lite_spec_helper.rb +56 -0
  147. data/spec/mongoid/{relations → association}/accessors_spec.rb +40 -1
  148. data/spec/mongoid/{relations → association}/auto_save_spec.rb +60 -12
  149. data/spec/mongoid/{relations → association}/builders_spec.rb +1 -1
  150. data/spec/mongoid/association/constrainable_spec.rb +115 -0
  151. data/spec/mongoid/{relations → association}/counter_cache_spec.rb +1 -1
  152. data/spec/mongoid/association/depending_spec.rb +866 -0
  153. data/spec/mongoid/{relations → association}/eager_spec.rb +12 -12
  154. data/spec/mongoid/{relations → association/embedded}/cyclic_spec.rb +1 -1
  155. data/spec/mongoid/{relations/bindings/embedded/in_spec.rb → association/embedded/embedded_in/binding_spec.rb} +13 -13
  156. data/spec/mongoid/{relations/builders/embedded/in_spec.rb → association/embedded/embedded_in/buildable_spec.rb} +9 -9
  157. data/spec/mongoid/{relations/embedded/in_spec.rb → association/embedded/embedded_in/proxy_spec.rb} +5 -77
  158. data/spec/mongoid/association/embedded/embedded_in_spec.rb +843 -0
  159. data/spec/mongoid/{relations/bindings/embedded/many_spec.rb → association/embedded/embeds_many/binding_spec.rb} +3 -3
  160. data/spec/mongoid/{relations/builders/embedded/many_spec.rb → association/embedded/embeds_many/buildable_spec.rb} +17 -45
  161. data/spec/mongoid/{relations/embedded/many_spec.rb → association/embedded/embeds_many/proxy_spec.rb} +124 -182
  162. data/spec/mongoid/association/embedded/embeds_many_spec.rb +852 -0
  163. data/spec/mongoid/{relations/bindings/embedded/one_spec.rb → association/embedded/embeds_one/binding_spec.rb} +4 -4
  164. data/spec/mongoid/{relations/builders/embedded/one_spec.rb → association/embedded/embeds_one/buildable_spec.rb} +14 -34
  165. data/spec/mongoid/{relations/embedded/one_spec.rb → association/embedded/embeds_one/proxy_spec.rb} +39 -84
  166. data/spec/mongoid/association/embedded/embeds_one_spec.rb +908 -0
  167. data/spec/mongoid/{relations → association}/macros_spec.rb +148 -73
  168. data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/many_spec.rb +16 -19
  169. data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/one_spec.rb +17 -20
  170. data/spec/mongoid/association/options_spec.rb +1321 -0
  171. data/spec/mongoid/{relations → association}/polymorphic_spec.rb +66 -34
  172. data/spec/mongoid/{relations/bindings/referenced/in_spec.rb → association/referenced/belongs_to/binding_spec.rb} +7 -7
  173. data/spec/mongoid/{relations/builders/referenced/in_spec.rb → association/referenced/belongs_to/buildable_spec.rb} +46 -79
  174. data/spec/mongoid/{relations/eager/belongs_to_spec.rb → association/referenced/belongs_to/eager_spec.rb} +33 -14
  175. data/spec/mongoid/{relations/referenced/in_spec.rb → association/referenced/belongs_to/proxy_spec.rb} +57 -91
  176. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2006 -0
  177. data/spec/mongoid/{relations/bindings/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/binding_spec.rb} +5 -5
  178. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +121 -0
  179. data/spec/mongoid/{relations/eager/has_and_belongs_to_many_spec.rb → association/referenced/has_and_belongs_to_many/eager_spec.rb} +26 -7
  180. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +56 -0
  181. data/spec/mongoid/{relations/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/proxy_spec.rb} +107 -98
  182. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +26 -0
  183. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +1027 -0
  184. data/spec/mongoid/{relations/bindings/referenced/many_spec.rb → association/referenced/has_many/binding_spec.rb} +5 -5
  185. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +119 -0
  186. data/spec/mongoid/{relations/eager/has_many_spec.rb → association/referenced/has_many/eager_spec.rb} +26 -11
  187. data/spec/mongoid/{relations/targets → association/referenced/has_many}/enumerable_spec.rb +122 -1
  188. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +23 -0
  189. data/spec/mongoid/{relations/referenced/many_spec.rb → association/referenced/has_many/proxy_spec.rb} +28 -93
  190. data/spec/mongoid/association/referenced/has_many_models.rb +37 -0
  191. data/spec/mongoid/association/referenced/has_many_spec.rb +1225 -0
  192. data/spec/mongoid/{relations/bindings/referenced/one_spec.rb → association/referenced/has_one/binding_spec.rb} +4 -4
  193. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +113 -0
  194. data/spec/mongoid/{relations/eager/has_one_spec.rb → association/referenced/has_one/eager_spec.rb} +10 -10
  195. data/spec/mongoid/{relations/referenced/one_spec.rb → association/referenced/has_one/proxy_spec.rb} +9 -109
  196. data/spec/mongoid/association/referenced/has_one_models.rb +48 -0
  197. data/spec/mongoid/association/referenced/has_one_spec.rb +1350 -0
  198. data/spec/mongoid/{relations → association}/reflections_spec.rb +1 -12
  199. data/spec/mongoid/{relations/synchronization_spec.rb → association/syncable_spec.rb} +4 -2
  200. data/spec/mongoid/{relations_spec.rb → association_spec.rb} +1 -1
  201. data/spec/mongoid/atomic/modifiers_spec.rb +2 -2
  202. data/spec/mongoid/atomic_spec.rb +4 -4
  203. data/spec/mongoid/attributes/nested_spec.rb +29 -11
  204. data/spec/mongoid/attributes/readonly_spec.rb +80 -125
  205. data/spec/mongoid/attributes_spec.rb +38 -2
  206. data/spec/mongoid/clients/factory_spec.rb +24 -18
  207. data/spec/mongoid/clients/options_spec.rb +58 -44
  208. data/spec/mongoid/clients/sessions_spec.rb +1 -1
  209. data/spec/mongoid/clients/transactions_spec.rb +369 -0
  210. data/spec/mongoid/clients_spec.rb +68 -8
  211. data/spec/mongoid/config_spec.rb +27 -1
  212. data/spec/mongoid/contextual/memory_spec.rb +19 -0
  213. data/spec/mongoid/contextual/mongo_spec.rb +33 -5
  214. data/spec/mongoid/copyable_spec.rb +90 -6
  215. data/spec/mongoid/copyable_spec_models.rb +17 -0
  216. data/spec/mongoid/criteria/modifiable_spec.rb +183 -60
  217. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +3 -3
  218. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +43 -0
  219. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +12 -0
  220. data/spec/mongoid/criteria/queryable/selectable_spec.rb +42 -3
  221. data/spec/mongoid/criteria/queryable/selector_spec.rb +2 -2
  222. data/spec/mongoid/criteria/scopable_spec.rb +81 -0
  223. data/spec/mongoid/criteria_spec.rb +33 -18
  224. data/spec/mongoid/document_spec.rb +83 -4
  225. data/spec/mongoid/extensions/array_spec.rb +11 -15
  226. data/spec/mongoid/extensions/big_decimal_spec.rb +9 -9
  227. data/spec/mongoid/extensions/hash_spec.rb +18 -1
  228. data/spec/mongoid/extensions/object_spec.rb +7 -11
  229. data/spec/mongoid/extensions/range_spec.rb +7 -0
  230. data/spec/mongoid/extensions/regexp_spec.rb +23 -0
  231. data/spec/mongoid/factory_spec.rb +19 -1
  232. data/spec/mongoid/fields/foreign_key_spec.rb +24 -32
  233. data/spec/mongoid/fields_spec.rb +2 -2
  234. data/spec/mongoid/findable_spec.rb +1 -1
  235. data/spec/mongoid/indexable_spec.rb +18 -8
  236. data/spec/mongoid/interceptable_spec.rb +22 -1
  237. data/spec/mongoid/matchable/elem_match_spec.rb +20 -0
  238. data/spec/mongoid/matchable/eq_spec.rb +48 -0
  239. data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
  240. data/spec/mongoid/persistable/savable_spec.rb +2 -2
  241. data/spec/mongoid/persistable/settable_spec.rb +95 -10
  242. data/spec/mongoid/persistable_spec.rb +21 -6
  243. data/spec/mongoid/persistence_context_spec.rb +1 -1
  244. data/spec/mongoid/query_cache_spec.rb +61 -22
  245. data/spec/mongoid/relations/proxy_spec.rb +124 -124
  246. data/spec/mongoid/scopable_spec.rb +13 -0
  247. data/spec/mongoid/shardable_spec.rb +32 -12
  248. data/spec/mongoid/threaded_spec.rb +68 -0
  249. data/spec/mongoid/{relations/touchable_spec.rb → touchable_spec.rb} +40 -1
  250. data/spec/mongoid/validatable/associated_spec.rb +1 -1
  251. data/spec/mongoid/validatable/presence_spec.rb +7 -6
  252. data/spec/mongoid/validatable_spec.rb +1 -1
  253. data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
  254. data/spec/spec_helper.rb +51 -25
  255. data/spec/support/constraints.rb +101 -0
  256. data/spec/support/macros.rb +20 -0
  257. data/spec/support/spec_config.rb +39 -0
  258. metadata +602 -582
  259. checksums.yaml.gz.sig +0 -2
  260. data/lib/mongoid/relations/accessors.rb +0 -267
  261. data/lib/mongoid/relations/auto_save.rb +0 -94
  262. data/lib/mongoid/relations/bindings/embedded/in.rb +0 -59
  263. data/lib/mongoid/relations/bindings/referenced/in.rb +0 -65
  264. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +0 -70
  265. data/lib/mongoid/relations/bindings.rb +0 -9
  266. data/lib/mongoid/relations/builder.rb +0 -57
  267. data/lib/mongoid/relations/builders/nested_attributes/many.rb +0 -199
  268. data/lib/mongoid/relations/builders/referenced/in.rb +0 -26
  269. data/lib/mongoid/relations/builders/referenced/many.rb +0 -26
  270. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +0 -39
  271. data/lib/mongoid/relations/builders/referenced/one.rb +0 -26
  272. data/lib/mongoid/relations/builders.rb +0 -106
  273. data/lib/mongoid/relations/cascading/delete.rb +0 -44
  274. data/lib/mongoid/relations/cascading/destroy.rb +0 -43
  275. data/lib/mongoid/relations/cascading/nullify.rb +0 -35
  276. data/lib/mongoid/relations/cascading/restrict.rb +0 -39
  277. data/lib/mongoid/relations/cascading.rb +0 -56
  278. data/lib/mongoid/relations/conversions.rb +0 -34
  279. data/lib/mongoid/relations/counter_cache.rb +0 -160
  280. data/lib/mongoid/relations/cyclic.rb +0 -107
  281. data/lib/mongoid/relations/eager/base.rb +0 -153
  282. data/lib/mongoid/relations/eager/belongs_to.rb +0 -31
  283. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +0 -47
  284. data/lib/mongoid/relations/eager/has_many.rb +0 -38
  285. data/lib/mongoid/relations/eager/has_one.rb +0 -30
  286. data/lib/mongoid/relations/embedded/in.rb +0 -241
  287. data/lib/mongoid/relations/embedded/many.rb +0 -683
  288. data/lib/mongoid/relations/embedded/one.rb +0 -235
  289. data/lib/mongoid/relations/macros.rb +0 -367
  290. data/lib/mongoid/relations/metadata.rb +0 -1179
  291. data/lib/mongoid/relations/nested_builder.rb +0 -74
  292. data/lib/mongoid/relations/options.rb +0 -49
  293. data/lib/mongoid/relations/polymorphic.rb +0 -39
  294. data/lib/mongoid/relations/referenced/in.rb +0 -304
  295. data/lib/mongoid/relations/referenced/many.rb +0 -812
  296. data/lib/mongoid/relations/referenced/many_to_many.rb +0 -479
  297. data/lib/mongoid/relations/referenced/one.rb +0 -290
  298. data/lib/mongoid/relations/synchronization.rb +0 -169
  299. data/lib/mongoid/relations/targets/enumerable.rb +0 -493
  300. data/lib/mongoid/relations/targets.rb +0 -2
  301. data/lib/mongoid/relations/touchable.rb +0 -97
  302. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +0 -184
  303. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +0 -201
  304. data/spec/mongoid/relations/builders/referenced/many_spec.rb +0 -137
  305. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +0 -178
  306. data/spec/mongoid/relations/builders/referenced/one_spec.rb +0 -111
  307. data/spec/mongoid/relations/cascading/delete_spec.rb +0 -101
  308. data/spec/mongoid/relations/cascading/destroy_spec.rb +0 -47
  309. data/spec/mongoid/relations/cascading/nullify_spec.rb +0 -32
  310. data/spec/mongoid/relations/cascading/restrict_spec.rb +0 -68
  311. data/spec/mongoid/relations/cascading_spec.rb +0 -355
  312. data/spec/mongoid/relations/constraint_spec.rb +0 -75
  313. data/spec/mongoid/relations/conversions_spec.rb +0 -128
  314. data/spec/mongoid/relations/metadata_spec.rb +0 -1985
  315. data/spec/mongoid/relations/options_spec.rb +0 -35
  316. data.tar.gz.sig +0 -0
  317. metadata.gz.sig +0 -0
  318. /data/spec/mongoid/{relations → association}/embedded/dirty_spec.rb +0 -0
@@ -0,0 +1,1350 @@
1
+ require "spec_helper"
2
+ require_relative './has_one_models'
3
+
4
+ describe Mongoid::Association::Referenced::HasOne do
5
+
6
+ before do
7
+ class OwnerObject; include Mongoid::Document; end
8
+ class BelongingObject; include Mongoid::Document; end
9
+ end
10
+
11
+ after do
12
+ Object.send(:remove_const, :BelongingObject)
13
+ Object.send(:remove_const, :OwnerObject)
14
+ end
15
+
16
+ let(:has_one_class) do
17
+ OwnerObject
18
+ end
19
+
20
+ let(:name) do
21
+ :belonging_object
22
+ end
23
+
24
+ let(:association) do
25
+ has_one_class.has_one name, options
26
+ end
27
+
28
+ let(:options) do
29
+ { }
30
+ end
31
+
32
+ describe '#relation_complements' do
33
+
34
+ let(:expected_complements) do
35
+ [
36
+ Mongoid::Association::Referenced::BelongsTo,
37
+ ]
38
+ end
39
+
40
+ it 'returns the relation complements' do
41
+ expect(association.relation_complements).to eq(expected_complements)
42
+ end
43
+ end
44
+
45
+ describe '#setup!' do
46
+
47
+ it 'sets up a getter for the relation' do
48
+ expect(Mongoid::Association::Accessors).to receive(:define_getter!).with(association)
49
+ association.setup!
50
+ end
51
+
52
+ it 'sets up a setter for the relation' do
53
+ expect(Mongoid::Association::Accessors).to receive(:define_setter!).with(association)
54
+ association.setup!
55
+ end
56
+
57
+ it 'sets up an existence check for the relation' do
58
+ expect(Mongoid::Association::Accessors).to receive(:define_existence_check!).with(association)
59
+ association.setup!
60
+ end
61
+
62
+ it 'sets up the builder for the relation' do
63
+ expect(Mongoid::Association::Builders).to receive(:define_builder!).with(association)
64
+ association.setup!
65
+ end
66
+
67
+ it 'sets up the creator for the relation' do
68
+ expect(Mongoid::Association::Builders).to receive(:define_creator!).with(association)
69
+ association.setup!
70
+ end
71
+
72
+ context 'autosave' do
73
+
74
+ context 'when the :autosave option is true' do
75
+
76
+ let(:options) do
77
+ {
78
+ autosave: true
79
+ }
80
+ end
81
+
82
+ let(:association) do
83
+ # Note that it is necessary to create the association directly, otherwise the
84
+ # setup! method will be called by the :has_one macro
85
+ described_class.new(has_one_class, name, options)
86
+ end
87
+
88
+ it 'sets up autosave' do
89
+ expect(Mongoid::Association::Referenced::AutoSave).to receive(:define_autosave!).with(association)
90
+ association.setup!
91
+ end
92
+ end
93
+
94
+ context 'when the :autosave option is false' do
95
+
96
+ let(:options) do
97
+ {
98
+ autosave: false
99
+ }
100
+ end
101
+
102
+ it 'does not set up autosave' do
103
+ expect(Mongoid::Association::Referenced::AutoSave).not_to receive(:define_autosave!)
104
+ association.setup!
105
+ end
106
+ end
107
+
108
+ context 'when the :autosave option is not provided' do
109
+
110
+ let(:association) do
111
+ # Note that it is necessary to create the association directly, otherwise the
112
+ # setup! method will be called by the :has_one macro
113
+ described_class.new(has_one_class, name, options)
114
+ end
115
+
116
+ it 'does not set up autosave' do
117
+ expect(Mongoid::Association::Referenced::AutoSave).not_to receive(:define_autosave!)
118
+ association.setup!
119
+ end
120
+ end
121
+ end
122
+
123
+ context 'when the :validate option is true' do
124
+
125
+ let(:options) do
126
+ {
127
+ validate: true
128
+ }
129
+ end
130
+
131
+ let(:association) do
132
+ # Note that it is necessary to create the association directly, otherwise the
133
+ # setup! method will be called by the :has_one macro
134
+ described_class.new(has_one_class, name, options)
135
+ end
136
+
137
+ it 'sets up validation' do
138
+ expect(has_one_class).to receive(:validates_associated).with(name).and_call_original
139
+ association.setup!
140
+ end
141
+ end
142
+
143
+ context 'when the :validate option is false' do
144
+
145
+ let(:options) do
146
+ {
147
+ validate: false
148
+ }
149
+ end
150
+
151
+ it 'does not set up validation' do
152
+ expect(has_one_class).not_to receive(:validates_associated)
153
+ association.setup!
154
+ end
155
+ end
156
+
157
+ context 'when the :validate option is not provided' do
158
+
159
+ let(:association) do
160
+ # Note that it is necessary to create the association directly, otherwise the
161
+ # setup! method will be called by the :embeds_one macro
162
+ described_class.new(has_one_class, name, options)
163
+ end
164
+
165
+ it 'sets up the validation because it uses the validation default (true)' do
166
+ expect(has_one_class).to receive(:validates_associated).with(name).and_call_original
167
+ association.setup!
168
+ end
169
+ end
170
+
171
+ context 'polymorphic' do
172
+
173
+ context 'when the as option is provided' do
174
+
175
+
176
+ let(:options) do
177
+ {
178
+ as: :containable
179
+ }
180
+ end
181
+
182
+ before do
183
+ association
184
+ end
185
+
186
+ it 'set the polymorphic attribute on the owner class' do
187
+ expect(has_one_class.polymorphic).to be(true)
188
+ end
189
+ end
190
+
191
+ context 'when the as option is not provided' do
192
+
193
+ it 'does not set the polymorphic attribute on the owner class' do
194
+ expect(has_one_class.polymorphic).to be(false)
195
+ end
196
+ end
197
+ end
198
+
199
+ context 'dependent' do
200
+
201
+ context 'when the dependent option is provided' do
202
+
203
+ context 'when the dependent option is :delete_all' do
204
+
205
+ let(:options) do
206
+ {
207
+ dependent: :delete_all
208
+ }
209
+ end
210
+
211
+ let(:association) do
212
+ # Note that it is necessary to create the association directly, otherwise the
213
+ # setup! method will be called by the :belongs_to macro
214
+ described_class.new(has_one_class, name, options)
215
+ end
216
+
217
+ it 'sets up the dependency' do
218
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
219
+ association.setup!
220
+ end
221
+ end
222
+
223
+ context 'when the dependent option is :destroy' do
224
+
225
+ let(:options) do
226
+ {
227
+ dependent: :destroy
228
+ }
229
+ end
230
+
231
+ let(:association) do
232
+ # Note that it is necessary to create the association directly, otherwise the
233
+ # setup! method will be called by the :belongs_to macro
234
+ described_class.new(has_one_class, name, options)
235
+ end
236
+
237
+ it 'sets up the dependency' do
238
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
239
+ association.setup!
240
+ end
241
+ end
242
+
243
+ context 'when the dependent option is :nullify' do
244
+
245
+ let(:options) do
246
+ {
247
+ dependent: :nullify
248
+ }
249
+ end
250
+
251
+ let(:association) do
252
+ # Note that it is necessary to create the association directly, otherwise the
253
+ # setup! method will be called by the :belongs_to macro
254
+ described_class.new(has_one_class, name, options)
255
+ end
256
+
257
+ it 'sets up the dependency' do
258
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
259
+ association.setup!
260
+ end
261
+ end
262
+
263
+ context 'when the dependent option is :restrict_with_exception' do
264
+
265
+ let(:options) do
266
+ {
267
+ dependent: :restrict_with_exception
268
+ }
269
+ end
270
+
271
+ let(:association) do
272
+ # Note that it is necessary to create the association directly, otherwise the
273
+ # setup! method will be called by the :belongs_to macro
274
+ described_class.new(has_one_class, name, options)
275
+ end
276
+
277
+ it 'sets up the dependency' do
278
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
279
+ association.setup!
280
+ end
281
+ end
282
+
283
+ context 'when the dependent option is :restrict_with_error' do
284
+
285
+ let(:options) do
286
+ {
287
+ dependent: :restrict_with_error
288
+ }
289
+ end
290
+
291
+ let(:association) do
292
+ # Note that it is necessary to create the association directly, otherwise the
293
+ # setup! method will be called by the :belongs_to macro
294
+ described_class.new(has_one_class, name, options)
295
+ end
296
+
297
+ it 'sets up the dependency' do
298
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
299
+ association.setup!
300
+ end
301
+ end
302
+ end
303
+
304
+ context 'when the dependent option is not provided' do
305
+
306
+ it 'does not set up the dependency' do
307
+ expect(Mongoid::Association::Depending).not_to receive(:define_dependency!)
308
+ association.setup!
309
+ end
310
+ end
311
+ end
312
+ end
313
+
314
+ describe '#type' do
315
+
316
+ context 'when polymorphic' do
317
+
318
+ let(:options) do
319
+ { as: :containable }
320
+ end
321
+
322
+ it 'returns the as attribute followed by "_type"' do
323
+ expect(association.type).to eq("#{options[:as]}_type")
324
+ end
325
+ end
326
+
327
+ context 'when not polymorphic' do
328
+
329
+ it 'returns nil' do
330
+ expect(association.type).to be_nil
331
+ end
332
+ end
333
+ end
334
+
335
+ describe '#inverse_type' do
336
+
337
+ context 'when polymorphic' do
338
+
339
+ let(:options) do
340
+ { as: :containable }
341
+ end
342
+
343
+ it 'returns nil' do
344
+ expect(association.inverse_type).to be_nil
345
+ end
346
+ end
347
+
348
+ context 'when not polymorphic' do
349
+
350
+ it 'returns nil' do
351
+ expect(association.inverse_type).to be_nil
352
+ end
353
+ end
354
+ end
355
+
356
+ describe '#inverse_type_setter' do
357
+
358
+ context 'when polymorphic' do
359
+
360
+ let(:options) do
361
+ { as: :containable }
362
+ end
363
+
364
+ it 'returns nil' do
365
+ expect(association.inverse_type).to be_nil
366
+ end
367
+ end
368
+
369
+ context 'when not polymorphic' do
370
+
371
+ it 'returns nil' do
372
+ expect(association.inverse_type).to be_nil
373
+ end
374
+ end
375
+ end
376
+
377
+ describe '#foreign_key' do
378
+
379
+ context 'when options has foreign_key specified' do
380
+
381
+ let(:options) do
382
+ { foreign_key: :other_object_id }
383
+ end
384
+
385
+ it 'raises returns the foreign key as a String' do
386
+ expect(association.foreign_key).to eq(options[:foreign_key].to_s)
387
+ end
388
+ end
389
+
390
+ context 'when options does not have foreign_key specified' do
391
+
392
+ it 'returns the default foreign key, the name of the inverse followed by "_id"' do
393
+ expect(association.foreign_key).to eq("#{association.inverse}_id")
394
+ end
395
+ end
396
+ end
397
+
398
+ describe '#embedded?' do
399
+
400
+ it 'returns false' do
401
+ expect(association.embedded?).to be(false)
402
+ end
403
+ end
404
+
405
+ describe '#primary_key' do
406
+
407
+ context 'when the :primary_key option is specified' do
408
+
409
+ let(:options) do
410
+ {
411
+ primary_key: 'guid'
412
+ }
413
+ end
414
+
415
+ it 'returns the primary_key' do
416
+ expect(association.primary_key).to eq(options[:primary_key])
417
+ end
418
+ end
419
+
420
+ context 'when the :primary_key option is not specified' do
421
+
422
+ it 'returns the primary_key default' do
423
+ expect(association.primary_key).to eq(Mongoid::Association::Relatable::PRIMARY_KEY_DEFAULT)
424
+ end
425
+ end
426
+ end
427
+
428
+ describe '#indexed?' do
429
+
430
+ it 'returns false' do
431
+ expect(association.indexed?).to be(false)
432
+ end
433
+ end
434
+
435
+ describe '#relation' do
436
+
437
+ it 'returns Mongoid::Association::Referenced::HasOne::Proxy' do
438
+ expect(association.relation).to be(Mongoid::Association::Referenced::HasOne::Proxy)
439
+ end
440
+ end
441
+
442
+ describe '#validation_default' do
443
+
444
+ it 'returns true' do
445
+ expect(association.validation_default).to be(true)
446
+ end
447
+ end
448
+
449
+ describe '#name' do
450
+
451
+ it 'returns the name of the relation' do
452
+ expect(association.name).to be(name)
453
+ end
454
+ end
455
+
456
+ describe '#options' do
457
+
458
+ it 'returns the options' do
459
+ expect(association.options).to be(options)
460
+ end
461
+ end
462
+
463
+ describe '#merge!' do
464
+
465
+ end
466
+
467
+ describe '#store_as' do
468
+ it 'returns nil' do
469
+ expect(association.store_as).to be_nil
470
+ end
471
+ end
472
+
473
+ describe '#touchable?' do
474
+
475
+ it 'return false' do
476
+ expect(association.send(:touchable?)).to be(false)
477
+ end
478
+ end
479
+
480
+ describe '#order' do
481
+
482
+ it 'returns nil' do
483
+ expect(association.order).to be_nil
484
+ end
485
+ end
486
+
487
+ describe '#as' do
488
+
489
+ context 'when :as is specified in the options' do
490
+
491
+ let(:options) do
492
+ {
493
+ as: :containable
494
+ }
495
+ end
496
+
497
+ it 'returns the :as option' do
498
+ expect(association.as).to eq(options[:as])
499
+ end
500
+ end
501
+
502
+ context 'when :as is not specified in the options' do
503
+
504
+ it 'returns nil' do
505
+ expect(association.as).to be_nil
506
+ end
507
+ end
508
+ end
509
+
510
+ describe '#polymorphic?' do
511
+
512
+ context 'when :as is specified in the options' do
513
+
514
+ let(:options) do
515
+ {
516
+ as: :containable
517
+ }
518
+ end
519
+
520
+ it 'returns true' do
521
+ expect(association.polymorphic?).to be(true)
522
+ end
523
+
524
+ end
525
+
526
+ context 'when :as is not specified in the options' do
527
+
528
+ it 'returns false' do
529
+ expect(association.polymorphic?).to be(false)
530
+ end
531
+ end
532
+ end
533
+
534
+ describe '#type_setter' do
535
+
536
+ context 'when polymorphic' do
537
+
538
+ let(:options) do
539
+ { as: :containable }
540
+ end
541
+
542
+ it 'returns the type followed by = as a String' do
543
+ expect(association.type_setter).to eq("containable_type=")
544
+ end
545
+ end
546
+
547
+ context 'when not polymorphic' do
548
+
549
+ it 'returns nil' do
550
+ expect(association.type).to be_nil
551
+ end
552
+ end
553
+ end
554
+
555
+ describe '#dependent' do
556
+
557
+ context 'when the dependent option is provided' do
558
+
559
+ context 'when the dependent option is :delete_all' do
560
+
561
+ let(:options) do
562
+ {
563
+ dependent: :delete_all
564
+ }
565
+ end
566
+
567
+ it 'returns :delete_all' do
568
+ expect(association.dependent).to eq(:delete_all)
569
+ end
570
+ end
571
+
572
+ context 'when the dependent option is :destroy' do
573
+
574
+ let(:options) do
575
+ {
576
+ dependent: :destroy
577
+ }
578
+ end
579
+
580
+ it 'returns :destroy' do
581
+ expect(association.dependent).to eq(:destroy)
582
+ end
583
+ end
584
+
585
+ context 'when the dependent option is :nullify' do
586
+
587
+ let(:options) do
588
+ {
589
+ dependent: :nullify
590
+ }
591
+ end
592
+
593
+ it 'returns :nullify' do
594
+ expect(association.dependent).to eq(:nullify)
595
+ end
596
+ end
597
+
598
+ context 'when the dependent option is :restrict_with_exception' do
599
+
600
+ let(:options) do
601
+ {
602
+ dependent: :restrict_with_exception
603
+ }
604
+ end
605
+
606
+ it 'returns :restrict_with_exception' do
607
+ expect(association.dependent).to eq(:restrict_with_exception)
608
+ end
609
+ end
610
+
611
+ context 'when the dependent option is :restrict_with_error' do
612
+
613
+ let(:options) do
614
+ {
615
+ dependent: :restrict_with_error
616
+ }
617
+ end
618
+
619
+ it 'returns :restrict_with_error' do
620
+ expect(association.dependent).to eq(:restrict_with_error)
621
+ end
622
+ end
623
+ end
624
+
625
+ context 'when the dependent option is not provided' do
626
+
627
+ it 'returns nil' do
628
+ expect(association.dependent).to be_nil
629
+ end
630
+ end
631
+ end
632
+
633
+ describe '#inverse_type' do
634
+
635
+ it 'returns nil' do
636
+ expect(association.inverse_type).to be_nil
637
+ end
638
+ end
639
+
640
+ describe '#bindable?' do
641
+
642
+ it 'returns false' do
643
+ expect(association.bindable?(Person.new)).to be(false)
644
+ end
645
+ end
646
+
647
+ describe '#inverses' do
648
+
649
+ context 'when polymorphic' do
650
+
651
+ before do
652
+ BelongingObject.belongs_to :containable, polymorphic: true
653
+ end
654
+
655
+ let(:options) do
656
+ {
657
+ as: :containable
658
+ }
659
+ end
660
+
661
+ context 'when another object is passed to the method' do
662
+
663
+ let(:instance_of_other_class) do
664
+ BelongingObject.new
665
+ end
666
+
667
+ context 'when the relation class has only one relation whose class matches the owning class' do
668
+
669
+ it 'returns the :as attribute of this association' do
670
+ expect(association.inverses(instance_of_other_class)).to match_array([ :containable ])
671
+ end
672
+ end
673
+
674
+ context 'when :inverse_of is specified' do
675
+
676
+ before do
677
+ options.merge!(inverse_of: :inverse_name)
678
+ end
679
+
680
+ it 'returns the :inverse_of value' do
681
+ expect(association.inverses(instance_of_other_class)).to eq([ :inverse_name ])
682
+ end
683
+ end
684
+
685
+ context 'when inverse_of is not specified' do
686
+
687
+ it 'returns the :as attribute of this association' do
688
+ expect(association.inverses(instance_of_other_class)).to match_array([ :containable ])
689
+ end
690
+ end
691
+ end
692
+
693
+ context 'when another object is not passed to the method' do
694
+
695
+ context 'when inverse_of is specified' do
696
+
697
+ before do
698
+ options.merge!(inverse_of: :inverse_name)
699
+ end
700
+
701
+ it 'returns the :inverse_of value' do
702
+ expect(association.inverses).to eq([ :inverse_name ])
703
+ end
704
+ end
705
+
706
+ context 'when inverse_of is not specified' do
707
+
708
+ it 'returns the :as attribute' do
709
+ expect(association.inverses).to eq([ :containable ])
710
+ end
711
+ end
712
+ end
713
+ end
714
+
715
+ context 'when not polymorphic' do
716
+
717
+ before do
718
+ BelongingObject.belongs_to :owner_object
719
+ end
720
+
721
+ context 'when inverse_of is specified' do
722
+
723
+ before do
724
+ options.merge!(inverse_of: :inverse_name)
725
+ end
726
+
727
+ it 'returns the :inverse_of value' do
728
+ expect(association.inverses).to eq([ :inverse_name ])
729
+ end
730
+ end
731
+
732
+ context 'when inverse_of is not specified' do
733
+
734
+ it 'uses the inverse class to find the inverse name' do
735
+ expect(association.inverses).to eq([ :owner_object ])
736
+ end
737
+ end
738
+
739
+ context 'when :cyclic is specified' do
740
+
741
+ it 'returns the cyclic inverse name' do
742
+
743
+ end
744
+ end
745
+ end
746
+ end
747
+
748
+ describe '##inverse' do
749
+
750
+ context 'when polymorphic' do
751
+
752
+ before do
753
+ BelongingObject.belongs_to :containable, polymorphic: true
754
+ end
755
+
756
+ let(:options) do
757
+ {
758
+ as: :containable
759
+ }
760
+ end
761
+
762
+ context 'when another object is passed to the method' do
763
+
764
+ let(:instance_of_other_class) do
765
+ BelongingObject.new
766
+ end
767
+
768
+ context 'when the relation class has only one relation whose class matches the owning class' do
769
+
770
+ it 'returns the :as attribute of this association' do
771
+ expect(association.inverse(instance_of_other_class)).to eq(:containable)
772
+ end
773
+ end
774
+
775
+ context 'when :inverse_of is specified' do
776
+
777
+ before do
778
+ options.merge!(inverse_of: :inverse_name)
779
+ end
780
+
781
+ it 'returns the :inverse_of value' do
782
+ expect(association.inverse(instance_of_other_class)).to eq(:inverse_name)
783
+ end
784
+ end
785
+
786
+ context 'when inverse_of is not specified' do
787
+
788
+ it 'returns the :as attribute of this association' do
789
+ expect(association.inverse(instance_of_other_class)).to eq(:containable)
790
+ end
791
+ end
792
+ end
793
+
794
+ context 'when another object is not passed to the method' do
795
+
796
+ context 'when inverse_of is specified' do
797
+
798
+ before do
799
+ options.merge!(inverse_of: :inverse_name)
800
+ end
801
+
802
+ it 'returns the :inverse_of value' do
803
+ expect(association.inverse).to eq(:inverse_name)
804
+ end
805
+ end
806
+
807
+ context 'when inverse_of is not specified' do
808
+
809
+ it 'returns the :as attribute' do
810
+ expect(association.inverse).to eq(:containable)
811
+ end
812
+ end
813
+ end
814
+ end
815
+
816
+ context 'when not polymorphic' do
817
+
818
+ before do
819
+ BelongingObject.belongs_to :owner_object
820
+ end
821
+
822
+ context 'when inverse_of is specified' do
823
+
824
+ before do
825
+ options.merge!(inverse_of: :inverse_name)
826
+ end
827
+
828
+ it 'returns the :inverse_of value' do
829
+ expect(association.inverse).to eq(:inverse_name)
830
+ end
831
+ end
832
+
833
+ context 'when inverse_of is not specified' do
834
+
835
+ it 'uses the inverse class to find the inverse name' do
836
+ expect(association.inverse).to eq(:owner_object)
837
+ end
838
+ end
839
+
840
+ context 'when :cyclic is specified' do
841
+
842
+ it 'returns the cyclic inverse name' do
843
+
844
+ end
845
+ end
846
+ end
847
+ end
848
+
849
+ describe '#inverse_association' do
850
+
851
+ end
852
+
853
+ describe '#autosave' do
854
+
855
+ context 'when the autosave option is specified' do
856
+
857
+ context 'when the autosave option is true' do
858
+
859
+ let(:options) do
860
+ {
861
+ autosave: true
862
+ }
863
+ end
864
+
865
+ it 'returns true' do
866
+ expect(association.autosave).to be(true)
867
+ end
868
+ end
869
+
870
+ context 'when the autosave option is false' do
871
+
872
+ let(:options) do
873
+ {
874
+ autosave: false
875
+ }
876
+ end
877
+
878
+ it 'returns false' do
879
+ expect(association.autosave).to be(false)
880
+ end
881
+ end
882
+ end
883
+
884
+ context 'when the autosave option is not specified' do
885
+
886
+ it 'returns false' do
887
+ expect(association.autosave).to be(false)
888
+ end
889
+ end
890
+ end
891
+
892
+ describe '#relation_class_name' do
893
+
894
+ context 'when the classes are defined in a module' do
895
+
896
+ let(:define_classes) do
897
+ module HasOneAssociationClassName
898
+ class OwnedClass
899
+ include Mongoid::Document
900
+
901
+ belongs_to :owner_class
902
+ end
903
+
904
+ class OwnerClass
905
+ include Mongoid::Document
906
+
907
+ has_one :owned_class
908
+ end
909
+ end
910
+ end
911
+
912
+ it 'returns the proper namespaced class name' do
913
+ define_classes
914
+
915
+ expect(
916
+ HasOneAssociationClassName::OwnedClass.relations['owner_class'].relation_class_name
917
+ ).to eq('HasOneAssociationClassName::OwnerClass')
918
+ end
919
+ end
920
+
921
+ context 'when the :class_name option is specified' do
922
+
923
+ let(:options) do
924
+ { class_name: 'OtherBelongingObject' }
925
+ end
926
+
927
+ it 'returns the class name option' do
928
+ expect(association.relation_class_name).to eq('OtherBelongingObject')
929
+ end
930
+
931
+ context 'when the class is namespaced' do
932
+ let(:association) do
933
+ HomNs::PrefixedParent.relations['child']
934
+ end
935
+
936
+ it 'returns unqualified class name as given in the :class_name option' do
937
+ expect(association.relation_class_name).to eq('PrefixedChild')
938
+ end
939
+ end
940
+ end
941
+
942
+ context 'when the class_name option is not specified' do
943
+
944
+ it 'uses the name of the relation to deduce the class name' do
945
+ expect(association.relation_class_name).to eq('BelongingObject')
946
+ end
947
+ end
948
+ end
949
+
950
+ describe '#relation_class' do
951
+
952
+ context 'when the :class_name option is specified' do
953
+
954
+ let!(:_class) do
955
+ class OtherBelongingObject; end
956
+ OtherBelongingObject
957
+ end
958
+
959
+ let(:options) do
960
+ { class_name: 'OtherBelongingObject' }
961
+ end
962
+
963
+ it 'returns the class name option' do
964
+ expect(association.relation_class).to eq(_class)
965
+ end
966
+
967
+ context 'when the class is namespaced' do
968
+ let(:association) do
969
+ HomNs::PrefixedParent.relations['child']
970
+ end
971
+
972
+ it 'returns resolved class instance' do
973
+ expect(association.relation_class).to eq(HomNs::PrefixedChild)
974
+ end
975
+ end
976
+ end
977
+
978
+ context 'when the class_name option is not specified' do
979
+
980
+ it 'uses the name of the relation to deduce the class name' do
981
+ expect(association.relation_class).to eq(BelongingObject)
982
+ end
983
+ end
984
+ end
985
+
986
+ describe '#klass' do
987
+ it 'is the target class' do
988
+ expect(association.klass).to eq(BelongingObject)
989
+ end
990
+ end
991
+
992
+ describe '#inverse_class_name' do
993
+
994
+ it 'returns the name of the owner class' do
995
+ expect(association.inverse_class_name).to eq('OwnerObject')
996
+ end
997
+
998
+ context 'polymorphic association' do
999
+ let(:association) do
1000
+ has_one_class.has_one :belonging_object, as: :bar
1001
+ end
1002
+
1003
+ it 'returns the name of the owner class' do
1004
+ expect(association.inverse_class_name).to eq(OwnerObject.name)
1005
+ end
1006
+ end
1007
+ end
1008
+
1009
+ describe '#inverse_class' do
1010
+
1011
+ it 'returns the owner class' do
1012
+ expect(association.inverse_class).to be(OwnerObject)
1013
+ end
1014
+
1015
+ context 'polymorphic association' do
1016
+ let(:association) do
1017
+ has_one_class.has_one :belonging_object, as: :bar
1018
+ end
1019
+
1020
+ it 'returns the owner class' do
1021
+ expect(association.inverse_class).to be(OwnerObject)
1022
+ end
1023
+ end
1024
+ end
1025
+
1026
+ describe '#inverse_of' do
1027
+
1028
+ context 'when :inverse_of is specified in the options' do
1029
+
1030
+ let(:options) do
1031
+ { inverse_of: :a_belonging_object }
1032
+ end
1033
+
1034
+ it 'returns the inverse_of value' do
1035
+ expect(association.inverse_of).to eq(options[:inverse_of])
1036
+ end
1037
+ end
1038
+
1039
+ context 'when :inverse_of is not specified in the options' do
1040
+
1041
+ it 'returns nil' do
1042
+ expect(association.inverse_of).to be_nil
1043
+ end
1044
+ end
1045
+ end
1046
+
1047
+ describe '#key' do
1048
+
1049
+ it 'returns the primary key' do
1050
+ expect(association.key).to eq(association.primary_key)
1051
+ end
1052
+ end
1053
+
1054
+ describe '#setter' do
1055
+
1056
+ it 'returns a string of the name followed by =' do
1057
+ expect(association.setter).to eq("#{name}=")
1058
+ end
1059
+ end
1060
+
1061
+ describe '#validate?' do
1062
+
1063
+ context 'when :validate is specified in the options' do
1064
+
1065
+ context 'when validate is true' do
1066
+
1067
+ let(:options) do
1068
+ { validate: true }
1069
+ end
1070
+
1071
+ it 'returns true' do
1072
+ expect(association.send(:validate?)).to be(true)
1073
+ end
1074
+ end
1075
+
1076
+ context 'when validate is false' do
1077
+
1078
+ let(:options) do
1079
+ { validate: false }
1080
+ end
1081
+
1082
+ it 'returns false' do
1083
+ expect(association.send(:validate?)).to be(false)
1084
+ end
1085
+ end
1086
+ end
1087
+
1088
+ context 'when :validate is not specified in the options' do
1089
+
1090
+ it 'returns the validation_default' do
1091
+ expect(association.send(:validate?)).to eq(association.validation_default)
1092
+ end
1093
+ end
1094
+ end
1095
+
1096
+ describe '#autobuilding?' do
1097
+
1098
+ context 'when :autobuild is specified in the options' do
1099
+
1100
+ context 'when autobuild is true' do
1101
+
1102
+ let(:options) do
1103
+ { autobuild: true }
1104
+ end
1105
+
1106
+ it 'returns true' do
1107
+ expect(association.autobuilding?).to be(true)
1108
+ end
1109
+ end
1110
+
1111
+ context 'when autobuild is false' do
1112
+
1113
+ let(:options) do
1114
+ { autobuild: false }
1115
+ end
1116
+
1117
+ it 'returns true' do
1118
+ expect(association.autobuilding?).to be(false)
1119
+ end
1120
+ end
1121
+ end
1122
+
1123
+ context 'when :validate is not specified in the options' do
1124
+
1125
+ it 'returns false' do
1126
+ expect(association.autobuilding?).to be(false)
1127
+ end
1128
+ end
1129
+ end
1130
+
1131
+ describe '#forced_nil_inverse?' do
1132
+
1133
+ it 'returns false' do
1134
+ expect(association.forced_nil_inverse?).to be(false)
1135
+ end
1136
+ end
1137
+
1138
+ describe '#stores_foreign_key?' do
1139
+
1140
+ it 'returns false' do
1141
+ expect(association.stores_foreign_key?).to be(false)
1142
+ end
1143
+ end
1144
+
1145
+ describe '#inverse_setter' do
1146
+
1147
+ context 'when an inverse can be determined' do
1148
+
1149
+ before do
1150
+ BelongingObject.belongs_to :owner_object
1151
+ end
1152
+
1153
+ it 'returns the name of the inverse followed by =' do
1154
+ expect(association.inverse_setter).to eq('owner_object=')
1155
+ end
1156
+ end
1157
+
1158
+ context 'when an inverse cannot be determined' do
1159
+
1160
+ it 'returns nil' do
1161
+ expect(association.inverse_setter).to be_nil
1162
+ end
1163
+ end
1164
+ end
1165
+
1166
+ describe '#extension' do
1167
+
1168
+ context 'when a block is passed' do
1169
+
1170
+ let(:association) do
1171
+ has_one_class.embeds_one name, options do; end
1172
+ end
1173
+
1174
+ it 'defines an extension module' do
1175
+ expect(association.extension).to be_a(Module)
1176
+ end
1177
+
1178
+ it 'returns the extension' do
1179
+ expect(association.extension).to eq(
1180
+ "#{has_one_class.name}::#{has_one_class.name}#{name.to_s.camelize}RelationExtension".constantize)
1181
+ end
1182
+ end
1183
+
1184
+ context 'when an :extension is not specified in the options' do
1185
+
1186
+ it 'returns false' do
1187
+ expect(association.extension).to be_nil
1188
+ end
1189
+ end
1190
+ end
1191
+
1192
+ describe '#foreign_key_setter' do
1193
+
1194
+ it 'returns the foreign key followed by "="' do
1195
+ expect(association.foreign_key_setter).to eq("#{association.foreign_key}=")
1196
+ end
1197
+ end
1198
+
1199
+ describe '#destructive?' do
1200
+
1201
+ context 'when the dependent option is provided' do
1202
+
1203
+ context 'when the dependent option is :delete_all' do
1204
+
1205
+ let(:options) do
1206
+ {
1207
+ dependent: :delete_all
1208
+ }
1209
+ end
1210
+
1211
+ it 'returns true' do
1212
+ expect(association.destructive?).to be(true)
1213
+ end
1214
+ end
1215
+
1216
+ context 'when the dependent option is :destroy' do
1217
+
1218
+ let(:options) do
1219
+ {
1220
+ dependent: :destroy
1221
+ }
1222
+ end
1223
+
1224
+ it 'returns true' do
1225
+ expect(association.destructive?).to be(true)
1226
+ end
1227
+ end
1228
+
1229
+ context 'when the dependent option is :nullify' do
1230
+
1231
+ let(:options) do
1232
+ {
1233
+ dependent: :nullify
1234
+ }
1235
+ end
1236
+
1237
+ it 'returns false' do
1238
+ expect(association.destructive?).to be(false)
1239
+ end
1240
+ end
1241
+
1242
+ context 'when the dependent option is :restrict_with_exception' do
1243
+
1244
+ let(:options) do
1245
+ {
1246
+ dependent: :restrict_with_exception
1247
+ }
1248
+ end
1249
+
1250
+ it 'returns false' do
1251
+ expect(association.destructive?).to be(false)
1252
+ end
1253
+ end
1254
+
1255
+ context 'when the dependent option is :restrict_with_error' do
1256
+
1257
+ let(:options) do
1258
+ {
1259
+ dependent: :restrict_with_error
1260
+ }
1261
+ end
1262
+
1263
+ it 'returns false' do
1264
+ expect(association.destructive?).to be(false)
1265
+ end
1266
+ end
1267
+ end
1268
+
1269
+ context 'when the dependent option is not provided' do
1270
+
1271
+ it 'returns false' do
1272
+ expect(association.destructive?).to be(false)
1273
+ end
1274
+ end
1275
+ end
1276
+
1277
+ context 'when the classes are defined in a module' do
1278
+
1279
+ let(:define_classes) do
1280
+ module HasOneAssociationModuleDefinitions
1281
+ class OwnedClass
1282
+ include Mongoid::Document
1283
+
1284
+ belongs_to :owner_class
1285
+ end
1286
+
1287
+ class OwnerClass
1288
+ include Mongoid::Document
1289
+
1290
+ has_one :owned_class
1291
+ end
1292
+ end
1293
+ end
1294
+
1295
+ let(:owner) do
1296
+ HasOneAssociationModuleDefinitions::OwnerClass.create!
1297
+ end
1298
+
1299
+ let(:owned) do
1300
+ define_classes
1301
+ HasOneAssociationModuleDefinitions::OwnedClass.create!(owner_class: owner)
1302
+ end
1303
+
1304
+ it 'successfully creates the owned document' do
1305
+ expect { owned }.not_to raise_error
1306
+ end
1307
+ end
1308
+
1309
+ describe '#nested_builder' do
1310
+
1311
+ it 'returns an instance of Association::Nested::One' do
1312
+ expect(association.nested_builder({}, {})).to be_a(Mongoid::Association::Nested::One)
1313
+ end
1314
+ end
1315
+
1316
+ describe '#path' do
1317
+
1318
+ it 'returns an instance of Mongoid::Atomic::Paths::Root' do
1319
+ expect(association.path(double( :_parent => true))).to be_a(Mongoid::Atomic::Paths::Root)
1320
+ end
1321
+ end
1322
+
1323
+ describe '#foreign_key_check' do
1324
+
1325
+ it 'returns the nil' do
1326
+ expect(association.foreign_key_check).to be_nil
1327
+ end
1328
+ end
1329
+
1330
+ describe '#create_relation' do
1331
+
1332
+ let(:owner) do
1333
+ OwnerObject.new
1334
+ end
1335
+
1336
+ let(:target) do
1337
+ BelongingObject.new
1338
+ end
1339
+
1340
+ before do
1341
+ association
1342
+ BelongingObject.belongs_to :owner_object
1343
+ end
1344
+
1345
+ it 'returns an the target (EmbeddedObject)' do
1346
+ expect(Mongoid::Association::Referenced::HasOne::Proxy).to receive(:new).and_call_original
1347
+ expect(association.create_relation(owner, target)).to be_a(BelongingObject)
1348
+ end
1349
+ end
1350
+ end