mongoid 3.1.4 → 3.1.5

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 (429) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/lib/mongoid/contextual.rb +3 -0
  4. data/lib/mongoid/criteria.rb +10 -2
  5. data/lib/mongoid/document.rb +1 -1
  6. data/lib/mongoid/paranoia.rb +4 -0
  7. data/lib/mongoid/persistence/upsertion.rb +1 -0
  8. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +16 -2
  9. data/lib/mongoid/relations/macros.rb +1 -1
  10. data/lib/mongoid/relations/one.rb +12 -0
  11. data/lib/mongoid/relations/referenced/in.rb +18 -1
  12. data/lib/mongoid/relations/referenced/many_to_many.rb +2 -2
  13. data/lib/mongoid/validations.rb +1 -1
  14. data/lib/mongoid/validations/localizable.rb +1 -1
  15. data/lib/mongoid/validations/presence.rb +1 -1
  16. data/lib/mongoid/validations/uniqueness.rb +1 -1
  17. data/lib/mongoid/version.rb +1 -1
  18. data/lib/support/ruby_version.rb +1 -1
  19. data/spec/app/models/account.rb +32 -0
  20. data/spec/app/models/acolyte.rb +16 -0
  21. data/spec/app/models/actor.rb +19 -0
  22. data/spec/app/models/actor_observer.rb +15 -0
  23. data/spec/app/models/actress.rb +2 -0
  24. data/spec/app/models/address.rb +72 -0
  25. data/spec/app/models/address_component.rb +5 -0
  26. data/spec/app/models/address_number.rb +6 -0
  27. data/spec/app/models/agency.rb +5 -0
  28. data/spec/app/models/agent.rb +12 -0
  29. data/spec/app/models/album.rb +14 -0
  30. data/spec/app/models/alert.rb +5 -0
  31. data/spec/app/models/animal.rb +25 -0
  32. data/spec/app/models/answer.rb +4 -0
  33. data/spec/app/models/appointment.rb +7 -0
  34. data/spec/app/models/article.rb +13 -0
  35. data/spec/app/models/artist.rb +66 -0
  36. data/spec/app/models/artwork.rb +4 -0
  37. data/spec/app/models/augmentation.rb +11 -0
  38. data/spec/app/models/author.rb +6 -0
  39. data/spec/app/models/band.rb +25 -0
  40. data/spec/app/models/bar.rb +9 -0
  41. data/spec/app/models/basic.rb +6 -0
  42. data/spec/app/models/bed.rb +1 -0
  43. data/spec/app/models/big_palette.rb +2 -0
  44. data/spec/app/models/birthday.rb +13 -0
  45. data/spec/app/models/book.rb +12 -0
  46. data/spec/app/models/breed.rb +4 -0
  47. data/spec/app/models/browser.rb +6 -0
  48. data/spec/app/models/building.rb +7 -0
  49. data/spec/app/models/building_address.rb +7 -0
  50. data/spec/app/models/bus.rb +7 -0
  51. data/spec/app/models/business.rb +5 -0
  52. data/spec/app/models/callback_recorder.rb +25 -0
  53. data/spec/app/models/callback_test.rb +9 -0
  54. data/spec/app/models/canvas.rb +25 -0
  55. data/spec/app/models/car.rb +1 -0
  56. data/spec/app/models/cat.rb +8 -0
  57. data/spec/app/models/category.rb +8 -0
  58. data/spec/app/models/child.rb +4 -0
  59. data/spec/app/models/child_doc.rb +22 -0
  60. data/spec/app/models/church.rb +4 -0
  61. data/spec/app/models/circle.rb +3 -0
  62. data/spec/app/models/circuit.rb +4 -0
  63. data/spec/app/models/circus.rb +7 -0
  64. data/spec/app/models/code.rb +5 -0
  65. data/spec/app/models/comment.rb +16 -0
  66. data/spec/app/models/contractor.rb +7 -0
  67. data/spec/app/models/cookie.rb +6 -0
  68. data/spec/app/models/country_code.rb +8 -0
  69. data/spec/app/models/definition.rb +8 -0
  70. data/spec/app/models/description.rb +11 -0
  71. data/spec/app/models/dictionary.rb +10 -0
  72. data/spec/app/models/division.rb +10 -0
  73. data/spec/app/models/doctor.rb +12 -0
  74. data/spec/app/models/dog.rb +7 -0
  75. data/spec/app/models/dokument.rb +5 -0
  76. data/spec/app/models/driver.rb +7 -0
  77. data/spec/app/models/drug.rb +8 -0
  78. data/spec/app/models/email.rb +6 -0
  79. data/spec/app/models/employer.rb +5 -0
  80. data/spec/app/models/entry.rb +6 -0
  81. data/spec/app/models/eraser.rb +1 -0
  82. data/spec/app/models/event.rb +22 -0
  83. data/spec/app/models/exhibition.rb +4 -0
  84. data/spec/app/models/exhibitor.rb +5 -0
  85. data/spec/app/models/eye.rb +9 -0
  86. data/spec/app/models/eye_bowl.rb +9 -0
  87. data/spec/app/models/face.rb +8 -0
  88. data/spec/app/models/favorite.rb +6 -0
  89. data/spec/app/models/filesystem.rb +4 -0
  90. data/spec/app/models/fire_hydrant.rb +6 -0
  91. data/spec/app/models/firefox.rb +4 -0
  92. data/spec/app/models/fish.rb +8 -0
  93. data/spec/app/models/folder.rb +7 -0
  94. data/spec/app/models/folder_item.rb +9 -0
  95. data/spec/app/models/fruits.rb +28 -0
  96. data/spec/app/models/game.rb +21 -0
  97. data/spec/app/models/ghost.rb +7 -0
  98. data/spec/app/models/home.rb +4 -0
  99. data/spec/app/models/house.rb +8 -0
  100. data/spec/app/models/html_writer.rb +3 -0
  101. data/spec/app/models/image.rb +22 -0
  102. data/spec/app/models/implant.rb +16 -0
  103. data/spec/app/models/item.rb +12 -0
  104. data/spec/app/models/jar.rb +7 -0
  105. data/spec/app/models/label.rb +40 -0
  106. data/spec/app/models/language.rb +5 -0
  107. data/spec/app/models/lat_lng.rb +15 -0
  108. data/spec/app/models/league.rb +11 -0
  109. data/spec/app/models/learner.rb +2 -0
  110. data/spec/app/models/line_item.rb +6 -0
  111. data/spec/app/models/location.rb +8 -0
  112. data/spec/app/models/login.rb +8 -0
  113. data/spec/app/models/manufacturer.rb +7 -0
  114. data/spec/app/models/meat.rb +4 -0
  115. data/spec/app/models/membership.rb +4 -0
  116. data/spec/app/models/mixed_drink.rb +4 -0
  117. data/spec/app/models/movie.rb +12 -0
  118. data/spec/app/models/my_hash.rb +2 -0
  119. data/spec/app/models/name.rb +23 -0
  120. data/spec/app/models/node.rb +5 -0
  121. data/spec/app/models/note.rb +12 -0
  122. data/spec/app/models/ordered_post.rb +6 -0
  123. data/spec/app/models/ordered_preference.rb +6 -0
  124. data/spec/app/models/oscar.rb +15 -0
  125. data/spec/app/models/override.rb +16 -0
  126. data/spec/app/models/ownable.rb +6 -0
  127. data/spec/app/models/owner.rb +6 -0
  128. data/spec/app/models/pack.rb +3 -0
  129. data/spec/app/models/page.rb +5 -0
  130. data/spec/app/models/page_question.rb +4 -0
  131. data/spec/app/models/palette.rb +7 -0
  132. data/spec/app/models/paranoid_phone.rb +25 -0
  133. data/spec/app/models/paranoid_post.rb +36 -0
  134. data/spec/app/models/parent.rb +5 -0
  135. data/spec/app/models/parent_doc.rb +6 -0
  136. data/spec/app/models/passport.rb +5 -0
  137. data/spec/app/models/patient.rb +9 -0
  138. data/spec/app/models/pdf_writer.rb +3 -0
  139. data/spec/app/models/pencil.rb +1 -0
  140. data/spec/app/models/person.rb +201 -0
  141. data/spec/app/models/pet.rb +23 -0
  142. data/spec/app/models/pet_owner.rb +6 -0
  143. data/spec/app/models/phone.rb +11 -0
  144. data/spec/app/models/phone_observer.rb +6 -0
  145. data/spec/app/models/pizza.rb +7 -0
  146. data/spec/app/models/player.rb +35 -0
  147. data/spec/app/models/post.rb +43 -0
  148. data/spec/app/models/powerup.rb +11 -0
  149. data/spec/app/models/preference.rb +9 -0
  150. data/spec/app/models/princess.rb +8 -0
  151. data/spec/app/models/product.rb +17 -0
  152. data/spec/app/models/profile.rb +5 -0
  153. data/spec/app/models/pronunciation.rb +5 -0
  154. data/spec/app/models/purchase.rb +4 -0
  155. data/spec/app/models/question.rb +8 -0
  156. data/spec/app/models/quiz.rb +10 -0
  157. data/spec/app/models/rating.rb +8 -0
  158. data/spec/app/models/record.rb +46 -0
  159. data/spec/app/models/registry.rb +4 -0
  160. data/spec/app/models/role.rb +7 -0
  161. data/spec/app/models/root_category.rb +4 -0
  162. data/spec/app/models/sandwich.rb +4 -0
  163. data/spec/app/models/scheduler.rb +7 -0
  164. data/spec/app/models/seo.rb +7 -0
  165. data/spec/app/models/series.rb +4 -0
  166. data/spec/app/models/server.rb +13 -0
  167. data/spec/app/models/service.rb +22 -0
  168. data/spec/app/models/shape.rb +12 -0
  169. data/spec/app/models/shelf.rb +5 -0
  170. data/spec/app/models/shipping_container.rb +5 -0
  171. data/spec/app/models/shipping_pack.rb +3 -0
  172. data/spec/app/models/shop.rb +6 -0
  173. data/spec/app/models/short_agent.rb +4 -0
  174. data/spec/app/models/short_quiz.rb +5 -0
  175. data/spec/app/models/slave.rb +6 -0
  176. data/spec/app/models/song.rb +8 -0
  177. data/spec/app/models/square.rb +4 -0
  178. data/spec/app/models/strategy.rb +3 -0
  179. data/spec/app/models/sub_item.rb +3 -0
  180. data/spec/app/models/subscription.rb +4 -0
  181. data/spec/app/models/survey.rb +5 -0
  182. data/spec/app/models/symptom.rb +6 -0
  183. data/spec/app/models/tag.rb +8 -0
  184. data/spec/app/models/target.rb +5 -0
  185. data/spec/app/models/template.rb +5 -0
  186. data/spec/app/models/thing.rb +9 -0
  187. data/spec/app/models/title.rb +4 -0
  188. data/spec/app/models/tool.rb +8 -0
  189. data/spec/app/models/topping.rb +5 -0
  190. data/spec/app/models/track.rb +38 -0
  191. data/spec/app/models/translation.rb +5 -0
  192. data/spec/app/models/tree.rb +9 -0
  193. data/spec/app/models/truck.rb +3 -0
  194. data/spec/app/models/user.rb +21 -0
  195. data/spec/app/models/user_account.rb +10 -0
  196. data/spec/app/models/validation_callback.rb +10 -0
  197. data/spec/app/models/vehicle.rb +11 -0
  198. data/spec/app/models/version.rb +5 -0
  199. data/spec/app/models/vet_visit.rb +5 -0
  200. data/spec/app/models/video.rb +17 -0
  201. data/spec/app/models/video_game.rb +1 -0
  202. data/spec/app/models/weapon.rb +11 -0
  203. data/spec/app/models/wiki_page.rb +17 -0
  204. data/spec/app/models/word.rb +12 -0
  205. data/spec/app/models/word_origin.rb +11 -0
  206. data/spec/app/models/writer.rb +11 -0
  207. data/spec/config/mongoid.yml +40 -0
  208. data/spec/mongoid/atomic/modifiers_spec.rb +456 -0
  209. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +159 -0
  210. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +152 -0
  211. data/spec/mongoid/atomic/paths/root_spec.rb +106 -0
  212. data/spec/mongoid/atomic/paths_spec.rb +270 -0
  213. data/spec/mongoid/atomic/positionable_spec.rb +227 -0
  214. data/spec/mongoid/atomic_spec.rb +365 -0
  215. data/spec/mongoid/attributes/processing_spec.rb +149 -0
  216. data/spec/mongoid/attributes/readonly_spec.rb +169 -0
  217. data/spec/mongoid/attributes_spec.rb +1705 -0
  218. data/spec/mongoid/callbacks_spec.rb +1564 -0
  219. data/spec/mongoid/components_spec.rb +24 -0
  220. data/spec/mongoid/config/environment_spec.rb +83 -0
  221. data/spec/mongoid/config/options_spec.rb +56 -0
  222. data/spec/mongoid/config_spec.rb +334 -0
  223. data/spec/mongoid/contextual/aggregable/memory_spec.rb +293 -0
  224. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +455 -0
  225. data/spec/mongoid/contextual/atomic_spec.rb +525 -0
  226. data/spec/mongoid/contextual/find_and_modify_spec.rb +220 -0
  227. data/spec/mongoid/contextual/geo_near_spec.rb +405 -0
  228. data/spec/mongoid/contextual/map_reduce_spec.rb +464 -0
  229. data/spec/mongoid/contextual/memory_spec.rb +1236 -0
  230. data/spec/mongoid/contextual/mongo_spec.rb +1757 -0
  231. data/spec/mongoid/copyable_spec.rb +393 -0
  232. data/spec/mongoid/criteria_spec.rb +5140 -0
  233. data/spec/mongoid/criterion/destructive_spec.rb +101 -0
  234. data/spec/mongoid/criterion/inspection_spec.rb +27 -0
  235. data/spec/mongoid/criterion/marshalable_spec.rb +28 -0
  236. data/spec/mongoid/criterion/modifiable_spec.rb +409 -0
  237. data/spec/mongoid/criterion/modification_spec.rb +402 -0
  238. data/spec/mongoid/criterion/scoping_spec.rb +391 -0
  239. data/spec/mongoid/dirty_spec.rb +1508 -0
  240. data/spec/mongoid/document_spec.rb +1146 -0
  241. data/spec/mongoid/equality_spec.rb +241 -0
  242. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +29 -0
  243. data/spec/mongoid/errors/callback_spec.rb +29 -0
  244. data/spec/mongoid/errors/delete_restriction_spec.rb +29 -0
  245. data/spec/mongoid/errors/document_not_found_spec.rb +104 -0
  246. data/spec/mongoid/errors/eager_load_spec.rb +29 -0
  247. data/spec/mongoid/errors/invalid_collection_spec.rb +36 -0
  248. data/spec/mongoid/errors/invalid_config_option_spec.rb +29 -0
  249. data/spec/mongoid/errors/invalid_field_option_spec.rb +29 -0
  250. data/spec/mongoid/errors/invalid_field_spec.rb +37 -0
  251. data/spec/mongoid/errors/invalid_find_spec.rb +29 -0
  252. data/spec/mongoid/errors/invalid_includes_spec.rb +40 -0
  253. data/spec/mongoid/errors/invalid_index_spec.rb +29 -0
  254. data/spec/mongoid/errors/invalid_options_spec.rb +29 -0
  255. data/spec/mongoid/errors/invalid_path_spec.rb +23 -0
  256. data/spec/mongoid/errors/invalid_scope_spec.rb +29 -0
  257. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +17 -0
  258. data/spec/mongoid/errors/invalid_storage_options_spec.rb +29 -0
  259. data/spec/mongoid/errors/invalid_time_spec.rb +29 -0
  260. data/spec/mongoid/errors/inverse_not_found_spec.rb +29 -0
  261. data/spec/mongoid/errors/mixed_relations_spec.rb +29 -0
  262. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +29 -0
  263. data/spec/mongoid/errors/mongoid_error_spec.rb +48 -0
  264. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +29 -0
  265. data/spec/mongoid/errors/no_environment_spec.rb +29 -0
  266. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +29 -0
  267. data/spec/mongoid/errors/no_metadata_spec.rb +23 -0
  268. data/spec/mongoid/errors/no_parent_spec.rb +29 -0
  269. data/spec/mongoid/errors/no_session_config_spec.rb +29 -0
  270. data/spec/mongoid/errors/no_session_database_spec.rb +29 -0
  271. data/spec/mongoid/errors/no_session_hosts_spec.rb +29 -0
  272. data/spec/mongoid/errors/no_sessions_config_spec.rb +29 -0
  273. data/spec/mongoid/errors/readonly_attribute_spec.rb +29 -0
  274. data/spec/mongoid/errors/scope_overwrite_spec.rb +29 -0
  275. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +29 -0
  276. data/spec/mongoid/errors/unknown_attribute_spec.rb +29 -0
  277. data/spec/mongoid/errors/unsaved_document_spec.rb +37 -0
  278. data/spec/mongoid/errors/unsupported_javascript_spec.rb +29 -0
  279. data/spec/mongoid/errors/validations_spec.rb +45 -0
  280. data/spec/mongoid/errors/versioning_not_on_root_spec.rb +29 -0
  281. data/spec/mongoid/extensions/array_spec.rb +638 -0
  282. data/spec/mongoid/extensions/big_decimal_spec.rb +104 -0
  283. data/spec/mongoid/extensions/binary_spec.rb +60 -0
  284. data/spec/mongoid/extensions/boolean_spec.rb +135 -0
  285. data/spec/mongoid/extensions/date_spec.rb +235 -0
  286. data/spec/mongoid/extensions/date_time_spec.rb +155 -0
  287. data/spec/mongoid/extensions/false_class_spec.rb +42 -0
  288. data/spec/mongoid/extensions/float_spec.rb +133 -0
  289. data/spec/mongoid/extensions/hash_spec.rb +333 -0
  290. data/spec/mongoid/extensions/integer_spec.rb +136 -0
  291. data/spec/mongoid/extensions/module_spec.rb +42 -0
  292. data/spec/mongoid/extensions/nil_class_spec.rb +11 -0
  293. data/spec/mongoid/extensions/object_id_spec.rb +946 -0
  294. data/spec/mongoid/extensions/object_spec.rb +292 -0
  295. data/spec/mongoid/extensions/range_spec.rb +105 -0
  296. data/spec/mongoid/extensions/regexp_spec.rb +47 -0
  297. data/spec/mongoid/extensions/set_spec.rb +33 -0
  298. data/spec/mongoid/extensions/string_spec.rb +368 -0
  299. data/spec/mongoid/extensions/symbol_spec.rb +76 -0
  300. data/spec/mongoid/extensions/time_spec.rb +467 -0
  301. data/spec/mongoid/extensions/time_with_zone_spec.rb +405 -0
  302. data/spec/mongoid/extensions/true_class_spec.rb +42 -0
  303. data/spec/mongoid/factory_spec.rb +185 -0
  304. data/spec/mongoid/fields/foreign_key_spec.rb +694 -0
  305. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +184 -0
  306. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +201 -0
  307. data/spec/mongoid/fields/localized_spec.rb +386 -0
  308. data/spec/mongoid/fields/standard_spec.rb +166 -0
  309. data/spec/mongoid/fields_spec.rb +1253 -0
  310. data/spec/mongoid/finders_spec.rb +321 -0
  311. data/spec/mongoid/hierarchy_spec.rb +244 -0
  312. data/spec/mongoid/identity_map_spec.rb +564 -0
  313. data/spec/mongoid/indexes_spec.rb +404 -0
  314. data/spec/mongoid/inspection_spec.rb +57 -0
  315. data/spec/mongoid/json_spec.rb +33 -0
  316. data/spec/mongoid/loggable_spec.rb +21 -0
  317. data/spec/mongoid/matchers/all_spec.rb +31 -0
  318. data/spec/mongoid/matchers/and_spec.rb +162 -0
  319. data/spec/mongoid/matchers/default_spec.rb +130 -0
  320. data/spec/mongoid/matchers/exists_spec.rb +57 -0
  321. data/spec/mongoid/matchers/gt_spec.rb +74 -0
  322. data/spec/mongoid/matchers/gte_spec.rb +74 -0
  323. data/spec/mongoid/matchers/in_spec.rb +25 -0
  324. data/spec/mongoid/matchers/lt_spec.rb +74 -0
  325. data/spec/mongoid/matchers/lte_spec.rb +74 -0
  326. data/spec/mongoid/matchers/ne_spec.rb +25 -0
  327. data/spec/mongoid/matchers/nin_spec.rb +25 -0
  328. data/spec/mongoid/matchers/or_spec.rb +106 -0
  329. data/spec/mongoid/matchers/size_spec.rb +25 -0
  330. data/spec/mongoid/matchers_spec.rb +532 -0
  331. data/spec/mongoid/multi_parameter_attributes_spec.rb +128 -0
  332. data/spec/mongoid/nested_attributes_spec.rb +4945 -0
  333. data/spec/mongoid/observer_spec.rb +290 -0
  334. data/spec/mongoid/paranoia_spec.rb +759 -0
  335. data/spec/mongoid/persistence/atomic/add_to_set_spec.rb +262 -0
  336. data/spec/mongoid/persistence/atomic/bit_spec.rb +88 -0
  337. data/spec/mongoid/persistence/atomic/inc_spec.rb +133 -0
  338. data/spec/mongoid/persistence/atomic/pop_spec.rb +111 -0
  339. data/spec/mongoid/persistence/atomic/pull_all_spec.rb +77 -0
  340. data/spec/mongoid/persistence/atomic/pull_spec.rb +80 -0
  341. data/spec/mongoid/persistence/atomic/push_all_spec.rb +77 -0
  342. data/spec/mongoid/persistence/atomic/push_spec.rb +77 -0
  343. data/spec/mongoid/persistence/atomic/rename_spec.rb +42 -0
  344. data/spec/mongoid/persistence/atomic/sets_spec.rb +154 -0
  345. data/spec/mongoid/persistence/atomic/unset_spec.rb +65 -0
  346. data/spec/mongoid/persistence/atomic_spec.rb +216 -0
  347. data/spec/mongoid/persistence/operations/embedded/insert_spec.rb +191 -0
  348. data/spec/mongoid/persistence/operations/embedded/remove_spec.rb +8 -0
  349. data/spec/mongoid/persistence/operations/insert_spec.rb +149 -0
  350. data/spec/mongoid/persistence/operations/remove_spec.rb +113 -0
  351. data/spec/mongoid/persistence/operations/update_spec.rb +141 -0
  352. data/spec/mongoid/persistence/operations/upsert_spec.rb +59 -0
  353. data/spec/mongoid/persistence/operations_spec.rb +313 -0
  354. data/spec/mongoid/persistence_spec.rb +2279 -0
  355. data/spec/mongoid/railties/document_spec.rb +24 -0
  356. data/spec/mongoid/relations/accessors_spec.rb +844 -0
  357. data/spec/mongoid/relations/auto_save_spec.rb +261 -0
  358. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +171 -0
  359. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +54 -0
  360. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +77 -0
  361. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +241 -0
  362. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +153 -0
  363. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +178 -0
  364. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +131 -0
  365. data/spec/mongoid/relations/builders/embedded/in_spec.rb +34 -0
  366. data/spec/mongoid/relations/builders/embedded/many_spec.rb +132 -0
  367. data/spec/mongoid/relations/builders/embedded/one_spec.rb +99 -0
  368. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +234 -0
  369. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +250 -0
  370. data/spec/mongoid/relations/builders/referenced/in_spec.rb +241 -0
  371. data/spec/mongoid/relations/builders/referenced/many_spec.rb +137 -0
  372. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +178 -0
  373. data/spec/mongoid/relations/builders/referenced/one_spec.rb +124 -0
  374. data/spec/mongoid/relations/builders_spec.rb +226 -0
  375. data/spec/mongoid/relations/cascading/delete_spec.rb +101 -0
  376. data/spec/mongoid/relations/cascading/destroy_spec.rb +47 -0
  377. data/spec/mongoid/relations/cascading/nullify_spec.rb +32 -0
  378. data/spec/mongoid/relations/cascading/restrict_spec.rb +68 -0
  379. data/spec/mongoid/relations/cascading_spec.rb +355 -0
  380. data/spec/mongoid/relations/constraint_spec.rb +74 -0
  381. data/spec/mongoid/relations/conversions_spec.rb +126 -0
  382. data/spec/mongoid/relations/counter_cache_spec.rb +205 -0
  383. data/spec/mongoid/relations/cyclic_spec.rb +156 -0
  384. data/spec/mongoid/relations/embedded/dirty_spec.rb +65 -0
  385. data/spec/mongoid/relations/embedded/in_spec.rb +580 -0
  386. data/spec/mongoid/relations/embedded/many_spec.rb +3841 -0
  387. data/spec/mongoid/relations/embedded/one_spec.rb +1055 -0
  388. data/spec/mongoid/relations/macros_spec.rb +625 -0
  389. data/spec/mongoid/relations/metadata_spec.rb +2030 -0
  390. data/spec/mongoid/relations/options_spec.rb +35 -0
  391. data/spec/mongoid/relations/polymorphic_spec.rb +132 -0
  392. data/spec/mongoid/relations/proxy_spec.rb +48 -0
  393. data/spec/mongoid/relations/referenced/in_spec.rb +1501 -0
  394. data/spec/mongoid/relations/referenced/many_spec.rb +3632 -0
  395. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +3561 -0
  396. data/spec/mongoid/relations/referenced/one_spec.rb +1331 -0
  397. data/spec/mongoid/relations/reflections_spec.rb +101 -0
  398. data/spec/mongoid/relations/synchronization_spec.rb +453 -0
  399. data/spec/mongoid/relations/targets/enumerable_spec.rb +1710 -0
  400. data/spec/mongoid/relations_spec.rb +188 -0
  401. data/spec/mongoid/reloading_spec.rb +305 -0
  402. data/spec/mongoid/scoping_spec.rb +978 -0
  403. data/spec/mongoid/serialization_spec.rb +833 -0
  404. data/spec/mongoid/sessions/factory_spec.rb +312 -0
  405. data/spec/mongoid/sessions/mongo_uri_spec.rb +103 -0
  406. data/spec/mongoid/sessions_spec.rb +1111 -0
  407. data/spec/mongoid/sharding_spec.rb +61 -0
  408. data/spec/mongoid/state_spec.rb +102 -0
  409. data/spec/mongoid/threaded_spec.rb +296 -0
  410. data/spec/mongoid/timestamps/created/short_spec.rb +51 -0
  411. data/spec/mongoid/timestamps/created_spec.rb +44 -0
  412. data/spec/mongoid/timestamps/timeless_spec.rb +130 -0
  413. data/spec/mongoid/timestamps/updated/short_spec.rb +90 -0
  414. data/spec/mongoid/timestamps/updated_spec.rb +86 -0
  415. data/spec/mongoid/timestamps_spec.rb +112 -0
  416. data/spec/mongoid/unit_of_work_spec.rb +196 -0
  417. data/spec/mongoid/validations/associated_spec.rb +183 -0
  418. data/spec/mongoid/validations/format_spec.rb +83 -0
  419. data/spec/mongoid/validations/length_spec.rb +223 -0
  420. data/spec/mongoid/validations/numericality_spec.rb +30 -0
  421. data/spec/mongoid/validations/presence_spec.rb +592 -0
  422. data/spec/mongoid/validations/uniqueness_spec.rb +2399 -0
  423. data/spec/mongoid/validations_spec.rb +309 -0
  424. data/spec/mongoid/versioning_spec.rb +540 -0
  425. data/spec/mongoid_spec.rb +74 -0
  426. data/spec/rack/mongoid/middleware/identity_map_spec.rb +72 -0
  427. data/spec/rails/mongoid_spec.rb +462 -0
  428. data/spec/spec_helper.rb +93 -0
  429. metadata +826 -6
@@ -0,0 +1,1146 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Document do
4
+
5
+ let(:klass) do
6
+ Person
7
+ end
8
+
9
+ let(:person) do
10
+ Person.new
11
+ end
12
+
13
+ it "does not respond to _destroy" do
14
+ person.should_not respond_to(:_destroy)
15
+ end
16
+
17
+ describe ".included" do
18
+
19
+ let(:models) do
20
+ Mongoid.models
21
+ end
22
+
23
+ let(:new_klass_name) do
24
+ 'NewKlassName'
25
+ end
26
+
27
+ let(:new_klass) do
28
+ Class.new do
29
+ class << self; attr_accessor :name; end
30
+ end.tap{|new_klass| new_klass.name = new_klass_name}
31
+ end
32
+
33
+ let(:new_model) do
34
+ new_klass.tap do
35
+ new_klass.send(:include, ::Mongoid::Document)
36
+ end
37
+ end
38
+
39
+ let(:twice_a_new_model) do
40
+ new_klass.tap do
41
+ 2.times{ new_klass.send(:include, ::Mongoid::Document) }
42
+ end
43
+ end
44
+
45
+ context "when Document has been included in a model" do
46
+ it ".models should include that model" do
47
+ models.should include(klass)
48
+ end
49
+ end
50
+
51
+ context "before Document has been included" do
52
+ it ".models should *not* include that model" do
53
+ models.should_not include(new_klass)
54
+ end
55
+ end
56
+
57
+ context "after Document has been included" do
58
+ it ".models should include that model" do
59
+ models.should include(new_model)
60
+ end
61
+ end
62
+
63
+ context "after Document has been included multiple times" do
64
+ it ".models should include that model just once" do
65
+ models.count(twice_a_new_model).should be_eql(1)
66
+ end
67
+ end
68
+ end
69
+
70
+ describe "._types" do
71
+
72
+ context "when the document is subclassed" do
73
+
74
+ let(:types) do
75
+ Person._types
76
+ end
77
+
78
+ it "includes the root" do
79
+ types.should include("Person")
80
+ end
81
+
82
+ it "includes the subclasses" do
83
+ types.should include("Doctor")
84
+ end
85
+ end
86
+
87
+ context "when the document is not subclassed" do
88
+
89
+ let(:types) do
90
+ Address._types
91
+ end
92
+
93
+ it "returns the document" do
94
+ types.should eq([ "Address" ])
95
+ end
96
+ end
97
+
98
+ context "when ._types had been called before class declaration" do
99
+ let(:descendant) do
100
+ Class.new(Person)
101
+ end
102
+
103
+ before do
104
+ Person._types
105
+ descendant
106
+ end
107
+
108
+ it "should clear descendants' cache" do
109
+ Person._types.should include(descendant.to_s)
110
+ end
111
+ end
112
+ end
113
+
114
+ describe "#attributes" do
115
+
116
+ let(:person) do
117
+ Person.new(title: "Sir")
118
+ end
119
+
120
+ it "returns the attributes with indifferent access" do
121
+ person[:title].should eq("Sir")
122
+ end
123
+ end
124
+
125
+ describe "#cache_key" do
126
+
127
+ let(:document) do
128
+ Dokument.new
129
+ end
130
+
131
+ context "when the document is new" do
132
+
133
+ it "has a new key name" do
134
+ document.cache_key.should eq("dokuments/new")
135
+ end
136
+ end
137
+
138
+ context "when persisted" do
139
+
140
+ before do
141
+ document.save
142
+ end
143
+
144
+ context "with updated_at" do
145
+
146
+ let!(:updated_at) do
147
+ document.updated_at.utc.to_s(:number)
148
+ end
149
+
150
+ it "has the id and updated_at key name" do
151
+ document.cache_key.should eq("dokuments/#{document.id}-#{updated_at}")
152
+ end
153
+ end
154
+
155
+ context "without updated_at, with Timestamps" do
156
+
157
+ before do
158
+ document.updated_at = nil
159
+ end
160
+
161
+ it "has the id key name" do
162
+ document.cache_key.should eq("dokuments/#{document.id}")
163
+ end
164
+ end
165
+
166
+ context "without updated_at, without Timestamps" do
167
+ let(:artist) do
168
+ Artist.new
169
+ end
170
+ before do
171
+ artist.save
172
+ end
173
+
174
+ it "should have the id key name" do
175
+ artist.cache_key.should eq("artists/#{artist.id}")
176
+ end
177
+ end
178
+
179
+ end
180
+ end
181
+
182
+ describe "#identity" do
183
+
184
+ let(:person) do
185
+ Person.new
186
+ end
187
+
188
+ it "returns a [doc.class, doc.id] array" do
189
+ person.identity.should eq([person.class, person.id])
190
+ end
191
+ end
192
+
193
+ describe "#hash" do
194
+
195
+ let(:person) do
196
+ Person.new
197
+ end
198
+
199
+ it "returns the identity hash" do
200
+ person.hash.should eq(person.identity.hash)
201
+ end
202
+ end
203
+
204
+ describe "#initialize" do
205
+
206
+ let(:person) do
207
+ Person.new(title: "Sir")
208
+ end
209
+
210
+ it "sets persisted to false" do
211
+ person.should_not be_persisted
212
+ end
213
+
214
+ it "creates an id for the document" do
215
+ person.id.should be_a(Moped::BSON::ObjectId)
216
+ end
217
+
218
+ it "sets the attributes" do
219
+ person.title.should eq("Sir")
220
+ end
221
+
222
+ context "when accessing a relation from an overridden setter" do
223
+
224
+ let(:doctor) do
225
+ Doctor.new(specialty: "surgery")
226
+ end
227
+
228
+ it "allows access to the relation" do
229
+ doctor.users.first.should be_a(User)
230
+ end
231
+
232
+ it "properly allows super calls" do
233
+ doctor.specialty.should eq("surgery")
234
+ end
235
+ end
236
+
237
+ context "when initialize callbacks are defined" do
238
+
239
+ context "when accessing attributes" do
240
+
241
+ before do
242
+ Person.set_callback :initialize, :after do |doc|
243
+ doc.title = "Madam"
244
+ end
245
+ end
246
+
247
+ after do
248
+ Person.reset_callbacks(:initialize)
249
+ end
250
+
251
+ it "runs the callbacks" do
252
+ person.title.should eq("Madam")
253
+ end
254
+ end
255
+
256
+ context "when accessing relations" do
257
+
258
+ let(:person) do
259
+ Person.new(game: Game.new)
260
+ end
261
+
262
+ before do
263
+ Person.after_initialize do
264
+ self.game.name = "Ms. Pacman"
265
+ end
266
+ end
267
+
268
+ after do
269
+ Person.reset_callbacks(:initialize)
270
+ end
271
+
272
+ it "runs the callbacks" do
273
+ person.game.name.should eq("Ms. Pacman")
274
+ end
275
+ end
276
+
277
+ context "when instantiating model" do
278
+
279
+ let(:person) do
280
+ Person.instantiate("_id" => Moped::BSON::ObjectId.new, "title" => "Sir")
281
+ end
282
+
283
+ before do
284
+ Person.set_callback :initialize, :after do |doc|
285
+ doc.title = "Madam"
286
+ end
287
+ end
288
+
289
+ after do
290
+ Person.reset_callbacks(:initialize)
291
+ end
292
+
293
+ it "runs the callbacks" do
294
+ person.title.should eq("Madam")
295
+ end
296
+ end
297
+ end
298
+
299
+ context "when defaults are defined" do
300
+
301
+ it "sets the default values" do
302
+ person.age.should eq(100)
303
+ end
304
+ end
305
+
306
+ context "when a block is provided" do
307
+
308
+ let(:person) do
309
+ Person.new do |doc|
310
+ doc.title = "King"
311
+ end
312
+ end
313
+
314
+ it "yields to the block" do
315
+ person.title.should eq("King")
316
+ end
317
+ end
318
+ end
319
+
320
+ describe ".instantiate" do
321
+
322
+ context "when passing a block" do
323
+
324
+ let(:id) do
325
+ Moped::BSON::ObjectId.new
326
+ end
327
+
328
+ let(:document) do
329
+ Band.instantiate("_id" => id, "name" => "Depeche Mode") do |band|
330
+ band.likes = 1000
331
+ end
332
+ end
333
+
334
+ it "yields to the block" do
335
+ document.likes.should eq(1000)
336
+ end
337
+ end
338
+
339
+ context "when an id exists" do
340
+
341
+ before do
342
+ Mongoid.identity_map_enabled = true
343
+ end
344
+
345
+ after do
346
+ Mongoid.identity_map_enabled = false
347
+ end
348
+
349
+ let(:id) do
350
+ Moped::BSON::ObjectId.new
351
+ end
352
+
353
+ let!(:person) do
354
+ Person.instantiate("_id" => id, "title" => "Sir")
355
+ end
356
+
357
+ it "sets the attributes" do
358
+ person.title.should eq("Sir")
359
+ end
360
+
361
+ it "sets persisted to true" do
362
+ person.should be_persisted
363
+ end
364
+
365
+ it "puts the document in the identity map" do
366
+ Mongoid::IdentityMap.get(Person, id).should eq(person)
367
+ end
368
+ end
369
+
370
+ context "when attributes are nil" do
371
+
372
+ let(:person) do
373
+ Person.instantiate
374
+ end
375
+
376
+ it "creates a new document" do
377
+ person.should be_a(Person)
378
+ end
379
+ end
380
+ end
381
+
382
+ describe "#model_name" do
383
+
384
+ let(:person) do
385
+ Person.new
386
+ end
387
+
388
+ it "returns the class model name" do
389
+ person.model_name.should eq("Person")
390
+ end
391
+ end
392
+
393
+ describe "#raw_attributes" do
394
+
395
+ let(:person) do
396
+ Person.new(title: "Sir")
397
+ end
398
+
399
+ it "returns the internal attributes" do
400
+ person.raw_attributes["title"].should eq("Sir")
401
+ end
402
+ end
403
+
404
+ describe "#to_a" do
405
+
406
+ let(:person) do
407
+ Person.new
408
+ end
409
+
410
+ let(:people) do
411
+ person.to_a
412
+ end
413
+
414
+ it "returns the document in an array" do
415
+ people.should eq([ person ])
416
+ end
417
+ end
418
+
419
+ describe "#as_document" do
420
+
421
+ let!(:person) do
422
+ Person.new(title: "Sir")
423
+ end
424
+
425
+ let!(:address) do
426
+ person.addresses.build(street: "Upper")
427
+ end
428
+
429
+ let!(:name) do
430
+ person.build_name(first_name: "James")
431
+ end
432
+
433
+ let!(:location) do
434
+ address.locations.build(name: "Home")
435
+ end
436
+
437
+ it "includes embeds one attributes" do
438
+ person.as_document.should have_key("name")
439
+ end
440
+
441
+ it "includes embeds many attributes" do
442
+ person.as_document.should have_key("addresses")
443
+ end
444
+
445
+ it "includes second level embeds many attributes" do
446
+ person.as_document["addresses"].first.should have_key("locations")
447
+ end
448
+
449
+ context "with relation define store_as option in embeded_many" do
450
+
451
+ let!(:phone) do
452
+ person.phones.build(number: '+33123456789')
453
+ end
454
+
455
+ it 'includes the store_as key association' do
456
+ person.as_document.should have_key("mobile_phones")
457
+ end
458
+
459
+ it 'should not include the key of association' do
460
+ person.as_document.should_not have_key("phones")
461
+ end
462
+ end
463
+
464
+ context "when removing an embedded document" do
465
+
466
+ before do
467
+ person.save
468
+ person.addresses.delete(address)
469
+ end
470
+
471
+ it "does not include the document in the hash" do
472
+ person.as_document["addresses"].should be_empty
473
+ end
474
+ end
475
+
476
+ context "when an embedded relation has been set to nil" do
477
+
478
+ before do
479
+ # Save the doc, then set an embeds_one relation to nil
480
+ person.save
481
+ person.name = nil
482
+ person.save
483
+ end
484
+
485
+ it "does not include the document in the hash" do
486
+ person.as_document.should_not have_key("name")
487
+ end
488
+ end
489
+ end
490
+
491
+ describe "#to_key" do
492
+
493
+ context "when the document is new" do
494
+
495
+ let(:person) do
496
+ Person.new
497
+ end
498
+
499
+ it "returns nil" do
500
+ person.to_key.should be_nil
501
+ end
502
+ end
503
+
504
+ context "when the document is not new" do
505
+
506
+ let(:person) do
507
+ Person.instantiate("_id" => Moped::BSON::ObjectId.new)
508
+ end
509
+
510
+ it "returns the id in an array" do
511
+ person.to_key.should eq([ person.id ])
512
+ end
513
+ end
514
+
515
+ context "when the document is destroyed" do
516
+
517
+ let(:person) do
518
+ Person.instantiate("_id" => Moped::BSON::ObjectId.new).tap do |peep|
519
+ peep.destroyed = true
520
+ end
521
+ end
522
+
523
+ it "returns the id in an array" do
524
+ person.to_key.should eq([ person.id ])
525
+ end
526
+ end
527
+ end
528
+
529
+ describe "#to_param" do
530
+
531
+ context "when the document is new" do
532
+
533
+ let(:person) do
534
+ Person.new
535
+ end
536
+
537
+ it "returns nil" do
538
+ person.to_param.should be_nil
539
+ end
540
+ end
541
+
542
+ context "when the document is not new" do
543
+
544
+ let(:person) do
545
+ Person.instantiate("_id" => Moped::BSON::ObjectId.new)
546
+ end
547
+
548
+ it "returns the id as a string" do
549
+ person.to_param.should eq(person.id.to_s)
550
+ end
551
+ end
552
+ end
553
+
554
+ describe "#frozen?" do
555
+
556
+ let(:person) do
557
+ Person.new
558
+ end
559
+
560
+ context "when attributes are not frozen" do
561
+
562
+ it "return false" do
563
+ person.should_not be_frozen
564
+ expect {
565
+ person.title = "something"
566
+ }.to_not raise_error
567
+ end
568
+ end
569
+
570
+ context "when attributes are frozen" do
571
+ before do
572
+ person.raw_attributes.freeze
573
+ end
574
+
575
+ it "return true" do
576
+ person.should be_frozen
577
+ end
578
+ end
579
+ end
580
+
581
+ describe "#freeze" do
582
+
583
+ let(:person) do
584
+ Person.new
585
+ end
586
+
587
+ context "when not frozen" do
588
+
589
+ it "freezes attributes" do
590
+ person.freeze.should eq(person)
591
+ expect { person.title = "something" }.to raise_error
592
+ end
593
+ end
594
+
595
+ context "when frozen" do
596
+
597
+ before do
598
+ person.raw_attributes.freeze
599
+ end
600
+
601
+ it "keeps things frozen" do
602
+ person.freeze
603
+ expect {
604
+ person.title = "something"
605
+ }.to raise_error
606
+ end
607
+ end
608
+ end
609
+
610
+ describe ".logger" do
611
+
612
+ it "returns the mongoid logger" do
613
+ Person.logger.should eq(Mongoid.logger)
614
+ end
615
+ end
616
+
617
+ describe "#logger" do
618
+
619
+ let(:person) do
620
+ Person.new
621
+ end
622
+
623
+ it "returns the mongoid logger" do
624
+ person.send(:logger).should eq(Mongoid.logger)
625
+ end
626
+ end
627
+
628
+ context "after including the document module" do
629
+
630
+ let(:movie) do
631
+ Movie.new
632
+ end
633
+
634
+ it "resets to the global scope" do
635
+ movie.global_set.should be_a(::Set)
636
+ end
637
+ end
638
+ context "when a model name conflicts with a mongoid internal" do
639
+
640
+ let(:scheduler) do
641
+ Scheduler.new
642
+ end
643
+
644
+ it "allows the model name" do
645
+ scheduler.strategy.should be_a(Strategy)
646
+ end
647
+ end
648
+
649
+ describe "#initialize" do
650
+
651
+ context "when providing a block" do
652
+
653
+ it "sets the defaults before yielding" do
654
+ Person.new do |person|
655
+ person.age.should eq(100)
656
+ end
657
+ end
658
+ end
659
+ end
660
+
661
+ context "defining a Moped::BSON::ObjectId as a field" do
662
+
663
+ let(:bson_id) do
664
+ Moped::BSON::ObjectId.new
665
+ end
666
+
667
+ let(:person) do
668
+ Person.new(bson_id: bson_id)
669
+ end
670
+
671
+ before do
672
+ person.save
673
+ end
674
+
675
+ it "persists the correct type" do
676
+ person.reload.bson_id.should be_a(Moped::BSON::ObjectId)
677
+ end
678
+
679
+ it "has the correct value" do
680
+ person.bson_id.should eq(bson_id)
681
+ end
682
+ end
683
+
684
+ context "when setting bson id fields to empty strings" do
685
+
686
+ let(:post) do
687
+ Post.new
688
+ end
689
+
690
+ before do
691
+ post.person_id = ""
692
+ end
693
+
694
+ it "converts them to nil" do
695
+ post.person_id.should be_nil
696
+ end
697
+ end
698
+
699
+ context "creating anonymous documents" do
700
+
701
+ context "when defining collection" do
702
+
703
+ let(:model) do
704
+ Class.new do
705
+ include Mongoid::Document
706
+ store_in collection: "anonymous"
707
+ field :gender
708
+ end
709
+ end
710
+
711
+ it "allows the creation" do
712
+ Object.const_set "Anonymous", model
713
+ end
714
+ end
715
+ end
716
+
717
+ describe "#becomes" do
718
+
719
+ before(:all) do
720
+ Person.validates_format_of(:ssn, without: /\$\$\$/)
721
+
722
+ class Manager < Person
723
+ field :level, type: Integer, default: 1
724
+ end
725
+ end
726
+
727
+ after(:all) do
728
+ Person.reset_callbacks(:validate)
729
+ Object.send(:remove_const, :Manager)
730
+ end
731
+
732
+ context "when casting to a superclass" do
733
+
734
+ let(:manager) do
735
+ Manager.new(title: "Sir")
736
+ end
737
+
738
+ context "when no embedded documents are present" do
739
+
740
+ let(:person) do
741
+ manager.becomes(Person)
742
+ end
743
+
744
+ it "copies attributes" do
745
+ person.title.should eq('Sir')
746
+ end
747
+
748
+ it "keeps the same object id" do
749
+ person.id.should eq(manager.id)
750
+ end
751
+
752
+ it "sets the class type" do
753
+ person._type.should eq("Person")
754
+ end
755
+
756
+ it "raises an error when inappropriate class is provided" do
757
+ expect {
758
+ manager.becomes(String)
759
+ }.to raise_error(ArgumentError)
760
+ end
761
+ end
762
+
763
+ context "when the document has embedded documents" do
764
+
765
+ context "when the attribtues are protected" do
766
+
767
+ let!(:appointment) do
768
+ manager.appointments.build
769
+ end
770
+
771
+ let(:person) do
772
+ manager.becomes(Person)
773
+ end
774
+
775
+ it "copies the embedded documents" do
776
+ person.appointments.first.should eq(appointment)
777
+ end
778
+
779
+ it "returns new instances" do
780
+ person.appointments.first.should_not equal(appointment)
781
+ end
782
+ end
783
+
784
+ context "when the attributes are not protected" do
785
+
786
+ context "when embedded doc is not persisted" do
787
+
788
+ let!(:address) do
789
+ manager.addresses.build(street: "hobrecht")
790
+ end
791
+
792
+ let(:person) do
793
+ manager.becomes(Person)
794
+ end
795
+
796
+ it "copies the embedded documents" do
797
+ person.addresses.first.should eq(address)
798
+ end
799
+
800
+ it "returns new instances" do
801
+ person.addresses.first.should_not equal(address)
802
+ end
803
+ end
804
+
805
+ context "when embedded doc is persisted" do
806
+
807
+ let(:manager) do
808
+ Manager.create(title: "Sir")
809
+ end
810
+
811
+ let!(:address) do
812
+ manager.addresses.create(street: "hobrecht")
813
+ end
814
+
815
+ let(:person) do
816
+ manager.becomes(Person)
817
+ end
818
+
819
+ before do
820
+ person.save!
821
+ end
822
+
823
+ it "copies the embedded documents" do
824
+ person.addresses.first.should eq(address)
825
+ end
826
+
827
+ it "copies the embedded documents only once" do
828
+ person.reload.addresses.length.should eq(1)
829
+ end
830
+ end
831
+ end
832
+ end
833
+
834
+ context "when the document has a localize field" do
835
+
836
+ let(:manager) do
837
+ Manager.new(title: "Sir", desc: "description")
838
+ end
839
+
840
+ let(:person) do
841
+ manager.becomes(Person)
842
+ end
843
+
844
+ it "copies the localize attribute" do
845
+ person.desc.should eq("description")
846
+ end
847
+ end
848
+
849
+ context "when the document is new" do
850
+
851
+ let(:person) do
852
+ manager.becomes(Person)
853
+ end
854
+
855
+ it "copies the state" do
856
+ person.should be_a_new_record
857
+ end
858
+ end
859
+
860
+ context "when the document is persisted" do
861
+
862
+ before do
863
+ manager.save
864
+ end
865
+
866
+ let(:person) do
867
+ manager.becomes(Person)
868
+ end
869
+
870
+ it "copies the state" do
871
+ person.should be_persisted
872
+ end
873
+ end
874
+
875
+ context "when the document is destroyed" do
876
+
877
+ before do
878
+ manager.destroy
879
+ end
880
+
881
+ let(:person) do
882
+ manager.becomes(Person)
883
+ end
884
+
885
+ it "copies the state" do
886
+ person.should be_destroyed
887
+ end
888
+ end
889
+
890
+ context "when the document is dirty" do
891
+
892
+ before do
893
+ manager.save
894
+ manager.ssn = "123-22-1234"
895
+ end
896
+
897
+ let(:person) do
898
+ manager.becomes(Person)
899
+ end
900
+
901
+ it "copies over the dirty changes" do
902
+ person.changes["ssn"].should eq([ nil, "123-22-1234" ])
903
+ end
904
+
905
+ it "adds the _type change" do
906
+ person.changes["_type"].should eq([ "Manager", "Person" ])
907
+ end
908
+ end
909
+
910
+ context "when the document is invalid" do
911
+
912
+ before do
913
+ manager.ssn = "$$$"
914
+ manager.valid?
915
+ end
916
+
917
+ let(:person) do
918
+ manager.becomes(Person)
919
+ end
920
+
921
+ it "copies the errors" do
922
+ person.errors.should include(:ssn)
923
+ end
924
+ end
925
+ end
926
+
927
+ context "when casting to a subclass" do
928
+
929
+ let(:person) do
930
+ Person.new(title: "Sir")
931
+ end
932
+
933
+ context "when no embedded documents are present" do
934
+
935
+ let(:manager) do
936
+ person.becomes(Manager)
937
+ end
938
+
939
+ it "copies attributes" do
940
+ manager.title.should eq('Sir')
941
+ end
942
+
943
+ it "keeps the same object id" do
944
+ manager.id.should eq(person.id)
945
+ end
946
+
947
+ it "sets the class type" do
948
+ manager._type.should eq("Manager")
949
+ end
950
+
951
+ it "raises an error when inappropriate class is provided" do
952
+ expect {
953
+ person.becomes(String)
954
+ }.to raise_error(ArgumentError)
955
+ end
956
+ end
957
+
958
+ context "when the document has embedded documents" do
959
+
960
+ let!(:address) do
961
+ person.addresses.build(street: "hobrecht")
962
+ end
963
+
964
+ let(:manager) do
965
+ person.becomes(Manager)
966
+ end
967
+
968
+ it "copies the embedded documents" do
969
+ manager.addresses.first.should eq(address)
970
+ end
971
+
972
+ it "returns new instances" do
973
+ manager.addresses.first.should_not equal(address)
974
+ end
975
+ end
976
+
977
+ context "when the document is new" do
978
+
979
+ let(:manager) do
980
+ person.becomes(Manager)
981
+ end
982
+
983
+ it "copies the state" do
984
+ manager.should be_a_new_record
985
+ end
986
+ end
987
+
988
+ context "when the document is persisted" do
989
+
990
+ before do
991
+ person.save
992
+ end
993
+
994
+ let(:manager) do
995
+ person.becomes(Manager)
996
+ end
997
+
998
+ it "copies the state" do
999
+ manager.should be_persisted
1000
+ end
1001
+
1002
+ context "when downcasted document is saved" do
1003
+
1004
+ before do
1005
+ manager.save
1006
+ end
1007
+
1008
+ it "keeps the type" do
1009
+ manager.should be_an_instance_of(Manager)
1010
+ end
1011
+
1012
+ it "can by queried by the parent class" do
1013
+ Person.find(manager.id).should be_an_instance_of(Manager)
1014
+ end
1015
+
1016
+ it "can by queried by the main class" do
1017
+ Manager.find(manager.id).should be_an_instance_of(Manager)
1018
+ end
1019
+ end
1020
+ end
1021
+
1022
+ context "when the document is destroyed" do
1023
+
1024
+ before do
1025
+ person.destroy
1026
+ end
1027
+
1028
+ let(:manager) do
1029
+ person.becomes(Manager)
1030
+ end
1031
+
1032
+ it "copies the state" do
1033
+ manager.should be_destroyed
1034
+ end
1035
+ end
1036
+
1037
+ context "when the document is dirty" do
1038
+
1039
+ before do
1040
+ person.save
1041
+ person.ssn = "123-22-1234"
1042
+ end
1043
+
1044
+ let(:manager) do
1045
+ person.becomes(Manager)
1046
+ end
1047
+
1048
+ it "copies over the dirty changes" do
1049
+ manager.changes["ssn"].should eq([ nil, "123-22-1234" ])
1050
+ end
1051
+
1052
+ it "adds the _type change" do
1053
+ manager.changes["_type"].should eq([ "Person", "Manager" ])
1054
+ end
1055
+ end
1056
+
1057
+ context "when the document is invalid" do
1058
+
1059
+ before do
1060
+ person.ssn = "$$$"
1061
+ person.valid?
1062
+ end
1063
+
1064
+ let(:manager) do
1065
+ person.becomes(Manager)
1066
+ end
1067
+
1068
+ it "copies the errors" do
1069
+ manager.errors.should include(:ssn)
1070
+ end
1071
+ end
1072
+
1073
+ context "when the subclass has defaults" do
1074
+
1075
+ let(:manager) do
1076
+ Person.new(title: 'Sir').becomes(Manager)
1077
+ end
1078
+
1079
+ it "applies default attributes" do
1080
+ manager.level.should eq(1)
1081
+ end
1082
+ end
1083
+ end
1084
+ end
1085
+
1086
+ context "when marshalling the document" do
1087
+
1088
+ let(:person) do
1089
+ Person.new.tap do |person|
1090
+ person.addresses.extension
1091
+ end
1092
+ end
1093
+
1094
+ let!(:account) do
1095
+ person.create_account(name: "savings")
1096
+ end
1097
+
1098
+ describe Marshal, ".dump" do
1099
+
1100
+ it "successfully dumps the document" do
1101
+ expect {
1102
+ Marshal.dump(person)
1103
+ Marshal.dump(account)
1104
+ }.not_to raise_error
1105
+ end
1106
+ end
1107
+
1108
+ describe Marshal, ".load" do
1109
+
1110
+ it "successfully loads the document" do
1111
+ expect { Marshal.load(Marshal.dump(person)) }.not_to raise_error
1112
+ end
1113
+ end
1114
+ end
1115
+
1116
+ context "when putting a document in the cache" do
1117
+
1118
+ describe ActiveSupport::Cache do
1119
+
1120
+ let(:cache) do
1121
+ ActiveSupport::Cache::MemoryStore.new
1122
+ end
1123
+
1124
+ describe "#fetch" do
1125
+
1126
+ let!(:person) do
1127
+ Person.new
1128
+ end
1129
+
1130
+ let!(:account) do
1131
+ person.create_account(name: "savings")
1132
+ end
1133
+
1134
+ it "stores the parent object" do
1135
+ cache.fetch("key") { person }.should eq(person)
1136
+ cache.fetch("key").should eq(person)
1137
+ end
1138
+
1139
+ it "stores the embedded object" do
1140
+ cache.fetch("key") { account }.should eq(account)
1141
+ cache.fetch("key").should eq(account)
1142
+ end
1143
+ end
1144
+ end
1145
+ end
1146
+ end