mongoid_rails4 4.0.0

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 (659) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3213 -0
  3. data/LICENSE +20 -0
  4. data/README.md +62 -0
  5. data/Rakefile +35 -0
  6. data/lib/config/locales/en.yml +448 -0
  7. data/lib/mongoid.rb +104 -0
  8. data/lib/mongoid/atomic.rb +384 -0
  9. data/lib/mongoid/atomic/modifiers.rb +317 -0
  10. data/lib/mongoid/atomic/paths.rb +3 -0
  11. data/lib/mongoid/atomic/paths/embedded.rb +28 -0
  12. data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
  13. data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
  14. data/lib/mongoid/atomic/paths/root.rb +39 -0
  15. data/lib/mongoid/attributes.rb +284 -0
  16. data/lib/mongoid/attributes/dynamic.rb +154 -0
  17. data/lib/mongoid/attributes/nested.rb +82 -0
  18. data/lib/mongoid/attributes/processing.rb +147 -0
  19. data/lib/mongoid/attributes/readonly.rb +56 -0
  20. data/lib/mongoid/changeable.rb +379 -0
  21. data/lib/mongoid/composable.rb +104 -0
  22. data/lib/mongoid/config.rb +263 -0
  23. data/lib/mongoid/config/environment.rb +44 -0
  24. data/lib/mongoid/config/options.rb +74 -0
  25. data/lib/mongoid/config/validators.rb +3 -0
  26. data/lib/mongoid/config/validators/option.rb +25 -0
  27. data/lib/mongoid/config/validators/session.rb +140 -0
  28. data/lib/mongoid/contextual.rb +54 -0
  29. data/lib/mongoid/contextual/aggregable/memory.rb +109 -0
  30. data/lib/mongoid/contextual/aggregable/mongo.rb +147 -0
  31. data/lib/mongoid/contextual/atomic.rb +180 -0
  32. data/lib/mongoid/contextual/command.rb +61 -0
  33. data/lib/mongoid/contextual/eager.rb +158 -0
  34. data/lib/mongoid/contextual/find_and_modify.rb +69 -0
  35. data/lib/mongoid/contextual/geo_near.rb +238 -0
  36. data/lib/mongoid/contextual/map_reduce.rb +324 -0
  37. data/lib/mongoid/contextual/memory.rb +440 -0
  38. data/lib/mongoid/contextual/mongo.rb +676 -0
  39. data/lib/mongoid/contextual/queryable.rb +25 -0
  40. data/lib/mongoid/contextual/text_search.rb +180 -0
  41. data/lib/mongoid/copyable.rb +67 -0
  42. data/lib/mongoid/criteria.rb +562 -0
  43. data/lib/mongoid/criteria/findable.rb +179 -0
  44. data/lib/mongoid/criteria/inspectable.rb +25 -0
  45. data/lib/mongoid/criteria/marshalable.rb +50 -0
  46. data/lib/mongoid/criteria/modifiable.rb +189 -0
  47. data/lib/mongoid/criteria/scopable.rb +158 -0
  48. data/lib/mongoid/document.rb +361 -0
  49. data/lib/mongoid/equality.rb +66 -0
  50. data/lib/mongoid/errors.rb +40 -0
  51. data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
  52. data/lib/mongoid/errors/callback.rb +25 -0
  53. data/lib/mongoid/errors/delete_restriction.rb +29 -0
  54. data/lib/mongoid/errors/document_not_found.rb +111 -0
  55. data/lib/mongoid/errors/eager_load.rb +22 -0
  56. data/lib/mongoid/errors/invalid_collection.rb +18 -0
  57. data/lib/mongoid/errors/invalid_config_option.rb +27 -0
  58. data/lib/mongoid/errors/invalid_field.rb +64 -0
  59. data/lib/mongoid/errors/invalid_field_option.rb +35 -0
  60. data/lib/mongoid/errors/invalid_find.rb +19 -0
  61. data/lib/mongoid/errors/invalid_includes.rb +32 -0
  62. data/lib/mongoid/errors/invalid_index.rb +28 -0
  63. data/lib/mongoid/errors/invalid_options.rb +28 -0
  64. data/lib/mongoid/errors/invalid_path.rb +21 -0
  65. data/lib/mongoid/errors/invalid_scope.rb +24 -0
  66. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
  67. data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
  68. data/lib/mongoid/errors/invalid_time.rb +22 -0
  69. data/lib/mongoid/errors/inverse_not_found.rb +29 -0
  70. data/lib/mongoid/errors/mixed_relations.rb +32 -0
  71. data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
  72. data/lib/mongoid/errors/mongoid_error.rb +92 -0
  73. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
  74. data/lib/mongoid/errors/no_default_session.rb +23 -0
  75. data/lib/mongoid/errors/no_environment.rb +19 -0
  76. data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
  77. data/lib/mongoid/errors/no_metadata.rb +21 -0
  78. data/lib/mongoid/errors/no_parent.rb +24 -0
  79. data/lib/mongoid/errors/no_session_config.rb +22 -0
  80. data/lib/mongoid/errors/no_session_database.rb +27 -0
  81. data/lib/mongoid/errors/no_session_hosts.rb +27 -0
  82. data/lib/mongoid/errors/no_sessions_config.rb +20 -0
  83. data/lib/mongoid/errors/readonly_attribute.rb +25 -0
  84. data/lib/mongoid/errors/scope_overwrite.rb +21 -0
  85. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
  86. data/lib/mongoid/errors/unknown_attribute.rb +25 -0
  87. data/lib/mongoid/errors/unsaved_document.rb +19 -0
  88. data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
  89. data/lib/mongoid/errors/validations.rb +29 -0
  90. data/lib/mongoid/evolvable.rb +19 -0
  91. data/lib/mongoid/extensions.rb +35 -0
  92. data/lib/mongoid/extensions/array.rb +180 -0
  93. data/lib/mongoid/extensions/big_decimal.rb +69 -0
  94. data/lib/mongoid/extensions/boolean.rb +21 -0
  95. data/lib/mongoid/extensions/date.rb +77 -0
  96. data/lib/mongoid/extensions/date_time.rb +73 -0
  97. data/lib/mongoid/extensions/false_class.rb +38 -0
  98. data/lib/mongoid/extensions/float.rb +56 -0
  99. data/lib/mongoid/extensions/hash.rb +209 -0
  100. data/lib/mongoid/extensions/integer.rb +67 -0
  101. data/lib/mongoid/extensions/module.rb +28 -0
  102. data/lib/mongoid/extensions/nil_class.rb +33 -0
  103. data/lib/mongoid/extensions/object.rb +274 -0
  104. data/lib/mongoid/extensions/object_id.rb +54 -0
  105. data/lib/mongoid/extensions/range.rb +79 -0
  106. data/lib/mongoid/extensions/regexp.rb +27 -0
  107. data/lib/mongoid/extensions/set.rb +55 -0
  108. data/lib/mongoid/extensions/string.rb +199 -0
  109. data/lib/mongoid/extensions/symbol.rb +54 -0
  110. data/lib/mongoid/extensions/time.rb +88 -0
  111. data/lib/mongoid/extensions/time_with_zone.rb +56 -0
  112. data/lib/mongoid/extensions/true_class.rb +38 -0
  113. data/lib/mongoid/factory.rb +46 -0
  114. data/lib/mongoid/fields.rb +542 -0
  115. data/lib/mongoid/fields/foreign_key.rb +174 -0
  116. data/lib/mongoid/fields/localized.rb +73 -0
  117. data/lib/mongoid/fields/standard.rb +273 -0
  118. data/lib/mongoid/fields/validators.rb +2 -0
  119. data/lib/mongoid/fields/validators/macro.rb +92 -0
  120. data/lib/mongoid/findable.rb +133 -0
  121. data/lib/mongoid/identity_map.rb +163 -0
  122. data/lib/mongoid/indexable.rb +147 -0
  123. data/lib/mongoid/indexable/specification.rb +115 -0
  124. data/lib/mongoid/indexable/validators/options.rb +103 -0
  125. data/lib/mongoid/inspectable.rb +59 -0
  126. data/lib/mongoid/interceptable.rb +265 -0
  127. data/lib/mongoid/loggable.rb +69 -0
  128. data/lib/mongoid/matchable.rb +152 -0
  129. data/lib/mongoid/matchable/all.rb +27 -0
  130. data/lib/mongoid/matchable/and.rb +30 -0
  131. data/lib/mongoid/matchable/default.rb +72 -0
  132. data/lib/mongoid/matchable/exists.rb +23 -0
  133. data/lib/mongoid/matchable/gt.rb +21 -0
  134. data/lib/mongoid/matchable/gte.rb +21 -0
  135. data/lib/mongoid/matchable/in.rb +24 -0
  136. data/lib/mongoid/matchable/lt.rb +21 -0
  137. data/lib/mongoid/matchable/lte.rb +21 -0
  138. data/lib/mongoid/matchable/ne.rb +21 -0
  139. data/lib/mongoid/matchable/nin.rb +21 -0
  140. data/lib/mongoid/matchable/or.rb +33 -0
  141. data/lib/mongoid/matchable/size.rb +21 -0
  142. data/lib/mongoid/persistable.rb +207 -0
  143. data/lib/mongoid/persistable/creatable.rb +189 -0
  144. data/lib/mongoid/persistable/deletable.rb +149 -0
  145. data/lib/mongoid/persistable/destroyable.rb +55 -0
  146. data/lib/mongoid/persistable/incrementable.rb +36 -0
  147. data/lib/mongoid/persistable/logical.rb +38 -0
  148. data/lib/mongoid/persistable/poppable.rb +39 -0
  149. data/lib/mongoid/persistable/pullable.rb +55 -0
  150. data/lib/mongoid/persistable/pushable.rb +62 -0
  151. data/lib/mongoid/persistable/renamable.rb +35 -0
  152. data/lib/mongoid/persistable/savable.rb +52 -0
  153. data/lib/mongoid/persistable/settable.rb +33 -0
  154. data/lib/mongoid/persistable/unsettable.rb +36 -0
  155. data/lib/mongoid/persistable/updatable.rb +151 -0
  156. data/lib/mongoid/persistable/upsertable.rb +55 -0
  157. data/lib/mongoid/positional.rb +71 -0
  158. data/lib/mongoid/railtie.rb +156 -0
  159. data/lib/mongoid/railties/database.rake +97 -0
  160. data/lib/mongoid/railties/document.rb +12 -0
  161. data/lib/mongoid/relations.rb +162 -0
  162. data/lib/mongoid/relations/accessors.rb +299 -0
  163. data/lib/mongoid/relations/auto_save.rb +106 -0
  164. data/lib/mongoid/relations/binding.rb +218 -0
  165. data/lib/mongoid/relations/bindings.rb +9 -0
  166. data/lib/mongoid/relations/bindings/embedded/in.rb +63 -0
  167. data/lib/mongoid/relations/bindings/embedded/many.rb +50 -0
  168. data/lib/mongoid/relations/bindings/embedded/one.rb +55 -0
  169. data/lib/mongoid/relations/bindings/referenced/in.rb +65 -0
  170. data/lib/mongoid/relations/bindings/referenced/many.rb +42 -0
  171. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +67 -0
  172. data/lib/mongoid/relations/bindings/referenced/one.rb +44 -0
  173. data/lib/mongoid/relations/builder.rb +57 -0
  174. data/lib/mongoid/relations/builders.rb +104 -0
  175. data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
  176. data/lib/mongoid/relations/builders/embedded/many.rb +36 -0
  177. data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
  178. data/lib/mongoid/relations/builders/nested_attributes/many.rb +174 -0
  179. data/lib/mongoid/relations/builders/nested_attributes/one.rb +126 -0
  180. data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
  181. data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
  182. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +40 -0
  183. data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
  184. data/lib/mongoid/relations/cascading.rb +56 -0
  185. data/lib/mongoid/relations/cascading/delete.rb +44 -0
  186. data/lib/mongoid/relations/cascading/destroy.rb +43 -0
  187. data/lib/mongoid/relations/cascading/nullify.rb +35 -0
  188. data/lib/mongoid/relations/cascading/restrict.rb +39 -0
  189. data/lib/mongoid/relations/constraint.rb +49 -0
  190. data/lib/mongoid/relations/conversions.rb +34 -0
  191. data/lib/mongoid/relations/counter_cache.rb +105 -0
  192. data/lib/mongoid/relations/cyclic.rb +107 -0
  193. data/lib/mongoid/relations/embedded/batchable.rb +355 -0
  194. data/lib/mongoid/relations/embedded/in.rb +231 -0
  195. data/lib/mongoid/relations/embedded/many.rb +639 -0
  196. data/lib/mongoid/relations/embedded/one.rb +223 -0
  197. data/lib/mongoid/relations/macros.rb +356 -0
  198. data/lib/mongoid/relations/many.rb +208 -0
  199. data/lib/mongoid/relations/marshalable.rb +32 -0
  200. data/lib/mongoid/relations/metadata.rb +1174 -0
  201. data/lib/mongoid/relations/nested_builder.rb +74 -0
  202. data/lib/mongoid/relations/one.rb +48 -0
  203. data/lib/mongoid/relations/options.rb +48 -0
  204. data/lib/mongoid/relations/polymorphic.rb +39 -0
  205. data/lib/mongoid/relations/proxy.rb +270 -0
  206. data/lib/mongoid/relations/referenced/in.rb +297 -0
  207. data/lib/mongoid/relations/referenced/many.rb +787 -0
  208. data/lib/mongoid/relations/referenced/many_to_many.rb +486 -0
  209. data/lib/mongoid/relations/referenced/one.rb +290 -0
  210. data/lib/mongoid/relations/reflections.rb +62 -0
  211. data/lib/mongoid/relations/synchronization.rb +169 -0
  212. data/lib/mongoid/relations/targets.rb +2 -0
  213. data/lib/mongoid/relations/targets/enumerable.rb +473 -0
  214. data/lib/mongoid/relations/touchable.rb +94 -0
  215. data/lib/mongoid/reloadable.rb +95 -0
  216. data/lib/mongoid/scopable.rb +379 -0
  217. data/lib/mongoid/selectable.rb +59 -0
  218. data/lib/mongoid/serializable.rb +170 -0
  219. data/lib/mongoid/sessions.rb +330 -0
  220. data/lib/mongoid/sessions/factory.rb +129 -0
  221. data/lib/mongoid/sessions/mongo_uri.rb +93 -0
  222. data/lib/mongoid/sessions/options.rb +141 -0
  223. data/lib/mongoid/sessions/validators.rb +2 -0
  224. data/lib/mongoid/sessions/validators/storage.rb +49 -0
  225. data/lib/mongoid/shardable.rb +65 -0
  226. data/lib/mongoid/state.rb +97 -0
  227. data/lib/mongoid/threaded.rb +383 -0
  228. data/lib/mongoid/threaded/lifecycle.rb +164 -0
  229. data/lib/mongoid/timestamps.rb +15 -0
  230. data/lib/mongoid/timestamps/created.rb +30 -0
  231. data/lib/mongoid/timestamps/created/short.rb +19 -0
  232. data/lib/mongoid/timestamps/short.rb +10 -0
  233. data/lib/mongoid/timestamps/updated.rb +39 -0
  234. data/lib/mongoid/timestamps/updated/short.rb +19 -0
  235. data/lib/mongoid/traversable.rb +192 -0
  236. data/lib/mongoid/unit_of_work.rb +61 -0
  237. data/lib/mongoid/validatable.rb +180 -0
  238. data/lib/mongoid/validatable/associated.rb +48 -0
  239. data/lib/mongoid/validatable/format.rb +20 -0
  240. data/lib/mongoid/validatable/length.rb +20 -0
  241. data/lib/mongoid/validatable/localizable.rb +30 -0
  242. data/lib/mongoid/validatable/macros.rb +94 -0
  243. data/lib/mongoid/validatable/presence.rb +86 -0
  244. data/lib/mongoid/validatable/queryable.rb +30 -0
  245. data/lib/mongoid/validatable/uniqueness.rb +330 -0
  246. data/lib/mongoid/version.rb +4 -0
  247. data/lib/rack/mongoid.rb +2 -0
  248. data/lib/rack/mongoid/middleware/identity_map.rb +39 -0
  249. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  250. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +76 -0
  251. data/lib/rails/generators/mongoid/model/model_generator.rb +25 -0
  252. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
  253. data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
  254. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
  255. data/lib/rails/generators/mongoid_generator.rb +65 -0
  256. data/lib/rails/mongoid.rb +180 -0
  257. data/lib/support/ruby_version.rb +26 -0
  258. data/spec/app/models/account.rb +28 -0
  259. data/spec/app/models/acolyte.rb +17 -0
  260. data/spec/app/models/actor.rb +18 -0
  261. data/spec/app/models/actress.rb +2 -0
  262. data/spec/app/models/address.rb +77 -0
  263. data/spec/app/models/address_component.rb +5 -0
  264. data/spec/app/models/address_number.rb +6 -0
  265. data/spec/app/models/agency.rb +5 -0
  266. data/spec/app/models/agent.rb +12 -0
  267. data/spec/app/models/album.rb +14 -0
  268. data/spec/app/models/alert.rb +5 -0
  269. data/spec/app/models/animal.rb +25 -0
  270. data/spec/app/models/answer.rb +4 -0
  271. data/spec/app/models/appointment.rb +7 -0
  272. data/spec/app/models/article.rb +10 -0
  273. data/spec/app/models/artist.rb +66 -0
  274. data/spec/app/models/artwork.rb +4 -0
  275. data/spec/app/models/audio.rb +5 -0
  276. data/spec/app/models/augmentation.rb +11 -0
  277. data/spec/app/models/author.rb +4 -0
  278. data/spec/app/models/band.rb +26 -0
  279. data/spec/app/models/bar.rb +10 -0
  280. data/spec/app/models/basic.rb +6 -0
  281. data/spec/app/models/bed.rb +1 -0
  282. data/spec/app/models/big_palette.rb +2 -0
  283. data/spec/app/models/birthday.rb +13 -0
  284. data/spec/app/models/book.rb +13 -0
  285. data/spec/app/models/breed.rb +4 -0
  286. data/spec/app/models/browser.rb +6 -0
  287. data/spec/app/models/building.rb +5 -0
  288. data/spec/app/models/building_address.rb +5 -0
  289. data/spec/app/models/bus.rb +7 -0
  290. data/spec/app/models/business.rb +5 -0
  291. data/spec/app/models/callback_recorder.rb +25 -0
  292. data/spec/app/models/callback_test.rb +9 -0
  293. data/spec/app/models/canvas.rb +25 -0
  294. data/spec/app/models/car.rb +1 -0
  295. data/spec/app/models/cat.rb +8 -0
  296. data/spec/app/models/category.rb +8 -0
  297. data/spec/app/models/child.rb +4 -0
  298. data/spec/app/models/child_doc.rb +22 -0
  299. data/spec/app/models/church.rb +4 -0
  300. data/spec/app/models/circle.rb +3 -0
  301. data/spec/app/models/circuit.rb +4 -0
  302. data/spec/app/models/circus.rb +7 -0
  303. data/spec/app/models/code.rb +5 -0
  304. data/spec/app/models/comment.rb +16 -0
  305. data/spec/app/models/contractor.rb +5 -0
  306. data/spec/app/models/cookie.rb +6 -0
  307. data/spec/app/models/country_code.rb +8 -0
  308. data/spec/app/models/definition.rb +7 -0
  309. data/spec/app/models/description.rb +11 -0
  310. data/spec/app/models/dictionary.rb +10 -0
  311. data/spec/app/models/division.rb +10 -0
  312. data/spec/app/models/doctor.rb +12 -0
  313. data/spec/app/models/dog.rb +7 -0
  314. data/spec/app/models/dokument.rb +5 -0
  315. data/spec/app/models/dragon.rb +4 -0
  316. data/spec/app/models/driver.rb +7 -0
  317. data/spec/app/models/drug.rb +6 -0
  318. data/spec/app/models/dungeon.rb +4 -0
  319. data/spec/app/models/email.rb +6 -0
  320. data/spec/app/models/employer.rb +5 -0
  321. data/spec/app/models/entry.rb +6 -0
  322. data/spec/app/models/eraser.rb +1 -0
  323. data/spec/app/models/event.rb +22 -0
  324. data/spec/app/models/exhibition.rb +4 -0
  325. data/spec/app/models/exhibitor.rb +5 -0
  326. data/spec/app/models/eye.rb +9 -0
  327. data/spec/app/models/eye_bowl.rb +9 -0
  328. data/spec/app/models/face.rb +8 -0
  329. data/spec/app/models/favorite.rb +6 -0
  330. data/spec/app/models/filesystem.rb +5 -0
  331. data/spec/app/models/fire_hydrant.rb +6 -0
  332. data/spec/app/models/firefox.rb +4 -0
  333. data/spec/app/models/fish.rb +7 -0
  334. data/spec/app/models/folder.rb +7 -0
  335. data/spec/app/models/folder_item.rb +9 -0
  336. data/spec/app/models/fruits.rb +28 -0
  337. data/spec/app/models/game.rb +19 -0
  338. data/spec/app/models/ghost.rb +7 -0
  339. data/spec/app/models/home.rb +4 -0
  340. data/spec/app/models/house.rb +6 -0
  341. data/spec/app/models/html_writer.rb +3 -0
  342. data/spec/app/models/image.rb +22 -0
  343. data/spec/app/models/implant.rb +16 -0
  344. data/spec/app/models/item.rb +8 -0
  345. data/spec/app/models/jar.rb +7 -0
  346. data/spec/app/models/label.rb +40 -0
  347. data/spec/app/models/language.rb +5 -0
  348. data/spec/app/models/lat_lng.rb +15 -0
  349. data/spec/app/models/league.rb +11 -0
  350. data/spec/app/models/learner.rb +2 -0
  351. data/spec/app/models/line_item.rb +6 -0
  352. data/spec/app/models/location.rb +8 -0
  353. data/spec/app/models/login.rb +8 -0
  354. data/spec/app/models/manufacturer.rb +7 -0
  355. data/spec/app/models/meat.rb +4 -0
  356. data/spec/app/models/membership.rb +4 -0
  357. data/spec/app/models/mixed_drink.rb +4 -0
  358. data/spec/app/models/movie.rb +13 -0
  359. data/spec/app/models/my_hash.rb +2 -0
  360. data/spec/app/models/name.rb +23 -0
  361. data/spec/app/models/node.rb +5 -0
  362. data/spec/app/models/note.rb +12 -0
  363. data/spec/app/models/ordered_post.rb +6 -0
  364. data/spec/app/models/ordered_preference.rb +6 -0
  365. data/spec/app/models/oscar.rb +15 -0
  366. data/spec/app/models/override.rb +16 -0
  367. data/spec/app/models/ownable.rb +6 -0
  368. data/spec/app/models/owner.rb +6 -0
  369. data/spec/app/models/pack.rb +3 -0
  370. data/spec/app/models/page.rb +5 -0
  371. data/spec/app/models/page_question.rb +4 -0
  372. data/spec/app/models/palette.rb +7 -0
  373. data/spec/app/models/parent.rb +5 -0
  374. data/spec/app/models/parent_doc.rb +6 -0
  375. data/spec/app/models/passport.rb +5 -0
  376. data/spec/app/models/patient.rb +9 -0
  377. data/spec/app/models/pdf_writer.rb +3 -0
  378. data/spec/app/models/pencil.rb +1 -0
  379. data/spec/app/models/person.rb +205 -0
  380. data/spec/app/models/pet.rb +23 -0
  381. data/spec/app/models/pet_owner.rb +6 -0
  382. data/spec/app/models/phone.rb +11 -0
  383. data/spec/app/models/pizza.rb +7 -0
  384. data/spec/app/models/player.rb +35 -0
  385. data/spec/app/models/post.rb +44 -0
  386. data/spec/app/models/powerup.rb +11 -0
  387. data/spec/app/models/preference.rb +9 -0
  388. data/spec/app/models/princess.rb +8 -0
  389. data/spec/app/models/product.rb +15 -0
  390. data/spec/app/models/profile.rb +5 -0
  391. data/spec/app/models/pronunciation.rb +5 -0
  392. data/spec/app/models/purchase.rb +4 -0
  393. data/spec/app/models/question.rb +8 -0
  394. data/spec/app/models/quiz.rb +7 -0
  395. data/spec/app/models/rating.rb +8 -0
  396. data/spec/app/models/record.rb +46 -0
  397. data/spec/app/models/registry.rb +4 -0
  398. data/spec/app/models/role.rb +7 -0
  399. data/spec/app/models/root_category.rb +4 -0
  400. data/spec/app/models/sandwich.rb +4 -0
  401. data/spec/app/models/scheduler.rb +7 -0
  402. data/spec/app/models/seo.rb +7 -0
  403. data/spec/app/models/series.rb +4 -0
  404. data/spec/app/models/server.rb +13 -0
  405. data/spec/app/models/service.rb +22 -0
  406. data/spec/app/models/shape.rb +12 -0
  407. data/spec/app/models/shelf.rb +5 -0
  408. data/spec/app/models/shipping_container.rb +5 -0
  409. data/spec/app/models/shipping_pack.rb +3 -0
  410. data/spec/app/models/shop.rb +6 -0
  411. data/spec/app/models/short_agent.rb +4 -0
  412. data/spec/app/models/short_quiz.rb +5 -0
  413. data/spec/app/models/slave.rb +6 -0
  414. data/spec/app/models/song.rb +8 -0
  415. data/spec/app/models/sound.rb +5 -0
  416. data/spec/app/models/square.rb +4 -0
  417. data/spec/app/models/strategy.rb +3 -0
  418. data/spec/app/models/sub_item.rb +3 -0
  419. data/spec/app/models/subscription.rb +4 -0
  420. data/spec/app/models/survey.rb +5 -0
  421. data/spec/app/models/symptom.rb +6 -0
  422. data/spec/app/models/tag.rb +8 -0
  423. data/spec/app/models/target.rb +5 -0
  424. data/spec/app/models/template.rb +5 -0
  425. data/spec/app/models/thing.rb +9 -0
  426. data/spec/app/models/title.rb +3 -0
  427. data/spec/app/models/tool.rb +8 -0
  428. data/spec/app/models/topping.rb +5 -0
  429. data/spec/app/models/track.rb +38 -0
  430. data/spec/app/models/translation.rb +5 -0
  431. data/spec/app/models/tree.rb +9 -0
  432. data/spec/app/models/truck.rb +3 -0
  433. data/spec/app/models/user.rb +21 -0
  434. data/spec/app/models/user_account.rb +10 -0
  435. data/spec/app/models/validation_callback.rb +10 -0
  436. data/spec/app/models/vehicle.rb +11 -0
  437. data/spec/app/models/version.rb +5 -0
  438. data/spec/app/models/vet_visit.rb +5 -0
  439. data/spec/app/models/video.rb +13 -0
  440. data/spec/app/models/weapon.rb +11 -0
  441. data/spec/app/models/wiki_page.rb +14 -0
  442. data/spec/app/models/word.rb +15 -0
  443. data/spec/app/models/word_origin.rb +11 -0
  444. data/spec/app/models/writer.rb +11 -0
  445. data/spec/config/mongoid.yml +38 -0
  446. data/spec/mongoid/atomic/modifiers_spec.rb +456 -0
  447. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +118 -0
  448. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +110 -0
  449. data/spec/mongoid/atomic/paths/root_spec.rb +48 -0
  450. data/spec/mongoid/atomic/paths_spec.rb +270 -0
  451. data/spec/mongoid/atomic_spec.rb +365 -0
  452. data/spec/mongoid/attributes/nested_spec.rb +4832 -0
  453. data/spec/mongoid/attributes/readonly_spec.rb +169 -0
  454. data/spec/mongoid/attributes_spec.rb +1412 -0
  455. data/spec/mongoid/changeable_spec.rb +1507 -0
  456. data/spec/mongoid/composable_spec.rb +24 -0
  457. data/spec/mongoid/config/environment_spec.rb +83 -0
  458. data/spec/mongoid/config/options_spec.rb +56 -0
  459. data/spec/mongoid/config_spec.rb +318 -0
  460. data/spec/mongoid/contextual/aggregable/memory_spec.rb +293 -0
  461. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +455 -0
  462. data/spec/mongoid/contextual/atomic_spec.rb +529 -0
  463. data/spec/mongoid/contextual/find_and_modify_spec.rb +220 -0
  464. data/spec/mongoid/contextual/geo_near_spec.rb +405 -0
  465. data/spec/mongoid/contextual/map_reduce_spec.rb +464 -0
  466. data/spec/mongoid/contextual/memory_spec.rb +1236 -0
  467. data/spec/mongoid/contextual/mongo_spec.rb +1843 -0
  468. data/spec/mongoid/contextual/text_search_spec.rb +207 -0
  469. data/spec/mongoid/copyable_spec.rb +393 -0
  470. data/spec/mongoid/criteria/findable_spec.rb +1189 -0
  471. data/spec/mongoid/criteria/inspectable_spec.rb +27 -0
  472. data/spec/mongoid/criteria/marshalable_spec.rb +28 -0
  473. data/spec/mongoid/criteria/modifiable_spec.rb +1063 -0
  474. data/spec/mongoid/criteria/scopable_spec.rb +391 -0
  475. data/spec/mongoid/criteria_spec.rb +3821 -0
  476. data/spec/mongoid/document_spec.rb +1205 -0
  477. data/spec/mongoid/equality_spec.rb +241 -0
  478. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +29 -0
  479. data/spec/mongoid/errors/callback_spec.rb +29 -0
  480. data/spec/mongoid/errors/delete_restriction_spec.rb +29 -0
  481. data/spec/mongoid/errors/document_not_found_spec.rb +104 -0
  482. data/spec/mongoid/errors/eager_load_spec.rb +29 -0
  483. data/spec/mongoid/errors/invalid_collection_spec.rb +36 -0
  484. data/spec/mongoid/errors/invalid_config_option_spec.rb +29 -0
  485. data/spec/mongoid/errors/invalid_field_option_spec.rb +29 -0
  486. data/spec/mongoid/errors/invalid_field_spec.rb +37 -0
  487. data/spec/mongoid/errors/invalid_find_spec.rb +29 -0
  488. data/spec/mongoid/errors/invalid_includes_spec.rb +40 -0
  489. data/spec/mongoid/errors/invalid_index_spec.rb +29 -0
  490. data/spec/mongoid/errors/invalid_options_spec.rb +29 -0
  491. data/spec/mongoid/errors/invalid_path_spec.rb +23 -0
  492. data/spec/mongoid/errors/invalid_scope_spec.rb +29 -0
  493. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +17 -0
  494. data/spec/mongoid/errors/invalid_storage_options_spec.rb +29 -0
  495. data/spec/mongoid/errors/invalid_time_spec.rb +29 -0
  496. data/spec/mongoid/errors/inverse_not_found_spec.rb +29 -0
  497. data/spec/mongoid/errors/mixed_relations_spec.rb +29 -0
  498. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +29 -0
  499. data/spec/mongoid/errors/mongoid_error_spec.rb +48 -0
  500. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +29 -0
  501. data/spec/mongoid/errors/no_environment_spec.rb +29 -0
  502. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +29 -0
  503. data/spec/mongoid/errors/no_metadata_spec.rb +23 -0
  504. data/spec/mongoid/errors/no_parent_spec.rb +29 -0
  505. data/spec/mongoid/errors/no_session_config_spec.rb +29 -0
  506. data/spec/mongoid/errors/no_session_database_spec.rb +29 -0
  507. data/spec/mongoid/errors/no_session_hosts_spec.rb +29 -0
  508. data/spec/mongoid/errors/no_sessions_config_spec.rb +29 -0
  509. data/spec/mongoid/errors/readonly_attribute_spec.rb +29 -0
  510. data/spec/mongoid/errors/scope_overwrite_spec.rb +29 -0
  511. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +29 -0
  512. data/spec/mongoid/errors/unknown_attribute_spec.rb +29 -0
  513. data/spec/mongoid/errors/unsaved_document_spec.rb +37 -0
  514. data/spec/mongoid/errors/unsupported_javascript_spec.rb +29 -0
  515. data/spec/mongoid/errors/validations_spec.rb +45 -0
  516. data/spec/mongoid/extensions/array_spec.rb +638 -0
  517. data/spec/mongoid/extensions/big_decimal_spec.rb +104 -0
  518. data/spec/mongoid/extensions/binary_spec.rb +60 -0
  519. data/spec/mongoid/extensions/boolean_spec.rb +135 -0
  520. data/spec/mongoid/extensions/date_spec.rb +235 -0
  521. data/spec/mongoid/extensions/date_time_spec.rb +155 -0
  522. data/spec/mongoid/extensions/false_class_spec.rb +42 -0
  523. data/spec/mongoid/extensions/float_spec.rb +133 -0
  524. data/spec/mongoid/extensions/hash_spec.rb +333 -0
  525. data/spec/mongoid/extensions/integer_spec.rb +136 -0
  526. data/spec/mongoid/extensions/module_spec.rb +42 -0
  527. data/spec/mongoid/extensions/nil_class_spec.rb +11 -0
  528. data/spec/mongoid/extensions/object_id_spec.rb +946 -0
  529. data/spec/mongoid/extensions/object_spec.rb +292 -0
  530. data/spec/mongoid/extensions/range_spec.rb +105 -0
  531. data/spec/mongoid/extensions/regexp_spec.rb +47 -0
  532. data/spec/mongoid/extensions/set_spec.rb +33 -0
  533. data/spec/mongoid/extensions/string_spec.rb +357 -0
  534. data/spec/mongoid/extensions/symbol_spec.rb +76 -0
  535. data/spec/mongoid/extensions/time_spec.rb +467 -0
  536. data/spec/mongoid/extensions/time_with_zone_spec.rb +405 -0
  537. data/spec/mongoid/extensions/true_class_spec.rb +42 -0
  538. data/spec/mongoid/extensions_spec.rb +15 -0
  539. data/spec/mongoid/factory_spec.rb +185 -0
  540. data/spec/mongoid/fields/foreign_key_spec.rb +694 -0
  541. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +184 -0
  542. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +201 -0
  543. data/spec/mongoid/fields/localized_spec.rb +386 -0
  544. data/spec/mongoid/fields/standard_spec.rb +166 -0
  545. data/spec/mongoid/fields_spec.rb +1229 -0
  546. data/spec/mongoid/findable_spec.rb +342 -0
  547. data/spec/mongoid/identity_map_spec.rb +564 -0
  548. data/spec/mongoid/indexable/specification_spec.rb +87 -0
  549. data/spec/mongoid/indexable_spec.rb +504 -0
  550. data/spec/mongoid/inspectable_spec.rb +49 -0
  551. data/spec/mongoid/interceptable_spec.rb +1564 -0
  552. data/spec/mongoid/loggable_spec.rb +21 -0
  553. data/spec/mongoid/matchable/all_spec.rb +31 -0
  554. data/spec/mongoid/matchable/and_spec.rb +162 -0
  555. data/spec/mongoid/matchable/default_spec.rb +130 -0
  556. data/spec/mongoid/matchable/exists_spec.rb +57 -0
  557. data/spec/mongoid/matchable/gt_spec.rb +75 -0
  558. data/spec/mongoid/matchable/gte_spec.rb +74 -0
  559. data/spec/mongoid/matchable/in_spec.rb +25 -0
  560. data/spec/mongoid/matchable/lt_spec.rb +74 -0
  561. data/spec/mongoid/matchable/lte_spec.rb +74 -0
  562. data/spec/mongoid/matchable/ne_spec.rb +25 -0
  563. data/spec/mongoid/matchable/nin_spec.rb +25 -0
  564. data/spec/mongoid/matchable/or_spec.rb +106 -0
  565. data/spec/mongoid/matchable/size_spec.rb +25 -0
  566. data/spec/mongoid/matchable_spec.rb +532 -0
  567. data/spec/mongoid/persistable/creatable_spec.rb +512 -0
  568. data/spec/mongoid/persistable/deletable_spec.rb +205 -0
  569. data/spec/mongoid/persistable/destroyable_spec.rb +148 -0
  570. data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
  571. data/spec/mongoid/persistable/logical_spec.rb +143 -0
  572. data/spec/mongoid/persistable/poppable_spec.rb +115 -0
  573. data/spec/mongoid/persistable/pullable_spec.rb +228 -0
  574. data/spec/mongoid/persistable/pushable_spec.rb +258 -0
  575. data/spec/mongoid/persistable/renamable_spec.rb +135 -0
  576. data/spec/mongoid/persistable/savable_spec.rb +432 -0
  577. data/spec/mongoid/persistable/settable_spec.rb +139 -0
  578. data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
  579. data/spec/mongoid/persistable/updatable_spec.rb +522 -0
  580. data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
  581. data/spec/mongoid/persistable_spec.rb +206 -0
  582. data/spec/mongoid/positional_spec.rb +227 -0
  583. data/spec/mongoid/railties/document_spec.rb +24 -0
  584. data/spec/mongoid/relations/accessors_spec.rb +736 -0
  585. data/spec/mongoid/relations/auto_save_spec.rb +261 -0
  586. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +171 -0
  587. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +54 -0
  588. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +77 -0
  589. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +241 -0
  590. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +153 -0
  591. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +178 -0
  592. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +131 -0
  593. data/spec/mongoid/relations/builders/embedded/in_spec.rb +34 -0
  594. data/spec/mongoid/relations/builders/embedded/many_spec.rb +132 -0
  595. data/spec/mongoid/relations/builders/embedded/one_spec.rb +99 -0
  596. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +234 -0
  597. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +250 -0
  598. data/spec/mongoid/relations/builders/referenced/in_spec.rb +241 -0
  599. data/spec/mongoid/relations/builders/referenced/many_spec.rb +137 -0
  600. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +178 -0
  601. data/spec/mongoid/relations/builders/referenced/one_spec.rb +124 -0
  602. data/spec/mongoid/relations/builders_spec.rb +226 -0
  603. data/spec/mongoid/relations/cascading/delete_spec.rb +101 -0
  604. data/spec/mongoid/relations/cascading/destroy_spec.rb +47 -0
  605. data/spec/mongoid/relations/cascading/nullify_spec.rb +32 -0
  606. data/spec/mongoid/relations/cascading/restrict_spec.rb +68 -0
  607. data/spec/mongoid/relations/cascading_spec.rb +355 -0
  608. data/spec/mongoid/relations/constraint_spec.rb +74 -0
  609. data/spec/mongoid/relations/conversions_spec.rb +126 -0
  610. data/spec/mongoid/relations/counter_cache_spec.rb +205 -0
  611. data/spec/mongoid/relations/cyclic_spec.rb +156 -0
  612. data/spec/mongoid/relations/embedded/dirty_spec.rb +65 -0
  613. data/spec/mongoid/relations/embedded/in_spec.rb +579 -0
  614. data/spec/mongoid/relations/embedded/many_spec.rb +3781 -0
  615. data/spec/mongoid/relations/embedded/one_spec.rb +1014 -0
  616. data/spec/mongoid/relations/macros_spec.rb +613 -0
  617. data/spec/mongoid/relations/metadata_spec.rb +1917 -0
  618. data/spec/mongoid/relations/options_spec.rb +35 -0
  619. data/spec/mongoid/relations/polymorphic_spec.rb +128 -0
  620. data/spec/mongoid/relations/proxy_spec.rb +48 -0
  621. data/spec/mongoid/relations/referenced/in_spec.rb +1435 -0
  622. data/spec/mongoid/relations/referenced/many_spec.rb +3546 -0
  623. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +3556 -0
  624. data/spec/mongoid/relations/referenced/one_spec.rb +1289 -0
  625. data/spec/mongoid/relations/reflections_spec.rb +101 -0
  626. data/spec/mongoid/relations/synchronization_spec.rb +449 -0
  627. data/spec/mongoid/relations/targets/enumerable_spec.rb +1710 -0
  628. data/spec/mongoid/relations/touchable_spec.rb +296 -0
  629. data/spec/mongoid/relations_spec.rb +188 -0
  630. data/spec/mongoid/reloadable_spec.rb +305 -0
  631. data/spec/mongoid/scopable_spec.rb +926 -0
  632. data/spec/mongoid/selectable_spec.rb +134 -0
  633. data/spec/mongoid/serializable_spec.rb +862 -0
  634. data/spec/mongoid/sessions/factory_spec.rb +312 -0
  635. data/spec/mongoid/sessions/mongo_uri_spec.rb +103 -0
  636. data/spec/mongoid/sessions/options_spec.rb +71 -0
  637. data/spec/mongoid/sessions_spec.rb +1078 -0
  638. data/spec/mongoid/shardable_spec.rb +61 -0
  639. data/spec/mongoid/state_spec.rb +102 -0
  640. data/spec/mongoid/threaded_spec.rb +258 -0
  641. data/spec/mongoid/timestamps/created/short_spec.rb +51 -0
  642. data/spec/mongoid/timestamps/created_spec.rb +44 -0
  643. data/spec/mongoid/timestamps/updated/short_spec.rb +90 -0
  644. data/spec/mongoid/timestamps/updated_spec.rb +86 -0
  645. data/spec/mongoid/timestamps_spec.rb +112 -0
  646. data/spec/mongoid/traversable_spec.rb +244 -0
  647. data/spec/mongoid/unit_of_work_spec.rb +196 -0
  648. data/spec/mongoid/validatable/associated_spec.rb +183 -0
  649. data/spec/mongoid/validatable/format_spec.rb +83 -0
  650. data/spec/mongoid/validatable/length_spec.rb +119 -0
  651. data/spec/mongoid/validatable/numericality_spec.rb +30 -0
  652. data/spec/mongoid/validatable/presence_spec.rb +511 -0
  653. data/spec/mongoid/validatable/uniqueness_spec.rb +2305 -0
  654. data/spec/mongoid/validatable_spec.rb +309 -0
  655. data/spec/mongoid_spec.rb +74 -0
  656. data/spec/rack/mongoid/middleware/identity_map_spec.rb +72 -0
  657. data/spec/rails/mongoid_spec.rb +462 -0
  658. data/spec/spec_helper.rb +103 -0
  659. metadata +1159 -0
@@ -0,0 +1,2305 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Validatable::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
+ expect(websters).to_not be_valid
33
+ end
34
+
35
+ it "adds the uniqueness error" do
36
+ websters.valid?
37
+ expect(websters.errors[:name]).to_not be_nil
38
+ end
39
+
40
+ it "clears the persistence options in the thread local" do
41
+ websters.valid?
42
+ expect(Dictionary.persistence_options).to 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
+ expect(oxford).to be_valid
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ context "when the document contains no compound key" do
60
+
61
+ context "when validating a relation" do
62
+
63
+ before do
64
+ Word.validates_uniqueness_of :dictionary
65
+ end
66
+
67
+ after do
68
+ Word.reset_callbacks(:validate)
69
+ end
70
+
71
+ context "when the attribute id is unique" do
72
+
73
+ let(:dictionary) do
74
+ Dictionary.create
75
+ end
76
+
77
+ let(:word) do
78
+ Word.new(dictionary: dictionary)
79
+ end
80
+
81
+ it "returns true" do
82
+ expect(word).to be_valid
83
+ end
84
+ end
85
+ end
86
+
87
+ context "when the field name is aliased" do
88
+
89
+ before do
90
+ Dictionary.create!(language: "en")
91
+ end
92
+
93
+ let(:dictionary) do
94
+ Dictionary.new(language: "en")
95
+ end
96
+
97
+ after do
98
+ Dictionary.reset_callbacks(:validate)
99
+ end
100
+
101
+ context "when the validation uses the aliased name" do
102
+
103
+ before do
104
+ Dictionary.validates_uniqueness_of :language
105
+ end
106
+
107
+ it "correctly detects a uniqueness conflict" do
108
+ expect(dictionary).to_not be_valid
109
+ end
110
+
111
+ it "adds the uniqueness error to the aliased field name" do
112
+ dictionary.valid?
113
+ expect(dictionary.errors).to have_key(:language)
114
+ expect(dictionary.errors[:language]).to eq([ "is already taken" ])
115
+ end
116
+ end
117
+
118
+ context "when the validation uses the underlying field name" do
119
+
120
+ before do
121
+ Dictionary.validates_uniqueness_of :l
122
+ end
123
+
124
+ it "correctly detects a uniqueness conflict" do
125
+ expect(dictionary).to_not be_valid
126
+ end
127
+
128
+ it "adds the uniqueness error to the underlying field name" do
129
+ dictionary.valid?
130
+ expect(dictionary.errors).to have_key(:l)
131
+ expect(dictionary.errors[:l]).to eq([ "is already taken" ])
132
+ end
133
+ end
134
+ end
135
+
136
+ context "when the field is localized" do
137
+
138
+ context "when no scope is provided" do
139
+
140
+ context "when case sensitive is true" do
141
+
142
+ before do
143
+ Dictionary.validates_uniqueness_of :description
144
+ end
145
+
146
+ after do
147
+ Dictionary.reset_callbacks(:validate)
148
+ end
149
+
150
+ context "when the attribute is unique" do
151
+
152
+ context "when single localization" do
153
+
154
+ before do
155
+ Dictionary.with(safe: true).create(description: "english")
156
+ end
157
+
158
+ let(:dictionary) do
159
+ Dictionary.new(description: "English")
160
+ end
161
+
162
+ it "returns true" do
163
+ expect(dictionary).to be_valid
164
+ end
165
+ end
166
+
167
+ context "when multiple localizations" do
168
+
169
+ before do
170
+ Dictionary.with(safe: true).
171
+ create(description_translations: { "en" => "english", "de" => "german" })
172
+ end
173
+
174
+ let(:dictionary) do
175
+ Dictionary.new(description_translations: { "en" => "English", "de" => "German" })
176
+ end
177
+
178
+ it "returns true" do
179
+ expect(dictionary).to be_valid
180
+ end
181
+ end
182
+ end
183
+
184
+ context "when the attribute is not unique" do
185
+
186
+ context "when the document is not the match" do
187
+
188
+ context "when single localization" do
189
+
190
+ before do
191
+ Dictionary.with(safe: true).create(description: "english")
192
+ end
193
+
194
+ let(:dictionary) do
195
+ Dictionary.new(description: "english")
196
+ end
197
+
198
+ it "returns false" do
199
+ expect(dictionary).to_not be_valid
200
+ end
201
+
202
+ it "adds the uniqueness error" do
203
+ dictionary.valid?
204
+ expect(dictionary.errors[:description]).to eq([ "is already taken" ])
205
+ end
206
+ end
207
+
208
+ context "when multiple localizations" do
209
+
210
+ before do
211
+ Dictionary.with(safe: true).
212
+ create(description_translations: { "en" => "english", "de" => "german" })
213
+ end
214
+
215
+ let(:dictionary) do
216
+ Dictionary.new(description_translations: { "en" => "english", "de" => "German" })
217
+ end
218
+
219
+ it "returns false" do
220
+ expect(dictionary).to_not be_valid
221
+ end
222
+
223
+ it "adds the uniqueness error" do
224
+ dictionary.valid?
225
+ expect(dictionary.errors[:description]).to eq([ "is already taken" ])
226
+ end
227
+ end
228
+ end
229
+ end
230
+ end
231
+
232
+ context "when case sensitive is false" do
233
+
234
+ before do
235
+ Dictionary.validates_uniqueness_of :description, case_sensitive: false
236
+ end
237
+
238
+ after do
239
+ Dictionary.reset_callbacks(:validate)
240
+ end
241
+
242
+ context "when the attribute is unique" do
243
+
244
+ context "when there are no special characters" do
245
+
246
+ before do
247
+ Dictionary.with(safe: true).create(description: "english")
248
+ end
249
+
250
+ let(:dictionary) do
251
+ Dictionary.new(description: "german")
252
+ end
253
+
254
+ it "returns true" do
255
+ expect(dictionary).to be_valid
256
+ end
257
+ end
258
+
259
+ context "when special characters exist" do
260
+
261
+ before do
262
+ Dictionary.with(safe: true).create(description: "english")
263
+ end
264
+
265
+ let(:dictionary) do
266
+ Dictionary.new(description: "en@gl.ish")
267
+ end
268
+
269
+ it "returns true" do
270
+ expect(dictionary).to be_valid
271
+ end
272
+ end
273
+ end
274
+
275
+ context "when the attribute is not unique" do
276
+
277
+ context "when the document is not the match" do
278
+
279
+ context "when signle localization" do
280
+
281
+ before do
282
+ Dictionary.with(safe: true).create(description: "english")
283
+ end
284
+
285
+ let(:dictionary) do
286
+ Dictionary.new(description: "English")
287
+ end
288
+
289
+ it "returns false" do
290
+ expect(dictionary).to_not be_valid
291
+ end
292
+
293
+ it "adds the uniqueness error" do
294
+ dictionary.valid?
295
+ expect(dictionary.errors[:description]).to eq([ "is already taken" ])
296
+ end
297
+ end
298
+
299
+ context "when multiple localizations" do
300
+
301
+ before do
302
+ Dictionary.with(safe: true).
303
+ create(description_translations: { "en" => "english", "de" => "german" })
304
+ end
305
+
306
+ let(:dictionary) do
307
+ Dictionary.new(description_translations: { "en" => "English", "de" => "German" })
308
+ end
309
+
310
+ it "returns false" do
311
+ expect(dictionary).to_not be_valid
312
+ end
313
+
314
+ it "adds the uniqueness error" do
315
+ dictionary.valid?
316
+ expect(dictionary.errors[:description]).to eq([ "is already taken" ])
317
+ end
318
+ end
319
+ end
320
+
321
+ context "when the document is the match in the database" do
322
+
323
+ let!(:dictionary) do
324
+ Dictionary.with(safe: true).create(description: "english")
325
+ end
326
+
327
+ it "returns true" do
328
+ expect(dictionary).to be_valid
329
+ end
330
+ end
331
+ end
332
+ end
333
+ end
334
+
335
+ context "when a scope is provided" do
336
+
337
+ before do
338
+ Dictionary.validates_uniqueness_of :description, scope: :name
339
+ end
340
+
341
+ after do
342
+ Dictionary.reset_callbacks(:validate)
343
+ end
344
+
345
+ context "when the attribute is not unique in the scope" do
346
+
347
+ context "when the document is not the match" do
348
+
349
+ before do
350
+ Dictionary.with(safe: true).
351
+ create(description: "english", name: "test")
352
+ end
353
+
354
+ let(:dictionary) do
355
+ Dictionary.new(description: "english", name: "test")
356
+ end
357
+
358
+ it "returns false" do
359
+ expect(dictionary).to_not be_valid
360
+ end
361
+
362
+ it "adds the uniqueness error" do
363
+ dictionary.valid?
364
+ expect(dictionary.errors[:description]).to eq([ "is already taken" ])
365
+ end
366
+ end
367
+ end
368
+ end
369
+ end
370
+
371
+ context "when no scope is provided" do
372
+
373
+ before do
374
+ Dictionary.validates_uniqueness_of :name
375
+ end
376
+
377
+ after do
378
+ Dictionary.reset_callbacks(:validate)
379
+ end
380
+
381
+ context "when the attribute is unique" do
382
+
383
+ let!(:oxford) do
384
+ Dictionary.create(name: "Oxford")
385
+ end
386
+
387
+ let(:dictionary) do
388
+ Dictionary.new(name: "Webster")
389
+ end
390
+
391
+ it "returns true" do
392
+ expect(dictionary).to be_valid
393
+ end
394
+
395
+ context "when subsequently cloning the document" do
396
+
397
+ let(:clone) do
398
+ oxford.clone
399
+ end
400
+
401
+ it "returns false for the clone" do
402
+ expect(clone).to_not be_valid
403
+ end
404
+ end
405
+ end
406
+
407
+ context "when the attribute is not unique" do
408
+
409
+ context "when the document is not the match" do
410
+
411
+ before do
412
+ Dictionary.create(name: "Oxford")
413
+ end
414
+
415
+ let!(:dictionary) do
416
+ Dictionary.new(name: "Oxford")
417
+ end
418
+
419
+ it "returns false" do
420
+ expect(dictionary).to_not be_valid
421
+ end
422
+
423
+ it "adds the uniqueness error" do
424
+ dictionary.valid?
425
+ expect(dictionary.errors[:name]).to eq([ "is already taken" ])
426
+ end
427
+ end
428
+
429
+ context "when the document is the match in the database" do
430
+
431
+ context "when the field has changed" do
432
+
433
+ let!(:dictionary) do
434
+ Dictionary.create(name: "Oxford")
435
+ end
436
+
437
+ it "returns true" do
438
+ expect(dictionary).to be_valid
439
+ end
440
+ end
441
+
442
+ context "when the field has not changed" do
443
+
444
+ before do
445
+ Dictionary.default_scoping = nil
446
+ end
447
+
448
+ let!(:dictionary) do
449
+ Dictionary.create!(name: "Oxford")
450
+ end
451
+
452
+ let!(:from_db) do
453
+ Dictionary.find(dictionary.id)
454
+ end
455
+
456
+ it "returns true" do
457
+ expect(from_db).to be_valid
458
+ end
459
+
460
+ it "does not touch the database" do
461
+ Dictionary.should_receive(:where).never
462
+ from_db.valid?
463
+ end
464
+ end
465
+ end
466
+ end
467
+ end
468
+
469
+ context "when a default scope is on the model" do
470
+
471
+ before do
472
+ Dictionary.validates_uniqueness_of :name
473
+ Dictionary.default_scope(Dictionary.where(year: 1990))
474
+ end
475
+
476
+ after do
477
+ Dictionary.send(:strip_default_scope, Dictionary.where(year: 1990))
478
+ Dictionary.reset_callbacks(:validate)
479
+ end
480
+
481
+ context "when the document with the unqiue attribute is not in default scope" do
482
+
483
+ context "when the attribute is not unique" do
484
+
485
+ before do
486
+ Dictionary.with(safe: true).create(name: "Oxford")
487
+ end
488
+
489
+ let(:dictionary) do
490
+ Dictionary.new(name: "Oxford")
491
+ end
492
+
493
+ it "returns false" do
494
+ expect(dictionary).to_not be_valid
495
+ end
496
+ end
497
+ end
498
+ end
499
+
500
+ context "when an aliased scope is provided" do
501
+
502
+ before do
503
+ Dictionary.validates_uniqueness_of :name, scope: :language
504
+ end
505
+
506
+ after do
507
+ Dictionary.reset_callbacks(:validate)
508
+ end
509
+
510
+ context "when the attribute is unique" do
511
+
512
+ before do
513
+ Dictionary.create(name: "Oxford", language: "English")
514
+ end
515
+
516
+ let(:dictionary) do
517
+ Dictionary.new(name: "Webster")
518
+ end
519
+
520
+ it "returns true" do
521
+ expect(dictionary).to be_valid
522
+ end
523
+ end
524
+
525
+ context "when the attribute is unique in the scope" do
526
+
527
+ before do
528
+ Dictionary.create(name: "Oxford", language: "English")
529
+ end
530
+
531
+ let(:dictionary) do
532
+ Dictionary.new(name: "Webster", language: "English")
533
+ end
534
+
535
+ it "returns true" do
536
+ expect(dictionary).to be_valid
537
+ end
538
+ end
539
+
540
+ context "when the attribute is not unique with no scope" do
541
+
542
+ before do
543
+ Dictionary.create(name: "Oxford", language: "English")
544
+ end
545
+
546
+ let(:dictionary) do
547
+ Dictionary.new(name: "Oxford")
548
+ end
549
+
550
+ it "returns true" do
551
+ expect(dictionary).to be_valid
552
+ end
553
+ end
554
+
555
+ context "when the attribute is not unique in another scope" do
556
+
557
+ before do
558
+ Dictionary.create(name: "Oxford", language: "English")
559
+ end
560
+
561
+ let(:dictionary) do
562
+ Dictionary.new(name: "Oxford", language: "Deutsch")
563
+ end
564
+
565
+ it "returns true" do
566
+ expect(dictionary).to be_valid
567
+ end
568
+ end
569
+
570
+ context "when the attribute is not unique in the same scope" do
571
+
572
+ context "when the document is not the match" do
573
+
574
+ before do
575
+ Dictionary.create(name: "Oxford", language: "English")
576
+ end
577
+
578
+ let(:dictionary) do
579
+ Dictionary.new(name: "Oxford", language: "English")
580
+ end
581
+
582
+ it "returns false" do
583
+ expect(dictionary).to_not be_valid
584
+ end
585
+
586
+ it "adds the uniqueness errors" do
587
+ dictionary.valid?
588
+ expect(dictionary.errors[:name]).to eq([ "is already taken" ])
589
+ end
590
+ end
591
+
592
+ context "when the document is the match in the database" do
593
+
594
+ let!(:dictionary) do
595
+ Dictionary.create(name: "Oxford", language: "English")
596
+ end
597
+
598
+ it "returns true" do
599
+ expect(dictionary).to be_valid
600
+ end
601
+ end
602
+ end
603
+ end
604
+
605
+ context "when a single scope is provided" do
606
+
607
+ before do
608
+ Dictionary.validates_uniqueness_of :name, scope: :publisher
609
+ end
610
+
611
+ after do
612
+ Dictionary.reset_callbacks(:validate)
613
+ end
614
+
615
+ context "when the attribute is unique" do
616
+
617
+ before do
618
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
619
+ end
620
+
621
+ let(:dictionary) do
622
+ Dictionary.new(name: "Webster")
623
+ end
624
+
625
+ it "returns true" do
626
+ expect(dictionary).to be_valid
627
+ end
628
+ end
629
+
630
+ context "when the attribute is unique in the scope" do
631
+
632
+ before do
633
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
634
+ end
635
+
636
+ let(:dictionary) do
637
+ Dictionary.new(name: "Webster", publisher: "Amazon")
638
+ end
639
+
640
+ it "returns true" do
641
+ expect(dictionary).to be_valid
642
+ end
643
+ end
644
+
645
+ context "when uniqueness is violated due to scope change" do
646
+
647
+ let(:personal_folder) do
648
+ Folder.create!(name: "Personal")
649
+ end
650
+
651
+ let(:public_folder) do
652
+ Folder.create!(name: "Public")
653
+ end
654
+
655
+ before do
656
+ personal_folder.folder_items << FolderItem.new(name: "non-unique")
657
+ public_folder.folder_items << FolderItem.new(name: "non-unique")
658
+ end
659
+
660
+ let(:item) do
661
+ public_folder.folder_items.last
662
+ end
663
+
664
+ it "should set an error for associated object not being unique" do
665
+ item.update_attributes(folder_id: personal_folder.id)
666
+ expect(item.errors.messages[:name].first).to eq("is already taken")
667
+ end
668
+ end
669
+
670
+ context "when the attribute is not unique with no scope" do
671
+
672
+ before do
673
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
674
+ end
675
+
676
+ let(:dictionary) do
677
+ Dictionary.new(name: "Oxford")
678
+ end
679
+
680
+ it "returns true" do
681
+ expect(dictionary).to be_valid
682
+ end
683
+ end
684
+
685
+ context "when the attribute is not unique in another scope" do
686
+
687
+ before do
688
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
689
+ end
690
+
691
+ let(:dictionary) do
692
+ Dictionary.new(name: "Oxford", publisher: "Addison")
693
+ end
694
+
695
+ it "returns true" do
696
+ expect(dictionary).to be_valid
697
+ end
698
+ end
699
+
700
+ context "when the attribute is not unique in the same scope" do
701
+
702
+ context "when the document is not the match" do
703
+
704
+ before do
705
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
706
+ end
707
+
708
+ let(:dictionary) do
709
+ Dictionary.new(name: "Oxford", publisher: "Amazon")
710
+ end
711
+
712
+ it "returns false" do
713
+ expect(dictionary).to_not be_valid
714
+ end
715
+
716
+ it "adds the uniqueness errors" do
717
+ dictionary.valid?
718
+ expect(dictionary.errors[:name]).to eq([ "is already taken" ])
719
+ end
720
+ end
721
+
722
+ context "when the document is the match in the database" do
723
+
724
+ let!(:dictionary) do
725
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
726
+ end
727
+
728
+ it "returns true" do
729
+ expect(dictionary).to be_valid
730
+ end
731
+ end
732
+
733
+ context "when one of the scopes is a time" do
734
+
735
+ before do
736
+ Dictionary.create(
737
+ name: "Oxford",
738
+ publisher: "Amazon",
739
+ published: 10.days.ago.to_time
740
+ )
741
+ end
742
+
743
+ let(:dictionary) do
744
+ Dictionary.new(
745
+ name: "Oxford",
746
+ publisher: "Amazon",
747
+ published: 10.days.ago.to_time
748
+ )
749
+ end
750
+
751
+ it "returns false" do
752
+ expect(dictionary).to_not be_valid
753
+ end
754
+
755
+ it "adds the uniqueness errors" do
756
+ dictionary.valid?
757
+ expect(dictionary.errors[:name]).to eq([ "is already taken" ])
758
+ end
759
+ end
760
+ end
761
+ end
762
+
763
+ context "when multiple scopes are provided" do
764
+
765
+ before do
766
+ Dictionary.validates_uniqueness_of :name, scope: [ :publisher, :year ]
767
+ end
768
+
769
+ after do
770
+ Dictionary.reset_callbacks(:validate)
771
+ end
772
+
773
+ context "when the attribute is unique" do
774
+
775
+ before do
776
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
777
+ end
778
+
779
+ let(:dictionary) do
780
+ Dictionary.new(name: "Webster")
781
+ end
782
+
783
+ it "returns true" do
784
+ expect(dictionary).to be_valid
785
+ end
786
+ end
787
+
788
+ context "when the attribute is unique in the scope" do
789
+
790
+ before do
791
+ Dictionary.create(
792
+ name: "Oxford",
793
+ publisher: "Amazon",
794
+ year: 2011
795
+ )
796
+ end
797
+
798
+ let(:dictionary) do
799
+ Dictionary.new(
800
+ name: "Webster",
801
+ publisher: "Amazon",
802
+ year: 2011
803
+ )
804
+ end
805
+
806
+ it "returns true" do
807
+ expect(dictionary).to be_valid
808
+ end
809
+ end
810
+
811
+ context "when the attribute is not unique with no scope" do
812
+
813
+ before do
814
+ Dictionary.create(name: "Oxford", publisher: "Amazon")
815
+ end
816
+
817
+ let(:dictionary) do
818
+ Dictionary.new(name: "Oxford")
819
+ end
820
+
821
+ it "returns true" do
822
+ expect(dictionary).to be_valid
823
+ end
824
+ end
825
+
826
+ context "when the attribute is not unique in another scope" do
827
+
828
+ before do
829
+ Dictionary.create(
830
+ name: "Oxford",
831
+ publisher: "Amazon",
832
+ year: 1995
833
+ )
834
+ end
835
+
836
+ let(:dictionary) do
837
+ Dictionary.new(
838
+ name: "Oxford",
839
+ publisher: "Addison",
840
+ year: 2011
841
+ )
842
+ end
843
+
844
+ it "returns true" do
845
+ expect(dictionary).to be_valid
846
+ end
847
+ end
848
+
849
+ context "when the attribute is not unique in the same scope" do
850
+
851
+ context "when the document is not the match" do
852
+
853
+ before do
854
+ Dictionary.create(
855
+ name: "Oxford",
856
+ publisher: "Amazon",
857
+ year: 1960
858
+ )
859
+ end
860
+
861
+ let(:dictionary) do
862
+ Dictionary.new(
863
+ name: "Oxford",
864
+ publisher: "Amazon",
865
+ year: 1960
866
+ )
867
+ end
868
+
869
+ it "returns false" do
870
+ expect(dictionary).to_not be_valid
871
+ end
872
+
873
+ it "adds the uniqueness errors" do
874
+ dictionary.valid?
875
+ expect(dictionary.errors[:name]).to eq([ "is already taken" ])
876
+ end
877
+ end
878
+
879
+ context "when the document is the match in the database" do
880
+
881
+ let!(:dictionary) do
882
+ Dictionary.create(
883
+ name: "Oxford",
884
+ publisher: "Amazon",
885
+ year: 1960
886
+ )
887
+ end
888
+
889
+ it "returns true" do
890
+ expect(dictionary).to be_valid
891
+ end
892
+ end
893
+ end
894
+ end
895
+
896
+ context "when case sensitive is true" do
897
+
898
+ before do
899
+ Dictionary.validates_uniqueness_of :name
900
+ end
901
+
902
+ after do
903
+ Dictionary.reset_callbacks(:validate)
904
+ end
905
+
906
+ context "when the attribute is unique" do
907
+
908
+ before do
909
+ Dictionary.create(name: "Oxford")
910
+ end
911
+
912
+ let(:dictionary) do
913
+ Dictionary.new(name: "Webster")
914
+ end
915
+
916
+ it "returns true" do
917
+ expect(dictionary).to be_valid
918
+ end
919
+ end
920
+
921
+ context "when the attribute is not unique" do
922
+
923
+ context "when the document is not the match" do
924
+
925
+ before do
926
+ Dictionary.create(name: "Oxford")
927
+ end
928
+
929
+ let(:dictionary) do
930
+ Dictionary.new(name: "Oxford")
931
+ end
932
+
933
+ it "returns false" do
934
+ expect(dictionary).to_not be_valid
935
+ end
936
+
937
+ it "adds the uniqueness error" do
938
+ dictionary.valid?
939
+ expect(dictionary.errors[:name]).to eq([ "is already taken" ])
940
+ end
941
+ end
942
+
943
+ context "when the document is the match in the database" do
944
+
945
+ let!(:dictionary) do
946
+ Dictionary.create(name: "Oxford")
947
+ end
948
+
949
+ it "returns true" do
950
+ expect(dictionary).to be_valid
951
+ end
952
+ end
953
+ end
954
+ end
955
+
956
+ context "when case sensitive is false" do
957
+
958
+ before do
959
+ Dictionary.validates_uniqueness_of :name, case_sensitive: false
960
+ end
961
+
962
+ after do
963
+ Dictionary.reset_callbacks(:validate)
964
+ end
965
+
966
+ context "when the attribute is unique" do
967
+
968
+ context "when there are no special characters" do
969
+
970
+ before do
971
+ Dictionary.create(name: "Oxford")
972
+ end
973
+
974
+ let(:dictionary) do
975
+ Dictionary.new(name: "Webster")
976
+ end
977
+
978
+ it "returns true" do
979
+ expect(dictionary).to be_valid
980
+ end
981
+ end
982
+
983
+ context "when special characters exist" do
984
+
985
+ before do
986
+ Dictionary.create(name: "Oxford")
987
+ end
988
+
989
+ let(:dictionary) do
990
+ Dictionary.new(name: "Web@st.er")
991
+ end
992
+
993
+ it "returns true" do
994
+ expect(dictionary).to be_valid
995
+ end
996
+ end
997
+ end
998
+
999
+ context "when the attribute is not unique" do
1000
+
1001
+ context "when the document is not the match" do
1002
+
1003
+ before do
1004
+ Dictionary.create(name: "Oxford")
1005
+ end
1006
+
1007
+ let(:dictionary) do
1008
+ Dictionary.new(name: "oxford")
1009
+ end
1010
+
1011
+ it "returns false" do
1012
+ expect(dictionary).to_not be_valid
1013
+ end
1014
+
1015
+ it "adds the uniqueness error" do
1016
+ dictionary.valid?
1017
+ expect(dictionary.errors[:name]).to eq([ "is already taken" ])
1018
+ end
1019
+ end
1020
+
1021
+ context "when the document is the match in the database" do
1022
+
1023
+ let!(:dictionary) do
1024
+ Dictionary.create(name: "Oxford")
1025
+ end
1026
+
1027
+ it "returns true" do
1028
+ expect(dictionary).to be_valid
1029
+ end
1030
+ end
1031
+ end
1032
+ end
1033
+
1034
+ context "when allowing nil" do
1035
+
1036
+ before do
1037
+ Dictionary.validates_uniqueness_of :name, allow_nil: true
1038
+ end
1039
+
1040
+ after do
1041
+ Dictionary.reset_callbacks(:validate)
1042
+ end
1043
+
1044
+ context "when the attribute is nil" do
1045
+
1046
+ before do
1047
+ Dictionary.create
1048
+ end
1049
+
1050
+ let(:dictionary) do
1051
+ Dictionary.new
1052
+ end
1053
+
1054
+ it "returns true" do
1055
+ expect(dictionary).to be_valid
1056
+ end
1057
+ end
1058
+ end
1059
+
1060
+ context "when allowing blank" do
1061
+
1062
+ before do
1063
+ Dictionary.validates_uniqueness_of :name, allow_blank: true
1064
+ end
1065
+
1066
+ after do
1067
+ Dictionary.reset_callbacks(:validate)
1068
+ end
1069
+
1070
+ context "when the attribute is blank" do
1071
+
1072
+ before do
1073
+ Dictionary.create(name: "")
1074
+ end
1075
+
1076
+ let(:dictionary) do
1077
+ Dictionary.new(name: "")
1078
+ end
1079
+
1080
+ it "returns true" do
1081
+ expect(dictionary).to be_valid
1082
+ end
1083
+ end
1084
+ end
1085
+ end
1086
+
1087
+ context "when the document contains a compound key" do
1088
+
1089
+ context "when no scope is provided" do
1090
+
1091
+ before do
1092
+ Login.validates_uniqueness_of :username
1093
+ end
1094
+
1095
+ after do
1096
+ Login.reset_callbacks(:validate)
1097
+ end
1098
+
1099
+ context "when the attribute is unique" do
1100
+
1101
+ before do
1102
+ Login.create(username: "Oxford")
1103
+ end
1104
+
1105
+ let(:login) do
1106
+ Login.new(username: "Webster")
1107
+ end
1108
+
1109
+ it "returns true" do
1110
+ expect(login).to be_valid
1111
+ end
1112
+ end
1113
+
1114
+ context "when the attribute is not unique" do
1115
+
1116
+ context "when the document is not the match" do
1117
+
1118
+ before do
1119
+ Login.create(username: "Oxford")
1120
+ end
1121
+
1122
+ let(:login) do
1123
+ Login.new(username: "Oxford")
1124
+ end
1125
+
1126
+ it "returns false" do
1127
+ expect(login).to_not be_valid
1128
+ end
1129
+
1130
+ it "adds the uniqueness error" do
1131
+ login.valid?
1132
+ expect(login.errors[:username]).to eq([ "is already taken" ])
1133
+ end
1134
+ end
1135
+
1136
+ context "when the document is the match in the database" do
1137
+
1138
+ let!(:login) do
1139
+ Login.create(username: "Oxford")
1140
+ end
1141
+
1142
+ it "returns true" do
1143
+ expect(login).to be_valid
1144
+ end
1145
+ end
1146
+ end
1147
+ end
1148
+
1149
+ context "when a single scope is provided" do
1150
+
1151
+ before do
1152
+ Login.validates_uniqueness_of :username, scope: :application_id
1153
+ end
1154
+
1155
+ after do
1156
+ Login.reset_callbacks(:validate)
1157
+ end
1158
+
1159
+ context "when the attribute is unique" do
1160
+
1161
+ before do
1162
+ Login.create(username: "Oxford", application_id: 1)
1163
+ end
1164
+
1165
+ let(:login) do
1166
+ Login.new(username: "Webster")
1167
+ end
1168
+
1169
+ it "returns true" do
1170
+ expect(login).to be_valid
1171
+ end
1172
+ end
1173
+
1174
+ context "when the attribute is unique in the scope" do
1175
+
1176
+ before do
1177
+ Login.create(username: "Oxford", application_id: 1)
1178
+ end
1179
+
1180
+ let(:login) do
1181
+ Login.new(username: "Webster", application_id: 1)
1182
+ end
1183
+
1184
+ it "returns true" do
1185
+ expect(login).to be_valid
1186
+ end
1187
+ end
1188
+
1189
+ context "when the attribute is not unique with no scope" do
1190
+
1191
+ before do
1192
+ Login.create(username: "Oxford", application_id: 1)
1193
+ end
1194
+
1195
+ let(:login) do
1196
+ Login.new(username: "Oxford")
1197
+ end
1198
+
1199
+ it "returns true" do
1200
+ expect(login).to be_valid
1201
+ end
1202
+ end
1203
+
1204
+ context "when the attribute is not unique in another scope" do
1205
+
1206
+ before do
1207
+ Login.create(username: "Oxford", application_id: 1)
1208
+ end
1209
+
1210
+ let(:login) do
1211
+ Login.new(username: "Oxford", application_id: 2)
1212
+ end
1213
+
1214
+ it "returns true" do
1215
+ expect(login).to be_valid
1216
+ end
1217
+ end
1218
+
1219
+ context "when the attribute is not unique in the same scope" do
1220
+
1221
+ context "when the document is not the match" do
1222
+
1223
+ before do
1224
+ Login.create(username: "Oxford", application_id: 1)
1225
+ end
1226
+
1227
+ let(:login) do
1228
+ Login.new(username: "Oxford", application_id: 1)
1229
+ end
1230
+
1231
+ it "returns false" do
1232
+ expect(login).to_not be_valid
1233
+ end
1234
+
1235
+ it "adds the uniqueness errors" do
1236
+ login.valid?
1237
+ expect(login.errors[:username]).to eq([ "is already taken" ])
1238
+ end
1239
+ end
1240
+
1241
+ context "when the document is the match in the database" do
1242
+
1243
+ let!(:login) do
1244
+ Login.create(username: "Oxford", application_id: 1)
1245
+ end
1246
+
1247
+ it "returns true" do
1248
+ expect(login).to be_valid
1249
+ end
1250
+ end
1251
+ end
1252
+ end
1253
+
1254
+ context "when case sensitive is true" do
1255
+
1256
+ before do
1257
+ Login.validates_uniqueness_of :username
1258
+ end
1259
+
1260
+ after do
1261
+ Login.reset_callbacks(:validate)
1262
+ end
1263
+
1264
+ context "when the attribute is unique" do
1265
+
1266
+ before do
1267
+ Login.create(username: "Oxford")
1268
+ end
1269
+
1270
+ let(:login) do
1271
+ Login.new(username: "Webster")
1272
+ end
1273
+
1274
+ it "returns true" do
1275
+ expect(login).to be_valid
1276
+ end
1277
+ end
1278
+
1279
+ context "when the attribute is not unique" do
1280
+
1281
+ context "when the document is not the match" do
1282
+
1283
+ before do
1284
+ Login.create(username: "Oxford")
1285
+ end
1286
+
1287
+ let(:login) do
1288
+ Login.new(username: "Oxford")
1289
+ end
1290
+
1291
+ it "returns false" do
1292
+ expect(login).to_not be_valid
1293
+ end
1294
+
1295
+ it "adds the uniqueness error" do
1296
+ login.valid?
1297
+ expect(login.errors[:username]).to eq([ "is already taken" ])
1298
+ end
1299
+ end
1300
+
1301
+ context "when the document is the match in the database" do
1302
+
1303
+ let!(:login) do
1304
+ Login.create(username: "Oxford")
1305
+ end
1306
+
1307
+ it "returns true" do
1308
+ expect(login).to be_valid
1309
+ end
1310
+ end
1311
+ end
1312
+ end
1313
+
1314
+ context "when case sensitive is false" do
1315
+
1316
+ before do
1317
+ Login.validates_uniqueness_of :username, case_sensitive: false
1318
+ end
1319
+
1320
+ after do
1321
+ Login.reset_callbacks(:validate)
1322
+ end
1323
+
1324
+ context "when the attribute is unique" do
1325
+
1326
+ context "when there are no special characters" do
1327
+
1328
+ before do
1329
+ Login.create(username: "Oxford")
1330
+ end
1331
+
1332
+ let(:login) do
1333
+ Login.new(username: "Webster")
1334
+ end
1335
+
1336
+ it "returns true" do
1337
+ expect(login).to be_valid
1338
+ end
1339
+ end
1340
+
1341
+ context "when special characters exist" do
1342
+
1343
+ before do
1344
+ Login.create(username: "Oxford")
1345
+ end
1346
+
1347
+ let(:login) do
1348
+ Login.new(username: "Web@st.er")
1349
+ end
1350
+
1351
+ it "returns true" do
1352
+ expect(login).to be_valid
1353
+ end
1354
+ end
1355
+ end
1356
+
1357
+ context "when the attribute is not unique" do
1358
+
1359
+ context "when the document is not the match" do
1360
+
1361
+ before do
1362
+ Login.create(username: "Oxford")
1363
+ end
1364
+
1365
+ let(:login) do
1366
+ Login.new(username: "oxford")
1367
+ end
1368
+
1369
+ it "returns false" do
1370
+ expect(login).to_not be_valid
1371
+ end
1372
+
1373
+ it "adds the uniqueness error" do
1374
+ login.valid?
1375
+ expect(login.errors[:username]).to eq([ "is already taken" ])
1376
+ end
1377
+ end
1378
+
1379
+ context "when the document is the match in the database" do
1380
+
1381
+ let!(:login) do
1382
+ Login.create(username: "Oxford")
1383
+ end
1384
+
1385
+ it "returns true" do
1386
+ expect(login).to be_valid
1387
+ end
1388
+ end
1389
+ end
1390
+ end
1391
+
1392
+ context "when allowing nil" do
1393
+
1394
+ before do
1395
+ Login.validates_uniqueness_of :username, allow_nil: true
1396
+ end
1397
+
1398
+ after do
1399
+ Login.reset_callbacks(:validate)
1400
+ end
1401
+
1402
+ context "when the attribute is nil" do
1403
+
1404
+ before do
1405
+ Login.create
1406
+ end
1407
+
1408
+ let(:login) do
1409
+ Login.new
1410
+ end
1411
+
1412
+ it "returns true" do
1413
+ expect(login).to be_valid
1414
+ end
1415
+ end
1416
+ end
1417
+
1418
+ context "when allowing blank" do
1419
+
1420
+ before do
1421
+ Login.validates_uniqueness_of :username, allow_blank: true
1422
+ end
1423
+
1424
+ after do
1425
+ Login.reset_callbacks(:validate)
1426
+ end
1427
+
1428
+ context "when the attribute is blank" do
1429
+
1430
+ before do
1431
+ Login.create(username: "")
1432
+ end
1433
+
1434
+ let(:login) do
1435
+ Login.new(username: "")
1436
+ end
1437
+
1438
+ it "returns true" do
1439
+ expect(login).to be_valid
1440
+ end
1441
+ end
1442
+ end
1443
+ end
1444
+
1445
+ context "when the attribute is a custom type" do
1446
+
1447
+ before do
1448
+ Bar.validates_uniqueness_of :lat_lng
1449
+ end
1450
+
1451
+ after do
1452
+ Bar.reset_callbacks(:validate)
1453
+ end
1454
+
1455
+ context "when the attribute is unique" do
1456
+
1457
+ before do
1458
+ Bar.create(lat_lng: LatLng.new(52.30, 13.25))
1459
+ end
1460
+
1461
+ let(:unique_bar) do
1462
+ Bar.new(lat_lng: LatLng.new(54.30, 14.25))
1463
+ end
1464
+
1465
+ it "returns true" do
1466
+ expect(unique_bar).to be_valid
1467
+ end
1468
+
1469
+ end
1470
+
1471
+ context "when the attribute is not unique" do
1472
+
1473
+ before do
1474
+ Bar.create(lat_lng: LatLng.new(52.30, 13.25))
1475
+ end
1476
+
1477
+ let(:non_unique_bar) do
1478
+ Bar.new(lat_lng: LatLng.new(52.30, 13.25))
1479
+ end
1480
+
1481
+ it "returns false" do
1482
+ expect(non_unique_bar).to_not be_valid
1483
+ end
1484
+
1485
+ end
1486
+
1487
+ end
1488
+ end
1489
+ end
1490
+
1491
+ context "when the document is embedded" do
1492
+
1493
+ let(:word) do
1494
+ Word.create(name: "Schadenfreude")
1495
+ end
1496
+
1497
+ context "when in an embeds_many" do
1498
+
1499
+ let!(:def_one) do
1500
+ word.definitions.create(description: "1")
1501
+ end
1502
+
1503
+ let!(:def_two) do
1504
+ word.definitions.create(description: "2")
1505
+ end
1506
+
1507
+ context "when a document is being destroyed" do
1508
+
1509
+ before do
1510
+ Definition.validates_uniqueness_of :description
1511
+ end
1512
+
1513
+ after do
1514
+ Definition.reset_callbacks(:validate)
1515
+ end
1516
+
1517
+ context "when changing a document to the destroyed property" do
1518
+
1519
+ let(:attributes) do
1520
+ {
1521
+ definitions_attributes: {
1522
+ "0" => { id: def_one.id, description: "0", "_destroy" => 1 },
1523
+ "1" => { id: def_two.id, description: "1" }
1524
+ }
1525
+ }
1526
+ end
1527
+
1528
+ before do
1529
+ word.attributes = attributes
1530
+ end
1531
+
1532
+ it "returns true" do
1533
+ expect(def_two).to be_valid
1534
+ end
1535
+ end
1536
+ end
1537
+
1538
+ context "when the document does not use composite keys" do
1539
+
1540
+ context "when no scope is provided" do
1541
+
1542
+ before do
1543
+ Definition.validates_uniqueness_of :description
1544
+ end
1545
+
1546
+ after do
1547
+ Definition.reset_callbacks(:validate)
1548
+ end
1549
+
1550
+ context "when the attribute is unique" do
1551
+
1552
+ before do
1553
+ word.definitions.build(description: "Malicious joy")
1554
+ end
1555
+
1556
+ let(:definition) do
1557
+ word.definitions.build(description: "Gloating")
1558
+ end
1559
+
1560
+ it "returns true" do
1561
+ expect(definition).to be_valid
1562
+ end
1563
+ end
1564
+
1565
+ context "when the attribute is not unique" do
1566
+
1567
+ context "when the document is not the match" do
1568
+
1569
+ before do
1570
+ word.definitions.build(description: "Malicious joy")
1571
+ end
1572
+
1573
+ let(:definition) do
1574
+ word.definitions.build(description: "Malicious joy")
1575
+ end
1576
+
1577
+ it "returns false" do
1578
+ expect(definition).to_not be_valid
1579
+ end
1580
+
1581
+ it "adds the uniqueness error" do
1582
+ definition.valid?
1583
+ expect(definition.errors[:description]).to eq([ "is already taken" ])
1584
+ end
1585
+ end
1586
+
1587
+ context "when the document is the match in the database" do
1588
+
1589
+ let!(:definition) do
1590
+ word.definitions.build(description: "Malicious joy")
1591
+ end
1592
+
1593
+ it "returns true" do
1594
+ expect(definition).to be_valid
1595
+ end
1596
+ end
1597
+ end
1598
+ end
1599
+
1600
+ context "when a single scope is provided" do
1601
+
1602
+ before do
1603
+ Definition.validates_uniqueness_of :description, scope: :part
1604
+ end
1605
+
1606
+ after do
1607
+ Definition.reset_callbacks(:validate)
1608
+ end
1609
+
1610
+ context "when the attribute is unique" do
1611
+
1612
+ before do
1613
+ word.definitions.build(
1614
+ description: "Malicious joy", part: "Noun"
1615
+ )
1616
+ end
1617
+
1618
+ let(:definition) do
1619
+ word.definitions.build(description: "Gloating")
1620
+ end
1621
+
1622
+ it "returns true" do
1623
+ expect(definition).to be_valid
1624
+ end
1625
+ end
1626
+
1627
+ context "when the attribute is unique in the scope" do
1628
+
1629
+ before do
1630
+ word.definitions.build(
1631
+ description: "Malicious joy",
1632
+ part: "Noun"
1633
+ )
1634
+ end
1635
+
1636
+ let(:definition) do
1637
+ word.definitions.build(
1638
+ description: "Gloating",
1639
+ part: "Noun"
1640
+ )
1641
+ end
1642
+
1643
+ it "returns true" do
1644
+ expect(definition).to be_valid
1645
+ end
1646
+ end
1647
+
1648
+ context "when the attribute is not unique with no scope" do
1649
+
1650
+ before do
1651
+ word.definitions.build(
1652
+ description: "Malicious joy",
1653
+ part: "Noun"
1654
+ )
1655
+ end
1656
+
1657
+ let(:definition) do
1658
+ word.definitions.build(description: "Malicious joy")
1659
+ end
1660
+
1661
+ it "returns true" do
1662
+ expect(definition).to be_valid
1663
+ end
1664
+ end
1665
+
1666
+ context "when the attribute is not unique in another scope" do
1667
+
1668
+ before do
1669
+ word.definitions.build(
1670
+ description: "Malicious joy",
1671
+ part: "Noun"
1672
+ )
1673
+ end
1674
+
1675
+ let(:definition) do
1676
+ word.definitions.build(
1677
+ description: "Malicious joy",
1678
+ part: "Adj"
1679
+ )
1680
+ end
1681
+
1682
+ it "returns true" do
1683
+ expect(definition).to be_valid
1684
+ end
1685
+ end
1686
+
1687
+ context "when the attribute is not unique in the same scope" do
1688
+
1689
+ context "when the document is not the match" do
1690
+
1691
+ before do
1692
+ word.definitions.build(
1693
+ description: "Malicious joy",
1694
+ part: "Noun"
1695
+ )
1696
+ end
1697
+
1698
+ let(:definition) do
1699
+ word.definitions.build(
1700
+ description: "Malicious joy",
1701
+ part: "Noun"
1702
+ )
1703
+ end
1704
+
1705
+ it "returns false" do
1706
+ expect(definition).to_not be_valid
1707
+ end
1708
+
1709
+ it "adds the uniqueness errors" do
1710
+ definition.valid?
1711
+ expect(definition.errors[:description]).to eq([ "is already taken" ])
1712
+ end
1713
+ end
1714
+
1715
+ context "when the document is the match in the database" do
1716
+
1717
+ let!(:definition) do
1718
+ word.definitions.build(
1719
+ description: "Malicious joy",
1720
+ part: "Noun"
1721
+ )
1722
+ end
1723
+
1724
+ it "returns true" do
1725
+ expect(definition).to be_valid
1726
+ end
1727
+ end
1728
+ end
1729
+ end
1730
+
1731
+ context "when multiple scopes are provided" do
1732
+
1733
+ before do
1734
+ Definition.validates_uniqueness_of :description, scope: [ :part, :regular ]
1735
+ end
1736
+
1737
+ after do
1738
+ Definition.reset_callbacks(:validate)
1739
+ end
1740
+
1741
+ context "when the attribute is unique" do
1742
+
1743
+ before do
1744
+ word.definitions.build(
1745
+ description: "Malicious joy",
1746
+ part: "Noun"
1747
+ )
1748
+ end
1749
+
1750
+ let(:definition) do
1751
+ word.definitions.build(description: "Gloating")
1752
+ end
1753
+
1754
+ it "returns true" do
1755
+ expect(definition).to be_valid
1756
+ end
1757
+ end
1758
+
1759
+ context "when the attribute is unique in the scope" do
1760
+
1761
+ before do
1762
+ word.definitions.build(
1763
+ description: "Malicious joy",
1764
+ part: "Noun",
1765
+ regular: true
1766
+ )
1767
+ end
1768
+
1769
+ let(:definition) do
1770
+ word.definitions.build(
1771
+ description: "Gloating",
1772
+ part: "Noun",
1773
+ regular: true
1774
+ )
1775
+ end
1776
+
1777
+ it "returns true" do
1778
+ expect(definition).to be_valid
1779
+ end
1780
+ end
1781
+
1782
+ context "when the attribute is not unique with no scope" do
1783
+
1784
+ before do
1785
+ word.definitions.build(
1786
+ description: "Malicious joy",
1787
+ part: "Noun"
1788
+ )
1789
+ end
1790
+
1791
+ let(:definition) do
1792
+ word.definitions.build(description: "Malicious scope")
1793
+ end
1794
+
1795
+ it "returns true" do
1796
+ expect(definition).to be_valid
1797
+ end
1798
+ end
1799
+
1800
+ context "when the attribute is not unique in another scope" do
1801
+
1802
+ before do
1803
+ word.definitions.build(
1804
+ description: "Malicious joy",
1805
+ part: "Noun",
1806
+ regular: true
1807
+ )
1808
+ end
1809
+
1810
+ let(:definition) do
1811
+ word.definitions.build(
1812
+ description: "Malicious joy",
1813
+ part: "Adj",
1814
+ regular: true
1815
+ )
1816
+ end
1817
+
1818
+ it "returns true" do
1819
+ expect(definition).to be_valid
1820
+ end
1821
+ end
1822
+
1823
+ context "when the attribute is not unique in the same scope" do
1824
+
1825
+ context "when the document is not the match" do
1826
+
1827
+ before do
1828
+ word.definitions.build(
1829
+ description: "Malicious joy",
1830
+ part: "Noun",
1831
+ regular: true
1832
+ )
1833
+ end
1834
+
1835
+ let(:definition) do
1836
+ word.definitions.build(
1837
+ description: "Malicious joy",
1838
+ part: "Noun",
1839
+ regular: true
1840
+ )
1841
+ end
1842
+
1843
+ it "returns false" do
1844
+ expect(definition).to_not be_valid
1845
+ end
1846
+
1847
+ it "adds the uniqueness errors" do
1848
+ definition.valid?
1849
+ expect(definition.errors[:description]).to eq([ "is already taken" ])
1850
+ end
1851
+ end
1852
+
1853
+ context "when the document is the match in the database" do
1854
+
1855
+ let!(:definition) do
1856
+ word.definitions.build(
1857
+ description: "Malicious joy",
1858
+ part: "Noun",
1859
+ regular: false
1860
+ )
1861
+ end
1862
+
1863
+ it "returns true" do
1864
+ expect(definition).to be_valid
1865
+ end
1866
+ end
1867
+ end
1868
+ end
1869
+
1870
+ context "when case sensitive is true" do
1871
+
1872
+ before do
1873
+ Definition.validates_uniqueness_of :description
1874
+ end
1875
+
1876
+ after do
1877
+ Definition.reset_callbacks(:validate)
1878
+ end
1879
+
1880
+ context "when the attribute is unique" do
1881
+
1882
+ before do
1883
+ word.definitions.build(description: "Malicious jo")
1884
+ end
1885
+
1886
+ let(:definition) do
1887
+ word.definitions.build(description: "Gloating")
1888
+ end
1889
+
1890
+ it "returns true" do
1891
+ expect(definition).to be_valid
1892
+ end
1893
+ end
1894
+
1895
+ context "when the attribute is not unique" do
1896
+
1897
+ context "when the document is not the match" do
1898
+
1899
+ before do
1900
+ word.definitions.build(description: "Malicious joy")
1901
+ end
1902
+
1903
+ let(:definition) do
1904
+ word.definitions.build(description: "Malicious joy")
1905
+ end
1906
+
1907
+ it "returns false" do
1908
+ expect(definition).to_not be_valid
1909
+ end
1910
+
1911
+ it "adds the uniqueness error" do
1912
+ definition.valid?
1913
+ expect(definition.errors[:description]).to eq([ "is already taken" ])
1914
+ end
1915
+ end
1916
+
1917
+ context "when the document is the match in the database" do
1918
+
1919
+ let!(:definition) do
1920
+ word.definitions.build(description: "Malicious joy")
1921
+ end
1922
+
1923
+ it "returns true" do
1924
+ expect(definition).to be_valid
1925
+ end
1926
+ end
1927
+ end
1928
+ end
1929
+
1930
+ context "when case sensitive is false" do
1931
+
1932
+ before do
1933
+ Definition.validates_uniqueness_of :description, case_sensitive: false
1934
+ end
1935
+
1936
+ after do
1937
+ Definition.reset_callbacks(:validate)
1938
+ end
1939
+
1940
+ context "when the attribute is unique" do
1941
+
1942
+ context "when there are no special characters" do
1943
+
1944
+ before do
1945
+ word.definitions.build(description: "Malicious joy")
1946
+ end
1947
+
1948
+ let(:definition) do
1949
+ word.definitions.build(description: "Gloating")
1950
+ end
1951
+
1952
+ it "returns true" do
1953
+ expect(definition).to be_valid
1954
+ end
1955
+ end
1956
+
1957
+ context "when special characters exist" do
1958
+
1959
+ before do
1960
+ word.definitions.build(description: "Malicious joy")
1961
+ end
1962
+
1963
+ let(:definition) do
1964
+ word.definitions.build(description: "M@licious.joy")
1965
+ end
1966
+
1967
+ it "returns true" do
1968
+ expect(definition).to be_valid
1969
+ end
1970
+ end
1971
+ end
1972
+
1973
+ context "when the attribute is not unique" do
1974
+
1975
+ context "when the document is not the match" do
1976
+
1977
+ before do
1978
+ word.definitions.build(description: "Malicious joy")
1979
+ end
1980
+
1981
+ let(:definition) do
1982
+ word.definitions.build(description: "Malicious JOY")
1983
+ end
1984
+
1985
+ it "returns false" do
1986
+ expect(definition).to_not be_valid
1987
+ end
1988
+
1989
+ it "adds the uniqueness error" do
1990
+ definition.valid?
1991
+ expect(definition.errors[:description]).to eq([ "is already taken" ])
1992
+ end
1993
+ end
1994
+
1995
+ context "when the document is the match in the database" do
1996
+
1997
+ let!(:definition) do
1998
+ word.definitions.build(description: "Malicious joy")
1999
+ end
2000
+
2001
+ it "returns true" do
2002
+ expect(definition).to be_valid
2003
+ end
2004
+ end
2005
+ end
2006
+ end
2007
+
2008
+ context "when allowing nil" do
2009
+
2010
+ before do
2011
+ Definition.validates_uniqueness_of :description, allow_nil: true
2012
+ end
2013
+
2014
+ after do
2015
+ Definition.reset_callbacks(:validate)
2016
+ end
2017
+
2018
+ context "when the attribute is nil" do
2019
+
2020
+ before do
2021
+ word.definitions.build
2022
+ end
2023
+
2024
+ let(:definition) do
2025
+ word.definitions.build
2026
+ end
2027
+
2028
+ it "returns true" do
2029
+ expect(definition).to be_valid
2030
+ end
2031
+ end
2032
+ end
2033
+
2034
+ context "when allowing blank" do
2035
+
2036
+ before do
2037
+ Definition.validates_uniqueness_of :description, allow_blank: true
2038
+ end
2039
+
2040
+ after do
2041
+ Definition.reset_callbacks(:validate)
2042
+ end
2043
+
2044
+ context "when the attribute is blank" do
2045
+
2046
+ before do
2047
+ word.definitions.build(description: "")
2048
+ end
2049
+
2050
+ let(:definition) do
2051
+ word.definitions.build(description: "")
2052
+ end
2053
+
2054
+ it "returns true" do
2055
+ expect(definition).to be_valid
2056
+ end
2057
+ end
2058
+ end
2059
+
2060
+ context "when the field name is aliased" do
2061
+
2062
+ before do
2063
+ word.definitions.build(part: "noun")
2064
+ end
2065
+
2066
+ let(:definition) do
2067
+ word.definitions.build(part: "noun")
2068
+ end
2069
+
2070
+ after do
2071
+ Definition.reset_callbacks(:validate)
2072
+ end
2073
+
2074
+ context "when the validation uses the aliased name" do
2075
+
2076
+ before do
2077
+ Definition.validates_uniqueness_of :part, case_sensitive: false
2078
+ end
2079
+
2080
+ it "correctly detects a uniqueness conflict" do
2081
+ expect(definition).to_not be_valid
2082
+ end
2083
+
2084
+ it "adds the uniqueness error to the aliased field name" do
2085
+ definition.valid?
2086
+ expect(definition.errors).to have_key(:part)
2087
+ expect(definition.errors[:part]).to eq([ "is already taken" ])
2088
+ end
2089
+ end
2090
+
2091
+ context "when the validation uses the underlying field name" do
2092
+
2093
+ before do
2094
+ Definition.validates_uniqueness_of :p, case_sensitive: false
2095
+ end
2096
+
2097
+ it "correctly detects a uniqueness conflict" do
2098
+ expect(definition).to_not be_valid
2099
+ end
2100
+
2101
+ it "adds the uniqueness error to the underlying field name" do
2102
+ definition.valid?
2103
+ expect(definition.errors).to have_key(:p)
2104
+ expect(definition.errors[:p]).to eq([ "is already taken" ])
2105
+ end
2106
+ end
2107
+ end
2108
+ end
2109
+
2110
+ context "when the document uses composite keys" do
2111
+
2112
+ context "when no scope is provided" do
2113
+
2114
+ before do
2115
+ WordOrigin.validates_uniqueness_of :origin_id
2116
+ end
2117
+
2118
+ after do
2119
+ WordOrigin.reset_callbacks(:validate)
2120
+ end
2121
+
2122
+ context "when the attribute is unique" do
2123
+
2124
+ before do
2125
+ word.word_origins.build(origin_id: 1)
2126
+ end
2127
+
2128
+ let(:word_origin) do
2129
+ word.word_origins.build(origin_id: 2)
2130
+ end
2131
+
2132
+ it "returns true" do
2133
+ expect(word_origin).to be_valid
2134
+ end
2135
+ end
2136
+
2137
+ context "when the attribute is not unique" do
2138
+
2139
+ context "when the document is not the match" do
2140
+
2141
+ before do
2142
+ word.word_origins.build(origin_id: 1)
2143
+ end
2144
+
2145
+ let(:word_origin) do
2146
+ word.word_origins.build(origin_id: 1)
2147
+ end
2148
+
2149
+ it "returns false" do
2150
+ expect(word_origin).to_not be_valid
2151
+ end
2152
+
2153
+ it "adds the uniqueness error" do
2154
+ word_origin.valid?
2155
+ expect(word_origin.errors[:origin_id]).to eq([ "is already taken" ])
2156
+ end
2157
+ end
2158
+
2159
+ context "when the document is the match in the database" do
2160
+
2161
+ let!(:word_origin) do
2162
+ word.word_origins.build(origin_id: 1)
2163
+ end
2164
+
2165
+ it "returns true" do
2166
+ expect(word_origin).to be_valid
2167
+ end
2168
+ end
2169
+ end
2170
+ end
2171
+
2172
+ context "when allowing nil" do
2173
+
2174
+ before do
2175
+ WordOrigin.validates_uniqueness_of :origin_id, allow_nil: true
2176
+ end
2177
+
2178
+ after do
2179
+ WordOrigin.reset_callbacks(:validate)
2180
+ end
2181
+
2182
+ context "when the attribute is nil" do
2183
+
2184
+ before do
2185
+ word.word_origins.build
2186
+ end
2187
+
2188
+ let(:word_origin) do
2189
+ word.word_origins.build
2190
+ end
2191
+
2192
+ it "returns true" do
2193
+ expect(word_origin).to be_valid
2194
+ end
2195
+ end
2196
+ end
2197
+
2198
+ context "when allowing blank" do
2199
+
2200
+ before do
2201
+ WordOrigin.validates_uniqueness_of :origin_id, allow_blank: true
2202
+ end
2203
+
2204
+ after do
2205
+ WordOrigin.reset_callbacks(:validate)
2206
+ end
2207
+
2208
+ context "when the attribute is blank" do
2209
+
2210
+ before do
2211
+ word.word_origins.build(origin_id: "")
2212
+ end
2213
+
2214
+ let(:word_origin) do
2215
+ word.word_origins.build(origin_id: "")
2216
+ end
2217
+
2218
+ it "returns true" do
2219
+ expect(word_origin).to be_valid
2220
+ end
2221
+ end
2222
+ end
2223
+ end
2224
+ end
2225
+
2226
+ context "when in an embeds_one" do
2227
+
2228
+ before do
2229
+ Pronunciation.validates_uniqueness_of :sound
2230
+ end
2231
+
2232
+ after do
2233
+ Pronunciation.reset_callbacks(:validate)
2234
+ end
2235
+
2236
+ let(:pronunciation) do
2237
+ word.build_pronunciation(sound: "Schwa")
2238
+ end
2239
+
2240
+ it "always returns true" do
2241
+ expect(pronunciation).to be_valid
2242
+ end
2243
+ end
2244
+ end
2245
+
2246
+ context "when describing validation on the instance level" do
2247
+
2248
+ let!(:dictionary) do
2249
+ Dictionary.create!(name: "en")
2250
+ end
2251
+
2252
+ let(:validators) do
2253
+ dictionary.validates_uniqueness_of :name
2254
+ end
2255
+
2256
+ it "adds the validation only to the instance" do
2257
+ expect(validators).to eq([ described_class ])
2258
+ end
2259
+ end
2260
+
2261
+ context "when validation works with inheritance" do
2262
+
2263
+ before do
2264
+ Actor.validates_uniqueness_of :name
2265
+ Actor.create!(name: "Johnny Depp")
2266
+ end
2267
+
2268
+ after do
2269
+ Actor.reset_callbacks(:validate)
2270
+ end
2271
+
2272
+ let!(:subclass_document_with_duplicated_name) do
2273
+ Actress.new(name: "Johnny Depp")
2274
+ end
2275
+
2276
+ it "should be invalid" do
2277
+ subclass_document_with_duplicated_name.tap do |d|
2278
+ expect(d).to be_invalid
2279
+ expect(d.errors[:name]).to eq([ "is already taken" ])
2280
+ end
2281
+ end
2282
+ end
2283
+
2284
+ context "when persisting with safe options" do
2285
+
2286
+ before do
2287
+ Person.validates_uniqueness_of(:username)
2288
+ Person.create_indexes
2289
+ end
2290
+
2291
+ let!(:person) do
2292
+ Person.create(ssn: "132-11-1111", username: "aaasdaffff")
2293
+ end
2294
+
2295
+ after do
2296
+ Person.reset_callbacks(:validate)
2297
+ end
2298
+
2299
+ it "transfers the options to the cloned session" do
2300
+ expect {
2301
+ Person.with(safe: true).create!(ssn: "132-11-1111", username: "asdfsdfA")
2302
+ }.to raise_error
2303
+ end
2304
+ end
2305
+ end