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,166 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Fields::Standard do
4
+
5
+ describe "#lazy?" do
6
+
7
+ let(:field) do
8
+ described_class.new(:test, type: String)
9
+ end
10
+
11
+ it "returns false" do
12
+ field.should_not be_lazy
13
+ end
14
+ end
15
+
16
+ describe "#pre_processed?" do
17
+
18
+ before(:all) do
19
+ class FieldTest
20
+ include Mongoid::Document
21
+ end
22
+ end
23
+
24
+ after(:all) do
25
+ Object.send(:remove_const, :FieldTest)
26
+ end
27
+
28
+ context "when the field has a default" do
29
+
30
+ context "when the default is a proc" do
31
+
32
+ context "when the pre-processed option is true" do
33
+
34
+ let(:field) do
35
+ described_class.new(
36
+ :test,
37
+ default: ->{ "testing" },
38
+ pre_processed: true,
39
+ klass: FieldTest,
40
+ type: String
41
+ )
42
+ end
43
+
44
+ it "returns true" do
45
+ field.should be_pre_processed
46
+ end
47
+ end
48
+
49
+ context "when the pre-processed option is not true" do
50
+
51
+ let(:field) do
52
+ described_class.new(
53
+ :test,
54
+ default: ->{ "testing" },
55
+ klass: FieldTest,
56
+ type: String
57
+ )
58
+ end
59
+
60
+ it "returns false" do
61
+ field.should_not be_pre_processed
62
+ end
63
+ end
64
+ end
65
+
66
+ context "when the default is not a proc" do
67
+
68
+ let(:field) do
69
+ described_class.new(
70
+ :test,
71
+ default: "testing",
72
+ klass: FieldTest,
73
+ type: String
74
+ )
75
+ end
76
+
77
+ it "returns true" do
78
+ field.should be_pre_processed
79
+ end
80
+ end
81
+ end
82
+
83
+ context "when the field has no default" do
84
+
85
+ let(:field) do
86
+ described_class.new(
87
+ :test,
88
+ type: String
89
+ )
90
+ end
91
+
92
+ it "returns false" do
93
+ field.should_not be_pre_processed
94
+ end
95
+ end
96
+ end
97
+
98
+ context "when checking hash values in a custom serializer" do
99
+
100
+ let(:image) do
101
+ Image.new("test")
102
+ end
103
+
104
+ it "does not conflict with the ruby core hash" do
105
+ image.hash_is_hash.should be_true
106
+ end
107
+ end
108
+
109
+ context "when included in a hash" do
110
+
111
+ let(:hash) do
112
+ MyHash.new
113
+ end
114
+
115
+ context "when setting a value" do
116
+
117
+ before do
118
+ hash[:key] = "value"
119
+ end
120
+
121
+ it "allows normal hash access" do
122
+ hash[:key].should eq("value")
123
+ end
124
+ end
125
+
126
+ context "when getting a non existant value" do
127
+
128
+ it "returns nil" do
129
+ hash[:key].should be_nil
130
+ end
131
+ end
132
+ end
133
+
134
+ context "when subclassing a serializable field" do
135
+
136
+ let(:thumbnail) do
137
+ Thumbnail.new("test")
138
+ end
139
+
140
+ it "inherits the parents deserialize method" do
141
+ Thumbnail.demongoize("testy").name.should eq("testy")
142
+ end
143
+
144
+ it "inherits the parents serialize method" do
145
+ thumbnail.mongoize.should eq("test")
146
+ end
147
+
148
+ context "when instantiating the class" do
149
+
150
+ let(:movie) do
151
+ Movie.new(
152
+ poster: Image.new("poster"),
153
+ poster_thumb: Thumbnail.new("thumb")
154
+ )
155
+ end
156
+
157
+ it "deserializes the parent type" do
158
+ movie.poster.name.should eq("poster")
159
+ end
160
+
161
+ it "deserializes the child type" do
162
+ movie.poster_thumb.name.should eq("thumb")
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,1253 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Fields do
4
+
5
+ before(:all) do
6
+ Mongoid.use_activesupport_time_zone = false
7
+ end
8
+
9
+ describe "#\{field}_translations" do
10
+
11
+ let(:product) do
12
+ Product.new
13
+ end
14
+
15
+ context "when the field is localized" do
16
+
17
+ context "when translations exist" do
18
+
19
+ before do
20
+ product.description = "test"
21
+ ::I18n.locale = :de
22
+ product.description = "The best"
23
+ end
24
+
25
+ after do
26
+ ::I18n.locale = :en
27
+ end
28
+
29
+ let(:translations) do
30
+ product.description_translations
31
+ end
32
+
33
+ it "returns all the translations" do
34
+ translations.should eq(
35
+ { "en" => "test", "de" => "The best" }
36
+ )
37
+ end
38
+ end
39
+
40
+ context "when translations do not exist" do
41
+
42
+ context "when no default is provided" do
43
+
44
+ it "returns an empty hash" do
45
+ product.description_translations.should be_empty
46
+ end
47
+ end
48
+
49
+ context "when a default is provided" do
50
+
51
+ it "returns the translations with the default" do
52
+ product.name_translations.should eq(
53
+ { "en" => "no translation" }
54
+ )
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ context "when the field is not localized" do
61
+
62
+ it "does not respond to the method" do
63
+ product.should_not respond_to(:price_translations)
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "#\{field}_translations=" do
69
+
70
+ let(:product) do
71
+ Product.new
72
+ end
73
+
74
+ let(:dictionary) do
75
+ Dictionary.new
76
+ end
77
+
78
+ context "when the field is localized" do
79
+
80
+ context "when the field does not require mongoizations" do
81
+
82
+ let(:translations) do
83
+ { "en" => "test", "de" => "testing" }
84
+ end
85
+
86
+ before do
87
+ product.description_translations = translations
88
+ end
89
+
90
+ it "sets the raw values of the translations" do
91
+ product.description_translations.should eq(translations)
92
+ end
93
+
94
+ context "when saving the new translations" do
95
+
96
+ before do
97
+ product.save
98
+ end
99
+
100
+ it "persists the changes" do
101
+ product.reload.description_translations.should eq(translations)
102
+ end
103
+
104
+ context "when updating the translations" do
105
+
106
+ before do
107
+ product.description_translations = { "en" => "overwritten" }
108
+ product.save
109
+ end
110
+
111
+ it "persists the changes" do
112
+ product.reload.description_translations.should eq(
113
+ { "en" => "overwritten" }
114
+ )
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ context "when the field requires mongoization" do
121
+
122
+ let(:translations) do
123
+ { "en" => 1, "de" => 2 }
124
+ end
125
+
126
+ before do
127
+ dictionary.description_translations = translations
128
+ end
129
+
130
+ it "sets the mongoized values of the translations" do
131
+ dictionary.description_translations.should eq(
132
+ { "en" => "1", "de" => "2" }
133
+ )
134
+ end
135
+
136
+ context "when saving the new translations" do
137
+
138
+ before do
139
+ dictionary.save
140
+ end
141
+
142
+ it "persists the changes" do
143
+ dictionary.reload.description_translations.should eq(
144
+ { "en" => "1", "de" => "2" }
145
+ )
146
+ end
147
+
148
+ context "when updating the translations" do
149
+
150
+ before do
151
+ dictionary.description_translations = { "en" => "overwritten" }
152
+ dictionary.save
153
+ end
154
+
155
+ it "persists the changes" do
156
+ dictionary.reload.description_translations.should eq(
157
+ { "en" => "overwritten" }
158
+ )
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ context "when the field is not localized" do
166
+
167
+ it "does not respond to the method" do
168
+ product.should_not respond_to(:price_translations=)
169
+ end
170
+ end
171
+ end
172
+
173
+ describe "#aliased_fields" do
174
+
175
+ let(:person) do
176
+ Person.new
177
+ end
178
+
179
+ context "when the document is subclassed" do
180
+
181
+ it "does not include the child aliases" do
182
+ person.aliased_fields.keys.should_not include("spec")
183
+ end
184
+ end
185
+ end
186
+
187
+ describe "#attribute_names" do
188
+
189
+ context "when the document is a parent class" do
190
+
191
+ let(:shape) do
192
+ Shape.new
193
+ end
194
+
195
+ it "includes the _id field" do
196
+ shape.attribute_names.should include("_id")
197
+ end
198
+
199
+ it "includes the _type field" do
200
+ shape.attribute_names.should include("_type")
201
+ end
202
+
203
+ it "includes its own fields" do
204
+ shape.attribute_names.should include("x")
205
+ end
206
+
207
+ it "does not return subclass fields" do
208
+ shape.attribute_names.should_not include("radius")
209
+ end
210
+ end
211
+
212
+ context "when the document is a subclass" do
213
+
214
+ let(:circle) do
215
+ Circle.new
216
+ end
217
+
218
+ it "includes the _id field" do
219
+ circle.attribute_names.should include("_id")
220
+ end
221
+
222
+ it "includes the _type field" do
223
+ circle.attribute_names.should include("_type")
224
+ end
225
+
226
+ it "includes the first parent field" do
227
+ circle.attribute_names.should include("x")
228
+ end
229
+
230
+ it "includes the second parent field" do
231
+ circle.attribute_names.should include("y")
232
+ end
233
+
234
+ it "includes the child fields" do
235
+ circle.attribute_names.should include("radius")
236
+ end
237
+ end
238
+ end
239
+
240
+ describe ".attribute_names" do
241
+
242
+ context "when the class is a parent" do
243
+
244
+ it "includes the _id field" do
245
+ Shape.attribute_names.should include("_id")
246
+ end
247
+
248
+ it "includes the _type field" do
249
+ Shape.attribute_names.should include("_type")
250
+ end
251
+
252
+ it "includes its own fields" do
253
+ Shape.attribute_names.should include("x")
254
+ end
255
+
256
+ it "does not return subclass fields" do
257
+ Shape.attribute_names.should_not include("radius")
258
+ end
259
+ end
260
+
261
+ context "when the class is a subclass" do
262
+
263
+ it "includes the _id field" do
264
+ Circle.attribute_names.should include("_id")
265
+ end
266
+
267
+ it "includes the _type field" do
268
+ Circle.attribute_names.should include("_type")
269
+ end
270
+
271
+ it "includes the first parent field" do
272
+ Circle.attribute_names.should include("x")
273
+ end
274
+
275
+ it "includes the second parent field" do
276
+ Circle.attribute_names.should include("y")
277
+ end
278
+
279
+ it "includes the child fields" do
280
+ Circle.attribute_names.should include("radius")
281
+ end
282
+ end
283
+ end
284
+
285
+ describe "#field" do
286
+
287
+ before(:all) do
288
+ Mongoid::Fields.option :custom do |model, field, value|
289
+ end
290
+ end
291
+
292
+ context "when the options are valid" do
293
+
294
+ context "when the options are all standard" do
295
+
296
+ before do
297
+ Band.field :acceptable, type: Boolean
298
+ end
299
+
300
+ after do
301
+ Band.fields.delete("acceptable")
302
+ end
303
+
304
+ it "adds the field to the model" do
305
+ Band.fields["acceptable"].should_not be_nil
306
+ end
307
+ end
308
+
309
+ context "when a custom option is provided" do
310
+
311
+ before do
312
+ Band.field :acceptable, type: Boolean, custom: true
313
+ end
314
+
315
+ it "adds the field to the model" do
316
+ Band.fields["acceptable"].should_not be_nil
317
+ end
318
+ end
319
+ end
320
+
321
+ context "when the options are not valid" do
322
+
323
+ it "raises an error" do
324
+ expect {
325
+ Band.field :unacceptable, bad: true
326
+ }.to raise_error(Mongoid::Errors::InvalidFieldOption)
327
+ end
328
+ end
329
+ end
330
+
331
+ describe "#getter" do
332
+
333
+ context "when the field is binary" do
334
+
335
+ let(:binary) do
336
+ Moped::BSON::Binary.new(:md5, "testing")
337
+ end
338
+
339
+ let(:registry) do
340
+ Registry.new(data: binary)
341
+ end
342
+
343
+ it "returns the binary data intact" do
344
+ registry.data.should eq(binary)
345
+ end
346
+ end
347
+
348
+ context "when a field is localized" do
349
+
350
+ let(:product) do
351
+ Product.new
352
+ end
353
+
354
+ context "when no locale is set" do
355
+
356
+ before do
357
+ product.description = "The best"
358
+ end
359
+
360
+ let(:description) do
361
+ product.description
362
+ end
363
+
364
+ it "returns the default locale value" do
365
+ description.should eq("The best")
366
+ end
367
+ end
368
+
369
+ context "when a single locale is set" do
370
+
371
+ before do
372
+ ::I18n.locale = :de
373
+ product.description = "The best"
374
+ end
375
+
376
+ after do
377
+ ::I18n.locale = :en
378
+ end
379
+
380
+ let(:description) do
381
+ product.description
382
+ end
383
+
384
+ it "returns the set locale value" do
385
+ description.should eq("The best")
386
+ end
387
+ end
388
+
389
+ context "when multiple locales are set" do
390
+
391
+ before do
392
+ product.description = "Cheap drinks"
393
+ ::I18n.locale = :de
394
+ product.description = "Cheaper drinks"
395
+ end
396
+
397
+ after do
398
+ ::I18n.locale = :en
399
+ end
400
+
401
+ let(:description) do
402
+ product.description
403
+ end
404
+
405
+ it "returns the current locale value" do
406
+ description.should eq("Cheaper drinks")
407
+ end
408
+ end
409
+ end
410
+ end
411
+
412
+ describe "#getter_before_type_cast" do
413
+ let(:person) do
414
+ Person.new
415
+ end
416
+
417
+ context "when the attribute has not been assigned" do
418
+
419
+ it "delgates to the getter" do
420
+ person.age_before_type_cast.should eq(person.age)
421
+ end
422
+ end
423
+
424
+ context "when the attribute has been assigned" do
425
+
426
+ it "returns the attribute before type cast" do
427
+ person.age = "old"
428
+ person.age_before_type_cast.should eq("old")
429
+ end
430
+ end
431
+ end
432
+
433
+ describe "#setter=" do
434
+
435
+ let(:product) do
436
+ Product.new
437
+ end
438
+
439
+ context "when the field is binary" do
440
+
441
+ let(:binary) do
442
+ Moped::BSON::Binary.new(:md5, "testing")
443
+ end
444
+
445
+ let(:registry) do
446
+ Registry.new
447
+ end
448
+
449
+ before do
450
+ registry.data = binary
451
+ end
452
+
453
+ it "returns the binary data intact" do
454
+ registry.data.should eq(binary)
455
+ end
456
+ end
457
+
458
+ context "when the field is an array" do
459
+
460
+ before do
461
+ product.stores = [ "kadewe", "karstadt" ]
462
+ product.save
463
+ end
464
+
465
+ context "when setting the value to nil" do
466
+
467
+ before do
468
+ product.stores = nil
469
+ product.save
470
+ end
471
+
472
+ it "allows the set" do
473
+ product.stores.should be_nil
474
+ end
475
+ end
476
+
477
+ context "when setting any of the values to nil" do
478
+
479
+ before do
480
+ product.stores = [ "kadewe", nil ]
481
+ product.save
482
+ end
483
+
484
+ it "allows the set of nil values" do
485
+ product.stores.should eq([ "kadewe", nil ])
486
+ end
487
+
488
+ it "persists the nil values" do
489
+ product.reload.stores.should eq([ "kadewe", nil ])
490
+ end
491
+ end
492
+
493
+ context "when reversing the array values" do
494
+
495
+ before do
496
+ product.stores = [ "karstadt", "kadewe" ]
497
+ product.save
498
+ end
499
+
500
+ it "reverses the values" do
501
+ product.stores.should eq([ "karstadt", "kadewe" ])
502
+ end
503
+
504
+ it "persists the changes" do
505
+ product.reload.stores.should eq([ "karstadt", "kadewe" ])
506
+ end
507
+ end
508
+ end
509
+
510
+ context "when a field is localized" do
511
+
512
+ context "when no locale is set" do
513
+
514
+ before do
515
+ product.description = "Cheap drinks"
516
+ end
517
+
518
+ let(:description) do
519
+ product.attributes["description"]
520
+ end
521
+
522
+ it "sets the value in the default locale" do
523
+ description.should eq({ "en" => "Cheap drinks" })
524
+ end
525
+ end
526
+
527
+ context "when a locale is set" do
528
+
529
+ before do
530
+ ::I18n.locale = :de
531
+ product.description = "Cheaper drinks"
532
+ end
533
+
534
+ after do
535
+ ::I18n.locale = :en
536
+ end
537
+
538
+ let(:description) do
539
+ product.attributes["description"]
540
+ end
541
+
542
+ it "sets the value in the default locale" do
543
+ description.should eq({ "de" => "Cheaper drinks" })
544
+ end
545
+ end
546
+
547
+ context "when having multiple locales" do
548
+
549
+ before do
550
+ product.description = "Cheap drinks"
551
+ ::I18n.locale = :de
552
+ product.description = "Cheaper drinks"
553
+ end
554
+
555
+ after do
556
+ ::I18n.locale = :en
557
+ end
558
+
559
+ let(:description) do
560
+ product.attributes["description"]
561
+ end
562
+
563
+ it "sets the value in both locales" do
564
+ description.should eq(
565
+ { "de" => "Cheaper drinks", "en" => "Cheap drinks" }
566
+ )
567
+ end
568
+ end
569
+ end
570
+ end
571
+
572
+ describe "#defaults" do
573
+
574
+ context "with defaults specified as a non-primitive" do
575
+
576
+ let(:person_one) do
577
+ Person.new
578
+ end
579
+
580
+ let(:person_two) do
581
+ Person.new
582
+ end
583
+
584
+ context "when provided a default array" do
585
+
586
+ before do
587
+ Person.field(:array_testing, type: Array, default: [])
588
+ end
589
+
590
+ after do
591
+ Person.fields.delete("array_testing")
592
+ Person.pre_processed_defaults.delete_one("array_testing")
593
+ end
594
+
595
+ it "returns an equal object of a different instance" do
596
+ person_one.array_testing.object_id.should_not eq(
597
+ person_two.array_testing.object_id
598
+ )
599
+ end
600
+ end
601
+
602
+ context "when provided a default hash" do
603
+
604
+ before do
605
+ Person.field(:hash_testing, type: Hash, default: {})
606
+ end
607
+
608
+ after do
609
+ Person.fields.delete("hash_testing")
610
+ end
611
+
612
+ it "returns an equal object of a different instance" do
613
+ person_one.hash_testing.object_id.should_not eq(
614
+ person_two.hash_testing.object_id
615
+ )
616
+ end
617
+ end
618
+
619
+ context "when provided a default proc" do
620
+
621
+ context "when the proc has no argument" do
622
+
623
+ before do
624
+ Person.field(
625
+ :generated_testing,
626
+ type: Float,
627
+ default: ->{ Time.now.to_f }
628
+ )
629
+ end
630
+
631
+ after do
632
+ Person.fields.delete("generated_testing")
633
+ Person.pre_processed_defaults.delete_one("generated_testing")
634
+ end
635
+
636
+ it "returns an equal object of a different instance" do
637
+ person_one.generated_testing.object_id.should_not eq(
638
+ person_two.generated_testing.object_id
639
+ )
640
+ end
641
+ end
642
+
643
+ context "when the proc has to be evaluated on the document" do
644
+
645
+ before do
646
+ Person.field(
647
+ :rank,
648
+ type: Integer,
649
+ default: ->{ title? ? 1 : 2 }
650
+ )
651
+ end
652
+
653
+ after do
654
+ Person.fields.delete("rank")
655
+ Person.post_processed_defaults.delete_one("rank")
656
+ end
657
+
658
+ it "yields the document to the proc" do
659
+ Person.new.rank.should eq(2)
660
+ end
661
+ end
662
+ end
663
+ end
664
+
665
+ context "on parent classes" do
666
+
667
+ let(:shape) do
668
+ Shape.new
669
+ end
670
+
671
+ it "does not return subclass defaults" do
672
+ shape.pre_processed_defaults.should eq([ "_id", "x", "y", "_type" ])
673
+ end
674
+ end
675
+
676
+ context "on subclasses" do
677
+
678
+ let(:circle) do
679
+ Circle.new
680
+ end
681
+
682
+ it "has the parent and child defaults" do
683
+ circle.pre_processed_defaults.should eq([ "_id", "x", "y", "_type", "radius" ])
684
+ end
685
+ end
686
+ end
687
+
688
+ describe ".field" do
689
+
690
+ it "returns the generated field" do
691
+ Person.field(:testing).should equal Person.fields["testing"]
692
+ end
693
+
694
+ context "when the field name conflicts with mongoid's internals" do
695
+
696
+ context "when the field is named metadata" do
697
+
698
+ it "raises an error" do
699
+ expect {
700
+ Person.field(:metadata)
701
+ }.to raise_error(Mongoid::Errors::InvalidField)
702
+ end
703
+ end
704
+ end
705
+
706
+ context "when the field is a time" do
707
+
708
+ let!(:time) do
709
+ Time.now
710
+ end
711
+
712
+ let!(:person) do
713
+ Person.new(lunch_time: time.utc)
714
+ end
715
+
716
+ context "when reading the field" do
717
+
718
+ before do
719
+ Time.zone = "Berlin"
720
+ end
721
+
722
+ after do
723
+ Time.zone = nil
724
+ end
725
+
726
+ it "performs the necessary time conversions" do
727
+ person.lunch_time.to_s.should eq(time.getlocal.to_s)
728
+ end
729
+ end
730
+ end
731
+
732
+ context "when providing no options" do
733
+
734
+ before do
735
+ Person.field(:testing)
736
+ end
737
+
738
+ let(:person) do
739
+ Person.new(testing: "Test")
740
+ end
741
+
742
+ it "adds a reader for the fields defined" do
743
+ person.testing.should eq("Test")
744
+ end
745
+
746
+ it "adds a writer for the fields defined" do
747
+ (person.testing = "Testy").should eq("Testy")
748
+ end
749
+
750
+ it "adds an existance method" do
751
+ Person.new.testing?.should be_false
752
+ end
753
+
754
+ context "when overwriting an existing field" do
755
+
756
+ before do
757
+ Person.class_eval do
758
+ attr_reader :testing_override_called
759
+ def testing=(value)
760
+ @testing_override_called = true
761
+ super
762
+ end
763
+ end
764
+ person.testing = 'Test'
765
+ end
766
+
767
+ it "properly overwrites the method" do
768
+ person.testing_override_called.should be_true
769
+ end
770
+ end
771
+ end
772
+
773
+ context "when the type is an object" do
774
+
775
+ let(:bob) do
776
+ Person.new(reading: 10.023)
777
+ end
778
+
779
+ it "returns the given value" do
780
+ bob.reading.should eq(10.023)
781
+ end
782
+ end
783
+
784
+ context "when type is a boolean" do
785
+
786
+ let(:person) do
787
+ Person.new(terms: true)
788
+ end
789
+
790
+ it "adds an accessor method with a question mark" do
791
+ person.terms?.should be_true
792
+ end
793
+ end
794
+
795
+ context "when as is specified" do
796
+
797
+ let(:person) do
798
+ Person.new(alias: true)
799
+ end
800
+
801
+ before do
802
+ Person.field :aliased, as: :alias, type: Boolean
803
+ end
804
+
805
+ it "uses the alias to write the attribute" do
806
+ (person.alias = true).should be_true
807
+ end
808
+
809
+ it "uses the alias to read the attribute" do
810
+ person.alias.should be_true
811
+ end
812
+
813
+ it "uses the alias for the query method" do
814
+ person.should be_alias
815
+ end
816
+
817
+ it "uses the name to write the attribute" do
818
+ (person.aliased = true).should be_true
819
+ end
820
+
821
+ it "uses the name to read the attribute" do
822
+ person.aliased.should be_true
823
+ end
824
+
825
+ it "uses the name for the query method" do
826
+ person.should be_aliased
827
+ end
828
+
829
+ it "creates dirty methods for the name" do
830
+ person.should respond_to(:aliased_changed?)
831
+ end
832
+
833
+ it "creates dirty methods for the alias" do
834
+ person.should respond_to(:alias_changed?)
835
+ end
836
+
837
+ context "when changing the name" do
838
+
839
+ before do
840
+ person.aliased = true
841
+ end
842
+
843
+ it "sets name_changed?" do
844
+ person.aliased_changed?.should be_true
845
+ end
846
+
847
+ it "sets alias_changed?" do
848
+ person.alias_changed?.should be_true
849
+ end
850
+ end
851
+
852
+ context "when changing the alias" do
853
+
854
+ before do
855
+ person.alias = true
856
+ end
857
+
858
+ it "sets name_changed?" do
859
+ person.aliased_changed?.should be_true
860
+ end
861
+
862
+ it "sets alias_changed?" do
863
+ person.alias_changed?.should be_true
864
+ end
865
+ end
866
+
867
+ context "when defining a criteria" do
868
+
869
+ let(:criteria) do
870
+ Person.where(alias: "true")
871
+ end
872
+
873
+ it "properly serializes the aliased field" do
874
+ criteria.selector.should eq({ "aliased" => true })
875
+ end
876
+ end
877
+ end
878
+
879
+ context "custom options" do
880
+
881
+ let(:handler) do
882
+ proc {}
883
+ end
884
+
885
+ before do
886
+ Mongoid::Fields.option :option, &handler
887
+ end
888
+
889
+ context "when option is provided" do
890
+
891
+ it "calls the handler with the model" do
892
+ handler.should_receive(:call).with do |model,_,_|
893
+ model.should eql User
894
+ end
895
+
896
+ User.field :custom, option: true
897
+ end
898
+
899
+ it "calls the handler with the field" do
900
+ handler.should_receive(:call).with do |_,field,_|
901
+ field.should eql User.fields["custom"]
902
+ end
903
+
904
+ User.field :custom, option: true
905
+ end
906
+
907
+ it "calls the handler with the option value" do
908
+ handler.should_receive(:call).with do |_,_,value|
909
+ value.should eql true
910
+ end
911
+
912
+ User.field :custom, option: true
913
+ end
914
+ end
915
+
916
+ context "when option is nil" do
917
+
918
+ it "calls the handler" do
919
+ handler.should_receive(:call)
920
+ User.field :custom, option: nil
921
+ end
922
+ end
923
+
924
+ context "when option is not provided" do
925
+
926
+ it "does not call the handler" do
927
+ handler.should_receive(:call).never
928
+
929
+ User.field :custom
930
+ end
931
+ end
932
+ end
933
+ end
934
+
935
+ describe "#fields" do
936
+
937
+ context "on parent classes" do
938
+
939
+ let(:shape) do
940
+ Shape.new
941
+ end
942
+
943
+ it "includes its own fields" do
944
+ shape.fields.keys.should include("x")
945
+ end
946
+
947
+ it "does not return subclass fields" do
948
+ shape.fields.keys.should_not include("radius")
949
+ end
950
+ end
951
+
952
+ context "on subclasses" do
953
+
954
+ let(:circle) do
955
+ Circle.new
956
+ end
957
+
958
+ it "includes the first parent field" do
959
+ circle.fields.keys.should include("x")
960
+ end
961
+
962
+ it "includes the second parent field" do
963
+ circle.fields.keys.should include("y")
964
+ end
965
+
966
+ it "includes the child fields" do
967
+ circle.fields.keys.should include("radius")
968
+ end
969
+ end
970
+ end
971
+
972
+ describe ".replace_field" do
973
+
974
+ let!(:original) do
975
+ Person.field(:id_test, type: Moped::BSON::ObjectId, label: "id")
976
+ end
977
+
978
+ let!(:altered) do
979
+ Person.replace_field("id_test", String)
980
+ end
981
+
982
+ after do
983
+ Person.fields.delete("id_test")
984
+ end
985
+
986
+ let(:new_field) do
987
+ Person.fields["id_test"]
988
+ end
989
+
990
+ it "sets the new type on the field" do
991
+ new_field.type.should eq(String)
992
+ end
993
+
994
+ it "keeps the options from the old field" do
995
+ new_field.options[:label].should eq("id")
996
+ end
997
+ end
998
+
999
+ context "when sending an include of another module at runtime" do
1000
+
1001
+ before do
1002
+ Basic.send(:include, Ownable)
1003
+ end
1004
+
1005
+ context "when the class is a parent" do
1006
+
1007
+ let(:fields) do
1008
+ Basic.fields
1009
+ end
1010
+
1011
+ it "resets the fields" do
1012
+ fields.keys.should include("user_id")
1013
+ end
1014
+ end
1015
+
1016
+ context "when the class is a subclass" do
1017
+
1018
+ let(:fields) do
1019
+ SubBasic.fields
1020
+ end
1021
+
1022
+ it "resets the fields" do
1023
+ fields.keys.should include("user_id")
1024
+ end
1025
+ end
1026
+ end
1027
+
1028
+ context "when a setter accesses a field with a default" do
1029
+
1030
+ let(:person) do
1031
+ Person.new(set_on_map_with_default: "testing")
1032
+ end
1033
+
1034
+ it "sets the default value pre process" do
1035
+ person.map_with_default.should eq({ "key" => "testing" })
1036
+ end
1037
+ end
1038
+
1039
+ context "when dealing with auto protection" do
1040
+
1041
+ context "when auto protect ids and types is true" do
1042
+
1043
+ context "when redefining as accessible" do
1044
+
1045
+ before do
1046
+ Person.attr_accessible :id, :_id, :_type
1047
+ end
1048
+
1049
+ after do
1050
+ Person.attr_protected :id, :_id, :_type
1051
+ end
1052
+
1053
+ let(:bson_id) do
1054
+ Moped::BSON::ObjectId.new
1055
+ end
1056
+
1057
+ it "allows mass assignment of id" do
1058
+ Person.new(_id: bson_id).id.should eq(bson_id)
1059
+ end
1060
+
1061
+ it "allows mass assignment of type" do
1062
+ Person.new(_type: "Something")._type.should eq("Something")
1063
+ end
1064
+ end
1065
+
1066
+ context "when redefining as protected" do
1067
+
1068
+ before do
1069
+ Person.attr_protected :id, :_id, :_type
1070
+ end
1071
+
1072
+ let(:bson_id) do
1073
+ Moped::BSON::ObjectId.new
1074
+ end
1075
+
1076
+ it "protects assignment of id" do
1077
+ Person.new(_id: bson_id).id.should_not eq(bson_id)
1078
+ end
1079
+
1080
+ it "protects assignment of type" do
1081
+ Person.new(_type: "Something")._type.should_not eq("Something")
1082
+ end
1083
+ end
1084
+ end
1085
+
1086
+ context "when auto protecting ids and types is false" do
1087
+
1088
+ before do
1089
+ Mongoid.protect_sensitive_fields = false
1090
+ end
1091
+
1092
+ after do
1093
+ Mongoid.protect_sensitive_fields = true
1094
+ end
1095
+
1096
+ let(:klass) do
1097
+ Class.new do
1098
+ include Mongoid::Document
1099
+ end
1100
+ end
1101
+
1102
+ let(:bson_id) do
1103
+ Moped::BSON::ObjectId.new
1104
+ end
1105
+
1106
+ let(:model) do
1107
+ klass.new(id: bson_id, _type: "Model")
1108
+ end
1109
+
1110
+ it "allows mass assignment of id" do
1111
+ model.id.should eq(bson_id)
1112
+ end
1113
+
1114
+ it "allows mass assignment of type" do
1115
+ model._type.should eq("Model")
1116
+ end
1117
+ end
1118
+ end
1119
+
1120
+ context "when a field is defined as a big decimal" do
1121
+
1122
+ let(:band) do
1123
+ Band.new(name: "Tool")
1124
+ end
1125
+
1126
+ let(:decimal) do
1127
+ BigDecimal.new("1000000.00")
1128
+ end
1129
+
1130
+ context "when setting to a big decimal" do
1131
+
1132
+ before do
1133
+ band.sales = decimal
1134
+ end
1135
+
1136
+ it "properly persists as a string" do
1137
+ band.attributes["sales"].should eq(decimal.to_s)
1138
+ end
1139
+
1140
+ it "returns the proper big decimal" do
1141
+ band.sales.should eq(decimal)
1142
+ end
1143
+ end
1144
+
1145
+ context "when setting to a string" do
1146
+
1147
+ before do
1148
+ band.sales = decimal.to_s
1149
+ end
1150
+
1151
+ it "properly persists as a string" do
1152
+ band.attributes["sales"].should eq(decimal.to_s)
1153
+ end
1154
+
1155
+ it "returns the proper big decimal" do
1156
+ band.sales.should eq(decimal)
1157
+ end
1158
+ end
1159
+
1160
+ context "when setting to an integer" do
1161
+
1162
+ before do
1163
+ band.sales = decimal.to_i
1164
+ end
1165
+
1166
+ it "properly persists as a string" do
1167
+ band.attributes["sales"].should eq("1000000")
1168
+ end
1169
+
1170
+ it "returns the proper big decimal" do
1171
+ band.sales.should eq(decimal)
1172
+ end
1173
+ end
1174
+
1175
+ context "when setting to a float" do
1176
+
1177
+ before do
1178
+ band.sales = decimal.to_f
1179
+ end
1180
+
1181
+ it "properly persists as a string" do
1182
+ band.attributes["sales"].should eq(decimal.to_s)
1183
+ end
1184
+
1185
+ it "returns the proper big decimal" do
1186
+ band.sales.should eq(decimal)
1187
+ end
1188
+ end
1189
+ end
1190
+
1191
+ context "when the field is a hash of arrays" do
1192
+
1193
+ let(:person) do
1194
+ Person.create
1195
+ end
1196
+
1197
+ let(:map) do
1198
+ {
1199
+ "stack1" => [ 1, 2, 3, 4 ],
1200
+ "stack2" => [ 1, 2, 3, 4 ],
1201
+ "stack3" => [ 1, 2, 3, 4 ]
1202
+ }
1203
+ end
1204
+
1205
+ before do
1206
+ person.map = map
1207
+ person.map["stack1"].reverse!
1208
+ person.save
1209
+ end
1210
+
1211
+ it "properly updates the hash" do
1212
+ person.map.should eq(
1213
+ {
1214
+ "stack1" => [ 4, 3, 2, 1 ],
1215
+ "stack2" => [ 1, 2, 3, 4 ],
1216
+ "stack3" => [ 1, 2, 3, 4 ]
1217
+ }
1218
+ )
1219
+ end
1220
+
1221
+ it "persists the changes" do
1222
+ person.reload.map.should eq(
1223
+ {
1224
+ "stack1" => [ 4, 3, 2, 1 ],
1225
+ "stack2" => [ 1, 2, 3, 4 ],
1226
+ "stack3" => [ 1, 2, 3, 4 ]
1227
+ }
1228
+ )
1229
+ end
1230
+ end
1231
+
1232
+ context "when overriding a parent class field" do
1233
+
1234
+ context "when the field has a default value" do
1235
+
1236
+ let!(:canvas) do
1237
+ Canvas.new
1238
+ end
1239
+
1240
+ let!(:test) do
1241
+ Canvas::Test.new
1242
+ end
1243
+
1244
+ it "does not override the parent" do
1245
+ canvas.foo.should eq("original")
1246
+ end
1247
+
1248
+ it "overrides the default" do
1249
+ test.foo.should eq("overridden")
1250
+ end
1251
+ end
1252
+ end
1253
+ end