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,312 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Sessions::Factory do
4
+
5
+ describe ".create" do
6
+
7
+ context "when provided a name" do
8
+
9
+ context "when the configuration exists" do
10
+
11
+ context "when the configuration is standard" do
12
+
13
+ let(:config) do
14
+ {
15
+ default: { hosts: [ "localhost:27017" ], database: database_id },
16
+ secondary: { hosts: [ "localhost:27017" ], database: database_id }
17
+ }
18
+ end
19
+
20
+ before do
21
+ Mongoid::Config.sessions = config
22
+ end
23
+
24
+ let(:session) do
25
+ described_class.create(:secondary)
26
+ end
27
+
28
+ let(:cluster) do
29
+ session.cluster
30
+ end
31
+
32
+ it "returns a session" do
33
+ session.should be_a(Moped::Session)
34
+ end
35
+
36
+ it "sets the cluster's seeds" do
37
+ cluster.seeds.should eq([ "localhost:27017" ])
38
+ end
39
+ end
40
+
41
+ context "when the configuration has no ports" do
42
+
43
+ let(:config) do
44
+ {
45
+ default: { hosts: [ "127.0.0.1" ], database: database_id },
46
+ secondary: { hosts: [ "localhost" ], database: database_id }
47
+ }
48
+ end
49
+
50
+ before do
51
+ Mongoid::Config.sessions = config
52
+ end
53
+
54
+ let(:session) do
55
+ described_class.create(:secondary)
56
+ end
57
+
58
+ let(:default) do
59
+ described_class.create(:default)
60
+ end
61
+
62
+ let(:cluster) do
63
+ session.cluster
64
+ end
65
+
66
+ it "returns a session" do
67
+ session.should be_a(Moped::Session)
68
+ end
69
+
70
+ it "sets the cluster's seed ports to 27017" do
71
+ cluster.seeds.should eq([ "localhost:27017" ])
72
+ end
73
+
74
+ it "sets ips with no ports to 27017" do
75
+ default.cluster.seeds.should eq([ "127.0.0.1:27017" ])
76
+ end
77
+ end
78
+
79
+ context "when configured via a uri" do
80
+
81
+ context "when the uri has a single host:port" do
82
+
83
+ let(:config) do
84
+ {
85
+ default: { hosts: [ "localhost:27017" ], database: database_id },
86
+ secondary: { uri: "mongodb://localhost:27017/mongoid_test" }
87
+ }
88
+ end
89
+
90
+ before do
91
+ Mongoid::Config.sessions = config
92
+ end
93
+
94
+ let(:session) do
95
+ described_class.create(:secondary)
96
+ end
97
+
98
+ let(:cluster) do
99
+ session.cluster
100
+ end
101
+
102
+ it "returns a session" do
103
+ session.should be_a(Moped::Session)
104
+ end
105
+
106
+ it "sets the cluster's seeds" do
107
+ cluster.seeds.should eq([ "localhost:27017" ])
108
+ end
109
+
110
+ it "sets the database" do
111
+ session.options[:database].should eq("mongoid_test")
112
+ end
113
+
114
+ it "sets the database in the configuration" do
115
+ session
116
+ Mongoid.sessions[:secondary].should include(:database)
117
+ end
118
+
119
+ it "sets the hosts in the configuration" do
120
+ session
121
+ Mongoid.sessions[:secondary].should include(:hosts)
122
+ end
123
+
124
+ it "removes the uri from the configuration" do
125
+ session
126
+ Mongoid.sessions[:secondary].should_not include(:uri)
127
+ end
128
+ end
129
+
130
+ context "when the uri has multiple host:port pairs" do
131
+
132
+ let(:config) do
133
+ {
134
+ default: { hosts: [ "localhost:27017" ], database: database_id },
135
+ secondary: { uri: "mongodb://localhost:27017,localhost:27017/mongoid_test" }
136
+ }
137
+ end
138
+
139
+ before do
140
+ Mongoid::Config.sessions = config
141
+ end
142
+
143
+ let(:session) do
144
+ described_class.create(:secondary)
145
+ end
146
+
147
+ let(:cluster) do
148
+ session.cluster
149
+ end
150
+
151
+ it "returns a session" do
152
+ session.should be_a(Moped::Session)
153
+ end
154
+
155
+ it "sets the cluster's seeds" do
156
+ cluster.seeds.should eq([ "localhost:27017", "localhost:27017" ])
157
+ end
158
+
159
+ it "sets the database" do
160
+ session.options[:database].should eq("mongoid_test")
161
+ end
162
+
163
+ it "sets the database in the configuration" do
164
+ session
165
+ Mongoid.sessions[:secondary].should include(:database)
166
+ end
167
+
168
+ it "sets the hosts in the configuration" do
169
+ session
170
+ Mongoid.sessions[:secondary].should include(:hosts)
171
+ end
172
+
173
+ it "removes the uri from the configuration" do
174
+ session
175
+ Mongoid.sessions[:secondary].should_not include(:uri)
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ context "when the configuration does not exist" do
182
+
183
+ it "raises an error" do
184
+ expect {
185
+ described_class.create(:unknown)
186
+ }.to raise_error(Mongoid::Errors::NoSessionConfig)
187
+ end
188
+ end
189
+ end
190
+
191
+ context "when no name is provided" do
192
+
193
+ let(:config) do
194
+ { default: { hosts: ["localhost:27017"], database: database_id }}
195
+ end
196
+
197
+ before do
198
+ Mongoid::Config.sessions = config
199
+ end
200
+
201
+ let(:session) do
202
+ described_class.create
203
+ end
204
+
205
+ let(:cluster) do
206
+ session.cluster
207
+ end
208
+
209
+ it "returns the default session" do
210
+ session.should be_a(Moped::Session)
211
+ end
212
+
213
+ it "sets the cluster's seeds" do
214
+ cluster.seeds.should eq([ "localhost:27017" ])
215
+ end
216
+ end
217
+
218
+ context "when nil is provided and no default config" do
219
+
220
+ let(:config) { nil }
221
+
222
+ before do
223
+ Mongoid.sessions[:default] = nil
224
+ end
225
+
226
+ it "raises NoSessionsConfig error" do
227
+ expect{ Mongoid::Sessions::Factory.create(config) }.to raise_error(Mongoid::Errors::NoSessionsConfig)
228
+ end
229
+ end
230
+ end
231
+
232
+ describe ".default" do
233
+
234
+ let(:config) do
235
+ { default: { hosts: ["localhost:27017"], database: database_id }}
236
+ end
237
+
238
+ before do
239
+ Mongoid::Config.sessions = config
240
+ end
241
+
242
+ let(:session) do
243
+ described_class.default
244
+ end
245
+
246
+ let(:cluster) do
247
+ session.cluster
248
+ end
249
+
250
+ it "returns the default session" do
251
+ session.should be_a(Moped::Session)
252
+ end
253
+
254
+ it "sets the cluster's seeds" do
255
+ cluster.seeds.should eq([ "localhost:27017" ])
256
+ end
257
+ end
258
+
259
+ context "when options are provided with string keys" do
260
+
261
+ let(:config) do
262
+ {
263
+ default: {
264
+ hosts: [ "localhost:27017" ],
265
+ database: database_id,
266
+ options: {
267
+ "down_interval" => 10,
268
+ "max_retries" => 5,
269
+ "refresh_interval" => 30,
270
+ "retry_interval" => 0.1
271
+ }
272
+ }
273
+ }
274
+ end
275
+
276
+ before do
277
+ Mongoid::Config.sessions = config
278
+ end
279
+
280
+ let(:session) do
281
+ described_class.default
282
+ end
283
+
284
+ let(:cluster) do
285
+ session.cluster
286
+ end
287
+
288
+ it "returns the default session" do
289
+ session.should be_a(Moped::Session)
290
+ end
291
+
292
+ it "sets the cluster's seeds" do
293
+ cluster.seeds.should eq([ "localhost:27017" ])
294
+ end
295
+
296
+ it "sets the cluster down interval" do
297
+ cluster.down_interval.should eq(10)
298
+ end
299
+
300
+ it "sets the cluster max retries" do
301
+ cluster.max_retries.should eq(5)
302
+ end
303
+
304
+ it "sets the cluster refresh interval" do
305
+ cluster.refresh_interval.should eq(30)
306
+ end
307
+
308
+ it "sets the cluster retry interval" do
309
+ cluster.retry_interval.should eq(0.1)
310
+ end
311
+ end
312
+ end
@@ -0,0 +1,103 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Sessions::MongoUri do
4
+
5
+ let(:single) do
6
+ "mongodb://user:pass@localhost:27017/mongoid_test"
7
+ end
8
+
9
+ let(:multiple) do
10
+ "mongodb://localhost:27017,localhost:27017/mongoid_test"
11
+ end
12
+
13
+ describe "#database" do
14
+
15
+ let(:uri) do
16
+ described_class.new(single)
17
+ end
18
+
19
+ it "returns the database name" do
20
+ uri.database.should eq("mongoid_test")
21
+ end
22
+ end
23
+
24
+ describe "#hosts" do
25
+
26
+ context "when a single node is provided" do
27
+
28
+ let(:uri) do
29
+ described_class.new(single)
30
+ end
31
+
32
+ it "returns an array with 1 node" do
33
+ uri.hosts.should eq([ "localhost:27017" ])
34
+ end
35
+ end
36
+
37
+ context "when multiple nodes are provided" do
38
+
39
+ let(:uri) do
40
+ described_class.new(multiple)
41
+ end
42
+
43
+ it "returns an array with 2 nodes" do
44
+ uri.hosts.should eq([ "localhost:27017", "localhost:27017" ])
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "#password" do
50
+
51
+ let(:uri) do
52
+ described_class.new(single)
53
+ end
54
+
55
+ it "returns the password" do
56
+ uri.password.should eq("pass")
57
+ end
58
+ end
59
+
60
+ describe "#to_hash" do
61
+
62
+ context "when a user and password are not provided" do
63
+
64
+ let(:uri) do
65
+ described_class.new(multiple)
66
+ end
67
+
68
+ it "does not include the username and password" do
69
+ uri.to_hash.should eq({
70
+ hosts: [ "localhost:27017", "localhost:27017" ],
71
+ database: "mongoid_test"
72
+ })
73
+ end
74
+ end
75
+
76
+ context "when a user and password are provided" do
77
+
78
+ let(:uri) do
79
+ described_class.new(single)
80
+ end
81
+
82
+ it "includes the username and password" do
83
+ uri.to_hash.should eq({
84
+ hosts: [ "localhost:27017" ],
85
+ database: "mongoid_test",
86
+ username: "user",
87
+ password: "pass"
88
+ })
89
+ end
90
+ end
91
+ end
92
+
93
+ describe "#username" do
94
+
95
+ let(:uri) do
96
+ described_class.new(single)
97
+ end
98
+
99
+ it "returns the userame" do
100
+ uri.username.should eq("user")
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,1111 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Sessions do
4
+
5
+ describe ".clear_persistence_options" do
6
+
7
+ context "when options exist on the current thread" do
8
+
9
+ before do
10
+ Band.with(safe: true)
11
+ end
12
+
13
+ let!(:cleared) do
14
+ Band.clear_persistence_options
15
+ end
16
+
17
+ it "remove the options from the current thread" do
18
+ Band.persistence_options.should be_nil
19
+ end
20
+
21
+ it "returns true" do
22
+ cleared.should be_true
23
+ end
24
+ end
25
+
26
+ context "when options do not exist on the current thread" do
27
+
28
+ it "returns true" do
29
+ Band.clear_persistence_options.should be_true
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "#collection" do
35
+
36
+ context "when overriding the default with store_in" do
37
+
38
+ shared_examples_for "an overridden collection at the class level" do
39
+
40
+ let(:band) do
41
+ Band.new
42
+ end
43
+
44
+ it "returns the collection for the model" do
45
+ band.collection.should be_a(Moped::Collection)
46
+ end
47
+
48
+ it "sets the correct collection name" do
49
+ band.collection.name.to_s.should eq("artists")
50
+ end
51
+
52
+ context "when accessing from the class level" do
53
+
54
+ it "returns the collection for the model" do
55
+ Band.collection.should be_a(Moped::Collection)
56
+ end
57
+
58
+ it "sets the correct collection name" do
59
+ Band.collection.name.to_s.should eq("artists")
60
+ end
61
+ end
62
+
63
+ context "when safety options exist" do
64
+
65
+ context "when the options are from the current thread" do
66
+
67
+ before do
68
+ Band.with(safe: { w: 3 })
69
+ end
70
+
71
+ it "clears the options from the current thread" do
72
+ Band.collection
73
+ Band.persistence_options.should be_nil
74
+ end
75
+
76
+ it "returns the collection" do
77
+ Band.collection.should be_a(Moped::Collection)
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ after do
84
+ Band.storage_options = nil
85
+ end
86
+
87
+ context "when called multiple times with different options" do
88
+ before do
89
+ Band.store_in collection: "artists"
90
+ Band.store_in session: "another"
91
+ end
92
+
93
+ it "should merge the options together" do
94
+ Band.storage_options.should == {
95
+ collection: "artists",
96
+ session: "another"
97
+ }
98
+ end
99
+ end
100
+
101
+ context "when overriding with a proc" do
102
+
103
+ before do
104
+ Band.store_in(collection: ->{ "artists" })
105
+ end
106
+
107
+ it_behaves_like "an overridden collection at the class level"
108
+ end
109
+
110
+ context "when overriding with a string" do
111
+
112
+ before do
113
+ Band.store_in(collection: "artists")
114
+ end
115
+
116
+ it_behaves_like "an overridden collection at the class level"
117
+ end
118
+
119
+ context "when overriding with a symbol" do
120
+
121
+ before do
122
+ Band.store_in(collection: :artists)
123
+ end
124
+
125
+ it_behaves_like "an overridden collection at the class level"
126
+ end
127
+ end
128
+
129
+ context "when not overriding the default" do
130
+
131
+ let(:band) do
132
+ Band.new
133
+ end
134
+
135
+ it "returns the collection for the model" do
136
+ band.collection.should be_a(Moped::Collection)
137
+ end
138
+
139
+ it "sets the correct collection name" do
140
+ band.collection.name.to_s.should eq("bands")
141
+ end
142
+
143
+ context "when accessing from the class level" do
144
+
145
+ it "returns the collection for the model" do
146
+ Band.collection.should be_a(Moped::Collection)
147
+ end
148
+
149
+ it "sets the correct collection name" do
150
+ Band.collection.name.to_s.should eq("bands")
151
+ end
152
+ end
153
+ end
154
+ end
155
+
156
+ describe "#collection_name" do
157
+
158
+ context "when overriding the default with store_in" do
159
+
160
+ shared_examples_for "an overridden collection name at the class level" do
161
+
162
+ let(:band) do
163
+ Band.new
164
+ end
165
+
166
+ context "when accessing from the instance" do
167
+
168
+ it "returns the overridden value" do
169
+ band.collection_name.should eq(:artists)
170
+ end
171
+ end
172
+
173
+ context "when accessing from the class level" do
174
+
175
+ it "returns the overridden value" do
176
+ Band.collection_name.should eq(:artists)
177
+ end
178
+ end
179
+ end
180
+
181
+ after do
182
+ Band.storage_options = nil
183
+ end
184
+
185
+ context "when overriding with a proc" do
186
+
187
+ before do
188
+ Band.store_in(collection: ->{ "artists" })
189
+ end
190
+
191
+ it_behaves_like "an overridden collection name at the class level"
192
+ end
193
+
194
+ context "when overriding with a string" do
195
+
196
+ before do
197
+ Band.store_in(collection: "artists")
198
+ end
199
+
200
+ it_behaves_like "an overridden collection name at the class level"
201
+ end
202
+
203
+ context "when overriding with a symbol" do
204
+
205
+ before do
206
+ Band.store_in(collection: :artists)
207
+ end
208
+
209
+ it_behaves_like "an overridden collection name at the class level"
210
+ end
211
+ end
212
+
213
+ context "when not overriding the default" do
214
+
215
+ let(:band) do
216
+ Band.new
217
+ end
218
+
219
+ it "returns the pluralized model name" do
220
+ band.collection_name.should eq(:bands)
221
+ end
222
+
223
+ context "when accessing from the class level" do
224
+
225
+ it "returns the pluralized model name" do
226
+ Band.collection_name.should eq(:bands)
227
+ end
228
+ end
229
+ end
230
+
231
+ context "when the model is a subclass" do
232
+
233
+ let(:firefox) do
234
+ Firefox.new
235
+ end
236
+
237
+ it "returns the root class pluralized model name" do
238
+ firefox.collection_name.should eq(:canvases)
239
+ end
240
+
241
+ context "when accessing from the class level" do
242
+
243
+ it "returns the root class pluralized model name" do
244
+ Firefox.collection_name.should eq(:canvases)
245
+ end
246
+ end
247
+ end
248
+ end
249
+
250
+ describe "#mongo_session" do
251
+
252
+ let(:file) do
253
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
254
+ end
255
+
256
+ before do
257
+ described_class.clear
258
+ Mongoid.load!(file, :test)
259
+ Mongoid.sessions[:default][:database] = database_id
260
+ end
261
+
262
+ after do
263
+ Band.storage_options = nil
264
+ end
265
+
266
+ context "when getting the default" do
267
+
268
+ let(:file) do
269
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
270
+ end
271
+
272
+ before do
273
+ Band.storage_options = nil
274
+ described_class.clear
275
+ Mongoid.load!(file, :test)
276
+ Mongoid.sessions[:default][:database] = database_id
277
+ end
278
+
279
+ after do
280
+ Band.storage_options = nil
281
+ end
282
+
283
+ let!(:band) do
284
+ Band.new
285
+ end
286
+
287
+ let!(:mongo_session) do
288
+ band.mongo_session
289
+ end
290
+
291
+ it "returns the default session" do
292
+ mongo_session.options[:database].should eq(database_id)
293
+ end
294
+ end
295
+
296
+ context "when overriding to a monghq single server", config: :mongohq do
297
+
298
+ shared_examples_for "an overridden session to a mongohq single server" do
299
+
300
+ let(:band) do
301
+ Band.new
302
+ end
303
+
304
+ let(:single_session) do
305
+ band.mongo_session
306
+ end
307
+
308
+ it "returns the default session" do
309
+ single_session.options[:database].should eq(ENV["MONGOHQ_SINGLE_NAME"])
310
+ end
311
+ end
312
+
313
+ context "when overriding with a proc" do
314
+
315
+ before do
316
+ Band.store_in(session: ->{ :mongohq_single })
317
+ end
318
+
319
+ it_behaves_like "an overridden session to a mongohq single server"
320
+ end
321
+
322
+ context "when overriding with a string" do
323
+
324
+ before do
325
+ Band.store_in(session: "mongohq_single")
326
+ end
327
+
328
+ it_behaves_like "an overridden session to a mongohq single server"
329
+ end
330
+
331
+ context "when overriding with a symbol" do
332
+
333
+ before do
334
+ Band.store_in(session: :mongohq_single)
335
+ end
336
+
337
+ it_behaves_like "an overridden session to a mongohq single server"
338
+ end
339
+ end
340
+
341
+ context "when overriding to a mongohq replica set", config: :mongohq do
342
+
343
+ let(:band) do
344
+ Band.new
345
+ end
346
+
347
+ let(:replica_session) do
348
+ band.mongo_session
349
+ end
350
+
351
+ shared_examples_for "an overridden session to a mongohq replica set" do
352
+
353
+ it "returns the default session" do
354
+ replica_session.options[:database].should eq(ENV["MONGOHQ_REPL_NAME"])
355
+ end
356
+ end
357
+
358
+ context "when overriding with a proc" do
359
+
360
+ before do
361
+ Band.store_in(session: ->{ :mongohq_repl })
362
+ end
363
+
364
+ it_behaves_like "an overridden session to a mongohq replica set"
365
+ end
366
+
367
+ context "when overriding with a string" do
368
+
369
+ before do
370
+ Band.store_in(session: "mongohq_repl")
371
+ end
372
+
373
+ it_behaves_like "an overridden session to a mongohq replica set"
374
+ end
375
+
376
+ context "when overriding with a symbol" do
377
+
378
+ before do
379
+ Band.store_in(session: :mongohq_repl)
380
+ end
381
+
382
+ it_behaves_like "an overridden session to a mongohq replica set"
383
+ end
384
+ end
385
+
386
+ context "when overriding to a mongohq replica set with uri config", config: :mongohq do
387
+
388
+ before(:all) do
389
+ Band.store_in(session: :mongohq_repl_uri)
390
+ end
391
+
392
+ let(:band) do
393
+ Band.new
394
+ end
395
+
396
+ let(:repl_session) do
397
+ band.mongo_session
398
+ end
399
+
400
+ it "returns the default session" do
401
+ repl_session.options[:database].should eq(ENV["MONGOHQ_REPL_NAME"])
402
+ end
403
+ end
404
+
405
+ context "when no session exists with the key" do
406
+
407
+ before(:all) do
408
+ Band.store_in(session: :nonexistant)
409
+ end
410
+
411
+ let(:band) do
412
+ Band.new
413
+ end
414
+
415
+ it "raises an error" do
416
+ expect {
417
+ band.mongo_session
418
+ }.to raise_error(Mongoid::Errors::NoSessionConfig)
419
+ end
420
+ end
421
+ end
422
+
423
+ describe ".mongo_session" do
424
+
425
+ let(:file) do
426
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
427
+ end
428
+
429
+ before do
430
+ described_class.clear
431
+ Mongoid.load!(file, :test)
432
+ Mongoid.sessions[:default][:database] = database_id
433
+ end
434
+
435
+ after do
436
+ Band.storage_options = nil
437
+ end
438
+
439
+ context "when getting the default" do
440
+
441
+ let(:file) do
442
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
443
+ end
444
+
445
+ before do
446
+ Band.storage_options = nil
447
+ described_class.clear
448
+ Mongoid.load!(file, :test)
449
+ Mongoid.sessions[:default][:database] = database_id
450
+ end
451
+
452
+ let!(:mongo_session) do
453
+ Band.mongo_session
454
+ end
455
+
456
+ it "returns the default session" do
457
+ mongo_session.options[:database].should eq(database_id)
458
+ end
459
+ end
460
+
461
+ context "when overriding to a monghq single server", config: :mongohq do
462
+
463
+ before(:all) do
464
+ Band.store_in(session: :mongohq_single)
465
+ end
466
+
467
+ let(:session) do
468
+ Band.mongo_session
469
+ end
470
+
471
+ it "returns the default session" do
472
+ session.options[:database].should eq(ENV["MONGOHQ_SINGLE_NAME"])
473
+ end
474
+ end
475
+
476
+ context "when overriding to a mongohq replica set", config: :mongohq do
477
+
478
+ before(:all) do
479
+ Band.store_in(session: :mongohq_repl)
480
+ end
481
+
482
+ let(:repl_session) do
483
+ Band.mongo_session
484
+ end
485
+
486
+ it "returns the default session" do
487
+ repl_session.options[:database].should eq(ENV["MONGOHQ_REPL_NAME"])
488
+ end
489
+ end
490
+
491
+ context "when no session exists with the key" do
492
+
493
+ before(:all) do
494
+ Band.store_in(session: :nonexistant)
495
+ end
496
+
497
+ it "raises an error" do
498
+ expect {
499
+ Band.mongo_session
500
+ }.to raise_error(Mongoid::Errors::NoSessionConfig)
501
+ end
502
+ end
503
+ end
504
+
505
+ describe ".persistence_options" do
506
+
507
+ context "when options exist on the current thread" do
508
+
509
+ before do
510
+ Band.with(safe: { w: 2 })
511
+ end
512
+
513
+ after do
514
+ Band.clear_persistence_options
515
+ end
516
+
517
+ it "returns the options" do
518
+ Band.persistence_options.should eq(safe: { w: 2 })
519
+ end
520
+ end
521
+
522
+ context "when there are no options on the current thread" do
523
+
524
+ it "returns nil" do
525
+ Band.persistence_options.should be_nil
526
+ end
527
+ end
528
+ end
529
+
530
+ describe ".store_in" do
531
+
532
+ context "when provided a non hash" do
533
+
534
+ it "raises an error" do
535
+ expect {
536
+ Band.store_in :artists
537
+ }.to raise_error(Mongoid::Errors::InvalidStorageOptions)
538
+ end
539
+ end
540
+
541
+ context "when provided a hash" do
542
+
543
+ context "when the hash is not valid" do
544
+
545
+ it "raises an error" do
546
+ expect {
547
+ Band.store_in coll: "artists"
548
+ }.to raise_error(Mongoid::Errors::InvalidStorageOptions)
549
+ end
550
+ end
551
+ end
552
+ end
553
+
554
+ describe ".with" do
555
+
556
+ context "when sending operations to a different database" do
557
+
558
+ after do
559
+ Band.with(database: "mongoid_test_alt").delete_all
560
+ end
561
+
562
+ describe ".create" do
563
+
564
+ let!(:band) do
565
+ Band.with(database: "mongoid_test_alt").create
566
+ end
567
+
568
+ it "does not persist to the default database" do
569
+ expect {
570
+ Band.find(band.id)
571
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
572
+ end
573
+
574
+ let(:from_db) do
575
+ Band.with(database: "mongoid_test_alt").find(band.id)
576
+ end
577
+
578
+ it "persists to the specified database" do
579
+ from_db.should eq(band)
580
+ end
581
+
582
+ it "persists the correct number of documents" do
583
+ Band.with(database: "mongoid_test_alt").count.should eq(1)
584
+ end
585
+ end
586
+
587
+ describe ".map_reduce", config: :mongohq do
588
+
589
+ let(:map) do
590
+ %Q{
591
+ function() {
592
+ emit(this.name, { likes: this.likes });
593
+ }}
594
+ end
595
+
596
+ let(:reduce) do
597
+ %Q{
598
+ function(key, values) {
599
+ var result = { likes: 0 };
600
+ values.forEach(function(value) {
601
+ result.likes += value.likes;
602
+ });
603
+ return result;
604
+ }}
605
+ end
606
+
607
+ before do
608
+ Band.with(database: "mongoid_test_alt").delete_all
609
+ end
610
+
611
+ let!(:depeche_mode) do
612
+ Band.with(database: "mongoid_test_alt").
613
+ create(name: "Depeche Mode", likes: 200)
614
+ end
615
+
616
+ let!(:tool) do
617
+ Band.with(database: "mongoid_test_alt").
618
+ create(name: "Tool", likes: 100)
619
+ end
620
+
621
+ context "when outputting in memory" do
622
+
623
+ let(:results) do
624
+ Band.with(database: "mongoid_test_alt").
625
+ map_reduce(map, reduce).out(inline: 1)
626
+ end
627
+
628
+ it "executes the map/reduce on the correct database" do
629
+ results.first["value"].should eq({ "likes" => 200 })
630
+ end
631
+ end
632
+
633
+ context "when outputting to a collection" do
634
+
635
+ let(:results) do
636
+ Band.with(database: "mongoid_test_alt").
637
+ map_reduce(map, reduce).out(replace: "bands_output")
638
+ end
639
+
640
+ it "executes the map/reduce on the correct database" do
641
+ results.first["value"].should eq({ "likes" => 200 })
642
+ end
643
+ end
644
+ end
645
+ end
646
+
647
+ context "when sending operations to a different collection" do
648
+
649
+ describe ".create" do
650
+
651
+ let!(:band) do
652
+ Band.with(collection: "artists").create
653
+ end
654
+
655
+ it "does not persist to the default database" do
656
+ expect {
657
+ Band.find(band.id)
658
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
659
+ end
660
+
661
+ let(:from_db) do
662
+ Band.with(collection: "artists").find(band.id)
663
+ end
664
+
665
+ it "persists to the specified database" do
666
+ from_db.should eq(band)
667
+ end
668
+
669
+ it "persists the correct number of documents" do
670
+ Band.with(collection: "artists").count.should eq(1)
671
+ end
672
+ end
673
+
674
+ describe ".map_reduce", config: :mongohq do
675
+
676
+ let(:map) do
677
+ %Q{
678
+ function() {
679
+ emit(this.name, { likes: this.likes });
680
+ }}
681
+ end
682
+
683
+ let(:reduce) do
684
+ %Q{
685
+ function(key, values) {
686
+ var result = { likes: 0 };
687
+ values.forEach(function(value) {
688
+ result.likes += value.likes;
689
+ });
690
+ return result;
691
+ }}
692
+ end
693
+
694
+ before do
695
+ Band.with(collection: "artists").delete_all
696
+ end
697
+
698
+ let!(:depeche_mode) do
699
+ Band.with(collection: "artists").
700
+ create(name: "Depeche Mode", likes: 200)
701
+ end
702
+
703
+ let!(:tool) do
704
+ Band.with(collection: "artists").
705
+ create(name: "Tool", likes: 100)
706
+ end
707
+
708
+ let(:results) do
709
+ Band.with(collection: "artists").
710
+ map_reduce(map, reduce).out(inline: 1)
711
+ end
712
+
713
+ it "executes the map/reduce on the correct collection" do
714
+ results.first["value"].should eq({ "likes" => 200 })
715
+ end
716
+ end
717
+ end
718
+
719
+ context "when sending operations to a different session" do
720
+
721
+ describe ".create" do
722
+
723
+ let(:file) do
724
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
725
+ end
726
+
727
+ before do
728
+ described_class.clear
729
+ Mongoid.load!(file, :test)
730
+ end
731
+
732
+ context "when sending to a mongohq single server", config: :mongohq do
733
+
734
+ let!(:band) do
735
+ Band.with(
736
+ session: "mongohq_single",
737
+ database: database_id
738
+ ).create
739
+ end
740
+
741
+ let(:from_db) do
742
+ Band.with(
743
+ session: "mongohq_single",
744
+ database: database_id
745
+ ).find(band.id)
746
+ end
747
+
748
+ it "persists to the specified database" do
749
+ from_db.should eq(band)
750
+ end
751
+ end
752
+
753
+ context "when sending to a mongohq replica set", config: :mongohq do
754
+
755
+ let!(:band) do
756
+ Band.with(
757
+ session: "mongohq_repl",
758
+ database: "mongoid_replica"
759
+ ).create
760
+ end
761
+
762
+ let(:from_db) do
763
+ Band.with(
764
+ session: "mongohq_repl",
765
+ database: "mongoid_replica"
766
+ ).find(band.id)
767
+ end
768
+
769
+ it "persists to the specified database" do
770
+ from_db.should eq(band)
771
+ end
772
+ end
773
+
774
+ context "when sending to a mongohq replica set with uri config", config: :mongohq do
775
+
776
+ let!(:band) do
777
+ Band.with(
778
+ session: "mongohq_repl_uri",
779
+ database: "mongoid_replica"
780
+ ).create
781
+ end
782
+
783
+ let(:from_db) do
784
+ Band.with(
785
+ session: "mongohq_repl_uri",
786
+ database: "mongoid_replica"
787
+ ).find(band.id)
788
+ end
789
+
790
+ it "persists to the specified database" do
791
+ from_db.should eq(band)
792
+ end
793
+ end
794
+ end
795
+
796
+ describe ".map_reduce", config: :mongohq do
797
+
798
+ let(:file) do
799
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
800
+ end
801
+
802
+ before do
803
+ described_class.clear
804
+ Mongoid.load!(file, :test)
805
+ end
806
+
807
+ let(:map) do
808
+ %Q{
809
+ function() {
810
+ emit(this.name, { likes: this.likes });
811
+ }}
812
+ end
813
+
814
+ let(:reduce) do
815
+ %Q{
816
+ function(key, values) {
817
+ var result = { likes: 0 };
818
+ values.forEach(function(value) {
819
+ result.likes += value.likes;
820
+ });
821
+ return result;
822
+ }}
823
+ end
824
+
825
+ before do
826
+ Band.with(
827
+ session: "mongohq_repl",
828
+ database: "mongoid_replica"
829
+ ).delete_all
830
+ end
831
+
832
+ let!(:depeche_mode) do
833
+ Band.with(
834
+ session: "mongohq_repl",
835
+ database: "mongoid_replica"
836
+ ).create(name: "Depeche Mode", likes: 200)
837
+ end
838
+
839
+ let!(:tool) do
840
+ Band.with(
841
+ session: "mongohq_repl",
842
+ database: "mongoid_replica"
843
+ ).create(name: "Tool", likes: 100)
844
+ end
845
+
846
+ let(:results) do
847
+ Band.with(
848
+ session: "mongohq_repl",
849
+ database: "mongoid_replica"
850
+ ).map_reduce(map, reduce).out(inline: 1)
851
+ end
852
+
853
+ it "executes the map/reduce on the correct session" do
854
+ results.first["value"].should eq({ "likes" => 200 })
855
+ end
856
+ end
857
+ end
858
+
859
+ context "when sending operations with safe mode" do
860
+
861
+ describe ".create" do
862
+
863
+ before do
864
+ Person.with(safe: true).create(ssn: "432-97-1111")
865
+ end
866
+
867
+ context "when no error occurs" do
868
+
869
+ it "inserts the document" do
870
+ Person.count.should eq(1)
871
+ end
872
+ end
873
+
874
+ context "when a mongodb error occurs" do
875
+
876
+ before do
877
+ Person.create_indexes
878
+ end
879
+
880
+ it "bubbles up to the caller" do
881
+ expect {
882
+ Person.with(safe: true).create(ssn: "432-97-1111")
883
+ }.to raise_error(Moped::Errors::OperationFailure)
884
+ end
885
+ end
886
+
887
+ context "when using safe: false" do
888
+
889
+ it "ignores mongodb error" do
890
+ Person.with(safe: false).create(ssn: "432-97-1111").should be_true
891
+ end
892
+ end
893
+ end
894
+
895
+ describe ".create!" do
896
+
897
+ before do
898
+ Person.with(safe: true).create!(ssn: "432-97-1112")
899
+ end
900
+
901
+ context "when no error occurs" do
902
+
903
+ it "inserts the document" do
904
+ Person.count.should eq(1)
905
+ end
906
+ end
907
+
908
+ context "when a mongodb error occurs" do
909
+
910
+ before do
911
+ Person.create_indexes
912
+ end
913
+
914
+ it "bubbles up to the caller" do
915
+ expect {
916
+ Person.with(safe: true).create!(ssn: "432-97-1112")
917
+ }.to raise_error(Moped::Errors::OperationFailure)
918
+ end
919
+ end
920
+
921
+ context "when a validation error occurs" do
922
+
923
+ it "raises the validation error" do
924
+ expect {
925
+ Account.with(safe: true).create!(name: "this name is way too long")
926
+ }.to raise_error(Mongoid::Errors::Validations)
927
+ end
928
+ end
929
+ end
930
+
931
+ describe ".save" do
932
+
933
+ before do
934
+ Person.with(safe: true).create(ssn: "432-97-1113")
935
+ end
936
+
937
+ context "when a mongodb error occurs" do
938
+
939
+ let(:person) do
940
+ Person.new(ssn: "432-97-1113")
941
+ end
942
+
943
+ before do
944
+ Person.create_indexes
945
+ end
946
+
947
+ it "bubbles up to the caller" do
948
+ expect {
949
+ person.with(safe: true).save
950
+ }.to raise_error(Moped::Errors::OperationFailure)
951
+ end
952
+ end
953
+ end
954
+
955
+ describe ".save!" do
956
+
957
+ before do
958
+ Person.with(safe: true).create!(ssn: "432-97-1114")
959
+ end
960
+
961
+ context "when a mongodb error occurs" do
962
+
963
+ let(:person) do
964
+ Person.new(ssn: "432-97-1114")
965
+ end
966
+
967
+ before do
968
+ Person.create_indexes
969
+ end
970
+
971
+ it "bubbles up to the caller" do
972
+ expect {
973
+ person.with(safe: true).save!
974
+ }.to raise_error(Moped::Errors::OperationFailure)
975
+ end
976
+ end
977
+
978
+ context "when a validation error occurs" do
979
+
980
+ let(:account) do
981
+ Account.new(name: "this name is way too long")
982
+ end
983
+
984
+ it "raises the validation error" do
985
+ expect {
986
+ account.with(safe: true).save!
987
+ }.to raise_error(Mongoid::Errors::Validations)
988
+ end
989
+ end
990
+ end
991
+ end
992
+ end
993
+
994
+ context "when the default database uses a uri" do
995
+
996
+ let(:file) do
997
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
998
+ end
999
+
1000
+ let(:config) do
1001
+ { default: { uri: "mongodb://localhost:#{PORT}/#{database_id}" }}
1002
+ end
1003
+
1004
+ before do
1005
+ Mongoid::Threaded.sessions.clear
1006
+ Mongoid.sessions = config
1007
+ end
1008
+
1009
+ context "when creating a document" do
1010
+
1011
+ let!(:band) do
1012
+ Band.create(name: "Placebo")
1013
+ end
1014
+
1015
+ it "persists the document to the correct database" do
1016
+ Band.find(band.id).should eq(band)
1017
+ end
1018
+ end
1019
+ end
1020
+
1021
+ context "when overriding the default database "do
1022
+
1023
+ let(:file) do
1024
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
1025
+ end
1026
+
1027
+ before do
1028
+ Mongoid::Config.load!(file, :test)
1029
+ end
1030
+
1031
+ context "when the override is global" do
1032
+
1033
+ before do
1034
+ Mongoid.override_database(:mongoid_optional)
1035
+ end
1036
+
1037
+ after do
1038
+ Band.delete_all
1039
+ Mongoid.override_database(nil)
1040
+ end
1041
+
1042
+ let!(:band) do
1043
+ Band.create(name: "Tool")
1044
+ end
1045
+
1046
+ it "persists to the overridden database" do
1047
+ Band.mongo_session.with(database: :mongoid_optional) do |sess|
1048
+ sess[:bands].find(name: "Tool").should_not be_nil
1049
+ end
1050
+ end
1051
+ end
1052
+ end
1053
+
1054
+ context "when overriding the default session", config: :mongohq do
1055
+
1056
+ context "when the override is configured with a uri" do
1057
+
1058
+ let(:database_name) do
1059
+ "mongoid_other"
1060
+ end
1061
+
1062
+ let(:config) do
1063
+ { default: { uri: "mongodb://localhost:#{PORT}/#{database_id}" },
1064
+ session1: { uri: "mongodb://localhost:#{PORT}/#{database_name}" }}
1065
+ end
1066
+
1067
+ before do
1068
+ Mongoid::Threaded.sessions.clear
1069
+ Mongoid.sessions = config
1070
+ Mongoid.override_session(:session1)
1071
+ end
1072
+
1073
+ after do
1074
+ Mongoid.override_session(nil)
1075
+ end
1076
+
1077
+ it "has some database name on session" do
1078
+ Band.mongo_session.options[:database].should eq(database_name)
1079
+ end
1080
+ end
1081
+
1082
+ context "when the override is global" do
1083
+
1084
+ let(:file) do
1085
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
1086
+ end
1087
+
1088
+ before do
1089
+ Mongoid::Config.load!(file, :test)
1090
+ Mongoid.override_session(:mongohq_single)
1091
+ end
1092
+
1093
+ after do
1094
+ Band.with(database: database_id).delete_all
1095
+ Mongoid.override_session(nil)
1096
+ end
1097
+
1098
+ let!(:band) do
1099
+ Band.with(database: database_id).create(name: "Tool")
1100
+ end
1101
+
1102
+ let(:persisted) do
1103
+ Band.with(session: :mongohq_single, database: database_id).where(name: "Tool").first
1104
+ end
1105
+
1106
+ it "persists to the overridden session" do
1107
+ persisted.should eq(band)
1108
+ end
1109
+ end
1110
+ end
1111
+ end