ibm_db 3.0.4 → 3.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (459) 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/test/active_record/connection_adapters/fake_adapter.rb +46 -46
  19. data/test/assets/example.log +1 -1
  20. data/test/assets/test.txt +1 -1
  21. data/test/cases/adapter_test.rb +276 -261
  22. data/test/cases/aggregations_test.rb +158 -158
  23. data/test/cases/ar_schema_test.rb +161 -161
  24. data/test/cases/associations/association_scope_test.rb +21 -21
  25. data/test/cases/associations/belongs_to_associations_test.rb +1029 -1029
  26. data/test/cases/associations/callbacks_test.rb +192 -192
  27. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  28. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +26 -26
  29. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  30. data/test/cases/associations/eager_load_nested_include_test.rb +128 -128
  31. data/test/cases/associations/eager_singularization_test.rb +148 -148
  32. data/test/cases/associations/eager_test.rb +1429 -1411
  33. data/test/cases/associations/extension_test.rb +82 -82
  34. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +972 -932
  35. data/test/cases/associations/has_many_associations_test.rb +2182 -2162
  36. data/test/cases/associations/has_many_through_associations_test.rb +1204 -1204
  37. data/test/cases/associations/has_one_associations_test.rb +610 -610
  38. data/test/cases/associations/has_one_through_associations_test.rb +380 -380
  39. data/test/cases/associations/inner_join_association_test.rb +139 -139
  40. data/test/cases/associations/inverse_associations_test.rb +706 -693
  41. data/test/cases/associations/join_model_test.rb +754 -754
  42. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  43. data/test/cases/associations/required_test.rb +82 -82
  44. data/test/cases/associations_test.rb +380 -380
  45. data/test/cases/attribute_decorators_test.rb +125 -125
  46. data/test/cases/attribute_methods/read_test.rb +60 -60
  47. data/test/cases/attribute_methods/serialization_test.rb +29 -29
  48. data/test/cases/attribute_methods_test.rb +952 -952
  49. data/test/cases/attribute_set_test.rb +210 -200
  50. data/test/cases/attribute_test.rb +180 -180
  51. data/test/cases/attributes_test.rb +136 -136
  52. data/test/cases/autosave_association_test.rb +1595 -1595
  53. data/test/cases/base_test.rb +1664 -1638
  54. data/test/cases/batches_test.rb +212 -212
  55. data/test/cases/binary_test.rb +52 -52
  56. data/test/cases/bind_parameter_test.rb +100 -100
  57. data/test/cases/calculations_test.rb +646 -646
  58. data/test/cases/callbacks_test.rb +543 -543
  59. data/test/cases/clone_test.rb +40 -40
  60. data/test/cases/coders/yaml_column_test.rb +63 -63
  61. data/test/cases/column_alias_test.rb +17 -17
  62. data/test/cases/column_definition_test.rb +123 -123
  63. data/test/cases/connection_adapters/adapter_leasing_test.rb +54 -54
  64. data/test/cases/connection_adapters/connection_handler_test.rb +53 -53
  65. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  66. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +293 -293
  67. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +65 -65
  68. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  69. data/test/cases/connection_adapters/schema_cache_test.rb +56 -56
  70. data/test/cases/connection_adapters/type_lookup_test.rb +110 -110
  71. data/test/cases/connection_management_test.rb +122 -122
  72. data/test/cases/connection_pool_test.rb +346 -346
  73. data/test/cases/connection_specification/resolver_test.rb +116 -116
  74. data/test/cases/core_test.rb +112 -112
  75. data/test/cases/counter_cache_test.rb +209 -209
  76. data/test/cases/custom_locking_test.rb +17 -17
  77. data/test/cases/database_statements_test.rb +19 -19
  78. data/test/cases/date_time_test.rb +61 -61
  79. data/test/cases/defaults_test.rb +223 -223
  80. data/test/cases/dirty_test.rb +785 -775
  81. data/test/cases/disconnected_test.rb +28 -28
  82. data/test/cases/dup_test.rb +157 -157
  83. data/test/cases/enum_test.rb +290 -290
  84. data/test/cases/explain_subscriber_test.rb +64 -64
  85. data/test/cases/explain_test.rb +76 -76
  86. data/test/cases/finder_respond_to_test.rb +60 -60
  87. data/test/cases/finder_test.rb +1169 -1166
  88. data/test/cases/fixture_set/file_test.rb +138 -138
  89. data/test/cases/fixtures_test.rb +908 -897
  90. data/test/cases/forbidden_attributes_protection_test.rb +99 -99
  91. data/test/cases/habtm_destroy_order_test.rb +61 -61
  92. data/test/cases/helper.rb +210 -210
  93. data/test/cases/hot_compatibility_test.rb +54 -54
  94. data/test/cases/i18n_test.rb +45 -45
  95. data/test/cases/inheritance_test.rb +375 -375
  96. data/test/cases/integration_test.rb +139 -139
  97. data/test/cases/invalid_connection_test.rb +22 -22
  98. data/test/cases/invalid_date_test.rb +32 -32
  99. data/test/cases/invertible_migration_test.rb +295 -295
  100. data/test/cases/json_serialization_test.rb +302 -302
  101. data/test/cases/locking_test.rb +477 -477
  102. data/test/cases/log_subscriber_test.rb +136 -136
  103. data/test/cases/migration/change_schema_test - Copy.rb +448 -448
  104. data/test/cases/migration/change_schema_test.rb +512 -472
  105. data/test/cases/migration/change_table_test.rb +224 -224
  106. data/test/cases/migration/column_attributes_test.rb +192 -192
  107. data/test/cases/migration/column_positioning_test.rb +56 -56
  108. data/test/cases/migration/columns_test.rb +304 -304
  109. data/test/cases/migration/command_recorder_test.rb +305 -305
  110. data/test/cases/migration/create_join_table_test.rb +148 -148
  111. data/test/cases/migration/foreign_key_test - Changed.rb +325 -325
  112. data/test/cases/migration/foreign_key_test.rb +328 -360
  113. data/test/cases/migration/helper.rb +39 -39
  114. data/test/cases/migration/index_test.rb +216 -216
  115. data/test/cases/migration/logger_test.rb +36 -36
  116. data/test/cases/migration/pending_migrations_test.rb +53 -53
  117. data/test/cases/migration/references_foreign_key_test.rb +169 -214
  118. data/test/cases/migration/references_index_test.rb +101 -101
  119. data/test/cases/migration/references_statements_test.rb +116 -116
  120. data/test/cases/migration/rename_table_test.rb +93 -93
  121. data/test/cases/migration/table_and_index_test.rb +24 -24
  122. data/test/cases/migration_test.rb +959 -959
  123. data/test/cases/migrator_test.rb +388 -388
  124. data/test/cases/mixin_test.rb +70 -70
  125. data/test/cases/modules_test.rb +173 -173
  126. data/test/cases/multiparameter_attributes_test.rb +350 -350
  127. data/test/cases/multiple_db_test.rb +115 -115
  128. data/test/cases/nested_attributes_test.rb +1070 -1057
  129. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  130. data/test/cases/persistence_test.rb +909 -909
  131. data/test/cases/pooled_connections_test.rb +81 -81
  132. data/test/cases/primary_keys_test.rb +237 -237
  133. data/test/cases/query_cache_test.rb +326 -326
  134. data/test/cases/quoting_test.rb +156 -156
  135. data/test/cases/readonly_test.rb +118 -118
  136. data/test/cases/reaper_test.rb +85 -85
  137. data/test/cases/reflection_test.rb +463 -454
  138. data/test/cases/relation/delegation_test.rb +68 -68
  139. data/test/cases/relation/merging_test.rb +161 -161
  140. data/test/cases/relation/mutation_test.rb +165 -165
  141. data/test/cases/relation/predicate_builder_test.rb +14 -14
  142. data/test/cases/relation/where_chain_test.rb +181 -181
  143. data/test/cases/relation/where_test.rb +300 -300
  144. data/test/cases/relation/where_test2.rb +36 -36
  145. data/test/cases/relation_test.rb +319 -297
  146. data/test/cases/relations_test.rb +1815 -1815
  147. data/test/cases/reload_models_test.rb +22 -22
  148. data/test/cases/result_test.rb +80 -80
  149. data/test/cases/sanitize_test.rb +83 -83
  150. data/test/cases/schema_dumper_test.rb +463 -463
  151. data/test/cases/scoping/default_scoping_test.rb +454 -454
  152. data/test/cases/scoping/named_scoping_test.rb +524 -524
  153. data/test/cases/scoping/relation_scoping_test.rb +357 -357
  154. data/test/cases/serialization_test.rb +104 -104
  155. data/test/cases/serialized_attribute_test.rb +277 -277
  156. data/test/cases/statement_cache_test.rb +98 -98
  157. data/test/cases/store_test.rb +194 -194
  158. data/test/cases/tasks/database_tasks_test.rb +398 -396
  159. data/test/cases/tasks/mysql_rake_test.rb +324 -311
  160. data/test/cases/tasks/postgresql_rake_test.rb +250 -245
  161. data/test/cases/tasks/sqlite_rake_test.rb +193 -193
  162. data/test/cases/test_case.rb +123 -123
  163. data/test/cases/timestamp_test.rb +467 -468
  164. data/test/cases/transaction_callbacks_test.rb +452 -452
  165. data/test/cases/transaction_isolation_test.rb +106 -106
  166. data/test/cases/transactions_test.rb +817 -817
  167. data/test/cases/type/decimal_test.rb +56 -51
  168. data/test/cases/type/integer_test.rb +121 -121
  169. data/test/cases/type/string_test.rb +36 -36
  170. data/test/cases/type/type_map_test.rb +177 -177
  171. data/test/cases/type/unsigned_integer_test.rb +18 -18
  172. data/test/cases/types_test.rb +141 -141
  173. data/test/cases/unconnected_test.rb +33 -33
  174. data/test/cases/validations/association_validation_test.rb +86 -86
  175. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  176. data/test/cases/validations/i18n_validation_test.rb +90 -90
  177. data/test/cases/validations/length_validation_test.rb +47 -47
  178. data/test/cases/validations/presence_validation_test.rb +68 -68
  179. data/test/cases/validations/uniqueness_validation_test.rb +457 -434
  180. data/test/cases/validations_repair_helper.rb +23 -23
  181. data/test/cases/validations_test.rb +165 -165
  182. data/test/cases/view_test.rb +119 -113
  183. data/test/cases/xml_serialization_test.rb +457 -457
  184. data/test/cases/yaml_serialization_test.rb +126 -86
  185. data/test/config.rb +5 -5
  186. data/test/config.yml +154 -154
  187. data/test/connections/native_ibm_db/connection.rb +43 -43
  188. data/test/fixtures/accounts.yml +29 -29
  189. data/test/fixtures/admin/accounts.yml +2 -2
  190. data/test/fixtures/admin/randomly_named_a9.yml +7 -7
  191. data/test/fixtures/admin/randomly_named_b0.yml +7 -7
  192. data/test/fixtures/admin/users.yml +10 -10
  193. data/test/fixtures/author_addresses.yml +17 -17
  194. data/test/fixtures/author_favorites.yml +3 -3
  195. data/test/fixtures/authors.yml +23 -23
  196. data/test/fixtures/binaries.yml +133 -133
  197. data/test/fixtures/books.yml +11 -11
  198. data/test/fixtures/bulbs.yml +5 -5
  199. data/test/fixtures/cars.yml +9 -9
  200. data/test/fixtures/categories.yml +19 -19
  201. data/test/fixtures/categories/special_categories.yml +9 -9
  202. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  203. data/test/fixtures/categories_ordered.yml +7 -7
  204. data/test/fixtures/categories_posts.yml +31 -31
  205. data/test/fixtures/categorizations.yml +23 -23
  206. data/test/fixtures/clubs.yml +8 -8
  207. data/test/fixtures/collections.yml +3 -3
  208. data/test/fixtures/colleges.yml +3 -3
  209. data/test/fixtures/comments.yml +65 -65
  210. data/test/fixtures/companies.yml +67 -67
  211. data/test/fixtures/computers.yml +10 -10
  212. data/test/fixtures/courses.yml +8 -8
  213. data/test/fixtures/customers.yml +25 -25
  214. data/test/fixtures/dashboards.yml +6 -6
  215. data/test/fixtures/developers.yml +21 -21
  216. data/test/fixtures/developers_projects.yml +16 -16
  217. data/test/fixtures/dog_lovers.yml +7 -7
  218. data/test/fixtures/dogs.yml +4 -4
  219. data/test/fixtures/doubloons.yml +3 -3
  220. data/test/fixtures/edges.yml +5 -5
  221. data/test/fixtures/entrants.yml +14 -14
  222. data/test/fixtures/essays.yml +6 -6
  223. data/test/fixtures/faces.yml +11 -11
  224. data/test/fixtures/fk_test_has_fk.yml +3 -3
  225. data/test/fixtures/fk_test_has_pk.yml +1 -1
  226. data/test/fixtures/friendships.yml +4 -4
  227. data/test/fixtures/funny_jokes.yml +10 -10
  228. data/test/fixtures/interests.yml +33 -33
  229. data/test/fixtures/items.yml +3 -3
  230. data/test/fixtures/jobs.yml +7 -7
  231. data/test/fixtures/legacy_things.yml +3 -3
  232. data/test/fixtures/mateys.yml +4 -4
  233. data/test/fixtures/member_details.yml +8 -8
  234. data/test/fixtures/member_types.yml +6 -6
  235. data/test/fixtures/members.yml +11 -11
  236. data/test/fixtures/memberships.yml +34 -34
  237. data/test/fixtures/men.yml +5 -5
  238. data/test/fixtures/minimalistics.yml +2 -2
  239. data/test/fixtures/minivans.yml +5 -5
  240. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  241. data/test/fixtures/mixins.yml +29 -29
  242. data/test/fixtures/movies.yml +7 -7
  243. data/test/fixtures/naked/csv/accounts.csv +1 -1
  244. data/test/fixtures/naked/yml/accounts.yml +1 -1
  245. data/test/fixtures/naked/yml/companies.yml +1 -1
  246. data/test/fixtures/naked/yml/courses.yml +1 -1
  247. data/test/fixtures/organizations.yml +5 -5
  248. data/test/fixtures/other_topics.yml +42 -42
  249. data/test/fixtures/owners.yml +9 -9
  250. data/test/fixtures/parrots.yml +27 -27
  251. data/test/fixtures/parrots_pirates.yml +7 -7
  252. data/test/fixtures/people.yml +24 -24
  253. data/test/fixtures/peoples_treasures.yml +3 -3
  254. data/test/fixtures/pets.yml +19 -19
  255. data/test/fixtures/pirates.yml +12 -12
  256. data/test/fixtures/posts.yml +80 -80
  257. data/test/fixtures/price_estimates.yml +7 -7
  258. data/test/fixtures/products.yml +4 -4
  259. data/test/fixtures/projects.yml +7 -7
  260. data/test/fixtures/randomly_named_a9.yml +7 -7
  261. data/test/fixtures/ratings.yml +14 -14
  262. data/test/fixtures/readers.yml +11 -11
  263. data/test/fixtures/references.yml +17 -17
  264. data/test/fixtures/reserved_words/distinct.yml +5 -5
  265. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  266. data/test/fixtures/reserved_words/group.yml +14 -14
  267. data/test/fixtures/reserved_words/select.yml +8 -8
  268. data/test/fixtures/reserved_words/values.yml +7 -7
  269. data/test/fixtures/ships.yml +6 -6
  270. data/test/fixtures/speedometers.yml +8 -8
  271. data/test/fixtures/sponsors.yml +12 -12
  272. data/test/fixtures/string_key_objects.yml +7 -7
  273. data/test/fixtures/subscribers.yml +10 -10
  274. data/test/fixtures/subscriptions.yml +12 -12
  275. data/test/fixtures/taggings.yml +78 -78
  276. data/test/fixtures/tags.yml +11 -11
  277. data/test/fixtures/tasks.yml +7 -7
  278. data/test/fixtures/teapots.yml +3 -3
  279. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  280. data/test/fixtures/to_be_linked/users.yml +10 -10
  281. data/test/fixtures/topics.yml +49 -49
  282. data/test/fixtures/toys.yml +14 -14
  283. data/test/fixtures/traffic_lights.yml +9 -9
  284. data/test/fixtures/treasures.yml +10 -10
  285. data/test/fixtures/uuid_children.yml +3 -3
  286. data/test/fixtures/uuid_parents.yml +2 -2
  287. data/test/fixtures/variants.yml +4 -4
  288. data/test/fixtures/vegetables.yml +19 -19
  289. data/test/fixtures/vertices.yml +3 -3
  290. data/test/fixtures/warehouse_things.yml +2 -2
  291. data/test/fixtures/zines.yml +5 -5
  292. data/test/ibm_db_test.rb +24 -24
  293. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  294. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  295. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  296. data/test/migrations/missing/1000_people_have_middle_names.rb +8 -8
  297. data/test/migrations/missing/1_people_have_last_names.rb +8 -8
  298. data/test/migrations/missing/3_we_need_reminders.rb +11 -11
  299. data/test/migrations/missing/4_innocent_jointable.rb +11 -11
  300. data/test/migrations/rename/1_we_need_things.rb +10 -10
  301. data/test/migrations/rename/2_rename_things.rb +8 -8
  302. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  303. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  304. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  305. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  306. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  307. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  308. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  309. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  310. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  311. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  312. data/test/migrations/valid/2_we_need_reminders.rb +11 -11
  313. data/test/migrations/valid/3_innocent_jointable.rb +11 -11
  314. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  315. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +11 -11
  316. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +11 -11
  317. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  318. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  319. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  320. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  321. data/test/models/admin.rb +4 -4
  322. data/test/models/admin/account.rb +2 -2
  323. data/test/models/admin/randomly_named_c1.rb +3 -3
  324. data/test/models/admin/user.rb +40 -40
  325. data/test/models/aircraft.rb +4 -4
  326. data/test/models/arunit2_model.rb +3 -3
  327. data/test/models/author.rb +212 -212
  328. data/test/models/auto_id.rb +4 -4
  329. data/test/models/autoloadable/extra_firm.rb +2 -2
  330. data/test/models/binary.rb +1 -1
  331. data/test/models/bird.rb +12 -12
  332. data/test/models/book.rb +18 -18
  333. data/test/models/boolean.rb +2 -2
  334. data/test/models/bulb.rb +51 -51
  335. data/test/models/cake_designer.rb +3 -3
  336. data/test/models/car.rb +26 -26
  337. data/test/models/carrier.rb +2 -2
  338. data/test/models/categorization.rb +19 -19
  339. data/test/models/category.rb +35 -35
  340. data/test/models/chef.rb +7 -3
  341. data/test/models/citation.rb +3 -3
  342. data/test/models/club.rb +23 -23
  343. data/test/models/college.rb +10 -10
  344. data/test/models/column.rb +3 -3
  345. data/test/models/column_name.rb +3 -3
  346. data/test/models/comment.rb +64 -64
  347. data/test/models/company.rb +228 -225
  348. data/test/models/company_in_module.rb +98 -98
  349. data/test/models/computer.rb +3 -3
  350. data/test/models/contact.rb +41 -41
  351. data/test/models/contract.rb +20 -20
  352. data/test/models/country.rb +7 -7
  353. data/test/models/course.rb +6 -6
  354. data/test/models/customer.rb +77 -77
  355. data/test/models/customer_carrier.rb +14 -14
  356. data/test/models/dashboard.rb +3 -3
  357. data/test/models/default.rb +2 -2
  358. data/test/models/department.rb +4 -4
  359. data/test/models/developer.rb +255 -252
  360. data/test/models/dog.rb +5 -5
  361. data/test/models/dog_lover.rb +5 -5
  362. data/test/models/doubloon.rb +12 -12
  363. data/test/models/drink_designer.rb +3 -3
  364. data/test/models/edge.rb +5 -5
  365. data/test/models/electron.rb +5 -5
  366. data/test/models/engine.rb +4 -4
  367. data/test/models/entrant.rb +3 -3
  368. data/test/models/essay.rb +5 -5
  369. data/test/models/event.rb +2 -2
  370. data/test/models/eye.rb +37 -37
  371. data/test/models/face.rb +9 -9
  372. data/test/models/friendship.rb +6 -6
  373. data/test/models/guid.rb +1 -1
  374. data/test/models/hotel.rb +9 -6
  375. data/test/models/image.rb +3 -3
  376. data/test/models/interest.rb +5 -5
  377. data/test/models/invoice.rb +4 -4
  378. data/test/models/item.rb +7 -7
  379. data/test/models/job.rb +7 -7
  380. data/test/models/joke.rb +7 -7
  381. data/test/models/keyboard.rb +3 -3
  382. data/test/models/legacy_thing.rb +3 -3
  383. data/test/models/lesson.rb +11 -11
  384. data/test/models/line_item.rb +3 -3
  385. data/test/models/liquid.rb +4 -4
  386. data/test/models/man.rb +11 -11
  387. data/test/models/matey.rb +4 -4
  388. data/test/models/member.rb +41 -41
  389. data/test/models/member_detail.rb +7 -7
  390. data/test/models/member_type.rb +3 -3
  391. data/test/models/membership.rb +35 -35
  392. data/test/models/minimalistic.rb +2 -2
  393. data/test/models/minivan.rb +9 -9
  394. data/test/models/mixed_case_monkey.rb +3 -3
  395. data/test/models/molecule.rb +6 -6
  396. data/test/models/movie.rb +5 -5
  397. data/test/models/order.rb +4 -4
  398. data/test/models/organization.rb +14 -14
  399. data/test/models/owner.rb +34 -34
  400. data/test/models/parrot.rb +29 -29
  401. data/test/models/person.rb +143 -143
  402. data/test/models/personal_legacy_thing.rb +4 -4
  403. data/test/models/pet.rb +15 -15
  404. data/test/models/pirate.rb +92 -92
  405. data/test/models/possession.rb +3 -3
  406. data/test/models/post.rb +264 -264
  407. data/test/models/price_estimate.rb +4 -4
  408. data/test/models/professor.rb +5 -5
  409. data/test/models/project.rb +31 -29
  410. data/test/models/publisher.rb +2 -2
  411. data/test/models/publisher/article.rb +4 -4
  412. data/test/models/publisher/magazine.rb +3 -3
  413. data/test/models/randomly_named_c1.rb +3 -3
  414. data/test/models/rating.rb +4 -4
  415. data/test/models/reader.rb +23 -23
  416. data/test/models/record.rb +2 -2
  417. data/test/models/reference.rb +22 -22
  418. data/test/models/reply.rb +61 -61
  419. data/test/models/ship.rb +33 -33
  420. data/test/models/ship_part.rb +7 -7
  421. data/test/models/shop.rb +17 -17
  422. data/test/models/shop_account.rb +6 -6
  423. data/test/models/speedometer.rb +6 -6
  424. data/test/models/sponsor.rb +7 -7
  425. data/test/models/string_key_object.rb +3 -3
  426. data/test/models/student.rb +4 -4
  427. data/test/models/subject.rb +16 -16
  428. data/test/models/subscriber.rb +8 -8
  429. data/test/models/subscription.rb +4 -4
  430. data/test/models/tag.rb +7 -7
  431. data/test/models/tagging.rb +13 -13
  432. data/test/models/task.rb +5 -5
  433. data/test/models/topic.rb +124 -124
  434. data/test/models/toy.rb +6 -6
  435. data/test/models/traffic_light.rb +4 -4
  436. data/test/models/treasure.rb +14 -14
  437. data/test/models/treaty.rb +7 -7
  438. data/test/models/tyre.rb +11 -11
  439. data/test/models/uuid_child.rb +3 -3
  440. data/test/models/uuid_parent.rb +3 -3
  441. data/test/models/vegetables.rb +24 -24
  442. data/test/models/vehicle.rb +6 -6
  443. data/test/models/vertex.rb +9 -9
  444. data/test/models/warehouse_thing.rb +5 -5
  445. data/test/models/wheel.rb +3 -3
  446. data/test/models/without_table.rb +3 -3
  447. data/test/models/zine.rb +3 -3
  448. data/test/schema/mysql2_specific_schema.rb +58 -58
  449. data/test/schema/mysql_specific_schema.rb +70 -70
  450. data/test/schema/oracle_specific_schema.rb +43 -43
  451. data/test/schema/postgresql_specific_schema.rb +202 -202
  452. data/test/schema/schema.rb +952 -938
  453. data/test/schema/sqlite_specific_schema.rb +21 -21
  454. data/test/support/config.rb +43 -43
  455. data/test/support/connection.rb +22 -22
  456. data/test/support/connection_helper.rb +14 -14
  457. data/test/support/ddl_helper.rb +8 -8
  458. data/test/support/schema_dumping_helper.rb +20 -20
  459. metadata +3 -3
@@ -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