ibm_db 3.0.4-x86-mingw32 → 3.0.5-x86-mingw32

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 (463) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +4 -1
  3. data/LICENSE +1 -1
  4. data/MANIFEST +14 -14
  5. data/README +225 -225
  6. data/ext/Makefile.nt32 +181 -181
  7. data/ext/Makefile.nt32.191 +212 -212
  8. data/ext/extconf.rb +291 -291
  9. data/ext/ibm_db.c +11887 -11884
  10. data/ext/ruby_ibm_db.h +241 -241
  11. data/ext/ruby_ibm_db_cli.c +866 -866
  12. data/ext/ruby_ibm_db_cli.h +500 -500
  13. data/init.rb +41 -41
  14. data/lib/IBM_DB.rb +27 -27
  15. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3177 -3177
  16. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +1 -1
  17. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
  18. data/lib/mswin32/ibm_db.rb +122 -122
  19. data/lib/mswin32/rb21x/i386/ibm_db.so +0 -0
  20. data/lib/mswin32/rb22x/i386/ibm_db.so +0 -0
  21. data/lib/mswin32/rb23x/i386/ibm_db.so +0 -0
  22. data/test/active_record/connection_adapters/fake_adapter.rb +46 -46
  23. data/test/assets/example.log +1 -1
  24. data/test/assets/test.txt +1 -1
  25. data/test/cases/adapter_test.rb +276 -261
  26. data/test/cases/aggregations_test.rb +158 -158
  27. data/test/cases/ar_schema_test.rb +161 -161
  28. data/test/cases/associations/association_scope_test.rb +21 -21
  29. data/test/cases/associations/belongs_to_associations_test.rb +1029 -1029
  30. data/test/cases/associations/callbacks_test.rb +192 -192
  31. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  32. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +26 -26
  33. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  34. data/test/cases/associations/eager_load_nested_include_test.rb +128 -128
  35. data/test/cases/associations/eager_singularization_test.rb +148 -148
  36. data/test/cases/associations/eager_test.rb +1429 -1411
  37. data/test/cases/associations/extension_test.rb +82 -82
  38. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +972 -932
  39. data/test/cases/associations/has_many_associations_test.rb +2182 -2162
  40. data/test/cases/associations/has_many_through_associations_test.rb +1204 -1204
  41. data/test/cases/associations/has_one_associations_test.rb +610 -610
  42. data/test/cases/associations/has_one_through_associations_test.rb +380 -380
  43. data/test/cases/associations/inner_join_association_test.rb +139 -139
  44. data/test/cases/associations/inverse_associations_test.rb +706 -693
  45. data/test/cases/associations/join_model_test.rb +754 -754
  46. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  47. data/test/cases/associations/required_test.rb +82 -82
  48. data/test/cases/associations_test.rb +380 -380
  49. data/test/cases/attribute_decorators_test.rb +125 -125
  50. data/test/cases/attribute_methods/read_test.rb +60 -60
  51. data/test/cases/attribute_methods/serialization_test.rb +29 -29
  52. data/test/cases/attribute_methods_test.rb +952 -952
  53. data/test/cases/attribute_set_test.rb +210 -200
  54. data/test/cases/attribute_test.rb +180 -180
  55. data/test/cases/attributes_test.rb +136 -136
  56. data/test/cases/autosave_association_test.rb +1595 -1595
  57. data/test/cases/base_test.rb +1664 -1638
  58. data/test/cases/batches_test.rb +212 -212
  59. data/test/cases/binary_test.rb +52 -52
  60. data/test/cases/bind_parameter_test.rb +100 -100
  61. data/test/cases/calculations_test.rb +646 -646
  62. data/test/cases/callbacks_test.rb +543 -543
  63. data/test/cases/clone_test.rb +40 -40
  64. data/test/cases/coders/yaml_column_test.rb +63 -63
  65. data/test/cases/column_alias_test.rb +17 -17
  66. data/test/cases/column_definition_test.rb +123 -123
  67. data/test/cases/connection_adapters/adapter_leasing_test.rb +54 -54
  68. data/test/cases/connection_adapters/connection_handler_test.rb +53 -53
  69. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  70. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +293 -293
  71. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +65 -65
  72. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  73. data/test/cases/connection_adapters/schema_cache_test.rb +56 -56
  74. data/test/cases/connection_adapters/type_lookup_test.rb +110 -110
  75. data/test/cases/connection_management_test.rb +122 -122
  76. data/test/cases/connection_pool_test.rb +346 -346
  77. data/test/cases/connection_specification/resolver_test.rb +116 -116
  78. data/test/cases/core_test.rb +112 -112
  79. data/test/cases/counter_cache_test.rb +209 -209
  80. data/test/cases/custom_locking_test.rb +17 -17
  81. data/test/cases/database_statements_test.rb +19 -19
  82. data/test/cases/date_time_test.rb +61 -61
  83. data/test/cases/defaults_test.rb +223 -223
  84. data/test/cases/dirty_test.rb +785 -775
  85. data/test/cases/disconnected_test.rb +28 -28
  86. data/test/cases/dup_test.rb +157 -157
  87. data/test/cases/enum_test.rb +290 -290
  88. data/test/cases/explain_subscriber_test.rb +64 -64
  89. data/test/cases/explain_test.rb +76 -76
  90. data/test/cases/finder_respond_to_test.rb +60 -60
  91. data/test/cases/finder_test.rb +1169 -1166
  92. data/test/cases/fixture_set/file_test.rb +138 -138
  93. data/test/cases/fixtures_test.rb +908 -897
  94. data/test/cases/forbidden_attributes_protection_test.rb +99 -99
  95. data/test/cases/habtm_destroy_order_test.rb +61 -61
  96. data/test/cases/helper.rb +210 -210
  97. data/test/cases/hot_compatibility_test.rb +54 -54
  98. data/test/cases/i18n_test.rb +45 -45
  99. data/test/cases/inheritance_test.rb +375 -375
  100. data/test/cases/integration_test.rb +139 -139
  101. data/test/cases/invalid_connection_test.rb +22 -22
  102. data/test/cases/invalid_date_test.rb +32 -32
  103. data/test/cases/invertible_migration_test.rb +295 -295
  104. data/test/cases/json_serialization_test.rb +302 -302
  105. data/test/cases/locking_test.rb +477 -477
  106. data/test/cases/log_subscriber_test.rb +136 -136
  107. data/test/cases/migration/change_schema_test - Copy.rb +448 -448
  108. data/test/cases/migration/change_schema_test.rb +512 -472
  109. data/test/cases/migration/change_table_test.rb +224 -224
  110. data/test/cases/migration/column_attributes_test.rb +192 -192
  111. data/test/cases/migration/column_positioning_test.rb +56 -56
  112. data/test/cases/migration/columns_test.rb +304 -304
  113. data/test/cases/migration/command_recorder_test.rb +305 -305
  114. data/test/cases/migration/create_join_table_test.rb +148 -148
  115. data/test/cases/migration/foreign_key_test - Changed.rb +325 -325
  116. data/test/cases/migration/foreign_key_test.rb +328 -360
  117. data/test/cases/migration/helper.rb +39 -39
  118. data/test/cases/migration/index_test.rb +216 -216
  119. data/test/cases/migration/logger_test.rb +36 -36
  120. data/test/cases/migration/pending_migrations_test.rb +53 -53
  121. data/test/cases/migration/references_foreign_key_test.rb +169 -214
  122. data/test/cases/migration/references_index_test.rb +101 -101
  123. data/test/cases/migration/references_statements_test.rb +116 -116
  124. data/test/cases/migration/rename_table_test.rb +93 -93
  125. data/test/cases/migration/table_and_index_test.rb +24 -24
  126. data/test/cases/migration_test.rb +959 -959
  127. data/test/cases/migrator_test.rb +388 -388
  128. data/test/cases/mixin_test.rb +70 -70
  129. data/test/cases/modules_test.rb +173 -173
  130. data/test/cases/multiparameter_attributes_test.rb +350 -350
  131. data/test/cases/multiple_db_test.rb +115 -115
  132. data/test/cases/nested_attributes_test.rb +1070 -1057
  133. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  134. data/test/cases/persistence_test.rb +909 -909
  135. data/test/cases/pooled_connections_test.rb +81 -81
  136. data/test/cases/primary_keys_test.rb +237 -237
  137. data/test/cases/query_cache_test.rb +326 -326
  138. data/test/cases/quoting_test.rb +156 -156
  139. data/test/cases/readonly_test.rb +118 -118
  140. data/test/cases/reaper_test.rb +85 -85
  141. data/test/cases/reflection_test.rb +463 -454
  142. data/test/cases/relation/delegation_test.rb +68 -68
  143. data/test/cases/relation/merging_test.rb +161 -161
  144. data/test/cases/relation/mutation_test.rb +165 -165
  145. data/test/cases/relation/predicate_builder_test.rb +14 -14
  146. data/test/cases/relation/where_chain_test.rb +181 -181
  147. data/test/cases/relation/where_test.rb +300 -300
  148. data/test/cases/relation/where_test2.rb +36 -36
  149. data/test/cases/relation_test.rb +319 -297
  150. data/test/cases/relations_test.rb +1815 -1815
  151. data/test/cases/reload_models_test.rb +22 -22
  152. data/test/cases/result_test.rb +80 -80
  153. data/test/cases/sanitize_test.rb +83 -83
  154. data/test/cases/schema_dumper_test.rb +463 -463
  155. data/test/cases/scoping/default_scoping_test.rb +454 -454
  156. data/test/cases/scoping/named_scoping_test.rb +524 -524
  157. data/test/cases/scoping/relation_scoping_test.rb +357 -357
  158. data/test/cases/serialization_test.rb +104 -104
  159. data/test/cases/serialized_attribute_test.rb +277 -277
  160. data/test/cases/statement_cache_test.rb +98 -98
  161. data/test/cases/store_test.rb +194 -194
  162. data/test/cases/tasks/database_tasks_test.rb +398 -396
  163. data/test/cases/tasks/mysql_rake_test.rb +324 -311
  164. data/test/cases/tasks/postgresql_rake_test.rb +250 -245
  165. data/test/cases/tasks/sqlite_rake_test.rb +193 -193
  166. data/test/cases/test_case.rb +123 -123
  167. data/test/cases/timestamp_test.rb +467 -468
  168. data/test/cases/transaction_callbacks_test.rb +452 -452
  169. data/test/cases/transaction_isolation_test.rb +106 -106
  170. data/test/cases/transactions_test.rb +817 -817
  171. data/test/cases/type/decimal_test.rb +56 -51
  172. data/test/cases/type/integer_test.rb +121 -121
  173. data/test/cases/type/string_test.rb +36 -36
  174. data/test/cases/type/type_map_test.rb +177 -177
  175. data/test/cases/type/unsigned_integer_test.rb +18 -18
  176. data/test/cases/types_test.rb +141 -141
  177. data/test/cases/unconnected_test.rb +33 -33
  178. data/test/cases/validations/association_validation_test.rb +86 -86
  179. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  180. data/test/cases/validations/i18n_validation_test.rb +90 -90
  181. data/test/cases/validations/length_validation_test.rb +47 -47
  182. data/test/cases/validations/presence_validation_test.rb +68 -68
  183. data/test/cases/validations/uniqueness_validation_test.rb +457 -434
  184. data/test/cases/validations_repair_helper.rb +23 -23
  185. data/test/cases/validations_test.rb +165 -165
  186. data/test/cases/view_test.rb +119 -113
  187. data/test/cases/xml_serialization_test.rb +457 -457
  188. data/test/cases/yaml_serialization_test.rb +126 -86
  189. data/test/config.rb +5 -5
  190. data/test/config.yml +154 -154
  191. data/test/connections/native_ibm_db/connection.rb +43 -43
  192. data/test/fixtures/accounts.yml +29 -29
  193. data/test/fixtures/admin/accounts.yml +2 -2
  194. data/test/fixtures/admin/randomly_named_a9.yml +7 -7
  195. data/test/fixtures/admin/randomly_named_b0.yml +7 -7
  196. data/test/fixtures/admin/users.yml +10 -10
  197. data/test/fixtures/author_addresses.yml +17 -17
  198. data/test/fixtures/author_favorites.yml +3 -3
  199. data/test/fixtures/authors.yml +23 -23
  200. data/test/fixtures/binaries.yml +133 -133
  201. data/test/fixtures/books.yml +11 -11
  202. data/test/fixtures/bulbs.yml +5 -5
  203. data/test/fixtures/cars.yml +9 -9
  204. data/test/fixtures/categories.yml +19 -19
  205. data/test/fixtures/categories/special_categories.yml +9 -9
  206. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  207. data/test/fixtures/categories_ordered.yml +7 -7
  208. data/test/fixtures/categories_posts.yml +31 -31
  209. data/test/fixtures/categorizations.yml +23 -23
  210. data/test/fixtures/clubs.yml +8 -8
  211. data/test/fixtures/collections.yml +3 -3
  212. data/test/fixtures/colleges.yml +3 -3
  213. data/test/fixtures/comments.yml +65 -65
  214. data/test/fixtures/companies.yml +67 -67
  215. data/test/fixtures/computers.yml +10 -10
  216. data/test/fixtures/courses.yml +8 -8
  217. data/test/fixtures/customers.yml +25 -25
  218. data/test/fixtures/dashboards.yml +6 -6
  219. data/test/fixtures/developers.yml +21 -21
  220. data/test/fixtures/developers_projects.yml +16 -16
  221. data/test/fixtures/dog_lovers.yml +7 -7
  222. data/test/fixtures/dogs.yml +4 -4
  223. data/test/fixtures/doubloons.yml +3 -3
  224. data/test/fixtures/edges.yml +5 -5
  225. data/test/fixtures/entrants.yml +14 -14
  226. data/test/fixtures/essays.yml +6 -6
  227. data/test/fixtures/faces.yml +11 -11
  228. data/test/fixtures/fk_test_has_fk.yml +3 -3
  229. data/test/fixtures/fk_test_has_pk.yml +1 -1
  230. data/test/fixtures/friendships.yml +4 -4
  231. data/test/fixtures/funny_jokes.yml +10 -10
  232. data/test/fixtures/interests.yml +33 -33
  233. data/test/fixtures/items.yml +3 -3
  234. data/test/fixtures/jobs.yml +7 -7
  235. data/test/fixtures/legacy_things.yml +3 -3
  236. data/test/fixtures/mateys.yml +4 -4
  237. data/test/fixtures/member_details.yml +8 -8
  238. data/test/fixtures/member_types.yml +6 -6
  239. data/test/fixtures/members.yml +11 -11
  240. data/test/fixtures/memberships.yml +34 -34
  241. data/test/fixtures/men.yml +5 -5
  242. data/test/fixtures/minimalistics.yml +2 -2
  243. data/test/fixtures/minivans.yml +5 -5
  244. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  245. data/test/fixtures/mixins.yml +29 -29
  246. data/test/fixtures/movies.yml +7 -7
  247. data/test/fixtures/naked/csv/accounts.csv +1 -1
  248. data/test/fixtures/naked/yml/accounts.yml +1 -1
  249. data/test/fixtures/naked/yml/companies.yml +1 -1
  250. data/test/fixtures/naked/yml/courses.yml +1 -1
  251. data/test/fixtures/organizations.yml +5 -5
  252. data/test/fixtures/other_topics.yml +42 -42
  253. data/test/fixtures/owners.yml +9 -9
  254. data/test/fixtures/parrots.yml +27 -27
  255. data/test/fixtures/parrots_pirates.yml +7 -7
  256. data/test/fixtures/people.yml +24 -24
  257. data/test/fixtures/peoples_treasures.yml +3 -3
  258. data/test/fixtures/pets.yml +19 -19
  259. data/test/fixtures/pirates.yml +12 -12
  260. data/test/fixtures/posts.yml +80 -80
  261. data/test/fixtures/price_estimates.yml +7 -7
  262. data/test/fixtures/products.yml +4 -4
  263. data/test/fixtures/projects.yml +7 -7
  264. data/test/fixtures/randomly_named_a9.yml +7 -7
  265. data/test/fixtures/ratings.yml +14 -14
  266. data/test/fixtures/readers.yml +11 -11
  267. data/test/fixtures/references.yml +17 -17
  268. data/test/fixtures/reserved_words/distinct.yml +5 -5
  269. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  270. data/test/fixtures/reserved_words/group.yml +14 -14
  271. data/test/fixtures/reserved_words/select.yml +8 -8
  272. data/test/fixtures/reserved_words/values.yml +7 -7
  273. data/test/fixtures/ships.yml +6 -6
  274. data/test/fixtures/speedometers.yml +8 -8
  275. data/test/fixtures/sponsors.yml +12 -12
  276. data/test/fixtures/string_key_objects.yml +7 -7
  277. data/test/fixtures/subscribers.yml +10 -10
  278. data/test/fixtures/subscriptions.yml +12 -12
  279. data/test/fixtures/taggings.yml +78 -78
  280. data/test/fixtures/tags.yml +11 -11
  281. data/test/fixtures/tasks.yml +7 -7
  282. data/test/fixtures/teapots.yml +3 -3
  283. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  284. data/test/fixtures/to_be_linked/users.yml +10 -10
  285. data/test/fixtures/topics.yml +49 -49
  286. data/test/fixtures/toys.yml +14 -14
  287. data/test/fixtures/traffic_lights.yml +9 -9
  288. data/test/fixtures/treasures.yml +10 -10
  289. data/test/fixtures/uuid_children.yml +3 -3
  290. data/test/fixtures/uuid_parents.yml +2 -2
  291. data/test/fixtures/variants.yml +4 -4
  292. data/test/fixtures/vegetables.yml +19 -19
  293. data/test/fixtures/vertices.yml +3 -3
  294. data/test/fixtures/warehouse_things.yml +2 -2
  295. data/test/fixtures/zines.yml +5 -5
  296. data/test/ibm_db_test.rb +24 -24
  297. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  298. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  299. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  300. data/test/migrations/missing/1000_people_have_middle_names.rb +8 -8
  301. data/test/migrations/missing/1_people_have_last_names.rb +8 -8
  302. data/test/migrations/missing/3_we_need_reminders.rb +11 -11
  303. data/test/migrations/missing/4_innocent_jointable.rb +11 -11
  304. data/test/migrations/rename/1_we_need_things.rb +10 -10
  305. data/test/migrations/rename/2_rename_things.rb +8 -8
  306. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  307. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  308. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  309. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  310. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  311. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  312. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  313. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  314. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  315. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  316. data/test/migrations/valid/2_we_need_reminders.rb +11 -11
  317. data/test/migrations/valid/3_innocent_jointable.rb +11 -11
  318. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  319. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +11 -11
  320. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +11 -11
  321. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  322. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  323. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  324. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  325. data/test/models/admin.rb +4 -4
  326. data/test/models/admin/account.rb +2 -2
  327. data/test/models/admin/randomly_named_c1.rb +3 -3
  328. data/test/models/admin/user.rb +40 -40
  329. data/test/models/aircraft.rb +4 -4
  330. data/test/models/arunit2_model.rb +3 -3
  331. data/test/models/author.rb +212 -212
  332. data/test/models/auto_id.rb +4 -4
  333. data/test/models/autoloadable/extra_firm.rb +2 -2
  334. data/test/models/binary.rb +1 -1
  335. data/test/models/bird.rb +12 -12
  336. data/test/models/book.rb +18 -18
  337. data/test/models/boolean.rb +2 -2
  338. data/test/models/bulb.rb +51 -51
  339. data/test/models/cake_designer.rb +3 -3
  340. data/test/models/car.rb +26 -26
  341. data/test/models/carrier.rb +2 -2
  342. data/test/models/categorization.rb +19 -19
  343. data/test/models/category.rb +35 -35
  344. data/test/models/chef.rb +7 -3
  345. data/test/models/citation.rb +3 -3
  346. data/test/models/club.rb +23 -23
  347. data/test/models/college.rb +10 -10
  348. data/test/models/column.rb +3 -3
  349. data/test/models/column_name.rb +3 -3
  350. data/test/models/comment.rb +64 -64
  351. data/test/models/company.rb +228 -225
  352. data/test/models/company_in_module.rb +98 -98
  353. data/test/models/computer.rb +3 -3
  354. data/test/models/contact.rb +41 -41
  355. data/test/models/contract.rb +20 -20
  356. data/test/models/country.rb +7 -7
  357. data/test/models/course.rb +6 -6
  358. data/test/models/customer.rb +77 -77
  359. data/test/models/customer_carrier.rb +14 -14
  360. data/test/models/dashboard.rb +3 -3
  361. data/test/models/default.rb +2 -2
  362. data/test/models/department.rb +4 -4
  363. data/test/models/developer.rb +255 -252
  364. data/test/models/dog.rb +5 -5
  365. data/test/models/dog_lover.rb +5 -5
  366. data/test/models/doubloon.rb +12 -12
  367. data/test/models/drink_designer.rb +3 -3
  368. data/test/models/edge.rb +5 -5
  369. data/test/models/electron.rb +5 -5
  370. data/test/models/engine.rb +4 -4
  371. data/test/models/entrant.rb +3 -3
  372. data/test/models/essay.rb +5 -5
  373. data/test/models/event.rb +2 -2
  374. data/test/models/eye.rb +37 -37
  375. data/test/models/face.rb +9 -9
  376. data/test/models/friendship.rb +6 -6
  377. data/test/models/guid.rb +1 -1
  378. data/test/models/hotel.rb +9 -6
  379. data/test/models/image.rb +3 -3
  380. data/test/models/interest.rb +5 -5
  381. data/test/models/invoice.rb +4 -4
  382. data/test/models/item.rb +7 -7
  383. data/test/models/job.rb +7 -7
  384. data/test/models/joke.rb +7 -7
  385. data/test/models/keyboard.rb +3 -3
  386. data/test/models/legacy_thing.rb +3 -3
  387. data/test/models/lesson.rb +11 -11
  388. data/test/models/line_item.rb +3 -3
  389. data/test/models/liquid.rb +4 -4
  390. data/test/models/man.rb +11 -11
  391. data/test/models/matey.rb +4 -4
  392. data/test/models/member.rb +41 -41
  393. data/test/models/member_detail.rb +7 -7
  394. data/test/models/member_type.rb +3 -3
  395. data/test/models/membership.rb +35 -35
  396. data/test/models/minimalistic.rb +2 -2
  397. data/test/models/minivan.rb +9 -9
  398. data/test/models/mixed_case_monkey.rb +3 -3
  399. data/test/models/molecule.rb +6 -6
  400. data/test/models/movie.rb +5 -5
  401. data/test/models/order.rb +4 -4
  402. data/test/models/organization.rb +14 -14
  403. data/test/models/owner.rb +34 -34
  404. data/test/models/parrot.rb +29 -29
  405. data/test/models/person.rb +143 -143
  406. data/test/models/personal_legacy_thing.rb +4 -4
  407. data/test/models/pet.rb +15 -15
  408. data/test/models/pirate.rb +92 -92
  409. data/test/models/possession.rb +3 -3
  410. data/test/models/post.rb +264 -264
  411. data/test/models/price_estimate.rb +4 -4
  412. data/test/models/professor.rb +5 -5
  413. data/test/models/project.rb +31 -29
  414. data/test/models/publisher.rb +2 -2
  415. data/test/models/publisher/article.rb +4 -4
  416. data/test/models/publisher/magazine.rb +3 -3
  417. data/test/models/randomly_named_c1.rb +3 -3
  418. data/test/models/rating.rb +4 -4
  419. data/test/models/reader.rb +23 -23
  420. data/test/models/record.rb +2 -2
  421. data/test/models/reference.rb +22 -22
  422. data/test/models/reply.rb +61 -61
  423. data/test/models/ship.rb +33 -33
  424. data/test/models/ship_part.rb +7 -7
  425. data/test/models/shop.rb +17 -17
  426. data/test/models/shop_account.rb +6 -6
  427. data/test/models/speedometer.rb +6 -6
  428. data/test/models/sponsor.rb +7 -7
  429. data/test/models/string_key_object.rb +3 -3
  430. data/test/models/student.rb +4 -4
  431. data/test/models/subject.rb +16 -16
  432. data/test/models/subscriber.rb +8 -8
  433. data/test/models/subscription.rb +4 -4
  434. data/test/models/tag.rb +7 -7
  435. data/test/models/tagging.rb +13 -13
  436. data/test/models/task.rb +5 -5
  437. data/test/models/topic.rb +124 -124
  438. data/test/models/toy.rb +6 -6
  439. data/test/models/traffic_light.rb +4 -4
  440. data/test/models/treasure.rb +14 -14
  441. data/test/models/treaty.rb +7 -7
  442. data/test/models/tyre.rb +11 -11
  443. data/test/models/uuid_child.rb +3 -3
  444. data/test/models/uuid_parent.rb +3 -3
  445. data/test/models/vegetables.rb +24 -24
  446. data/test/models/vehicle.rb +6 -6
  447. data/test/models/vertex.rb +9 -9
  448. data/test/models/warehouse_thing.rb +5 -5
  449. data/test/models/wheel.rb +3 -3
  450. data/test/models/without_table.rb +3 -3
  451. data/test/models/zine.rb +3 -3
  452. data/test/schema/mysql2_specific_schema.rb +58 -58
  453. data/test/schema/mysql_specific_schema.rb +70 -70
  454. data/test/schema/oracle_specific_schema.rb +43 -43
  455. data/test/schema/postgresql_specific_schema.rb +202 -202
  456. data/test/schema/schema.rb +952 -938
  457. data/test/schema/sqlite_specific_schema.rb +21 -21
  458. data/test/support/config.rb +43 -43
  459. data/test/support/connection.rb +22 -22
  460. data/test/support/connection_helper.rb +14 -14
  461. data/test/support/ddl_helper.rb +8 -8
  462. data/test/support/schema_dumping_helper.rb +20 -20
  463. metadata +2 -2
@@ -1,434 +1,457 @@
1
- # encoding: utf-8
2
- require "cases/helper"
3
- require 'models/topic'
4
- require 'models/reply'
5
- require 'models/warehouse_thing'
6
- require 'models/guid'
7
- require 'models/event'
8
-
9
- class Wizard < ActiveRecord::Base
10
- self.abstract_class = true
11
-
12
- validates_uniqueness_of :name
13
- end
14
-
15
- class IneptWizard < Wizard
16
- validates_uniqueness_of :city
17
- end
18
-
19
- class Conjurer < IneptWizard
20
- end
21
-
22
- class Thaumaturgist < IneptWizard
23
- end
24
-
25
- class ReplyTitle; end
26
-
27
- class ReplyWithTitleObject < Reply
28
- validates_uniqueness_of :content, :scope => :title
29
-
30
- def title; ReplyTitle.new; end
31
- end
32
-
33
- class Employee < ActiveRecord::Base
34
- self.table_name = 'postgresql_arrays'
35
- validates_uniqueness_of :nicknames
36
- end
37
-
38
- class TopicWithUniqEvent < Topic
39
- belongs_to :event, foreign_key: :parent_id
40
- validates :event, uniqueness: true
41
- end
42
-
43
- class BigIntTest < ActiveRecord::Base
44
- INT_MAX_VALUE = 2147483647
45
- self.table_name = 'cars'
46
- validates :engines_count, uniqueness: true, inclusion: { in: 0..INT_MAX_VALUE }
47
- end
48
-
49
- class BigIntReverseTest < ActiveRecord::Base
50
- INT_MAX_VALUE = 2147483647
51
- self.table_name = 'cars'
52
- validates :engines_count, inclusion: { in: 0..INT_MAX_VALUE }
53
- validates :engines_count, uniqueness: true
54
- end
55
-
56
- class UniquenessValidationTest < ActiveRecord::TestCase
57
- INT_MAX_VALUE = 2147483647
58
-
59
- fixtures :topics, 'warehouse_things'
60
-
61
- repair_validations(Topic, Reply)
62
-
63
- def test_validate_uniqueness
64
- Topic.validates_uniqueness_of(:title)
65
-
66
- t = Topic.new("title" => "I'm uniqué!")
67
- assert t.save, "Should save t as unique"
68
-
69
- t.content = "Remaining unique"
70
- assert t.save, "Should still save t as unique"
71
-
72
- t2 = Topic.new("title" => "I'm uniqué!")
73
- assert !t2.valid?, "Shouldn't be valid"
74
- assert !t2.save, "Shouldn't save t2 as unique"
75
- assert_equal ["has already been taken"], t2.errors[:title]
76
-
77
- t2.title = "Now I am really also unique"
78
- assert t2.save, "Should now save t2 as unique"
79
- end
80
-
81
- def test_validate_uniqueness_with_alias_attribute
82
- Topic.alias_attribute :new_title, :title
83
- Topic.validates_uniqueness_of(:new_title)
84
-
85
- topic = Topic.new(new_title: 'abc')
86
- assert topic.valid?
87
- end
88
-
89
- def test_validates_uniqueness_with_nil_value
90
- Topic.validates_uniqueness_of(:title)
91
-
92
- t = Topic.new("title" => nil)
93
- assert t.save, "Should save t as unique"
94
-
95
- t2 = Topic.new("title" => nil)
96
- assert !t2.valid?, "Shouldn't be valid"
97
- assert !t2.save, "Shouldn't save t2 as unique"
98
- assert_equal ["has already been taken"], t2.errors[:title]
99
- end
100
-
101
- def test_validates_uniqueness_with_validates
102
- Topic.validates :title, :uniqueness => true
103
- Topic.create!('title' => 'abc')
104
-
105
- t2 = Topic.new('title' => 'abc')
106
- assert !t2.valid?
107
- assert t2.errors[:title]
108
- end
109
-
110
- def test_validate_uniqueness_when_integer_out_of_range
111
- entry = BigIntTest.create(engines_count: INT_MAX_VALUE + 1)
112
- assert_equal entry.errors[:engines_count], ['is not included in the list']
113
- end
114
-
115
- def test_validate_uniqueness_when_integer_out_of_range_show_order_does_not_matter
116
- entry = BigIntReverseTest.create(engines_count: INT_MAX_VALUE + 1)
117
- assert_equal entry.errors[:engines_count], ['is not included in the list']
118
- end
119
-
120
- def test_validates_uniqueness_with_newline_chars
121
- Topic.validates_uniqueness_of(:title, :case_sensitive => false)
122
-
123
- t = Topic.new("title" => "new\nline")
124
- assert t.save, "Should save t as unique"
125
- end
126
-
127
- def test_validate_uniqueness_with_scope
128
- Reply.validates_uniqueness_of(:content, :scope => "parent_id")
129
-
130
- t = Topic.create("title" => "I'm unique!")
131
-
132
- r1 = t.replies.create "title" => "r1", "content" => "hello world"
133
- assert r1.valid?, "Saving r1"
134
-
135
- r2 = t.replies.create "title" => "r2", "content" => "hello world"
136
- assert !r2.valid?, "Saving r2 first time"
137
-
138
- r2.content = "something else"
139
- assert r2.save, "Saving r2 second time"
140
-
141
- t2 = Topic.create("title" => "I'm unique too!")
142
- r3 = t2.replies.create "title" => "r3", "content" => "hello world"
143
- assert r3.valid?, "Saving r3"
144
- end
145
-
146
- def test_validate_uniqueness_with_object_scope
147
- Reply.validates_uniqueness_of(:content, :scope => :topic)
148
-
149
- t = Topic.create("title" => "I'm unique!")
150
-
151
- r1 = t.replies.create "title" => "r1", "content" => "hello world"
152
- assert r1.valid?, "Saving r1"
153
-
154
- r2 = t.replies.create "title" => "r2", "content" => "hello world"
155
- assert !r2.valid?, "Saving r2 first time"
156
- end
157
-
158
- def test_validate_uniqueness_with_composed_attribute_scope
159
- r1 = ReplyWithTitleObject.create "title" => "r1", "content" => "hello world"
160
- assert r1.valid?, "Saving r1"
161
-
162
- r2 = ReplyWithTitleObject.create "title" => "r1", "content" => "hello world"
163
- assert !r2.valid?, "Saving r2 first time"
164
- end
165
-
166
- def test_validate_uniqueness_with_object_arg
167
- Reply.validates_uniqueness_of(:topic)
168
-
169
- t = Topic.create("title" => "I'm unique!")
170
-
171
- r1 = t.replies.create "title" => "r1", "content" => "hello world"
172
- assert r1.valid?, "Saving r1"
173
-
174
- r2 = t.replies.create "title" => "r2", "content" => "hello world"
175
- assert !r2.valid?, "Saving r2 first time"
176
- end
177
-
178
- def test_validate_uniqueness_scoped_to_defining_class
179
- t = Topic.create("title" => "What, me worry?")
180
-
181
- r1 = t.unique_replies.create "title" => "r1", "content" => "a barrel of fun"
182
- assert r1.valid?, "Saving r1"
183
-
184
- r2 = t.silly_unique_replies.create "title" => "r2", "content" => "a barrel of fun"
185
- assert !r2.valid?, "Saving r2"
186
-
187
- # Should succeed as validates_uniqueness_of only applies to
188
- # UniqueReply and its subclasses
189
- r3 = t.replies.create "title" => "r2", "content" => "a barrel of fun"
190
- assert r3.valid?, "Saving r3"
191
- end
192
-
193
- def test_validate_uniqueness_with_scope_array
194
- Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id])
195
-
196
- t = Topic.create("title" => "The earth is actually flat!")
197
-
198
- r1 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply"
199
- assert r1.valid?, "Saving r1"
200
-
201
- r2 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply again..."
202
- assert !r2.valid?, "Saving r2. Double reply by same author."
203
-
204
- r2.author_email_address = "jeremy_alt_email@rubyonrails.com"
205
- assert r2.save, "Saving r2 the second time."
206
-
207
- r3 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy_alt_email@rubyonrails.com", "title" => "You're wrong", "content" => "It's cubic"
208
- assert !r3.valid?, "Saving r3"
209
-
210
- r3.author_name = "jj"
211
- assert r3.save, "Saving r3 the second time."
212
-
213
- r3.author_name = "jeremy"
214
- assert !r3.save, "Saving r3 the third time."
215
- end
216
-
217
- def test_validate_case_insensitive_uniqueness
218
- Topic.validates_uniqueness_of(:title, :parent_id, :case_sensitive => false, :allow_nil => true)
219
-
220
- t = Topic.new("title" => "I'm unique!", :parent_id => 2)
221
- assert t.save, "Should save t as unique"
222
-
223
- t.content = "Remaining unique"
224
- assert t.save, "Should still save t as unique"
225
-
226
- t2 = Topic.new("title" => "I'm UNIQUE!", :parent_id => 1)
227
- assert !t2.valid?, "Shouldn't be valid"
228
- assert !t2.save, "Shouldn't save t2 as unique"
229
- assert t2.errors[:title].any?
230
- assert t2.errors[:parent_id].any?
231
- assert_equal ["has already been taken"], t2.errors[:title]
232
-
233
- t2.title = "I'm truly UNIQUE!"
234
- assert !t2.valid?, "Shouldn't be valid"
235
- assert !t2.save, "Shouldn't save t2 as unique"
236
- assert t2.errors[:title].empty?
237
- assert t2.errors[:parent_id].any?
238
-
239
- t2.parent_id = 4
240
- assert t2.save, "Should now save t2 as unique"
241
-
242
- t2.parent_id = nil
243
- t2.title = nil
244
- assert t2.valid?, "should validate with nil"
245
- assert t2.save, "should save with nil"
246
-
247
- t_utf8 = Topic.new("title" => "Я тоже уникальный!")
248
- assert t_utf8.save, "Should save t_utf8 as unique"
249
-
250
- # If database hasn't UTF-8 character set, this test fails
251
- if Topic.all.merge!(:select => 'LOWER(title) AS title').find(t_utf8.id).title == тоже уникальный!"
252
- t2_utf8 = Topic.new("title" => "я тоже УНИКАЛЬНЫЙ!")
253
- assert !t2_utf8.valid?, "Shouldn't be valid"
254
- assert !t2_utf8.save, "Shouldn't save t2_utf8 as unique"
255
- end
256
- end
257
-
258
- def test_validate_case_sensitive_uniqueness_with_special_sql_like_chars
259
- Topic.validates_uniqueness_of(:title, :case_sensitive => true)
260
-
261
- t = Topic.new("title" => "I'm unique!")
262
- assert t.save, "Should save t as unique"
263
-
264
- t2 = Topic.new("title" => "I'm %")
265
- assert t2.save, "Should save t2 as unique"
266
-
267
- t3 = Topic.new("title" => "I'm uniqu_!")
268
- assert t3.save, "Should save t3 as unique"
269
- end
270
-
271
- def test_validate_case_insensitive_uniqueness_with_special_sql_like_chars
272
- Topic.validates_uniqueness_of(:title, :case_sensitive => false)
273
-
274
- t = Topic.new("title" => "I'm unique!")
275
- assert t.save, "Should save t as unique"
276
-
277
- t2 = Topic.new("title" => "I'm %")
278
- assert t2.save, "Should save t2 as unique"
279
-
280
- t3 = Topic.new("title" => "I'm uniqu_!")
281
- assert t3.save, "Should save t3 as unique"
282
- end
283
-
284
- def test_validate_case_sensitive_uniqueness
285
- Topic.validates_uniqueness_of(:title, :case_sensitive => true, :allow_nil => true)
286
-
287
- t = Topic.new("title" => "I'm unique!")
288
- assert t.save, "Should save t as unique"
289
-
290
- t.content = "Remaining unique"
291
- assert t.save, "Should still save t as unique"
292
-
293
- t2 = Topic.new("title" => "I'M UNIQUE!")
294
- assert t2.valid?, "Should be valid"
295
- assert t2.save, "Should save t2 as unique"
296
- assert t2.errors[:title].empty?
297
- assert t2.errors[:parent_id].empty?
298
- assert_not_equal ["has already been taken"], t2.errors[:title]
299
-
300
- t3 = Topic.new("title" => "I'M uNiQUe!")
301
- assert t3.valid?, "Should be valid"
302
- assert t3.save, "Should save t2 as unique"
303
- assert t3.errors[:title].empty?
304
- assert t3.errors[:parent_id].empty?
305
- assert_not_equal ["has already been taken"], t3.errors[:title]
306
- end
307
-
308
- def test_validate_case_sensitive_uniqueness_with_attribute_passed_as_integer
309
- Topic.validates_uniqueness_of(:title, :case_sensitive => true)
310
- Topic.create!('title' => 101)
311
-
312
- t2 = Topic.new('title' => 101)
313
- assert !t2.valid?
314
- assert t2.errors[:title]
315
- end
316
-
317
- def test_validate_uniqueness_with_non_standard_table_names
318
- i1 = WarehouseThing.create(:value => 1000)
319
- assert !i1.valid?, "i1 should not be valid"
320
- assert i1.errors[:value].any?, "Should not be empty"
321
- end
322
-
323
- def test_validates_uniqueness_inside_scoping
324
- Topic.validates_uniqueness_of(:title)
325
-
326
- Topic.where(:author_name => "David").scoping do
327
- t1 = Topic.new("title" => "I'm unique!", "author_name" => "Mary")
328
- assert t1.save
329
- t2 = Topic.new("title" => "I'm unique!", "author_name" => "David")
330
- assert !t2.valid?
331
- end
332
- end
333
-
334
- def test_validate_uniqueness_with_columns_which_are_sql_keywords
335
- repair_validations(Guid) do
336
- Guid.validates_uniqueness_of :key
337
- g = Guid.new
338
- g.key = "foo"
339
- assert_nothing_raised { !g.valid? }
340
- end
341
- end
342
-
343
- def test_validate_uniqueness_with_limit
344
- # Event.title is limited to 5 characters
345
- e1 = Event.create(:title => "abcde")
346
- assert e1.valid?, "Could not create an event with a unique, 5 character title"
347
- e2 = Event.create(:title => "abcdefgh")
348
- assert !e2.valid?, "Created an event whose title, with limit taken into account, is not unique"
349
- end
350
-
351
- def test_validate_uniqueness_with_limit_and_utf8
352
- unless current_adapter?(:IBM_DBAdapter)
353
- # Limit for the varchar field is number of bytes and not characters for DB2. Hence the below test cases is expected to fail.
354
- # Event.title is limited to 5 characters
355
- e1 = Event.create(:title => "一二三四五")
356
- assert e1.valid?, "Could not create an event with a unique, 5 character title"
357
- e2 = Event.create(:title => "一二三四五六七八")
358
- assert !e2.valid?, "Created an event whose title, with limit taken into account, is not unique"
359
- end
360
- end
361
-
362
- def test_validate_straight_inheritance_uniqueness
363
- w1 = IneptWizard.create(:name => "Rincewind", :city => "Ankh-Morpork")
364
- assert w1.valid?, "Saving w1"
365
-
366
- # Should use validation from base class (which is abstract)
367
- w2 = IneptWizard.new(:name => "Rincewind", :city => "Quirm")
368
- assert !w2.valid?, "w2 shouldn't be valid"
369
- assert w2.errors[:name].any?, "Should have errors for name"
370
- assert_equal ["has already been taken"], w2.errors[:name], "Should have uniqueness message for name"
371
-
372
- w3 = Conjurer.new(:name => "Rincewind", :city => "Quirm")
373
- assert !w3.valid?, "w3 shouldn't be valid"
374
- assert w3.errors[:name].any?, "Should have errors for name"
375
- assert_equal ["has already been taken"], w3.errors[:name], "Should have uniqueness message for name"
376
-
377
- w4 = Conjurer.create(:name => "The Amazing Bonko", :city => "Quirm")
378
- assert w4.valid?, "Saving w4"
379
-
380
- w5 = Thaumaturgist.new(:name => "The Amazing Bonko", :city => "Lancre")
381
- assert !w5.valid?, "w5 shouldn't be valid"
382
- assert w5.errors[:name].any?, "Should have errors for name"
383
- assert_equal ["has already been taken"], w5.errors[:name], "Should have uniqueness message for name"
384
-
385
- w6 = Thaumaturgist.new(:name => "Mustrum Ridcully", :city => "Quirm")
386
- assert !w6.valid?, "w6 shouldn't be valid"
387
- assert w6.errors[:city].any?, "Should have errors for city"
388
- assert_equal ["has already been taken"], w6.errors[:city], "Should have uniqueness message for city"
389
- end
390
-
391
- def test_validate_uniqueness_with_conditions
392
- Topic.validates_uniqueness_of :title, conditions: -> { where(approved: true) }
393
- Topic.create("title" => "I'm a topic", "approved" => true)
394
- Topic.create("title" => "I'm an unapproved topic", "approved" => false)
395
-
396
- t3 = Topic.new("title" => "I'm a topic", "approved" => true)
397
- assert !t3.valid?, "t3 shouldn't be valid"
398
-
399
- t4 = Topic.new("title" => "I'm an unapproved topic", "approved" => false)
400
- assert t4.valid?, "t4 should be valid"
401
- end
402
-
403
- def test_validate_uniqueness_with_non_callable_conditions_is_not_supported
404
- assert_raises(ArgumentError) {
405
- Topic.validates_uniqueness_of :title, conditions: Topic.where(approved: true)
406
- }
407
- end
408
-
409
- if current_adapter? :PostgreSQLAdapter
410
- def test_validate_uniqueness_with_array_column
411
- e1 = Employee.create("nicknames" => ["john", "johnny"], "commission_by_quarter" => [1000, 1200])
412
- assert e1.persisted?, "Saving e1"
413
-
414
- e2 = Employee.create("nicknames" => ["john", "johnny"], "commission_by_quarter" => [2200])
415
- assert !e2.persisted?, "e2 shouldn't be valid"
416
- assert e2.errors[:nicknames].any?, "Should have errors for nicknames"
417
- assert_equal ["has already been taken"], e2.errors[:nicknames], "Should have uniqueness message for nicknames"
418
- end
419
- end
420
-
421
- def test_validate_uniqueness_on_existing_relation
422
- event = Event.create
423
- assert TopicWithUniqEvent.create(event: event).valid?
424
-
425
- topic = TopicWithUniqEvent.new(event: event)
426
- assert_not topic.valid?
427
- assert_equal ['has already been taken'], topic.errors[:event]
428
- end
429
-
430
- def test_validate_uniqueness_on_empty_relation
431
- topic = TopicWithUniqEvent.new
432
- assert topic.valid?
433
- end
434
- end
1
+ # encoding: utf-8
2
+ require "cases/helper"
3
+ require 'models/topic'
4
+ require 'models/reply'
5
+ require 'models/warehouse_thing'
6
+ require 'models/guid'
7
+ require 'models/event'
8
+ require 'models/dashboard'
9
+
10
+ class Wizard < ActiveRecord::Base
11
+ self.abstract_class = true
12
+
13
+ validates_uniqueness_of :name
14
+ end
15
+
16
+ class IneptWizard < Wizard
17
+ validates_uniqueness_of :city
18
+ end
19
+
20
+ class Conjurer < IneptWizard
21
+ end
22
+
23
+ class Thaumaturgist < IneptWizard
24
+ end
25
+
26
+ class ReplyTitle; end
27
+
28
+ class ReplyWithTitleObject < Reply
29
+ validates_uniqueness_of :content, :scope => :title
30
+
31
+ def title; ReplyTitle.new; end
32
+ end
33
+
34
+ class Employee < ActiveRecord::Base
35
+ self.table_name = 'postgresql_arrays'
36
+ validates_uniqueness_of :nicknames
37
+ end
38
+
39
+ class TopicWithUniqEvent < Topic
40
+ belongs_to :event, foreign_key: :parent_id
41
+ validates :event, uniqueness: true
42
+ end
43
+
44
+ class BigIntTest < ActiveRecord::Base
45
+ INT_MAX_VALUE = 2147483647
46
+ self.table_name = 'cars'
47
+ validates :engines_count, uniqueness: true, inclusion: { in: 0..INT_MAX_VALUE }
48
+ end
49
+
50
+ class BigIntReverseTest < ActiveRecord::Base
51
+ INT_MAX_VALUE = 2147483647
52
+ self.table_name = 'cars'
53
+ validates :engines_count, inclusion: { in: 0..INT_MAX_VALUE }
54
+ validates :engines_count, uniqueness: true
55
+ end
56
+
57
+ class UniquenessValidationTest < ActiveRecord::TestCase
58
+ INT_MAX_VALUE = 2147483647
59
+
60
+ fixtures :topics, 'warehouse_things'
61
+
62
+ repair_validations(Topic, Reply)
63
+
64
+ def test_validate_uniqueness
65
+ Topic.validates_uniqueness_of(:title)
66
+
67
+ t = Topic.new("title" => "I'm uniqué!")
68
+ assert t.save, "Should save t as unique"
69
+
70
+ t.content = "Remaining unique"
71
+ assert t.save, "Should still save t as unique"
72
+
73
+ t2 = Topic.new("title" => "I'm uniqué!")
74
+ assert !t2.valid?, "Shouldn't be valid"
75
+ assert !t2.save, "Shouldn't save t2 as unique"
76
+ assert_equal ["has already been taken"], t2.errors[:title]
77
+
78
+ t2.title = "Now I am really also unique"
79
+ assert t2.save, "Should now save t2 as unique"
80
+ end
81
+
82
+ def test_validate_uniqueness_with_alias_attribute
83
+ Topic.alias_attribute :new_title, :title
84
+ Topic.validates_uniqueness_of(:new_title)
85
+
86
+ topic = Topic.new(new_title: 'abc')
87
+ assert topic.valid?
88
+ end
89
+
90
+ def test_validates_uniqueness_with_nil_value
91
+ Topic.validates_uniqueness_of(:title)
92
+
93
+ t = Topic.new("title" => nil)
94
+ assert t.save, "Should save t as unique"
95
+
96
+ t2 = Topic.new("title" => nil)
97
+ assert !t2.valid?, "Shouldn't be valid"
98
+ assert !t2.save, "Shouldn't save t2 as unique"
99
+ assert_equal ["has already been taken"], t2.errors[:title]
100
+ end
101
+
102
+ def test_validates_uniqueness_with_validates
103
+ Topic.validates :title, :uniqueness => true
104
+ Topic.create!('title' => 'abc')
105
+
106
+ t2 = Topic.new('title' => 'abc')
107
+ assert !t2.valid?
108
+ assert t2.errors[:title]
109
+ end
110
+
111
+ def test_validate_uniqueness_when_integer_out_of_range
112
+ entry = BigIntTest.create(engines_count: INT_MAX_VALUE + 1)
113
+ assert_equal entry.errors[:engines_count], ['is not included in the list']
114
+ end
115
+
116
+ def test_validate_uniqueness_when_integer_out_of_range_show_order_does_not_matter
117
+ entry = BigIntReverseTest.create(engines_count: INT_MAX_VALUE + 1)
118
+ assert_equal entry.errors[:engines_count], ['is not included in the list']
119
+ end
120
+
121
+ def test_validates_uniqueness_with_newline_chars
122
+ Topic.validates_uniqueness_of(:title, :case_sensitive => false)
123
+
124
+ t = Topic.new("title" => "new\nline")
125
+ assert t.save, "Should save t as unique"
126
+ end
127
+
128
+ def test_validate_uniqueness_with_scope
129
+ Reply.validates_uniqueness_of(:content, :scope => "parent_id")
130
+
131
+ t = Topic.create("title" => "I'm unique!")
132
+
133
+ r1 = t.replies.create "title" => "r1", "content" => "hello world"
134
+ assert r1.valid?, "Saving r1"
135
+
136
+ r2 = t.replies.create "title" => "r2", "content" => "hello world"
137
+ assert !r2.valid?, "Saving r2 first time"
138
+
139
+ r2.content = "something else"
140
+ assert r2.save, "Saving r2 second time"
141
+
142
+ t2 = Topic.create("title" => "I'm unique too!")
143
+ r3 = t2.replies.create "title" => "r3", "content" => "hello world"
144
+ assert r3.valid?, "Saving r3"
145
+ end
146
+
147
+ def test_validate_uniqueness_with_object_scope
148
+ Reply.validates_uniqueness_of(:content, :scope => :topic)
149
+
150
+ t = Topic.create("title" => "I'm unique!")
151
+
152
+ r1 = t.replies.create "title" => "r1", "content" => "hello world"
153
+ assert r1.valid?, "Saving r1"
154
+
155
+ r2 = t.replies.create "title" => "r2", "content" => "hello world"
156
+ assert !r2.valid?, "Saving r2 first time"
157
+ end
158
+
159
+ def test_validate_uniqueness_with_composed_attribute_scope
160
+ r1 = ReplyWithTitleObject.create "title" => "r1", "content" => "hello world"
161
+ assert r1.valid?, "Saving r1"
162
+
163
+ r2 = ReplyWithTitleObject.create "title" => "r1", "content" => "hello world"
164
+ assert !r2.valid?, "Saving r2 first time"
165
+ end
166
+
167
+ def test_validate_uniqueness_with_object_arg
168
+ Reply.validates_uniqueness_of(:topic)
169
+
170
+ t = Topic.create("title" => "I'm unique!")
171
+
172
+ r1 = t.replies.create "title" => "r1", "content" => "hello world"
173
+ assert r1.valid?, "Saving r1"
174
+
175
+ r2 = t.replies.create "title" => "r2", "content" => "hello world"
176
+ assert !r2.valid?, "Saving r2 first time"
177
+ end
178
+
179
+ def test_validate_uniqueness_scoped_to_defining_class
180
+ t = Topic.create("title" => "What, me worry?")
181
+
182
+ r1 = t.unique_replies.create "title" => "r1", "content" => "a barrel of fun"
183
+ assert r1.valid?, "Saving r1"
184
+
185
+ r2 = t.silly_unique_replies.create "title" => "r2", "content" => "a barrel of fun"
186
+ assert !r2.valid?, "Saving r2"
187
+
188
+ # Should succeed as validates_uniqueness_of only applies to
189
+ # UniqueReply and its subclasses
190
+ r3 = t.replies.create "title" => "r2", "content" => "a barrel of fun"
191
+ assert r3.valid?, "Saving r3"
192
+ end
193
+
194
+ def test_validate_uniqueness_with_scope_array
195
+ Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id])
196
+
197
+ t = Topic.create("title" => "The earth is actually flat!")
198
+
199
+ r1 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply"
200
+ assert r1.valid?, "Saving r1"
201
+
202
+ r2 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply again..."
203
+ assert !r2.valid?, "Saving r2. Double reply by same author."
204
+
205
+ r2.author_email_address = "jeremy_alt_email@rubyonrails.com"
206
+ assert r2.save, "Saving r2 the second time."
207
+
208
+ r3 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy_alt_email@rubyonrails.com", "title" => "You're wrong", "content" => "It's cubic"
209
+ assert !r3.valid?, "Saving r3"
210
+
211
+ r3.author_name = "jj"
212
+ assert r3.save, "Saving r3 the second time."
213
+
214
+ r3.author_name = "jeremy"
215
+ assert !r3.save, "Saving r3 the third time."
216
+ end
217
+
218
+ def test_validate_case_insensitive_uniqueness
219
+ Topic.validates_uniqueness_of(:title, :parent_id, :case_sensitive => false, :allow_nil => true)
220
+
221
+ t = Topic.new("title" => "I'm unique!", :parent_id => 2)
222
+ assert t.save, "Should save t as unique"
223
+
224
+ t.content = "Remaining unique"
225
+ assert t.save, "Should still save t as unique"
226
+
227
+ t2 = Topic.new("title" => "I'm UNIQUE!", :parent_id => 1)
228
+ assert !t2.valid?, "Shouldn't be valid"
229
+ assert !t2.save, "Shouldn't save t2 as unique"
230
+ assert t2.errors[:title].any?
231
+ assert t2.errors[:parent_id].any?
232
+ assert_equal ["has already been taken"], t2.errors[:title]
233
+
234
+ t2.title = "I'm truly UNIQUE!"
235
+ assert !t2.valid?, "Shouldn't be valid"
236
+ assert !t2.save, "Shouldn't save t2 as unique"
237
+ assert t2.errors[:title].empty?
238
+ assert t2.errors[:parent_id].any?
239
+
240
+ t2.parent_id = 4
241
+ assert t2.save, "Should now save t2 as unique"
242
+
243
+ t2.parent_id = nil
244
+ t2.title = nil
245
+ assert t2.valid?, "should validate with nil"
246
+ assert t2.save, "should save with nil"
247
+
248
+ t_utf8 = Topic.new("title" => тоже уникальный!")
249
+ assert t_utf8.save, "Should save t_utf8 as unique"
250
+
251
+ # If database hasn't UTF-8 character set, this test fails
252
+ if Topic.all.merge!(:select => 'LOWER(title) AS title').find(t_utf8.id).title == "я тоже уникальный!"
253
+ t2_utf8 = Topic.new("title" => "я тоже УНИКАЛЬНЫЙ!")
254
+ assert !t2_utf8.valid?, "Shouldn't be valid"
255
+ assert !t2_utf8.save, "Shouldn't save t2_utf8 as unique"
256
+ end
257
+ end
258
+
259
+ def test_validate_case_sensitive_uniqueness_with_special_sql_like_chars
260
+ Topic.validates_uniqueness_of(:title, :case_sensitive => true)
261
+
262
+ t = Topic.new("title" => "I'm unique!")
263
+ assert t.save, "Should save t as unique"
264
+
265
+ t2 = Topic.new("title" => "I'm %")
266
+ assert t2.save, "Should save t2 as unique"
267
+
268
+ t3 = Topic.new("title" => "I'm uniqu_!")
269
+ assert t3.save, "Should save t3 as unique"
270
+ end
271
+
272
+ def test_validate_case_insensitive_uniqueness_with_special_sql_like_chars
273
+ Topic.validates_uniqueness_of(:title, :case_sensitive => false)
274
+
275
+ t = Topic.new("title" => "I'm unique!")
276
+ assert t.save, "Should save t as unique"
277
+
278
+ t2 = Topic.new("title" => "I'm %")
279
+ assert t2.save, "Should save t2 as unique"
280
+
281
+ t3 = Topic.new("title" => "I'm uniqu_!")
282
+ assert t3.save, "Should save t3 as unique"
283
+ end
284
+
285
+ def test_validate_case_sensitive_uniqueness
286
+ Topic.validates_uniqueness_of(:title, :case_sensitive => true, :allow_nil => true)
287
+
288
+ t = Topic.new("title" => "I'm unique!")
289
+ assert t.save, "Should save t as unique"
290
+
291
+ t.content = "Remaining unique"
292
+ assert t.save, "Should still save t as unique"
293
+
294
+ t2 = Topic.new("title" => "I'M UNIQUE!")
295
+ assert t2.valid?, "Should be valid"
296
+ assert t2.save, "Should save t2 as unique"
297
+ assert t2.errors[:title].empty?
298
+ assert t2.errors[:parent_id].empty?
299
+ assert_not_equal ["has already been taken"], t2.errors[:title]
300
+
301
+ t3 = Topic.new("title" => "I'M uNiQUe!")
302
+ assert t3.valid?, "Should be valid"
303
+ assert t3.save, "Should save t2 as unique"
304
+ assert t3.errors[:title].empty?
305
+ assert t3.errors[:parent_id].empty?
306
+ assert_not_equal ["has already been taken"], t3.errors[:title]
307
+ end
308
+
309
+ def test_validate_case_sensitive_uniqueness_with_attribute_passed_as_integer
310
+ Topic.validates_uniqueness_of(:title, :case_sensitive => true)
311
+ Topic.create!('title' => 101)
312
+
313
+ t2 = Topic.new('title' => 101)
314
+ assert !t2.valid?
315
+ assert t2.errors[:title]
316
+ end
317
+
318
+ def test_validate_uniqueness_with_non_standard_table_names
319
+ i1 = WarehouseThing.create(:value => 1000)
320
+ assert !i1.valid?, "i1 should not be valid"
321
+ assert i1.errors[:value].any?, "Should not be empty"
322
+ end
323
+
324
+ def test_validates_uniqueness_inside_scoping
325
+ Topic.validates_uniqueness_of(:title)
326
+
327
+ Topic.where(:author_name => "David").scoping do
328
+ t1 = Topic.new("title" => "I'm unique!", "author_name" => "Mary")
329
+ assert t1.save
330
+ t2 = Topic.new("title" => "I'm unique!", "author_name" => "David")
331
+ assert !t2.valid?
332
+ end
333
+ end
334
+
335
+ def test_validate_uniqueness_with_columns_which_are_sql_keywords
336
+ repair_validations(Guid) do
337
+ Guid.validates_uniqueness_of :key
338
+ g = Guid.new
339
+ g.key = "foo"
340
+ assert_nothing_raised { !g.valid? }
341
+ end
342
+ end
343
+
344
+ def test_validate_uniqueness_with_limit
345
+ # Event.title is limited to 5 characters
346
+ e1 = Event.create(:title => "abcde")
347
+ assert e1.valid?, "Could not create an event with a unique, 5 character title"
348
+ e2 = Event.create(:title => "abcdefgh")
349
+ assert !e2.valid?, "Created an event whose title, with limit taken into account, is not unique"
350
+ end
351
+
352
+ def test_validate_uniqueness_with_limit_and_utf8
353
+ unless current_adapter?(:IBM_DBAdapter)
354
+ # Limit for the varchar field is number of bytes and not characters for DB2. Hence the below test cases is expected to fail.
355
+ # Event.title is limited to 5 characters
356
+ e1 = Event.create(:title => "一二三四五")
357
+ assert e1.valid?, "Could not create an event with a unique, 5 character title"
358
+ e2 = Event.create(:title => "一二三四五六七八")
359
+ assert !e2.valid?, "Created an event whose title, with limit taken into account, is not unique"
360
+ end
361
+ end
362
+
363
+ def test_validate_straight_inheritance_uniqueness
364
+ w1 = IneptWizard.create(:name => "Rincewind", :city => "Ankh-Morpork")
365
+ assert w1.valid?, "Saving w1"
366
+
367
+ # Should use validation from base class (which is abstract)
368
+ w2 = IneptWizard.new(:name => "Rincewind", :city => "Quirm")
369
+ assert !w2.valid?, "w2 shouldn't be valid"
370
+ assert w2.errors[:name].any?, "Should have errors for name"
371
+ assert_equal ["has already been taken"], w2.errors[:name], "Should have uniqueness message for name"
372
+
373
+ w3 = Conjurer.new(:name => "Rincewind", :city => "Quirm")
374
+ assert !w3.valid?, "w3 shouldn't be valid"
375
+ assert w3.errors[:name].any?, "Should have errors for name"
376
+ assert_equal ["has already been taken"], w3.errors[:name], "Should have uniqueness message for name"
377
+
378
+ w4 = Conjurer.create(:name => "The Amazing Bonko", :city => "Quirm")
379
+ assert w4.valid?, "Saving w4"
380
+
381
+ w5 = Thaumaturgist.new(:name => "The Amazing Bonko", :city => "Lancre")
382
+ assert !w5.valid?, "w5 shouldn't be valid"
383
+ assert w5.errors[:name].any?, "Should have errors for name"
384
+ assert_equal ["has already been taken"], w5.errors[:name], "Should have uniqueness message for name"
385
+
386
+ w6 = Thaumaturgist.new(:name => "Mustrum Ridcully", :city => "Quirm")
387
+ assert !w6.valid?, "w6 shouldn't be valid"
388
+ assert w6.errors[:city].any?, "Should have errors for city"
389
+ assert_equal ["has already been taken"], w6.errors[:city], "Should have uniqueness message for city"
390
+ end
391
+
392
+ def test_validate_uniqueness_with_conditions
393
+ Topic.validates_uniqueness_of :title, conditions: -> { where(approved: true) }
394
+ Topic.create("title" => "I'm a topic", "approved" => true)
395
+ Topic.create("title" => "I'm an unapproved topic", "approved" => false)
396
+
397
+ t3 = Topic.new("title" => "I'm a topic", "approved" => true)
398
+ assert !t3.valid?, "t3 shouldn't be valid"
399
+
400
+ t4 = Topic.new("title" => "I'm an unapproved topic", "approved" => false)
401
+ assert t4.valid?, "t4 should be valid"
402
+ end
403
+
404
+ def test_validate_uniqueness_with_non_callable_conditions_is_not_supported
405
+ assert_raises(ArgumentError) {
406
+ Topic.validates_uniqueness_of :title, conditions: Topic.where(approved: true)
407
+ }
408
+ end
409
+
410
+ if current_adapter? :PostgreSQLAdapter
411
+ def test_validate_uniqueness_with_array_column
412
+ e1 = Employee.create("nicknames" => ["john", "johnny"], "commission_by_quarter" => [1000, 1200])
413
+ assert e1.persisted?, "Saving e1"
414
+
415
+ e2 = Employee.create("nicknames" => ["john", "johnny"], "commission_by_quarter" => [2200])
416
+ assert !e2.persisted?, "e2 shouldn't be valid"
417
+ assert e2.errors[:nicknames].any?, "Should have errors for nicknames"
418
+ assert_equal ["has already been taken"], e2.errors[:nicknames], "Should have uniqueness message for nicknames"
419
+ end
420
+ end
421
+
422
+ def test_validate_uniqueness_on_existing_relation
423
+ event = Event.create
424
+ assert TopicWithUniqEvent.create(event: event).valid?
425
+
426
+ topic = TopicWithUniqEvent.new(event: event)
427
+ assert_not topic.valid?
428
+ assert_equal ['has already been taken'], topic.errors[:event]
429
+ end
430
+
431
+ def test_validate_uniqueness_on_empty_relation
432
+ topic = TopicWithUniqEvent.new
433
+ assert topic.valid?
434
+ end
435
+
436
+ def test_validate_uniqueness_without_primary_key
437
+ klass = Class.new(ActiveRecord::Base) do
438
+ self.table_name = "dashboards"
439
+
440
+ validates_uniqueness_of :dashboard_id
441
+
442
+ def self.name; "Dashboard" end
443
+ end
444
+
445
+ abc = klass.create!(dashboard_id: "abc")
446
+ assert klass.new(dashboard_id: "xyz").valid?
447
+ assert_not klass.new(dashboard_id: "abc").valid?
448
+
449
+ abc.dashboard_id = "def"
450
+
451
+ e = assert_raises ActiveRecord::UnknownPrimaryKey do
452
+ abc.save!
453
+ end
454
+ assert_match(/\AUnknown primary key for table dashboards in model/, e.message)
455
+ assert_match(/Can not validate uniqueness for persisted record without primary key.\z/, e.message)
456
+ end
457
+ end