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,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