ibm_db 5.1.0-x86-mingw32 → 5.3.2-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 (624) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +9 -0
  3. data/LICENSE +55 -18
  4. data/ext/Makefile +14 -14
  5. data/ext/extconf.rb +4 -4
  6. data/ext/ibm_db.c +62 -57
  7. data/ext/ibm_db.o +0 -0
  8. data/ext/ibm_db.so +0 -0
  9. data/ext/mkmf.log +11 -11
  10. data/ext/ruby_ibm_db_cli.c +1 -0
  11. data/ext/ruby_ibm_db_cli.o +0 -0
  12. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1463 -1279
  13. data/lib/ibm_db.so +1 -0
  14. data/lib/mswin32/ibm_db.rb +7 -3
  15. data/lib/mswin32/rb2x/i386/ruby25/ibm_db.so +0 -0
  16. data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
  17. data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
  18. data/test/activejob/destroy_association_async_test.rb +305 -0
  19. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  20. data/test/activejob/helper.rb +15 -0
  21. data/test/assets/schema_dump_5_1.yml +345 -0
  22. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  23. data/test/cases/adapter_test.rb +432 -218
  24. data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
  25. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  26. data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
  27. data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
  28. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
  29. data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
  30. data/test/cases/adapters/mysql2/connection_test.rb +48 -50
  31. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  32. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
  33. data/test/cases/adapters/mysql2/enum_test.rb +32 -11
  34. data/test/cases/adapters/mysql2/explain_test.rb +13 -11
  35. data/test/cases/adapters/mysql2/json_test.rb +17 -188
  36. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  37. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
  38. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  39. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  40. data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
  41. data/test/cases/adapters/mysql2/schema_test.rb +24 -22
  42. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  43. data/test/cases/adapters/mysql2/sp_test.rb +10 -8
  44. data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
  45. data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
  46. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  47. data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
  48. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  49. data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
  50. data/test/cases/adapters/postgresql/array_test.rb +118 -63
  51. data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
  52. data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
  53. data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
  54. data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
  55. data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
  56. data/test/cases/adapters/postgresql/citext_test.rb +58 -58
  57. data/test/cases/adapters/postgresql/collation_test.rb +17 -15
  58. data/test/cases/adapters/postgresql/composite_test.rb +25 -23
  59. data/test/cases/adapters/postgresql/connection_test.rb +73 -85
  60. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  61. data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
  62. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  63. data/test/cases/adapters/postgresql/domain_test.rb +9 -7
  64. data/test/cases/adapters/postgresql/enum_test.rb +12 -10
  65. data/test/cases/adapters/postgresql/explain_test.rb +10 -8
  66. data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
  67. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  68. data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
  69. data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
  70. data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
  71. data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
  72. data/test/cases/adapters/postgresql/integer_test.rb +2 -0
  73. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  74. data/test/cases/adapters/postgresql/json_test.rb +16 -201
  75. data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
  76. data/test/cases/adapters/postgresql/money_test.rb +47 -16
  77. data/test/cases/adapters/postgresql/network_test.rb +36 -28
  78. data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
  79. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  80. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  81. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  82. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
  83. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  84. data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
  85. data/test/cases/adapters/postgresql/range_test.rb +406 -292
  86. data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
  87. data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
  88. data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
  89. data/test/cases/adapters/postgresql/schema_test.rb +207 -91
  90. data/test/cases/adapters/postgresql/serial_test.rb +9 -7
  91. data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
  92. data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
  93. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  94. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  95. data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
  96. data/test/cases/adapters/postgresql/utils_test.rb +11 -9
  97. data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
  98. data/test/cases/adapters/postgresql/xml_test.rb +10 -14
  99. data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
  100. data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
  101. data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
  102. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  103. data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
  104. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  105. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
  106. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
  107. data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
  108. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  109. data/test/cases/aggregations_test.rb +14 -12
  110. data/test/cases/annotate_test.rb +46 -0
  111. data/test/cases/ar_schema_test.rb +153 -86
  112. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  113. data/test/cases/arel/attributes/math_test.rb +83 -0
  114. data/test/cases/arel/attributes_test.rb +27 -0
  115. data/test/cases/arel/collectors/bind_test.rb +40 -0
  116. data/test/cases/arel/collectors/composite_test.rb +47 -0
  117. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  118. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  119. data/test/cases/arel/crud_test.rb +65 -0
  120. data/test/cases/arel/delete_manager_test.rb +53 -0
  121. data/test/cases/arel/factory_methods_test.rb +46 -0
  122. data/test/cases/arel/helper.rb +45 -0
  123. data/test/cases/arel/insert_manager_test.rb +241 -0
  124. data/test/cases/arel/nodes/and_test.rb +30 -0
  125. data/test/cases/arel/nodes/as_test.rb +36 -0
  126. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  127. data/test/cases/arel/nodes/bin_test.rb +35 -0
  128. data/test/cases/arel/nodes/binary_test.rb +29 -0
  129. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  130. data/test/cases/arel/nodes/case_test.rb +96 -0
  131. data/test/cases/arel/nodes/casted_test.rb +18 -0
  132. data/test/cases/arel/nodes/comment_test.rb +22 -0
  133. data/test/cases/arel/nodes/count_test.rb +35 -0
  134. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  135. data/test/cases/arel/nodes/descending_test.rb +46 -0
  136. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  137. data/test/cases/arel/nodes/equality_test.rb +62 -0
  138. data/test/cases/arel/nodes/extract_test.rb +43 -0
  139. data/test/cases/arel/nodes/false_test.rb +21 -0
  140. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  141. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  142. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  143. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  144. data/test/cases/arel/nodes/node_test.rb +22 -0
  145. data/test/cases/arel/nodes/not_test.rb +31 -0
  146. data/test/cases/arel/nodes/or_test.rb +36 -0
  147. data/test/cases/arel/nodes/over_test.rb +69 -0
  148. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  149. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  150. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  151. data/test/cases/arel/nodes/sum_test.rb +35 -0
  152. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  153. data/test/cases/arel/nodes/true_test.rb +21 -0
  154. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  155. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  156. data/test/cases/arel/nodes/window_test.rb +81 -0
  157. data/test/cases/arel/nodes_test.rb +34 -0
  158. data/test/cases/arel/select_manager_test.rb +1238 -0
  159. data/test/cases/arel/support/fake_record.rb +135 -0
  160. data/test/cases/arel/table_test.rb +216 -0
  161. data/test/cases/arel/update_manager_test.rb +126 -0
  162. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  163. data/test/cases/arel/visitors/dot_test.rb +90 -0
  164. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  165. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  166. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  167. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  168. data/test/cases/associations/belongs_to_associations_test.rb +510 -158
  169. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
  170. data/test/cases/associations/callbacks_test.rb +56 -38
  171. data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
  172. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
  173. data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
  174. data/test/cases/associations/eager_singularization_test.rb +21 -21
  175. data/test/cases/associations/eager_test.rb +559 -415
  176. data/test/cases/associations/extension_test.rb +18 -12
  177. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
  178. data/test/cases/associations/has_many_associations_test.rb +1038 -465
  179. data/test/cases/associations/has_many_through_associations_test.rb +558 -249
  180. data/test/cases/associations/has_one_associations_test.rb +294 -129
  181. data/test/cases/associations/has_one_through_associations_test.rb +121 -75
  182. data/test/cases/associations/inner_join_association_test.rb +114 -38
  183. data/test/cases/associations/inverse_associations_test.rb +606 -398
  184. data/test/cases/associations/join_model_test.rb +158 -148
  185. data/test/cases/associations/left_outer_join_association_test.rb +59 -24
  186. data/test/cases/associations/nested_through_associations_test.rb +166 -109
  187. data/test/cases/associations/required_test.rb +35 -10
  188. data/test/cases/associations_test.rb +241 -110
  189. data/test/cases/attribute_methods/read_test.rb +11 -11
  190. data/test/cases/attribute_methods_test.rb +413 -298
  191. data/test/cases/attributes_test.rb +145 -27
  192. data/test/cases/autosave_association_test.rb +681 -436
  193. data/test/cases/base_prevent_writes_test.rb +229 -0
  194. data/test/cases/base_test.rb +599 -542
  195. data/test/cases/batches_test.rb +288 -82
  196. data/test/cases/binary_test.rb +26 -31
  197. data/test/cases/bind_parameter_test.rb +194 -21
  198. data/test/cases/boolean_test.rb +52 -0
  199. data/test/cases/cache_key_test.rb +110 -5
  200. data/test/cases/calculations_test.rb +740 -177
  201. data/test/cases/callbacks_test.rb +74 -207
  202. data/test/cases/clone_test.rb +15 -10
  203. data/test/cases/coders/json_test.rb +2 -0
  204. data/test/cases/coders/yaml_column_test.rb +16 -13
  205. data/test/cases/collection_cache_key_test.rb +177 -20
  206. data/test/cases/column_alias_test.rb +9 -7
  207. data/test/cases/column_definition_test.rb +10 -68
  208. data/test/cases/comment_test.rb +166 -107
  209. data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
  210. data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
  211. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  212. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  213. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  214. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  215. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  216. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  217. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
  218. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
  219. data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
  220. data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
  221. data/test/cases/connection_management_test.rb +13 -11
  222. data/test/cases/connection_pool_test.rb +316 -83
  223. data/test/cases/core_test.rb +82 -58
  224. data/test/cases/counter_cache_test.rb +204 -50
  225. data/test/cases/custom_locking_test.rb +5 -3
  226. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  227. data/test/cases/database_configurations/resolver_test.rb +150 -0
  228. data/test/cases/database_configurations_test.rb +145 -0
  229. data/test/cases/database_selector_test.rb +296 -0
  230. data/test/cases/database_statements_test.rb +18 -16
  231. data/test/cases/date_test.rb +8 -16
  232. data/test/cases/date_time_precision_test.rb +100 -78
  233. data/test/cases/date_time_test.rb +23 -8
  234. data/test/cases/defaults_test.rb +106 -71
  235. data/test/cases/delegated_type_test.rb +57 -0
  236. data/test/cases/dirty_test.rb +419 -223
  237. data/test/cases/disconnected_test.rb +6 -6
  238. data/test/cases/dup_test.rb +54 -27
  239. data/test/cases/enum_test.rb +461 -82
  240. data/test/cases/errors_test.rb +7 -7
  241. data/test/cases/explain_subscriber_test.rb +17 -15
  242. data/test/cases/explain_test.rb +11 -19
  243. data/test/cases/filter_attributes_test.rb +153 -0
  244. data/test/cases/finder_respond_to_test.rb +14 -14
  245. data/test/cases/finder_test.rb +669 -287
  246. data/test/cases/fixture_set/file_test.rb +34 -38
  247. data/test/cases/fixtures_test.rb +833 -176
  248. data/test/cases/forbidden_attributes_protection_test.rb +32 -67
  249. data/test/cases/habtm_destroy_order_test.rb +25 -25
  250. data/test/cases/helper.rb +78 -49
  251. data/test/cases/hot_compatibility_test.rb +33 -32
  252. data/test/cases/i18n_test.rb +18 -17
  253. data/test/cases/inheritance_test.rb +180 -115
  254. data/test/cases/insert_all_test.rb +489 -0
  255. data/test/cases/instrumentation_test.rb +101 -0
  256. data/test/cases/integration_test.rb +119 -31
  257. data/test/cases/invalid_connection_test.rb +18 -16
  258. data/test/cases/invertible_migration_test.rb +183 -43
  259. data/test/cases/json_attribute_test.rb +35 -0
  260. data/test/cases/json_serialization_test.rb +57 -58
  261. data/test/cases/json_shared_test_cases.rb +290 -0
  262. data/test/cases/locking_test.rb +413 -119
  263. data/test/cases/log_subscriber_test.rb +68 -26
  264. data/test/cases/marshal_serialization_test.rb +39 -0
  265. data/test/cases/migration/change_schema_test.rb +118 -72
  266. data/test/cases/migration/change_table_test.rb +138 -30
  267. data/test/cases/migration/check_constraint_test.rb +162 -0
  268. data/test/cases/migration/column_attributes_test.rb +45 -35
  269. data/test/cases/migration/column_positioning_test.rb +18 -6
  270. data/test/cases/migration/columns_test.rb +93 -77
  271. data/test/cases/migration/command_recorder_test.rb +121 -34
  272. data/test/cases/migration/compatibility_test.rb +578 -23
  273. data/test/cases/migration/create_join_table_test.rb +35 -25
  274. data/test/cases/migration/foreign_key_test.rb +503 -284
  275. data/test/cases/migration/helper.rb +4 -3
  276. data/test/cases/migration/index_test.rb +119 -70
  277. data/test/cases/migration/logger_test.rb +9 -6
  278. data/test/cases/migration/pending_migrations_test.rb +88 -34
  279. data/test/cases/migration/references_foreign_key_test.rb +164 -150
  280. data/test/cases/migration/references_index_test.rb +38 -19
  281. data/test/cases/migration/references_statements_test.rb +15 -14
  282. data/test/cases/migration/rename_table_test.rb +53 -30
  283. data/test/cases/migration_test.rb +637 -269
  284. data/test/cases/migrator_test.rb +191 -135
  285. data/test/cases/mixin_test.rb +7 -11
  286. data/test/cases/modules_test.rb +36 -34
  287. data/test/cases/multi_db_migrator_test.rb +223 -0
  288. data/test/cases/multiparameter_attributes_test.rb +60 -33
  289. data/test/cases/multiple_db_test.rb +16 -22
  290. data/test/cases/nested_attributes_test.rb +341 -320
  291. data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
  292. data/test/cases/null_relation_test.rb +84 -0
  293. data/test/cases/numeric_data_test.rb +93 -0
  294. data/test/cases/persistence_test.rb +361 -269
  295. data/test/cases/pooled_connections_test.rb +18 -26
  296. data/test/cases/prepared_statement_status_test.rb +48 -0
  297. data/test/cases/primary_keys_test.rb +210 -104
  298. data/test/cases/query_cache_test.rb +610 -141
  299. data/test/cases/quoting_test.rb +132 -31
  300. data/test/cases/readonly_test.rb +49 -48
  301. data/test/cases/reaper_test.rb +146 -32
  302. data/test/cases/reflection_test.rb +167 -156
  303. data/test/cases/relation/delegation_test.rb +49 -36
  304. data/test/cases/relation/delete_all_test.rb +117 -0
  305. data/test/cases/relation/merging_test.rb +319 -42
  306. data/test/cases/relation/mutation_test.rb +55 -93
  307. data/test/cases/relation/or_test.rb +129 -29
  308. data/test/cases/relation/predicate_builder_test.rb +21 -6
  309. data/test/cases/relation/record_fetch_warning_test.rb +5 -3
  310. data/test/cases/relation/select_test.rb +67 -0
  311. data/test/cases/relation/update_all_test.rb +317 -0
  312. data/test/cases/relation/where_chain_test.rb +68 -32
  313. data/test/cases/relation/where_clause_test.rb +136 -61
  314. data/test/cases/relation/where_test.rb +155 -48
  315. data/test/cases/relation_test.rb +266 -112
  316. data/test/cases/relations_test.rb +969 -744
  317. data/test/cases/reload_models_test.rb +13 -9
  318. data/test/cases/reserved_word_test.rb +141 -0
  319. data/test/cases/result_test.rb +68 -17
  320. data/test/cases/sanitize_test.rb +87 -71
  321. data/test/cases/schema_dumper_test.rb +221 -128
  322. data/test/cases/schema_loading_test.rb +3 -2
  323. data/test/cases/scoping/default_scoping_test.rb +185 -144
  324. data/test/cases/scoping/named_scoping_test.rb +177 -89
  325. data/test/cases/scoping/relation_scoping_test.rb +197 -75
  326. data/test/cases/secure_token_test.rb +18 -3
  327. data/test/cases/serialization_test.rb +30 -28
  328. data/test/cases/serialized_attribute_test.rb +133 -42
  329. data/test/cases/signed_id_test.rb +168 -0
  330. data/test/cases/statement_cache_test.rb +41 -24
  331. data/test/cases/statement_invalid_test.rb +42 -0
  332. data/test/cases/store_test.rb +180 -55
  333. data/test/cases/strict_loading_test.rb +473 -0
  334. data/test/cases/suppressor_test.rb +26 -12
  335. data/test/cases/tasks/database_tasks_test.rb +1258 -194
  336. data/test/cases/tasks/mysql_rake_test.rb +370 -298
  337. data/test/cases/tasks/postgresql_rake_test.rb +481 -251
  338. data/test/cases/tasks/sqlite_rake_test.rb +225 -178
  339. data/test/cases/test_case.rb +51 -40
  340. data/test/cases/test_databases_test.rb +79 -0
  341. data/test/cases/test_fixtures_test.rb +79 -19
  342. data/test/cases/time_precision_test.rb +98 -76
  343. data/test/cases/timestamp_test.rb +102 -99
  344. data/test/cases/touch_later_test.rb +12 -10
  345. data/test/cases/transaction_callbacks_test.rb +344 -90
  346. data/test/cases/transaction_isolation_test.rb +12 -12
  347. data/test/cases/transactions_test.rb +612 -162
  348. data/test/cases/type/adapter_specific_registry_test.rb +14 -2
  349. data/test/cases/type/date_time_test.rb +4 -2
  350. data/test/cases/type/integer_test.rb +4 -2
  351. data/test/cases/type/string_test.rb +10 -8
  352. data/test/cases/type/time_test.rb +28 -0
  353. data/test/cases/type/type_map_test.rb +29 -28
  354. data/test/cases/type/unsigned_integer_test.rb +19 -0
  355. data/test/cases/type_test.rb +2 -0
  356. data/test/cases/types_test.rb +3 -1
  357. data/test/cases/unconnected_test.rb +14 -1
  358. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  359. data/test/cases/validations/absence_validation_test.rb +19 -17
  360. data/test/cases/validations/association_validation_test.rb +30 -28
  361. data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
  362. data/test/cases/validations/i18n_validation_test.rb +22 -21
  363. data/test/cases/validations/length_validation_test.rb +34 -33
  364. data/test/cases/validations/numericality_validation_test.rb +181 -0
  365. data/test/cases/validations/presence_validation_test.rb +21 -19
  366. data/test/cases/validations/uniqueness_validation_test.rb +156 -86
  367. data/test/cases/validations_repair_helper.rb +2 -0
  368. data/test/cases/validations_test.rb +61 -26
  369. data/test/cases/view_test.rb +122 -116
  370. data/test/cases/yaml_serialization_test.rb +79 -34
  371. data/test/config.example.yml +19 -19
  372. data/test/config.rb +3 -1
  373. data/test/config.yml +16 -6
  374. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  375. data/test/fixtures/author_addresses.yml +1 -8
  376. data/test/fixtures/authors.yml +1 -7
  377. data/test/fixtures/binaries.yml +4 -0
  378. data/test/fixtures/books.yml +9 -2
  379. data/test/fixtures/categories_posts.yml +3 -0
  380. data/test/fixtures/citations.yml +5 -0
  381. data/test/fixtures/comments.yml +7 -0
  382. data/test/fixtures/companies.yml +5 -0
  383. data/test/fixtures/computers.yml +2 -0
  384. data/test/fixtures/customers.yml +10 -1
  385. data/test/fixtures/developers.yml +1 -1
  386. data/test/fixtures/essays.yml +10 -0
  387. data/test/fixtures/faces.yml +3 -3
  388. data/test/fixtures/humans.yml +5 -0
  389. data/test/fixtures/interests.yml +7 -7
  390. data/test/fixtures/memberships.yml +7 -0
  391. data/test/fixtures/minimalistics.yml +3 -0
  392. data/test/fixtures/mixed_case_monkeys.yml +2 -2
  393. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  394. data/test/fixtures/naked/yml/parrots.yml +1 -0
  395. data/test/fixtures/other_books.yml +26 -0
  396. data/test/fixtures/other_posts.yml +1 -0
  397. data/test/fixtures/parrots.yml +7 -1
  398. data/test/fixtures/pirates.yml +3 -0
  399. data/test/fixtures/posts.yml +11 -3
  400. data/test/fixtures/readers.yml +6 -0
  401. data/test/fixtures/reserved_words/values.yml +2 -2
  402. data/test/fixtures/sponsors.yml +3 -0
  403. data/test/fixtures/strict_zines.yml +2 -0
  404. data/test/fixtures/subscribers.yml +1 -1
  405. data/test/fixtures/tasks.yml +1 -1
  406. data/test/fixtures/warehouse-things.yml +3 -0
  407. data/test/migrations/10_urban/9_add_expressions.rb +2 -0
  408. data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
  409. data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
  410. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
  411. data/test/migrations/missing/1_people_have_last_names.rb +2 -0
  412. data/test/migrations/missing/3_we_need_reminders.rb +2 -0
  413. data/test/migrations/missing/4_innocent_jointable.rb +3 -1
  414. data/test/migrations/rename/1_we_need_things.rb +2 -0
  415. data/test/migrations/rename/2_rename_things.rb +2 -0
  416. data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
  417. data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
  418. data/test/migrations/to_copy2/1_create_articles.rb +2 -0
  419. data/test/migrations/to_copy2/2_create_comments.rb +3 -1
  420. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
  421. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
  422. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
  423. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
  424. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
  425. data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
  426. data/test/migrations/valid/2_we_need_reminders.rb +2 -0
  427. data/test/migrations/valid/3_innocent_jointable.rb +3 -1
  428. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
  429. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
  430. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
  431. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
  432. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
  433. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
  434. data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
  435. data/test/models/account.rb +46 -0
  436. data/test/models/admin/account.rb +3 -1
  437. data/test/models/admin/randomly_named_c1.rb +2 -0
  438. data/test/models/admin/user.rb +16 -8
  439. data/test/models/admin.rb +4 -2
  440. data/test/models/aircraft.rb +3 -1
  441. data/test/models/arunit2_model.rb +2 -0
  442. data/test/models/author.rb +153 -102
  443. data/test/models/auto_id.rb +2 -0
  444. data/test/models/autoloadable/extra_firm.rb +2 -0
  445. data/test/models/binary.rb +3 -1
  446. data/test/models/binary_field.rb +6 -0
  447. data/test/models/bird.rb +13 -1
  448. data/test/models/book.rb +14 -4
  449. data/test/models/book_destroy_async.rb +24 -0
  450. data/test/models/boolean.rb +5 -0
  451. data/test/models/bulb.rb +13 -4
  452. data/test/models/cake_designer.rb +2 -0
  453. data/test/models/car.rb +17 -10
  454. data/test/models/carrier.rb +2 -0
  455. data/test/models/cart.rb +5 -0
  456. data/test/models/cat.rb +2 -0
  457. data/test/models/categorization.rb +8 -6
  458. data/test/models/category.rb +28 -16
  459. data/test/models/chef.rb +2 -0
  460. data/test/models/citation.rb +5 -1
  461. data/test/models/club.rb +13 -10
  462. data/test/models/college.rb +4 -2
  463. data/test/models/column.rb +2 -0
  464. data/test/models/column_name.rb +2 -0
  465. data/test/models/comment.rb +32 -10
  466. data/test/models/company.rb +102 -106
  467. data/test/models/company_in_module.rb +27 -26
  468. data/test/models/computer.rb +3 -1
  469. data/test/models/contact.rb +15 -13
  470. data/test/models/content.rb +5 -3
  471. data/test/models/contract.rb +21 -3
  472. data/test/models/country.rb +2 -4
  473. data/test/models/course.rb +3 -1
  474. data/test/models/customer.rb +10 -8
  475. data/test/models/customer_carrier.rb +2 -0
  476. data/test/models/dashboard.rb +2 -0
  477. data/test/models/default.rb +2 -0
  478. data/test/models/department.rb +2 -0
  479. data/test/models/destroy_async_parent.rb +15 -0
  480. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  481. data/test/models/developer.rb +152 -85
  482. data/test/models/dl_keyed_belongs_to.rb +13 -0
  483. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  484. data/test/models/dl_keyed_has_many.rb +5 -0
  485. data/test/models/dl_keyed_has_many_through.rb +5 -0
  486. data/test/models/dl_keyed_has_one.rb +5 -0
  487. data/test/models/dl_keyed_join.rb +10 -0
  488. data/test/models/dog.rb +2 -0
  489. data/test/models/dog_lover.rb +2 -0
  490. data/test/models/doubloon.rb +3 -1
  491. data/test/models/drink_designer.rb +17 -0
  492. data/test/models/edge.rb +4 -2
  493. data/test/models/electron.rb +2 -0
  494. data/test/models/engine.rb +3 -2
  495. data/test/models/entrant.rb +2 -0
  496. data/test/models/entry.rb +5 -0
  497. data/test/models/essay.rb +6 -3
  498. data/test/models/essay_destroy_async.rb +12 -0
  499. data/test/models/event.rb +3 -1
  500. data/test/models/eye.rb +5 -3
  501. data/test/models/face.rb +14 -6
  502. data/test/models/family.rb +6 -0
  503. data/test/models/family_tree.rb +6 -0
  504. data/test/models/friendship.rb +5 -3
  505. data/test/models/frog.rb +8 -0
  506. data/test/models/guid.rb +3 -1
  507. data/test/models/guitar.rb +2 -0
  508. data/test/models/hotel.rb +5 -3
  509. data/test/models/human.rb +39 -0
  510. data/test/models/image.rb +3 -1
  511. data/test/models/interest.rb +14 -3
  512. data/test/models/invoice.rb +4 -2
  513. data/test/models/item.rb +3 -1
  514. data/test/models/job.rb +5 -3
  515. data/test/models/joke.rb +4 -2
  516. data/test/models/keyboard.rb +3 -1
  517. data/test/models/legacy_thing.rb +2 -0
  518. data/test/models/lesson.rb +2 -0
  519. data/test/models/line_item.rb +3 -1
  520. data/test/models/liquid.rb +2 -0
  521. data/test/models/matey.rb +3 -1
  522. data/test/models/measurement.rb +4 -0
  523. data/test/models/member.rb +23 -20
  524. data/test/models/member_detail.rb +3 -0
  525. data/test/models/member_type.rb +2 -0
  526. data/test/models/membership.rb +4 -1
  527. data/test/models/mentor.rb +3 -1
  528. data/test/models/message.rb +5 -0
  529. data/test/models/minimalistic.rb +2 -0
  530. data/test/models/minivan.rb +3 -2
  531. data/test/models/mixed_case_monkey.rb +3 -1
  532. data/test/models/molecule.rb +2 -0
  533. data/test/models/mouse.rb +6 -0
  534. data/test/models/movie.rb +2 -0
  535. data/test/models/node.rb +4 -2
  536. data/test/models/non_primary_key.rb +2 -0
  537. data/test/models/notification.rb +2 -0
  538. data/test/models/numeric_data.rb +12 -0
  539. data/test/models/order.rb +4 -2
  540. data/test/models/organization.rb +9 -7
  541. data/test/models/other_dog.rb +3 -1
  542. data/test/models/owner.rb +6 -4
  543. data/test/models/parrot.rb +12 -4
  544. data/test/models/person.rb +59 -54
  545. data/test/models/personal_legacy_thing.rb +3 -1
  546. data/test/models/pet.rb +4 -2
  547. data/test/models/pet_treasure.rb +2 -0
  548. data/test/models/pirate.rb +67 -43
  549. data/test/models/possession.rb +3 -1
  550. data/test/models/post.rb +184 -86
  551. data/test/models/price_estimate.rb +11 -1
  552. data/test/models/professor.rb +3 -1
  553. data/test/models/project.rb +14 -12
  554. data/test/models/publisher/article.rb +2 -0
  555. data/test/models/publisher/magazine.rb +2 -0
  556. data/test/models/publisher.rb +2 -0
  557. data/test/models/randomly_named_c1.rb +2 -0
  558. data/test/models/rating.rb +5 -1
  559. data/test/models/reader.rb +7 -5
  560. data/test/models/recipe.rb +2 -0
  561. data/test/models/record.rb +2 -0
  562. data/test/models/reference.rb +6 -3
  563. data/test/models/reply.rb +39 -21
  564. data/test/models/room.rb +6 -0
  565. data/test/models/section.rb +6 -0
  566. data/test/models/seminar.rb +6 -0
  567. data/test/models/session.rb +6 -0
  568. data/test/models/ship.rb +12 -9
  569. data/test/models/ship_part.rb +5 -3
  570. data/test/models/shop.rb +4 -2
  571. data/test/models/shop_account.rb +2 -0
  572. data/test/models/speedometer.rb +2 -0
  573. data/test/models/sponsor.rb +8 -5
  574. data/test/models/squeak.rb +6 -0
  575. data/test/models/strict_zine.rb +7 -0
  576. data/test/models/string_key_object.rb +2 -0
  577. data/test/models/student.rb +2 -0
  578. data/test/models/subscriber.rb +4 -2
  579. data/test/models/subscription.rb +5 -1
  580. data/test/models/tag.rb +6 -3
  581. data/test/models/tagging.rb +13 -6
  582. data/test/models/task.rb +2 -0
  583. data/test/models/topic.rb +54 -19
  584. data/test/models/toy.rb +4 -0
  585. data/test/models/traffic_light.rb +2 -0
  586. data/test/models/treasure.rb +5 -3
  587. data/test/models/treaty.rb +2 -4
  588. data/test/models/tree.rb +2 -0
  589. data/test/models/tuning_peg.rb +2 -0
  590. data/test/models/tyre.rb +2 -0
  591. data/test/models/user.rb +12 -4
  592. data/test/models/uuid_child.rb +2 -0
  593. data/test/models/uuid_item.rb +2 -0
  594. data/test/models/uuid_parent.rb +2 -0
  595. data/test/models/vegetables.rb +12 -3
  596. data/test/models/vertex.rb +6 -4
  597. data/test/models/warehouse_thing.rb +2 -0
  598. data/test/models/wheel.rb +3 -1
  599. data/test/models/without_table.rb +3 -1
  600. data/test/models/zine.rb +3 -1
  601. data/test/schema/mysql2_specific_schema.rb +49 -35
  602. data/test/schema/oracle_specific_schema.rb +13 -15
  603. data/test/schema/postgresql_specific_schema.rb +51 -40
  604. data/test/schema/schema.rb +334 -154
  605. data/test/schema/sqlite_specific_schema.rb +9 -16
  606. data/test/support/config.rb +26 -26
  607. data/test/support/connection.rb +14 -8
  608. data/test/support/connection_helper.rb +3 -1
  609. data/test/support/ddl_helper.rb +2 -0
  610. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  611. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  612. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  613. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  614. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  615. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  616. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  617. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  618. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  619. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  620. data/test/support/schema_dumping_helper.rb +2 -0
  621. data/test/support/stubs/strong_parameters.rb +40 -0
  622. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  623. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  624. metadata +196 -11
@@ -1,362 +1,581 @@
1
- require 'cases/helper'
2
- require 'support/ddl_helper'
3
- require 'support/schema_dumping_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "support/schema_dumping_helper"
4
5
 
5
6
  if ActiveRecord::Base.connection.supports_foreign_keys?
6
- module ActiveRecord
7
- class Migration
8
- class ForeignKeyTest < ActiveRecord::TestCase
9
- include DdlHelper
10
- include SchemaDumpingHelper
11
- include ActiveSupport::Testing::Stream
12
-
13
- class Rocket < ActiveRecord::Base
7
+ module ActiveRecord
8
+ class Migration
9
+ class ForeignKeyInCreateTest < ActiveRecord::TestCase
10
+ def test_foreign_keys
11
+ foreign_keys = ActiveRecord::Base.connection.foreign_keys("fk_test_has_fk")
12
+ assert_equal 1, foreign_keys.size
13
+
14
+ fk = foreign_keys.first
15
+ assert_equal "fk_test_has_fk", fk.from_table
16
+ assert_equal "fk_test_has_pk", fk.to_table
17
+ assert_equal "fk_id", fk.column
18
+ assert_equal "pk_id", fk.primary_key
19
+ assert_equal "fk_name", fk.name unless current_adapter?(:SQLite3Adapter)
20
+ end
14
21
  end
15
22
 
16
- class Astronaut < ActiveRecord::Base
17
- end
23
+ class ForeignKeyChangeColumnTest < ActiveRecord::TestCase
24
+ self.use_transactional_tests = false
18
25
 
19
- setup do
20
- @connection = ActiveRecord::Base.connection
21
- @connection.create_table "rockets", force: true do |t|
22
- t.string :name
26
+ class Rocket < ActiveRecord::Base
27
+ has_many :astronauts
23
28
  end
24
29
 
25
- @connection.create_table "astronauts", force: true do |t|
26
- t.string :name
27
- t.references :rocket
30
+ class Astronaut < ActiveRecord::Base
31
+ belongs_to :rocket
28
32
  end
29
- end
30
33
 
31
- teardown do
32
- if defined?(@connection)
33
- @connection.drop_table "astronauts"
34
- #, if_exists: true
35
- @connection.drop_table "rockets"
36
- #, if_exists: true
34
+ class CreateRocketsMigration < ActiveRecord::Migration::Current
35
+ def change
36
+ create_table :rockets do |t|
37
+ t.string :name
38
+ end
39
+
40
+ create_table :astronauts do |t|
41
+ t.string :name
42
+ t.references :rocket, foreign_key: true
43
+ end
44
+ end
37
45
  end
38
- end
39
46
 
40
- def test_foreign_keys
41
- foreign_keys = @connection.foreign_keys("fk_test_has_fk")
42
- assert_equal 1, foreign_keys.size
43
-
44
- fk = foreign_keys.first
45
- if current_adapter?(:IBM_DBAdapter)
46
- assert_equal "fk_test_has_fk".upcase, fk.from_table.upcase
47
- assert_equal "fk_test_has_pk".upcase, fk.to_table.upcase
48
- assert_equal "fk_id".upcase, fk.column.upcase
49
- assert_equal "pk_id".upcase, fk.primary_key.upcase
50
- assert_equal "fk_name".upcase, fk.name.upcase
51
- else
52
- assert_equal "fk_test_has_fk", fk.from_table
53
- assert_equal "fk_test_has_pk", fk.to_table
54
- assert_equal "fk_id", fk.column
55
- assert_equal "pk_id", fk.primary_key
56
- assert_equal "fk_name", fk.name
57
- end
58
- end
47
+ def setup
48
+ @connection = ActiveRecord::Base.connection
49
+ @migration = CreateRocketsMigration.new
50
+ silence_stream($stdout) { @migration.migrate(:up) }
51
+ Rocket.reset_table_name
52
+ Rocket.reset_column_information
53
+ Astronaut.reset_table_name
54
+ Astronaut.reset_column_information
55
+ end
59
56
 
60
- def test_add_foreign_key_inferes_column
61
- @connection.add_foreign_key :astronauts, :rockets
62
-
63
- foreign_keys = @connection.foreign_keys("astronauts")
64
- assert_equal 1, foreign_keys.size
65
-
66
- fk = foreign_keys.first
67
-
68
- if current_adapter?(:IBM_DBAdapter)
69
- assert_equal "astronauts".upcase, fk.from_table.upcase
70
- else
71
- assert_equal "astronauts", fk.from_table
72
- end
73
-
74
- if current_adapter?(:IBM_DBAdapter)
75
- assert_equal "rockets".upcase, fk.to_table.upcase
76
- assert_equal "rocket_id".upcase, fk.column.upcase
77
- assert_equal "id".upcase, fk.primary_key.upcase
78
- assert_equal("fk_rails_78146ddd2e".upcase, fk.name.upcase)
79
- else
80
- assert_equal "rockets", fk.to_table
81
- assert_equal "rocket_id", fk.column
82
- assert_equal "id", fk.primary_key
83
- assert_equal("fk_rails_78146ddd2e", fk.name)
84
- end
85
-
86
- end
57
+ def teardown
58
+ silence_stream($stdout) { @migration.migrate(:down) }
59
+ Rocket.reset_table_name
60
+ Rocket.reset_column_information
61
+ Astronaut.reset_table_name
62
+ Astronaut.reset_column_information
63
+ end
87
64
 
88
- def test_add_foreign_key_with_column
89
- @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
90
-
91
- foreign_keys = @connection.foreign_keys("astronauts")
92
- assert_equal 1, foreign_keys.size
93
-
94
- fk = foreign_keys.first
95
- if current_adapter?(:IBM_DBAdapter)
96
- assert_equal "astronauts".upcase, fk.from_table.upcase
97
- assert_equal "rockets".upcase, fk.to_table.upcase
98
- assert_equal "rocket_id".upcase, fk.column.upcase
99
- assert_equal "id".upcase, fk.primary_key.upcase
100
- assert_equal("fk_rails_78146ddd2e".upcase, fk.name.upcase)
101
- else
102
- assert_equal "astronauts", fk.from_table
103
- assert_equal "rockets", fk.to_table
104
- assert_equal "rocket_id", fk.column
105
- assert_equal "id", fk.primary_key
106
- assert_equal("fk_rails_78146ddd2e", fk.name)
107
- end
108
-
109
- end
65
+ def test_change_column_of_parent_table
66
+ rocket = Rocket.create!(name: "myrocket")
67
+ rocket.astronauts << Astronaut.create!
68
+
69
+ @connection.change_column_null Rocket.table_name, :name, false
70
+
71
+ foreign_keys = @connection.foreign_keys(Astronaut.table_name)
72
+ assert_equal 1, foreign_keys.size
110
73
 
111
- def test_add_foreign_key_with_non_standard_primary_key
112
- if current_adapter?(:IBM_DBAdapter)
113
- @connection.create_table :space_shuttles, force: true, id: false do |t|
114
- t.primary_key :pk
115
- end
116
- @connection.add_foreign_key(:astronauts, :space_shuttles,
117
- column: "rocket_id", primary_key: "pk", name: "custom_pk")
118
- foreign_keys = @connection.foreign_keys("astronauts")
119
- assert_equal 1, foreign_keys.size
120
- fk = foreign_keys.first
121
- assert_equal "astronauts".upcase, fk.from_table.upcase
122
- assert_equal "space_shuttles".upcase, fk.to_table.upcase
123
- assert_equal "pk".upcase, fk.primary_key.upcase
124
- @connection.remove_foreign_key :astronauts, name: "custom_pk"
125
- else
126
- with_example_table @connection, "space_shuttles", "pk integer PRIMARY KEY" do
127
- @connection.add_foreign_key(:astronauts, :space_shuttles,
128
- column: "rocket_id", primary_key: "pk", name: "custom_pk")
129
- foreign_keys = @connection.foreign_keys("astronauts")
130
- assert_equal 1, foreign_keys.size
131
- fk = foreign_keys.first
132
- assert_equal "astronauts", fk.from_table
133
- assert_equal "space_shuttles", fk.to_table
134
- assert_equal "pk", fk.primary_key
135
- @connection.remove_foreign_key :astronauts, name: "custom_pk"
136
- end
74
+ fk = foreign_keys.first
75
+ assert_equal "myrocket", Rocket.first.name
76
+ assert_equal Astronaut.table_name, fk.from_table
77
+ assert_equal Rocket.table_name, fk.to_table
137
78
  end
138
- end
139
79
 
140
- def test_add_on_delete_restrict_foreign_key
141
- @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :restrict
80
+ def test_rename_column_of_child_table
81
+ rocket = Rocket.create!(name: "myrocket")
82
+ rocket.astronauts << Astronaut.create!
142
83
 
143
- foreign_keys = @connection.foreign_keys("astronauts")
144
- assert_equal 1, foreign_keys.size
84
+ @connection.rename_column Astronaut.table_name, :name, :astronaut_name
145
85
 
146
- fk = foreign_keys.first
147
- if current_adapter?(:Mysql2Adapter)
148
- # ON DELETE RESTRICT is the default on MySQL
149
- assert_equal nil, fk.on_delete
150
- else
151
- assert_equal :restrict, fk.on_delete
86
+ foreign_keys = @connection.foreign_keys(Astronaut.table_name)
87
+ assert_equal 1, foreign_keys.size
88
+
89
+ fk = foreign_keys.first
90
+ assert_equal "myrocket", Rocket.first.name
91
+ assert_equal Astronaut.table_name, fk.from_table
92
+ assert_equal Rocket.table_name, fk.to_table
152
93
  end
153
- end
154
94
 
155
- def test_add_on_delete_cascade_foreign_key
156
- @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :cascade
95
+ def test_rename_reference_column_of_child_table
96
+ if current_adapter?(:Mysql2Adapter) && !@connection.send(:supports_rename_index?)
97
+ skip "Cannot drop index, needed in a foreign key constraint"
98
+ end
157
99
 
158
- foreign_keys = @connection.foreign_keys("astronauts")
159
- assert_equal 1, foreign_keys.size
100
+ rocket = Rocket.create!(name: "myrocket")
101
+ rocket.astronauts << Astronaut.create!
160
102
 
161
- fk = foreign_keys.first
162
- assert_equal :cascade, fk.on_delete
163
- end
103
+ @connection.rename_column Astronaut.table_name, :rocket_id, :new_rocket_id
164
104
 
165
- def test_add_on_delete_nullify_foreign_key
166
- @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :nullify
105
+ foreign_keys = @connection.foreign_keys(Astronaut.table_name)
106
+ assert_equal 1, foreign_keys.size
167
107
 
168
- foreign_keys = @connection.foreign_keys("astronauts")
169
- assert_equal 1, foreign_keys.size
108
+ fk = foreign_keys.first
109
+ assert_equal "myrocket", Rocket.first.name
110
+ assert_equal Astronaut.table_name, fk.from_table
111
+ assert_equal Rocket.table_name, fk.to_table
112
+ assert_equal "new_rocket_id", fk.options[:column]
113
+ end
170
114
 
171
- fk = foreign_keys.first
172
- assert_equal :nullify, fk.on_delete
173
- end
115
+ def test_remove_reference_column_of_child_table
116
+ rocket = Rocket.create!(name: "myrocket")
117
+ rocket.astronauts << Astronaut.create!
174
118
 
175
- def test_on_update_and_on_delete_raises_with_invalid_values
176
- assert_raises ArgumentError do
177
- @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :invalid
119
+ @connection.remove_column Astronaut.table_name, :rocket_id
120
+
121
+ assert_empty @connection.foreign_keys(Astronaut.table_name)
178
122
  end
179
123
 
180
- assert_raises ArgumentError do
181
- @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_update: :invalid
124
+ def test_remove_foreign_key_by_column
125
+ rocket = Rocket.create!(name: "myrocket")
126
+ rocket.astronauts << Astronaut.create!
127
+
128
+ @connection.remove_foreign_key Astronaut.table_name, column: :rocket_id
129
+
130
+ assert_empty @connection.foreign_keys(Astronaut.table_name)
182
131
  end
183
- end
184
132
 
185
- def test_add_foreign_key_with_on_update
186
- @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_update: :nullify
133
+ def test_remove_foreign_key_by_column_in_change_table
134
+ rocket = Rocket.create!(name: "myrocket")
135
+ rocket.astronauts << Astronaut.create!
187
136
 
188
- foreign_keys = @connection.foreign_keys("astronauts")
189
- assert_equal 1, foreign_keys.size
137
+ @connection.change_table Astronaut.table_name do |t|
138
+ t.remove_foreign_key column: :rocket_id
139
+ end
190
140
 
191
- fk = foreign_keys.first
192
- assert_equal :nullify, fk.on_update
141
+ assert_empty @connection.foreign_keys(Astronaut.table_name)
142
+ end
193
143
  end
194
144
 
195
- def test_foreign_key_exists
196
- @connection.add_foreign_key :astronauts, :rockets
145
+ class ForeignKeyChangeColumnWithPrefixTest < ForeignKeyChangeColumnTest
146
+ setup do
147
+ ActiveRecord::Base.table_name_prefix = "p_"
148
+ end
197
149
 
198
- assert @connection.foreign_key_exists?(:astronauts, :rockets)
199
- assert_not @connection.foreign_key_exists?(:astronauts, :stars)
150
+ teardown do
151
+ ActiveRecord::Base.table_name_prefix = nil
152
+ end
200
153
  end
201
154
 
202
- def test_foreign_key_exists_by_column
203
- @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
155
+ class ForeignKeyChangeColumnWithSuffixTest < ForeignKeyChangeColumnTest
156
+ setup do
157
+ ActiveRecord::Base.table_name_suffix = "_s"
158
+ end
204
159
 
205
- assert @connection.foreign_key_exists?(:astronauts, column: "rocket_id")
206
- assert_not @connection.foreign_key_exists?(:astronauts, column: "star_id")
160
+ teardown do
161
+ ActiveRecord::Base.table_name_suffix = nil
162
+ end
207
163
  end
164
+ end
165
+ end
208
166
 
209
- def test_foreign_key_exists_by_name
210
- @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk"
167
+ module ActiveRecord
168
+ class Migration
169
+ class ForeignKeyTest < ActiveRecord::TestCase
170
+ include SchemaDumpingHelper
171
+ include ActiveSupport::Testing::Stream
211
172
 
212
- assert @connection.foreign_key_exists?(:astronauts, name: "fancy_named_fk")
213
- assert_not @connection.foreign_key_exists?(:astronauts, name: "other_fancy_named_fk")
214
- end
173
+ class Rocket < ActiveRecord::Base
174
+ end
215
175
 
216
- def test_remove_foreign_key_inferes_column
217
- @connection.add_foreign_key :astronauts, :rockets
176
+ class Astronaut < ActiveRecord::Base
177
+ end
218
178
 
219
- assert_equal 1, @connection.foreign_keys("astronauts").size
220
- @connection.remove_foreign_key :astronauts, :rockets
221
- assert_equal [], @connection.foreign_keys("astronauts")
222
- end
179
+ setup do
180
+ @connection = ActiveRecord::Base.connection
181
+ @connection.create_table "rockets", force: true do |t|
182
+ t.string :name
183
+ end
223
184
 
224
- def test_remove_foreign_key_by_column
225
- @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
185
+ @connection.create_table "astronauts", force: true do |t|
186
+ t.string :name
187
+ t.references :rocket
188
+ end
189
+ end
226
190
 
227
- assert_equal 1, @connection.foreign_keys("astronauts").size
228
- @connection.remove_foreign_key :astronauts, column: "rocket_id"
229
- assert_equal [], @connection.foreign_keys("astronauts")
230
- end
191
+ teardown do
192
+ @connection.drop_table "astronauts", if_exists: true rescue nil
193
+ @connection.drop_table "rockets", if_exists: true rescue nil
194
+ end
231
195
 
232
- def test_remove_foreign_key_by_symbol_column
233
- @connection.add_foreign_key :astronauts, :rockets, column: :rocket_id
196
+ def test_foreign_keys
197
+ foreign_keys = @connection.foreign_keys("fk_test_has_fk")
198
+ assert_equal 1, foreign_keys.size
234
199
 
235
- assert_equal 1, @connection.foreign_keys("astronauts").size
236
- @connection.remove_foreign_key :astronauts, column: :rocket_id
237
- assert_equal [], @connection.foreign_keys("astronauts")
238
- end
200
+ fk = foreign_keys.first
201
+ assert_equal "fk_test_has_fk", fk.from_table
202
+ assert_equal "fk_test_has_pk", fk.to_table
203
+ assert_equal "fk_id", fk.column
204
+ assert_equal "pk_id", fk.primary_key
205
+ assert_equal "fk_name", fk.name unless current_adapter?(:SQLite3Adapter)
206
+ end
239
207
 
240
- def test_remove_foreign_key_by_name
241
- @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk"
208
+ def test_add_foreign_key_inferes_column
209
+ @connection.add_foreign_key :astronauts, :rockets
242
210
 
243
- assert_equal 1, @connection.foreign_keys("astronauts").size
244
- @connection.remove_foreign_key :astronauts, name: "fancy_named_fk"
245
- assert_equal [], @connection.foreign_keys("astronauts")
246
- end
211
+ foreign_keys = @connection.foreign_keys("astronauts")
212
+ assert_equal 1, foreign_keys.size
213
+
214
+ fk = foreign_keys.first
215
+ assert_equal "astronauts", fk.from_table
216
+ assert_equal "rockets", fk.to_table
217
+ assert_equal "rocket_id", fk.column
218
+ assert_equal "id", fk.primary_key
219
+ assert_equal "fk_rails_78146ddd2e", fk.name unless current_adapter?(:SQLite3Adapter)
220
+ end
221
+
222
+ def test_add_foreign_key_with_column
223
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
224
+
225
+ foreign_keys = @connection.foreign_keys("astronauts")
226
+ assert_equal 1, foreign_keys.size
227
+
228
+ fk = foreign_keys.first
229
+ assert_equal "astronauts", fk.from_table
230
+ assert_equal "rockets", fk.to_table
231
+ assert_equal "rocket_id", fk.column
232
+ assert_equal "id", fk.primary_key
233
+ assert_equal "fk_rails_78146ddd2e", fk.name unless current_adapter?(:SQLite3Adapter)
234
+ end
235
+
236
+ def test_add_foreign_key_with_non_standard_primary_key
237
+ @connection.create_table :space_shuttles, id: false, force: true do |t|
238
+ t.bigint :pk, primary_key: true
239
+ end
240
+
241
+ @connection.add_foreign_key(:astronauts, :space_shuttles,
242
+ column: "rocket_id", primary_key: "pk", name: "custom_pk")
243
+
244
+ foreign_keys = @connection.foreign_keys("astronauts")
245
+ assert_equal 1, foreign_keys.size
246
+
247
+ fk = foreign_keys.first
248
+ assert_equal "astronauts", fk.from_table
249
+ assert_equal "space_shuttles", fk.to_table
250
+ assert_equal "pk", fk.primary_key
251
+ ensure
252
+ @connection.remove_foreign_key :astronauts, name: "custom_pk", to_table: "space_shuttles"
253
+ @connection.drop_table :space_shuttles
254
+ end
255
+
256
+ def test_add_on_delete_restrict_foreign_key
257
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :restrict
258
+
259
+ foreign_keys = @connection.foreign_keys("astronauts")
260
+ assert_equal 1, foreign_keys.size
261
+
262
+ fk = foreign_keys.first
263
+ if current_adapter?(:Mysql2Adapter)
264
+ # ON DELETE RESTRICT is the default on MySQL
265
+ assert_nil fk.on_delete
266
+ else
267
+ assert_equal :restrict, fk.on_delete
268
+ end
269
+ end
270
+
271
+ def test_add_on_delete_cascade_foreign_key
272
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :cascade
273
+
274
+ foreign_keys = @connection.foreign_keys("astronauts")
275
+ assert_equal 1, foreign_keys.size
276
+
277
+ fk = foreign_keys.first
278
+ assert_equal :cascade, fk.on_delete
279
+ end
280
+
281
+ def test_add_on_delete_nullify_foreign_key
282
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :nullify
283
+
284
+ foreign_keys = @connection.foreign_keys("astronauts")
285
+ assert_equal 1, foreign_keys.size
286
+
287
+ fk = foreign_keys.first
288
+ assert_equal :nullify, fk.on_delete
289
+ end
290
+
291
+ def test_on_update_and_on_delete_raises_with_invalid_values
292
+ assert_raises ArgumentError do
293
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :invalid
294
+ end
295
+
296
+ assert_raises ArgumentError do
297
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_update: :invalid
298
+ end
299
+ end
300
+
301
+ def test_add_foreign_key_with_on_update
302
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_update: :nullify
303
+
304
+ foreign_keys = @connection.foreign_keys("astronauts")
305
+ assert_equal 1, foreign_keys.size
306
+
307
+ fk = foreign_keys.first
308
+ assert_equal :nullify, fk.on_update
309
+ end
310
+
311
+ def test_add_foreign_key_with_non_existent_from_table_raises
312
+ e = assert_raises ArgumentError do
313
+ @connection.add_foreign_key :missions, :rockets
314
+ end
315
+ assert_match(/missions/i, e.message)
316
+ end
317
+
318
+ def test_add_foreign_key_with_non_existent_to_table_raises
319
+ e = assert_raises ArgumentError do
320
+ @connection.add_foreign_key :missions, :rockets
321
+ end
322
+ assert_match(/missions/i, e.message)
323
+ end
324
+
325
+ def test_foreign_key_exists
326
+ @connection.add_foreign_key :astronauts, :rockets
327
+
328
+ assert @connection.foreign_key_exists?(:astronauts, :rockets)
329
+ assert_not @connection.foreign_key_exists?(:astronauts, :stars)
330
+ end
331
+
332
+ def test_foreign_key_exists_by_column
333
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
334
+
335
+ assert @connection.foreign_key_exists?(:astronauts, column: "rocket_id")
336
+ assert_not @connection.foreign_key_exists?(:astronauts, column: "star_id")
337
+ end
338
+
339
+ def test_foreign_key_exists_by_name
340
+ skip if current_adapter?(:SQLite3Adapter)
341
+
342
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk"
343
+
344
+ assert @connection.foreign_key_exists?(:astronauts, name: "fancy_named_fk")
345
+ assert_not @connection.foreign_key_exists?(:astronauts, name: "other_fancy_named_fk")
346
+ end
247
347
 
248
- def test_remove_foreign_non_existing_foreign_key_raises
249
- assert_raises ArgumentError do
348
+ def test_foreign_key_exists_in_change_table
349
+ @connection.change_table(:astronauts) do |t|
350
+ t.foreign_key :rockets, column: "rocket_id", name: "fancy_named_fk"
351
+
352
+ assert t.foreign_key_exists?(column: "rocket_id")
353
+ assert_not t.foreign_key_exists?(column: "star_id")
354
+
355
+ unless current_adapter?(:SQLite3Adapter)
356
+ assert t.foreign_key_exists?(name: "fancy_named_fk")
357
+ assert_not t.foreign_key_exists?(name: "other_fancy_named_fk")
358
+ end
359
+ end
360
+ end
361
+
362
+ def test_remove_foreign_key_inferes_column
363
+ @connection.add_foreign_key :astronauts, :rockets
364
+
365
+ assert_equal 1, @connection.foreign_keys("astronauts").size
250
366
  @connection.remove_foreign_key :astronauts, :rockets
367
+ assert_equal [], @connection.foreign_keys("astronauts")
251
368
  end
252
- end
253
369
 
254
- def test_schema_dumping
255
- @connection.add_foreign_key :astronauts, :rockets
256
- output = dump_table_schema "astronauts"
257
- assert_match %r{\s+add_foreign_key "astronauts", "rockets"$}, output
258
- end
370
+ def test_remove_foreign_key_by_column
371
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
259
372
 
260
- def test_schema_dumping_with_options
261
- output = dump_table_schema "fk_test_has_fk"
262
- assert_match %r{\s+add_foreign_key "fk_test_has_fk", "fk_test_has_pk", column: "fk_id", primary_key: "pk_id", name: "fk_name"$}, output
263
- end
373
+ assert_equal 1, @connection.foreign_keys("astronauts").size
374
+ @connection.remove_foreign_key :astronauts, column: "rocket_id"
375
+ assert_equal [], @connection.foreign_keys("astronauts")
376
+ end
264
377
 
265
- def test_schema_dumping_on_delete_and_on_update_options
266
- @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :nullify, on_update: :cascade
378
+ def test_remove_foreign_key_by_symbol_column
379
+ @connection.add_foreign_key :astronauts, :rockets, column: :rocket_id
267
380
 
268
- output = dump_table_schema "astronauts"
269
- assert_match %r{\s+add_foreign_key "astronauts",.+on_update: :cascade,.+on_delete: :nullify$}, output
270
- end
381
+ assert_equal 1, @connection.foreign_keys("astronauts").size
382
+ @connection.remove_foreign_key :astronauts, column: :rocket_id
383
+ assert_equal [], @connection.foreign_keys("astronauts")
384
+ end
385
+
386
+ def test_remove_foreign_key_by_name
387
+ skip if current_adapter?(:SQLite3Adapter)
388
+
389
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk"
271
390
 
272
- class CreateCitiesAndHousesMigration < ActiveRecord::Migration::Current
273
- def change
274
- create_table("cities") { |t| }
391
+ assert_equal 1, @connection.foreign_keys("astronauts").size
392
+ @connection.remove_foreign_key :astronauts, name: "fancy_named_fk"
393
+ assert_equal [], @connection.foreign_keys("astronauts")
394
+ end
275
395
 
276
- create_table("houses") do |t|
277
- t.column :city_id, :integer
396
+ def test_remove_foreign_non_existing_foreign_key_raises
397
+ e = assert_raises ArgumentError do
398
+ @connection.remove_foreign_key :astronauts, :rockets
278
399
  end
279
- add_foreign_key :houses, :cities, column: "city_id"
400
+ assert_equal "Table 'astronauts' has no foreign key for rockets", e.message
401
+ end
402
+
403
+ def test_remove_foreign_key_by_the_select_one_on_the_same_table
404
+ @connection.add_foreign_key :astronauts, :rockets
405
+ @connection.add_reference :astronauts, :myrocket, foreign_key: { to_table: :rockets }
280
406
 
281
- # remove and re-add to test that schema is updated and not accidently cached
282
- remove_foreign_key :houses, :cities
283
- add_foreign_key :houses, :cities, column: "city_id", on_delete: :cascade
407
+ assert_equal 2, @connection.foreign_keys("astronauts").size
408
+
409
+ @connection.remove_foreign_key :astronauts, :rockets, column: "myrocket_id"
410
+
411
+ assert_equal [["astronauts", "rockets", "rocket_id"]],
412
+ @connection.foreign_keys("astronauts").map { |fk| [fk.from_table, fk.to_table, fk.column] }
284
413
  end
285
- end
286
414
 
287
- def test_add_foreign_key_is_reversible
288
- migration = CreateCitiesAndHousesMigration.new
289
- silence_stream($stdout) { migration.migrate(:up) }
290
- assert_equal 1, @connection.foreign_keys("houses").size
291
- ensure
292
- silence_stream($stdout) { migration.migrate(:down) }
293
- end
415
+ if ActiveRecord::Base.connection.supports_validate_constraints?
416
+ def test_add_invalid_foreign_key
417
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", validate: false
294
418
 
295
- def test_foreign_key_constraint_is_not_cached_incorrectly
296
- migration = CreateCitiesAndHousesMigration.new
297
- silence_stream($stdout) { migration.migrate(:up) }
298
- output = dump_table_schema "houses"
299
- assert_match %r{\s+add_foreign_key "houses",.+on_delete: :cascade$}, output
300
- ensure
301
- silence_stream($stdout) { migration.migrate(:down) }
302
- end
419
+ foreign_keys = @connection.foreign_keys("astronauts")
420
+ assert_equal 1, foreign_keys.size
303
421
 
304
- class CreateSchoolsAndClassesMigration < ActiveRecord::Migration::Current
305
- def change
306
- create_table(:schools)
422
+ fk = foreign_keys.first
423
+ assert_not_predicate fk, :validated?
424
+ end
425
+
426
+ def test_validate_foreign_key_infers_column
427
+ @connection.add_foreign_key :astronauts, :rockets, validate: false
428
+ assert_not_predicate @connection.foreign_keys("astronauts").first, :validated?
429
+
430
+ @connection.validate_foreign_key :astronauts, :rockets
431
+ assert_predicate @connection.foreign_keys("astronauts").first, :validated?
432
+ end
433
+
434
+ def test_validate_foreign_key_by_column
435
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", validate: false
436
+ assert_not_predicate @connection.foreign_keys("astronauts").first, :validated?
307
437
 
308
- create_table(:classes) do |t|
309
- t.column :school_id, :integer
438
+ @connection.validate_foreign_key :astronauts, column: "rocket_id"
439
+ assert_predicate @connection.foreign_keys("astronauts").first, :validated?
440
+ end
441
+
442
+ def test_validate_foreign_key_by_symbol_column
443
+ @connection.add_foreign_key :astronauts, :rockets, column: :rocket_id, validate: false
444
+ assert_not_predicate @connection.foreign_keys("astronauts").first, :validated?
445
+
446
+ @connection.validate_foreign_key :astronauts, column: :rocket_id
447
+ assert_predicate @connection.foreign_keys("astronauts").first, :validated?
448
+ end
449
+
450
+ def test_validate_foreign_key_by_name
451
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk", validate: false
452
+ assert_not_predicate @connection.foreign_keys("astronauts").first, :validated?
453
+
454
+ @connection.validate_foreign_key :astronauts, name: "fancy_named_fk"
455
+ assert_predicate @connection.foreign_keys("astronauts").first, :validated?
456
+ end
457
+
458
+ def test_validate_foreign_non_existing_foreign_key_raises
459
+ assert_raises ArgumentError do
460
+ @connection.validate_foreign_key :astronauts, :rockets
461
+ end
462
+ end
463
+
464
+ def test_validate_constraint_by_name
465
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk", validate: false
466
+
467
+ @connection.validate_constraint :astronauts, "fancy_named_fk"
468
+ assert_predicate @connection.foreign_keys("astronauts").first, :validated?
469
+ end
470
+ else
471
+ # Foreign key should still be created, but should not be invalid
472
+ def test_add_invalid_foreign_key
473
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", validate: false
474
+
475
+ foreign_keys = @connection.foreign_keys("astronauts")
476
+ assert_equal 1, foreign_keys.size
477
+
478
+ fk = foreign_keys.first
479
+ assert_predicate fk, :validated?
310
480
  end
311
- add_foreign_key :classes, :schools
312
481
  end
313
- end
314
482
 
315
- def test_add_foreign_key_with_prefix
316
- ActiveRecord::Base.table_name_prefix = 'p_'
317
- migration = CreateSchoolsAndClassesMigration.new
318
- silence_stream($stdout) { migration.migrate(:up) }
319
- assert_equal 1, @connection.foreign_keys("p_classes").size
320
- ensure
321
- silence_stream($stdout) { migration.migrate(:down) }
322
- ActiveRecord::Base.table_name_prefix = nil
323
- end
483
+ def test_schema_dumping
484
+ @connection.add_foreign_key :astronauts, :rockets
485
+ output = dump_table_schema "astronauts"
486
+ assert_match %r{\s+add_foreign_key "astronauts", "rockets"$}, output
487
+ end
324
488
 
325
- def test_add_foreign_key_with_suffix
326
- ActiveRecord::Base.table_name_suffix = '_s'
327
- migration = CreateSchoolsAndClassesMigration.new
328
- silence_stream($stdout) { migration.migrate(:up) }
329
- assert_equal 1, @connection.foreign_keys("classes_s").size
330
- ensure
331
- silence_stream($stdout) { migration.migrate(:down) }
332
- ActiveRecord::Base.table_name_suffix = nil
333
- end
489
+ def test_schema_dumping_with_options
490
+ output = dump_table_schema "fk_test_has_fk"
491
+ if current_adapter?(:SQLite3Adapter)
492
+ assert_match %r{\s+add_foreign_key "fk_test_has_fk", "fk_test_has_pk", column: "fk_id", primary_key: "pk_id"$}, output
493
+ else
494
+ assert_match %r{\s+add_foreign_key "fk_test_has_fk", "fk_test_has_pk", column: "fk_id", primary_key: "pk_id", name: "fk_name"$}, output
495
+ end
496
+ end
334
497
 
335
- end
336
- end
337
- end
338
- else
339
- module ActiveRecord
340
- class Migration
341
- class NoForeignKeySupportTest < ActiveRecord::TestCase
342
- setup do
343
- @connection = ActiveRecord::Base.connection
344
- end
498
+ def test_schema_dumping_with_custom_fk_ignore_pattern
499
+ original_pattern = ActiveRecord::SchemaDumper.fk_ignore_pattern
500
+ ActiveRecord::SchemaDumper.fk_ignore_pattern = /^ignored_/
501
+ @connection.add_foreign_key :astronauts, :rockets, name: :ignored_fk_astronauts_rockets
345
502
 
346
- def test_add_foreign_key_should_be_noop
347
- @connection.add_foreign_key :clubs, :categories
348
- end
503
+ output = dump_table_schema "astronauts"
504
+ assert_match %r{\s+add_foreign_key "astronauts", "rockets"$}, output
349
505
 
350
- def test_remove_foreign_key_should_be_noop
351
- @connection.remove_foreign_key :clubs, :categories
352
- end
506
+ ActiveRecord::SchemaDumper.fk_ignore_pattern = original_pattern
507
+ end
508
+
509
+ def test_schema_dumping_on_delete_and_on_update_options
510
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :nullify, on_update: :cascade
353
511
 
354
- def test_foreign_keys_should_raise_not_implemented
355
- assert_raises NotImplementedError do
356
- @connection.foreign_keys("clubs")
512
+ output = dump_table_schema "astronauts"
513
+ assert_match %r{\s+add_foreign_key "astronauts",.+on_update: :cascade,.+on_delete: :nullify$}, output
514
+ end
515
+
516
+ class CreateCitiesAndHousesMigration < ActiveRecord::Migration::Current
517
+ def change
518
+ create_table("cities") { |t| }
519
+
520
+ create_table("houses") do |t|
521
+ t.references :city
522
+ end
523
+ add_foreign_key :houses, :cities, column: "city_id"
524
+
525
+ # remove and re-add to test that schema is updated and not accidentally cached
526
+ remove_foreign_key :houses, :cities
527
+ add_foreign_key :houses, :cities, column: "city_id", on_delete: :cascade
528
+ end
529
+ end
530
+
531
+ def test_add_foreign_key_is_reversible
532
+ migration = CreateCitiesAndHousesMigration.new
533
+ silence_stream($stdout) { migration.migrate(:up) }
534
+ assert_equal 1, @connection.foreign_keys("houses").size
535
+ ensure
536
+ silence_stream($stdout) { migration.migrate(:down) }
537
+ end
538
+
539
+ def test_foreign_key_constraint_is_not_cached_incorrectly
540
+ migration = CreateCitiesAndHousesMigration.new
541
+ silence_stream($stdout) { migration.migrate(:up) }
542
+ output = dump_table_schema "houses"
543
+ assert_match %r{\s+add_foreign_key "houses",.+on_delete: :cascade$}, output
544
+ ensure
545
+ silence_stream($stdout) { migration.migrate(:down) }
546
+ end
547
+
548
+ class CreateSchoolsAndClassesMigration < ActiveRecord::Migration::Current
549
+ def change
550
+ create_table(:schools)
551
+
552
+ create_table(:classes) do |t|
553
+ t.references :school
554
+ end
555
+ add_foreign_key :classes, :schools, validate: true
556
+ end
557
+ end
558
+
559
+ def test_add_foreign_key_with_prefix
560
+ ActiveRecord::Base.table_name_prefix = "p_"
561
+ migration = CreateSchoolsAndClassesMigration.new
562
+ silence_stream($stdout) { migration.migrate(:up) }
563
+ assert_equal 1, @connection.foreign_keys("p_classes").size
564
+ ensure
565
+ silence_stream($stdout) { migration.migrate(:down) }
566
+ ActiveRecord::Base.table_name_prefix = nil
567
+ end
568
+
569
+ def test_add_foreign_key_with_suffix
570
+ ActiveRecord::Base.table_name_suffix = "_s"
571
+ migration = CreateSchoolsAndClassesMigration.new
572
+ silence_stream($stdout) { migration.migrate(:up) }
573
+ assert_equal 1, @connection.foreign_keys("classes_s").size
574
+ ensure
575
+ silence_stream($stdout) { migration.migrate(:down) }
576
+ ActiveRecord::Base.table_name_suffix = nil
357
577
  end
358
578
  end
359
579
  end
360
580
  end
361
581
  end
362
- end