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,1757 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Contextual::Mongo do
4
+
5
+ [ :blank?, :empty? ].each do |method|
6
+
7
+ describe "##{method}" do
8
+
9
+ before do
10
+ Band.create(name: "Depeche Mode")
11
+ end
12
+
13
+ context "when the count is zero" do
14
+
15
+ let(:criteria) do
16
+ Band.where(name: "New Order")
17
+ end
18
+
19
+ let(:context) do
20
+ described_class.new(criteria)
21
+ end
22
+
23
+ it "returns true" do
24
+ context.send(method).should be_true
25
+ end
26
+ end
27
+
28
+ context "when the count is greater than zero" do
29
+
30
+ let(:criteria) do
31
+ Band.where(name: "Depeche Mode")
32
+ end
33
+
34
+ let(:context) do
35
+ described_class.new(criteria)
36
+ end
37
+
38
+ it "returns false" do
39
+ context.send(method).should be_false
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "#cached?" do
46
+
47
+ context "when the criteria is cached" do
48
+
49
+ let(:criteria) do
50
+ Band.all.cache
51
+ end
52
+
53
+ let(:context) do
54
+ described_class.new(criteria)
55
+ end
56
+
57
+ it "returns true" do
58
+ context.should be_cached
59
+ end
60
+ end
61
+
62
+ context "when the criteria is not cached" do
63
+
64
+ let(:criteria) do
65
+ Band.all
66
+ end
67
+
68
+ let(:context) do
69
+ described_class.new(criteria)
70
+ end
71
+
72
+ it "returns false" do
73
+ context.should_not be_cached
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "#count" do
79
+
80
+ let!(:depeche) do
81
+ Band.create(name: "Depeche Mode")
82
+ end
83
+
84
+ let!(:new_order) do
85
+ Band.create(name: "New Order")
86
+ end
87
+
88
+ let(:criteria) do
89
+ Band.where(name: "Depeche Mode")
90
+ end
91
+
92
+ context "when no arguments are provided" do
93
+
94
+ let(:context) do
95
+ described_class.new(criteria)
96
+ end
97
+
98
+ it "returns the number of documents that match" do
99
+ context.count.should eq(1)
100
+ end
101
+ end
102
+
103
+ context "when context is cached" do
104
+
105
+ let(:context) do
106
+ described_class.new(criteria.cache)
107
+ end
108
+
109
+ before do
110
+ context.query.should_receive(:count).once.and_return(1)
111
+ end
112
+
113
+ it "returns the count cached value after first call" do
114
+ 2.times { context.count.should eq(1) }
115
+ end
116
+ end
117
+
118
+ context "when provided a document" do
119
+
120
+ let(:context) do
121
+ described_class.new(criteria)
122
+ end
123
+
124
+ let(:count) do
125
+ context.count(depeche)
126
+ end
127
+
128
+ it "returns the number of documents that match" do
129
+ count.should eq(1)
130
+ end
131
+ end
132
+
133
+ context "when provided a block" do
134
+
135
+ let(:context) do
136
+ described_class.new(criteria)
137
+ end
138
+
139
+ let(:count) do
140
+ context.count do |doc|
141
+ doc.likes.nil?
142
+ end
143
+ end
144
+
145
+ it "returns the number of documents that match" do
146
+ count.should eq(1)
147
+ end
148
+
149
+ context "and a limit true" do
150
+
151
+ before do
152
+ 2.times { Band.create(name: "Depeche Mode", likes: 1) }
153
+ end
154
+
155
+ let(:count) do
156
+ context.count(true) do |doc|
157
+ doc.likes.nil?
158
+ end
159
+ end
160
+
161
+ it "returns the number of documents that match" do
162
+ count.should eq(1)
163
+ end
164
+ end
165
+ end
166
+
167
+ context "when provided limit true" do
168
+
169
+ before do
170
+ 2.times { Band.create(name: "Depeche Mode") }
171
+ end
172
+
173
+ let(:context) do
174
+ described_class.new(criteria.limit(2))
175
+ end
176
+
177
+ let(:count) do
178
+ context.count(true)
179
+ end
180
+
181
+ it "returns the number of documents that match" do
182
+ count.should eq(2)
183
+ end
184
+ end
185
+ end
186
+
187
+ [ :delete, :delete_all ].each do |method|
188
+
189
+ describe "##{method}" do
190
+
191
+ let!(:depeche_mode) do
192
+ Band.create(name: "Depeche Mode")
193
+ end
194
+
195
+ let!(:new_order) do
196
+ Band.create(name: "New Order")
197
+ end
198
+
199
+ context "when the selector is contraining" do
200
+
201
+ let(:criteria) do
202
+ Band.where(name: "Depeche Mode")
203
+ end
204
+
205
+ let(:context) do
206
+ described_class.new(criteria)
207
+ end
208
+
209
+ let!(:deleted) do
210
+ context.send(method)
211
+ end
212
+
213
+ it "deletes the matching documents" do
214
+ Band.find(new_order.id).should eq(new_order)
215
+ end
216
+
217
+ it "deletes the correct number of documents" do
218
+ Band.count.should eq(1)
219
+ end
220
+
221
+ it "returns the number of documents deleted" do
222
+ deleted.should eq(1)
223
+ end
224
+ end
225
+
226
+ context "when the selector is not contraining" do
227
+
228
+ let(:criteria) do
229
+ Band.all
230
+ end
231
+
232
+ let(:context) do
233
+ described_class.new(criteria)
234
+ end
235
+
236
+ before do
237
+ context.send(method)
238
+ end
239
+
240
+ it "deletes all the documents" do
241
+ Band.count.should eq(0)
242
+ end
243
+ end
244
+ end
245
+ end
246
+
247
+ [ :destroy, :destroy_all ].each do |method|
248
+
249
+ describe "##{method}" do
250
+
251
+ let!(:depeche_mode) do
252
+ Band.create(name: "Depeche Mode")
253
+ end
254
+
255
+ let!(:new_order) do
256
+ Band.create(name: "New Order")
257
+ end
258
+
259
+ context "when the selector is contraining" do
260
+
261
+ let(:criteria) do
262
+ Band.where(name: "Depeche Mode")
263
+ end
264
+
265
+ let(:context) do
266
+ described_class.new(criteria)
267
+ end
268
+
269
+ let!(:destroyed) do
270
+ context.send(method)
271
+ end
272
+
273
+ it "destroys the matching documents" do
274
+ Band.find(new_order.id).should eq(new_order)
275
+ end
276
+
277
+ it "destroys the correct number of documents" do
278
+ Band.count.should eq(1)
279
+ end
280
+
281
+ it "returns the number of documents destroyed" do
282
+ destroyed.should eq(1)
283
+ end
284
+ end
285
+
286
+ context "when the selector is not contraining" do
287
+
288
+ let(:criteria) do
289
+ Band.all
290
+ end
291
+
292
+ let(:context) do
293
+ described_class.new(criteria)
294
+ end
295
+
296
+ before do
297
+ context.send(method)
298
+ end
299
+
300
+ it "destroys all the documents" do
301
+ Band.count.should eq(0)
302
+ end
303
+ end
304
+ end
305
+ end
306
+
307
+ describe "#distinct" do
308
+
309
+ before do
310
+ Band.create(name: "Depeche Mode", years: 30)
311
+ Band.create(name: "New Order", years: 25)
312
+ end
313
+
314
+ context "when limiting the result set" do
315
+
316
+ let(:criteria) do
317
+ Band.where(name: "Depeche Mode")
318
+ end
319
+
320
+ let(:context) do
321
+ described_class.new(criteria)
322
+ end
323
+
324
+ it "returns the distinct matching fields" do
325
+ context.distinct(:name).should eq([ "Depeche Mode" ])
326
+ end
327
+ end
328
+
329
+ context "when not limiting the result set" do
330
+
331
+ let(:criteria) do
332
+ Band.criteria
333
+ end
334
+
335
+ let(:context) do
336
+ described_class.new(criteria)
337
+ end
338
+
339
+ it "returns the distinct field values" do
340
+ context.distinct(:name).should eq([ "Depeche Mode", "New Order" ])
341
+ end
342
+ end
343
+
344
+ context "when providing an aliased field" do
345
+
346
+ let(:criteria) do
347
+ Band.criteria
348
+ end
349
+
350
+ let(:context) do
351
+ described_class.new(criteria)
352
+ end
353
+
354
+ it "returns the distinct field values" do
355
+ context.distinct(:years).should eq([ 30, 25 ])
356
+ end
357
+ end
358
+ end
359
+
360
+ describe "#each" do
361
+
362
+ before do
363
+ Band.create(name: "Depeche Mode")
364
+ end
365
+
366
+ let(:criteria) do
367
+ Band.where(name: "Depeche Mode")
368
+ end
369
+
370
+ let(:context) do
371
+ described_class.new(criteria)
372
+ end
373
+
374
+ context "when providing a block" do
375
+
376
+ it "yields mongoid documents to the block" do
377
+ context.each do |doc|
378
+ doc.should be_a(Mongoid::Document)
379
+ end
380
+ end
381
+
382
+ it "iterates over the matching documents" do
383
+ context.each do |doc|
384
+ doc.name.should eq("Depeche Mode")
385
+ end
386
+ end
387
+
388
+ it "returns self" do
389
+ context.each{}.should be(context)
390
+ end
391
+ end
392
+
393
+ context "when no block is provided" do
394
+
395
+ let(:enum) do
396
+ context.each
397
+ end
398
+
399
+ it "returns an enumerator" do
400
+ enum.should be_a(Enumerator)
401
+ end
402
+
403
+ context "when iterating over the enumerator" do
404
+
405
+ context "when iterating with each" do
406
+
407
+ it "yields mongoid documents to the block" do
408
+ enum.each do |doc|
409
+ doc.should be_a(Mongoid::Document)
410
+ end
411
+ end
412
+ end
413
+
414
+ context "when iterating with next" do
415
+
416
+ it "yields mongoid documents" do
417
+ enum.next.should be_a(Mongoid::Document)
418
+ end
419
+ end
420
+ end
421
+ end
422
+ end
423
+
424
+ describe "#eager_load" do
425
+
426
+ let(:criteria) do
427
+ Person.includes(:game)
428
+ end
429
+
430
+ let(:context) do
431
+ described_class.new(criteria)
432
+ end
433
+
434
+ context "when no documents are returned" do
435
+
436
+ let(:game_metadata) do
437
+ Person.reflect_on_association(:game)
438
+ end
439
+
440
+ it "does not make any additional database queries" do
441
+ game_metadata.should_receive(:eager_load).never
442
+ context.send(:eager_load, [])
443
+ end
444
+ end
445
+ end
446
+
447
+ describe "#exists?" do
448
+
449
+ before do
450
+ Band.create(name: "Depeche Mode")
451
+ end
452
+
453
+ context "when the count is zero" do
454
+
455
+ let(:criteria) do
456
+ Band.where(name: "New Order")
457
+ end
458
+
459
+ let(:context) do
460
+ described_class.new(criteria)
461
+ end
462
+
463
+ it "returns false" do
464
+ context.should_not be_exists
465
+ end
466
+ end
467
+
468
+ context "when the count is greater than zero" do
469
+
470
+ let(:criteria) do
471
+ Band.where(name: "Depeche Mode")
472
+ end
473
+
474
+ let(:context) do
475
+ described_class.new(criteria)
476
+ end
477
+
478
+ it "returns true" do
479
+ context.should be_exists
480
+ end
481
+ end
482
+
483
+ context "when caching is enabled" do
484
+
485
+ let(:criteria) do
486
+ Band.where(name: "Depeche Mode").cache
487
+ end
488
+
489
+ let(:context) do
490
+ described_class.new(criteria)
491
+ end
492
+
493
+ context "when the cache is loaded" do
494
+
495
+ before do
496
+ context.to_a
497
+ end
498
+
499
+ it "does not hit the database" do
500
+ context.should_receive(:query).never
501
+ context.should be_exists
502
+ end
503
+ end
504
+
505
+ context "when the cache is not loaded" do
506
+
507
+ context "when a count has been executed" do
508
+
509
+ before do
510
+ context.count
511
+ end
512
+
513
+ it "does not hit the database" do
514
+ context.should_receive(:query).never
515
+ context.should be_exists
516
+ end
517
+ end
518
+ end
519
+ end
520
+ end
521
+
522
+ describe "#explain" do
523
+
524
+ let(:criteria) do
525
+ Band.where(name: "Depeche Mode")
526
+ end
527
+
528
+ let(:context) do
529
+ described_class.new(criteria)
530
+ end
531
+
532
+ it "returns the criteria explain path" do
533
+ context.explain["cursor"].should eq("BasicCursor")
534
+ end
535
+ end
536
+
537
+ describe "#find_and_modify" do
538
+
539
+ let!(:depeche) do
540
+ Band.create(name: "Depeche Mode")
541
+ end
542
+
543
+ let!(:tool) do
544
+ Band.create(name: "Tool")
545
+ end
546
+
547
+ context "when the selector matches" do
548
+
549
+ context "when not providing options" do
550
+
551
+ let(:criteria) do
552
+ Band.where(name: "Depeche Mode")
553
+ end
554
+
555
+ let(:context) do
556
+ described_class.new(criteria)
557
+ end
558
+
559
+ let!(:result) do
560
+ context.find_and_modify("$inc" => { likes: 1 })
561
+ end
562
+
563
+ it "returns the first matching document" do
564
+ result.should eq(depeche)
565
+ end
566
+
567
+ it "updates the document in the database" do
568
+ depeche.reload.likes.should eq(1)
569
+ end
570
+ end
571
+
572
+ context "when sorting" do
573
+
574
+ let(:criteria) do
575
+ Band.desc(:name)
576
+ end
577
+
578
+ let(:context) do
579
+ described_class.new(criteria)
580
+ end
581
+
582
+ let!(:result) do
583
+ context.find_and_modify("$inc" => { likes: 1 })
584
+ end
585
+
586
+ it "returns the first matching document" do
587
+ result.should eq(tool)
588
+ end
589
+
590
+ it "updates the document in the database" do
591
+ tool.reload.likes.should eq(1)
592
+ end
593
+ end
594
+
595
+ context "when limiting fields" do
596
+
597
+ let(:criteria) do
598
+ Band.only(:_id)
599
+ end
600
+
601
+ let(:context) do
602
+ described_class.new(criteria)
603
+ end
604
+
605
+ let!(:result) do
606
+ context.find_and_modify("$inc" => { likes: 1 })
607
+ end
608
+
609
+ it "returns the first matching document" do
610
+ result.should eq(depeche)
611
+ end
612
+
613
+ it "limits the returned fields" do
614
+ result.name.should be_nil
615
+ end
616
+
617
+ it "updates the document in the database" do
618
+ depeche.reload.likes.should eq(1)
619
+ end
620
+ end
621
+
622
+ context "when returning new" do
623
+
624
+ let(:criteria) do
625
+ Band.where(name: "Depeche Mode")
626
+ end
627
+
628
+ let(:context) do
629
+ described_class.new(criteria)
630
+ end
631
+
632
+ let!(:result) do
633
+ context.find_and_modify({ "$inc" => { likes: 1 }}, new: true)
634
+ end
635
+
636
+ it "returns the first matching document" do
637
+ result.should eq(depeche)
638
+ end
639
+
640
+ it "returns the updated document" do
641
+ result.likes.should eq(1)
642
+ end
643
+ end
644
+
645
+ context "when removing" do
646
+
647
+ let(:criteria) do
648
+ Band.where(name: "Depeche Mode")
649
+ end
650
+
651
+ let(:context) do
652
+ described_class.new(criteria)
653
+ end
654
+
655
+ let!(:result) do
656
+ context.find_and_modify({}, remove: true)
657
+ end
658
+
659
+ it "returns the first matching document" do
660
+ result.should eq(depeche)
661
+ end
662
+
663
+ it "deletes the document from the database" do
664
+ expect {
665
+ depeche.reload
666
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
667
+ end
668
+ end
669
+ end
670
+
671
+ context "when the selector does not match" do
672
+
673
+ let(:criteria) do
674
+ Band.where(name: "Placebo")
675
+ end
676
+
677
+ let(:context) do
678
+ described_class.new(criteria)
679
+ end
680
+
681
+ let(:result) do
682
+ context.find_and_modify("$inc" => { likes: 1 })
683
+ end
684
+
685
+ it "returns nil" do
686
+ result.should be_nil
687
+ end
688
+ end
689
+ end
690
+
691
+ [ :first, :one ].each do |method|
692
+
693
+ describe "##{method}" do
694
+
695
+ let!(:depeche_mode) do
696
+ Band.create(name: "Depeche Mode")
697
+ end
698
+
699
+ let!(:new_order) do
700
+ Band.create(name: "New Order")
701
+ end
702
+
703
+ context "when the context is not cached" do
704
+
705
+ let(:criteria) do
706
+ Band.where(name: "Depeche Mode")
707
+ end
708
+
709
+ let(:context) do
710
+ described_class.new(criteria)
711
+ end
712
+
713
+ it "returns the first matching document" do
714
+ context.send(method).should eq(depeche_mode)
715
+ end
716
+ end
717
+
718
+ context "when using .desc" do
719
+
720
+ let(:criteria) do
721
+ Band.desc(:name)
722
+ end
723
+
724
+ let(:context) do
725
+ described_class.new(criteria)
726
+ end
727
+
728
+ context "when there is sort on the context" do
729
+
730
+ it "follows the main sort" do
731
+ context.send(method).should eq(new_order)
732
+ end
733
+ end
734
+
735
+ context "when subsequently calling #last" do
736
+
737
+ it "returns the correnct document" do
738
+ context.send(method).should eq(new_order)
739
+ context.last.should eq(depeche_mode)
740
+ end
741
+ end
742
+ end
743
+
744
+ context "when using .sort" do
745
+
746
+ let(:criteria) do
747
+ Band.all.sort(:name => -1).criteria
748
+ end
749
+
750
+ let(:context) do
751
+ described_class.new(criteria)
752
+ end
753
+
754
+ context "when there is sort on the context" do
755
+
756
+ it "follows the main sort" do
757
+ context.send(method).should eq(new_order)
758
+ end
759
+ end
760
+
761
+ context "when subsequently calling #last" do
762
+
763
+ it "returns the correnct document" do
764
+ context.send(method).should eq(new_order)
765
+ context.last.should eq(depeche_mode)
766
+ end
767
+ end
768
+ end
769
+
770
+ context "when the context is cached" do
771
+
772
+ let(:criteria) do
773
+ Band.where(name: "Depeche Mode").cache
774
+ end
775
+
776
+ let(:context) do
777
+ described_class.new(criteria)
778
+ end
779
+
780
+ context "when the cache is loaded" do
781
+
782
+ before do
783
+ context.to_a
784
+ end
785
+
786
+ it "returns the first document without touching the database" do
787
+ context.should_receive(:query).never
788
+ context.send(method).should eq(depeche_mode)
789
+ end
790
+ end
791
+ end
792
+ end
793
+ end
794
+
795
+ describe "#initialize" do
796
+
797
+ let(:criteria) do
798
+ Band.where(name: "Depeche Mode").no_timeout
799
+ end
800
+
801
+ let(:context) do
802
+ described_class.new(criteria)
803
+ end
804
+
805
+ it "sets the criteria" do
806
+ context.criteria.should eq(criteria)
807
+ end
808
+
809
+ it "sets the klass" do
810
+ context.klass.should eq(Band)
811
+ end
812
+
813
+ it "sets the query" do
814
+ context.query.should be_a(Moped::Query)
815
+ end
816
+
817
+ it "sets the query selector" do
818
+ context.query.selector.should eq({ "name" => "Depeche Mode" })
819
+ end
820
+
821
+ it "sets timeout options" do
822
+ context.query.operation.flags.should eq([ :no_cursor_timeout ])
823
+ end
824
+ end
825
+
826
+ describe "#last" do
827
+
828
+ context "when no default scope" do
829
+
830
+ let!(:depeche_mode) do
831
+ Band.create(name: "Depeche Mode")
832
+ end
833
+
834
+ let!(:new_order) do
835
+ Band.create(name: "New Order")
836
+ end
837
+
838
+ let(:criteria) do
839
+ Band.all
840
+ end
841
+
842
+ let(:context) do
843
+ described_class.new(criteria)
844
+ end
845
+
846
+ it "returns the last matching document" do
847
+ context.last.should eq(new_order)
848
+ end
849
+ end
850
+
851
+ context "when default scope" do
852
+
853
+ let!(:palm) do
854
+ Tree.create(name: "Palm")
855
+ end
856
+
857
+ let!(:maple) do
858
+ Tree.create(name: "Maple")
859
+ end
860
+
861
+ let(:criteria) do
862
+ Tree.all
863
+ end
864
+
865
+ let(:context) do
866
+ described_class.new(criteria)
867
+ end
868
+
869
+ it "respects default scope" do
870
+ context.last.should eq(palm)
871
+ end
872
+ end
873
+
874
+ context "when subsequently calling #first" do
875
+
876
+ let!(:depeche_mode) do
877
+ Band.create(name: "Depeche Mode")
878
+ end
879
+
880
+ let!(:new_order) do
881
+ Band.create(name: "New Order")
882
+ end
883
+
884
+ let(:criteria) do
885
+ Band.asc(:name)
886
+ end
887
+
888
+ let(:context) do
889
+ described_class.new(criteria)
890
+ end
891
+
892
+ it "returns the correnct document" do
893
+ context.last.should eq(new_order)
894
+ context.first.should eq(depeche_mode)
895
+ end
896
+ end
897
+ end
898
+
899
+ [ :length, :size ].each do |method|
900
+
901
+ describe "##{method}" do
902
+
903
+ before do
904
+ Band.create(name: "Depeche Mode")
905
+ Band.create(name: "New Order")
906
+ end
907
+
908
+ context "when the criteria has a limit" do
909
+
910
+ let(:criteria) do
911
+ Band.limit(1)
912
+ end
913
+
914
+ let(:context) do
915
+ described_class.new(criteria)
916
+ end
917
+
918
+ it "returns the number of documents that match" do
919
+ context.send(method).should eq(2)
920
+ end
921
+
922
+ context "when calling more than once" do
923
+
924
+ before do
925
+ context.query.should_receive(:count).once.and_return(2)
926
+ end
927
+
928
+ it "returns the cached value for subsequent calls" do
929
+ 2.times { context.send(method).should eq(2) }
930
+ end
931
+ end
932
+
933
+ context "when the results have been iterated over" do
934
+
935
+ before do
936
+ context.entries
937
+ context.query.should_receive(:count).once.and_return(2)
938
+ end
939
+
940
+ it "returns the cached value for all calls" do
941
+ context.send(method).should eq(2)
942
+ end
943
+
944
+ context "when the results have been iterated over multiple times" do
945
+
946
+ before do
947
+ context.entries
948
+ end
949
+
950
+ it "resets the length on each full iteration" do
951
+ context.should have(2).items
952
+ end
953
+ end
954
+ end
955
+ end
956
+
957
+ context "when the criteria has no limit" do
958
+
959
+ let(:criteria) do
960
+ Band.where(name: "Depeche Mode")
961
+ end
962
+
963
+ let(:context) do
964
+ described_class.new(criteria)
965
+ end
966
+
967
+ it "returns the number of documents that match" do
968
+ context.send(method).should eq(1)
969
+ end
970
+
971
+ context "when calling more than once" do
972
+
973
+ before do
974
+ context.query.should_receive(:count).once.and_return(1)
975
+ end
976
+
977
+ it "returns the cached value for subsequent calls" do
978
+ 2.times { context.send(method).should eq(1) }
979
+ end
980
+ end
981
+
982
+ context "when the results have been iterated over" do
983
+
984
+ before do
985
+ context.entries
986
+ context.query.should_receive(:count).once.and_return(1)
987
+ end
988
+
989
+ it "returns the cached value for all calls" do
990
+ context.send(method).should eq(1)
991
+ end
992
+
993
+ context "when the results have been iterated over multiple times" do
994
+
995
+ before do
996
+ context.entries
997
+ end
998
+
999
+ it "resets the length on each full iteration" do
1000
+ context.should have(1).item
1001
+ end
1002
+ end
1003
+ end
1004
+ end
1005
+ end
1006
+ end
1007
+
1008
+ describe "#limit" do
1009
+
1010
+ let!(:depeche_mode) do
1011
+ Band.create(name: "Depeche Mode")
1012
+ end
1013
+
1014
+ let!(:new_order) do
1015
+ Band.create(name: "New Order")
1016
+ end
1017
+
1018
+ let(:criteria) do
1019
+ Band.all
1020
+ end
1021
+
1022
+ let(:context) do
1023
+ described_class.new(criteria)
1024
+ end
1025
+
1026
+ it "limits the results" do
1027
+ context.limit(1).entries.should eq([ depeche_mode ])
1028
+ end
1029
+ end
1030
+
1031
+ describe "#map" do
1032
+
1033
+ before do
1034
+ Band.create(name: "Depeche Mode")
1035
+ Band.create(name: "New Order")
1036
+ end
1037
+
1038
+ let(:criteria) do
1039
+ Band.all
1040
+ end
1041
+
1042
+ let(:context) do
1043
+ described_class.new(criteria)
1044
+ end
1045
+
1046
+ context "when passed the symbol field name" do
1047
+
1048
+ it "limits query to that field" do
1049
+ criteria.should_receive(:only).with(:name).and_call_original
1050
+ context.map(:name)
1051
+ end
1052
+
1053
+ it "performs mapping" do
1054
+ context.map(:name).should eq ["Depeche Mode", "New Order"]
1055
+ end
1056
+ end
1057
+
1058
+ context "when passed a block" do
1059
+
1060
+ it "performs mapping" do
1061
+ context.map(&:name).should eq ["Depeche Mode", "New Order"]
1062
+ end
1063
+ end
1064
+ end
1065
+
1066
+ describe "#map_reduce" do
1067
+
1068
+ let!(:depeche_mode) do
1069
+ Band.create(name: "Depeche Mode", likes: 200)
1070
+ end
1071
+
1072
+ let!(:tool) do
1073
+ Band.create(name: "Tool", likes: 100)
1074
+ end
1075
+
1076
+ let(:map) do
1077
+ %Q{
1078
+ function() {
1079
+ emit(this.name, { likes: this.likes });
1080
+ }}
1081
+ end
1082
+
1083
+ let(:reduce) do
1084
+ %Q{
1085
+ function(key, values) {
1086
+ var result = { likes: 0 };
1087
+ values.forEach(function(value) {
1088
+ result.likes += value.likes;
1089
+ });
1090
+ return result;
1091
+ }}
1092
+ end
1093
+
1094
+ context "when no selection is provided" do
1095
+
1096
+ let(:criteria) do
1097
+ Band.all
1098
+ end
1099
+
1100
+ let(:context) do
1101
+ described_class.new(criteria)
1102
+ end
1103
+
1104
+ let(:results) do
1105
+ context.map_reduce(map, reduce).out(inline: 1)
1106
+ end
1107
+
1108
+ it "returns the first aggregate result" do
1109
+ results.should include(
1110
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1111
+ )
1112
+ end
1113
+
1114
+ it "returns the second aggregate result" do
1115
+ results.should include(
1116
+ { "_id" => "Tool", "value" => { "likes" => 100 }}
1117
+ )
1118
+ end
1119
+
1120
+ it "returns the correct number of documents" do
1121
+ results.count.should eq(2)
1122
+ end
1123
+
1124
+ it "contains the entire raw results" do
1125
+ results["results"].should eq([
1126
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }},
1127
+ { "_id" => "Tool", "value" => { "likes" => 100 }}
1128
+ ])
1129
+ end
1130
+
1131
+ it "contains the execution time" do
1132
+ results.time.should_not be_nil
1133
+ end
1134
+
1135
+ it "contains the count statistics" do
1136
+ results["counts"].should eq({
1137
+ "input" => 2, "emit" => 2, "reduce" => 0, "output" => 2
1138
+ })
1139
+ end
1140
+
1141
+ it "contains the input count" do
1142
+ results.input.should eq(2)
1143
+ end
1144
+
1145
+ it "contains the emitted count" do
1146
+ results.emitted.should eq(2)
1147
+ end
1148
+
1149
+ it "contains the reduced count" do
1150
+ results.reduced.should eq(0)
1151
+ end
1152
+
1153
+ it "contains the output count" do
1154
+ results.output.should eq(2)
1155
+ end
1156
+ end
1157
+
1158
+ context "when selection is provided" do
1159
+
1160
+ let(:criteria) do
1161
+ Band.where(name: "Depeche Mode")
1162
+ end
1163
+
1164
+ let(:context) do
1165
+ described_class.new(criteria)
1166
+ end
1167
+
1168
+ let(:results) do
1169
+ context.map_reduce(map, reduce).out(inline: 1)
1170
+ end
1171
+
1172
+ it "includes the aggregate result" do
1173
+ results.should include(
1174
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1175
+ )
1176
+ end
1177
+
1178
+ it "returns the correct number of documents" do
1179
+ results.count.should eq(1)
1180
+ end
1181
+
1182
+ it "contains the entire raw results" do
1183
+ results["results"].should eq([
1184
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1185
+ ])
1186
+ end
1187
+
1188
+ it "contains the execution time" do
1189
+ results.time.should_not be_nil
1190
+ end
1191
+
1192
+ it "contains the count statistics" do
1193
+ results["counts"].should eq({
1194
+ "input" => 1, "emit" => 1, "reduce" => 0, "output" => 1
1195
+ })
1196
+ end
1197
+
1198
+ it "contains the input count" do
1199
+ results.input.should eq(1)
1200
+ end
1201
+
1202
+ it "contains the emitted count" do
1203
+ results.emitted.should eq(1)
1204
+ end
1205
+
1206
+ it "contains the reduced count" do
1207
+ results.reduced.should eq(0)
1208
+ end
1209
+
1210
+ it "contains the output count" do
1211
+ results.output.should eq(1)
1212
+ end
1213
+ end
1214
+
1215
+ context "when sorting is provided" do
1216
+
1217
+ before do
1218
+ Band.index(name: -1)
1219
+ Band.create_indexes
1220
+ end
1221
+
1222
+ let(:criteria) do
1223
+ Band.desc(:name)
1224
+ end
1225
+
1226
+ let(:context) do
1227
+ described_class.new(criteria)
1228
+ end
1229
+
1230
+ let(:results) do
1231
+ context.map_reduce(map, reduce).out(inline: 1)
1232
+ end
1233
+
1234
+ it "returns the first aggregate result" do
1235
+ results.should include(
1236
+ { "_id" => "Tool", "value" => { "likes" => 100 }}
1237
+ )
1238
+ end
1239
+
1240
+ it "returns the second aggregate result" do
1241
+ results.should include(
1242
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1243
+ )
1244
+ end
1245
+
1246
+ it "returns the correct number of documents" do
1247
+ results.count.should eq(2)
1248
+ end
1249
+
1250
+ it "contains the entire raw results" do
1251
+ results["results"].should eq([
1252
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }},
1253
+ { "_id" => "Tool", "value" => { "likes" => 100 }}
1254
+ ])
1255
+ end
1256
+ end
1257
+
1258
+ context "when limiting is provided" do
1259
+
1260
+ let(:criteria) do
1261
+ Band.limit(1)
1262
+ end
1263
+
1264
+ let(:context) do
1265
+ described_class.new(criteria)
1266
+ end
1267
+
1268
+ let(:results) do
1269
+ context.map_reduce(map, reduce).out(inline: 1)
1270
+ end
1271
+
1272
+ it "returns the first aggregate result" do
1273
+ results.should include(
1274
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1275
+ )
1276
+ end
1277
+
1278
+ it "returns the correct number of documents" do
1279
+ results.count.should eq(1)
1280
+ end
1281
+
1282
+ it "contains the entire raw results" do
1283
+ results["results"].should eq([
1284
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1285
+ ])
1286
+ end
1287
+ end
1288
+
1289
+ context "when the output is replace" do
1290
+
1291
+ let(:criteria) do
1292
+ Band.limit(1)
1293
+ end
1294
+
1295
+ let(:context) do
1296
+ described_class.new(criteria)
1297
+ end
1298
+
1299
+ let(:results) do
1300
+ context.map_reduce(map, reduce).out(replace: "mr-output")
1301
+ end
1302
+
1303
+ it "returns the correct number of documents" do
1304
+ results.count.should eq(1)
1305
+ end
1306
+
1307
+ it "contains the entire results" do
1308
+ results.should eq([
1309
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1310
+ ])
1311
+ end
1312
+ end
1313
+
1314
+ context "when the output is reduce" do
1315
+
1316
+ let(:criteria) do
1317
+ Band.limit(1)
1318
+ end
1319
+
1320
+ let(:context) do
1321
+ described_class.new(criteria)
1322
+ end
1323
+
1324
+ let(:results) do
1325
+ context.map_reduce(map, reduce).out(reduce: :mr_output)
1326
+ end
1327
+
1328
+ it "returns the correct number of documents" do
1329
+ results.count.should eq(1)
1330
+ end
1331
+
1332
+ it "contains the entire results" do
1333
+ results.should eq([
1334
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1335
+ ])
1336
+ end
1337
+ end
1338
+
1339
+ context "when the output is merge" do
1340
+
1341
+ let(:criteria) do
1342
+ Band.limit(1)
1343
+ end
1344
+
1345
+ let(:context) do
1346
+ described_class.new(criteria)
1347
+ end
1348
+
1349
+ let(:results) do
1350
+ context.map_reduce(map, reduce).out(merge: :mr_output)
1351
+ end
1352
+
1353
+ it "returns the correct number of documents" do
1354
+ results.count.should eq(1)
1355
+ end
1356
+
1357
+ it "contains the entire results" do
1358
+ results.should eq([
1359
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200 }}
1360
+ ])
1361
+ end
1362
+ end
1363
+
1364
+ context "when providing no output" do
1365
+
1366
+ let(:criteria) do
1367
+ Band.limit(1)
1368
+ end
1369
+
1370
+ let(:context) do
1371
+ described_class.new(criteria)
1372
+ end
1373
+
1374
+ let(:results) do
1375
+ context.map_reduce(map, reduce)
1376
+ end
1377
+
1378
+ it "raises an error" do
1379
+ expect {
1380
+ results.entries
1381
+ }.to raise_error(Mongoid::Errors::NoMapReduceOutput)
1382
+ end
1383
+ end
1384
+
1385
+ context "when providing a finalize" do
1386
+
1387
+ let(:criteria) do
1388
+ Band.limit(1)
1389
+ end
1390
+
1391
+ let(:context) do
1392
+ described_class.new(criteria)
1393
+ end
1394
+
1395
+ let(:finalize) do
1396
+ %Q{
1397
+ function(key, value) {
1398
+ value.extra = true;
1399
+ return value;
1400
+ }}
1401
+ end
1402
+
1403
+ let(:results) do
1404
+ context.map_reduce(map, reduce).out(inline: 1).finalize(finalize)
1405
+ end
1406
+
1407
+ it "returns the correct number of documents" do
1408
+ results.count.should eq(1)
1409
+ end
1410
+
1411
+ it "contains the entire results" do
1412
+ results.should eq([
1413
+ { "_id" => "Depeche Mode", "value" => { "likes" => 200, "extra" => true }}
1414
+ ])
1415
+ end
1416
+ end
1417
+ end
1418
+
1419
+ describe "#skip" do
1420
+
1421
+ let!(:depeche_mode) do
1422
+ Band.create(name: "Depeche Mode")
1423
+ end
1424
+
1425
+ let!(:new_order) do
1426
+ Band.create(name: "New Order")
1427
+ end
1428
+
1429
+ let(:criteria) do
1430
+ Band.all
1431
+ end
1432
+
1433
+ let(:context) do
1434
+ described_class.new(criteria)
1435
+ end
1436
+
1437
+ it "limits the results" do
1438
+ context.skip(1).entries.should eq([ new_order ])
1439
+ end
1440
+ end
1441
+
1442
+ describe "#sort" do
1443
+
1444
+ let!(:depeche_mode) do
1445
+ Band.create(name: "Depeche Mode")
1446
+ end
1447
+
1448
+ let!(:new_order) do
1449
+ Band.create(name: "New Order")
1450
+ end
1451
+
1452
+ let(:criteria) do
1453
+ Band.all
1454
+ end
1455
+
1456
+ let(:context) do
1457
+ described_class.new(criteria)
1458
+ end
1459
+
1460
+ context "when providing a spec" do
1461
+
1462
+ it "sorts the results" do
1463
+ context.sort(name: -1).entries.should eq([ new_order, depeche_mode ])
1464
+ end
1465
+
1466
+ it "returns the context" do
1467
+ context.sort(name: 1).should eq(context)
1468
+ end
1469
+ end
1470
+
1471
+ context "when providing a block" do
1472
+
1473
+ let(:sorted) do
1474
+ context.sort do |a, b|
1475
+ b.name <=> a.name
1476
+ end
1477
+ end
1478
+
1479
+ it "sorts the results in memory" do
1480
+ sorted.should eq([ new_order, depeche_mode ])
1481
+ end
1482
+ end
1483
+ end
1484
+
1485
+ describe "#update" do
1486
+
1487
+ let!(:depeche_mode) do
1488
+ Band.create(name: "Depeche Mode")
1489
+ end
1490
+
1491
+ let!(:new_order) do
1492
+ Band.create(name: "New Order")
1493
+ end
1494
+
1495
+ let(:criteria) do
1496
+ Band.all
1497
+ end
1498
+
1499
+ let(:context) do
1500
+ described_class.new(criteria)
1501
+ end
1502
+
1503
+ context "when providing attributes" do
1504
+
1505
+ context "when the attributes are of the correct type" do
1506
+
1507
+ before do
1508
+ context.update(name: "Smiths")
1509
+ end
1510
+
1511
+ it "updates only the first matching document" do
1512
+ depeche_mode.reload.name.should eq("Smiths")
1513
+ end
1514
+
1515
+ it "does not update the last matching document" do
1516
+ new_order.reload.name.should eq("New Order")
1517
+ end
1518
+ end
1519
+
1520
+ context "when the attributes must be mongoized" do
1521
+
1522
+ context "when coercing a string to integer" do
1523
+
1524
+ before do
1525
+ context.update(member_count: "1")
1526
+ end
1527
+
1528
+ it "updates the first matching document" do
1529
+ depeche_mode.reload.member_count.should eq(1)
1530
+ end
1531
+
1532
+ it "does not update the last matching document" do
1533
+ new_order.reload.member_count.should be_nil
1534
+ end
1535
+ end
1536
+
1537
+ context "when coercing a string to date" do
1538
+
1539
+ before do
1540
+ context.update(founded: "1979/1/1")
1541
+ end
1542
+
1543
+ it "updates the first matching document" do
1544
+ depeche_mode.reload.founded.should eq(Date.new(1979, 1, 1))
1545
+ end
1546
+
1547
+ it "does not update the last matching document" do
1548
+ new_order.reload.founded.should be_nil
1549
+ end
1550
+ end
1551
+ end
1552
+ end
1553
+
1554
+ context "when providing atomic operations" do
1555
+
1556
+ context "when only atomic operations are provided" do
1557
+
1558
+ context "when the attributes are in the correct type" do
1559
+
1560
+ before do
1561
+ context.update("$set" => { name: "Smiths" })
1562
+ end
1563
+
1564
+ it "updates the first matching document" do
1565
+ depeche_mode.reload.name.should eq("Smiths")
1566
+ end
1567
+
1568
+ it "does not update the last matching document" do
1569
+ new_order.reload.name.should eq("New Order")
1570
+ end
1571
+ end
1572
+
1573
+ context "when the attributes must be mongoized" do
1574
+
1575
+ before do
1576
+ context.update("$set" => { member_count: "1" })
1577
+ end
1578
+
1579
+ it "updates the first matching document" do
1580
+ depeche_mode.reload.member_count.should eq(1)
1581
+ end
1582
+
1583
+ it "does not update the last matching document" do
1584
+ new_order.reload.member_count.should be_nil
1585
+ end
1586
+ end
1587
+ end
1588
+
1589
+ context "when a mix are provided" do
1590
+
1591
+ before do
1592
+ context.update("$set" => { name: "Smiths" }, likes: 100)
1593
+ end
1594
+
1595
+ it "updates the first matching document's set" do
1596
+ depeche_mode.reload.name.should eq("Smiths")
1597
+ end
1598
+
1599
+ it "updates the first matching document's updates" do
1600
+ depeche_mode.reload.likes.should eq(100)
1601
+ end
1602
+
1603
+ it "does not update the last matching document's set" do
1604
+ new_order.reload.name.should eq("New Order")
1605
+ end
1606
+
1607
+ it "does not update the last matching document's updates" do
1608
+ new_order.reload.likes.should be_nil
1609
+ end
1610
+ end
1611
+ end
1612
+
1613
+ context "when providing no attributes" do
1614
+
1615
+ it "returns false" do
1616
+ context.update.should be_false
1617
+ end
1618
+ end
1619
+ end
1620
+
1621
+ describe "#update_all" do
1622
+
1623
+ let!(:depeche_mode) do
1624
+ Band.create(name: "Depeche Mode", origin: "Essex")
1625
+ end
1626
+
1627
+ let!(:new_order) do
1628
+ Band.create(name: "New Order")
1629
+ end
1630
+
1631
+ let(:criteria) do
1632
+ Band.all
1633
+ end
1634
+
1635
+ let(:context) do
1636
+ described_class.new(criteria)
1637
+ end
1638
+
1639
+ context "when providing attributes" do
1640
+
1641
+ context "when the attributes are of the correct type" do
1642
+
1643
+ before do
1644
+ context.update_all(name: "Smiths")
1645
+ end
1646
+
1647
+ it "updates the first matching document" do
1648
+ depeche_mode.reload.name.should eq("Smiths")
1649
+ end
1650
+
1651
+ it "does not clear out other attributes" do
1652
+ depeche_mode.reload.origin.should eq("Essex")
1653
+ end
1654
+
1655
+ it "updates the last matching document" do
1656
+ new_order.reload.name.should eq("Smiths")
1657
+ end
1658
+ end
1659
+
1660
+ context "when the attributes must be mongoized" do
1661
+
1662
+ before do
1663
+ context.update_all(member_count: "1")
1664
+ end
1665
+
1666
+ it "updates the first matching document" do
1667
+ depeche_mode.reload.member_count.should eq(1)
1668
+ end
1669
+
1670
+ it "updates the last matching document" do
1671
+ new_order.reload.member_count.should eq(1)
1672
+ end
1673
+ end
1674
+
1675
+ context "when using aliased field names" do
1676
+
1677
+ before do
1678
+ context.update_all(years: 100)
1679
+ end
1680
+
1681
+ it "updates the first matching document" do
1682
+ depeche_mode.reload.years.should eq(100)
1683
+ end
1684
+
1685
+ it "updates the last matching document" do
1686
+ new_order.reload.years.should eq(100)
1687
+ end
1688
+ end
1689
+ end
1690
+
1691
+ context "when providing atomic operations" do
1692
+
1693
+ context "when only atomic operations are provided" do
1694
+
1695
+ context "when the attributes are in the correct type" do
1696
+
1697
+ before do
1698
+ context.update_all("$set" => { name: "Smiths" })
1699
+ end
1700
+
1701
+ it "updates the first matching document" do
1702
+ depeche_mode.reload.name.should eq("Smiths")
1703
+ end
1704
+
1705
+ it "updates the last matching document" do
1706
+ new_order.reload.name.should eq("Smiths")
1707
+ end
1708
+ end
1709
+
1710
+ context "when the attributes must be mongoized" do
1711
+
1712
+ before do
1713
+ context.update_all("$set" => { member_count: "1" })
1714
+ end
1715
+
1716
+ it "updates the first matching document" do
1717
+ depeche_mode.reload.member_count.should eq(1)
1718
+ end
1719
+
1720
+ it "updates the last matching document" do
1721
+ new_order.reload.member_count.should eq(1)
1722
+ end
1723
+ end
1724
+ end
1725
+
1726
+ context "when a mix are provided" do
1727
+
1728
+ before do
1729
+ context.update_all("$set" => { name: "Smiths" }, likes: 100)
1730
+ end
1731
+
1732
+ it "updates the first matching document's set" do
1733
+ depeche_mode.reload.name.should eq("Smiths")
1734
+ end
1735
+
1736
+ it "updates the first matching document's updates" do
1737
+ depeche_mode.reload.likes.should eq(100)
1738
+ end
1739
+
1740
+ it "updates the last matching document's set" do
1741
+ new_order.reload.name.should eq("Smiths")
1742
+ end
1743
+
1744
+ it "updates the last matching document's updates" do
1745
+ new_order.reload.likes.should eq(100)
1746
+ end
1747
+ end
1748
+ end
1749
+
1750
+ context "when providing no attributes" do
1751
+
1752
+ it "returns false" do
1753
+ context.update_all.should be_false
1754
+ end
1755
+ end
1756
+ end
1757
+ end