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
@@ -3,6 +3,7 @@
3
3
  require "cases/helper"
4
4
  require "models/topic"
5
5
  require "models/customer"
6
+ require "models/comment"
6
7
  require "models/company"
7
8
  require "models/company_in_module"
8
9
  require "models/ship"
@@ -26,6 +27,12 @@ require "models/department"
26
27
  require "models/cake_designer"
27
28
  require "models/drink_designer"
28
29
  require "models/recipe"
30
+ require "models/user_with_invalid_relation"
31
+ require "models/hardback"
32
+ require "models/sharded/comment"
33
+ require "models/admin"
34
+ require "models/admin/user"
35
+ require "models/user"
29
36
 
30
37
  class ReflectionTest < ActiveRecord::TestCase
31
38
  include ActiveRecord::Reflection
@@ -43,25 +50,25 @@ class ReflectionTest < ActiveRecord::TestCase
43
50
 
44
51
  def test_read_attribute_names
45
52
  assert_equal(
46
- %w( id title author_name author_email_address bonus_time written_on last_read content important group approved replies_count unique_replies_count parent_id parent_title type created_at updated_at ).sort,
53
+ %w( id title author_name author_email_address bonus_time written_on last_read content important binary_content group approved replies_count unique_replies_count parent_id parent_title type created_at updated_at ).sort,
47
54
  @first.attribute_names.sort
48
55
  )
49
56
  end
50
57
 
51
58
  def test_columns
52
- assert_equal 18, Topic.columns.length
59
+ assert_equal 19, Topic.columns.length
53
60
  end
54
61
 
55
62
  def test_columns_are_returned_in_the_order_they_were_declared
56
63
  column_names = Topic.columns.map(&:name)
57
- assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content important approved replies_count unique_replies_count parent_id parent_title type group created_at updated_at), column_names
64
+ assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content important binary_content approved replies_count unique_replies_count parent_id parent_title type group created_at updated_at), column_names
58
65
  end
59
66
 
60
67
  def test_content_columns
61
68
  content_columns = Topic.content_columns
62
69
  content_column_names = content_columns.map(&:name)
63
- assert_equal 13, content_columns.length
64
- assert_equal %w(title author_name author_email_address written_on bonus_time last_read content important group approved parent_title created_at updated_at).sort, content_column_names.sort
70
+ assert_equal 14, content_columns.length
71
+ assert_equal %w(title author_name author_email_address written_on bonus_time last_read content important binary_content group approved parent_title created_at updated_at).sort, content_column_names.sort
65
72
  end
66
73
 
67
74
  def test_column_string_type_and_limit
@@ -137,6 +144,82 @@ class ReflectionTest < ActiveRecord::TestCase
137
144
  assert_equal "PluralIrregular", reflection.class_name
138
145
  end
139
146
 
147
+ def test_reflection_klass_not_found_with_no_class_name_option
148
+ error = assert_raise(NameError) do
149
+ UserWithInvalidRelation.reflect_on_association(:not_a_class).klass
150
+ end
151
+
152
+ assert_equal "NotAClass", error.name
153
+ assert_match %r/missing/i, error.message
154
+ assert_match "NotAClass", error.message
155
+ assert_match "UserWithInvalidRelation#not_a_class", error.message
156
+ assert_match ":class_name", error.message
157
+ end
158
+
159
+ def test_reflection_klass_not_found_with_pointer_to_non_existent_class_name
160
+ error = assert_raise(NameError) do
161
+ UserWithInvalidRelation.reflect_on_association(:class_name_provided_not_a_class).klass
162
+ end
163
+
164
+ assert_equal "NotAClass", error.name
165
+ assert_match %r/missing/i, error.message
166
+ assert_match %r/\bNotAClass\b/, error.message
167
+ assert_match "UserWithInvalidRelation#class_name_provided_not_a_class", error.message
168
+ assert_no_match ":class_name", error.message
169
+ end
170
+
171
+ def test_reflection_klass_requires_ar_subclass
172
+ [ :account_invalid, # has_one, without :class_name
173
+ :account_class_name, # has_one, with :class_name
174
+ :info_invalids, # has_many through, without :class_name
175
+ :infos_class_name, # has_many through, with :class_name
176
+ :infos_through_class_name, # has_many through other :class_name, with :class_name
177
+ ].each do |rel|
178
+ error = assert_raise(ArgumentError) do
179
+ UserWithInvalidRelation.reflect_on_association(rel).klass
180
+ end
181
+
182
+ assert_match "not an ActiveRecord::Base subclass", error.message
183
+ assert_match "UserWithInvalidRelation##{rel}", error.message
184
+ end
185
+ end
186
+
187
+ def test_reflection_klass_with_same_demodularized_name
188
+ reflection = ActiveRecord::Reflection.create(
189
+ :has_one,
190
+ :user,
191
+ nil,
192
+ {},
193
+ Admin::User
194
+ )
195
+
196
+ assert_equal User, reflection.klass
197
+ end
198
+
199
+ def test_reflection_klass_with_same_demodularized_different_modularized_name
200
+ reflection = ActiveRecord::Reflection.create(
201
+ :has_one,
202
+ :user,
203
+ nil,
204
+ { class_name: "Nested::User" },
205
+ Admin::User
206
+ )
207
+
208
+ assert_equal Nested::User, reflection.klass
209
+ end
210
+
211
+ def test_reflection_klass_with_same_modularized_name
212
+ reflection = ActiveRecord::Reflection.create(
213
+ :has_many,
214
+ :nested_users,
215
+ nil,
216
+ {},
217
+ Nested::NestedUser
218
+ )
219
+
220
+ assert_equal Nested::NestedUser, reflection.klass
221
+ end
222
+
140
223
  def test_aggregation_reflection
141
224
  reflection_for_address = AggregateReflection.new(
142
225
  :address, nil, { mapping: [ %w(address_street street), %w(address_city city), %w(address_country country) ] }, Customer
@@ -246,7 +329,7 @@ class ReflectionTest < ActiveRecord::TestCase
246
329
  end
247
330
 
248
331
  def test_reflections_should_return_keys_as_strings
249
- assert Category.reflections.keys.all? { |key| key.is_a? String }, "Model.reflections is expected to return string for keys"
332
+ assert Category.reflections.keys.all?(String), "Model.reflections is expected to return string for keys"
250
333
  end
251
334
 
252
335
  def test_has_and_belongs_to_many_reflection
@@ -283,7 +366,7 @@ class ReflectionTest < ActiveRecord::TestCase
283
366
  assert_equal 2, hotel.chefs.count
284
367
  end
285
368
 
286
- def test_scope_chain_does_not_interfere_with_hmt_with_polymorphic_case_and_sti
369
+ def test_scope_chain_does_not_interfere_with_hmt_with_polymorphic_case_and_subclass_source
287
370
  hotel = Hotel.create!
288
371
  hotel.mocktail_designers << MocktailDesigner.create!
289
372
 
@@ -300,6 +383,20 @@ class ReflectionTest < ActiveRecord::TestCase
300
383
  assert_equal 0, hotel.chef_lists.count
301
384
  end
302
385
 
386
+ def test_scope_chain_does_not_interfere_with_hmt_with_polymorphic_and_subclass_source_2
387
+ author = Author.create!(name: "John Doe")
388
+ hardback = BestHardback.create!
389
+ author.best_hardbacks << hardback
390
+
391
+ assert_equal [hardback], author.best_hardbacks
392
+ assert_equal [hardback], author.reload.best_hardbacks
393
+
394
+ author.best_hardbacks = []
395
+
396
+ assert_empty author.best_hardbacks
397
+ assert_empty author.reload.best_hardbacks
398
+ end
399
+
303
400
  def test_scope_chain_of_polymorphic_association_does_not_leak_into_other_hmt_associations
304
401
  hotel = Hotel.create!
305
402
  department = hotel.departments.create!
@@ -405,6 +502,11 @@ class ReflectionTest < ActiveRecord::TestCase
405
502
  def test_foreign_key
406
503
  assert_equal "author_id", Author.reflect_on_association(:posts).foreign_key.to_s
407
504
  assert_equal "category_id", Post.reflect_on_association(:categorizations).foreign_key.to_s
505
+ assert_equal "comment_id", FirstPost.reflect_on_association(:comment_with_inverse).foreign_key.to_s
506
+ end
507
+
508
+ def test_foreign_key_is_inferred_from_model_name
509
+ assert_equal "post_id", PostRecord.reflect_on_association(:comments).foreign_key.to_s
408
510
  end
409
511
 
410
512
  def test_symbol_for_class_name
@@ -418,6 +520,13 @@ class ReflectionTest < ActiveRecord::TestCase
418
520
  assert_equal "A class was passed to `:class_name` but we are expecting a string.", error.message
419
521
  end
420
522
 
523
+ def test_class_for_source_type
524
+ error = assert_raises(ArgumentError) do
525
+ ActiveRecord::Reflection.create(:has_many, :tagged_posts, nil, { through: :taggings, source: :taggable, source_type: Post }, Tag)
526
+ end
527
+ assert_equal "A class was passed to `:source_type` but we are expecting a string.", error.message
528
+ end
529
+
421
530
  def test_join_table
422
531
  category = Struct.new(:table_name, :pluralize_table_names).new("categories", true)
423
532
  product = Struct.new(:table_name, :pluralize_table_names).new("products", true)
@@ -500,13 +609,102 @@ class ReflectionTest < ActiveRecord::TestCase
500
609
 
501
610
  def test_reflect_on_association_accepts_symbols
502
611
  assert_nothing_raised do
503
- assert_equal Hotel.reflect_on_association(:departments).name, :departments
612
+ assert_equal :departments, Hotel.reflect_on_association(:departments).name
504
613
  end
505
614
  end
506
615
 
507
616
  def test_reflect_on_association_accepts_strings
508
617
  assert_nothing_raised do
509
- assert_equal Hotel.reflect_on_association("departments").name, :departments
618
+ assert_equal :departments, Hotel.reflect_on_association("departments").name
619
+ end
620
+ end
621
+
622
+ def test_reflect_on_missing_source_assocation
623
+ assert_nothing_raised do
624
+ assert_nil Hotel.reflect_on_association(:lost_items).source_reflection
625
+ end
626
+ end
627
+
628
+ def test_reflect_on_missing_source_assocation_raise_exception
629
+ assert_raises(ActiveRecord::HasManyThroughSourceAssociationNotFoundError) do
630
+ Hotel.reflect_on_association(:lost_items).check_validity!
631
+ end
632
+ end
633
+
634
+ def test_name_error_from_incidental_code_is_not_converted_to_name_error_for_association
635
+ UserWithInvalidRelation.stub(:const_missing, proc { oops }) do
636
+ reflection = UserWithInvalidRelation.reflect_on_association(:not_a_class)
637
+
638
+ error = assert_raises(NameError) do
639
+ reflection.klass
640
+ end
641
+
642
+ assert_equal :oops, error.name
643
+ assert_match "oops", error.message
644
+ assert_no_match "NotAClass", error.message
645
+ assert_no_match "not_a_class", error.message
646
+ end
647
+ end
648
+
649
+ def test_automatic_inverse_suppresses_name_error_for_association
650
+ reflection = UserWithInvalidRelation.reflect_on_association(:not_a_class)
651
+ assert_not reflection.dup.has_inverse? # dup to prevent global memoization
652
+ end
653
+
654
+ def test_automatic_inverse_does_not_suppress_name_error_from_incidental_code
655
+ UserWithInvalidRelation.stub(:const_missing, proc { oops }) do
656
+ reflection = UserWithInvalidRelation.reflect_on_association(:not_a_class)
657
+
658
+ error = assert_raises(NameError) do
659
+ reflection.dup.has_inverse? # dup to prevent global memoization
660
+ end
661
+
662
+ assert_equal :oops, error.name
663
+ assert_match "oops", error.message
664
+ assert_no_match "NotAClass", error.message
665
+ assert_no_match "not_a_class", error.message
666
+ end
667
+ end
668
+
669
+ def test_association_primary_key_uses_explicit_primary_key_option_as_first_priority
670
+ actual = Sharded::Comment.reflect_on_association(:blog_post_by_id).association_primary_key
671
+ assert_equal "id", actual
672
+ end
673
+
674
+ def test_belongs_to_reflection_with_query_constraints_infers_correct_foreign_key
675
+ blog_foreign_key = Sharded::Comment.reflect_on_association(:blog).foreign_key
676
+ blog_post_foreign_key = Sharded::Comment.reflect_on_association(:blog_post).foreign_key
677
+
678
+ assert_equal "blog_id", blog_foreign_key
679
+ assert_equal ["blog_id", "blog_post_id"], blog_post_foreign_key
680
+ end
681
+
682
+ def test_using_query_constraints_warns_about_changing_behavior
683
+ has_many_expected_message = <<~MSG.squish
684
+ Setting `query_constraints:` option on `Firm.has_many :clients` is not allowed.
685
+ To get the same behavior, use the `foreign_key` option instead.
686
+ MSG
687
+
688
+ assert_raises(ActiveRecord::ConfigurationError, match: has_many_expected_message) do
689
+ ActiveRecord::Reflection.create(:has_many, :clients, nil, { query_constraints: [:firm_id, :firm_name] }, Firm)
690
+ end
691
+
692
+ has_one_expected_message = <<~MSG.squish
693
+ Setting `query_constraints:` option on `Firm.has_one :account` is not allowed.
694
+ To get the same behavior, use the `foreign_key` option instead.
695
+ MSG
696
+
697
+ assert_raises(ActiveRecord::ConfigurationError, match: has_one_expected_message) do
698
+ ActiveRecord::Reflection.create(:has_one, :account, nil, { query_constraints: [:firm_id, :firm_name] }, Firm)
699
+ end
700
+
701
+ belongs_to_expected_message = <<~MSG.squish
702
+ Setting `query_constraints:` option on `Firm.belongs_to :client` is not allowed.
703
+ To get the same behavior, use the `foreign_key` option instead.
704
+ MSG
705
+
706
+ assert_raises(ActiveRecord::ConfigurationError, match: belongs_to_expected_message) do
707
+ ActiveRecord::Reflection.create(:belongs_to, :client, nil, { query_constraints: [:firm_id, :firm_name] }, Firm)
510
708
  end
511
709
  end
512
710
 
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "models/author"
5
+
6
+ module ActiveRecord
7
+ class AndTest < ActiveRecord::TestCase
8
+ fixtures :authors, :author_addresses
9
+
10
+ def test_and
11
+ david, mary, bob = authors(:david, :mary, :bob)
12
+
13
+ david_and_mary = Author.where(id: [david, mary]).order(:id)
14
+ mary_and_bob = Author.where(id: [mary, bob]).order(:id)
15
+
16
+ assert_equal [mary], david_and_mary.and(mary_and_bob)
17
+ end
18
+
19
+ def test_and_with_non_relation_attribute
20
+ hash = { "id" => 123 }
21
+ error = assert_raises(ArgumentError) do
22
+ Author.and(hash)
23
+ end
24
+
25
+ assert_equal(
26
+ "You have passed Hash object to #and. Pass an ActiveRecord::Relation object instead.",
27
+ error.message
28
+ )
29
+ end
30
+
31
+ def test_and_with_structurally_incompatible_scope
32
+ posts_scope = Author.unscope(:order).limit(10).offset(10).select(:id).order(:id)
33
+ error = assert_raises(ArgumentError) do
34
+ Author.limit(10).select(:id).order(:name).and(posts_scope)
35
+ end
36
+
37
+ assert_equal(
38
+ "Relation passed to #and must be structurally compatible. Incompatible values: [:order, :offset]",
39
+ error.message
40
+ )
41
+ end
42
+ end
43
+ end
@@ -3,7 +3,8 @@
3
3
  require "cases/helper"
4
4
  require "models/post"
5
5
  require "models/comment"
6
- require "active_support/core_ext/symbol/starts_ends_with"
6
+ require "models/project"
7
+ require "models/developer"
7
8
 
8
9
  module ActiveRecord
9
10
  module DelegationTests
@@ -14,7 +15,8 @@ module ActiveRecord
14
15
  :map, :none?, :one?, :partition, :reject, :reverse, :rotate,
15
16
  :sample, :second, :sort, :sort_by, :slice, :third, :index, :rindex,
16
17
  :to_ary, :to_set, :to_xml, :to_yaml, :join,
17
- :in_groups, :in_groups_of, :to_sentence, :to_formatted_s, :as_json
18
+ :in_groups, :in_groups_of, :to_sentence, :to_formatted_s, :to_fs, :as_json,
19
+ :intersect?
18
20
  ]
19
21
 
20
22
  ARRAY_DELEGATES.each do |method|
@@ -44,6 +46,14 @@ module ActiveRecord
44
46
  end
45
47
  end
46
48
 
49
+ class DelegationRecordsTest < ActiveRecord::TestCase
50
+ include DelegationTests
51
+
52
+ def target
53
+ Comment.all.records
54
+ end
55
+ end
56
+
47
57
  class QueryingMethodsDelegationTest < ActiveRecord::TestCase
48
58
  QUERYING_METHODS =
49
59
  ActiveRecord::Batches.public_instance_methods(false) +
@@ -51,13 +61,14 @@ module ActiveRecord
51
61
  ActiveRecord::FinderMethods.public_instance_methods(false) - [:include?, :member?, :raise_record_not_found_exception!] +
52
62
  ActiveRecord::SpawnMethods.public_instance_methods(false) - [:spawn, :merge!] +
53
63
  ActiveRecord::QueryMethods.public_instance_methods(false).reject { |method|
54
- method.end_with?("=", "!", "value", "values", "clause")
55
- } - [:reverse_order, :arel, :extensions, :construct_join_dependency] + [
64
+ method.end_with?("=", "!", "?", "value", "values", "clause")
65
+ } - [:all, :reverse_order, :arel, :extensions, :construct_join_dependency] + [
56
66
  :any?, :many?, :none?, :one?,
57
67
  :first_or_create, :first_or_create!, :first_or_initialize,
58
68
  :find_or_create_by, :find_or_create_by!, :find_or_initialize_by,
59
69
  :create_or_find_by, :create_or_find_by!,
60
- :destroy_all, :delete_all, :update_all, :touch_all, :delete_by, :destroy_by
70
+ :destroy, :destroy_all, :delete, :delete_all, :update_all, :touch_all, :delete_by, :destroy_by,
71
+ :insert, :insert_all, :insert!, :insert_all!, :upsert, :upsert_all,
61
72
  ]
62
73
 
63
74
  def test_delegate_querying_methods
@@ -73,4 +84,20 @@ module ActiveRecord
73
84
  end
74
85
  end
75
86
  end
87
+
88
+ class DelegationCachingTest < ActiveRecord::TestCase
89
+ fixtures :projects, :developers
90
+
91
+ test "delegation doesn't override methods defined in other relation subclasses" do
92
+ # precondition, some methods are available on ActiveRecord::Relation subclasses
93
+ # but not ActiveRecord::Relation itself. Here `target` is just an example.
94
+ assert_equal false, ActiveRecord::Relation.method_defined?(:target)
95
+ assert_equal true, ActiveRecord::Associations::CollectionProxy.method_defined?(:target)
96
+
97
+ project = projects(:active_record)
98
+ original_owner = project.developers_with_callbacks.method(:target).owner
99
+ assert_equal :__target__, Developer.all.target
100
+ assert_equal original_owner, project.developers_with_callbacks.method(:target).owner
101
+ end
102
+ end
76
103
  end
@@ -5,9 +5,11 @@ require "models/author"
5
5
  require "models/post"
6
6
  require "models/pet"
7
7
  require "models/toy"
8
+ require "models/comment"
9
+ require "models/cpk"
8
10
 
9
11
  class DeleteAllTest < ActiveRecord::TestCase
10
- fixtures :authors, :author_addresses, :posts, :pets, :toys
12
+ fixtures :authors, :author_addresses, :comments, :posts, :pets, :toys, :cpk_orders, :cpk_order_agreements
11
13
 
12
14
  def test_destroy_all
13
15
  davids = Author.where(name: "David")
@@ -53,10 +55,23 @@ class DeleteAllTest < ActiveRecord::TestCase
53
55
  assert_predicate davids, :loaded?
54
56
  end
55
57
 
58
+ def test_delete_all_with_group_by_and_having
59
+ minimum_comments_count = 2
60
+ posts_to_be_deleted = Post.most_commented(minimum_comments_count).all.to_a
61
+ assert_operator posts_to_be_deleted.length, :>, 0
62
+
63
+ assert_difference("Post.count", -posts_to_be_deleted.length) do
64
+ Post.most_commented(minimum_comments_count).delete_all
65
+ end
66
+
67
+ posts_to_be_deleted.each do |deleted_post|
68
+ assert_raise(ActiveRecord::RecordNotFound) { deleted_post.reload }
69
+ end
70
+ end
71
+
56
72
  def test_delete_all_with_unpermitted_relation_raises_error
57
73
  assert_raises(ActiveRecord::ActiveRecordError) { Author.distinct.delete_all }
58
- assert_raises(ActiveRecord::ActiveRecordError) { Author.group(:name).delete_all }
59
- assert_raises(ActiveRecord::ActiveRecordError) { Author.having("SUM(id) < 3").delete_all }
74
+ assert_raises(ActiveRecord::ActiveRecordError) { Author.with(limited: Author.limit(2)).delete_all }
60
75
  end
61
76
 
62
77
  def test_delete_all_with_joins_and_where_part_is_hash
@@ -67,10 +82,10 @@ class DeleteAllTest < ActiveRecord::TestCase
67
82
  assert_equal pets.count, pets.delete_all
68
83
  end
69
84
 
70
- if current_adapter?(:Mysql2Adapter)
71
- assert_no_match %r/SELECT DISTINCT #{Regexp.escape(Pet.connection.quote_table_name("pets.pet_id"))}/, sqls.last
85
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
86
+ assert_no_match %r/SELECT DISTINCT #{Regexp.escape(quote_table_name("pets.pet_id"))}/, sqls.last
72
87
  else
73
- assert_match %r/SELECT #{Regexp.escape(Pet.connection.quote_table_name("pets.pet_id"))}/, sqls.last
88
+ assert_match %r/SELECT #{Regexp.escape(quote_table_name("pets.pet_id"))}/, sqls.last
74
89
  end
75
90
  end
76
91
 
@@ -114,4 +129,10 @@ class DeleteAllTest < ActiveRecord::TestCase
114
129
  assert_raise(ActiveRecord::RecordNotFound) { posts(:thinking) }
115
130
  assert posts(:welcome)
116
131
  end
132
+
133
+ def test_delete_all_composite_model_with_join_subquery
134
+ agreement = cpk_order_agreements(:order_agreement_three)
135
+ join_scope = Cpk::Order.joins(:order_agreements).where(order_agreements: { signature: agreement.signature })
136
+ assert_equal 1, join_scope.delete_all
137
+ end
117
138
  end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "models/author"
5
+ require "models/post"
6
+ require "models/book"
7
+
8
+ class FieldOrderedValuesTest < ActiveRecord::TestCase
9
+ fixtures :posts
10
+
11
+ def test_in_order_of
12
+ order = [3, 4, 1]
13
+ posts = Post.in_order_of(:id, order)
14
+
15
+ assert_equal(order, posts.map(&:id))
16
+ end
17
+
18
+ def test_in_order_of_empty
19
+ posts = Post.in_order_of(:id, [])
20
+
21
+ assert_empty(posts)
22
+ end
23
+
24
+ def test_in_order_of_with_enums_values
25
+ skip "DB2 unique index semantics treat multiple NULL values as duplicates for books fixtures" if current_adapter?(:IBM_DBAdapter)
26
+
27
+ Book.destroy_all
28
+ Book.create!(status: :proposed)
29
+ Book.create!(status: :written)
30
+ Book.create!(status: :published)
31
+
32
+ order = %w[written published proposed]
33
+ books = Book.in_order_of(:status, order)
34
+ assert_equal(order, books.map(&:status))
35
+
36
+ books = Book.in_order_of("status", order)
37
+ assert_equal(order, books.map(&:status))
38
+ end
39
+
40
+ def test_in_order_of_with_enums_keys
41
+ skip "DB2 unique index semantics treat multiple NULL values as duplicates for books fixtures" if current_adapter?(:IBM_DBAdapter)
42
+
43
+ Book.destroy_all
44
+ Book.create!(status: :proposed)
45
+ Book.create!(status: :written)
46
+ Book.create!(status: :published)
47
+
48
+ order = [Book.statuses[:written], Book.statuses[:published], Book.statuses[:proposed]]
49
+ books = Book.in_order_of(:status, order)
50
+
51
+ assert_equal(order, books.map { |book| Book.statuses[book.status] })
52
+ end
53
+
54
+ def test_in_order_of_expression
55
+ order = [3, 4, 1]
56
+ posts = Post.in_order_of(Arel.sql("id * 2"), order.map { |id| id * 2 })
57
+
58
+ assert_equal(order, posts.map(&:id))
59
+ end
60
+
61
+ def test_in_order_of_with_string_column
62
+ skip "DB2 unique index semantics treat multiple NULL values as duplicates for books fixtures" if current_adapter?(:IBM_DBAdapter)
63
+
64
+ Book.destroy_all
65
+ Book.create!(format: "paperback")
66
+ Book.create!(format: "ebook")
67
+ Book.create!(format: "hardcover")
68
+
69
+ order = %w[hardcover paperback ebook]
70
+ books = Book.in_order_of(:format, order)
71
+ assert_equal(order, books.map(&:format))
72
+
73
+ books = Book.in_order_of("format", order)
74
+ assert_equal(order, books.map(&:format))
75
+ end
76
+
77
+ def test_in_order_of_after_regular_order
78
+ order = [3, 4, 1]
79
+ posts = Post.where(type: "Post").order(:type).in_order_of(:id, order)
80
+ assert_equal(order, posts.map(&:id))
81
+
82
+ posts = Post.where(type: "Post").order(:type).in_order_of("id", order)
83
+ assert_equal(order, posts.map(&:id))
84
+ end
85
+
86
+ def test_in_order_of_with_nil
87
+ skip "DB2 unique index semantics treat multiple NULL values as duplicates for books fixtures" if current_adapter?(:IBM_DBAdapter)
88
+
89
+ Book.destroy_all
90
+ Book.create!(format: "paperback")
91
+ Book.create!(format: "ebook")
92
+ Book.create!(format: nil)
93
+
94
+ order = ["ebook", nil, "paperback"]
95
+ books = Book.in_order_of(:format, order)
96
+ assert_equal(order, books.map(&:format))
97
+
98
+ books = Book.in_order_of("format", order)
99
+ assert_equal(order, books.map(&:format))
100
+ end
101
+
102
+ def test_in_order_of_with_associations
103
+ Author.destroy_all
104
+ Book.destroy_all
105
+ john = Author.create(name: "John")
106
+ bob = Author.create(name: "Bob")
107
+ anna = Author.create(name: "Anna")
108
+
109
+ john.books.create
110
+ bob.books.create
111
+ anna.books.create
112
+
113
+ order = ["Bob", "Anna", "John"]
114
+ books = Book.joins(:author).in_order_of("authors.name", order)
115
+ assert_equal(order, books.map { |book| book.author.name })
116
+
117
+ books = Book.joins(:author).in_order_of(:"authors.name", order)
118
+ assert_equal(order, books.map { |book| book.author.name })
119
+ end
120
+
121
+ def test_in_order_of_with_filter_false
122
+ order = [3, 4, 1]
123
+ posts = Post.in_order_of(:id, order, filter: false)
124
+
125
+ assert_equal(order, posts.limit(3).map(&:id))
126
+ assert_equal(11, posts.count)
127
+ end
128
+ end