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,1225 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Association::Referenced::HasMany do
4
+
5
+ before do
6
+ class OwnerObject; include Mongoid::Document; end
7
+ class BelongingObject; include Mongoid::Document; end
8
+ end
9
+
10
+ after do
11
+ Object.send(:remove_const, :BelongingObject)
12
+ Object.send(:remove_const, :OwnerObject)
13
+ end
14
+
15
+ let(:has_many_class) do
16
+ OwnerObject
17
+ end
18
+
19
+ let(:name) do
20
+ :belonging_objects
21
+ end
22
+
23
+ let(:association) do
24
+ has_many_class.has_many name, options
25
+ end
26
+
27
+ let(:options) do
28
+ { }
29
+ end
30
+
31
+ describe '#relation_complements' do
32
+
33
+ let(:expected_complements) do
34
+ [
35
+ Mongoid::Association::Referenced::BelongsTo,
36
+ ]
37
+ end
38
+
39
+ it 'returns the relation complements' do
40
+ expect(association.relation_complements).to eq(expected_complements)
41
+ end
42
+ end
43
+
44
+ describe '#setup!' do
45
+
46
+ it 'sets up a getter for the relation' do
47
+ expect(Mongoid::Association::Accessors).to receive(:define_getter!).with(association)
48
+ association.setup!
49
+ end
50
+
51
+ it 'sets up a ids getter for the relation' do
52
+ expect(Mongoid::Association::Accessors).to receive(:define_ids_getter!).with(association)
53
+ association.setup!
54
+ end
55
+
56
+ it 'sets up a setter for the relation' do
57
+ expect(Mongoid::Association::Accessors).to receive(:define_setter!).with(association)
58
+ association.setup!
59
+ end
60
+
61
+ it 'sets up a ids setter for the relation' do
62
+ expect(Mongoid::Association::Accessors).to receive(:define_ids_setter!).with(association)
63
+ association.setup!
64
+ end
65
+
66
+ it 'sets up an existence check for the relation' do
67
+ expect(Mongoid::Association::Accessors).to receive(:define_existence_check!).with(association)
68
+ association.setup!
69
+ end
70
+
71
+ context 'autosave' do
72
+
73
+ context 'when the :autosave option is true' do
74
+
75
+ let(:options) do
76
+ {
77
+ autosave: true
78
+ }
79
+ end
80
+
81
+ let(:association) do
82
+ # Note that it is necessary to create the association directly, otherwise the
83
+ # setup! method will be called by the :has_many macro
84
+ described_class.new(has_many_class, name, options)
85
+ end
86
+
87
+ it 'sets up autosave' do
88
+ expect(Mongoid::Association::Referenced::AutoSave).to receive(:define_autosave!).with(association)
89
+ association.setup!
90
+ end
91
+ end
92
+
93
+ context 'when the :autosave option is false' do
94
+
95
+ let(:options) do
96
+ {
97
+ autosave: false
98
+ }
99
+ end
100
+
101
+ it 'does not set up autosave' do
102
+ expect(Mongoid::Association::Referenced::AutoSave).not_to receive(:define_autosave!)
103
+ association.setup_instance_methods!
104
+ end
105
+ end
106
+
107
+ context 'when the :autosave option is not provided' do
108
+
109
+ let(:association) do
110
+ # Note that it is necessary to create the association directly, otherwise the
111
+ # setup! method will be called by the :has_many macro
112
+ described_class.new(has_many_class, name, options)
113
+ end
114
+
115
+ it 'does not set up autosave' do
116
+ expect(Mongoid::Association::Referenced::AutoSave).not_to receive(:define_autosave!)
117
+ association.setup!
118
+ end
119
+ end
120
+ end
121
+
122
+ context 'when the :validate option is true' do
123
+
124
+ let(:options) do
125
+ {
126
+ validate: true
127
+ }
128
+ end
129
+
130
+ let(:association) do
131
+ # Note that it is necessary to create the association directly, otherwise the
132
+ # setup! method will be called by the :has_many macro
133
+ described_class.new(has_many_class, name, options)
134
+ end
135
+
136
+ it 'sets up validation' do
137
+ expect(has_many_class).to receive(:validates_associated).with(name).and_call_original
138
+ association.setup!
139
+ end
140
+ end
141
+
142
+ context 'when the :validate option is false' do
143
+
144
+ let(:options) do
145
+ {
146
+ validate: false
147
+ }
148
+ end
149
+
150
+ it 'does not set up validation' do
151
+ expect(has_many_class).not_to receive(:validates_associated)
152
+ association.setup_instance_methods!
153
+ end
154
+ end
155
+
156
+ context 'when the :validate option is not provided' do
157
+
158
+ let(:association) do
159
+ # Note that it is necessary to create the association directly, otherwise the
160
+ # setup! method will be called by the :has_many macro
161
+ described_class.new(has_many_class, name, options)
162
+ end
163
+
164
+ it 'sets up the validation because it uses the validation default (true)' do
165
+ expect(has_many_class).to receive(:validates_associated).with(name).and_call_original
166
+ association.setup!
167
+ end
168
+ end
169
+
170
+ context 'polymorphic' do
171
+
172
+ context 'when the as option is provided' do
173
+
174
+
175
+ let(:options) do
176
+ {
177
+ as: :containable
178
+ }
179
+ end
180
+
181
+ before do
182
+ association
183
+ end
184
+
185
+ it 'set the polymorphic attribute on the owner class' do
186
+ expect(has_many_class.polymorphic).to be(true)
187
+ end
188
+ end
189
+
190
+ context 'when the as option is not provided' do
191
+
192
+ it 'does not set the polymorphic attribute on the owner class' do
193
+ expect(has_many_class.polymorphic).to be(false)
194
+ end
195
+ end
196
+ end
197
+
198
+ context 'dependent' do
199
+
200
+ context 'when the dependent option is provided' do
201
+
202
+ context 'when the dependent option is :delete_all' do
203
+
204
+ let(:options) do
205
+ {
206
+ dependent: :delete_all
207
+ }
208
+ end
209
+
210
+ let(:association) do
211
+ # Note that it is necessary to create the association directly, otherwise the
212
+ # setup! method will be called by the :belongs_to macro
213
+ described_class.new(has_many_class, name, options)
214
+ end
215
+
216
+ it 'sets up the dependency' do
217
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
218
+ association.setup!
219
+ end
220
+ end
221
+
222
+ context 'when the dependent option is :destroy' do
223
+
224
+ let(:options) do
225
+ {
226
+ dependent: :destroy
227
+ }
228
+ end
229
+
230
+ let(:association) do
231
+ # Note that it is necessary to create the association directly, otherwise the
232
+ # setup! method will be called by the :belongs_to macro
233
+ described_class.new(has_many_class, name, options)
234
+ end
235
+
236
+ it 'sets up the dependency' do
237
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
238
+ association.setup!
239
+ end
240
+ end
241
+
242
+ context 'when the dependent option is :nullify' do
243
+
244
+ let(:options) do
245
+ {
246
+ dependent: :nullify
247
+ }
248
+ end
249
+
250
+ let(:association) do
251
+ # Note that it is necessary to create the association directly, otherwise the
252
+ # setup! method will be called by the :belongs_to macro
253
+ described_class.new(has_many_class, name, options)
254
+ end
255
+
256
+ it 'sets up the dependency' do
257
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
258
+ association.setup!
259
+ end
260
+ end
261
+
262
+ context 'when the dependent option is :restrict_with_exception' do
263
+
264
+ let(:options) do
265
+ {
266
+ dependent: :restrict_with_exception
267
+ }
268
+ end
269
+
270
+ let(:association) do
271
+ # Note that it is necessary to create the association directly, otherwise the
272
+ # setup! method will be called by the :belongs_to macro
273
+ described_class.new(has_many_class, name, options)
274
+ end
275
+
276
+ it 'sets up the dependency' do
277
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
278
+ association.setup!
279
+ end
280
+ end
281
+
282
+ context 'when the dependent option is :restrict_with_error' do
283
+
284
+ let(:options) do
285
+ {
286
+ dependent: :restrict_with_error
287
+ }
288
+ end
289
+
290
+ let(:association) do
291
+ # Note that it is necessary to create the association directly, otherwise the
292
+ # setup_instance_methods! method will be called by the :belongs_to macro
293
+ described_class.new(has_many_class, name, options)
294
+ end
295
+
296
+ it 'sets up the dependency' do
297
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
298
+ association.setup!
299
+ end
300
+ end
301
+ end
302
+
303
+ context 'when the dependent option is not provided' do
304
+
305
+ it 'does not set up the dependency' do
306
+ expect(Mongoid::Association::Depending).not_to receive(:define_dependency!)
307
+ association.setup!
308
+ end
309
+ end
310
+ end
311
+ end
312
+
313
+ describe '#type' do
314
+
315
+ context 'when polymorphic' do
316
+
317
+ let(:options) do
318
+ { as: :containable }
319
+ end
320
+
321
+ it 'returns the as attribute followed by "_type"' do
322
+ expect(association.type).to eq("#{options[:as]}_type")
323
+ end
324
+ end
325
+
326
+ context 'when not polymorphic' do
327
+
328
+ it 'returns nil' do
329
+ expect(association.type).to be_nil
330
+ end
331
+ end
332
+ end
333
+
334
+ describe '#inverse_type' do
335
+
336
+ context 'when polymorphic' do
337
+
338
+ let(:options) do
339
+ { as: :containable }
340
+ end
341
+
342
+ it 'returns nil' do
343
+ expect(association.inverse_type).to be_nil
344
+ end
345
+ end
346
+
347
+ context 'when not polymorphic' do
348
+
349
+ it 'returns nil' do
350
+ expect(association.inverse_type).to be_nil
351
+ end
352
+ end
353
+ end
354
+
355
+ describe '#inverse_type_setter' do
356
+
357
+ context 'when polymorphic' do
358
+
359
+ let(:options) do
360
+ { as: :containable }
361
+ end
362
+
363
+ it 'returns nil' do
364
+ expect(association.inverse_type).to be_nil
365
+ end
366
+ end
367
+
368
+ context 'when not polymorphic' do
369
+
370
+ it 'returns nil' do
371
+ expect(association.inverse_type).to be_nil
372
+ end
373
+ end
374
+ end
375
+
376
+ describe '#foreign_key' do
377
+
378
+ context 'when options has foreign_key specified' do
379
+
380
+ let(:options) do
381
+ { foreign_key: :other_object_id }
382
+ end
383
+
384
+ it 'raises returns the foreign key as a String' do
385
+ expect(association.foreign_key).to eq(options[:foreign_key].to_s)
386
+ end
387
+ end
388
+
389
+ context 'when options does not have foreign_key specified' do
390
+
391
+ it 'returns the default foreign key, the name of the inverse followed by "_id"' do
392
+ expect(association.foreign_key).to eq("#{association.inverse}_id")
393
+ end
394
+ end
395
+ end
396
+
397
+ describe '#embedded?' do
398
+
399
+ it 'returns false' do
400
+ expect(association.embedded?).to be(false)
401
+ end
402
+ end
403
+
404
+ describe '#primary_key' do
405
+
406
+ context 'when the :primary_key option is specified' do
407
+
408
+ let(:options) do
409
+ {
410
+ primary_key: 'guid'
411
+ }
412
+ end
413
+
414
+ it 'returns the primary_key' do
415
+ expect(association.primary_key).to eq(options[:primary_key])
416
+ end
417
+ end
418
+
419
+ context 'when the :primary_key option is not specified' do
420
+
421
+ it 'returns the primary_key default' do
422
+ expect(association.primary_key).to eq(Mongoid::Association::Relatable::PRIMARY_KEY_DEFAULT)
423
+ end
424
+ end
425
+ end
426
+
427
+ describe '#relation' do
428
+
429
+ it 'returns Mongoid::Association::Referenced::HasMany::Proxy' do
430
+ expect(association.relation).to be(Mongoid::Association::Referenced::HasMany::Proxy)
431
+ end
432
+ end
433
+
434
+ describe '#validation_default' do
435
+
436
+ it 'returns true' do
437
+ expect(association.validation_default).to be(true)
438
+ end
439
+ end
440
+
441
+ describe '#name' do
442
+
443
+ it 'returns the name of the relation' do
444
+ expect(association.name).to be(name)
445
+ end
446
+ end
447
+
448
+ describe '#options' do
449
+
450
+ it 'returns the options' do
451
+ expect(association.options).to be(options)
452
+ end
453
+ end
454
+
455
+ describe '#merge!' do
456
+
457
+ end
458
+
459
+ describe '#store_as' do
460
+ it 'returns nil' do
461
+ expect(association.store_as).to be_nil
462
+ end
463
+ end
464
+
465
+ describe '#touchable?' do
466
+
467
+ it 'return false' do
468
+ expect(association.send(:touchable?)).to be(false)
469
+ end
470
+ end
471
+
472
+ describe '#order' do
473
+
474
+ context 'when order is specified in the options' do
475
+
476
+ let(:options) do
477
+ {
478
+ order: :rating.desc
479
+ }
480
+ end
481
+
482
+ it 'returns a Criteria Queryable Key' do
483
+ expect(association.order).to be_a(Mongoid::Criteria::Queryable::Key)
484
+ end
485
+ end
486
+
487
+ context 'when order is not specified in the options' do
488
+
489
+ it 'returns nil' do
490
+ expect(association.order).to be_nil
491
+ end
492
+ end
493
+ end
494
+
495
+ describe '#as' do
496
+
497
+ context 'when :as is specified in the options' do
498
+
499
+ let(:options) do
500
+ {
501
+ as: :containable
502
+ }
503
+ end
504
+
505
+ it 'returns the :as option' do
506
+ expect(association.as).to eq(options[:as])
507
+ end
508
+ end
509
+
510
+ context 'when :as is not specified in the options' do
511
+
512
+ it 'returns nil' do
513
+ expect(association.as).to be_nil
514
+ end
515
+ end
516
+ end
517
+
518
+ describe '#polymorphic?' do
519
+
520
+ context 'when :as is specified in the options' do
521
+
522
+ let(:options) do
523
+ {
524
+ as: :containable
525
+ }
526
+ end
527
+
528
+ it 'returns true' do
529
+ expect(association.polymorphic?).to be(true)
530
+ end
531
+
532
+ end
533
+
534
+ context 'when :as is not specified in the options' do
535
+
536
+ it 'returns false' do
537
+ expect(association.polymorphic?).to be(false)
538
+ end
539
+ end
540
+ end
541
+
542
+ describe '#type_setter' do
543
+
544
+ context 'when polymorphic' do
545
+
546
+ let(:options) do
547
+ { as: :containable }
548
+ end
549
+
550
+ it 'returns the type followed by = as a String' do
551
+ expect(association.type_setter).to eq("containable_type=")
552
+ end
553
+ end
554
+
555
+ context 'when not polymorphic' do
556
+
557
+ it 'returns nil' do
558
+ expect(association.type).to be_nil
559
+ end
560
+ end
561
+ end
562
+
563
+ describe '#dependent' do
564
+
565
+ context 'when the dependent option is provided' do
566
+
567
+ context 'when the dependent option is :delete_all' do
568
+
569
+ let(:options) do
570
+ {
571
+ dependent: :delete_all
572
+ }
573
+ end
574
+
575
+ it 'returns :delete_all' do
576
+ expect(association.dependent).to eq(:delete_all)
577
+ end
578
+ end
579
+
580
+ context 'when the dependent option is :destroy' do
581
+
582
+ let(:options) do
583
+ {
584
+ dependent: :destroy
585
+ }
586
+ end
587
+
588
+ it 'returns :destroy' do
589
+ expect(association.dependent).to eq(:destroy)
590
+ end
591
+ end
592
+
593
+ context 'when the dependent option is :nullify' do
594
+
595
+ let(:options) do
596
+ {
597
+ dependent: :nullify
598
+ }
599
+ end
600
+
601
+ it 'returns :nullify' do
602
+ expect(association.dependent).to eq(:nullify)
603
+ end
604
+ end
605
+
606
+ context 'when the dependent option is :restrict_with_exception' do
607
+
608
+ let(:options) do
609
+ {
610
+ dependent: :restrict_with_exception
611
+ }
612
+ end
613
+
614
+ it 'returns :restrict_with_exception' do
615
+ expect(association.dependent).to eq(:restrict_with_exception)
616
+ end
617
+ end
618
+
619
+ context 'when the dependent option is :restrict_with_error' do
620
+
621
+ let(:options) do
622
+ {
623
+ dependent: :restrict_with_error
624
+ }
625
+ end
626
+
627
+ it 'returns :restrict_with_error' do
628
+ expect(association.dependent).to eq(:restrict_with_error)
629
+ end
630
+ end
631
+ end
632
+
633
+ context 'when the dependent option is not provided' do
634
+
635
+ it 'returns nil' do
636
+ expect(association.dependent).to be_nil
637
+ end
638
+ end
639
+ end
640
+
641
+ describe '#inverse_type' do
642
+
643
+ it 'returns nil' do
644
+ expect(association.inverse_type).to be_nil
645
+ end
646
+ end
647
+
648
+ describe '#bindable?' do
649
+
650
+ it 'returns false' do
651
+ expect(association.bindable?(Person.new)).to be(false)
652
+ end
653
+ end
654
+
655
+ describe '#inverses' do
656
+
657
+ context 'when polymorphic' do
658
+
659
+ before do
660
+ BelongingObject.belongs_to :containable, polymorphic: true
661
+ end
662
+
663
+ let(:options) do
664
+ {
665
+ as: :containable
666
+ }
667
+ end
668
+
669
+ context 'when another object is passed to the method' do
670
+
671
+ let(:instance_of_other_class) do
672
+ BelongingObject.new
673
+ end
674
+
675
+ context 'when the relation class has only one relation whose class matches the owning class' do
676
+
677
+ it 'returns the :as attribute of this association' do
678
+ expect(association.inverses(instance_of_other_class)).to match_array([ :containable ])
679
+ end
680
+ end
681
+
682
+ context 'when :inverse_of is specified' do
683
+
684
+ before do
685
+ options.merge!(inverse_of: :inverse_name)
686
+ end
687
+
688
+ it 'returns the :inverse_of value' do
689
+ expect(association.inverses(instance_of_other_class)).to eq([ :inverse_name ])
690
+ end
691
+ end
692
+
693
+ context 'when inverse_of is not specified' do
694
+
695
+ it 'returns the :as attribute of this association' do
696
+ expect(association.inverses(instance_of_other_class)).to match_array([ :containable ])
697
+ end
698
+ end
699
+ end
700
+
701
+ context 'when another object is not passed to the method' do
702
+
703
+ context 'when inverse_of is specified' do
704
+
705
+ before do
706
+ options.merge!(inverse_of: :inverse_name)
707
+ end
708
+
709
+ it 'returns the :inverse_of value' do
710
+ expect(association.inverses).to eq([ :inverse_name ])
711
+ end
712
+ end
713
+
714
+ context 'when inverse_of is not specified' do
715
+
716
+ it 'returns the :as attribute' do
717
+ expect(association.inverses).to eq([ :containable ])
718
+ end
719
+ end
720
+ end
721
+ end
722
+
723
+ context 'when not polymorphic' do
724
+
725
+ before do
726
+ BelongingObject.belongs_to :owner_object
727
+ end
728
+
729
+ context 'when inverse_of is specified' do
730
+
731
+ before do
732
+ options.merge!(inverse_of: :inverse_name)
733
+ end
734
+
735
+ it 'returns the :inverse_of value' do
736
+ expect(association.inverses).to eq([ :inverse_name ])
737
+ end
738
+ end
739
+
740
+ context 'when inverse_of is not specified' do
741
+
742
+ it 'uses the inverse class to find the inverse name' do
743
+ expect(association.inverses).to eq([ :owner_object ])
744
+ end
745
+ end
746
+
747
+ context 'when :cyclic is specified' do
748
+
749
+ it 'returns the cyclic inverse name' do
750
+
751
+ end
752
+ end
753
+ end
754
+ end
755
+
756
+ describe '##inverse' do
757
+
758
+ context 'when polymorphic' do
759
+
760
+ before do
761
+ BelongingObject.belongs_to :containable, polymorphic: true
762
+ end
763
+
764
+ let(:options) do
765
+ {
766
+ as: :containable
767
+ }
768
+ end
769
+
770
+ context 'when another object is passed to the method' do
771
+
772
+ let(:instance_of_other_class) do
773
+ BelongingObject.new
774
+ end
775
+
776
+ context 'when the relation class has only one relation whose class matches the owning class' do
777
+
778
+ it 'returns the :as attribute of this association' do
779
+ expect(association.inverse(instance_of_other_class)).to eq(:containable)
780
+ end
781
+ end
782
+
783
+ context 'when :inverse_of is specified' do
784
+
785
+ before do
786
+ options.merge!(inverse_of: :inverse_name)
787
+ end
788
+
789
+ it 'returns the :inverse_of value' do
790
+ expect(association.inverse(instance_of_other_class)).to eq(:inverse_name)
791
+ end
792
+ end
793
+
794
+ context 'when inverse_of is not specified' do
795
+
796
+ it 'returns the :as attribute of this association' do
797
+ expect(association.inverse(instance_of_other_class)).to eq(:containable)
798
+ end
799
+ end
800
+ end
801
+
802
+ context 'when another object is not passed to the method' do
803
+
804
+ context 'when inverse_of is specified' do
805
+
806
+ before do
807
+ options.merge!(inverse_of: :inverse_name)
808
+ end
809
+
810
+ it 'returns the :inverse_of value' do
811
+ expect(association.inverse).to eq(:inverse_name)
812
+ end
813
+ end
814
+
815
+ context 'when inverse_of is not specified' do
816
+
817
+ it 'returns the :as attribute' do
818
+ expect(association.inverse).to eq(:containable)
819
+ end
820
+ end
821
+ end
822
+ end
823
+
824
+ context 'when not polymorphic' do
825
+
826
+ before do
827
+ BelongingObject.belongs_to :owner_object
828
+ end
829
+
830
+ context 'when inverse_of is specified' do
831
+
832
+ before do
833
+ options.merge!(inverse_of: :inverse_name)
834
+ end
835
+
836
+ it 'returns the :inverse_of value' do
837
+ expect(association.inverse).to eq(:inverse_name)
838
+ end
839
+ end
840
+
841
+ context 'when inverse_of is not specified' do
842
+
843
+ it 'uses the inverse class to find the inverse name' do
844
+ expect(association.inverse).to eq(:owner_object)
845
+ end
846
+ end
847
+
848
+ context 'when :cyclic is specified' do
849
+
850
+ it 'returns the cyclic inverse name' do
851
+
852
+ end
853
+ end
854
+ end
855
+ end
856
+
857
+ describe '#inverse_association' do
858
+
859
+ end
860
+
861
+ describe '#autosave' do
862
+
863
+ context 'when the autosave option is specified' do
864
+
865
+ context 'when the autosave option is true' do
866
+
867
+ let(:options) do
868
+ {
869
+ autosave: true
870
+ }
871
+ end
872
+
873
+ it 'returns true' do
874
+ expect(association.autosave).to be(true)
875
+ end
876
+ end
877
+
878
+ context 'when the autosave option is false' do
879
+
880
+ let(:options) do
881
+ {
882
+ autosave: false
883
+ }
884
+ end
885
+
886
+ it 'returns false' do
887
+ expect(association.autosave).to be(false)
888
+ end
889
+ end
890
+ end
891
+
892
+ context 'when the autosave option is not specified' do
893
+
894
+ it 'returns false' do
895
+ expect(association.autosave).to be(false)
896
+ end
897
+ end
898
+ end
899
+
900
+ describe '#relation_class_name' do
901
+
902
+ context 'when the :class_name option is specified' do
903
+
904
+ let(:options) do
905
+ { class_name: 'OtherBelongingObject' }
906
+ end
907
+
908
+ it 'returns the class name option' do
909
+ expect(association.relation_class_name).to eq('OtherBelongingObject')
910
+ end
911
+ end
912
+
913
+ context 'when the class_name option is not specified' do
914
+
915
+ it 'uses the name of the relation to deduce the class name' do
916
+ expect(association.relation_class_name).to eq('BelongingObject')
917
+ end
918
+ end
919
+ end
920
+
921
+ describe '#relation_class' do
922
+
923
+ context 'when the :class_name option is specified' do
924
+
925
+ let!(:_class) do
926
+ class OtherBelongingObject; end
927
+ OtherBelongingObject
928
+ end
929
+
930
+ let(:options) do
931
+ { class_name: 'OtherBelongingObject' }
932
+ end
933
+
934
+ it 'returns the class name option' do
935
+ expect(association.relation_class).to eq(_class)
936
+ end
937
+ end
938
+
939
+ context 'when the class_name option is not specified' do
940
+
941
+ it 'uses the name of the relation to deduce the class name' do
942
+ expect(association.relation_class).to eq(BelongingObject)
943
+ end
944
+ end
945
+ end
946
+
947
+ describe '#inverse_class_name' do
948
+
949
+ it 'returns the name of the owner class' do
950
+ expect(association.inverse_class_name).to eq(OwnerObject.name)
951
+ end
952
+ end
953
+
954
+ describe '#inverse_class' do
955
+
956
+ it 'returns the owner class' do
957
+ expect(association.inverse_class).to be(OwnerObject)
958
+ end
959
+ end
960
+
961
+ describe '#inverse_of' do
962
+
963
+ context 'when :inverse_of is specified in the options' do
964
+
965
+ let(:options) do
966
+ { inverse_of: :a_belonging_object }
967
+ end
968
+
969
+ it 'returns the inverse_of value' do
970
+ expect(association.inverse_of).to eq(options[:inverse_of])
971
+ end
972
+ end
973
+
974
+ context 'when :inverse_of is not specified in the options' do
975
+
976
+ it 'returns nil' do
977
+ expect(association.inverse_of).to be_nil
978
+ end
979
+ end
980
+ end
981
+
982
+ describe '#key' do
983
+
984
+ it 'returns the primary key' do
985
+ expect(association.key).to eq(association.primary_key)
986
+ end
987
+ end
988
+
989
+ describe '#setter' do
990
+
991
+ it 'returns a string of the name followed by =' do
992
+ expect(association.setter).to eq("#{name}=")
993
+ end
994
+ end
995
+
996
+ describe '#validate?' do
997
+
998
+ context 'when :validate is specified in the options' do
999
+
1000
+ context 'when validate is true' do
1001
+
1002
+ let(:options) do
1003
+ { validate: true }
1004
+ end
1005
+
1006
+ it 'returns true' do
1007
+ expect(association.send(:validate?)).to be(true)
1008
+ end
1009
+ end
1010
+
1011
+ context 'when validate is false' do
1012
+
1013
+ let(:options) do
1014
+ { validate: false }
1015
+ end
1016
+
1017
+ it 'returns false' do
1018
+ expect(association.send(:validate?)).to be(false)
1019
+ end
1020
+ end
1021
+ end
1022
+
1023
+ context 'when :validate is not specified in the options' do
1024
+
1025
+ it 'returns the validation_default' do
1026
+ expect(association.send(:validate?)).to eq(association.validation_default)
1027
+ end
1028
+ end
1029
+ end
1030
+
1031
+ describe '#forced_nil_inverse?' do
1032
+
1033
+ it 'returns false' do
1034
+ expect(association.forced_nil_inverse?).to be(false)
1035
+ end
1036
+ end
1037
+
1038
+ describe '#stores_foreign_key?' do
1039
+
1040
+ it 'returns false' do
1041
+ expect(association.stores_foreign_key?).to be(false)
1042
+ end
1043
+ end
1044
+
1045
+ describe '#inverse_setter' do
1046
+
1047
+ context 'when an inverse can be determined' do
1048
+
1049
+ before do
1050
+ BelongingObject.belongs_to :owner_object
1051
+ end
1052
+
1053
+ it 'returns the name of the inverse followed by =' do
1054
+ expect(association.inverse_setter).to eq('owner_object=')
1055
+ end
1056
+ end
1057
+
1058
+ context 'when an inverse cannot be determined' do
1059
+
1060
+ it 'returns nil' do
1061
+ expect(association.inverse_setter).to be_nil
1062
+ end
1063
+ end
1064
+ end
1065
+
1066
+ describe '#extension' do
1067
+
1068
+ context 'when a block is passed' do
1069
+
1070
+ let(:association) do
1071
+ has_many_class.embeds_one name, options do; end
1072
+ end
1073
+
1074
+ it 'defines an extension module' do
1075
+ expect(association.extension).to be_a(Module)
1076
+ end
1077
+
1078
+ it 'returns the extension' do
1079
+ expect(association.extension).to eq(
1080
+ "#{has_many_class.name}::#{has_many_class.name}#{name.to_s.camelize}RelationExtension".constantize)
1081
+ end
1082
+ end
1083
+
1084
+ context 'when an :extension is not specified in the options' do
1085
+
1086
+ it 'returns false' do
1087
+ expect(association.extension).to be_nil
1088
+ end
1089
+ end
1090
+ end
1091
+
1092
+ describe '#foreign_key_setter' do
1093
+
1094
+ it 'returns the foreign key followed by "="' do
1095
+ expect(association.foreign_key_setter).to eq("#{association.foreign_key}=")
1096
+ end
1097
+ end
1098
+
1099
+ describe '#criteria' do
1100
+
1101
+ it 'returns a criteria object' do
1102
+ expect(association.criteria(OwnerObject.new)).to be_a(Mongoid::Criteria)
1103
+ end
1104
+ end
1105
+
1106
+ describe '#destructive?' do
1107
+
1108
+ context 'when the dependent option is provided' do
1109
+
1110
+ context 'when the dependent option is :delete_all' do
1111
+
1112
+ let(:options) do
1113
+ {
1114
+ dependent: :delete_all
1115
+ }
1116
+ end
1117
+
1118
+ it 'returns true' do
1119
+ expect(association.destructive?).to be(true)
1120
+ end
1121
+ end
1122
+
1123
+ context 'when the dependent option is :destroy' do
1124
+
1125
+ let(:options) do
1126
+ {
1127
+ dependent: :destroy
1128
+ }
1129
+ end
1130
+
1131
+ it 'returns true' do
1132
+ expect(association.destructive?).to be(true)
1133
+ end
1134
+ end
1135
+
1136
+ context 'when the dependent option is :nullify' do
1137
+
1138
+ let(:options) do
1139
+ {
1140
+ dependent: :nullify
1141
+ }
1142
+ end
1143
+
1144
+ it 'returns false' do
1145
+ expect(association.destructive?).to be(false)
1146
+ end
1147
+ end
1148
+
1149
+ context 'when the dependent option is :restrict_with_exception' do
1150
+
1151
+ let(:options) do
1152
+ {
1153
+ dependent: :restrict_with_exception
1154
+ }
1155
+ end
1156
+
1157
+ it 'returns false' do
1158
+ expect(association.destructive?).to be(false)
1159
+ end
1160
+ end
1161
+
1162
+ context 'when the dependent option is :restrict_with_error' do
1163
+
1164
+ let(:options) do
1165
+ {
1166
+ dependent: :restrict_with_error
1167
+ }
1168
+ end
1169
+
1170
+ it 'returns false' do
1171
+ expect(association.destructive?).to be(false)
1172
+ end
1173
+ end
1174
+ end
1175
+
1176
+ context 'when the dependent option is not provided' do
1177
+
1178
+ it 'returns false' do
1179
+ expect(association.destructive?).to be(false)
1180
+ end
1181
+ end
1182
+ end
1183
+
1184
+ describe '#nested_builder' do
1185
+
1186
+ it 'returns an instance of Association::Nested::Many' do
1187
+ expect(association.nested_builder({}, {})).to be_a(Mongoid::Association::Nested::Many)
1188
+ end
1189
+ end
1190
+
1191
+ describe '#path' do
1192
+
1193
+ it 'returns an instance of Mongoid::Atomic::Paths::Root' do
1194
+ expect(association.path(double( :_parent => true))).to be_a(Mongoid::Atomic::Paths::Root)
1195
+ end
1196
+ end
1197
+
1198
+ describe '#foreign_key_check' do
1199
+
1200
+ it 'returns the nil' do
1201
+ expect(association.foreign_key_check).to be_nil
1202
+ end
1203
+ end
1204
+
1205
+ describe '#create_relation' do
1206
+
1207
+ let(:owner) do
1208
+ OwnerObject.new
1209
+ end
1210
+
1211
+ let(:target) do
1212
+ [ BelongingObject.new ]
1213
+ end
1214
+
1215
+ before do
1216
+ association
1217
+ BelongingObject.belongs_to :owner_object
1218
+ end
1219
+
1220
+ it 'returns an the target (EmbeddedObject)' do
1221
+ expect(Mongoid::Association::Referenced::HasMany::Proxy).to receive(:new).and_call_original
1222
+ expect(association.create_relation(owner, target)).to be_a(Array)
1223
+ end
1224
+ end
1225
+ end