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,2399 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Validations::UniquenessValidator do
4
+
5
+ describe "#valid?" do
6
+
7
+ context "when the document is a root document" do
8
+
9
+ context "when adding custom persistence options" do
10
+
11
+ before do
12
+ Dictionary.validates_uniqueness_of :name
13
+ end
14
+
15
+ after do
16
+ Dictionary.reset_callbacks(:validate)
17
+ end
18
+
19
+ context "when persisting to another collection" do
20
+
21
+ before do
22
+ Dictionary.with(collection: "dicts").create(name: "websters")
23
+ end
24
+
25
+ context "when the document is not valid" do
26
+
27
+ let(:websters) do
28
+ Dictionary.with(collection: "dicts").new(name: "websters")
29
+ end
30
+
31
+ it "performs the validation on the correct collection" do
32
+ websters.should_not be_valid
33
+ end
34
+
35
+ it "adds the uniqueness error" do
36
+ websters.valid?
37
+ websters.errors[:name].should_not be_nil
38
+ end
39
+
40
+ it "clears the persistence options in the thread local" do
41
+ websters.valid?
42
+ Dictionary.persistence_options.should be_nil
43
+ end
44
+ end
45
+
46
+ context "when the document is valid" do
47
+
48
+ let(:oxford) do
49
+ Dictionary.with(collection: "dicts").new(name: "oxford")
50
+ end
51
+
52
+ it "performs the validation on the correct collection" do
53
+ oxford.should be_valid
54
+ end
55
+
56
+ it "does not clear the persistence options in the thread local" do
57
+ oxford.valid?
58
+ Dictionary.persistence_options.should_not be_nil
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ context "when the document is paranoid" do
65
+
66
+ before do
67
+ ParanoidPost.validates_uniqueness_of :title
68
+ end
69
+
70
+ after do
71
+ ParanoidPost.reset_callbacks(:validate)
72
+ end
73
+
74
+ let!(:post) do
75
+ ParanoidPost.create(title: "testing")
76
+ end
77
+
78
+ context "when the field is unique" do
79
+
80
+ let(:new_post) do
81
+ ParanoidPost.new(title: "test")
82
+ end
83
+
84
+ it "returns true" do
85
+ new_post.should be_valid
86
+ end
87
+ end
88
+
89
+ context "when the field is unique for non soft deleted docs" do
90
+
91
+ before do
92
+ post.delete
93
+ end
94
+
95
+ let(:new_post) do
96
+ ParanoidPost.new(title: "testing")
97
+ end
98
+
99
+ it "returns true" do
100
+ new_post.should be_valid
101
+ end
102
+ end
103
+
104
+ context "when the field is not unique" do
105
+
106
+ let(:new_post) do
107
+ ParanoidPost.new(title: "testing")
108
+ end
109
+
110
+ it "returns false" do
111
+ new_post.should_not be_valid
112
+ end
113
+ end
114
+ end
115
+
116
+ context "when the document contains no compound key" do
117
+
118
+ context "when validating a relation" do
119
+
120
+ before do
121
+ Word.validates_uniqueness_of :dictionary
122
+ end
123
+
124
+ after do
125
+ Word.reset_callbacks(:validate)
126
+ end
127
+
128
+ context "when the attribute id is unique" do
129
+
130
+ let(:dictionary) do
131
+ Dictionary.create
132
+ end
133
+
134
+ let(:word) do
135
+ Word.new(dictionary: dictionary)
136
+ end
137
+
138
+ it "returns true" do
139
+ word.should be_valid
140
+ end
141
+ end
142
+ end
143
+
144
+ context "when the field name is aliased" do
145
+
146
+ before do
147
+ Dictionary.create!(language: "en")
148
+ end
149
+
150
+ let(:dictionary) do
151
+ Dictionary.new(language: "en")
152
+ end
153
+
154
+ after do
155
+ Dictionary.reset_callbacks(:validate)
156
+ end
157
+
158
+ context "when the validation uses the aliased name" do
159
+
160
+ before do
161
+ Dictionary.validates_uniqueness_of :language
162
+ end
163
+
164
+ it "correctly detects a uniqueness conflict" do
165
+ expect(dictionary).to_not be_valid
166
+ end
167
+
168
+ it "adds the uniqueness error to the aliased field name" do
169
+ dictionary.valid?
170
+ expect(dictionary.errors).to have_key(:language)
171
+ expect(dictionary.errors[:language]).to eq([ "is already taken" ])
172
+ end
173
+ end
174
+
175
+ context "when the validation uses the underlying field name" do
176
+
177
+ before do
178
+ Dictionary.validates_uniqueness_of :l
179
+ end
180
+
181
+ it "correctly detects a uniqueness conflict" do
182
+ expect(dictionary).to_not be_valid
183
+ end
184
+
185
+ it "adds the uniqueness error to the underlying field name" do
186
+ dictionary.valid?
187
+ expect(dictionary.errors).to have_key(:l)
188
+ expect(dictionary.errors[:l]).to eq([ "is already taken" ])
189
+ end
190
+ end
191
+ end
192
+
193
+ context "when the field is localized" do
194
+
195
+ context "when no scope is provided" do
196
+
197
+ context "when case sensitive is true" do
198
+
199
+ before do
200
+ Dictionary.validates_uniqueness_of :description
201
+ end
202
+
203
+ after do
204
+ Dictionary.reset_callbacks(:validate)
205
+ end
206
+
207
+ context "when the attribute is unique" do
208
+
209
+ context "when single localization" do
210
+
211
+ before do
212
+ Dictionary.with(safe: true).create(description: "english")
213
+ end
214
+
215
+ let(:dictionary) do
216
+ Dictionary.new(description: "English")
217
+ end
218
+
219
+ it "returns true" do
220
+ expect(dictionary).to be_valid
221
+ end
222
+ end
223
+
224
+ context "when multiple localizations" do
225
+
226
+ before do
227
+ Dictionary.with(safe: true).
228
+ create(description_translations: { "en" => "english", "de" => "german" })
229
+ end
230
+
231
+ let(:dictionary) do
232
+ Dictionary.new(description_translations: { "en" => "English", "de" => "German" })
233
+ end
234
+
235
+ it "returns true" do
236
+ expect(dictionary).to be_valid
237
+ end
238
+ end
239
+ end
240
+
241
+ context "when the attribute is not unique" do
242
+
243
+ context "when the document is not the match" do
244
+
245
+ context "when single localization" do
246
+
247
+ before do
248
+ Dictionary.with(safe: true).create(description: "english")
249
+ end
250
+
251
+ let(:dictionary) do
252
+ Dictionary.new(description: "english")
253
+ end
254
+
255
+ it "returns false" do
256
+ expect(dictionary).to_not be_valid
257
+ end
258
+
259
+ it "adds the uniqueness error" do
260
+ dictionary.valid?
261
+ expect(dictionary.errors[:description]).to eq([ "is already taken" ])
262
+ end
263
+ end
264
+
265
+ context "when multiple localizations" do
266
+
267
+ before do
268
+ Dictionary.with(safe: true).
269
+ create(description_translations: { "en" => "english", "de" => "german" })
270
+ end
271
+
272
+ let(:dictionary) do
273
+ Dictionary.new(description_translations: { "en" => "english", "de" => "German" })
274
+ end
275
+
276
+ it "returns false" do
277
+ expect(dictionary).to_not be_valid
278
+ end
279
+
280
+ it "adds the uniqueness error" do
281
+ dictionary.valid?
282
+ expect(dictionary.errors[:description]).to eq([ "is already taken" ])
283
+ end
284
+ end
285
+ end
286
+ end
287
+ end
288
+
289
+ context "when case sensitive is false" do
290
+
291
+ before do
292
+ Dictionary.validates_uniqueness_of :description, case_sensitive: false
293
+ end
294
+
295
+ after do
296
+ Dictionary.reset_callbacks(:validate)
297
+ end
298
+
299
+ context "when the attribute is unique" do
300
+
301
+ context "when there are no special characters" do
302
+
303
+ before do
304
+ Dictionary.with(safe: true).create(description: "english")
305
+ end
306
+
307
+ let(:dictionary) do
308
+ Dictionary.new(description: "german")
309
+ end
310
+
311
+ it "returns true" do
312
+ expect(dictionary).to be_valid
313
+ end
314
+ end
315
+
316
+ context "when special characters exist" do
317
+
318
+ before do
319
+ Dictionary.with(safe: true).create(description: "english")
320
+ end
321
+
322
+ let(:dictionary) do
323
+ Dictionary.new(description: "en@gl.ish")
324
+ end
325
+
326
+ it "returns true" do
327
+ expect(dictionary).to be_valid
328
+ end
329
+ end
330
+ end
331
+
332
+ context "when the attribute is not unique" do
333
+
334
+ context "when the document is not the match" do
335
+
336
+ context "when signle localization" do
337
+
338
+ before do
339
+ Dictionary.with(safe: true).create(description: "english")
340
+ end
341
+
342
+ let(:dictionary) do
343
+ Dictionary.new(description: "English")
344
+ end
345
+
346
+ it "returns false" do
347
+ expect(dictionary).to_not be_valid
348
+ end
349
+
350
+ it "adds the uniqueness error" do
351
+ dictionary.valid?
352
+ expect(dictionary.errors[:description]).to eq([ "is already taken" ])
353
+ end
354
+ end
355
+
356
+ context "when multiple localizations" do
357
+
358
+ before do
359
+ Dictionary.with(safe: true).
360
+ create(description_translations: { "en" => "english", "de" => "german" })
361
+ end
362
+
363
+ let(:dictionary) do
364
+ Dictionary.new(description_translations: { "en" => "English", "de" => "German" })
365
+ end
366
+
367
+ it "returns false" do
368
+ expect(dictionary).to_not be_valid
369
+ end
370
+
371
+ it "adds the uniqueness error" do
372
+ dictionary.valid?
373
+ expect(dictionary.errors[:description]).to eq([ "is already taken" ])
374
+ end
375
+ end
376
+ end
377
+
378
+ context "when the document is the match in the database" do
379
+
380
+ let!(:dictionary) do
381
+ Dictionary.with(safe: true).create(description: "english")
382
+ end
383
+
384
+ it "returns true" do
385
+ expect(dictionary).to be_valid
386
+ end
387
+ end
388
+ end
389
+ end
390
+ end
391
+
392
+ context "when a scope is provided" do
393
+
394
+ before do
395
+ Dictionary.validates_uniqueness_of :description, scope: :name
396
+ end
397
+
398
+ after do
399
+ Dictionary.reset_callbacks(:validate)
400
+ end
401
+
402
+ context "when the attribute is not unique in the scope" do
403
+
404
+ context "when the document is not the match" do
405
+
406
+ before do
407
+ Dictionary.with(safe: true).
408
+ create(description: "english", name: "test")
409
+ end
410
+
411
+ let(:dictionary) do
412
+ Dictionary.new(description: "english", name: "test")
413
+ end
414
+
415
+ it "returns false" do
416
+ dictionary.should_not be_valid
417
+ end
418
+
419
+ it "adds the uniqueness error" do
420
+ dictionary.valid?
421
+ dictionary.errors[:description].should eq([ "is already taken" ])
422
+ end
423
+ end
424
+ end
425
+ end
426
+ end
427
+
428
+ context "when no scope is provided" do
429
+
430
+ before do
431
+ Dictionary.validates_uniqueness_of :name
432
+ end
433
+
434
+ after do
435
+ Dictionary.reset_callbacks(:validate)
436
+ end
437
+
438
+ context "when the attribute is unique" do
439
+
440
+ let!(:oxford) do
441
+ Dictionary.create(name: "Oxford")
442
+ end
443
+
444
+ let(:dictionary) do
445
+ Dictionary.new(name: "Webster")
446
+ end
447
+
448
+ it "returns true" do
449
+ dictionary.should be_valid
450
+ end
451
+
452
+ context "when subsequently cloning the document" do
453
+
454
+ let(:clone) do
455
+ oxford.clone
456
+ end
457
+
458
+ it "returns false for the clone" do
459
+ clone.should_not be_valid
460
+ end
461
+ end
462
+ end
463
+
464
+ context "when the attribute is not unique" do
465
+
466
+ context "when the document is not the match" do
467
+
468
+ before do
469
+ Dictionary.create(name: "Oxford")
470
+ end
471
+
472
+ let!(:dictionary) do
473
+ Dictionary.new(name: "Oxford")
474
+ end
475
+
476
+ it "returns false" do
477
+ dictionary.should_not be_valid
478
+ end
479
+
480
+ it "adds the uniqueness error" do
481
+ dictionary.valid?
482
+ dictionary.errors[:name].should eq([ "is already taken" ])
483
+ end
484
+ end
485
+
486
+ context "when the document is the match in the database" do
487
+
488
+ context "when the field has changed" do
489
+
490
+ let!(:dictionary) do
491
+ Dictionary.create(name: "Oxford")
492
+ end
493
+
494
+ it "returns true" do
495
+ dictionary.should be_valid
496
+ end
497
+ end
498
+
499
+ context "when the field has not changed" do
500
+
501
+ before do
502
+ Dictionary.default_scoping = nil
503
+ end
504
+
505
+ let!(:dictionary) do
506
+ Dictionary.create!(name: "Oxford")
507
+ end
508
+
509
+ let!(:from_db) do
510
+ Dictionary.find(dictionary.id)
511
+ end
512
+
513
+ it "returns true" do
514
+ from_db.should be_valid
515
+ end
516
+
517
+ it "does not touch the database" do
518
+ Dictionary.should_receive(:where).never
519
+ from_db.valid?
520
+ end
521
+ end
522
+ end
523
+ end
524
+ end
525
+
526
+ context "when a default scope is on the model" do
527
+
528
+ before do
529
+ Dictionary.validates_uniqueness_of :name
530
+ Dictionary.default_scope(Dictionary.where(year: 1990))
531
+ end
532
+
533
+ after do
534
+ Dictionary.send(:strip_default_scope, Dictionary.where(year: 1990))
535
+ Dictionary.reset_callbacks(:validate)
536
+ end
537
+
538
+ context "when the document with the unqiue attribute is not in default scope" do
539
+
540
+ context "when the attribute is not unique" do
541
+
542
+ before do
543
+ Dictionary.with(safe: true).create(name: "Oxford")
544
+ end
545
+
546
+ let(:dictionary) do
547
+ Dictionary.new(name: "Oxford")
548
+ end
549
+
550
+ it "returns false" do
551
+ dictionary.should_not be_valid
552
+ end
553
+ end
554
+ end
555
+ end
556
+
557
+ context "when an aliased scope is provided" do
558
+
559
+ before do
560
+ Dictionary.validates_uniqueness_of :name, scope: :language
561
+ end
562
+
563
+ after do
564
+ Dictionary.reset_callbacks(:validate)
565
+ end
566
+
567
+ context "when the attribute is unique" do
568
+
569
+ before do
570
+ Dictionary.create(name: "Oxford", language: "English")
571
+ end
572
+
573
+ let(:dictionary) do
574
+ Dictionary.new(name: "Webster")
575
+ end
576
+
577
+ it "returns true" do
578
+ dictionary.should be_valid
579
+ end
580
+ end
581
+
582
+ context "when the attribute is unique in the scope" do
583
+
584
+ before do
585
+ Dictionary.create(name: "Oxford", language: "English")
586
+ end
587
+
588
+ let(:dictionary) do
589
+ Dictionary.new(name: "Webster", language: "English")
590
+ end
591
+
592
+ it "returns true" do
593
+ dictionary.should be_valid
594
+ end
595
+ end
596
+
597
+ context "when the attribute is not unique with no scope" do
598
+
599
+ before do
600
+ Dictionary.create(name: "Oxford", language: "English")
601
+ end
602
+
603
+ let(:dictionary) do
604
+ Dictionary.new(name: "Oxford")
605
+ end
606
+
607
+ it "returns true" do
608
+ dictionary.should be_valid
609
+ end
610
+ end
611
+
612
+ context "when the attribute is not unique in another scope" do
613
+
614
+ before do
615
+ Dictionary.create(name: "Oxford", language: "English")
616
+ end
617
+
618
+ let(:dictionary) do
619
+ Dictionary.new(name: "Oxford", language: "Deutsch")
620
+ end
621
+
622
+ it "returns true" do
623
+ dictionary.should be_valid
624
+ end
625
+ end
626
+
627
+ context "when the attribute is not unique in the same scope" do
628
+
629
+ context "when the document is not the match" do
630
+
631
+ before do
632
+ Dictionary.create(name: "Oxford", language: "English")
633
+ end
634
+
635
+ let(:dictionary) do
636
+ Dictionary.new(name: "Oxford", language: "English")
637
+ end
638
+
639
+ it "returns false" do
640
+ dictionary.should_not be_valid
641
+ end
642
+
643
+ it "adds the uniqueness errors" do
644
+ dictionary.valid?
645
+ dictionary.errors[:name].should eq([ "is already taken" ])
646
+ end
647
+ end
648
+
649
+ context "when the document is the match in the database" do
650
+
651
+ let!(:dictionary) do
652
+ Dictionary.create(name: "Oxford", language: "English")
653
+ end
654
+
655
+ it "returns true" do
656
+ dictionary.should be_valid
657
+ end
658
+ end
659
+ end
660
+ end
661
+
662
+ context "when a single scope is provided" do
663
+
664
+ before do
665
+ Dictionary.validates_uniqueness_of :name, scope: :publisher
666
+ end
667
+
668
+ after do
669
+ Dictionary.reset_callbacks(:validate)
670
+ end
671
+
672
+ context "when the attribute is unique" do
673
+
674
+ before do
675
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
676
+ end
677
+
678
+ let(:dictionary) do
679
+ Dictionary.new(name: "Webster")
680
+ end
681
+
682
+ it "returns true" do
683
+ dictionary.should be_valid
684
+ end
685
+ end
686
+
687
+ context "when the attribute is unique in the scope" do
688
+
689
+ before do
690
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
691
+ end
692
+
693
+ let(:dictionary) do
694
+ Dictionary.new(name: "Webster", publisher: "Amazon")
695
+ end
696
+
697
+ it "returns true" do
698
+ dictionary.should be_valid
699
+ end
700
+ end
701
+
702
+ context "when uniqueness is violated due to scope change" do
703
+
704
+ let(:personal_folder) do
705
+ Folder.create!(name: "Personal")
706
+ end
707
+
708
+ let(:public_folder) do
709
+ Folder.create!(name: "Public")
710
+ end
711
+
712
+ before do
713
+ personal_folder.folder_items << FolderItem.new(name: "non-unique")
714
+ public_folder.folder_items << FolderItem.new(name: "non-unique")
715
+ end
716
+
717
+ let(:item) do
718
+ public_folder.folder_items.last
719
+ end
720
+
721
+ it "should set an error for associated object not being unique" do
722
+ item.update_attributes(folder_id: personal_folder.id)
723
+ item.errors.messages[:name].first.should eq("is already taken")
724
+ end
725
+ end
726
+
727
+ context "when the attribute is not unique with no scope" do
728
+
729
+ before do
730
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
731
+ end
732
+
733
+ let(:dictionary) do
734
+ Dictionary.new(name: "Oxford")
735
+ end
736
+
737
+ it "returns true" do
738
+ dictionary.should be_valid
739
+ end
740
+ end
741
+
742
+ context "when the attribute is not unique in another scope" do
743
+
744
+ before do
745
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
746
+ end
747
+
748
+ let(:dictionary) do
749
+ Dictionary.new(name: "Oxford", publisher: "Addison")
750
+ end
751
+
752
+ it "returns true" do
753
+ dictionary.should be_valid
754
+ end
755
+ end
756
+
757
+ context "when the attribute is not unique in the same scope" do
758
+
759
+ context "when the document is not the match" do
760
+
761
+ before do
762
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
763
+ end
764
+
765
+ let(:dictionary) do
766
+ Dictionary.new(name: "Oxford", publisher: "Amazon")
767
+ end
768
+
769
+ it "returns false" do
770
+ dictionary.should_not be_valid
771
+ end
772
+
773
+ it "adds the uniqueness errors" do
774
+ dictionary.valid?
775
+ dictionary.errors[:name].should eq([ "is already taken" ])
776
+ end
777
+ end
778
+
779
+ context "when the document is the match in the database" do
780
+
781
+ let!(:dictionary) do
782
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
783
+ end
784
+
785
+ it "returns true" do
786
+ dictionary.should be_valid
787
+ end
788
+ end
789
+
790
+ context "when one of the scopes is a time" do
791
+
792
+ before do
793
+ Dictionary.create(
794
+ name: "Oxford",
795
+ publisher: "Amazon",
796
+ published: 10.days.ago.to_time
797
+ )
798
+ end
799
+
800
+ let(:dictionary) do
801
+ Dictionary.new(
802
+ name: "Oxford",
803
+ publisher: "Amazon",
804
+ published: 10.days.ago.to_time
805
+ )
806
+ end
807
+
808
+ it "returns false" do
809
+ dictionary.should_not be_valid
810
+ end
811
+
812
+ it "adds the uniqueness errors" do
813
+ dictionary.valid?
814
+ dictionary.errors[:name].should eq([ "is already taken" ])
815
+ end
816
+ end
817
+ end
818
+ end
819
+
820
+ context "when multiple scopes are provided" do
821
+
822
+ before do
823
+ Dictionary.validates_uniqueness_of :name, scope: [ :publisher, :year ]
824
+ end
825
+
826
+ after do
827
+ Dictionary.reset_callbacks(:validate)
828
+ end
829
+
830
+ context "when the attribute is unique" do
831
+
832
+ before do
833
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
834
+ end
835
+
836
+ let(:dictionary) do
837
+ Dictionary.new(name: "Webster")
838
+ end
839
+
840
+ it "returns true" do
841
+ dictionary.should be_valid
842
+ end
843
+ end
844
+
845
+ context "when the attribute is unique in the scope" do
846
+
847
+ before do
848
+ Dictionary.create(
849
+ name: "Oxford",
850
+ publisher: "Amazon",
851
+ year: 2011
852
+ )
853
+ end
854
+
855
+ let(:dictionary) do
856
+ Dictionary.new(
857
+ name: "Webster",
858
+ publisher: "Amazon",
859
+ year: 2011
860
+ )
861
+ end
862
+
863
+ it "returns true" do
864
+ dictionary.should be_valid
865
+ end
866
+ end
867
+
868
+ context "when the attribute is not unique with no scope" do
869
+
870
+ before do
871
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
872
+ end
873
+
874
+ let(:dictionary) do
875
+ Dictionary.new(name: "Oxford")
876
+ end
877
+
878
+ it "returns true" do
879
+ dictionary.should be_valid
880
+ end
881
+ end
882
+
883
+ context "when the attribute is not unique in another scope" do
884
+
885
+ before do
886
+ Dictionary.create(
887
+ name: "Oxford",
888
+ publisher: "Amazon",
889
+ year: 1995
890
+ )
891
+ end
892
+
893
+ let(:dictionary) do
894
+ Dictionary.new(
895
+ name: "Oxford",
896
+ publisher: "Addison",
897
+ year: 2011
898
+ )
899
+ end
900
+
901
+ it "returns true" do
902
+ dictionary.should be_valid
903
+ end
904
+ end
905
+
906
+ context "when the attribute is not unique in the same scope" do
907
+
908
+ context "when the document is not the match" do
909
+
910
+ before do
911
+ Dictionary.create(
912
+ name: "Oxford",
913
+ publisher: "Amazon",
914
+ year: 1960
915
+ )
916
+ end
917
+
918
+ let(:dictionary) do
919
+ Dictionary.new(
920
+ name: "Oxford",
921
+ publisher: "Amazon",
922
+ year: 1960
923
+ )
924
+ end
925
+
926
+ it "returns false" do
927
+ dictionary.should_not be_valid
928
+ end
929
+
930
+ it "adds the uniqueness errors" do
931
+ dictionary.valid?
932
+ dictionary.errors[:name].should eq([ "is already taken" ])
933
+ end
934
+ end
935
+
936
+ context "when the document is the match in the database" do
937
+
938
+ let!(:dictionary) do
939
+ Dictionary.create(
940
+ name: "Oxford",
941
+ publisher: "Amazon",
942
+ year: 1960
943
+ )
944
+ end
945
+
946
+ it "returns true" do
947
+ dictionary.should be_valid
948
+ end
949
+ end
950
+ end
951
+ end
952
+
953
+ context "when case sensitive is true" do
954
+
955
+ before do
956
+ Dictionary.validates_uniqueness_of :name
957
+ end
958
+
959
+ after do
960
+ Dictionary.reset_callbacks(:validate)
961
+ end
962
+
963
+ context "when the attribute is unique" do
964
+
965
+ before do
966
+ Dictionary.create(name: "Oxford")
967
+ end
968
+
969
+ let(:dictionary) do
970
+ Dictionary.new(name: "Webster")
971
+ end
972
+
973
+ it "returns true" do
974
+ dictionary.should be_valid
975
+ end
976
+ end
977
+
978
+ context "when the attribute is not unique" do
979
+
980
+ context "when the document is not the match" do
981
+
982
+ before do
983
+ Dictionary.create(name: "Oxford")
984
+ end
985
+
986
+ let(:dictionary) do
987
+ Dictionary.new(name: "Oxford")
988
+ end
989
+
990
+ it "returns false" do
991
+ dictionary.should_not be_valid
992
+ end
993
+
994
+ it "adds the uniqueness error" do
995
+ dictionary.valid?
996
+ dictionary.errors[:name].should eq([ "is already taken" ])
997
+ end
998
+ end
999
+
1000
+ context "when the document is the match in the database" do
1001
+
1002
+ let!(:dictionary) do
1003
+ Dictionary.create(name: "Oxford")
1004
+ end
1005
+
1006
+ it "returns true" do
1007
+ dictionary.should be_valid
1008
+ end
1009
+ end
1010
+ end
1011
+ end
1012
+
1013
+ context "when case sensitive is false" do
1014
+
1015
+ before do
1016
+ Dictionary.validates_uniqueness_of :name, case_sensitive: false
1017
+ end
1018
+
1019
+ after do
1020
+ Dictionary.reset_callbacks(:validate)
1021
+ end
1022
+
1023
+ context "when the attribute is unique" do
1024
+
1025
+ context "when there are no special characters" do
1026
+
1027
+ before do
1028
+ Dictionary.create(name: "Oxford")
1029
+ end
1030
+
1031
+ let(:dictionary) do
1032
+ Dictionary.new(name: "Webster")
1033
+ end
1034
+
1035
+ it "returns true" do
1036
+ dictionary.should be_valid
1037
+ end
1038
+ end
1039
+
1040
+ context "when special characters exist" do
1041
+
1042
+ before do
1043
+ Dictionary.create(name: "Oxford")
1044
+ end
1045
+
1046
+ let(:dictionary) do
1047
+ Dictionary.new(name: "Web@st.er")
1048
+ end
1049
+
1050
+ it "returns true" do
1051
+ dictionary.should be_valid
1052
+ end
1053
+ end
1054
+ end
1055
+
1056
+ context "when the attribute is not unique" do
1057
+
1058
+ context "when the document is not the match" do
1059
+
1060
+ before do
1061
+ Dictionary.create(name: "Oxford")
1062
+ end
1063
+
1064
+ let(:dictionary) do
1065
+ Dictionary.new(name: "oxford")
1066
+ end
1067
+
1068
+ it "returns false" do
1069
+ dictionary.should_not be_valid
1070
+ end
1071
+
1072
+ it "adds the uniqueness error" do
1073
+ dictionary.valid?
1074
+ dictionary.errors[:name].should eq([ "is already taken" ])
1075
+ end
1076
+ end
1077
+
1078
+ context "when the document is the match in the database" do
1079
+
1080
+ let!(:dictionary) do
1081
+ Dictionary.create(name: "Oxford")
1082
+ end
1083
+
1084
+ it "returns true" do
1085
+ dictionary.should be_valid
1086
+ end
1087
+ end
1088
+ end
1089
+ end
1090
+
1091
+ context "when allowing nil" do
1092
+
1093
+ before do
1094
+ Dictionary.validates_uniqueness_of :name, allow_nil: true
1095
+ end
1096
+
1097
+ after do
1098
+ Dictionary.reset_callbacks(:validate)
1099
+ end
1100
+
1101
+ context "when the attribute is nil" do
1102
+
1103
+ before do
1104
+ Dictionary.create
1105
+ end
1106
+
1107
+ let(:dictionary) do
1108
+ Dictionary.new
1109
+ end
1110
+
1111
+ it "returns true" do
1112
+ dictionary.should be_valid
1113
+ end
1114
+ end
1115
+ end
1116
+
1117
+ context "when allowing blank" do
1118
+
1119
+ before do
1120
+ Dictionary.validates_uniqueness_of :name, allow_blank: true
1121
+ end
1122
+
1123
+ after do
1124
+ Dictionary.reset_callbacks(:validate)
1125
+ end
1126
+
1127
+ context "when the attribute is blank" do
1128
+
1129
+ before do
1130
+ Dictionary.create(name: "")
1131
+ end
1132
+
1133
+ let(:dictionary) do
1134
+ Dictionary.new(name: "")
1135
+ end
1136
+
1137
+ it "returns true" do
1138
+ dictionary.should be_valid
1139
+ end
1140
+ end
1141
+ end
1142
+ end
1143
+
1144
+ context "when the document contains a compound key" do
1145
+
1146
+ context "when no scope is provided" do
1147
+
1148
+ before do
1149
+ Login.validates_uniqueness_of :username
1150
+ end
1151
+
1152
+ after do
1153
+ Login.reset_callbacks(:validate)
1154
+ end
1155
+
1156
+ context "when the attribute is unique" do
1157
+
1158
+ before do
1159
+ Login.create(username: "Oxford")
1160
+ end
1161
+
1162
+ let(:login) do
1163
+ Login.new(username: "Webster")
1164
+ end
1165
+
1166
+ it "returns true" do
1167
+ login.should be_valid
1168
+ end
1169
+ end
1170
+
1171
+ context "when the attribute is not unique" do
1172
+
1173
+ context "when the document is not the match" do
1174
+
1175
+ before do
1176
+ Login.create(username: "Oxford")
1177
+ end
1178
+
1179
+ let(:login) do
1180
+ Login.new(username: "Oxford")
1181
+ end
1182
+
1183
+ it "returns false" do
1184
+ login.should_not be_valid
1185
+ end
1186
+
1187
+ it "adds the uniqueness error" do
1188
+ login.valid?
1189
+ login.errors[:username].should eq([ "is already taken" ])
1190
+ end
1191
+ end
1192
+
1193
+ context "when the document is the match in the database" do
1194
+
1195
+ let!(:login) do
1196
+ Login.create(username: "Oxford")
1197
+ end
1198
+
1199
+ it "returns true" do
1200
+ login.should be_valid
1201
+ end
1202
+ end
1203
+ end
1204
+ end
1205
+
1206
+ context "when a single scope is provided" do
1207
+
1208
+ before do
1209
+ Login.validates_uniqueness_of :username, scope: :application_id
1210
+ end
1211
+
1212
+ after do
1213
+ Login.reset_callbacks(:validate)
1214
+ end
1215
+
1216
+ context "when the attribute is unique" do
1217
+
1218
+ before do
1219
+ Login.create(username: "Oxford", application_id: 1)
1220
+ end
1221
+
1222
+ let(:login) do
1223
+ Login.new(username: "Webster")
1224
+ end
1225
+
1226
+ it "returns true" do
1227
+ login.should be_valid
1228
+ end
1229
+ end
1230
+
1231
+ context "when the attribute is unique in the scope" do
1232
+
1233
+ before do
1234
+ Login.create(username: "Oxford", application_id: 1)
1235
+ end
1236
+
1237
+ let(:login) do
1238
+ Login.new(username: "Webster", application_id: 1)
1239
+ end
1240
+
1241
+ it "returns true" do
1242
+ login.should be_valid
1243
+ end
1244
+ end
1245
+
1246
+ context "when the attribute is not unique with no scope" do
1247
+
1248
+ before do
1249
+ Login.create(username: "Oxford", application_id: 1)
1250
+ end
1251
+
1252
+ let(:login) do
1253
+ Login.new(username: "Oxford")
1254
+ end
1255
+
1256
+ it "returns true" do
1257
+ login.should be_valid
1258
+ end
1259
+ end
1260
+
1261
+ context "when the attribute is not unique in another scope" do
1262
+
1263
+ before do
1264
+ Login.create(username: "Oxford", application_id: 1)
1265
+ end
1266
+
1267
+ let(:login) do
1268
+ Login.new(username: "Oxford", application_id: 2)
1269
+ end
1270
+
1271
+ it "returns true" do
1272
+ login.should be_valid
1273
+ end
1274
+ end
1275
+
1276
+ context "when the attribute is not unique in the same scope" do
1277
+
1278
+ context "when the document is not the match" do
1279
+
1280
+ before do
1281
+ Login.create(username: "Oxford", application_id: 1)
1282
+ end
1283
+
1284
+ let(:login) do
1285
+ Login.new(username: "Oxford", application_id: 1)
1286
+ end
1287
+
1288
+ it "returns false" do
1289
+ login.should_not be_valid
1290
+ end
1291
+
1292
+ it "adds the uniqueness errors" do
1293
+ login.valid?
1294
+ login.errors[:username].should eq([ "is already taken" ])
1295
+ end
1296
+ end
1297
+
1298
+ context "when the document is the match in the database" do
1299
+
1300
+ let!(:login) do
1301
+ Login.create(username: "Oxford", application_id: 1)
1302
+ end
1303
+
1304
+ it "returns true" do
1305
+ login.should be_valid
1306
+ end
1307
+ end
1308
+ end
1309
+ end
1310
+
1311
+ context "when case sensitive is true" do
1312
+
1313
+ before do
1314
+ Login.validates_uniqueness_of :username
1315
+ end
1316
+
1317
+ after do
1318
+ Login.reset_callbacks(:validate)
1319
+ end
1320
+
1321
+ context "when the attribute is unique" do
1322
+
1323
+ before do
1324
+ Login.create(username: "Oxford")
1325
+ end
1326
+
1327
+ let(:login) do
1328
+ Login.new(username: "Webster")
1329
+ end
1330
+
1331
+ it "returns true" do
1332
+ login.should be_valid
1333
+ end
1334
+ end
1335
+
1336
+ context "when the attribute is not unique" do
1337
+
1338
+ context "when the document is not the match" do
1339
+
1340
+ before do
1341
+ Login.create(username: "Oxford")
1342
+ end
1343
+
1344
+ let(:login) do
1345
+ Login.new(username: "Oxford")
1346
+ end
1347
+
1348
+ it "returns false" do
1349
+ login.should_not be_valid
1350
+ end
1351
+
1352
+ it "adds the uniqueness error" do
1353
+ login.valid?
1354
+ login.errors[:username].should eq([ "is already taken" ])
1355
+ end
1356
+ end
1357
+
1358
+ context "when the document is the match in the database" do
1359
+
1360
+ let!(:login) do
1361
+ Login.create(username: "Oxford")
1362
+ end
1363
+
1364
+ it "returns true" do
1365
+ login.should be_valid
1366
+ end
1367
+ end
1368
+ end
1369
+ end
1370
+
1371
+ context "when case sensitive is false" do
1372
+
1373
+ before do
1374
+ Login.validates_uniqueness_of :username, case_sensitive: false
1375
+ end
1376
+
1377
+ after do
1378
+ Login.reset_callbacks(:validate)
1379
+ end
1380
+
1381
+ context "when the attribute is unique" do
1382
+
1383
+ context "when there are no special characters" do
1384
+
1385
+ before do
1386
+ Login.create(username: "Oxford")
1387
+ end
1388
+
1389
+ let(:login) do
1390
+ Login.new(username: "Webster")
1391
+ end
1392
+
1393
+ it "returns true" do
1394
+ login.should be_valid
1395
+ end
1396
+ end
1397
+
1398
+ context "when special characters exist" do
1399
+
1400
+ before do
1401
+ Login.create(username: "Oxford")
1402
+ end
1403
+
1404
+ let(:login) do
1405
+ Login.new(username: "Web@st.er")
1406
+ end
1407
+
1408
+ it "returns true" do
1409
+ login.should be_valid
1410
+ end
1411
+ end
1412
+ end
1413
+
1414
+ context "when the attribute is not unique" do
1415
+
1416
+ context "when the document is not the match" do
1417
+
1418
+ before do
1419
+ Login.create(username: "Oxford")
1420
+ end
1421
+
1422
+ let(:login) do
1423
+ Login.new(username: "oxford")
1424
+ end
1425
+
1426
+ it "returns false" do
1427
+ login.should_not be_valid
1428
+ end
1429
+
1430
+ it "adds the uniqueness error" do
1431
+ login.valid?
1432
+ login.errors[:username].should eq([ "is already taken" ])
1433
+ end
1434
+ end
1435
+
1436
+ context "when the document is the match in the database" do
1437
+
1438
+ let!(:login) do
1439
+ Login.create(username: "Oxford")
1440
+ end
1441
+
1442
+ it "returns true" do
1443
+ login.should be_valid
1444
+ end
1445
+ end
1446
+ end
1447
+ end
1448
+
1449
+ context "when allowing nil" do
1450
+
1451
+ before do
1452
+ Login.validates_uniqueness_of :username, allow_nil: true
1453
+ end
1454
+
1455
+ after do
1456
+ Login.reset_callbacks(:validate)
1457
+ end
1458
+
1459
+ context "when the attribute is nil" do
1460
+
1461
+ before do
1462
+ Login.create
1463
+ end
1464
+
1465
+ let(:login) do
1466
+ Login.new
1467
+ end
1468
+
1469
+ it "returns true" do
1470
+ login.should be_valid
1471
+ end
1472
+ end
1473
+ end
1474
+
1475
+ context "when allowing blank" do
1476
+
1477
+ before do
1478
+ Login.validates_uniqueness_of :username, allow_blank: true
1479
+ end
1480
+
1481
+ after do
1482
+ Login.reset_callbacks(:validate)
1483
+ end
1484
+
1485
+ context "when the attribute is blank" do
1486
+
1487
+ before do
1488
+ Login.create(username: "")
1489
+ end
1490
+
1491
+ let(:login) do
1492
+ Login.new(username: "")
1493
+ end
1494
+
1495
+ it "returns true" do
1496
+ login.should be_valid
1497
+ end
1498
+ end
1499
+ end
1500
+ end
1501
+
1502
+ context "when the attribute is a custom type" do
1503
+
1504
+ before do
1505
+ Bar.validates_uniqueness_of :lat_lng
1506
+ end
1507
+
1508
+ after do
1509
+ Bar.reset_callbacks(:validate)
1510
+ end
1511
+
1512
+ context "when the attribute is unique" do
1513
+
1514
+ before do
1515
+ Bar.create(lat_lng: LatLng.new(52.30, 13.25))
1516
+ end
1517
+
1518
+ let(:unique_bar) do
1519
+ Bar.new(lat_lng: LatLng.new(54.30, 14.25))
1520
+ end
1521
+
1522
+ it "returns true" do
1523
+ expect(unique_bar).to be_valid
1524
+ end
1525
+
1526
+ end
1527
+
1528
+ context "when the attribute is not unique" do
1529
+
1530
+ before do
1531
+ Bar.create(lat_lng: LatLng.new(52.30, 13.25))
1532
+ end
1533
+
1534
+ let(:non_unique_bar) do
1535
+ Bar.new(lat_lng: LatLng.new(52.30, 13.25))
1536
+ end
1537
+
1538
+ it "returns false" do
1539
+ expect(non_unique_bar).to_not be_valid
1540
+ end
1541
+
1542
+ end
1543
+
1544
+ end
1545
+ end
1546
+ end
1547
+
1548
+ context "when the document is embedded" do
1549
+
1550
+ let(:word) do
1551
+ Word.create(name: "Schadenfreude")
1552
+ end
1553
+
1554
+ context "when in an embeds_many" do
1555
+
1556
+ let!(:def_one) do
1557
+ word.definitions.create(description: "1")
1558
+ end
1559
+
1560
+ let!(:def_two) do
1561
+ word.definitions.create(description: "2")
1562
+ end
1563
+
1564
+ context "when a document is being destroyed" do
1565
+
1566
+ before do
1567
+ Definition.validates_uniqueness_of :description
1568
+ end
1569
+
1570
+ after do
1571
+ Definition.reset_callbacks(:validate)
1572
+ end
1573
+
1574
+ context "when changing a document to the destroyed property" do
1575
+
1576
+ let(:attributes) do
1577
+ {
1578
+ definitions_attributes: {
1579
+ "0" => { id: def_one.id, description: "0", "_destroy" => 1 },
1580
+ "1" => { id: def_two.id, description: "1" }
1581
+ }
1582
+ }
1583
+ end
1584
+
1585
+ before do
1586
+ word.attributes = attributes
1587
+ end
1588
+
1589
+ it "returns true" do
1590
+ def_two.should be_valid
1591
+ end
1592
+ end
1593
+ end
1594
+
1595
+ context "when the document does not use composite keys" do
1596
+
1597
+ context "when no scope is provided" do
1598
+
1599
+ before do
1600
+ Definition.validates_uniqueness_of :description
1601
+ end
1602
+
1603
+ after do
1604
+ Definition.reset_callbacks(:validate)
1605
+ end
1606
+
1607
+ context "when the attribute is unique" do
1608
+
1609
+ before do
1610
+ word.definitions.build(description: "Malicious joy")
1611
+ end
1612
+
1613
+ let(:definition) do
1614
+ word.definitions.build(description: "Gloating")
1615
+ end
1616
+
1617
+ it "returns true" do
1618
+ definition.should be_valid
1619
+ end
1620
+ end
1621
+
1622
+ context "when the attribute is not unique" do
1623
+
1624
+ context "when the document is not the match" do
1625
+
1626
+ before do
1627
+ word.definitions.build(description: "Malicious joy")
1628
+ end
1629
+
1630
+ let(:definition) do
1631
+ word.definitions.build(description: "Malicious joy")
1632
+ end
1633
+
1634
+ it "returns false" do
1635
+ definition.should_not be_valid
1636
+ end
1637
+
1638
+ it "adds the uniqueness error" do
1639
+ definition.valid?
1640
+ definition.errors[:description].should eq([ "is already taken" ])
1641
+ end
1642
+ end
1643
+
1644
+ context "when the document is the match in the database" do
1645
+
1646
+ let!(:definition) do
1647
+ word.definitions.build(description: "Malicious joy")
1648
+ end
1649
+
1650
+ it "returns true" do
1651
+ definition.should be_valid
1652
+ end
1653
+ end
1654
+ end
1655
+ end
1656
+
1657
+ context "when a single scope is provided" do
1658
+
1659
+ before do
1660
+ Definition.validates_uniqueness_of :description, scope: :part
1661
+ end
1662
+
1663
+ after do
1664
+ Definition.reset_callbacks(:validate)
1665
+ end
1666
+
1667
+ context "when the attribute is unique" do
1668
+
1669
+ before do
1670
+ word.definitions.build(
1671
+ description: "Malicious joy", part: "Noun"
1672
+ )
1673
+ end
1674
+
1675
+ let(:definition) do
1676
+ word.definitions.build(description: "Gloating")
1677
+ end
1678
+
1679
+ it "returns true" do
1680
+ definition.should be_valid
1681
+ end
1682
+ end
1683
+
1684
+ context "when the attribute is unique in the scope" do
1685
+
1686
+ before do
1687
+ word.definitions.build(
1688
+ description: "Malicious joy",
1689
+ part: "Noun"
1690
+ )
1691
+ end
1692
+
1693
+ let(:definition) do
1694
+ word.definitions.build(
1695
+ description: "Gloating",
1696
+ part: "Noun"
1697
+ )
1698
+ end
1699
+
1700
+ it "returns true" do
1701
+ definition.should be_valid
1702
+ end
1703
+ end
1704
+
1705
+ context "when the attribute is not unique with no scope" do
1706
+
1707
+ before do
1708
+ word.definitions.build(
1709
+ description: "Malicious joy",
1710
+ part: "Noun"
1711
+ )
1712
+ end
1713
+
1714
+ let(:definition) do
1715
+ word.definitions.build(description: "Malicious joy")
1716
+ end
1717
+
1718
+ it "returns true" do
1719
+ definition.should be_valid
1720
+ end
1721
+ end
1722
+
1723
+ context "when the attribute is not unique in another scope" do
1724
+
1725
+ before do
1726
+ word.definitions.build(
1727
+ description: "Malicious joy",
1728
+ part: "Noun"
1729
+ )
1730
+ end
1731
+
1732
+ let(:definition) do
1733
+ word.definitions.build(
1734
+ description: "Malicious joy",
1735
+ part: "Adj"
1736
+ )
1737
+ end
1738
+
1739
+ it "returns true" do
1740
+ definition.should be_valid
1741
+ end
1742
+ end
1743
+
1744
+ context "when the attribute is not unique in the same scope" do
1745
+
1746
+ context "when the document is not the match" do
1747
+
1748
+ before do
1749
+ word.definitions.build(
1750
+ description: "Malicious joy",
1751
+ part: "Noun"
1752
+ )
1753
+ end
1754
+
1755
+ let(:definition) do
1756
+ word.definitions.build(
1757
+ description: "Malicious joy",
1758
+ part: "Noun"
1759
+ )
1760
+ end
1761
+
1762
+ it "returns false" do
1763
+ definition.should_not be_valid
1764
+ end
1765
+
1766
+ it "adds the uniqueness errors" do
1767
+ definition.valid?
1768
+ definition.errors[:description].should eq([ "is already taken" ])
1769
+ end
1770
+ end
1771
+
1772
+ context "when the document is the match in the database" do
1773
+
1774
+ let!(:definition) do
1775
+ word.definitions.build(
1776
+ description: "Malicious joy",
1777
+ part: "Noun"
1778
+ )
1779
+ end
1780
+
1781
+ it "returns true" do
1782
+ definition.should be_valid
1783
+ end
1784
+ end
1785
+ end
1786
+ end
1787
+
1788
+ context "when multiple scopes are provided" do
1789
+
1790
+ before do
1791
+ Definition.validates_uniqueness_of :description, scope: [ :part, :regular ]
1792
+ end
1793
+
1794
+ after do
1795
+ Definition.reset_callbacks(:validate)
1796
+ end
1797
+
1798
+ context "when the attribute is unique" do
1799
+
1800
+ before do
1801
+ word.definitions.build(
1802
+ description: "Malicious joy",
1803
+ part: "Noun"
1804
+ )
1805
+ end
1806
+
1807
+ let(:definition) do
1808
+ word.definitions.build(description: "Gloating")
1809
+ end
1810
+
1811
+ it "returns true" do
1812
+ definition.should be_valid
1813
+ end
1814
+ end
1815
+
1816
+ context "when the attribute is unique in the scope" do
1817
+
1818
+ before do
1819
+ word.definitions.build(
1820
+ description: "Malicious joy",
1821
+ part: "Noun",
1822
+ regular: true
1823
+ )
1824
+ end
1825
+
1826
+ let(:definition) do
1827
+ word.definitions.build(
1828
+ description: "Gloating",
1829
+ part: "Noun",
1830
+ regular: true
1831
+ )
1832
+ end
1833
+
1834
+ it "returns true" do
1835
+ definition.should be_valid
1836
+ end
1837
+ end
1838
+
1839
+ context "when the attribute is not unique with no scope" do
1840
+
1841
+ before do
1842
+ word.definitions.build(
1843
+ description: "Malicious joy",
1844
+ part: "Noun"
1845
+ )
1846
+ end
1847
+
1848
+ let(:definition) do
1849
+ word.definitions.build(description: "Malicious scope")
1850
+ end
1851
+
1852
+ it "returns true" do
1853
+ definition.should be_valid
1854
+ end
1855
+ end
1856
+
1857
+ context "when the attribute is not unique in another scope" do
1858
+
1859
+ before do
1860
+ word.definitions.build(
1861
+ description: "Malicious joy",
1862
+ part: "Noun",
1863
+ regular: true
1864
+ )
1865
+ end
1866
+
1867
+ let(:definition) do
1868
+ word.definitions.build(
1869
+ description: "Malicious joy",
1870
+ part: "Adj",
1871
+ regular: true
1872
+ )
1873
+ end
1874
+
1875
+ it "returns true" do
1876
+ definition.should be_valid
1877
+ end
1878
+ end
1879
+
1880
+ context "when the attribute is not unique in the same scope" do
1881
+
1882
+ context "when the document is not the match" do
1883
+
1884
+ before do
1885
+ word.definitions.build(
1886
+ description: "Malicious joy",
1887
+ part: "Noun",
1888
+ regular: true
1889
+ )
1890
+ end
1891
+
1892
+ let(:definition) do
1893
+ word.definitions.build(
1894
+ description: "Malicious joy",
1895
+ part: "Noun",
1896
+ regular: true
1897
+ )
1898
+ end
1899
+
1900
+ it "returns false" do
1901
+ definition.should_not be_valid
1902
+ end
1903
+
1904
+ it "adds the uniqueness errors" do
1905
+ definition.valid?
1906
+ definition.errors[:description].should eq([ "is already taken" ])
1907
+ end
1908
+ end
1909
+
1910
+ context "when the document is the match in the database" do
1911
+
1912
+ let!(:definition) do
1913
+ word.definitions.build(
1914
+ description: "Malicious joy",
1915
+ part: "Noun",
1916
+ regular: false
1917
+ )
1918
+ end
1919
+
1920
+ it "returns true" do
1921
+ definition.should be_valid
1922
+ end
1923
+ end
1924
+ end
1925
+ end
1926
+
1927
+ context "when case sensitive is true" do
1928
+
1929
+ before do
1930
+ Definition.validates_uniqueness_of :description
1931
+ end
1932
+
1933
+ after do
1934
+ Definition.reset_callbacks(:validate)
1935
+ end
1936
+
1937
+ context "when the attribute is unique" do
1938
+
1939
+ before do
1940
+ word.definitions.build(description: "Malicious jo")
1941
+ end
1942
+
1943
+ let(:definition) do
1944
+ word.definitions.build(description: "Gloating")
1945
+ end
1946
+
1947
+ it "returns true" do
1948
+ definition.should be_valid
1949
+ end
1950
+ end
1951
+
1952
+ context "when the attribute is not unique" do
1953
+
1954
+ context "when the document is not the match" do
1955
+
1956
+ before do
1957
+ word.definitions.build(description: "Malicious joy")
1958
+ end
1959
+
1960
+ let(:definition) do
1961
+ word.definitions.build(description: "Malicious joy")
1962
+ end
1963
+
1964
+ it "returns false" do
1965
+ definition.should_not be_valid
1966
+ end
1967
+
1968
+ it "adds the uniqueness error" do
1969
+ definition.valid?
1970
+ definition.errors[:description].should eq([ "is already taken" ])
1971
+ end
1972
+ end
1973
+
1974
+ context "when the document is the match in the database" do
1975
+
1976
+ let!(:definition) do
1977
+ word.definitions.build(description: "Malicious joy")
1978
+ end
1979
+
1980
+ it "returns true" do
1981
+ definition.should be_valid
1982
+ end
1983
+ end
1984
+ end
1985
+ end
1986
+
1987
+ context "when case sensitive is false" do
1988
+
1989
+ before do
1990
+ Definition.validates_uniqueness_of :description, case_sensitive: false
1991
+ end
1992
+
1993
+ after do
1994
+ Definition.reset_callbacks(:validate)
1995
+ end
1996
+
1997
+ context "when the attribute is unique" do
1998
+
1999
+ context "when there are no special characters" do
2000
+
2001
+ before do
2002
+ word.definitions.build(description: "Malicious joy")
2003
+ end
2004
+
2005
+ let(:definition) do
2006
+ word.definitions.build(description: "Gloating")
2007
+ end
2008
+
2009
+ it "returns true" do
2010
+ definition.should be_valid
2011
+ end
2012
+ end
2013
+
2014
+ context "when special characters exist" do
2015
+
2016
+ before do
2017
+ word.definitions.build(description: "Malicious joy")
2018
+ end
2019
+
2020
+ let(:definition) do
2021
+ word.definitions.build(description: "M@licious.joy")
2022
+ end
2023
+
2024
+ it "returns true" do
2025
+ definition.should be_valid
2026
+ end
2027
+ end
2028
+ end
2029
+
2030
+ context "when the attribute is not unique" do
2031
+
2032
+ context "when the document is not the match" do
2033
+
2034
+ before do
2035
+ word.definitions.build(description: "Malicious joy")
2036
+ end
2037
+
2038
+ let(:definition) do
2039
+ word.definitions.build(description: "Malicious JOY")
2040
+ end
2041
+
2042
+ it "returns false" do
2043
+ definition.should_not be_valid
2044
+ end
2045
+
2046
+ it "adds the uniqueness error" do
2047
+ definition.valid?
2048
+ definition.errors[:description].should eq([ "is already taken" ])
2049
+ end
2050
+ end
2051
+
2052
+ context "when the document is the match in the database" do
2053
+
2054
+ let!(:definition) do
2055
+ word.definitions.build(description: "Malicious joy")
2056
+ end
2057
+
2058
+ it "returns true" do
2059
+ definition.should be_valid
2060
+ end
2061
+ end
2062
+ end
2063
+ end
2064
+
2065
+ context "when allowing nil" do
2066
+
2067
+ before do
2068
+ Definition.validates_uniqueness_of :description, allow_nil: true
2069
+ end
2070
+
2071
+ after do
2072
+ Definition.reset_callbacks(:validate)
2073
+ end
2074
+
2075
+ context "when the attribute is nil" do
2076
+
2077
+ before do
2078
+ word.definitions.build
2079
+ end
2080
+
2081
+ let(:definition) do
2082
+ word.definitions.build
2083
+ end
2084
+
2085
+ it "returns true" do
2086
+ definition.should be_valid
2087
+ end
2088
+ end
2089
+ end
2090
+
2091
+ context "when allowing blank" do
2092
+
2093
+ before do
2094
+ Definition.validates_uniqueness_of :description, allow_blank: true
2095
+ end
2096
+
2097
+ after do
2098
+ Definition.reset_callbacks(:validate)
2099
+ end
2100
+
2101
+ context "when the attribute is blank" do
2102
+
2103
+ before do
2104
+ word.definitions.build(description: "")
2105
+ end
2106
+
2107
+ let(:definition) do
2108
+ word.definitions.build(description: "")
2109
+ end
2110
+
2111
+ it "returns true" do
2112
+ definition.should be_valid
2113
+ end
2114
+ end
2115
+ end
2116
+
2117
+ context "when the field name is aliased" do
2118
+
2119
+ before do
2120
+ word.definitions.build(part: "noun", synonyms: "foo")
2121
+ end
2122
+
2123
+ let(:definition) do
2124
+ word.definitions.build(part: "noun", synonyms: "foo")
2125
+ end
2126
+
2127
+ after do
2128
+ Definition.reset_callbacks(:validate)
2129
+ end
2130
+
2131
+ context "when the validation uses the aliased name" do
2132
+
2133
+ before do
2134
+ Definition.validates_uniqueness_of :part, case_sensitive: false
2135
+ end
2136
+
2137
+ it "correctly detects a uniqueness conflict" do
2138
+ expect(definition).to_not be_valid
2139
+ end
2140
+
2141
+ it "adds the uniqueness error to the aliased field name" do
2142
+ definition.valid?
2143
+ expect(definition.errors).to have_key(:part)
2144
+ expect(definition.errors[:part]).to eq([ "is already taken" ])
2145
+ end
2146
+ end
2147
+
2148
+ context "when the validation uses the underlying field name" do
2149
+
2150
+ before do
2151
+ Definition.validates_uniqueness_of :p, case_sensitive: false
2152
+ end
2153
+
2154
+ it "correctly detects a uniqueness conflict" do
2155
+ expect(definition).to_not be_valid
2156
+ end
2157
+
2158
+ it "adds the uniqueness error to the underlying field name" do
2159
+ definition.valid?
2160
+ expect(definition.errors).to have_key(:p)
2161
+ expect(definition.errors[:p]).to eq([ "is already taken" ])
2162
+ end
2163
+ end
2164
+
2165
+ context "when the field is localized" do
2166
+
2167
+ context "when the validation uses the aliased name" do
2168
+
2169
+ before do
2170
+ Definition.validates_uniqueness_of :synonyms, case_sensitive: false
2171
+ end
2172
+
2173
+ it "correctly detects a uniqueness conflict" do
2174
+ expect(definition).to_not be_valid
2175
+ end
2176
+
2177
+ it "adds the uniqueness error to the aliased field name" do
2178
+ definition.valid?
2179
+ expect(definition.errors).to have_key(:synonyms)
2180
+ expect(definition.errors[:synonyms]).to eq([ "is already taken" ])
2181
+ end
2182
+ end
2183
+
2184
+ context "when the validation uses the underlying field name" do
2185
+
2186
+ before do
2187
+ Definition.validates_uniqueness_of :syn, case_sensitive: false
2188
+ end
2189
+
2190
+ it "correctly detects a uniqueness conflict" do
2191
+ expect(definition).to_not be_valid
2192
+ end
2193
+
2194
+ it "adds the uniqueness error to the aliased field name" do
2195
+ definition.valid?
2196
+ expect(definition.errors).to have_key(:syn)
2197
+ expect(definition.errors[:syn]).to eq([ "is already taken" ])
2198
+ end
2199
+ end
2200
+ end
2201
+ end
2202
+ end
2203
+
2204
+ context "when the document uses composite keys" do
2205
+
2206
+ context "when no scope is provided" do
2207
+
2208
+ before do
2209
+ WordOrigin.validates_uniqueness_of :origin_id
2210
+ end
2211
+
2212
+ after do
2213
+ WordOrigin.reset_callbacks(:validate)
2214
+ end
2215
+
2216
+ context "when the attribute is unique" do
2217
+
2218
+ before do
2219
+ word.word_origins.build(origin_id: 1)
2220
+ end
2221
+
2222
+ let(:word_origin) do
2223
+ word.word_origins.build(origin_id: 2)
2224
+ end
2225
+
2226
+ it "returns true" do
2227
+ word_origin.should be_valid
2228
+ end
2229
+ end
2230
+
2231
+ context "when the attribute is not unique" do
2232
+
2233
+ context "when the document is not the match" do
2234
+
2235
+ before do
2236
+ word.word_origins.build(origin_id: 1)
2237
+ end
2238
+
2239
+ let(:word_origin) do
2240
+ word.word_origins.build(origin_id: 1)
2241
+ end
2242
+
2243
+ it "returns false" do
2244
+ word_origin.should_not be_valid
2245
+ end
2246
+
2247
+ it "adds the uniqueness error" do
2248
+ word_origin.valid?
2249
+ word_origin.errors[:origin_id].should eq([ "is already taken" ])
2250
+ end
2251
+ end
2252
+
2253
+ context "when the document is the match in the database" do
2254
+
2255
+ let!(:word_origin) do
2256
+ word.word_origins.build(origin_id: 1)
2257
+ end
2258
+
2259
+ it "returns true" do
2260
+ word_origin.should be_valid
2261
+ end
2262
+ end
2263
+ end
2264
+ end
2265
+
2266
+ context "when allowing nil" do
2267
+
2268
+ before do
2269
+ WordOrigin.validates_uniqueness_of :origin_id, allow_nil: true
2270
+ end
2271
+
2272
+ after do
2273
+ WordOrigin.reset_callbacks(:validate)
2274
+ end
2275
+
2276
+ context "when the attribute is nil" do
2277
+
2278
+ before do
2279
+ word.word_origins.build
2280
+ end
2281
+
2282
+ let(:word_origin) do
2283
+ word.word_origins.build
2284
+ end
2285
+
2286
+ it "returns true" do
2287
+ word_origin.should be_valid
2288
+ end
2289
+ end
2290
+ end
2291
+
2292
+ context "when allowing blank" do
2293
+
2294
+ before do
2295
+ WordOrigin.validates_uniqueness_of :origin_id, allow_blank: true
2296
+ end
2297
+
2298
+ after do
2299
+ WordOrigin.reset_callbacks(:validate)
2300
+ end
2301
+
2302
+ context "when the attribute is blank" do
2303
+
2304
+ before do
2305
+ word.word_origins.build(origin_id: "")
2306
+ end
2307
+
2308
+ let(:word_origin) do
2309
+ word.word_origins.build(origin_id: "")
2310
+ end
2311
+
2312
+ it "returns true" do
2313
+ word_origin.should be_valid
2314
+ end
2315
+ end
2316
+ end
2317
+ end
2318
+ end
2319
+
2320
+ context "when in an embeds_one" do
2321
+
2322
+ before do
2323
+ Pronunciation.validates_uniqueness_of :sound
2324
+ end
2325
+
2326
+ after do
2327
+ Pronunciation.reset_callbacks(:validate)
2328
+ end
2329
+
2330
+ let(:pronunciation) do
2331
+ word.build_pronunciation(sound: "Schwa")
2332
+ end
2333
+
2334
+ it "always returns true" do
2335
+ pronunciation.should be_valid
2336
+ end
2337
+ end
2338
+ end
2339
+
2340
+ context "when describing validation on the instance level" do
2341
+
2342
+ let!(:dictionary) do
2343
+ Dictionary.create!(name: "en")
2344
+ end
2345
+
2346
+ let(:validators) do
2347
+ dictionary.validates_uniqueness_of :name
2348
+ end
2349
+
2350
+ it "adds the validation only to the instance" do
2351
+ validators.should eq([ described_class ])
2352
+ end
2353
+ end
2354
+
2355
+ context "when validation works with inheritance" do
2356
+
2357
+ before do
2358
+ Actor.validates_uniqueness_of :name
2359
+ Actor.create!(name: "Johnny Depp")
2360
+ end
2361
+
2362
+ after do
2363
+ Actor.reset_callbacks(:validate)
2364
+ end
2365
+
2366
+ let!(:subclass_document_with_duplicated_name) do
2367
+ Actress.new(name: "Johnny Depp")
2368
+ end
2369
+
2370
+ it "should be invalid" do
2371
+ subclass_document_with_duplicated_name.tap do |d|
2372
+ d.should be_invalid
2373
+ d.errors[:name].should eq([ "is already taken" ])
2374
+ end
2375
+ end
2376
+ end
2377
+
2378
+ context "when persisting with safe options" do
2379
+
2380
+ before do
2381
+ Person.validates_uniqueness_of(:username)
2382
+ Person.create_indexes
2383
+ end
2384
+
2385
+ let!(:person) do
2386
+ Person.create(ssn: "132-11-1111", username: "testing-1234")
2387
+ end
2388
+
2389
+ after do
2390
+ Person.reset_callbacks(:validate)
2391
+ end
2392
+
2393
+ it "transfers the options to the cloned session" do
2394
+ expect {
2395
+ Person.with(safe: true).create!(ssn: "132-11-1111", username: "testing-121111")
2396
+ }.to raise_error(Moped::Errors::OperationFailure)
2397
+ end
2398
+ end
2399
+ end