mongoid 3.1.6 → 4.0.2

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 (571) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +479 -8
  3. data/README.md +10 -7
  4. data/lib/config/locales/en.yml +34 -20
  5. data/lib/mongoid.rb +10 -76
  6. data/lib/mongoid/atomic.rb +3 -14
  7. data/lib/mongoid/atomic/paths/embedded.rb +0 -30
  8. data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
  9. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
  10. data/lib/mongoid/atomic/paths/root.rb +0 -13
  11. data/lib/mongoid/attributes.rb +65 -101
  12. data/lib/mongoid/attributes/dynamic.rb +154 -0
  13. data/lib/mongoid/attributes/nested.rb +82 -0
  14. data/lib/mongoid/attributes/processing.rb +13 -66
  15. data/lib/mongoid/{dirty.rb → changeable.rb} +32 -2
  16. data/lib/mongoid/composable.rb +105 -0
  17. data/lib/mongoid/config.rb +3 -9
  18. data/lib/mongoid/config/options.rb +1 -1
  19. data/lib/mongoid/contextual.rb +2 -0
  20. data/lib/mongoid/contextual/aggregable/memory.rb +2 -2
  21. data/lib/mongoid/contextual/aggregable/mongo.rb +7 -9
  22. data/lib/mongoid/contextual/atomic.rb +53 -53
  23. data/lib/mongoid/contextual/geo_near.rb +1 -1
  24. data/lib/mongoid/contextual/map_reduce.rb +4 -2
  25. data/lib/mongoid/contextual/memory.rb +23 -11
  26. data/lib/mongoid/contextual/mongo.rb +75 -57
  27. data/lib/mongoid/contextual/none.rb +90 -0
  28. data/lib/mongoid/contextual/text_search.rb +178 -0
  29. data/lib/mongoid/copyable.rb +2 -3
  30. data/lib/mongoid/criteria.rb +39 -34
  31. data/lib/mongoid/criteria/#findable.rb# +141 -0
  32. data/lib/mongoid/{criterion → criteria}/findable.rb +7 -47
  33. data/lib/mongoid/{criterion/inspection.rb → criteria/inspectable.rb} +2 -2
  34. data/lib/mongoid/{criterion → criteria}/marshalable.rb +3 -1
  35. data/lib/mongoid/{criterion → criteria}/modifiable.rb +28 -8
  36. data/lib/mongoid/criteria/permission.rb +70 -0
  37. data/lib/mongoid/{criterion/scoping.rb → criteria/scopable.rb} +2 -2
  38. data/lib/mongoid/document.rb +39 -24
  39. data/lib/mongoid/errors.rb +4 -1
  40. data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
  41. data/lib/mongoid/errors/document_not_found.rb +2 -1
  42. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  43. data/lib/mongoid/errors/invalid_storage_parent.rb +26 -0
  44. data/lib/mongoid/errors/invalid_value.rb +16 -0
  45. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  46. data/lib/mongoid/errors/readonly_document.rb +24 -0
  47. data/lib/mongoid/extensions.rb +15 -7
  48. data/lib/mongoid/extensions/array.rb +3 -3
  49. data/lib/mongoid/extensions/big_decimal.rb +1 -1
  50. data/lib/mongoid/extensions/boolean.rb +15 -17
  51. data/lib/mongoid/extensions/date.rb +1 -1
  52. data/lib/mongoid/extensions/date_time.rb +3 -3
  53. data/lib/mongoid/extensions/float.rb +2 -1
  54. data/lib/mongoid/extensions/hash.rb +3 -3
  55. data/lib/mongoid/extensions/integer.rb +1 -1
  56. data/lib/mongoid/extensions/object.rb +7 -7
  57. data/lib/mongoid/extensions/object_id.rb +5 -5
  58. data/lib/mongoid/extensions/range.rb +9 -3
  59. data/lib/mongoid/extensions/regexp.rb +1 -1
  60. data/lib/mongoid/extensions/set.rb +1 -1
  61. data/lib/mongoid/extensions/string.rb +6 -18
  62. data/lib/mongoid/extensions/symbol.rb +1 -1
  63. data/lib/mongoid/extensions/time.rb +3 -3
  64. data/lib/mongoid/extensions/time_with_zone.rb +1 -1
  65. data/lib/mongoid/factory.rb +8 -6
  66. data/lib/mongoid/fields.rb +41 -8
  67. data/lib/mongoid/fields/foreign_key.rb +3 -3
  68. data/lib/mongoid/fields/localized.rb +1 -1
  69. data/lib/mongoid/fields/standard.rb +5 -17
  70. data/lib/mongoid/fields/validators/macro.rb +15 -5
  71. data/lib/mongoid/{finders.rb → findable.rb} +35 -7
  72. data/lib/mongoid/{indexes.rb → indexable.rb} +50 -55
  73. data/lib/mongoid/indexable/specification.rb +104 -0
  74. data/lib/mongoid/{indexes → indexable}/validators/options.rb +2 -1
  75. data/lib/mongoid/{inspection.rb → inspectable.rb} +15 -11
  76. data/lib/mongoid/{callbacks.rb → interceptable.rb} +30 -62
  77. data/lib/mongoid/log_subscriber.rb +55 -0
  78. data/lib/mongoid/matchable.rb +152 -0
  79. data/lib/mongoid/{matchers → matchable}/all.rb +1 -1
  80. data/lib/mongoid/{matchers → matchable}/and.rb +2 -2
  81. data/lib/mongoid/{matchers → matchable}/default.rb +1 -1
  82. data/lib/mongoid/{matchers → matchable}/exists.rb +1 -1
  83. data/lib/mongoid/{matchers → matchable}/gt.rb +1 -1
  84. data/lib/mongoid/{matchers → matchable}/gte.rb +1 -1
  85. data/lib/mongoid/{matchers → matchable}/in.rb +2 -2
  86. data/lib/mongoid/{matchers → matchable}/lt.rb +1 -1
  87. data/lib/mongoid/{matchers → matchable}/lte.rb +1 -1
  88. data/lib/mongoid/{matchers → matchable}/ne.rb +2 -2
  89. data/lib/mongoid/{matchers → matchable}/nin.rb +3 -2
  90. data/lib/mongoid/{matchers → matchable}/or.rb +2 -2
  91. data/lib/mongoid/{matchers → matchable}/size.rb +1 -1
  92. data/lib/mongoid/persistable.rb +216 -0
  93. data/lib/mongoid/persistable/creatable.rb +189 -0
  94. data/lib/mongoid/persistable/deletable.rb +149 -0
  95. data/lib/mongoid/persistable/destroyable.rb +60 -0
  96. data/lib/mongoid/persistable/incrementable.rb +36 -0
  97. data/lib/mongoid/persistable/logical.rb +38 -0
  98. data/lib/mongoid/persistable/poppable.rb +39 -0
  99. data/lib/mongoid/persistable/pullable.rb +55 -0
  100. data/lib/mongoid/persistable/pushable.rb +62 -0
  101. data/lib/mongoid/persistable/renamable.rb +35 -0
  102. data/lib/mongoid/persistable/savable.rb +52 -0
  103. data/lib/mongoid/persistable/settable.rb +33 -0
  104. data/lib/mongoid/persistable/unsettable.rb +36 -0
  105. data/lib/mongoid/persistable/updatable.rb +153 -0
  106. data/lib/mongoid/persistable/upsertable.rb +55 -0
  107. data/lib/mongoid/positional.rb +71 -0
  108. data/lib/mongoid/query_cache.rb +255 -0
  109. data/lib/mongoid/railtie.rb +34 -60
  110. data/lib/mongoid/railties/database.rake +9 -25
  111. data/lib/mongoid/relations.rb +11 -25
  112. data/lib/mongoid/relations/accessors.rb +15 -51
  113. data/lib/mongoid/relations/auto_save.rb +15 -36
  114. data/lib/mongoid/relations/binding.rb +2 -25
  115. data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
  116. data/lib/mongoid/relations/bindings/embedded/many.rb +1 -3
  117. data/lib/mongoid/relations/bindings/referenced/in.rb +3 -8
  118. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -2
  119. data/lib/mongoid/relations/builder.rb +1 -1
  120. data/lib/mongoid/relations/builders.rb +2 -2
  121. data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
  122. data/lib/mongoid/relations/builders/nested_attributes/many.rb +10 -13
  123. data/lib/mongoid/relations/builders/nested_attributes/one.rb +5 -6
  124. data/lib/mongoid/relations/builders/referenced/in.rb +1 -1
  125. data/lib/mongoid/relations/builders/referenced/many.rb +1 -2
  126. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +1 -2
  127. data/lib/mongoid/relations/builders/referenced/one.rb +1 -1
  128. data/lib/mongoid/relations/cascading.rb +3 -5
  129. data/lib/mongoid/relations/constraint.rb +1 -1
  130. data/lib/mongoid/relations/conversions.rb +1 -1
  131. data/lib/mongoid/relations/counter_cache.rb +39 -15
  132. data/lib/mongoid/relations/eager.rb +46 -0
  133. data/lib/mongoid/relations/eager/base.rb +149 -0
  134. data/lib/mongoid/relations/eager/belongs_to.rb +31 -0
  135. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +47 -0
  136. data/lib/mongoid/relations/eager/has_many.rb +38 -0
  137. data/lib/mongoid/relations/eager/has_one.rb +30 -0
  138. data/lib/mongoid/relations/embedded/batchable.rb +4 -5
  139. data/lib/mongoid/relations/embedded/in.rb +4 -4
  140. data/lib/mongoid/relations/embedded/many.rb +14 -32
  141. data/lib/mongoid/relations/embedded/one.rb +1 -1
  142. data/lib/mongoid/relations/macros.rb +3 -4
  143. data/lib/mongoid/relations/many.rb +51 -31
  144. data/lib/mongoid/relations/marshalable.rb +3 -3
  145. data/lib/mongoid/relations/metadata.rb +14 -79
  146. data/lib/mongoid/relations/nested_builder.rb +2 -2
  147. data/lib/mongoid/relations/one.rb +1 -1
  148. data/lib/mongoid/relations/options.rb +1 -0
  149. data/lib/mongoid/relations/polymorphic.rb +0 -1
  150. data/lib/mongoid/relations/proxy.rb +21 -41
  151. data/lib/mongoid/relations/referenced/in.rb +4 -20
  152. data/lib/mongoid/relations/referenced/many.rb +22 -35
  153. data/lib/mongoid/relations/referenced/many_to_many.rb +19 -42
  154. data/lib/mongoid/relations/referenced/one.rb +6 -25
  155. data/lib/mongoid/relations/synchronization.rb +4 -4
  156. data/lib/mongoid/relations/targets/enumerable.rb +10 -10
  157. data/lib/mongoid/relations/touchable.rb +34 -1
  158. data/lib/mongoid/{reloading.rb → reloadable.rb} +7 -5
  159. data/lib/mongoid/{scoping.rb → scopable.rb} +36 -36
  160. data/lib/mongoid/selectable.rb +59 -0
  161. data/lib/mongoid/{serialization.rb → serializable.rb} +11 -2
  162. data/lib/mongoid/sessions.rb +37 -345
  163. data/lib/mongoid/sessions/factory.rb +2 -0
  164. data/lib/mongoid/sessions/options.rb +185 -0
  165. data/lib/mongoid/sessions/storage_options.rb +140 -0
  166. data/lib/mongoid/sessions/thread_options.rb +19 -0
  167. data/lib/mongoid/sessions/validators/storage.rb +16 -3
  168. data/lib/mongoid/{sharding.rb → shardable.rb} +5 -1
  169. data/lib/mongoid/{state.rb → stateful.rb} +13 -1
  170. data/lib/mongoid/support/query_counter.rb +23 -0
  171. data/lib/mongoid/tasks/database.rake +31 -0
  172. data/lib/mongoid/tasks/database.rb +107 -0
  173. data/lib/mongoid/threaded.rb +26 -172
  174. data/lib/mongoid/threaded/lifecycle.rb +0 -28
  175. data/lib/mongoid/timestamps/updated/short.rb +2 -2
  176. data/lib/mongoid/{hierarchy.rb → traversable.rb} +15 -7
  177. data/lib/mongoid/{validations.rb → validatable.rb} +23 -10
  178. data/lib/mongoid/{validations → validatable}/associated.rb +4 -2
  179. data/lib/mongoid/{validations → validatable}/format.rb +1 -1
  180. data/lib/mongoid/{validations → validatable}/length.rb +1 -1
  181. data/lib/mongoid/{validations → validatable}/localizable.rb +1 -1
  182. data/lib/mongoid/{validations → validatable}/macros.rb +4 -3
  183. data/lib/mongoid/{validations → validatable}/presence.rb +1 -1
  184. data/lib/mongoid/{validations → validatable}/queryable.rb +1 -2
  185. data/lib/mongoid/{validations → validatable}/uniqueness.rb +25 -21
  186. data/lib/mongoid/version.rb +1 -1
  187. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +46 -25
  188. data/lib/rails/generators/mongoid/model/model_generator.rb +0 -1
  189. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +0 -3
  190. data/lib/rails/generators/mongoid_generator.rb +3 -40
  191. data/lib/rails/mongoid.rb +0 -122
  192. data/lib/support/ruby_version.rb +1 -1
  193. data/spec/app/models/account.rb +2 -6
  194. data/spec/app/models/acolyte.rb +2 -1
  195. data/spec/app/models/actor.rb +0 -1
  196. data/spec/app/models/address.rb +8 -3
  197. data/spec/app/models/animal.rb +1 -1
  198. data/spec/app/models/appointment.rb +3 -3
  199. data/spec/app/models/article.rb +1 -4
  200. data/spec/app/models/audio.rb +5 -0
  201. data/spec/app/models/author.rb +0 -2
  202. data/spec/app/models/band.rb +3 -2
  203. data/spec/app/models/bar.rb +1 -0
  204. data/spec/app/models/book.rb +1 -0
  205. data/spec/app/models/building.rb +0 -2
  206. data/spec/app/models/building_address.rb +0 -2
  207. data/spec/app/models/bus.rb +1 -1
  208. data/spec/app/models/canvas.rb +1 -1
  209. data/spec/app/models/contextable_item.rb +5 -0
  210. data/spec/app/models/contractor.rb +0 -2
  211. data/spec/app/models/country_code.rb +1 -1
  212. data/spec/app/models/definition.rb +2 -2
  213. data/spec/app/models/dog.rb +1 -1
  214. data/spec/app/models/draft.rb +9 -0
  215. data/spec/app/models/dragon.rb +4 -0
  216. data/spec/app/models/drug.rb +1 -3
  217. data/spec/app/models/dungeon.rb +4 -0
  218. data/spec/app/models/edit.rb +5 -0
  219. data/spec/app/models/even.rb +7 -0
  220. data/spec/app/models/event.rb +1 -1
  221. data/spec/app/models/filesystem.rb +1 -0
  222. data/spec/app/models/fish.rb +0 -1
  223. data/spec/app/models/fruits.rb +6 -0
  224. data/spec/app/models/game.rb +0 -2
  225. data/spec/app/models/house.rb +1 -3
  226. data/spec/app/models/id_key.rb +6 -0
  227. data/spec/app/models/item.rb +1 -5
  228. data/spec/app/models/jar.rb +1 -1
  229. data/spec/app/models/label.rb +4 -4
  230. data/spec/app/models/line_item.rb +1 -1
  231. data/spec/app/models/login.rb +1 -1
  232. data/spec/app/models/message.rb +8 -0
  233. data/spec/app/models/movie.rb +1 -0
  234. data/spec/app/models/name.rb +3 -3
  235. data/spec/app/models/note.rb +3 -1
  236. data/spec/app/models/odd.rb +7 -0
  237. data/spec/app/models/oscar.rb +1 -1
  238. data/spec/app/models/parent_doc.rb +1 -1
  239. data/spec/app/models/person.rb +16 -10
  240. data/spec/app/models/phone.rb +1 -3
  241. data/spec/app/models/player.rb +3 -3
  242. data/spec/app/models/post.rb +5 -3
  243. data/spec/app/models/preference.rb +1 -1
  244. data/spec/app/models/quiz.rb +0 -3
  245. data/spec/app/models/record.rb +10 -5
  246. data/spec/app/models/registry.rb +1 -1
  247. data/spec/app/models/server.rb +1 -1
  248. data/spec/app/models/service.rb +3 -3
  249. data/spec/app/models/sound.rb +5 -0
  250. data/spec/app/models/symptom.rb +1 -1
  251. data/spec/app/models/template.rb +1 -1
  252. data/spec/app/models/title.rb +0 -1
  253. data/spec/app/models/track.rb +5 -5
  254. data/spec/app/models/tree.rb +3 -3
  255. data/spec/app/models/video.rb +1 -5
  256. data/spec/app/models/wiki_page.rb +2 -5
  257. data/spec/app/models/word.rb +3 -0
  258. data/spec/app/models/word_origin.rb +1 -1
  259. data/spec/config/mongoid.yml +7 -8
  260. data/spec/helpers.rb +18 -0
  261. data/spec/mongoid/#atomic_spec.rb# +365 -0
  262. data/spec/mongoid/atomic/modifiers_spec.rb +22 -22
  263. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +8 -49
  264. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +7 -49
  265. data/spec/mongoid/atomic/paths/root_spec.rb +3 -61
  266. data/spec/mongoid/atomic/paths_spec.rb +19 -19
  267. data/spec/mongoid/atomic_spec.rb +19 -19
  268. data/spec/mongoid/{nested_attributes_spec.rb → attributes/nested_spec.rb} +474 -592
  269. data/spec/mongoid/attributes/readonly_spec.rb +58 -18
  270. data/spec/mongoid/attributes_spec.rb +349 -434
  271. data/spec/mongoid/{dirty_spec.rb → changeable_spec.rb} +203 -153
  272. data/spec/mongoid/{components_spec.rb → composable_spec.rb} +3 -3
  273. data/spec/mongoid/config/environment_spec.rb +3 -3
  274. data/spec/mongoid/config/options_spec.rb +6 -6
  275. data/spec/mongoid/config_spec.rb +24 -48
  276. data/spec/mongoid/contextual/aggregable/memory_spec.rb +12 -12
  277. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +78 -38
  278. data/spec/mongoid/contextual/atomic_spec.rb +60 -56
  279. data/spec/mongoid/contextual/find_and_modify_spec.rb +14 -14
  280. data/spec/mongoid/contextual/geo_near_spec.rb +22 -22
  281. data/spec/mongoid/contextual/map_reduce_spec.rb +27 -27
  282. data/spec/mongoid/contextual/memory_spec.rb +156 -94
  283. data/spec/mongoid/contextual/mongo_spec.rb +238 -150
  284. data/spec/mongoid/contextual/none_spec.rb +127 -0
  285. data/spec/mongoid/contextual/text_search_spec.rb +209 -0
  286. data/spec/mongoid/copyable_spec.rb +56 -68
  287. data/spec/mongoid/criteria/findable_spec.rb +991 -0
  288. data/spec/mongoid/{criterion/inspection_spec.rb → criteria/inspectable_spec.rb} +5 -5
  289. data/spec/mongoid/{criterion → criteria}/marshalable_spec.rb +2 -2
  290. data/spec/mongoid/criteria/modifiable_spec.rb +1252 -0
  291. data/spec/mongoid/{criterion/scoping_spec.rb → criteria/scopable_spec.rb} +37 -37
  292. data/spec/mongoid/criteria_spec.rb +715 -2421
  293. data/spec/mongoid/document_spec.rb +171 -121
  294. data/spec/mongoid/equality_spec.rb +22 -22
  295. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +3 -3
  296. data/spec/mongoid/errors/callback_spec.rb +3 -3
  297. data/spec/mongoid/errors/delete_restriction_spec.rb +3 -3
  298. data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
  299. data/spec/mongoid/errors/document_not_found_spec.rb +11 -11
  300. data/spec/mongoid/errors/eager_load_spec.rb +3 -3
  301. data/spec/mongoid/errors/invalid_collection_spec.rb +3 -3
  302. data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -3
  303. data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -3
  304. data/spec/mongoid/errors/invalid_field_spec.rb +3 -3
  305. data/spec/mongoid/errors/invalid_find_spec.rb +3 -3
  306. data/spec/mongoid/errors/invalid_includes_spec.rb +3 -3
  307. data/spec/mongoid/errors/invalid_index_spec.rb +3 -3
  308. data/spec/mongoid/errors/invalid_options_spec.rb +3 -3
  309. data/spec/mongoid/errors/invalid_path_spec.rb +3 -3
  310. data/spec/mongoid/errors/invalid_scope_spec.rb +5 -5
  311. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -3
  312. data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -3
  313. data/spec/mongoid/errors/invalid_time_spec.rb +3 -3
  314. data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -3
  315. data/spec/mongoid/errors/mixed_relations_spec.rb +3 -3
  316. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +3 -3
  317. data/spec/mongoid/errors/mongoid_error_spec.rb +8 -8
  318. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +3 -3
  319. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  320. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -3
  321. data/spec/mongoid/errors/no_metadata_spec.rb +3 -3
  322. data/spec/mongoid/errors/no_parent_spec.rb +3 -3
  323. data/spec/mongoid/errors/no_session_config_spec.rb +3 -3
  324. data/spec/mongoid/errors/no_session_database_spec.rb +3 -3
  325. data/spec/mongoid/errors/no_session_hosts_spec.rb +3 -3
  326. data/spec/mongoid/errors/no_sessions_config_spec.rb +3 -3
  327. data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -3
  328. data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
  329. data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -3
  330. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -3
  331. data/spec/mongoid/errors/unknown_attribute_spec.rb +5 -5
  332. data/spec/mongoid/errors/unsaved_document_spec.rb +3 -3
  333. data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -3
  334. data/spec/mongoid/errors/validations_spec.rb +7 -7
  335. data/spec/mongoid/extensions/array_spec.rb +61 -61
  336. data/spec/mongoid/extensions/big_decimal_spec.rb +11 -11
  337. data/spec/mongoid/extensions/binary_spec.rb +12 -12
  338. data/spec/mongoid/extensions/boolean_spec.rb +18 -18
  339. data/spec/mongoid/extensions/date_spec.rb +13 -13
  340. data/spec/mongoid/extensions/date_time_spec.rb +8 -8
  341. data/spec/mongoid/extensions/false_class_spec.rb +5 -5
  342. data/spec/mongoid/extensions/float_spec.rb +29 -15
  343. data/spec/mongoid/extensions/hash_spec.rb +29 -29
  344. data/spec/mongoid/extensions/integer_spec.rb +15 -15
  345. data/spec/mongoid/extensions/module_spec.rb +2 -2
  346. data/spec/mongoid/extensions/nil_class_spec.rb +1 -1
  347. data/spec/mongoid/extensions/object_id_spec.rb +134 -134
  348. data/spec/mongoid/extensions/object_spec.rb +26 -26
  349. data/spec/mongoid/extensions/range_spec.rb +61 -12
  350. data/spec/mongoid/extensions/regexp_spec.rb +4 -4
  351. data/spec/mongoid/extensions/set_spec.rb +4 -4
  352. data/spec/mongoid/extensions/string_spec.rb +35 -46
  353. data/spec/mongoid/extensions/symbol_spec.rb +9 -9
  354. data/spec/mongoid/extensions/time_spec.rb +49 -49
  355. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -34
  356. data/spec/mongoid/extensions/true_class_spec.rb +5 -5
  357. data/spec/mongoid/extensions_spec.rb +29 -0
  358. data/spec/mongoid/factory_spec.rb +15 -15
  359. data/spec/mongoid/fields/foreign_key_spec.rb +73 -66
  360. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +15 -15
  361. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +22 -22
  362. data/spec/mongoid/fields/localized_spec.rb +38 -23
  363. data/spec/mongoid/fields/standard_spec.rb +12 -12
  364. data/spec/mongoid/fields_spec.rb +263 -217
  365. data/spec/mongoid/findable_spec.rb +509 -0
  366. data/spec/mongoid/indexable/specification_spec.rb +102 -0
  367. data/spec/mongoid/{indexes_spec.rb → indexable_spec.rb} +171 -51
  368. data/spec/mongoid/{inspection_spec.rb → inspectable_spec.rb} +6 -14
  369. data/spec/mongoid/{callbacks_spec.rb → interceptable_spec.rb} +117 -116
  370. data/spec/mongoid/log_subscriber_spec.rb +75 -0
  371. data/spec/mongoid/loggable_spec.rb +1 -1
  372. data/spec/mongoid/{matchers → matchable}/all_spec.rb +4 -4
  373. data/spec/mongoid/{matchers → matchable}/and_spec.rb +11 -11
  374. data/spec/mongoid/{matchers → matchable}/default_spec.rb +15 -15
  375. data/spec/mongoid/{matchers → matchable}/exists_spec.rb +5 -5
  376. data/spec/mongoid/{matchers → matchable}/gt_spec.rb +9 -8
  377. data/spec/mongoid/{matchers → matchable}/gte_spec.rb +7 -7
  378. data/spec/mongoid/matchable/in_spec.rb +49 -0
  379. data/spec/mongoid/{matchers → matchable}/lt_spec.rb +7 -7
  380. data/spec/mongoid/{matchers → matchable}/lte_spec.rb +7 -7
  381. data/spec/mongoid/matchable/ne_spec.rb +46 -0
  382. data/spec/mongoid/matchable/nin_spec.rb +48 -0
  383. data/spec/mongoid/{matchers → matchable}/or_spec.rb +6 -6
  384. data/spec/mongoid/{matchers → matchable}/size_spec.rb +3 -3
  385. data/spec/mongoid/{matchers_spec.rb → matchable_spec.rb} +41 -41
  386. data/spec/mongoid/persistable/creatable_spec.rb +553 -0
  387. data/spec/mongoid/persistable/deletable_spec.rb +218 -0
  388. data/spec/mongoid/persistable/destroyable_spec.rb +192 -0
  389. data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
  390. data/spec/mongoid/persistable/logical_spec.rb +143 -0
  391. data/spec/mongoid/persistable/poppable_spec.rb +115 -0
  392. data/spec/mongoid/persistable/pullable_spec.rb +228 -0
  393. data/spec/mongoid/persistable/pushable_spec.rb +258 -0
  394. data/spec/mongoid/persistable/renamable_spec.rb +135 -0
  395. data/spec/mongoid/persistable/savable_spec.rb +498 -0
  396. data/spec/mongoid/persistable/settable_spec.rb +162 -0
  397. data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
  398. data/spec/mongoid/persistable/updatable_spec.rb +558 -0
  399. data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
  400. data/spec/mongoid/persistable_spec.rb +206 -0
  401. data/spec/mongoid/{atomic/positionable_spec.rb → positional_spec.rb} +14 -19
  402. data/spec/mongoid/query_cache_spec.rb +263 -0
  403. data/spec/mongoid/railties/document_spec.rb +2 -2
  404. data/spec/mongoid/relations/accessors_spec.rb +53 -145
  405. data/spec/mongoid/relations/auto_save_spec.rb +37 -17
  406. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +12 -12
  407. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +3 -3
  408. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +5 -5
  409. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +26 -26
  410. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +10 -10
  411. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +19 -19
  412. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +12 -12
  413. data/spec/mongoid/relations/builders/embedded/in_spec.rb +4 -4
  414. data/spec/mongoid/relations/builders/embedded/many_spec.rb +18 -18
  415. data/spec/mongoid/relations/builders/embedded/one_spec.rb +11 -11
  416. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +12 -13
  417. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +14 -14
  418. data/spec/mongoid/relations/builders/referenced/in_spec.rb +24 -35
  419. data/spec/mongoid/relations/builders/referenced/many_spec.rb +15 -15
  420. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +18 -18
  421. data/spec/mongoid/relations/builders/referenced/one_spec.rb +12 -25
  422. data/spec/mongoid/relations/builders_spec.rb +21 -21
  423. data/spec/mongoid/relations/cascading/delete_spec.rb +9 -9
  424. data/spec/mongoid/relations/cascading/destroy_spec.rb +6 -6
  425. data/spec/mongoid/relations/cascading/nullify_spec.rb +4 -4
  426. data/spec/mongoid/relations/cascading/restrict_spec.rb +7 -7
  427. data/spec/mongoid/relations/cascading_spec.rb +16 -16
  428. data/spec/mongoid/relations/constraint_spec.rb +8 -7
  429. data/spec/mongoid/relations/conversions_spec.rb +16 -14
  430. data/spec/mongoid/relations/counter_cache_spec.rb +85 -0
  431. data/spec/mongoid/relations/cyclic_spec.rb +18 -18
  432. data/spec/mongoid/relations/eager/belongs_to_spec.rb +154 -0
  433. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +117 -0
  434. data/spec/mongoid/relations/eager/has_many_spec.rb +207 -0
  435. data/spec/mongoid/relations/eager/has_one_spec.rb +163 -0
  436. data/spec/mongoid/relations/eager_spec.rb +228 -0
  437. data/spec/mongoid/relations/embedded/dirty_spec.rb +8 -8
  438. data/spec/mongoid/relations/embedded/in_spec.rb +56 -57
  439. data/spec/mongoid/relations/embedded/many_spec.rb +467 -372
  440. data/spec/mongoid/relations/embedded/one_spec.rb +108 -141
  441. data/spec/mongoid/relations/macros_spec.rb +108 -102
  442. data/spec/mongoid/relations/metadata_spec.rb +180 -255
  443. data/spec/mongoid/relations/options_spec.rb +1 -1
  444. data/spec/mongoid/relations/polymorphic_spec.rb +13 -17
  445. data/spec/mongoid/relations/proxy_spec.rb +2 -2
  446. data/spec/mongoid/relations/referenced/in_spec.rb +128 -303
  447. data/spec/mongoid/relations/referenced/many_spec.rb +587 -527
  448. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +401 -424
  449. data/spec/mongoid/relations/referenced/one_spec.rb +149 -264
  450. data/spec/mongoid/relations/reflections_spec.rb +6 -6
  451. data/spec/mongoid/relations/synchronization_spec.rb +46 -50
  452. data/spec/mongoid/relations/targets/enumerable_spec.rb +118 -118
  453. data/spec/mongoid/relations/touchable_spec.rb +333 -0
  454. data/spec/mongoid/relations_spec.rb +16 -15
  455. data/spec/mongoid/{reloading_spec.rb → reloadable_spec.rb} +38 -55
  456. data/spec/mongoid/{scoping_spec.rb → scopable_spec.rb} +89 -164
  457. data/spec/mongoid/selectable_spec.rb +134 -0
  458. data/spec/mongoid/{serialization_spec.rb → serializable_spec.rb} +129 -82
  459. data/spec/mongoid/sessions/factory_spec.rb +49 -28
  460. data/spec/mongoid/sessions/mongo_uri_spec.rb +7 -7
  461. data/spec/mongoid/sessions/options_spec.rb +108 -0
  462. data/spec/mongoid/sessions_spec.rb +319 -178
  463. data/spec/mongoid/{sharding_spec.rb → shardable_spec.rb} +8 -8
  464. data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +36 -11
  465. data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
  466. data/spec/mongoid/tasks/database_spec.rb +160 -0
  467. data/spec/mongoid/threaded_spec.rb +17 -70
  468. data/spec/mongoid/timestamps/created/short_spec.rb +6 -6
  469. data/spec/mongoid/timestamps/created_spec.rb +5 -5
  470. data/spec/mongoid/timestamps/timeless_spec.rb +6 -6
  471. data/spec/mongoid/timestamps/updated/short_spec.rb +11 -11
  472. data/spec/mongoid/timestamps/updated_spec.rb +9 -13
  473. data/spec/mongoid/timestamps_spec.rb +9 -13
  474. data/spec/mongoid/{hierarchy_spec.rb → traversable_spec.rb} +19 -19
  475. data/spec/mongoid/{validations → validatable}/associated_spec.rb +45 -22
  476. data/spec/mongoid/{validations → validatable}/format_spec.rb +6 -6
  477. data/spec/mongoid/{validations → validatable}/length_spec.rb +14 -14
  478. data/spec/mongoid/{validations → validatable}/numericality_spec.rb +1 -1
  479. data/spec/mongoid/{validations → validatable}/presence_spec.rb +37 -44
  480. data/spec/mongoid/{validations → validatable}/uniqueness_spec.rb +184 -192
  481. data/spec/mongoid/{validations_spec.rb → validatable_spec.rb} +28 -28
  482. data/spec/mongoid_spec.rb +8 -8
  483. data/spec/rails/mongoid_spec.rb +19 -335
  484. data/spec/spec_helper.rb +31 -13
  485. metadata +303 -283
  486. data/lib/mongoid/atomic/positionable.rb +0 -73
  487. data/lib/mongoid/components.rb +0 -92
  488. data/lib/mongoid/config/inflections.rb +0 -6
  489. data/lib/mongoid/contextual/eager.rb +0 -158
  490. data/lib/mongoid/errors/versioning_not_on_root.rb +0 -23
  491. data/lib/mongoid/identity_map.rb +0 -163
  492. data/lib/mongoid/json.rb +0 -16
  493. data/lib/mongoid/matchers.rb +0 -32
  494. data/lib/mongoid/matchers/strategies.rb +0 -97
  495. data/lib/mongoid/multi_parameter_attributes.rb +0 -105
  496. data/lib/mongoid/nested_attributes.rb +0 -78
  497. data/lib/mongoid/observer.rb +0 -192
  498. data/lib/mongoid/paranoia.rb +0 -136
  499. data/lib/mongoid/persistence.rb +0 -357
  500. data/lib/mongoid/persistence/atomic.rb +0 -231
  501. data/lib/mongoid/persistence/atomic/add_to_set.rb +0 -47
  502. data/lib/mongoid/persistence/atomic/bit.rb +0 -35
  503. data/lib/mongoid/persistence/atomic/inc.rb +0 -45
  504. data/lib/mongoid/persistence/atomic/operation.rb +0 -154
  505. data/lib/mongoid/persistence/atomic/pop.rb +0 -32
  506. data/lib/mongoid/persistence/atomic/pull.rb +0 -32
  507. data/lib/mongoid/persistence/atomic/pull_all.rb +0 -32
  508. data/lib/mongoid/persistence/atomic/push.rb +0 -25
  509. data/lib/mongoid/persistence/atomic/push_all.rb +0 -25
  510. data/lib/mongoid/persistence/atomic/rename.rb +0 -30
  511. data/lib/mongoid/persistence/atomic/sets.rb +0 -28
  512. data/lib/mongoid/persistence/atomic/unset.rb +0 -27
  513. data/lib/mongoid/persistence/deletion.rb +0 -31
  514. data/lib/mongoid/persistence/insertion.rb +0 -38
  515. data/lib/mongoid/persistence/modification.rb +0 -35
  516. data/lib/mongoid/persistence/operations.rb +0 -214
  517. data/lib/mongoid/persistence/operations/embedded/insert.rb +0 -46
  518. data/lib/mongoid/persistence/operations/embedded/remove.rb +0 -43
  519. data/lib/mongoid/persistence/operations/insert.rb +0 -34
  520. data/lib/mongoid/persistence/operations/remove.rb +0 -33
  521. data/lib/mongoid/persistence/operations/update.rb +0 -59
  522. data/lib/mongoid/persistence/operations/upsert.rb +0 -28
  523. data/lib/mongoid/persistence/upsertion.rb +0 -31
  524. data/lib/mongoid/unit_of_work.rb +0 -61
  525. data/lib/mongoid/versioning.rb +0 -217
  526. data/lib/rack/mongoid.rb +0 -2
  527. data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
  528. data/lib/rails/generators/mongoid/observer/observer_generator.rb +0 -17
  529. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +0 -4
  530. data/spec/app/models/actor_observer.rb +0 -15
  531. data/spec/app/models/callback_recorder.rb +0 -25
  532. data/spec/app/models/paranoid_phone.rb +0 -25
  533. data/spec/app/models/paranoid_post.rb +0 -36
  534. data/spec/app/models/phone_observer.rb +0 -6
  535. data/spec/mongoid/attributes/processing_spec.rb +0 -149
  536. data/spec/mongoid/criterion/destructive_spec.rb +0 -101
  537. data/spec/mongoid/criterion/modifiable_spec.rb +0 -409
  538. data/spec/mongoid/criterion/modification_spec.rb +0 -402
  539. data/spec/mongoid/errors/versioning_not_on_root_spec.rb +0 -29
  540. data/spec/mongoid/finders_spec.rb +0 -321
  541. data/spec/mongoid/identity_map_spec.rb +0 -564
  542. data/spec/mongoid/json_spec.rb +0 -33
  543. data/spec/mongoid/matchers/in_spec.rb +0 -25
  544. data/spec/mongoid/matchers/ne_spec.rb +0 -25
  545. data/spec/mongoid/matchers/nin_spec.rb +0 -25
  546. data/spec/mongoid/multi_parameter_attributes_spec.rb +0 -128
  547. data/spec/mongoid/observer_spec.rb +0 -290
  548. data/spec/mongoid/paranoia_spec.rb +0 -759
  549. data/spec/mongoid/persistence/atomic/add_to_set_spec.rb +0 -262
  550. data/spec/mongoid/persistence/atomic/bit_spec.rb +0 -88
  551. data/spec/mongoid/persistence/atomic/inc_spec.rb +0 -133
  552. data/spec/mongoid/persistence/atomic/pop_spec.rb +0 -111
  553. data/spec/mongoid/persistence/atomic/pull_all_spec.rb +0 -77
  554. data/spec/mongoid/persistence/atomic/pull_spec.rb +0 -80
  555. data/spec/mongoid/persistence/atomic/push_all_spec.rb +0 -77
  556. data/spec/mongoid/persistence/atomic/push_spec.rb +0 -77
  557. data/spec/mongoid/persistence/atomic/rename_spec.rb +0 -42
  558. data/spec/mongoid/persistence/atomic/sets_spec.rb +0 -154
  559. data/spec/mongoid/persistence/atomic/unset_spec.rb +0 -65
  560. data/spec/mongoid/persistence/atomic_spec.rb +0 -216
  561. data/spec/mongoid/persistence/operations/embedded/insert_spec.rb +0 -191
  562. data/spec/mongoid/persistence/operations/embedded/remove_spec.rb +0 -8
  563. data/spec/mongoid/persistence/operations/insert_spec.rb +0 -149
  564. data/spec/mongoid/persistence/operations/remove_spec.rb +0 -113
  565. data/spec/mongoid/persistence/operations/update_spec.rb +0 -141
  566. data/spec/mongoid/persistence/operations/upsert_spec.rb +0 -59
  567. data/spec/mongoid/persistence/operations_spec.rb +0 -313
  568. data/spec/mongoid/persistence_spec.rb +0 -2279
  569. data/spec/mongoid/unit_of_work_spec.rb +0 -196
  570. data/spec/mongoid/versioning_spec.rb +0 -540
  571. data/spec/rack/mongoid/middleware/identity_map_spec.rb +0 -72
@@ -0,0 +1,258 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Persistable::Pushable do
4
+
5
+ describe "#add_to_set" do
6
+
7
+ context "when the document is a root document" do
8
+
9
+ shared_examples_for "a unique pushable root document" do
10
+
11
+ it "adds single values" do
12
+ expect(person.aliases).to eq([ 1, 2, 4 ])
13
+ end
14
+
15
+ it "does not add duplicate values" do
16
+ expect(person.array).to eq([ 4, 5 ])
17
+ end
18
+
19
+ it "sets absent values" do
20
+ expect(person.test_array).to eq([ 1 ])
21
+ end
22
+
23
+ it "returns self objet" do
24
+ expect(add).to eq(person)
25
+ end
26
+
27
+ it "resets the dirty changes" do
28
+ expect(person).to_not be_changed
29
+ end
30
+
31
+ it "persists single adds" do
32
+ expect(person.reload.aliases).to eq([ 1, 2, 4 ])
33
+ end
34
+
35
+ it "persists absent values" do
36
+ expect(person.reload.test_array).to eq([ 1 ])
37
+ end
38
+
39
+ it "flattens only 1 level" do
40
+ expect(person.reload.arrays).to eq([[ 7, 8 ]])
41
+ end
42
+ end
43
+
44
+ let(:person) do
45
+ Person.create(aliases: [ 1, 2 ], array: [ 4, 5 ])
46
+ end
47
+
48
+ context "when provided string fields" do
49
+
50
+ let!(:add) do
51
+ person.add_to_set("aliases" => 4, "array" => [4, 5], "test_array" => 1, "arrays" => [[ 7, 8 ]])
52
+ end
53
+
54
+ it_behaves_like "a unique pushable root document"
55
+ end
56
+
57
+ context "when provided symbol fields" do
58
+
59
+ let!(:add) do
60
+ person.add_to_set(aliases: 4, array: [4, 5], test_array: 1, arrays: [[ 7, 8 ]])
61
+ end
62
+
63
+ it_behaves_like "a unique pushable root document"
64
+ end
65
+ end
66
+
67
+ context "when the document is embedded" do
68
+
69
+ shared_examples_for "a unique pushable embedded document" do
70
+
71
+ it "adds single values" do
72
+ expect(address.services).to eq([ 1, 4 ])
73
+ end
74
+
75
+ it "does not add duplicate values" do
76
+ expect(address.a).to eq([ 4, 5 ])
77
+ end
78
+
79
+ it "sets absent values" do
80
+ expect(address.test).to eq([ 1 ])
81
+ end
82
+
83
+ it "returns self object" do
84
+ expect(add).to eq(address)
85
+ end
86
+
87
+ it "resets the dirty changes" do
88
+ expect(address).to_not be_changed
89
+ end
90
+
91
+ it "persists single adds" do
92
+ expect(address.reload.services).to eq([ 1, 4 ])
93
+ end
94
+
95
+ it "persists absent values" do
96
+ expect(address.reload.test).to eq([ 1 ])
97
+ end
98
+ end
99
+
100
+ let(:person) do
101
+ Person.create
102
+ end
103
+
104
+ let(:address) do
105
+ person.addresses.create(street: "t", services: [ 1 ], a: [ 4, 5 ])
106
+ end
107
+
108
+ context "when provided string fields" do
109
+
110
+ let!(:add) do
111
+ address.add_to_set("services" => 4, "a" => 5, "test" => 1)
112
+ end
113
+
114
+ it_behaves_like "a unique pushable embedded document"
115
+ end
116
+
117
+ context "when provided symbol fields" do
118
+
119
+ let!(:add) do
120
+ address.add_to_set(services: 4, a: 5, test: 1)
121
+ end
122
+
123
+ it_behaves_like "a unique pushable embedded document"
124
+ end
125
+ end
126
+ end
127
+
128
+ describe "#push" do
129
+
130
+ context "when the document is a root document" do
131
+
132
+ shared_examples_for "a pushable root document" do
133
+
134
+ it "pushes single values" do
135
+ expect(person.aliases).to eq([ 1, 2, 3, 4 ])
136
+ end
137
+
138
+ it "pushes multiple values" do
139
+ expect(person.array).to eq([ 4, 5, 6, 7, 8 ])
140
+ end
141
+
142
+ it "sets absent values" do
143
+ expect(person.test_array).to eq([ 1 ])
144
+ end
145
+
146
+ it "returns self object" do
147
+ expect(push).to eq(person)
148
+ end
149
+
150
+ it "resets the dirty changes" do
151
+ expect(person).to_not be_changed
152
+ end
153
+
154
+ it "persists single pushes" do
155
+ expect(person.reload.aliases).to eq([ 1, 2, 3, 4 ])
156
+ end
157
+
158
+ it "persists multiple pushes" do
159
+ expect(person.reload.array).to eq([ 4, 5, 6, 7, 8 ])
160
+ end
161
+
162
+ it "persists absent values" do
163
+ expect(person.reload.test_array).to eq([ 1 ])
164
+ end
165
+
166
+ it "flattens only 1 level" do
167
+ expect(person.reload.arrays).to eq([[ 7, 8 ]])
168
+ end
169
+ end
170
+
171
+ let(:person) do
172
+ Person.create(aliases: [ 1, 2, 3 ], array: [ 4, 5, 6 ])
173
+ end
174
+
175
+ context "when provided string fields" do
176
+
177
+ let!(:push) do
178
+ person.push("aliases" => 4, "array" => [ 7, 8 ], "test_array" => 1, "arrays" => [[ 7, 8 ]])
179
+ end
180
+
181
+ it_behaves_like "a pushable root document"
182
+ end
183
+
184
+ context "when provided symbol fields" do
185
+
186
+ let!(:push) do
187
+ person.push(aliases: 4, array: [ 7, 8 ], test_array: 1, arrays: [[ 7, 8 ]])
188
+ end
189
+
190
+ it_behaves_like "a pushable root document"
191
+ end
192
+ end
193
+
194
+ context "when the document is embedded" do
195
+
196
+ shared_examples_for "a pushable embedded document" do
197
+
198
+ it "pushes single values" do
199
+ expect(address.services).to eq([ 1, 4 ])
200
+ end
201
+
202
+ it "pushes multiple values" do
203
+ expect(address.a).to eq([ 4, 5, 6, 7 ])
204
+ end
205
+
206
+ it "sets absent values" do
207
+ expect(address.test).to eq([ 1 ])
208
+ end
209
+
210
+ it "returns self object" do
211
+ expect(push).to eq(address)
212
+ end
213
+
214
+ it "resets the dirty changes" do
215
+ expect(address).to_not be_changed
216
+ end
217
+
218
+ it "persists single pushes" do
219
+ expect(address.reload.services).to eq([ 1, 4 ])
220
+ end
221
+
222
+ it "persists multiple pushes" do
223
+ expect(address.reload.a).to eq([ 4, 5, 6, 7 ])
224
+ end
225
+
226
+ it "persists absent values" do
227
+ expect(address.reload.test).to eq([ 1 ])
228
+ end
229
+ end
230
+
231
+ let(:person) do
232
+ Person.create
233
+ end
234
+
235
+ let(:address) do
236
+ person.addresses.create(street: "t", services: [ 1 ], a: [ 4, 5 ])
237
+ end
238
+
239
+ context "when provided string fields" do
240
+
241
+ let!(:push) do
242
+ address.push("services" => 4, "a" => [ 6, 7 ], "test" => 1)
243
+ end
244
+
245
+ it_behaves_like "a pushable embedded document"
246
+ end
247
+
248
+ context "when provided symbol fields" do
249
+
250
+ let!(:push) do
251
+ address.push(services: 4, a: [ 6, 7 ], test: 1)
252
+ end
253
+
254
+ it_behaves_like "a pushable embedded document"
255
+ end
256
+ end
257
+ end
258
+ end
@@ -0,0 +1,135 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Persistable::Renamable do
4
+
5
+ describe "#rename" do
6
+
7
+ context "when the document is a root document" do
8
+
9
+ shared_examples_for "a renamable root document" do
10
+
11
+ it "renames the first field" do
12
+ expect(person.salutation).to eq("sir")
13
+ end
14
+
15
+ it "removes the first original value" do
16
+ expect(person.title).to be_nil
17
+ end
18
+
19
+ it "renames the second field" do
20
+ expect(person.date_of_birth.to_date).to eq(date)
21
+ end
22
+
23
+ it "removes the second original value" do
24
+ expect(person.dob).to be_nil
25
+ end
26
+
27
+ it "returns self object" do
28
+ expect(rename).to eq(person)
29
+ end
30
+
31
+ it "persists the first rename" do
32
+ expect(person.reload.salutation).to eq("sir")
33
+ end
34
+
35
+ it "persists the first original removal" do
36
+ expect(person.reload.title).to be_nil
37
+ end
38
+
39
+ it "persists the second rename" do
40
+ expect(person.reload.date_of_birth.to_date).to eq(date)
41
+ end
42
+
43
+ it "persists the second original removal" do
44
+ expect(person.reload.dob).to be_nil
45
+ end
46
+
47
+ it "clears out the dirty changes" do
48
+ expect(person).to_not be_changed
49
+ end
50
+ end
51
+
52
+ let(:date) do
53
+ Date.new(2013, 1, 1)
54
+ end
55
+
56
+ let(:person) do
57
+ Person.create(title: "sir", dob: date)
58
+ end
59
+
60
+ context "when provided symbol names" do
61
+
62
+ let!(:rename) do
63
+ person.rename(title: :salutation, dob: :date_of_birth)
64
+ end
65
+
66
+ it_behaves_like "a renamable root document"
67
+ end
68
+
69
+ context "when provided string names" do
70
+
71
+ let!(:rename) do
72
+ person.rename(title: "salutation", dob: "date_of_birth")
73
+ end
74
+
75
+ it_behaves_like "a renamable root document"
76
+ end
77
+ end
78
+
79
+ context "when the document is embedded" do
80
+
81
+ shared_examples_for "a renamable embedded document" do
82
+
83
+ it "renames the first field" do
84
+ expect(name.mi).to eq("blah")
85
+ end
86
+
87
+ it "removes the first original value" do
88
+ expect(name.middle).to be_nil
89
+ end
90
+
91
+ it "returns self object" do
92
+ expect(rename).to eq(name)
93
+ end
94
+
95
+ it "persists the first rename" do
96
+ expect(name.reload.mi).to eq("blah")
97
+ end
98
+
99
+ it "persists the first original removal" do
100
+ expect(name.reload.middle).to be_nil
101
+ end
102
+
103
+ it "clears out the dirty changes" do
104
+ expect(name).to_not be_changed
105
+ end
106
+ end
107
+
108
+ let(:person) do
109
+ Person.create
110
+ end
111
+
112
+ let(:name) do
113
+ person.create_name(first_name: "test", last_name: "user", middle: "blah")
114
+ end
115
+
116
+ context "when provided symbol names" do
117
+
118
+ let!(:rename) do
119
+ name.rename(middle: :mi)
120
+ end
121
+
122
+ it_behaves_like "a renamable embedded document"
123
+ end
124
+
125
+ context "when provided string names" do
126
+
127
+ let!(:rename) do
128
+ name.rename(middle: "mi")
129
+ end
130
+
131
+ it_behaves_like "a renamable embedded document"
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,498 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Persistable::Savable do
4
+
5
+ describe "#save" do
6
+
7
+ let(:person) do
8
+ Person.create
9
+ end
10
+
11
+ let(:contextable_item) do
12
+ ContextableItem.new
13
+ end
14
+
15
+ let(:persisted_contextable_item) do
16
+ ContextableItem.create(title: 'sir')
17
+ end
18
+
19
+ context "when skipping validation" do
20
+
21
+ context "when no relations are involved" do
22
+
23
+ let(:account) do
24
+ Account.new
25
+ end
26
+
27
+ let!(:saved) do
28
+ account.save(validate: false)
29
+ end
30
+
31
+ it "returns true" do
32
+ expect(saved).to be true
33
+ end
34
+
35
+ it "saves the document" do
36
+ expect(account).to be_persisted
37
+ end
38
+
39
+ it "does not add any validation errors" do
40
+ expect(account.errors).to be_empty
41
+ end
42
+ end
43
+
44
+ context "when saving document that is a belongs to child" do
45
+
46
+ let(:account) do
47
+ Account.create
48
+ end
49
+
50
+ let(:alert) do
51
+ Alert.new(account: account)
52
+ end
53
+
54
+ context "when validating presence of the parent" do
55
+
56
+ before do
57
+ Alert.validates(:message, :account, presence: true)
58
+ end
59
+
60
+ after do
61
+ Alert.reset_callbacks(:validate)
62
+ end
63
+
64
+ context "when the parent validates associated on the child" do
65
+
66
+ before do
67
+ alert.save(validate: false)
68
+ end
69
+
70
+ it "clears any errors off the document" do
71
+ expect(alert.errors).to be_empty
72
+ end
73
+
74
+ context "when the document is not new" do
75
+
76
+ before do
77
+ alert.save(validate: false)
78
+ end
79
+
80
+ it "clears any errors off the document" do
81
+ expect(alert.errors).to be_empty
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ context "when the document has been instantiated with limited fields" do
90
+
91
+ before do
92
+ person.age = 20
93
+ person.save
94
+ end
95
+
96
+ context "when a default is excluded" do
97
+
98
+ let(:limited) do
99
+ Person.only(:_id).find(person.id)
100
+ end
101
+
102
+ it "does not flag the excluded fields as dirty" do
103
+ expect(limited.changes).to be_empty
104
+ end
105
+ end
106
+
107
+ context "when iterating over the documents" do
108
+
109
+ let(:limited) do
110
+ Person.only(:_id)
111
+ end
112
+
113
+ it "does not flag any changes" do
114
+ limited.each do |person|
115
+ expect(person.changes).to be_empty
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ context "when validation passes" do
122
+
123
+ it "returns true" do
124
+ expect(person.save).to be true
125
+ end
126
+ end
127
+
128
+ context "when validation fails" do
129
+
130
+ let(:address) do
131
+ person.addresses.create(city: "London")
132
+ end
133
+
134
+ before do
135
+ address.save
136
+ end
137
+
138
+ it "has the appropriate errors" do
139
+ expect(address.errors[:street]).to eq(["can't be blank"])
140
+ end
141
+ end
142
+
143
+ context "when modifying the entire hierarchy" do
144
+
145
+ context "when performing modification and insert ops" do
146
+
147
+ let(:person) do
148
+ Person.create(title: "Blah")
149
+ end
150
+
151
+ let!(:address) do
152
+ person.addresses.build(street: "Bond St")
153
+ end
154
+
155
+ let!(:name) do
156
+ person.create_name(first_name: "Tony")
157
+ end
158
+
159
+ let(:from_db) do
160
+ Person.find(person.id)
161
+ end
162
+
163
+ before do
164
+ person.title = "King"
165
+ name.first_name = "Ryan"
166
+ end
167
+
168
+ it "persists with proper set and push modifiers" do
169
+ expect(person.atomic_updates).to eq({
170
+ "$set" => {
171
+ "title" => "King",
172
+ "name.first_name" => "Ryan"
173
+ },
174
+ "$pushAll"=> {
175
+ "addresses" => [ { "_id" => address.id, "street" => "Bond St" } ]
176
+ }
177
+ })
178
+ end
179
+
180
+ context "when saving the document" do
181
+
182
+ it "saves the root document" do
183
+ expect(person.title).to eq("King")
184
+ end
185
+
186
+ it "saves embedded many relations" do
187
+ expect(person.addresses.first.street).to eq("Bond St")
188
+ end
189
+
190
+ it "saves embedded one relations" do
191
+ expect(person.name.first_name).to eq("Ryan")
192
+ end
193
+ end
194
+ end
195
+
196
+ context "when combining modifications and pushes" do
197
+
198
+ let!(:location) do
199
+ Location.new(name: 'Work')
200
+ end
201
+
202
+ let!(:address) do
203
+ Address.new(
204
+ number: 101,
205
+ street: 'South St',
206
+ locations: [ location ]
207
+ )
208
+ end
209
+
210
+ let!(:person) do
211
+ Person.create(
212
+ title: "Blah",
213
+ addresses: [ address ]
214
+ )
215
+ end
216
+
217
+ let(:from_db) do
218
+ Person.find(person.id)
219
+ end
220
+
221
+ before do
222
+ address.number = 102
223
+ person.addresses << Address.new(street: "North Ave")
224
+ person.save
225
+ end
226
+
227
+ it "saves modifications to existing embedded docs" do
228
+ expect(from_db.addresses[0].number).to eq(102)
229
+ end
230
+
231
+ it "saves modifications to new embedded docs" do
232
+ expect(from_db.addresses[1].street).to eq('North Ave')
233
+ end
234
+
235
+ it "saves modifications to deeply embedded docs" do
236
+ expect(from_db.addresses[0].locations.first.name).to eq('Work')
237
+ end
238
+ end
239
+
240
+ context "when removing elements without using delete or destroy" do
241
+
242
+ let!(:person) do
243
+ Person.create!(title: "Blah")
244
+ end
245
+
246
+ let(:from_db) do
247
+ Person.find(person.id)
248
+ end
249
+
250
+ before do
251
+ person.create_name(first_name: "Tony")
252
+ person.name = nil
253
+ person.save
254
+ end
255
+
256
+ it "saves the hierarchy" do
257
+ expect(person.name).to be_nil
258
+ end
259
+ end
260
+ end
261
+
262
+ context "when setting floating point numbers" do
263
+
264
+ context "when value is an empty string" do
265
+
266
+ let(:person) do
267
+ Person.new
268
+ end
269
+
270
+ before do
271
+ Person.validates_numericality_of :blood_alcohol_content, allow_blank: true
272
+ end
273
+
274
+ it "does not set the value" do
275
+ expect(person.save).to be true
276
+ end
277
+ end
278
+ end
279
+
280
+ context "when the document is readonly" do
281
+
282
+ let(:person) do
283
+ Person.only(:title).first
284
+ end
285
+
286
+ before do
287
+ Person.create(title: "sir")
288
+ end
289
+
290
+ it "raises an error" do
291
+ expect {
292
+ person.save
293
+ }.to raise_error(Mongoid::Errors::ReadonlyDocument)
294
+ end
295
+ end
296
+
297
+ context "when validation context isn't assigned" do
298
+ it "returns true" do
299
+ expect(contextable_item.save).to be true
300
+ end
301
+ end
302
+
303
+ context "when validation context exists" do
304
+ context "on new document" do
305
+ it "returns true" do
306
+ contextable_item.title = "sir"
307
+ expect(contextable_item.save(context: :in_context)).to be true
308
+ end
309
+ it "returns false" do
310
+ expect(contextable_item.save(context: :in_context)).to be false
311
+ end
312
+ end
313
+
314
+ context "on persisted document" do
315
+ it "returns true" do
316
+ persisted_contextable_item.title = "lady"
317
+ expect(persisted_contextable_item.save(context: :in_context)).to be true
318
+ end
319
+ it "returns false" do
320
+ persisted_contextable_item.title = nil
321
+ expect(persisted_contextable_item.save(context: :in_context)).to be false
322
+ end
323
+ end
324
+ end
325
+ end
326
+
327
+ describe "save!" do
328
+
329
+ context "inserting with a field that is not unique" do
330
+
331
+ context "when a unique index exists" do
332
+
333
+ let(:person) do
334
+ Person.new(ssn: "555-55-9999")
335
+ end
336
+
337
+ before do
338
+ Person.create_indexes
339
+ Person.create!(ssn: "555-55-9999")
340
+ end
341
+
342
+ it "raises an error" do
343
+ expect { person.save! }.to raise_error
344
+ end
345
+ end
346
+ end
347
+
348
+ context "with a validation error" do
349
+
350
+ let(:person) do
351
+ Person.new
352
+ end
353
+
354
+ let!(:service) do
355
+ Service.new(person: person, sid: "a")
356
+ end
357
+
358
+ it "raises an error with multiple save attempts" do
359
+ expect { subject.save! }.to raise_error
360
+ expect { subject.save! }.to raise_error
361
+ end
362
+ end
363
+
364
+ context "when a callback returns false" do
365
+
366
+ let(:oscar) do
367
+ Oscar.new
368
+ end
369
+
370
+ it "raises a callback error" do
371
+ expect { oscar.save! }.to raise_error(Mongoid::Errors::Callback)
372
+ end
373
+ end
374
+
375
+ context "when a callback destroys the document" do
376
+
377
+ let(:oscar) do
378
+ Oscar.new(:destroy_after_save => true)
379
+ end
380
+
381
+ before do
382
+ oscar.save!
383
+ end
384
+
385
+ it "flags the document as destroyed" do
386
+ expect(oscar).to be_destroyed
387
+ end
388
+ end
389
+
390
+ context "when a DateTime attribute is updated and persisted" do
391
+
392
+ let(:user) do
393
+ User.create!(last_login: 2.days.ago).tap do |u|
394
+ u.last_login = DateTime.now
395
+ end
396
+ end
397
+
398
+ it "reads for persistance as a UTC Time" do
399
+ expect(user.changes["last_login"].last.class).to eq(Time)
400
+ end
401
+
402
+ it "persists with no exceptions thrown" do
403
+ expect {
404
+ user.save!
405
+ }.not_to raise_error
406
+ end
407
+ end
408
+
409
+ context "when a Date attribute is persisted" do
410
+
411
+ let(:user) do
412
+ User.create!(account_expires: 2.years.from_now).tap do |u|
413
+ u.account_expires = "2/2/2002".to_date
414
+ end
415
+ end
416
+
417
+ it "reads for persistance as a UTC Time" do
418
+ expect(user.changes["account_expires"].last.class).to eq(Time)
419
+ end
420
+
421
+ it "persists with no exceptions thrown" do
422
+ expect {
423
+ user.save!
424
+ }.not_to raise_error
425
+ end
426
+ end
427
+
428
+ context "when the document has associations" do
429
+
430
+ let!(:firefox) do
431
+ Firefox.create(name: "firefox")
432
+ end
433
+
434
+ let!(:writer) do
435
+ HtmlWriter.new(speed: 100)
436
+ end
437
+
438
+ let!(:circle) do
439
+ Circle.new(radius: 50)
440
+ end
441
+
442
+ let!(:square) do
443
+ Square.new(width: 300, height: 150)
444
+ end
445
+
446
+ let(:from_db) do
447
+ Firefox.find(firefox.id)
448
+ end
449
+
450
+ before do
451
+ firefox.writer = writer
452
+ firefox.shapes << [ circle, square ]
453
+ firefox.save!
454
+ end
455
+
456
+ it "properly persists the one-to-one type" do
457
+ expect(from_db).to be_a_kind_of(Firefox)
458
+ end
459
+
460
+ it "properly persists the one-to-one relations" do
461
+ expect(from_db.writer).to eq(writer)
462
+ end
463
+
464
+ it "properly persists the one-to-many type" do
465
+ expect(from_db.shapes.first).to eq(circle)
466
+ end
467
+
468
+ it "properly persists the one-to-many relations" do
469
+ expect(from_db.shapes.last).to eq(square)
470
+ end
471
+
472
+ it "properly sets up the parent relation" do
473
+ expect(from_db.shapes.first).to eq(circle)
474
+ end
475
+
476
+ it "properly sets up the entire hierarchy" do
477
+ expect(from_db.shapes.first.canvas).to eq(firefox)
478
+ end
479
+ end
480
+
481
+ context "when the document is readonly" do
482
+
483
+ let(:person) do
484
+ Person.only(:title).first
485
+ end
486
+
487
+ before do
488
+ Person.create(title: "sir")
489
+ end
490
+
491
+ it "raises an error" do
492
+ expect {
493
+ person.save!
494
+ }.to raise_error(Mongoid::Errors::ReadonlyDocument)
495
+ end
496
+ end
497
+ end
498
+ end