ibm_db 5.6.1 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (592) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Makefile +13 -9
  3. data/ext/extconf.rb +176 -110
  4. data/ext/ibm_db.c +60 -0
  5. data/ext/ibm_db.o +0 -0
  6. data/ext/ibm_db.so +0 -0
  7. data/ext/mkmf.log +6 -6
  8. data/ext/ruby_ibm_db_cli.c +14 -10
  9. data/ext/ruby_ibm_db_cli.h +4 -0
  10. data/ext/ruby_ibm_db_cli.o +0 -0
  11. data/lib/IBM_DB.rb +2 -2
  12. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1254 -277
  13. data/test/active_record/connection_adapters/fake_legacy_adapter.rb +17 -0
  14. data/test/active_record/connection_adapters/fake_misleading_legacy_adapter.rb +8 -0
  15. data/test/activejob/destroy_association_async_job_test.rb +62 -0
  16. data/test/activejob/destroy_association_async_test.rb +147 -11
  17. data/test/activejob/job_runtime_test.rb +41 -0
  18. data/test/activejob/unloadable_base_job.rb +3 -0
  19. data/test/cases/active_record_schema_test.rb +196 -0
  20. data/test/cases/active_record_test.rb +21 -0
  21. data/test/cases/adapter_prevent_writes_test.rb +26 -202
  22. data/test/cases/adapter_test.rb +592 -82
  23. data/test/cases/adapters/abstract_mysql_adapter/active_schema_test.rb +210 -0
  24. data/test/cases/adapters/abstract_mysql_adapter/adapter_prevent_writes_test.rb +111 -0
  25. data/test/cases/adapters/abstract_mysql_adapter/auto_increment_test.rb +48 -0
  26. data/test/cases/adapters/abstract_mysql_adapter/bind_parameter_test.rb +91 -0
  27. data/test/cases/adapters/abstract_mysql_adapter/case_sensitivity_test.rb +65 -0
  28. data/test/cases/adapters/abstract_mysql_adapter/charset_collation_test.rb +85 -0
  29. data/test/cases/adapters/abstract_mysql_adapter/connection_test.rb +267 -0
  30. data/test/cases/adapters/abstract_mysql_adapter/count_deleted_rows_with_lock_test.rb +29 -0
  31. data/test/cases/adapters/abstract_mysql_adapter/json_test.rb +24 -0
  32. data/test/cases/adapters/abstract_mysql_adapter/mysql_boolean_test.rb +102 -0
  33. data/test/cases/adapters/abstract_mysql_adapter/mysql_enum_test.rb +47 -0
  34. data/test/cases/adapters/abstract_mysql_adapter/mysql_explain_test.rb +71 -0
  35. data/test/cases/adapters/abstract_mysql_adapter/nested_deadlock_test.rb +191 -0
  36. data/test/cases/adapters/abstract_mysql_adapter/optimizer_hints_test.rb +69 -0
  37. data/test/cases/adapters/abstract_mysql_adapter/quoting_test.rb +49 -0
  38. data/test/cases/adapters/abstract_mysql_adapter/schema_migrations_test.rb +68 -0
  39. data/test/cases/adapters/abstract_mysql_adapter/schema_test.rb +130 -0
  40. data/test/cases/adapters/abstract_mysql_adapter/set_test.rb +32 -0
  41. data/test/cases/adapters/abstract_mysql_adapter/sp_test.rb +39 -0
  42. data/test/cases/adapters/abstract_mysql_adapter/sql_types_test.rb +16 -0
  43. data/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb +125 -0
  44. data/test/cases/adapters/abstract_mysql_adapter/transaction_test.rb +204 -0
  45. data/test/cases/adapters/abstract_mysql_adapter/unsigned_type_test.rb +77 -0
  46. data/test/cases/adapters/abstract_mysql_adapter/virtual_column_test.rb +69 -0
  47. data/test/cases/adapters/abstract_mysql_adapter/warnings_test.rb +109 -0
  48. data/test/cases/adapters/mysql2/check_constraint_quoting_test.rb +35 -0
  49. data/test/cases/adapters/mysql2/dbconsole_test.rb +87 -0
  50. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +136 -10
  51. data/test/cases/adapters/mysql2/mysql2_rake_test.rb +433 -0
  52. data/test/cases/adapters/postgresql/active_schema_test.rb +8 -4
  53. data/test/cases/adapters/postgresql/array_test.rb +6 -6
  54. data/test/cases/adapters/postgresql/bind_parameter_test.rb +52 -0
  55. data/test/cases/adapters/postgresql/bit_string_test.rb +2 -2
  56. data/test/cases/adapters/postgresql/bytea_test.rb +3 -3
  57. data/test/cases/adapters/postgresql/case_insensitive_test.rb +1 -1
  58. data/test/cases/adapters/postgresql/change_schema_test.rb +32 -1
  59. data/test/cases/adapters/postgresql/cidr_test.rb +17 -0
  60. data/test/cases/adapters/postgresql/citext_test.rb +7 -1
  61. data/test/cases/adapters/postgresql/collation_test.rb +1 -1
  62. data/test/cases/adapters/postgresql/composite_test.rb +1 -1
  63. data/test/cases/adapters/postgresql/connection_test.rb +43 -36
  64. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +3 -2
  65. data/test/cases/adapters/postgresql/datatype_test.rb +9 -4
  66. data/test/cases/adapters/postgresql/date_test.rb +2 -2
  67. data/test/cases/adapters/postgresql/dbconsole_test.rb +109 -0
  68. data/test/cases/adapters/postgresql/deferred_constraints_test.rb +55 -0
  69. data/test/cases/adapters/postgresql/domain_test.rb +1 -1
  70. data/test/cases/adapters/postgresql/enum_test.rb +208 -8
  71. data/test/cases/adapters/postgresql/explain_test.rb +25 -6
  72. data/test/cases/adapters/postgresql/extension_migration_test.rb +51 -9
  73. data/test/cases/adapters/postgresql/foreign_table_test.rb +3 -3
  74. data/test/cases/adapters/postgresql/full_text_test.rb +1 -1
  75. data/test/cases/adapters/postgresql/geometric_test.rb +13 -6
  76. data/test/cases/adapters/postgresql/hstore_test.rb +22 -32
  77. data/test/cases/adapters/postgresql/infinity_test.rb +13 -2
  78. data/test/cases/adapters/postgresql/integer_test.rb +1 -1
  79. data/test/cases/adapters/postgresql/interval_test.rb +9 -17
  80. data/test/cases/adapters/postgresql/invertible_migration_test.rb +139 -0
  81. data/test/cases/adapters/postgresql/json_test.rb +5 -0
  82. data/test/cases/adapters/postgresql/ltree_test.rb +1 -1
  83. data/test/cases/adapters/postgresql/money_test.rb +17 -9
  84. data/test/cases/adapters/postgresql/network_test.rb +13 -1
  85. data/test/cases/adapters/postgresql/numbers_test.rb +18 -2
  86. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +9 -9
  87. data/test/cases/adapters/postgresql/partitions_test.rb +5 -2
  88. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +7 -110
  89. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +403 -20
  90. data/test/cases/adapters/postgresql/postgresql_rake_test.rb +637 -0
  91. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +1 -1
  92. data/test/cases/adapters/postgresql/quoting_test.rb +60 -1
  93. data/test/cases/adapters/postgresql/range_test.rb +185 -21
  94. data/test/cases/adapters/postgresql/referential_integrity_test.rb +29 -5
  95. data/test/cases/adapters/postgresql/rename_table_test.rb +35 -8
  96. data/test/cases/adapters/postgresql/schema_authorization_test.rb +2 -2
  97. data/test/cases/adapters/postgresql/schema_test.rb +270 -20
  98. data/test/cases/adapters/postgresql/serial_test.rb +5 -5
  99. data/test/cases/adapters/postgresql/statement_pool_test.rb +6 -2
  100. data/test/cases/adapters/postgresql/timestamp_test.rb +122 -5
  101. data/test/cases/adapters/postgresql/transaction_nested_test.rb +130 -6
  102. data/test/cases/adapters/postgresql/transaction_test.rb +37 -11
  103. data/test/cases/adapters/postgresql/type_lookup_test.rb +1 -1
  104. data/test/cases/adapters/postgresql/uuid_test.rb +77 -9
  105. data/test/cases/adapters/postgresql/virtual_column_test.rb +114 -0
  106. data/test/cases/adapters/postgresql/xml_test.rb +1 -1
  107. data/test/cases/adapters/sqlite3/bind_parameter_test.rb +52 -0
  108. data/test/cases/adapters/sqlite3/collation_test.rb +1 -1
  109. data/test/cases/adapters/sqlite3/copy_table_test.rb +28 -7
  110. data/test/cases/adapters/sqlite3/dbconsole_test.rb +81 -0
  111. data/test/cases/adapters/sqlite3/explain_test.rb +3 -3
  112. data/test/cases/adapters/sqlite3/quoting_test.rb +34 -3
  113. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +9 -102
  114. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +727 -72
  115. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +6 -3
  116. data/test/cases/adapters/sqlite3/sqlite_rake_test.rb +264 -0
  117. data/test/cases/adapters/sqlite3/statement_pool_test.rb +1 -1
  118. data/test/cases/adapters/sqlite3/transaction_test.rb +6 -3
  119. data/test/cases/adapters/sqlite3/virtual_column_test.rb +138 -0
  120. data/test/cases/adapters/sqlite3/virtual_table_test.rb +51 -0
  121. data/test/cases/adapters/trilogy/dbconsole_test.rb +76 -0
  122. data/test/cases/adapters/trilogy/trilogy_adapter_test.rb +473 -0
  123. data/test/cases/adapters/trilogy/trilogy_rake_test.rb +433 -0
  124. data/test/cases/aggregations_test.rb +16 -0
  125. data/test/cases/annotate_test.rb +14 -12
  126. data/test/cases/arel/attributes/attribute_test.rb +86 -47
  127. data/test/cases/arel/collectors/bind_test.rb +1 -1
  128. data/test/cases/arel/collectors/composite_test.rb +11 -1
  129. data/test/cases/arel/collectors/sql_string_test.rb +1 -1
  130. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +1 -1
  131. data/test/cases/arel/delete_manager_test.rb +0 -6
  132. data/test/cases/arel/factory_methods_test.rb +45 -0
  133. data/test/cases/arel/insert_manager_test.rb +1 -7
  134. data/test/cases/arel/nodes/as_test.rb +12 -0
  135. data/test/cases/arel/nodes/ascending_test.rb +1 -1
  136. data/test/cases/arel/nodes/bin_test.rb +1 -1
  137. data/test/cases/arel/nodes/bound_sql_literal_test.rb +31 -0
  138. data/test/cases/arel/nodes/cte_test.rb +46 -0
  139. data/test/cases/arel/nodes/descending_test.rb +1 -1
  140. data/test/cases/arel/nodes/equality_test.rb +3 -3
  141. data/test/cases/arel/nodes/filter_test.rb +37 -0
  142. data/test/cases/arel/nodes/fragments_test.rb +38 -0
  143. data/test/cases/arel/nodes/homogeneous_in_test.rb +52 -0
  144. data/test/cases/arel/nodes/infix_operation_test.rb +1 -1
  145. data/test/cases/arel/nodes/node_test.rb +1 -1
  146. data/test/cases/arel/nodes/or_test.rb +2 -2
  147. data/test/cases/arel/nodes/sql_literal_test.rb +18 -1
  148. data/test/cases/arel/nodes/table_alias_test.rb +12 -0
  149. data/test/cases/arel/nodes/unary_operation_test.rb +1 -1
  150. data/test/cases/arel/nodes/update_statement_test.rb +4 -0
  151. data/test/cases/arel/nodes_test.rb +3 -2
  152. data/test/cases/arel/select_manager_test.rb +12 -12
  153. data/test/cases/arel/support/fake_record.rb +22 -17
  154. data/test/cases/arel/table_test.rb +15 -25
  155. data/test/cases/arel/update_manager_test.rb +51 -6
  156. data/test/cases/arel/visitors/dispatch_contamination_test.rb +1 -1
  157. data/test/cases/arel/visitors/dot_test.rb +177 -2
  158. data/test/cases/arel/visitors/mysql_test.rb +49 -1
  159. data/test/cases/arel/visitors/postgres_test.rb +1 -31
  160. data/test/cases/arel/visitors/sqlite_test.rb +1 -1
  161. data/test/cases/arel/visitors/to_sql_test.rb +330 -20
  162. data/test/cases/assertions/query_assertions_test.rb +136 -0
  163. data/test/cases/associations/belongs_to_associations_test.rb +502 -41
  164. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +1 -1
  165. data/test/cases/associations/cascaded_eager_loading_test.rb +26 -15
  166. data/test/cases/associations/eager_load_nested_include_test.rb +1 -1
  167. data/test/cases/associations/eager_singularization_test.rb +1 -1
  168. data/test/cases/associations/eager_test.rb +255 -93
  169. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +25 -53
  170. data/test/cases/associations/has_many_associations_test.rb +282 -72
  171. data/test/cases/associations/has_many_through_associations_test.rb +172 -45
  172. data/test/cases/associations/has_many_through_disable_joins_associations_test.rb +197 -0
  173. data/test/cases/associations/has_one_associations_test.rb +160 -29
  174. data/test/cases/associations/has_one_through_associations_test.rb +64 -15
  175. data/test/cases/associations/has_one_through_disable_joins_associations_test.rb +82 -0
  176. data/test/cases/associations/inner_join_association_test.rb +36 -6
  177. data/test/cases/associations/inverse_associations_test.rb +177 -40
  178. data/test/cases/associations/join_model_test.rb +17 -12
  179. data/test/cases/associations/left_outer_join_association_test.rb +14 -3
  180. data/test/cases/associations/nested_error_test.rb +116 -0
  181. data/test/cases/associations/nested_through_associations_test.rb +54 -19
  182. data/test/cases/associations/required_test.rb +1 -1
  183. data/test/cases/associations_test.rb +1278 -21
  184. data/test/cases/asynchronous_queries_test.rb +310 -0
  185. data/test/cases/attribute_methods/read_test.rb +6 -0
  186. data/test/cases/attribute_methods/time_zone_converter_test.rb +21 -0
  187. data/test/cases/attribute_methods_test.rb +565 -46
  188. data/test/cases/attributes_test.rb +42 -1
  189. data/test/cases/autosave_association_test.rb +645 -92
  190. data/test/cases/base_prevent_writes_test.rb +28 -159
  191. data/test/cases/base_test.rb +434 -209
  192. data/test/cases/batches_test.rb +441 -57
  193. data/test/cases/binary_test.rb +31 -0
  194. data/test/cases/bind_parameter_test.rb +107 -16
  195. data/test/cases/cache_key_test.rb +7 -7
  196. data/test/cases/calculations_test.rb +541 -110
  197. data/test/cases/callbacks_test.rb +0 -1
  198. data/test/cases/clone_test.rb +5 -4
  199. data/test/cases/coders/yaml_column_test.rb +97 -2
  200. data/test/cases/collection_cache_key_test.rb +24 -16
  201. data/test/cases/column_alias_test.rb +2 -8
  202. data/test/cases/column_definition_test.rb +12 -3
  203. data/test/cases/comment_test.rb +23 -26
  204. data/test/cases/connection_adapters/adapter_leasing_test.rb +9 -9
  205. data/test/cases/connection_adapters/connection_handler_test.rb +145 -99
  206. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +79 -55
  207. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +17 -20
  208. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +146 -55
  209. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +136 -23
  210. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +96 -27
  211. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -5
  212. data/test/cases/connection_adapters/registration_test.rb +98 -0
  213. data/test/cases/connection_adapters/schema_cache_test.rb +288 -135
  214. data/test/cases/connection_adapters/standalone_connection_test.rb +38 -0
  215. data/test/cases/connection_adapters/statement_pool_test.rb +29 -0
  216. data/test/cases/connection_adapters/type_lookup_test.rb +12 -24
  217. data/test/cases/connection_handling_test.rb +210 -0
  218. data/test/cases/connection_management_test.rb +44 -7
  219. data/test/cases/connection_pool_test.rb +466 -99
  220. data/test/cases/core_test.rb +167 -9
  221. data/test/cases/counter_cache_test.rb +129 -2
  222. data/test/cases/custom_locking_test.rb +3 -3
  223. data/test/cases/database_configurations/hash_config_test.rb +149 -13
  224. data/test/cases/database_configurations/resolver_test.rb +14 -10
  225. data/test/cases/database_configurations/url_config_test.rb +53 -0
  226. data/test/cases/database_configurations_test.rb +86 -43
  227. data/test/cases/database_selector_test.rb +30 -8
  228. data/test/cases/database_statements_test.rb +10 -14
  229. data/test/cases/date_time_precision_test.rb +141 -11
  230. data/test/cases/date_time_test.rb +19 -1
  231. data/test/cases/defaults_test.rb +107 -41
  232. data/test/cases/delegated_type_test.rb +69 -9
  233. data/test/cases/dirty_test.rb +82 -25
  234. data/test/cases/disconnected_test.rb +10 -9
  235. data/test/cases/dup_test.rb +26 -6
  236. data/test/cases/encryption/cipher/aes256_gcm_test.rb +50 -0
  237. data/test/cases/encryption/cipher_test.rb +65 -0
  238. data/test/cases/encryption/concurrency_test.rb +27 -0
  239. data/test/cases/encryption/config_test.rb +21 -0
  240. data/test/cases/encryption/configurable_test.rb +93 -0
  241. data/test/cases/encryption/contexts_test.rb +105 -0
  242. data/test/cases/encryption/derived_secret_key_provider_test.rb +31 -0
  243. data/test/cases/encryption/deterministic_key_provider_test.rb +11 -0
  244. data/test/cases/encryption/encryptable_record_api_test.rb +175 -0
  245. data/test/cases/encryption/encryptable_record_message_pack_serialized_test.rb +42 -0
  246. data/test/cases/encryption/encryptable_record_test.rb +470 -0
  247. data/test/cases/encryption/encrypted_fixtures_test.rb +22 -0
  248. data/test/cases/encryption/encrypting_only_encryptor_test.rb +20 -0
  249. data/test/cases/encryption/encryption_schemes_test.rb +240 -0
  250. data/test/cases/encryption/encryptor_test.rb +113 -0
  251. data/test/cases/encryption/envelope_encryption_key_provider_test.rb +49 -0
  252. data/test/cases/encryption/extended_deterministic_queries_test.rb +81 -0
  253. data/test/cases/encryption/helper.rb +152 -0
  254. data/test/cases/encryption/key_generator_test.rb +55 -0
  255. data/test/cases/encryption/key_provider_test.rb +57 -0
  256. data/test/cases/encryption/key_test.rb +17 -0
  257. data/test/cases/encryption/message_pack_message_serializer_test.rb +70 -0
  258. data/test/cases/encryption/message_serializer_test.rb +82 -0
  259. data/test/cases/encryption/message_test.rb +43 -0
  260. data/test/cases/encryption/null_encryptor_test.rb +21 -0
  261. data/test/cases/encryption/properties_test.rb +69 -0
  262. data/test/cases/encryption/read_only_null_encryptor_test.rb +19 -0
  263. data/test/cases/encryption/scheme_test.rb +58 -0
  264. data/test/cases/encryption/unencrypted_attributes_test.rb +27 -0
  265. data/test/cases/encryption/uniqueness_validations_test.rb +65 -0
  266. data/test/cases/enum_test.rb +374 -72
  267. data/test/cases/errors_test.rb +7 -4
  268. data/test/cases/excluding_test.rb +116 -0
  269. data/test/cases/explain_subscriber_test.rb +6 -1
  270. data/test/cases/explain_test.rb +119 -10
  271. data/test/cases/filter_attributes_test.rb +7 -14
  272. data/test/cases/finder_respond_to_test.rb +3 -3
  273. data/test/cases/finder_test.rb +357 -72
  274. data/test/cases/fixture_set/file_test.rb +9 -0
  275. data/test/cases/fixtures_test.rb +426 -190
  276. data/test/cases/helper.rb +66 -192
  277. data/test/cases/hot_compatibility_test.rb +10 -10
  278. data/test/cases/inheritance_test.rb +51 -61
  279. data/test/cases/inherited_test.rb +40 -0
  280. data/test/cases/insert_all_test.rb +419 -9
  281. data/test/cases/instrumentation_test.rb +202 -30
  282. data/test/cases/integration_test.rb +25 -7
  283. data/test/cases/invalid_connection_test.rb +5 -5
  284. data/test/cases/invertible_migration_test.rb +108 -24
  285. data/test/cases/json_attribute_test.rb +1 -0
  286. data/test/cases/json_serialization_test.rb +5 -5
  287. data/test/cases/json_shared_test_cases.rb +5 -9
  288. data/test/cases/locking_test.rb +67 -31
  289. data/test/cases/log_subscriber_test.rb +17 -15
  290. data/test/cases/marshal_serialization_test.rb +78 -5
  291. data/test/cases/message_pack_test.rb +91 -0
  292. data/test/cases/migration/change_schema_test.rb +77 -46
  293. data/test/cases/migration/change_table_test.rb +129 -114
  294. data/test/cases/migration/check_constraint_test.rb +192 -10
  295. data/test/cases/migration/column_attributes_test.rb +4 -9
  296. data/test/cases/migration/column_positioning_test.rb +2 -2
  297. data/test/cases/migration/columns_test.rb +118 -4
  298. data/test/cases/migration/command_recorder_test.rb +181 -14
  299. data/test/cases/migration/compatibility_test.rb +883 -196
  300. data/test/cases/migration/create_join_table_test.rb +8 -1
  301. data/test/cases/migration/exclusion_constraint_test.rb +192 -0
  302. data/test/cases/migration/foreign_key_test.rb +356 -14
  303. data/test/cases/migration/helper.rb +4 -1
  304. data/test/cases/migration/index_test.rb +67 -2
  305. data/test/cases/migration/invalid_options_test.rb +129 -0
  306. data/test/cases/migration/logger_test.rb +7 -4
  307. data/test/cases/migration/pending_migrations_test.rb +103 -60
  308. data/test/cases/migration/references_foreign_key_test.rb +73 -4
  309. data/test/cases/migration/references_index_test.rb +25 -27
  310. data/test/cases/migration/references_statements_test.rb +27 -3
  311. data/test/cases/migration/rename_table_test.rb +39 -54
  312. data/test/cases/migration/schema_definitions_test.rb +109 -0
  313. data/test/cases/migration/unique_constraint_test.rb +248 -0
  314. data/test/cases/migration_test.rb +677 -220
  315. data/test/cases/migrator_test.rb +102 -75
  316. data/test/cases/multi_db_migrator_test.rb +55 -34
  317. data/test/cases/multiparameter_attributes_test.rb +26 -29
  318. data/test/cases/multiple_db_test.rb +42 -19
  319. data/test/cases/nested_attributes_test.rb +124 -6
  320. data/test/cases/nested_attributes_with_callbacks_test.rb +2 -2
  321. data/test/cases/normalized_attribute_test.rb +117 -0
  322. data/test/cases/null_relation_test.rb +35 -2
  323. data/test/cases/persistence/reload_association_cache_test.rb +20 -0
  324. data/test/cases/persistence_test.rb +629 -22
  325. data/test/cases/pooled_connections_test.rb +57 -56
  326. data/test/cases/prepared_statement_status_test.rb +8 -3
  327. data/test/cases/primary_class_test.rb +134 -0
  328. data/test/cases/primary_keys_test.rb +171 -55
  329. data/test/cases/query_cache_test.rb +558 -263
  330. data/test/cases/query_logs_test.rb +293 -0
  331. data/test/cases/quoting_test.rb +39 -72
  332. data/test/cases/readonly_test.rb +50 -12
  333. data/test/cases/reaper_test.rb +22 -6
  334. data/test/cases/reflection_test.rb +207 -9
  335. data/test/cases/relation/and_test.rb +43 -0
  336. data/test/cases/relation/delegation_test.rb +32 -5
  337. data/test/cases/relation/delete_all_test.rb +27 -6
  338. data/test/cases/relation/field_ordered_values_test.rb +128 -0
  339. data/test/cases/relation/load_async_test.rb +650 -0
  340. data/test/cases/relation/merging_test.rb +80 -109
  341. data/test/cases/relation/mutation_test.rb +12 -7
  342. data/test/cases/relation/or_test.rb +11 -8
  343. data/test/cases/relation/order_test.rb +90 -0
  344. data/test/cases/relation/predicate_builder_test.rb +21 -6
  345. data/test/cases/relation/select_test.rb +162 -3
  346. data/test/cases/relation/structural_compatibility_test.rb +38 -0
  347. data/test/cases/relation/update_all_test.rb +81 -27
  348. data/test/cases/relation/where_chain_test.rb +190 -3
  349. data/test/cases/relation/where_clause_test.rb +43 -1
  350. data/test/cases/relation/where_test.rb +95 -7
  351. data/test/cases/relation/with_test.rb +165 -0
  352. data/test/cases/relation_test.rb +42 -37
  353. data/test/cases/relations_test.rb +436 -138
  354. data/test/cases/reload_models_test.rb +18 -14
  355. data/test/cases/reserved_word_test.rb +2 -1
  356. data/test/cases/result_test.rb +14 -22
  357. data/test/cases/sanitize_test.rb +89 -27
  358. data/test/cases/schema_dumper_test.rb +535 -62
  359. data/test/cases/scoping/default_scoping_test.rb +219 -35
  360. data/test/cases/scoping/named_scoping_test.rb +25 -46
  361. data/test/cases/scoping/relation_scoping_test.rb +112 -4
  362. data/test/cases/secure_password_test.rb +108 -0
  363. data/test/cases/secure_token_test.rb +72 -0
  364. data/test/cases/serialization_test.rb +1 -1
  365. data/test/cases/serialized_attribute_test.rb +305 -60
  366. data/test/cases/shard_keys_test.rb +125 -0
  367. data/test/cases/shard_selector_test.rb +45 -0
  368. data/test/cases/signed_id_test.rb +57 -5
  369. data/test/cases/statement_cache_test.rb +31 -30
  370. data/test/cases/statement_invalid_test.rb +8 -4
  371. data/test/cases/store_test.rb +73 -9
  372. data/test/cases/strict_loading_test.rb +327 -13
  373. data/test/cases/table_metadata_test.rb +16 -0
  374. data/test/cases/tasks/database_tasks_test.rb +517 -244
  375. data/test/cases/test_case.rb +254 -60
  376. data/test/cases/test_case_test.rb +69 -0
  377. data/test/cases/test_databases_test.rb +7 -3
  378. data/test/cases/test_fixtures_test.rb +19 -40
  379. data/test/cases/time_precision_test.rb +17 -5
  380. data/test/cases/timestamp_test.rb +124 -16
  381. data/test/cases/token_for_test.rb +165 -0
  382. data/test/cases/touch_later_test.rb +43 -1
  383. data/test/cases/transaction_callbacks_test.rb +325 -8
  384. data/test/cases/transaction_instrumentation_test.rb +453 -0
  385. data/test/cases/transaction_isolation_test.rb +12 -8
  386. data/test/cases/transactions_test.rb +629 -112
  387. data/test/cases/type/date_time_test.rb +7 -1
  388. data/test/cases/type/time_test.rb +9 -0
  389. data/test/cases/type/type_map_test.rb +108 -73
  390. data/test/cases/type/unsigned_integer_test.rb +12 -0
  391. data/test/cases/type_caster/connection_test.rb +19 -0
  392. data/test/cases/type_test.rb +1 -1
  393. data/test/cases/unconnected_test.rb +7 -7
  394. data/test/cases/unsafe_raw_sql_test.rb +39 -8
  395. data/test/cases/validations/absence_validation_test.rb +1 -1
  396. data/test/cases/validations/association_validation_test.rb +25 -3
  397. data/test/cases/validations/numericality_validation_test.rb +3 -9
  398. data/test/cases/validations/presence_validation_test.rb +1 -1
  399. data/test/cases/validations/uniqueness_validation_test.rb +280 -40
  400. data/test/cases/validations_test.rb +2 -2
  401. data/test/cases/view_test.rb +33 -22
  402. data/test/cases/yaml_serialization_test.rb +23 -17
  403. data/test/config.example.yml +58 -56
  404. data/test/config.rb +1 -0
  405. data/test/fixtures/1_need_quoting.yml +2 -0
  406. data/test/fixtures/accounts.yml +5 -0
  407. data/test/fixtures/aircrafts.yml +7 -0
  408. data/test/fixtures/book_identifiers.yml +11 -0
  409. data/test/fixtures/books.yml +5 -4
  410. data/test/fixtures/cake_designers.yml +5 -0
  411. data/test/fixtures/cars.yml +6 -0
  412. data/test/fixtures/chefs.yml +5 -0
  413. data/test/fixtures/clothing_items.yml +23 -0
  414. data/test/fixtures/clubs.yml +1 -1
  415. data/test/fixtures/comments.yml +2 -1
  416. data/test/fixtures/cpk_authors.yml +8 -0
  417. data/test/fixtures/cpk_books.yml +21 -0
  418. data/test/fixtures/cpk_order_agreements.yml +13 -0
  419. data/test/fixtures/cpk_order_tags.yml +15 -0
  420. data/test/fixtures/cpk_orders.yml +11 -0
  421. data/test/fixtures/cpk_posts.yml +12 -0
  422. data/test/fixtures/cpk_reviews.yml +13 -0
  423. data/test/fixtures/cpk_tags.yml +11 -0
  424. data/test/fixtures/drink_designers.yml +5 -0
  425. data/test/fixtures/encrypted_book_that_ignores_cases.yml +4 -0
  426. data/test/fixtures/encrypted_books.yml +4 -0
  427. data/test/fixtures/fk_object_to_point_to.yml +2 -0
  428. data/test/fixtures/memberships.yml +15 -15
  429. data/test/fixtures/paragraphs.yml +5 -0
  430. data/test/fixtures/parrots.yml +4 -0
  431. data/test/fixtures/people.yml +2 -0
  432. data/test/fixtures/pirates.yml +2 -2
  433. data/test/fixtures/primary_key_error/primary_key_error.yml +6 -0
  434. data/test/fixtures/references.yml +3 -3
  435. data/test/fixtures/sharded_blog_posts.yml +14 -0
  436. data/test/fixtures/sharded_blog_posts_tags.yml +27 -0
  437. data/test/fixtures/sharded_blogs.yml +8 -0
  438. data/test/fixtures/sharded_comments.yml +22 -0
  439. data/test/fixtures/sharded_tags.yml +34 -0
  440. data/test/fixtures/sponsors.yml +2 -2
  441. data/test/fixtures/topics.yml +1 -0
  442. data/test/fixtures/treasures.yml +4 -0
  443. data/test/fixtures/virtual_columns.yml +5 -0
  444. data/test/fixtures/warehouse_things.yml +1 -1
  445. data/test/migrations/old_and_new_versions/20210716122844_add_people_description.rb +5 -0
  446. data/test/migrations/old_and_new_versions/20210716123013_add_people_number_of_legs.rb +5 -0
  447. data/test/migrations/old_and_new_versions/230_add_people_hobby.rb +5 -0
  448. data/test/migrations/old_and_new_versions/231_add_people_last_name.rb +5 -0
  449. data/test/migrations/scope/1_unscoped.rb +7 -0
  450. data/test/migrations/scope/2_mysql_only.mysql.rb +7 -0
  451. data/test/models/admin/user.rb +2 -0
  452. data/test/models/admin/user_json.rb +48 -0
  453. data/test/models/attachment.rb +7 -0
  454. data/test/models/author.rb +70 -3
  455. data/test/models/author_encrypted.rb +16 -0
  456. data/test/models/bird.rb +1 -1
  457. data/test/models/book.rb +18 -11
  458. data/test/models/book_destroy_async.rb +1 -1
  459. data/test/models/book_encrypted.rb +106 -0
  460. data/test/models/book_identifier.rb +5 -0
  461. data/test/models/branch.rb +11 -0
  462. data/test/models/bulb.rb +1 -1
  463. data/test/models/car.rb +8 -1
  464. data/test/models/cat.rb +1 -1
  465. data/test/models/category.rb +3 -1
  466. data/test/models/chat_message.rb +8 -0
  467. data/test/models/chef.rb +52 -0
  468. data/test/models/clothing_item.rb +12 -0
  469. data/test/models/club.rb +4 -1
  470. data/test/models/comment.rb +7 -4
  471. data/test/models/comment_overlapping_counter_cache.rb +15 -0
  472. data/test/models/company.rb +16 -2
  473. data/test/models/computer.rb +1 -0
  474. data/test/models/contact.rb +3 -3
  475. data/test/models/contract.rb +5 -1
  476. data/test/models/cpk/author.rb +9 -0
  477. data/test/models/cpk/book.rb +55 -0
  478. data/test/models/cpk/book_destroy_async.rb +9 -0
  479. data/test/models/cpk/car.rb +9 -0
  480. data/test/models/cpk/car_review.rb +9 -0
  481. data/test/models/cpk/chapter.rb +16 -0
  482. data/test/models/cpk/chapter_destroy_async.rb +10 -0
  483. data/test/models/cpk/comment.rb +9 -0
  484. data/test/models/cpk/order.rb +55 -0
  485. data/test/models/cpk/order_agreement.rb +10 -0
  486. data/test/models/cpk/order_tag.rb +10 -0
  487. data/test/models/cpk/post.rb +10 -0
  488. data/test/models/cpk/posts_tag.rb +10 -0
  489. data/test/models/cpk/review.rb +9 -0
  490. data/test/models/cpk/tag.rb +10 -0
  491. data/test/models/cpk.rb +15 -0
  492. data/test/models/customer.rb +3 -1
  493. data/test/models/destroy_async_parent.rb +1 -1
  494. data/test/models/developer.rb +44 -3
  495. data/test/models/discount.rb +4 -0
  496. data/test/models/drink_designer.rb +1 -0
  497. data/test/models/editor.rb +8 -0
  498. data/test/models/editorship.rb +6 -0
  499. data/test/models/entry.rb +5 -0
  500. data/test/models/essay.rb +6 -1
  501. data/test/models/essay_destroy_async.rb +1 -0
  502. data/test/models/eye.rb +87 -21
  503. data/test/models/face.rb +1 -1
  504. data/test/models/friendship.rb +3 -0
  505. data/test/models/hardback.rb +7 -0
  506. data/test/models/hotel.rb +2 -0
  507. data/test/models/human.rb +2 -2
  508. data/test/models/invoice.rb +2 -1
  509. data/test/models/invokes_an_undefined_method.rb +5 -0
  510. data/test/models/line_item.rb +6 -0
  511. data/test/models/member.rb +9 -4
  512. data/test/models/membership.rb +2 -2
  513. data/test/models/message.rb +2 -1
  514. data/test/models/need_quoting.rb +5 -0
  515. data/test/models/paragraph.rb +5 -0
  516. data/test/models/parrot.rb +6 -3
  517. data/test/models/person.rb +7 -4
  518. data/test/models/pirate.rb +4 -1
  519. data/test/models/pk_autopopulated_by_a_trigger_record.rb +5 -0
  520. data/test/models/post.rb +65 -2
  521. data/test/models/post_encrypted.rb +15 -0
  522. data/test/models/post_with_prefetched_pk.rb +15 -0
  523. data/test/models/project.rb +1 -0
  524. data/test/models/publication.rb +16 -0
  525. data/test/models/raises_argument_error.rb +5 -0
  526. data/test/models/raises_no_method_error.rb +5 -0
  527. data/test/models/recipient.rb +5 -0
  528. data/test/models/reference.rb +1 -1
  529. data/test/models/reply.rb +1 -1
  530. data/test/models/room.rb +3 -0
  531. data/test/models/sharded/blog.rb +12 -0
  532. data/test/models/sharded/blog_post.rb +17 -0
  533. data/test/models/sharded/blog_post_destroy_async.rb +14 -0
  534. data/test/models/sharded/blog_post_tag.rb +11 -0
  535. data/test/models/sharded/blog_post_with_revision.rb +11 -0
  536. data/test/models/sharded/comment.rb +12 -0
  537. data/test/models/sharded/comment_destroy_async.rb +12 -0
  538. data/test/models/sharded/tag.rb +11 -0
  539. data/test/models/sharded.rb +8 -0
  540. data/test/models/ship.rb +1 -1
  541. data/test/models/shipping_line.rb +11 -0
  542. data/test/models/subscriber.rb +1 -0
  543. data/test/models/subscription.rb +3 -1
  544. data/test/models/too_long_table_name.rb +5 -0
  545. data/test/models/topic.rb +3 -1
  546. data/test/models/traffic_light.rb +2 -2
  547. data/test/models/traffic_light_encrypted.rb +21 -0
  548. data/test/models/translation.rb +9 -0
  549. data/test/models/treasure.rb +1 -1
  550. data/test/models/tyre.rb +1 -1
  551. data/test/models/user.rb +16 -0
  552. data/test/models/user_with_invalid_relation.rb +28 -0
  553. data/test/models/uuid_comment.rb +5 -0
  554. data/test/models/uuid_entry.rb +5 -0
  555. data/test/models/uuid_message.rb +5 -0
  556. data/test/models/zine.rb +2 -1
  557. data/test/schema/mysql2_specific_schema.rb +26 -12
  558. data/test/schema/postgresql_specific_schema.rb +121 -13
  559. data/test/schema/schema.rb +361 -103
  560. data/test/schema/sqlite_specific_schema.rb +17 -6
  561. data/test/schema/trilogy_specific_schema.rb +96 -0
  562. data/test/support/adapter_helper.rb +104 -0
  563. data/test/support/async_helper.rb +15 -0
  564. data/test/support/config.rb +1 -1
  565. data/test/support/connection.rb +14 -2
  566. data/test/support/ddl_helper.rb +1 -1
  567. data/test/support/fake_adapter.rb +42 -0
  568. data/test/support/load_schema_helper.rb +22 -0
  569. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic.dump +0 -0
  570. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic_associations.dump +0 -0
  571. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic.dump +0 -0
  572. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic_associations.dump +0 -0
  573. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic.dump +0 -0
  574. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic_associations.dump +0 -0
  575. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic.dump +0 -0
  576. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic_associations.dump +0 -0
  577. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic.dump +0 -0
  578. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic_associations.dump +0 -0
  579. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic.dump +0 -0
  580. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic_associations.dump +0 -0
  581. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic.dump +0 -0
  582. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic_associations.dump +0 -0
  583. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic.dump +0 -0
  584. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic_associations.dump +0 -0
  585. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic.dump +0 -0
  586. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic_associations.dump +0 -0
  587. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic.dump +0 -0
  588. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic_associations.dump +0 -0
  589. data/test/support/schema_dumping_helper.rb +15 -9
  590. data/test/support/tools.rb +37 -0
  591. data/test/support/yaml_compatibility_fixtures/rails_4_1_no_symbol.yml +22 -0
  592. metadata +247 -15
data/test/cases/helper.rb CHANGED
@@ -8,226 +8,100 @@ require "active_record"
8
8
  require "cases/test_case"
9
9
  require "active_support/dependencies"
10
10
  require "active_support/logger"
11
+ require "active_support/core_ext/kernel/reporting"
11
12
  require "active_support/core_ext/kernel/singleton_class"
12
13
 
13
- require "support/config"
14
- require "support/connection"
14
+ if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
15
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables = true
16
+ end
15
17
 
16
18
  # TODO: Move all these random hacks into the ARTest namespace and into the support/ dir
17
19
 
18
20
  Thread.abort_on_exception = true
19
21
 
20
22
  # Show backtraces for deprecated behavior for quicker cleanup.
21
- ActiveSupport::Deprecation.debug = true
22
-
23
- # Disable available locale checks to avoid warnings running the test suite.
24
- I18n.enforce_available_locales = false
25
-
26
- # Connect to the database
27
- ARTest.connect
28
-
29
- # Quote "type" if it's a reserved word for the current connection.
30
- QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name("type")
31
-
32
- def current_adapter?(*types)
33
- types.any? do |type|
34
- ActiveRecord::ConnectionAdapters.const_defined?(type) &&
35
- ActiveRecord::Base.connection.is_a?(ActiveRecord::ConnectionAdapters.const_get(type))
36
- end
37
- end
38
-
39
- def in_memory_db?
40
- current_adapter?(:SQLite3Adapter) &&
41
- ActiveRecord::Base.connection_pool.db_config.database == ":memory:"
42
- end
43
-
44
- def mysql_enforcing_gtid_consistency?
45
- current_adapter?(:Mysql2Adapter) && "ON" == ActiveRecord::Base.connection.show_variable("enforce_gtid_consistency")
46
- end
23
+ ActiveRecord.deprecator.debug = true
47
24
 
48
- def supports_default_expression?
49
- if current_adapter?(:PostgreSQLAdapter)
50
- true
51
- elsif current_adapter?(:Mysql2Adapter)
52
- conn = ActiveRecord::Base.connection
53
- !conn.mariadb? && conn.database_version >= "8.0.13"
54
- end
55
- end
25
+ # ActiveRecord::Base.connection is only soft deprecated but we ban it from the test suite
26
+ # to ensure it's not used internally.
27
+ ActiveRecord.permanent_connection_checkout = :disallowed
56
28
 
57
- def supports_text_column_with_default?
58
- if current_adapter?(:Mysql2Adapter)
59
- conn = ActiveRecord::Base.connection
60
- conn.mariadb? && conn.database_version >= "10.2.1"
61
- else
62
- true
63
- end
64
- end
29
+ ActiveRecord::Delegation::DelegateCache.delegate_base_methods = false
65
30
 
66
- %w[
67
- supports_savepoints?
68
- supports_partial_index?
69
- supports_partitioned_indexes?
70
- supports_expression_index?
71
- supports_insert_returning?
72
- supports_insert_on_duplicate_skip?
73
- supports_insert_on_duplicate_update?
74
- supports_insert_conflict_target?
75
- supports_optimizer_hints?
76
- supports_datetime_with_precision?
77
- ].each do |method_name|
78
- define_method method_name do
79
- ActiveRecord::Base.connection.public_send(method_name)
80
- end
81
- end
31
+ # Ensure this alias isn't being used by Active Record itself.
32
+ ActiveRecord::Relation.remove_method(:klass)
82
33
 
83
- def with_env_tz(new_tz = "US/Eastern")
84
- old_tz, ENV["TZ"] = ENV["TZ"], new_tz
85
- yield
86
- ensure
87
- old_tz ? ENV["TZ"] = old_tz : ENV.delete("TZ")
88
- end
89
-
90
- def with_timezone_config(cfg)
91
- verify_default_timezone_config
92
-
93
- old_default_zone = ActiveRecord::Base.default_timezone
94
- old_awareness = ActiveRecord::Base.time_zone_aware_attributes
95
- old_zone = Time.zone
96
-
97
- if cfg.has_key?(:default)
98
- ActiveRecord::Base.default_timezone = cfg[:default]
99
- end
100
- if cfg.has_key?(:aware_attributes)
101
- ActiveRecord::Base.time_zone_aware_attributes = cfg[:aware_attributes]
102
- end
103
- if cfg.has_key?(:zone)
104
- Time.zone = cfg[:zone]
105
- end
106
- yield
107
- ensure
108
- ActiveRecord::Base.default_timezone = old_default_zone
109
- ActiveRecord::Base.time_zone_aware_attributes = old_awareness
110
- Time.zone = old_zone
111
- end
34
+ # Disable available locale checks to avoid warnings running the test suite.
35
+ I18n.enforce_available_locales = false
112
36
 
113
- # This method makes sure that tests don't leak global state related to time zones.
114
- EXPECTED_ZONE = nil
115
- EXPECTED_DEFAULT_TIMEZONE = :utc
116
- EXPECTED_TIME_ZONE_AWARE_ATTRIBUTES = false
117
- def verify_default_timezone_config
118
- if Time.zone != EXPECTED_ZONE
119
- $stderr.puts <<-MSG
120
- \n#{self}
121
- Global state `Time.zone` was leaked.
122
- Expected: #{EXPECTED_ZONE}
123
- Got: #{Time.zone}
124
- MSG
125
- end
126
- if ActiveRecord::Base.default_timezone != EXPECTED_DEFAULT_TIMEZONE
127
- $stderr.puts <<-MSG
128
- \n#{self}
129
- Global state `ActiveRecord::Base.default_timezone` was leaked.
130
- Expected: #{EXPECTED_DEFAULT_TIMEZONE}
131
- Got: #{ActiveRecord::Base.default_timezone}
132
- MSG
133
- end
134
- if ActiveRecord::Base.time_zone_aware_attributes != EXPECTED_TIME_ZONE_AWARE_ATTRIBUTES
135
- $stderr.puts <<-MSG
136
- \n#{self}
137
- Global state `ActiveRecord::Base.time_zone_aware_attributes` was leaked.
138
- Expected: #{EXPECTED_TIME_ZONE_AWARE_ATTRIBUTES}
139
- Got: #{ActiveRecord::Base.time_zone_aware_attributes}
140
- MSG
141
- end
142
- end
37
+ # Quote "type" if it's a reserved word for the current connection.
38
+ QUOTED_TYPE = ActiveRecord::Base.lease_connection.quote_column_name("type")
143
39
 
144
- def enable_extension!(extension, connection)
145
- return false unless connection.supports_extensions?
146
- return connection.reconnect! if connection.extension_enabled?(extension)
40
+ ActiveRecord::Base.automatically_invert_plural_associations = true
147
41
 
148
- connection.enable_extension extension
149
- connection.commit_db_transaction if connection.transaction_open?
150
- connection.reconnect!
151
- end
42
+ ActiveRecord.raise_on_assign_to_attr_readonly = true
43
+ ActiveRecord.belongs_to_required_validates_foreign_key = false
152
44
 
153
- def disable_extension!(extension, connection)
154
- return false unless connection.supports_extensions?
155
- return true unless connection.extension_enabled?(extension)
45
+ ActiveRecord::ConnectionAdapters.register("abstract", "ActiveRecord::ConnectionAdapters::AbstractAdapter", "active_record/connection_adapters/abstract_adapter")
46
+ ActiveRecord::ConnectionAdapters.register("fake", "FakeActiveRecordAdapter", File.expand_path("../support/fake_adapter.rb", __dir__))
156
47
 
157
- connection.disable_extension extension
158
- connection.reconnect!
159
- end
48
+ class ActiveRecord::TestCase
49
+ class SQLSubscriber
50
+ attr_reader :logged
51
+ attr_reader :payloads
160
52
 
161
- def clean_up_legacy_connection_handlers
162
- handler = ActiveRecord::Base.default_connection_handler
163
- ActiveRecord::Base.connection_handlers = {}
53
+ def initialize
54
+ @logged = []
55
+ @payloads = []
56
+ end
164
57
 
165
- handler.connection_pool_names.each do |name|
166
- next if ["ActiveRecord::Base", "ARUnit2Model", "Contact", "ContactSti", "FirstAbstractClass", "SecondAbstractClass"].include?(name)
58
+ def start(name, id, payload)
59
+ @payloads << payload
60
+ @logged << [payload[:sql].squish, payload[:name], payload[:binds]]
61
+ end
167
62
 
168
- handler.send(:owner_to_pool_manager).delete(name)
63
+ def finish(name, id, payload); end
169
64
  end
170
- end
171
65
 
172
- def clean_up_connection_handler
173
- handler = ActiveRecord::Base.connection_handler
174
- handler.instance_variable_get(:@owner_to_pool_manager).each do |owner, pool_manager|
175
- pool_manager.role_names.each do |role_name|
176
- next if role_name == ActiveRecord::Base.default_role
177
- pool_manager.remove_role(role_name)
178
- end
66
+ module InTimeZone
67
+ private
68
+ def in_time_zone(zone)
69
+ old_zone = Time.zone
70
+ old_tz = ActiveRecord::Base.time_zone_aware_attributes
71
+
72
+ Time.zone = zone ? ActiveSupport::TimeZone[zone] : nil
73
+ ActiveRecord::Base.time_zone_aware_attributes = !zone.nil?
74
+ yield
75
+ ensure
76
+ Time.zone = old_zone
77
+ ActiveRecord::Base.time_zone_aware_attributes = old_tz
78
+ end
179
79
  end
180
- end
181
-
182
- def load_schema
183
- # silence verbose schema loading
184
- original_stdout = $stdout
185
- $stdout = StringIO.new
186
80
 
187
- adapter_name = ActiveRecord::Base.connection.adapter_name.downcase
188
- adapter_specific_schema_file = SCHEMA_ROOT + "/#{adapter_name}_specific_schema.rb"
81
+ module WaitForAsyncTestHelper
82
+ private
83
+ def wait_for_async_query(connection = ActiveRecord::Base.lease_connection, timeout: 5)
84
+ return unless connection.async_enabled?
189
85
 
190
- load SCHEMA_ROOT + "/schema.rb"
86
+ executor = connection.pool.async_executor
87
+ (timeout * 100).times do
88
+ return unless executor.scheduled_task_count > executor.completed_task_count
89
+ sleep 0.01
90
+ end
191
91
 
192
- if File.exist?(adapter_specific_schema_file)
193
- load adapter_specific_schema_file
92
+ raise Timeout::Error, "The async executor wasn't drained after #{timeout} seconds"
93
+ end
194
94
  end
195
-
196
- ActiveRecord::FixtureSet.reset_cache
197
- ensure
198
- $stdout = original_stdout
199
95
  end
200
96
 
201
- load_schema
202
-
203
- class SQLSubscriber
204
- attr_reader :logged
205
- attr_reader :payloads
97
+ # Encryption
206
98
 
207
- def initialize
208
- @logged = []
209
- @payloads = []
210
- end
99
+ ActiveRecord::Encryption.configure \
100
+ primary_key: "test master key",
101
+ deterministic_key: "test deterministic key",
102
+ key_derivation_salt: "testing key derivation salt"
211
103
 
212
- def start(name, id, payload)
213
- @payloads << payload
214
- @logged << [payload[:sql].squish, payload[:name], payload[:binds]]
215
- end
216
-
217
- def finish(name, id, payload); end
218
- end
219
-
220
- module InTimeZone
221
- private
222
- def in_time_zone(zone)
223
- old_zone = Time.zone
224
- old_tz = ActiveRecord::Base.time_zone_aware_attributes
225
-
226
- Time.zone = zone ? ActiveSupport::TimeZone[zone] : nil
227
- ActiveRecord::Base.time_zone_aware_attributes = !zone.nil?
228
- yield
229
- ensure
230
- Time.zone = old_zone
231
- ActiveRecord::Base.time_zone_aware_attributes = old_tz
232
- end
233
- end
104
+ # Simulate https://github.com/rails/rails/blob/735cba5bed7a54c7397dfeec1bed16033ae286f8/activerecord/lib/active_record/railtie.rb#L392
105
+ ActiveRecord::Encryption.config.extend_queries = true
106
+ ActiveRecord::Encryption::ExtendedDeterministicQueries.install_support
107
+ ActiveRecord::Encryption::ExtendedDeterministicUniquenessValidator.install_support
@@ -9,7 +9,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase
9
9
 
10
10
  setup do
11
11
  @klass = Class.new(ActiveRecord::Base) do
12
- connection.create_table :hot_compatibilities, force: true do |t|
12
+ lease_connection.create_table :hot_compatibilities, force: true do |t|
13
13
  t.string :foo
14
14
  t.string :bar
15
15
  end
@@ -19,7 +19,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase
19
19
  end
20
20
 
21
21
  teardown do
22
- ActiveRecord::Base.connection.drop_table :hot_compatibilities
22
+ ActiveRecord::Base.lease_connection.drop_table :hot_compatibilities
23
23
  end
24
24
 
25
25
  test "insert after remove_column" do
@@ -30,7 +30,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase
30
30
  assert_equal 3, @klass.columns.length
31
31
 
32
32
  # remove one of them
33
- @klass.connection.remove_column :hot_compatibilities, :bar
33
+ @klass.lease_connection.remove_column :hot_compatibilities, :bar
34
34
 
35
35
  # we still have 3 columns in the cache
36
36
  assert_equal 3, @klass.columns.length
@@ -45,7 +45,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase
45
45
  test "update after remove_column" do
46
46
  record = @klass.create! foo: "foo"
47
47
  assert_equal 3, @klass.columns.length
48
- @klass.connection.remove_column :hot_compatibilities, :bar
48
+ @klass.lease_connection.remove_column :hot_compatibilities, :bar
49
49
  assert_equal 3, @klass.columns.length
50
50
 
51
51
  record.reload
@@ -56,7 +56,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase
56
56
  assert_equal "bar", record.foo
57
57
  end
58
58
 
59
- if current_adapter?(:PostgreSQLAdapter) && ActiveRecord::Base.connection.prepared_statements
59
+ if current_adapter?(:PostgreSQLAdapter) && ActiveRecord::Base.lease_connection.prepared_statements
60
60
  test "cleans up after prepared statement failure in a transaction" do
61
61
  with_two_connections do |original_connection, ddl_connection|
62
62
  record = @klass.create! bar: "bar"
@@ -66,7 +66,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase
66
66
  record.reload
67
67
  end
68
68
 
69
- assert get_prepared_statement_cache(@klass.connection).any?,
69
+ assert_predicate get_prepared_statement_cache(@klass.lease_connection), :any?,
70
70
  "expected prepared statement cache to have something in it"
71
71
 
72
72
  # add a new column
@@ -78,7 +78,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase
78
78
  end
79
79
  end
80
80
 
81
- assert_empty get_prepared_statement_cache(@klass.connection),
81
+ assert_empty get_prepared_statement_cache(@klass.lease_connection),
82
82
  "expected prepared statement cache to be empty but it wasn't"
83
83
  end
84
84
  end
@@ -92,7 +92,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase
92
92
  record.reload
93
93
  end
94
94
 
95
- assert get_prepared_statement_cache(@klass.connection).any?,
95
+ assert_predicate get_prepared_statement_cache(@klass.lease_connection), :any?,
96
96
  "expected prepared statement cache to have something in it"
97
97
 
98
98
  # add a new column
@@ -108,7 +108,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase
108
108
  end
109
109
  end
110
110
 
111
- assert_empty get_prepared_statement_cache(@klass.connection),
111
+ assert_empty get_prepared_statement_cache(@klass.lease_connection),
112
112
  "expected prepared statement cache to be empty but it wasn't"
113
113
  end
114
114
  end
@@ -136,7 +136,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase
136
136
  ActiveRecord::Base.connection_pool.checkin ddl_connection
137
137
  end
138
138
  ensure
139
- ActiveRecord::Base.clear_all_connections!
139
+ ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
140
140
  end
141
141
  end
142
142
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/inflector"
4
+ require "zeitwerk"
3
5
  require "cases/helper"
4
6
  require "models/author"
5
7
  require "models/company"
@@ -11,6 +13,7 @@ require "models/subscriber"
11
13
  require "models/vegetables"
12
14
  require "models/shop"
13
15
  require "models/sponsor"
16
+ require "models/club"
14
17
 
15
18
  module InheritanceTestHelper
16
19
  def with_store_full_sti_class(&block)
@@ -43,14 +46,8 @@ class InheritanceTest < ActiveRecord::TestCase
43
46
  def test_class_with_blank_sti_name
44
47
  company = Company.first
45
48
  company = company.dup
46
- company.extend(Module.new {
47
- def _read_attribute(name)
48
- return " " if name == "type"
49
- super
50
- end
51
- })
52
- company.save!
53
- company = Company.all.to_a.find { |x| x.id == company.id }
49
+ company.update!(type: " ")
50
+ company = Company.find(company.id)
54
51
  assert_equal " ", company.type
55
52
  end
56
53
 
@@ -73,37 +70,33 @@ class InheritanceTest < ActiveRecord::TestCase
73
70
  end
74
71
 
75
72
  def test_compute_type_no_method_error
76
- ActiveSupport::Dependencies.stub(:safe_constantize, proc { raise NoMethodError }) do
77
- assert_raises NoMethodError do
78
- Company.send :compute_type, "InvalidModel"
79
- end
80
- end
73
+ # Done via autoload because you need the exception to happen when the file
74
+ # is required.
75
+ model = "RaisesNoMethodError"
76
+ Object.autoload(model, "#{MODELS_ROOT}/#{model.underscore}")
77
+ assert_raises(NoMethodError) { Company.send(:compute_type, model) }
78
+ ensure
79
+ Object.send(:remove_const, model)
81
80
  end
82
81
 
83
82
  def test_compute_type_on_undefined_method
84
- error = nil
85
- begin
86
- Class.new(Author) do
87
- alias_method :foo, :bar
88
- end
89
- rescue => e
90
- error = e
91
- end
92
-
93
- ActiveSupport::Dependencies.stub(:safe_constantize, proc { raise e }) do
94
- exception = assert_raises NameError do
95
- Company.send :compute_type, "InvalidModel"
96
- end
97
- assert_equal error.message, exception.message
98
- end
83
+ # Done via autoload because you need the exception to happen when the file
84
+ # is required.
85
+ model = "InvokesAnUndefinedMethod"
86
+ Object.autoload(model, "#{MODELS_ROOT}/#{model.underscore}")
87
+ assert_raises(NameError) { Company.send(:compute_type, model) }
88
+ ensure
89
+ Object.send(:remove_const, model)
99
90
  end
100
91
 
101
92
  def test_compute_type_argument_error
102
- ActiveSupport::Dependencies.stub(:safe_constantize, proc { raise ArgumentError }) do
103
- assert_raises ArgumentError do
104
- Company.send :compute_type, "InvalidModel"
105
- end
106
- end
93
+ # Done via autoload because you need the exception to happen when the file
94
+ # is required.
95
+ model = "RaisesArgumentError"
96
+ Object.autoload(model, "#{MODELS_ROOT}/#{model.underscore}")
97
+ assert_raises(ArgumentError) { Company.send(:compute_type, model) }
98
+ ensure
99
+ Object.send(:remove_const, model)
107
100
  end
108
101
 
109
102
  def test_should_store_demodulized_class_name_with_store_full_sti_class_option_disabled
@@ -160,8 +153,8 @@ class InheritanceTest < ActiveRecord::TestCase
160
153
 
161
154
  def test_company_descends_from_active_record
162
155
  assert_not_predicate ActiveRecord::Base, :descends_from_active_record?
163
- assert AbstractCompany.descends_from_active_record?, "AbstractCompany should descend from ActiveRecord::Base"
164
- assert Company.descends_from_active_record?, "Company should descend from ActiveRecord::Base"
156
+ assert_predicate AbstractCompany, :descends_from_active_record?, "AbstractCompany should descend from ActiveRecord::Base"
157
+ assert_predicate Company, :descends_from_active_record?, "Company should descend from ActiveRecord::Base"
165
158
  assert_not Class.new(Company).descends_from_active_record?, "Company subclass should not descend from ActiveRecord::Base"
166
159
  end
167
160
 
@@ -196,12 +189,13 @@ class InheritanceTest < ActiveRecord::TestCase
196
189
  end
197
190
 
198
191
  def test_base_class_activerecord_error
199
- klass = Class.new { include ActiveRecord::Inheritance }
200
- assert_raise(ActiveRecord::ActiveRecordError) { klass.base_class }
192
+ assert_raise(ActiveRecord::ActiveRecordError) do
193
+ Class.new { include ActiveRecord::Inheritance }
194
+ end
201
195
  end
202
196
 
203
197
  def test_a_bad_type_column
204
- Company.connection.insert "INSERT INTO companies (id, #{QUOTED_TYPE}, name) VALUES(100, 'bad_class!', 'Not happening')"
198
+ Company.lease_connection.insert "INSERT INTO companies (id, #{QUOTED_TYPE}, name) VALUES(100, 'bad_class!', 'Not happening')"
205
199
 
206
200
  assert_raise(ActiveRecord::SubclassNotFound) { Company.find(100) }
207
201
  end
@@ -382,13 +376,15 @@ class InheritanceTest < ActiveRecord::TestCase
382
376
 
383
377
  def test_new_with_autoload_paths
384
378
  path = File.expand_path("../models/autoloadable", __dir__)
385
- ActiveSupport::Dependencies.autoload_paths << path
386
-
387
- firm = Company.new(type: "ExtraFirm")
388
- assert_equal ExtraFirm, firm.class
389
- ensure
390
- ActiveSupport::Dependencies.autoload_paths.reject! { |p| p == path }
391
- ActiveSupport::Dependencies.clear
379
+ Zeitwerk.with_loader do |loader|
380
+ loader.push_dir(path)
381
+ loader.setup
382
+
383
+ firm = Company.new(type: "ExtraFirm")
384
+ assert_equal ExtraFirm, firm.class
385
+ ensure
386
+ loader.unload
387
+ end
392
388
  end
393
389
 
394
390
  def test_inheritance_condition
@@ -472,18 +468,17 @@ class InheritanceTest < ActiveRecord::TestCase
472
468
 
473
469
  def test_eager_load_belongs_to_something_inherited
474
470
  account = Account.all.merge!(includes: :firm).find(1)
475
- assert account.association(:firm).loaded?, "association was not eager loaded"
471
+ assert_predicate account.association(:firm), :loaded?, "association was not eager loaded"
476
472
  end
477
473
 
478
474
  def test_alt_eager_loading
479
475
  cabbage = RedCabbage.all.merge!(includes: :seller).find(4)
480
- assert cabbage.association(:seller).loaded?, "association was not eager loaded"
476
+ assert_predicate cabbage.association(:seller), :loaded?, "association was not eager loaded"
481
477
  end
482
478
 
483
479
  def test_eager_load_belongs_to_primary_key_quoting
484
- c = Account.connection
485
480
  bind_param = Arel::Nodes::BindParam.new(nil)
486
- assert_sql(/#{Regexp.escape(c.quote_table_name("companies.id"))} = (?:#{Regexp.escape(bind_param.to_sql)}|1)/i) do
481
+ assert_queries_match(/#{Regexp.escape(quote_table_name("companies.id"))} = (?:#{Regexp.escape(bind_param.to_sql)}|1)/i) do
487
482
  Account.all.merge!(includes: :firm).find(1)
488
483
  end
489
484
  end
@@ -548,7 +543,7 @@ class InheritanceComputeTypeTest < ActiveRecord::TestCase
548
543
 
549
544
  def test_inheritance_new_with_subclass_as_default
550
545
  original_type = Company.columns_hash["type"].default
551
- ActiveRecord::Base.connection.change_column_default :companies, :type, "Firm"
546
+ ActiveRecord::Base.lease_connection.change_column_default :companies, :type, "Firm"
552
547
  Company.reset_column_information
553
548
 
554
549
  firm = Company.new # without arguments
@@ -567,7 +562,7 @@ class InheritanceComputeTypeTest < ActiveRecord::TestCase
567
562
  assert_equal "Client", firm.type
568
563
  assert_instance_of Client, firm
569
564
  ensure
570
- ActiveRecord::Base.connection.change_column_default :companies, :type, original_type
565
+ ActiveRecord::Base.lease_connection.change_column_default :companies, :type, original_type
571
566
  Company.reset_column_information
572
567
  end
573
568
  end
@@ -597,17 +592,10 @@ end
597
592
 
598
593
  class InheritanceAttributeMappingTest < ActiveRecord::TestCase
599
594
  setup do
600
- @old_registry = ActiveRecord::Type.registry
601
- ActiveRecord::Type.registry = ActiveRecord::Type.registry.dup
602
- ActiveRecord::Type.register :omg_sti, InheritanceAttributeMappingTest::OmgStiType
603
595
  Company.delete_all
604
596
  Sponsor.delete_all
605
597
  end
606
598
 
607
- teardown do
608
- ActiveRecord::Type.registry = @old_registry
609
- end
610
-
611
599
  class OmgStiType < ActiveRecord::Type::String
612
600
  def cast_value(value)
613
601
  if value =~ /\Aomg_(.+)\z/
@@ -624,6 +612,8 @@ class InheritanceAttributeMappingTest < ActiveRecord::TestCase
624
612
  end
625
613
  end
626
614
 
615
+ ActiveRecord::Type.register :omg_sti, OmgStiType
616
+
627
617
  class Company < ActiveRecord::Base
628
618
  self.table_name = "companies"
629
619
  attribute :type, :omg_sti
@@ -644,7 +634,7 @@ class InheritanceAttributeMappingTest < ActiveRecord::TestCase
644
634
  Empire.create! name: "an Empire"
645
635
 
646
636
  assert_equal [["a Startup", "omg_inheritance_attribute_mapping_test/startup"],
647
- ["an Empire", "omg_inheritance_attribute_mapping_test/empire"]], ActiveRecord::Base.connection.select_rows("SELECT name, type FROM companies").sort
637
+ ["an Empire", "omg_inheritance_attribute_mapping_test/empire"]], ActiveRecord::Base.lease_connection.select_rows("SELECT name, type FROM companies").sort
648
638
  assert_equal [["a Startup", "InheritanceAttributeMappingTest::Startup"],
649
639
  ["an Empire", "InheritanceAttributeMappingTest::Empire"]], Company.all.map { |a| [a.name, a.type] }.sort
650
640
 
@@ -653,7 +643,7 @@ class InheritanceAttributeMappingTest < ActiveRecord::TestCase
653
643
  startup.save!
654
644
 
655
645
  assert_equal [["a Startup", "omg_inheritance_attribute_mapping_test/empire"],
656
- ["an Empire", "omg_inheritance_attribute_mapping_test/empire"]], ActiveRecord::Base.connection.select_rows("SELECT name, type FROM companies").sort
646
+ ["an Empire", "omg_inheritance_attribute_mapping_test/empire"]], ActiveRecord::Base.lease_connection.select_rows("SELECT name, type FROM companies").sort
657
647
 
658
648
  assert_equal [["a Startup", "InheritanceAttributeMappingTest::Empire"],
659
649
  ["an Empire", "InheritanceAttributeMappingTest::Empire"]], Company.all.map { |a| [a.name, a.type] }.sort
@@ -663,7 +653,7 @@ class InheritanceAttributeMappingTest < ActiveRecord::TestCase
663
653
  startup = Startup.create! name: "a Startup"
664
654
  sponsor = Sponsor.create! sponsorable: startup
665
655
 
666
- assert_equal ["omg_inheritance_attribute_mapping_test/company"], ActiveRecord::Base.connection.select_values("SELECT sponsorable_type FROM sponsors")
656
+ assert_equal ["omg_inheritance_attribute_mapping_test/company"], ActiveRecord::Base.lease_connection.select_values("SELECT sponsorable_type FROM sponsors")
667
657
 
668
658
  sponsor = Sponsor.find(sponsor.id)
669
659
  assert_equal startup, sponsor.sponsorable
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+
5
+ module Inherited
6
+ # When running the test with `RAILS_STRICT_WARNINGS` enabled, the `belongs_to`
7
+ # call should not emit a warning that the constant `GeneratedAssociationMethods`
8
+ # is already defined.
9
+ class Person < ActiveRecord::Base; end
10
+
11
+ class Device < ActiveRecord::Base
12
+ def self.inherited(subclass)
13
+ subclass.belongs_to :person, inverse_of: subclass.name.demodulize.tableize.to_sym
14
+ subclass.filter_attributes = [:secret_attribute, :"#{subclass.name.demodulize.downcase}_key"]
15
+ super
16
+ end
17
+ end
18
+
19
+ class Computer < Device; end
20
+
21
+ class Vehicle < ActiveRecord::Base
22
+ def self.inherited(subclass)
23
+ super
24
+ subclass.belongs_to :person, inverse_of: subclass.name.demodulize.tableize.to_sym
25
+ subclass.filter_attributes = [:secret_attribute, :"#{subclass.name.demodulize.downcase}_key"]
26
+ end
27
+ end
28
+
29
+ class Car < Vehicle; end
30
+ end
31
+
32
+ class InheritedTest < ActiveRecord::TestCase
33
+ def test_super_before_filter_attributes
34
+ assert_equal %i[secret_attribute car_key], Inherited::Car.filter_attributes
35
+ end
36
+
37
+ def test_super_after_filter_attributes
38
+ assert_equal %i[secret_attribute computer_key], Inherited::Computer.filter_attributes
39
+ end
40
+ end