mongoid 3.1.4 → 3.1.5

Sign up to get free protection for your applications and to get access to all the features.
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,149 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Attributes::Processing do
4
+
5
+ describe "#process_attributes" do
6
+
7
+ let(:building) do
8
+ Building.new
9
+ end
10
+
11
+ context "when setting embedded documents via the parent" do
12
+
13
+ let(:attributes) do
14
+ {
15
+ building_address: { city: "Berlin" },
16
+ contractors: [{ name: "Joe" }]
17
+ }
18
+ end
19
+
20
+ context "when providing a role" do
21
+
22
+ context "when creating new documents" do
23
+
24
+ before do
25
+ building.process_attributes(attributes, :admin, true)
26
+ end
27
+
28
+ let(:building_address) do
29
+ building.building_address
30
+ end
31
+
32
+ let(:contractor) do
33
+ building.contractors.first
34
+ end
35
+
36
+ context "when the child fields are accessible to the role" do
37
+
38
+ it "sets the fields on the 1-1 child" do
39
+ building_address.city.should eq("Berlin")
40
+ end
41
+
42
+ it "sets the fields on the 1-n child" do
43
+ contractor.name.should eq("Joe")
44
+ end
45
+ end
46
+
47
+ context "when updating the document" do
48
+
49
+ let(:updates) do
50
+ {
51
+ building_address: { city: "Kiew" },
52
+ contractors: [{ name: "Jim" }]
53
+ }
54
+ end
55
+
56
+ before do
57
+ building.process_attributes(updates, :admin, true)
58
+ end
59
+
60
+ it "updates the 1-1 child" do
61
+ building_address.city.should eq("Kiew")
62
+ end
63
+
64
+ it "updates the 1-n child" do
65
+ contractor.name.should eq("Jim")
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ context "when turning off mass assignment" do
72
+
73
+ context "when creating new documents" do
74
+
75
+ before do
76
+ building.process_attributes(attributes, :default, false)
77
+ end
78
+
79
+ let(:building_address) do
80
+ building.building_address
81
+ end
82
+
83
+ let(:contractor) do
84
+ building.contractors.first
85
+ end
86
+
87
+ context "when the child fields are accessible to the role" do
88
+
89
+ it "sets the fields on the 1-1 child" do
90
+ building_address.city.should eq("Berlin")
91
+ end
92
+
93
+ it "sets the fields on the 1-n child" do
94
+ contractor.name.should eq("Joe")
95
+ end
96
+ end
97
+
98
+ context "when updating the document" do
99
+
100
+ let(:updates) do
101
+ {
102
+ building_address: { city: "Kiew" },
103
+ contractors: [{ name: "Jim" }]
104
+ }
105
+ end
106
+
107
+ before do
108
+ building.process_attributes(updates, :default, false)
109
+ end
110
+
111
+ it "updates the 1-1 child" do
112
+ building_address.city.should eq("Kiew")
113
+ end
114
+
115
+ it "updates the 1-n child" do
116
+ contractor.name.should eq("Jim")
117
+ end
118
+
119
+ context "with a key that is not a valid ruby identifier" do
120
+ let(:dynamic_updates) do
121
+ {
122
+ building_address: { :"postal-code" => "V8N 1A1" },
123
+ contractors: [{ :"license number" => "12345" }]
124
+ }
125
+ end
126
+
127
+ before do
128
+ building.process_attributes(dynamic_updates, :default, false)
129
+ end
130
+
131
+ it "updates the 1-1 child" do
132
+ building_address['postal-code'].should eq("V8N 1A1")
133
+ end
134
+
135
+ it "updates the 1-n child" do
136
+ contractor['license number'].should eq("12345")
137
+ end
138
+
139
+ it "correctly handles a second call to #process_attributes" do
140
+ building.process_attributes(dynamic_updates, :default, false)
141
+ end
142
+ end
143
+
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,169 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Attributes::Readonly do
4
+
5
+ describe ".attr_readonly" do
6
+
7
+ after do
8
+ Person.readonly_attributes.clear
9
+ end
10
+
11
+ context "when providing a single field" do
12
+
13
+ before do
14
+ Person.attr_readonly :title
15
+ end
16
+
17
+ it "adds the field to readonly attributes" do
18
+ Person.readonly_attributes.to_a.should eq([ "title" ])
19
+ end
20
+ end
21
+
22
+ context "when providing multiple fields" do
23
+
24
+ before do
25
+ Person.attr_readonly :title, :terms
26
+ end
27
+
28
+ it "adds the fields to readonly attributes" do
29
+ Person.readonly_attributes.to_a.should eq([ "title", "terms" ])
30
+ end
31
+ end
32
+
33
+ context "when creating a new document with a readonly field" do
34
+
35
+ before do
36
+ Person.attr_readonly :title, :terms
37
+ end
38
+
39
+ let(:person) do
40
+ Person.create(title: "sir", terms: true)
41
+ end
42
+
43
+ it "sets the first readonly value" do
44
+ person.title.should eq("sir")
45
+ end
46
+
47
+ it "sets subsequent readonly values" do
48
+ person.terms.should be_true
49
+ end
50
+
51
+ it "persists the first readonly value" do
52
+ person.reload.title.should eq("sir")
53
+ end
54
+
55
+ it "persists subsequent readonly values" do
56
+ person.reload.terms.should be_true
57
+ end
58
+ end
59
+
60
+ context "when updating an existing readonly field" do
61
+
62
+ before do
63
+ Person.attr_readonly :title, :terms
64
+ end
65
+
66
+ let(:person) do
67
+ Person.create(title: "sir", terms: true)
68
+ end
69
+
70
+ context "when updating via the setter" do
71
+
72
+ before do
73
+ person.title = "mr"
74
+ person.save
75
+ end
76
+
77
+ it "does not update the field" do
78
+ person.title.should eq("sir")
79
+ end
80
+
81
+ it "does not persist the changes" do
82
+ person.reload.title.should eq("sir")
83
+ end
84
+ end
85
+
86
+ context "when updating via []=" do
87
+
88
+ before do
89
+ person[:title] = "mr"
90
+ person.save
91
+ end
92
+
93
+ it "does not update the field" do
94
+ person.title.should eq("sir")
95
+ end
96
+
97
+ it "does not persist the changes" do
98
+ person.reload.title.should eq("sir")
99
+ end
100
+ end
101
+
102
+ context "when updating via write_attribute" do
103
+
104
+ before do
105
+ person.write_attribute(:title, "mr")
106
+ person.save
107
+ end
108
+
109
+ it "does not update the field" do
110
+ person.title.should eq("sir")
111
+ end
112
+
113
+ it "does not persist the changes" do
114
+ person.reload.title.should eq("sir")
115
+ end
116
+ end
117
+
118
+ context "when updating via update_attributes" do
119
+
120
+ before do
121
+ person.update_attributes(title: "mr")
122
+ person.save
123
+ end
124
+
125
+ it "does not update the field" do
126
+ person.title.should eq("sir")
127
+ end
128
+
129
+ it "does not persist the changes" do
130
+ person.reload.title.should eq("sir")
131
+ end
132
+ end
133
+
134
+ context "when updating via update_attributes!" do
135
+
136
+ before do
137
+ person.update_attributes!(title: "mr")
138
+ person.save
139
+ end
140
+
141
+ it "does not update the field" do
142
+ person.title.should eq("sir")
143
+ end
144
+
145
+ it "does not persist the changes" do
146
+ person.reload.title.should eq("sir")
147
+ end
148
+ end
149
+
150
+ context "when updating via update_attribute" do
151
+
152
+ it "raises an error" do
153
+ expect {
154
+ person.update_attribute(:title, "mr")
155
+ }.to raise_error(Mongoid::Errors::ReadonlyAttribute)
156
+ end
157
+ end
158
+
159
+ context "when updating via remove_attribute" do
160
+
161
+ it "raises an error" do
162
+ expect {
163
+ person.remove_attribute(:title)
164
+ }.to raise_error(Mongoid::Errors::ReadonlyAttribute)
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,1705 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Attributes do
4
+
5
+ describe "\#{attribute}" do
6
+
7
+ context "when setting the value in the getter" do
8
+
9
+ let(:account) do
10
+ Account.new
11
+ end
12
+
13
+ it "does not cause an infinite loop" do
14
+ account.overridden.should eq("not recommended")
15
+ end
16
+ end
17
+ end
18
+
19
+ describe "#[]" do
20
+
21
+ context "when the document is a new record" do
22
+
23
+ let(:person) do
24
+ Person.new
25
+ end
26
+
27
+ context "when accessing a localized field" do
28
+
29
+ before do
30
+ person.desc = "testing"
31
+ end
32
+
33
+ context "when passing just the name" do
34
+
35
+ it "returns the full value" do
36
+ person[:desc].should eq("en" => "testing")
37
+ end
38
+ end
39
+
40
+ context "when passing the name with locale" do
41
+
42
+ it "returns the value for the locale" do
43
+ person["desc.en"].should eq("testing")
44
+ end
45
+ end
46
+ end
47
+
48
+ context "when attribute does not exist" do
49
+
50
+ it "returns the default value" do
51
+ person[:age].should eq(100)
52
+ end
53
+ end
54
+
55
+ context "when attribute is not accessible" do
56
+
57
+ before do
58
+ person.owner_id = 5
59
+ end
60
+
61
+ it "returns the value" do
62
+ person[:owner_id].should eq(5)
63
+ end
64
+ end
65
+ end
66
+
67
+ context "when the document is an existing record" do
68
+
69
+ let!(:person) do
70
+ Person.create(title: "sir")
71
+ end
72
+
73
+ context "when the attribute does not exist" do
74
+
75
+ before do
76
+ person.collection
77
+ .find({ _id: person.id })
78
+ .update({ "$unset" => { age: 1 }})
79
+ end
80
+
81
+ context "when found" do
82
+
83
+ let(:found) do
84
+ Person.find(person.id)
85
+ end
86
+
87
+ it "returns the default value" do
88
+ found[:age].should eq(100)
89
+ end
90
+ end
91
+
92
+ context "when reloaded" do
93
+
94
+ before do
95
+ Mongoid.raise_not_found_error = false
96
+ person.reload
97
+ Mongoid.raise_not_found_error = true
98
+ end
99
+
100
+ it "returns the default value" do
101
+ person[:age].should eq(100)
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "#[]=" do
109
+
110
+ let(:person) do
111
+ Person.new
112
+ end
113
+
114
+ context "when setting the attribute to nil" do
115
+
116
+ before do
117
+ person[:age] = nil
118
+ end
119
+
120
+ it "does not use the default value" do
121
+ person.age.should be_nil
122
+ end
123
+ end
124
+
125
+ context "when field has a default value" do
126
+
127
+ before do
128
+ person[:terms] = true
129
+ end
130
+
131
+ it "allows overwriting of the default value" do
132
+ person.terms.should be_true
133
+ end
134
+ end
135
+ end
136
+
137
+ describe ".attr_accessible" do
138
+
139
+ context "when the field is not _id" do
140
+
141
+ let(:account) do
142
+ Account.new(number: 999999)
143
+ end
144
+
145
+ it "prevents setting via mass assignment" do
146
+ account.number.should be_nil
147
+ end
148
+ end
149
+
150
+ context "when the field is _id" do
151
+
152
+ let(:account) do
153
+ Account.new(_id: "ABBA")
154
+ end
155
+
156
+ it "prevents setting via mass assignment" do
157
+ account._id.should_not eq("ABBA")
158
+ end
159
+ end
160
+
161
+ context "when using instantiate" do
162
+
163
+ let(:account) do
164
+ Account.instantiate("_id" => "1", "balance" => "ABBA")
165
+ end
166
+
167
+ it "ignores any protected attribute" do
168
+ account.balance.should eq("ABBA")
169
+ end
170
+ end
171
+
172
+ context "when using override" do
173
+
174
+ let(:account) do
175
+ Account.new
176
+ end
177
+
178
+ it "ignores any protected attribute" do
179
+ account.write_attributes({balance: "ABBA"}, false)
180
+ account.balance.should eq("ABBA")
181
+ end
182
+ end
183
+
184
+ context "when mass assignment role is indicated" do
185
+
186
+ context "when attributes assigned from default role" do
187
+
188
+ let(:article) do
189
+ Article.new(
190
+ title: "Some Title",
191
+ is_rss: true,
192
+ user_login: "SomeLogin"
193
+ )
194
+ end
195
+
196
+ it "sets the title field for default role" do
197
+ article.title.should eq("Some Title")
198
+ end
199
+
200
+ it "sets the user login field for the default role" do
201
+ article.user_login.should eq("SomeLogin")
202
+ end
203
+
204
+ it "sets the rss field for the default role" do
205
+ article.is_rss.should be_false
206
+ end
207
+ end
208
+
209
+ context "when attributes assigned from parser role" do
210
+
211
+ let(:article) do
212
+ Article.new({
213
+ title: "Some Title",
214
+ is_rss: true,
215
+ user_login: "SomeLogin"
216
+ }, as: :parser
217
+ )
218
+ end
219
+
220
+ it "sets the title field" do
221
+ article.title.should eq("Some Title")
222
+ end
223
+
224
+ it "sets the rss field" do
225
+ article.is_rss.should be_true
226
+ end
227
+
228
+ it "does not set the user login field" do
229
+ article.user_login.should be_nil
230
+ end
231
+ end
232
+
233
+ context "when attributes assigned without protection" do
234
+
235
+ let(:article) do
236
+ Article.new(
237
+ { title: "Some Title",
238
+ is_rss: true,
239
+ user_login: "SomeLogin"
240
+ }, without_protection: true
241
+ )
242
+ end
243
+
244
+ it "sets the title field" do
245
+ article.title.should eq("Some Title")
246
+ end
247
+
248
+ it "sets the user login field" do
249
+ article.user_login.should eq("SomeLogin")
250
+ end
251
+
252
+ it "sets the rss field" do
253
+ article.is_rss.should be_true
254
+ end
255
+ end
256
+ end
257
+ end
258
+
259
+ describe ".attr_protected" do
260
+
261
+ context "when the field is not _id" do
262
+
263
+ let(:person) do
264
+ Person.new(security_code: "ABBA")
265
+ end
266
+
267
+ it "prevents setting via mass assignment" do
268
+ person.security_code.should be_nil
269
+ end
270
+ end
271
+
272
+ context "when the field is _id" do
273
+
274
+ let(:game) do
275
+ Game.new(_id: "ABBA")
276
+ end
277
+
278
+ it "prevents setting via mass assignment" do
279
+ game._id.should_not eq("ABBA")
280
+ end
281
+ end
282
+
283
+ context "when using instantiate" do
284
+
285
+ let(:person) do
286
+ Person.instantiate("_id" => "1", "security_code" => "ABBA")
287
+ end
288
+
289
+ it "ignores any protected attribute" do
290
+ person.security_code.should eq("ABBA")
291
+ end
292
+ end
293
+
294
+ context "when using override" do
295
+
296
+ let(:person) do
297
+ Person.new
298
+ end
299
+
300
+ it "ignores any protected attribute" do
301
+ person.write_attributes({security_code: "ABBA"}, false)
302
+ person.security_code.should eq("ABBA")
303
+ end
304
+ end
305
+
306
+ context "when mass assignment role is indicated" do
307
+
308
+ let(:item) do
309
+ Item.new
310
+ end
311
+
312
+ context "when attributes assigned from default role" do
313
+
314
+ before do
315
+ item.assign_attributes(
316
+ title: "Some Title",
317
+ is_rss: true,
318
+ user_login: "SomeLogin"
319
+ )
320
+ end
321
+
322
+ it "sets the field for the default role" do
323
+ item.is_rss.should be_true
324
+ end
325
+
326
+ it "does not set the field for non default role title" do
327
+ item.title.should be_nil
328
+ end
329
+
330
+ it "does not set the field for non default role user login" do
331
+ item.user_login.should be_nil
332
+ end
333
+ end
334
+
335
+ context "when attributes assigned from parser role" do
336
+
337
+ before do
338
+ item.assign_attributes(
339
+ { title: "Some Title",
340
+ is_rss: true,
341
+ user_login: "SomeLogin" }, as: :parser
342
+ )
343
+ end
344
+
345
+ it "sets the user login field for parser role" do
346
+ item.user_login.should eq("SomeLogin")
347
+ end
348
+
349
+ it "sets the is rss field for parse role" do
350
+ item.is_rss.should be_false
351
+ end
352
+
353
+ it "does not set the title field" do
354
+ item.title.should be_nil
355
+ end
356
+ end
357
+
358
+ context "when attributes assigned without protection" do
359
+
360
+ before do
361
+ item.assign_attributes(
362
+ { title: "Some Title",
363
+ is_rss: true,
364
+ user_login: "SomeLogin"
365
+ }, without_protection: true
366
+ )
367
+ end
368
+
369
+ it "sets the title attribute" do
370
+ item.title.should eq("Some Title")
371
+ end
372
+
373
+ it "sets the user login attribute" do
374
+ item.user_login.should eq("SomeLogin")
375
+ end
376
+
377
+ it "sets the rss attribute" do
378
+ item.is_rss.should be_true
379
+ end
380
+ end
381
+ end
382
+ end
383
+
384
+ describe "#_id" do
385
+
386
+ let(:person) do
387
+ Person.new
388
+ end
389
+
390
+ it "delegates to #id" do
391
+ person._id.should eq(person.id)
392
+ end
393
+ end
394
+
395
+ describe "#_id=" do
396
+
397
+ after(:all) do
398
+ Person.field(
399
+ :_id,
400
+ type: Moped::BSON::ObjectId,
401
+ pre_processed: true,
402
+ default: ->{ Moped::BSON::ObjectId.new }
403
+ )
404
+ end
405
+
406
+ context "when using object ids" do
407
+
408
+ before(:all) do
409
+ Person.field(
410
+ :_id,
411
+ type: Moped::BSON::ObjectId,
412
+ pre_processed: true,
413
+ default: ->{ Moped::BSON::ObjectId.new }
414
+ )
415
+ end
416
+
417
+ let(:person) do
418
+ Person.new
419
+ end
420
+
421
+ let(:bson_id) do
422
+ Moped::BSON::ObjectId.new
423
+ end
424
+
425
+ context "when providing an object id" do
426
+
427
+ before do
428
+ person._id = bson_id
429
+ end
430
+
431
+ it "sets the id as the object id" do
432
+ person.id.should eq(bson_id)
433
+ end
434
+ end
435
+
436
+ context "when providing a string" do
437
+
438
+ before do
439
+ person._id = bson_id.to_s
440
+ end
441
+
442
+ it "sets the id as the object id" do
443
+ person.id.should eq(bson_id)
444
+ end
445
+ end
446
+
447
+ context "when providing an integer" do
448
+
449
+ before do
450
+ person._id = 2
451
+ end
452
+
453
+ it "sets the id as the supplied value to_s" do
454
+ person.id.should eq(2)
455
+ end
456
+ end
457
+ end
458
+
459
+ context "when using string ids" do
460
+
461
+ before(:all) do
462
+ Person.field(
463
+ :_id,
464
+ type: String,
465
+ pre_processed: true,
466
+ default: ->{ Moped::BSON::ObjectId.new.to_s }
467
+ )
468
+ end
469
+
470
+ let(:person) do
471
+ Person.new
472
+ end
473
+
474
+ let(:bson_id) do
475
+ Moped::BSON::ObjectId.new
476
+ end
477
+
478
+ context "when providing an object id" do
479
+
480
+ before do
481
+ person._id = bson_id
482
+ end
483
+
484
+ it "sets the id as the string of the object id" do
485
+ person.id.should eq(bson_id.to_s)
486
+ end
487
+ end
488
+
489
+ context "when providing a string" do
490
+
491
+ before do
492
+ person._id = bson_id.to_s
493
+ end
494
+
495
+ it "sets the id as the string" do
496
+ person.id.should eq(bson_id.to_s)
497
+ end
498
+ end
499
+
500
+ context "when providing an integer" do
501
+
502
+ before do
503
+ person._id = 2
504
+ end
505
+
506
+ it "sets the id as the supplied value to_s" do
507
+ person.id.should eq("2")
508
+ end
509
+ end
510
+ end
511
+
512
+ context "when using integer ids" do
513
+
514
+ before(:all) do
515
+ Person.field(:_id, type: Integer)
516
+ end
517
+
518
+ let(:person) do
519
+ Person.new
520
+ end
521
+
522
+ context "when providing a string" do
523
+
524
+ before do
525
+ person._id = 1.to_s
526
+ end
527
+
528
+ it "sets the id as the integer" do
529
+ person.id.should eq(1)
530
+ end
531
+ end
532
+
533
+ context "when providing an integer" do
534
+
535
+ before do
536
+ person._id = 2
537
+ end
538
+
539
+ it "sets the id as the supplied value" do
540
+ person.id.should eq(2)
541
+ end
542
+ end
543
+ end
544
+ end
545
+
546
+ describe "#method_missing" do
547
+
548
+ let(:attributes) do
549
+ { testing: "Testing" }
550
+ end
551
+
552
+ let(:person) do
553
+ Person.new(attributes)
554
+ end
555
+
556
+ before do
557
+ Mongoid.configure.allow_dynamic_fields = true
558
+ end
559
+
560
+ context "when an attribute exists" do
561
+
562
+ it "allows the getter" do
563
+ person.testing.should eq("Testing")
564
+ end
565
+
566
+ it "allows the setter" do
567
+ person.testing = "Test"
568
+ person.testing.should eq("Test")
569
+ end
570
+
571
+ it "allows the getter before_type_cast" do
572
+ person.testing_before_type_cast.should eq("Testing")
573
+ end
574
+
575
+ it "returns true for respond_to?" do
576
+ person.respond_to?(:testing).should be_true
577
+ end
578
+ end
579
+
580
+ context "when the provided value needs mongoization" do
581
+
582
+ let(:new_years) do
583
+ DateTime.new(2013, 1, 1, 0, 0, 0)
584
+ end
585
+
586
+ before do
587
+ person[:new_years] = new_years
588
+ end
589
+
590
+ it "mongoizes the dynamic field" do
591
+ person.new_years.should be_a(Time)
592
+ end
593
+
594
+ it "keeps the same value" do
595
+ person.new_years.should eq(new_years)
596
+ end
597
+ end
598
+ end
599
+
600
+ describe "#process" do
601
+
602
+ context "when passing non accessible fields" do
603
+
604
+ let(:person) do
605
+ Person.new(owner_id: 6)
606
+ end
607
+
608
+ it "does not set the value" do
609
+ person.owner_id.should be_nil
610
+ end
611
+ end
612
+
613
+ context "when attributes dont have fields defined" do
614
+
615
+ let(:attributes) do
616
+ {
617
+ nofieldstring: "Testing",
618
+ nofieldint: 5,
619
+ employer: Employer.new
620
+ }
621
+ end
622
+
623
+ context "when allowing dynamic fields" do
624
+
625
+ let!(:person) do
626
+ Person.new(attributes)
627
+ end
628
+
629
+ before do
630
+ Mongoid.configure.allow_dynamic_fields = true
631
+ end
632
+
633
+ context "when attribute is a string" do
634
+
635
+ it "adds the string to the attributes" do
636
+ person.attributes["nofieldstring"].should eq("Testing")
637
+ end
638
+ end
639
+
640
+ context "when attribute is not a string" do
641
+
642
+ it "adds a cast value to the attributes" do
643
+ person.attributes["nofieldint"].should eq(5)
644
+ end
645
+ end
646
+ end
647
+
648
+ context "when not allowing dynamic fields" do
649
+
650
+ let!(:attributes) do
651
+ { nofieldstring: "Testing" }
652
+ end
653
+
654
+ before do
655
+ Mongoid.configure.allow_dynamic_fields = false
656
+ Person.fields.delete(:nofieldstring)
657
+ end
658
+
659
+ after do
660
+ Mongoid.configure.allow_dynamic_fields = true
661
+ end
662
+
663
+ it "raises an unknown attribute error" do
664
+ expect {
665
+ Person.new({ anothernew: "Test" })
666
+ }.to raise_error(Mongoid::Errors::UnknownAttribute)
667
+ end
668
+ end
669
+ end
670
+
671
+ context "when supplied hash has string values" do
672
+
673
+ let(:bson_id) do
674
+ Moped::BSON::ObjectId.new
675
+ end
676
+
677
+ let!(:attributes) do
678
+ {
679
+ title: "value",
680
+ age: "30",
681
+ terms: "true",
682
+ score: "",
683
+ name: {
684
+ _id: "2", first_name: "Test", last_name: "User"
685
+ },
686
+ addresses: [
687
+ { _id: "3", street: "First Street" },
688
+ { _id: "4", street: "Second Street" }
689
+ ]
690
+ }
691
+ end
692
+
693
+ let!(:person) do
694
+ Person.new(attributes)
695
+ end
696
+
697
+ it "casts integers" do
698
+ person[:age].should eq(30)
699
+ end
700
+
701
+ it "casts booleans" do
702
+ person[:terms].should be_true
703
+ end
704
+
705
+ it "sets empty strings to nil" do
706
+ person[:score].should be_nil
707
+ end
708
+ end
709
+
710
+ context "when associations provided in the attributes" do
711
+
712
+ context "when association is a has_one" do
713
+
714
+ let(:name) do
715
+ Name.new(first_name: "Testy")
716
+ end
717
+
718
+ let(:attributes) do
719
+ { name: name }
720
+ end
721
+
722
+ let(:person) do
723
+ Person.new(attributes)
724
+ end
725
+
726
+ it "sets the associations" do
727
+ person.name.should eq(name)
728
+ end
729
+ end
730
+
731
+ context "when association is a references_one" do
732
+
733
+ let(:game) do
734
+ Game.new(score: 100)
735
+ end
736
+
737
+ let(:attributes) do
738
+ { game: game }
739
+ end
740
+
741
+ let!(:person) do
742
+ Person.new(attributes)
743
+ end
744
+
745
+ it "sets the parent association" do
746
+ person.game.should eq(game)
747
+ end
748
+
749
+ it "sets the inverse association" do
750
+ game.person.should eq(person)
751
+ end
752
+ end
753
+
754
+ context "when association is a embedded_in" do
755
+
756
+ let(:person) do
757
+ Person.new
758
+ end
759
+
760
+ let(:name) do
761
+ Name.new(first_name: "Tyler", person: person)
762
+ end
763
+
764
+ it "sets the association" do
765
+ name.person.should eq(person)
766
+ end
767
+ end
768
+ end
769
+
770
+ context "when non-associations provided in the attributes" do
771
+
772
+ let(:employer) do
773
+ Employer.new
774
+ end
775
+
776
+ let(:attributes) do
777
+ { employer_id: employer.id, title: "Sir" }
778
+ end
779
+
780
+ let(:person) do
781
+ Person.new(attributes)
782
+ end
783
+
784
+ it "calls the setter for the association" do
785
+ person.employer_id.should eq("1")
786
+ end
787
+ end
788
+
789
+ context "when an empty array is provided in the attributes" do
790
+
791
+ let(:attributes) do
792
+ { aliases: [] }
793
+ end
794
+
795
+ let(:person) do
796
+ Person.new(attributes)
797
+ end
798
+
799
+ it "sets the empty array" do
800
+ person.aliases.should be_empty
801
+ end
802
+ end
803
+
804
+ context "when an empty hash is provided in the attributes" do
805
+
806
+ let(:attributes) do
807
+ { map: {} }
808
+ end
809
+
810
+ let(:person) do
811
+ Person.new(attributes)
812
+ end
813
+
814
+ it "sets the empty hash" do
815
+ person.map.should eq({})
816
+ end
817
+ end
818
+ end
819
+
820
+ context "updating when attributes already exist" do
821
+
822
+ let(:person) do
823
+ Person.new(title: "Sir")
824
+ end
825
+
826
+ let(:attributes) do
827
+ { dob: "2000-01-01" }
828
+ end
829
+
830
+ before do
831
+ person.process_attributes(attributes)
832
+ end
833
+
834
+ it "only overwrites supplied attributes" do
835
+ person.title.should eq("Sir")
836
+ end
837
+ end
838
+
839
+ describe "#read_attribute" do
840
+
841
+ context "when the document is a new record" do
842
+
843
+ let(:person) do
844
+ Person.new
845
+ end
846
+
847
+ context "when attribute does not exist" do
848
+
849
+ it "returns the default value" do
850
+ person.age.should eq(100)
851
+ person.pets.should be_false
852
+ end
853
+
854
+ end
855
+
856
+ context "when attribute is not accessible" do
857
+
858
+ before do
859
+ person.owner_id = 5
860
+ end
861
+
862
+ it "returns the value" do
863
+ person.read_attribute(:owner_id).should eq(5)
864
+ end
865
+ end
866
+ end
867
+
868
+ context "when the document is an existing record" do
869
+
870
+ let(:person) do
871
+ Person.create
872
+ end
873
+
874
+ context "when the attribute does not exist" do
875
+
876
+ before do
877
+ person.collection
878
+ .find({ _id: person.id })
879
+ .update({ "$unset" => { age: 1 }})
880
+ Mongoid.raise_not_found_error = false
881
+ person.reload
882
+ Mongoid.raise_not_found_error = true
883
+ end
884
+
885
+ it "returns the default value" do
886
+ person.age.should eq(100)
887
+ end
888
+ end
889
+ end
890
+ end
891
+
892
+ describe "#read_attribute_before_type_cast" do
893
+ let(:person) do
894
+ Person.create
895
+ end
896
+
897
+ context "when the attribute has not yet been assigned" do
898
+
899
+ it "returns the default value" do
900
+ person.age_before_type_cast.should eq(100)
901
+ end
902
+ end
903
+
904
+ context "after the attribute has been assigned" do
905
+
906
+ it "returns the default value" do
907
+ person.age = "old"
908
+ person.age_before_type_cast.should eq("old")
909
+ end
910
+ end
911
+ end
912
+
913
+
914
+ describe "#attribute_present?" do
915
+
916
+ context "when document is a new record" do
917
+
918
+ let(:person) do
919
+ Person.new
920
+ end
921
+
922
+ context "when attribute does not exist" do
923
+
924
+ it "returns false" do
925
+ person.attribute_present?(:owner_id).should be_false
926
+ end
927
+ end
928
+
929
+ context "when attribute does exist" do
930
+ before do
931
+ person.owner_id = 5
932
+ end
933
+
934
+ it "returns true" do
935
+ person.attribute_present?(:owner_id).should be_true
936
+ end
937
+ end
938
+ end
939
+
940
+ context "when the document is an existing record" do
941
+
942
+ let(:person) do
943
+ Person.create
944
+ end
945
+
946
+ context "when the attribute does not exist" do
947
+
948
+ before do
949
+ person.collection
950
+ .find({ _id: person.id })
951
+ .update({ "$unset" => { age: 1 }})
952
+ Mongoid.raise_not_found_error = false
953
+ person.reload
954
+ Mongoid.raise_not_found_error = true
955
+ end
956
+
957
+ it "returns true" do
958
+ person.attribute_present?(:age).should be_true
959
+ end
960
+ end
961
+ end
962
+
963
+ context "when the value is boolean" do
964
+
965
+ let(:person) do
966
+ Person.new
967
+ end
968
+
969
+ context "when attribute does not exist" do
970
+
971
+ context "when the value is true" do
972
+
973
+ it "return true" do
974
+ person.terms = false
975
+ person.attribute_present?(:terms).should be_true
976
+ end
977
+ end
978
+
979
+ context "when the value is false" do
980
+
981
+ it "return true" do
982
+ person.terms = false
983
+ person.attribute_present?(:terms).should be_true
984
+ end
985
+ end
986
+ end
987
+ end
988
+
989
+ context "when the value is blank string" do
990
+
991
+ let(:person) do
992
+ Person.new(title: '')
993
+ end
994
+
995
+ it "return false" do
996
+ person.attribute_present?(:title).should be_false
997
+ end
998
+ end
999
+ end
1000
+
1001
+ describe "#has_attribute?" do
1002
+
1003
+ let(:person) do
1004
+ Person.new(title: "sir")
1005
+ end
1006
+
1007
+ context "when the key is in the attributes" do
1008
+
1009
+ context "when provided a symbol" do
1010
+
1011
+ it "returns true" do
1012
+ person.has_attribute?(:title).should be_true
1013
+ end
1014
+ end
1015
+
1016
+ context "when provided a string" do
1017
+
1018
+ it "returns true" do
1019
+ person.has_attribute?("title").should be_true
1020
+ end
1021
+ end
1022
+ end
1023
+
1024
+ context "when the key is not in the attributes" do
1025
+
1026
+ it "returns false" do
1027
+ person.has_attribute?(:employer_id).should be_false
1028
+ end
1029
+ end
1030
+ end
1031
+
1032
+ describe '#has_attribute_before_type_cast?' do
1033
+
1034
+ let(:person) do
1035
+ Person.new
1036
+ end
1037
+
1038
+ context "before the attribute has been assigned" do
1039
+
1040
+ it "returns false" do
1041
+ person.has_attribute_before_type_cast?(:age).should be_false
1042
+ end
1043
+ end
1044
+
1045
+ context "after the attribute has been assigned" do
1046
+
1047
+ it "returns true" do
1048
+ person.age = 'old'
1049
+ person.has_attribute_before_type_cast?(:age).should be_true
1050
+ end
1051
+ end
1052
+ end
1053
+
1054
+ describe "#remove_attribute" do
1055
+
1056
+ context "when the attribute exists" do
1057
+
1058
+ let(:person) do
1059
+ Person.create(title: "Sir")
1060
+ end
1061
+
1062
+ before do
1063
+ person.remove_attribute(:title)
1064
+ end
1065
+
1066
+ it "removes the attribute" do
1067
+ person.title.should be_nil
1068
+ end
1069
+
1070
+ it "removes the key from the attributes hash" do
1071
+ person.has_attribute?(:title).should be_false
1072
+ end
1073
+
1074
+ context "when saving after the removal" do
1075
+
1076
+ before do
1077
+ person.save
1078
+ end
1079
+
1080
+ it "persists the removal" do
1081
+ person.reload.has_attribute?(:title).should be_false
1082
+ end
1083
+ end
1084
+ end
1085
+
1086
+ context "when the attribute exists in embedded document" do
1087
+
1088
+ let(:pet) do
1089
+ Animal.new(name: "Cat")
1090
+ end
1091
+
1092
+ let(:person) do
1093
+ Person.new(pet: pet)
1094
+ end
1095
+
1096
+ before do
1097
+ person.save
1098
+ person.pet.remove_attribute(:name)
1099
+ end
1100
+
1101
+ it "removes the attribute" do
1102
+ person.pet.name.should be_nil
1103
+ end
1104
+
1105
+ it "removes the key from the attributes hash" do
1106
+ person.pet.has_attribute?(:name).should be_false
1107
+ end
1108
+
1109
+ context "when saving after the removal" do
1110
+
1111
+ before do
1112
+ person.save
1113
+ end
1114
+
1115
+ it "persists the removal" do
1116
+ person.reload.pet.has_attribute?(:name).should be_false
1117
+ end
1118
+ end
1119
+
1120
+ end
1121
+
1122
+ context "when the attribute does not exist" do
1123
+
1124
+ let(:person) do
1125
+ Person.new
1126
+ end
1127
+
1128
+ before do
1129
+ person.remove_attribute(:title)
1130
+ end
1131
+
1132
+ it "does not fail" do
1133
+ person.title.should be_nil
1134
+ end
1135
+ end
1136
+
1137
+ context "when the document is new" do
1138
+
1139
+ let(:person) do
1140
+ Person.new(title: "sir")
1141
+ end
1142
+
1143
+ before do
1144
+ person.remove_attribute(:title)
1145
+ end
1146
+
1147
+ it "does not add a delayed unset operation" do
1148
+ person.delayed_atomic_unsets.should be_empty
1149
+ end
1150
+ end
1151
+ end
1152
+
1153
+ describe "#respond_to?" do
1154
+
1155
+ context "when allowing dynamic fields" do
1156
+
1157
+ let(:person) do
1158
+ Person.new
1159
+ end
1160
+
1161
+ before(:all) do
1162
+ Mongoid.allow_dynamic_fields = true
1163
+ end
1164
+
1165
+ context "when asking for the getter" do
1166
+
1167
+ context "when the attribute exists" do
1168
+
1169
+ before do
1170
+ person[:attr] = "test"
1171
+ end
1172
+
1173
+ it "returns true" do
1174
+ person.should respond_to(:attr)
1175
+ end
1176
+ end
1177
+
1178
+ context "when the attribute does not exist" do
1179
+
1180
+ it "returns false" do
1181
+ person.should_not respond_to(:attr)
1182
+ end
1183
+ end
1184
+ end
1185
+
1186
+ context "when asking for the setter" do
1187
+
1188
+ context "when the attribute exists" do
1189
+
1190
+ before do
1191
+ person[:attr] = "test"
1192
+ end
1193
+
1194
+ it "returns true" do
1195
+ person.should respond_to(:attr=)
1196
+ end
1197
+ end
1198
+
1199
+ context "when the attribute does not exist" do
1200
+
1201
+ it "returns false" do
1202
+ person.should_not respond_to(:attr=)
1203
+ end
1204
+ end
1205
+ end
1206
+ end
1207
+
1208
+ context "when not allowing dynamic fields" do
1209
+
1210
+ let(:person) do
1211
+ Person.new
1212
+ end
1213
+
1214
+ before(:all) do
1215
+ Mongoid.allow_dynamic_fields = false
1216
+ end
1217
+
1218
+ after(:all) do
1219
+ Mongoid.allow_dynamic_fields = true
1220
+ end
1221
+
1222
+ context "when asking for the getter" do
1223
+
1224
+ it "returns false" do
1225
+ person.should_not respond_to(:attr)
1226
+ end
1227
+ end
1228
+
1229
+ context "when asking for the setter" do
1230
+
1231
+ it "returns false" do
1232
+ person.should_not respond_to(:attr=)
1233
+ end
1234
+ end
1235
+ end
1236
+ end
1237
+
1238
+ describe "#write_attribute" do
1239
+
1240
+ context "when attribute does not exist" do
1241
+
1242
+ let(:person) do
1243
+ Person.new
1244
+ end
1245
+
1246
+ it "returns the default value" do
1247
+ person.age.should eq(100)
1248
+ end
1249
+ end
1250
+
1251
+ context "when setting an attribute that needs type casting" do
1252
+ let(:person) do
1253
+ Person.new(age: "old")
1254
+ end
1255
+
1256
+ it "should store the attribute before type cast" do
1257
+ person.age_before_type_cast.should eq("old")
1258
+ end
1259
+ end
1260
+
1261
+ context "when setting the attribute to nil" do
1262
+
1263
+ let(:person) do
1264
+ Person.new(age: nil)
1265
+ end
1266
+
1267
+ it "does not use the default value" do
1268
+ person.age.should be_nil
1269
+ end
1270
+ end
1271
+
1272
+ context "when field has a default value" do
1273
+
1274
+ let(:person) do
1275
+ Person.new
1276
+ end
1277
+
1278
+ before do
1279
+ person.terms = true
1280
+ end
1281
+
1282
+ it "allows overwriting of the default value" do
1283
+ person.terms.should be_true
1284
+ end
1285
+ end
1286
+
1287
+ context "when attribute has an aliased name" do
1288
+
1289
+ let(:person) do
1290
+ Person.new
1291
+ end
1292
+
1293
+ before(:each) do
1294
+ person.write_attribute(:test, "aliased field to test")
1295
+ end
1296
+
1297
+ it "allows the field name to be udpated" do
1298
+ person.t.should eq("aliased field to test")
1299
+ end
1300
+ end
1301
+ end
1302
+
1303
+ describe "#typed_value_for" do
1304
+
1305
+ let(:person) do
1306
+ Person.new
1307
+ end
1308
+
1309
+ context "when the key has been specified as a field" do
1310
+
1311
+ it "retuns the typed value" do
1312
+ person.send(:typed_value_for, "age", "51")
1313
+ end
1314
+ end
1315
+
1316
+ context "when the key has not been specified as a field" do
1317
+
1318
+ before do
1319
+ person.stub(:fields).and_return({})
1320
+ end
1321
+
1322
+ it "returns the value" do
1323
+ person.send(:typed_value_for, "age", "51").should eq("51")
1324
+ end
1325
+ end
1326
+ end
1327
+
1328
+ describe "#apply_default_attributes" do
1329
+
1330
+ let(:person) do
1331
+ Person.new
1332
+ end
1333
+
1334
+ it "typecasts proc values" do
1335
+ person.age.should eq(100)
1336
+ end
1337
+ end
1338
+
1339
+ [:attributes=, :write_attributes].each do |method|
1340
+
1341
+ describe "##{method}" do
1342
+
1343
+ context "when nested" do
1344
+
1345
+ let(:person) do
1346
+ Person.new
1347
+ end
1348
+
1349
+ before do
1350
+ person.send(method, { videos: [{title: "Fight Club"}] })
1351
+ end
1352
+
1353
+ it "sets nested documents" do
1354
+ person.videos.first.title.should eq("Fight Club")
1355
+ end
1356
+ end
1357
+
1358
+ context "typecasting" do
1359
+
1360
+ let(:person) do
1361
+ Person.new
1362
+ end
1363
+
1364
+ let(:attributes) do
1365
+ { age: "50" }
1366
+ end
1367
+
1368
+ context "when passing a hash" do
1369
+
1370
+ before do
1371
+ person.send(method, attributes)
1372
+ end
1373
+
1374
+ it "properly casts values" do
1375
+ person.age.should eq(50)
1376
+ end
1377
+ end
1378
+
1379
+ context "when passing nil" do
1380
+
1381
+ before do
1382
+ person.send(method, nil)
1383
+ end
1384
+
1385
+ it "does not set anything" do
1386
+ person.age.should eq(100)
1387
+ end
1388
+ end
1389
+ end
1390
+
1391
+ context "on a parent document" do
1392
+
1393
+ context "when the parent has a has many through a has one" do
1394
+
1395
+ let(:owner) do
1396
+ PetOwner.new(title: "Mr")
1397
+ end
1398
+
1399
+ let(:pet) do
1400
+ Pet.new(name: "Fido")
1401
+ end
1402
+
1403
+ let(:vet_visit) do
1404
+ VetVisit.new(date: Date.today)
1405
+ end
1406
+
1407
+ before do
1408
+ owner.pet = pet
1409
+ pet.vet_visits = [ vet_visit ]
1410
+ owner.send(method, { pet: { name: "Bingo" } })
1411
+ end
1412
+
1413
+ it "does not overwrite child attributes if not in the hash" do
1414
+ owner.pet.name.should eq("Bingo")
1415
+ owner.pet.vet_visits.size.should eq(1)
1416
+ end
1417
+ end
1418
+
1419
+ context "when parent destroy all child on setter" do
1420
+
1421
+ let(:owner) do
1422
+ PetOwner.create!(title: "Mr")
1423
+ end
1424
+
1425
+ let(:pet) do
1426
+ Pet.create!(name: "Kika", pet_owner: owner)
1427
+ end
1428
+
1429
+ let!(:vet_visit) do
1430
+ pet.vet_visits.create!(date: Date.today)
1431
+ end
1432
+
1433
+ before do
1434
+ pet.send(method, { visits_count: 3 })
1435
+ pet.save!
1436
+ end
1437
+
1438
+ it "has 3 new entries" do
1439
+ pet.vet_visits.count.should eq(3)
1440
+ end
1441
+
1442
+ it "persists the changes" do
1443
+ pet.reload.vet_visits.count.should eq(3)
1444
+ end
1445
+ end
1446
+
1447
+ context "when the parent has an empty embeds_many" do
1448
+
1449
+ let(:person) do
1450
+ Person.new
1451
+ end
1452
+
1453
+ let(:attributes) do
1454
+ { services: [] }
1455
+ end
1456
+
1457
+ it "does not raise an error" do
1458
+ person.send(method, attributes)
1459
+ end
1460
+ end
1461
+ end
1462
+
1463
+ context "on a child document" do
1464
+
1465
+ context "when child is part of a has one" do
1466
+
1467
+ let(:person) do
1468
+ Person.new(title: "Sir", age: 30)
1469
+ end
1470
+
1471
+ let(:name) do
1472
+ Name.new(first_name: "Test", last_name: "User")
1473
+ end
1474
+
1475
+ before do
1476
+ person.name = name
1477
+ name.send(method, first_name: "Test2", last_name: "User2")
1478
+ end
1479
+
1480
+ it "sets the child attributes on the parent" do
1481
+ name.attributes.should eq(
1482
+ { "_id" => "Test-User", "first_name" => "Test2", "last_name" => "User2" }
1483
+ )
1484
+ end
1485
+ end
1486
+
1487
+ context "when child is part of a has many" do
1488
+
1489
+ let(:person) do
1490
+ Person.new(title: "Sir")
1491
+ end
1492
+
1493
+ let(:address) do
1494
+ Address.new(street: "Test")
1495
+ end
1496
+
1497
+ before do
1498
+ person.addresses << address
1499
+ address.send(method, "street" => "Test2")
1500
+ end
1501
+
1502
+ it "updates the child attributes on the parent" do
1503
+ address.attributes.should eq(
1504
+ { "_id" => "test", "street" => "Test2" }
1505
+ )
1506
+ end
1507
+ end
1508
+ end
1509
+ end
1510
+ end
1511
+
1512
+ describe "#alias_attribute" do
1513
+
1514
+ let(:product) do
1515
+ Product.new
1516
+ end
1517
+
1518
+ context "when checking against the alias" do
1519
+
1520
+ before do
1521
+ product.cost = 500
1522
+ end
1523
+
1524
+ it "aliases the getter" do
1525
+ product.cost.should eq(500)
1526
+ end
1527
+
1528
+ it "aliases the existance check" do
1529
+ product.cost?.should be_true
1530
+ end
1531
+
1532
+ it "aliases *_changed?" do
1533
+ product.cost_changed?.should be_true
1534
+ end
1535
+
1536
+ it "aliases *_change" do
1537
+ product.cost_change.should eq([ nil, 500 ])
1538
+ end
1539
+
1540
+ it "aliases *_will_change!" do
1541
+ product.should respond_to(:cost_will_change!)
1542
+ end
1543
+
1544
+ it "aliases *_was" do
1545
+ product.cost_was.should be_nil
1546
+ end
1547
+
1548
+ it "aliases reset_*!" do
1549
+ product.reset_cost!
1550
+ product.cost.should be_nil
1551
+ end
1552
+
1553
+ it "aliases *_before_type_cast" do
1554
+ product.cost = "expensive"
1555
+ product.cost_before_type_cast.should eq("expensive")
1556
+ end
1557
+ end
1558
+
1559
+ context "when checking against the original" do
1560
+
1561
+ before do
1562
+ product.price = 500
1563
+ end
1564
+
1565
+ it "aliases the getter" do
1566
+ product.price.should eq(500)
1567
+ end
1568
+
1569
+ it "aliases the existance check" do
1570
+ product.price?.should be_true
1571
+ end
1572
+
1573
+ it "aliases *_changed?" do
1574
+ product.price_changed?.should be_true
1575
+ end
1576
+
1577
+ it "aliases *_change" do
1578
+ product.price_change.should eq([ nil, 500 ])
1579
+ end
1580
+
1581
+ it "aliases *_will_change!" do
1582
+ product.should respond_to(:price_will_change!)
1583
+ end
1584
+
1585
+ it "aliases *_was" do
1586
+ product.price_was.should be_nil
1587
+ end
1588
+
1589
+ it "aliases reset_*!" do
1590
+ product.reset_price!
1591
+ product.price.should be_nil
1592
+ end
1593
+ end
1594
+ end
1595
+
1596
+ context "when persisting nil attributes" do
1597
+
1598
+ let!(:person) do
1599
+ Person.create(score: nil)
1600
+ end
1601
+
1602
+ it "has an entry in the attributes" do
1603
+ person.reload.attributes.should have_key("score")
1604
+ end
1605
+ end
1606
+
1607
+ context "with a default last_drink_taken_at" do
1608
+
1609
+ let(:person) do
1610
+ Person.new
1611
+ end
1612
+
1613
+ it "saves the default" do
1614
+ expect { person.save }.to_not raise_error
1615
+ person.last_drink_taken_at.should eq(1.day.ago.in_time_zone("Alaska").to_date)
1616
+ end
1617
+ end
1618
+
1619
+ context "when default values are defined" do
1620
+
1621
+ context "when no value exists in the database" do
1622
+
1623
+ let(:person) do
1624
+ Person.create
1625
+ end
1626
+
1627
+ it "applies the default value" do
1628
+ person.last_drink_taken_at.should eq(1.day.ago.in_time_zone("Alaska").to_date)
1629
+ end
1630
+ end
1631
+
1632
+ context "when a value exists in the database" do
1633
+
1634
+ context "when the value is not nil" do
1635
+
1636
+ let!(:person) do
1637
+ Person.create(age: 50)
1638
+ end
1639
+
1640
+ let(:from_db) do
1641
+ Person.find(person.id)
1642
+ end
1643
+
1644
+ it "does not set the default" do
1645
+ from_db.age.should eq(50)
1646
+ end
1647
+ end
1648
+
1649
+ context "when the value is explicitly nil" do
1650
+
1651
+ let!(:person) do
1652
+ Person.create(age: nil)
1653
+ end
1654
+
1655
+ let(:from_db) do
1656
+ Person.find(person.id)
1657
+ end
1658
+
1659
+ it "does not set the default" do
1660
+ from_db.age.should be_nil
1661
+ end
1662
+ end
1663
+
1664
+ context "when the default is a proc" do
1665
+
1666
+ let!(:account) do
1667
+ Account.create(name: "savings", balance: "100")
1668
+ end
1669
+
1670
+ let(:from_db) do
1671
+ Account.find(account.id)
1672
+ end
1673
+
1674
+ it "applies the defaults after all attributes are set" do
1675
+ from_db.should be_balanced
1676
+ end
1677
+ end
1678
+ end
1679
+ end
1680
+
1681
+ context "when dynamic fields are not allowed" do
1682
+
1683
+ before do
1684
+ Mongoid.configure.allow_dynamic_fields = false
1685
+ end
1686
+
1687
+ after do
1688
+ Mongoid.configure.allow_dynamic_fields = true
1689
+ end
1690
+
1691
+ context "when an embedded document has been persisted" do
1692
+
1693
+ context "when the field is no longer recognized" do
1694
+
1695
+ before do
1696
+ Person.collection.insert 'pet' => { 'unrecognized_field' => true }
1697
+ end
1698
+
1699
+ it "allows access to the legacy data" do
1700
+ Person.first.pet.read_attribute(:unrecognized_field).should be_true
1701
+ end
1702
+ end
1703
+ end
1704
+ end
1705
+ end