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
@@ -40,6 +40,10 @@ require "models/subscriber"
40
40
  require "models/subscription"
41
41
  require "models/zine"
42
42
  require "models/interest"
43
+ require "models/human"
44
+ require "models/sharded"
45
+ require "models/cpk"
46
+ require "models/comment_overlapping_counter_cache"
43
47
 
44
48
  class HasManyAssociationsTestForReorderWithJoinDependency < ActiveRecord::TestCase
45
49
  fixtures :authors, :author_addresses, :posts, :comments
@@ -59,7 +63,7 @@ class HasManyAssociationsTestPrimaryKeys < ActiveRecord::TestCase
59
63
  subscriber = Subscriber.new(nick: "webster132")
60
64
  assert_not_predicate subscriber.subscriptions, :loaded?
61
65
 
62
- assert_queries 1 do
66
+ assert_queries_count 1 do
63
67
  assert_equal 2, subscriber.subscriptions.size
64
68
  end
65
69
 
@@ -70,7 +74,7 @@ class HasManyAssociationsTestPrimaryKeys < ActiveRecord::TestCase
70
74
  author = Author.new(name: "David")
71
75
  assert_not_predicate author.essays, :loaded?
72
76
 
73
- assert_queries 1 do
77
+ assert_queries_count 1 do
74
78
  assert_equal 1, author.essays.size
75
79
  end
76
80
 
@@ -105,7 +109,7 @@ class HasManyAssociationsTestPrimaryKeys < ActiveRecord::TestCase
105
109
  author = Author.new
106
110
  assert_not_predicate author.essays, :loaded?
107
111
 
108
- assert_queries 0 do
112
+ assert_queries_count 0 do
109
113
  assert_equal 0, author.essays.size
110
114
  end
111
115
  end
@@ -115,7 +119,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
115
119
  fixtures :accounts, :categories, :companies, :developers, :projects,
116
120
  :developers_projects, :topics, :authors, :author_addresses, :comments,
117
121
  :posts, :readers, :taggings, :cars, :tags,
118
- :categorizations, :zines, :interests
122
+ :categorizations, :zines, :interests, :humans,
123
+ :sharded_blog_posts, :sharded_comments, :cpk_books, :cpk_authors
119
124
 
120
125
  def setup
121
126
  Client.destroyed_client_ids.clear
@@ -166,9 +171,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
166
171
  assert_equal 0, counter
167
172
  post = posts.first
168
173
  assert_equal 0, counter
169
- sql = capture_sql { post.comments.to_a }
174
+ queries = capture_sql_and_binds { post.comments.to_a }
170
175
  post.comments.reset
171
- assert_not_equal sql, capture_sql { post.comments.to_a }
176
+ assert_not_equal queries, capture_sql_and_binds { post.comments.to_a }
172
177
  end
173
178
 
174
179
  def test_has_many_build_with_options
@@ -384,7 +389,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
384
389
 
385
390
  speedometer.reload
386
391
 
387
- assert_equal ["first", "second"], speedometer.minivans.map(&:name)
392
+ assert_equal ["first", "second"], speedometer.minivans.map(&:name).sort
388
393
  assert_equal ["blue", "blue"], speedometer.minivans.map(&:color)
389
394
  end
390
395
 
@@ -398,7 +403,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
398
403
 
399
404
  speedometer.reload
400
405
 
401
- assert_equal ["first", "second"], speedometer.minivans.map(&:name)
406
+ assert_equal ["first", "second"], speedometer.minivans.map(&:name).sort
402
407
  assert_equal ["blue", "blue"], speedometer.minivans.map(&:color)
403
408
  end
404
409
 
@@ -411,7 +416,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
411
416
 
412
417
  speedometer.reload
413
418
 
414
- assert_equal ["first", "second"], speedometer.minivans.map(&:name)
419
+ assert_equal ["first", "second"], speedometer.minivans.map(&:name).sort
415
420
  assert_equal ["blue", "blue"], speedometer.minivans.map(&:color)
416
421
  end
417
422
 
@@ -424,7 +429,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
424
429
 
425
430
  speedometer.reload
426
431
 
427
- assert_equal ["first", "second"], speedometer.minivans.map(&:name)
432
+ assert_equal ["first", "second"], speedometer.minivans.map(&:name).sort
428
433
  assert_equal ["blue", "blue"], speedometer.minivans.map(&:color)
429
434
  end
430
435
 
@@ -481,7 +486,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
481
486
  self.table_name = "books"
482
487
 
483
488
  belongs_to :author
484
- enum last_read: { unread: 0, reading: 2, read: 3, forgotten: nil }
489
+ enum :last_read, { unread: 0, reading: 2, read: 3, forgotten: nil }
485
490
  end
486
491
 
487
492
  def test_association_enum_works_properly
@@ -555,14 +560,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
555
560
  company = companies(:first_firm)
556
561
  new_clients = []
557
562
 
558
- assert_queries(0) do
563
+ assert_queries_count(0) do
559
564
  new_clients << company.clients_of_firm.build(name: "Another Client")
560
565
  new_clients << company.clients_of_firm.build(name: "Another Client II")
561
566
  new_clients << company.clients_of_firm.build(name: "Another Client III")
562
567
  end
563
568
 
564
569
  assert_not_predicate company.clients_of_firm, :loaded?
565
- assert_queries(1) do
570
+ assert_queries_count(1) do
566
571
  assert_same new_clients[0], company.clients_of_firm.third
567
572
  assert_same new_clients[1], company.clients_of_firm.fourth
568
573
  assert_same new_clients[2], company.clients_of_firm.fifth
@@ -576,14 +581,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
576
581
  company = companies(:first_firm)
577
582
  new_clients = []
578
583
 
579
- assert_queries(0) do
584
+ assert_queries_count(0) do
580
585
  new_clients << company.clients_of_firm.build(name: "Another Client")
581
586
  new_clients << company.clients_of_firm.build(name: "Another Client II")
582
587
  new_clients << company.clients_of_firm.build(name: "Another Client III")
583
588
  end
584
589
 
585
590
  assert_not_predicate company.clients_of_firm, :loaded?
586
- assert_queries(1) do
591
+ assert_queries_count(1) do
587
592
  assert_same new_clients[0], company.clients_of_firm.third!
588
593
  assert_same new_clients[1], company.clients_of_firm.fourth!
589
594
  assert_same new_clients[2], company.clients_of_firm.fifth!
@@ -616,7 +621,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
616
621
  person.first_name = "Naruto"
617
622
  person.references << Reference.new
618
623
  person.save!
619
- assert_equal 1, person.references.update_all(favourite: true)
624
+ assert_equal 1, person.references.update_all(favorite: true)
620
625
  end
621
626
 
622
627
  def test_exists_respects_association_scope
@@ -726,7 +731,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
726
731
 
727
732
  def test_cant_save_has_many_readonly_association
728
733
  authors(:david).readonly_comments.each { |c| assert_raise(ActiveRecord::ReadOnlyRecord) { c.save! } }
729
- authors(:david).readonly_comments.each { |c| assert c.readonly? }
734
+ authors(:david).readonly_comments.each { |c| assert_predicate c, :readonly? }
730
735
  end
731
736
 
732
737
  def test_finding_default_orders
@@ -767,9 +772,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
767
772
  assert_equal firm.clients.count, firm.clients.update_all(description: "Great!")
768
773
  end
769
774
 
770
- def test_belongs_to_sanity
775
+ def test_belongs_to_with_new_object
771
776
  c = Client.new
772
- assert_nil c.firm, "belongs_to failed sanity check on new object"
777
+ assert_nil c.firm, "belongs_to failed on new object"
773
778
  end
774
779
 
775
780
  def test_find_ids
@@ -829,7 +834,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
829
834
 
830
835
  assert_not_predicate firm.clients, :loaded?
831
836
 
832
- assert_queries(4) do
837
+ assert_queries_count(4) do
833
838
  firm.clients.find_each(batch_size: 1) { |c| assert_equal firm.id, c.firm_id }
834
839
  end
835
840
 
@@ -839,7 +844,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
839
844
  def test_find_each_with_conditions
840
845
  firm = companies(:first_firm)
841
846
 
842
- assert_queries(2) do
847
+ assert_queries_count(2) do
843
848
  firm.clients.where(name: "Microsoft").find_each(batch_size: 1) do |c|
844
849
  assert_equal firm.id, c.firm_id
845
850
  assert_equal "Microsoft", c.name
@@ -854,7 +859,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
854
859
 
855
860
  assert_not_predicate firm.clients, :loaded?
856
861
 
857
- assert_queries(2) do
862
+ assert_queries_count(2) do
858
863
  firm.clients.find_in_batches(batch_size: 2) do |clients|
859
864
  clients.each { |c| assert_equal firm.id, c.firm_id }
860
865
  end
@@ -920,7 +925,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
920
925
  end
921
926
 
922
927
  def test_reload_with_query_cache
923
- connection = ActiveRecord::Base.connection
928
+ connection = ActiveRecord::Base.lease_connection
924
929
  connection.enable_query_cache!
925
930
  connection.clear_query_cache
926
931
 
@@ -932,17 +937,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
932
937
  assert_equal 2, connection.query_cache.size
933
938
 
934
939
  # Clear the cache and fetch the clients again, populating the cache with a query
935
- assert_queries(1) { firm.clients.reload }
940
+ assert_queries_count(1) { firm.clients.reload }
936
941
  # This query is cached, so it shouldn't make a real SQL query
937
- assert_queries(0) { firm.clients.load }
942
+ assert_queries_count(0) { firm.clients.load }
938
943
 
939
944
  assert_equal 1, connection.query_cache.size
940
945
  ensure
941
- ActiveRecord::Base.connection.disable_query_cache!
946
+ ActiveRecord::Base.lease_connection.disable_query_cache!
942
947
  end
943
948
 
944
949
  def test_reloading_unloaded_associations_with_query_cache
945
- connection = ActiveRecord::Base.connection
950
+ connection = ActiveRecord::Base.lease_connection
946
951
  connection.enable_query_cache!
947
952
  connection.clear_query_cache
948
953
 
@@ -958,7 +963,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
958
963
 
959
964
  assert_equal [client.name], firm.clients.reload.map(&:name)
960
965
  ensure
961
- ActiveRecord::Base.connection.disable_query_cache!
966
+ ActiveRecord::Base.lease_connection.disable_query_cache!
962
967
  end
963
968
 
964
969
  def test_find_all_with_include_and_conditions
@@ -1034,21 +1039,23 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1034
1039
  end
1035
1040
 
1036
1041
  def test_create_with_bang_on_has_many_when_parent_is_new_raises
1042
+ firm = Firm.new
1037
1043
  error = assert_raise(ActiveRecord::RecordNotSaved) do
1038
- firm = Firm.new
1039
1044
  firm.plain_clients.create! name: "Whoever"
1040
1045
  end
1041
1046
 
1042
1047
  assert_equal "You cannot call create unless the parent is saved", error.message
1048
+ assert_equal firm, error.record
1043
1049
  end
1044
1050
 
1045
1051
  def test_regular_create_on_has_many_when_parent_is_new_raises
1052
+ firm = Firm.new
1046
1053
  error = assert_raise(ActiveRecord::RecordNotSaved) do
1047
- firm = Firm.new
1048
1054
  firm.plain_clients.create name: "Whoever"
1049
1055
  end
1050
1056
 
1051
1057
  assert_equal "You cannot call create unless the parent is saved", error.message
1058
+ assert_equal firm, error.record
1052
1059
  end
1053
1060
 
1054
1061
  def test_create_with_bang_on_has_many_raises_when_record_not_saved
@@ -1059,11 +1066,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1059
1066
  end
1060
1067
 
1061
1068
  def test_create_with_bang_on_habtm_when_parent_is_new_raises
1069
+ developer = Developer.new("name" => "Aredridel")
1062
1070
  error = assert_raise(ActiveRecord::RecordNotSaved) do
1063
- Developer.new("name" => "Aredridel").projects.create!
1071
+ developer.projects.create!
1064
1072
  end
1065
1073
 
1066
1074
  assert_equal "You cannot call create unless the parent is saved", error.message
1075
+ assert_equal developer, error.record
1067
1076
  end
1068
1077
 
1069
1078
  def test_adding_a_mismatch_class
@@ -1097,14 +1106,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1097
1106
 
1098
1107
  def test_transactions_when_adding_to_new_record
1099
1108
  firm = Firm.new
1100
- assert_queries(0) do
1109
+ assert_queries_count(0) do
1101
1110
  firm.clients_of_firm.concat(Client.new("name" => "Natural Company"))
1102
1111
  end
1103
1112
  end
1104
1113
 
1105
1114
  def test_inverse_on_before_validate
1106
1115
  firm = companies(:first_firm)
1107
- assert_queries(1) do
1116
+ assert_queries_count(3) do
1108
1117
  firm.clients_of_firm << Client.new("name" => "Natural Company")
1109
1118
  end
1110
1119
  end
@@ -1112,7 +1121,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1112
1121
  def test_new_aliased_to_build
1113
1122
  company = companies(:first_firm)
1114
1123
 
1115
- new_client = assert_queries(0) { company.clients_of_firm.new("name" => "Another Client") }
1124
+ new_client = assert_queries_count(0) { company.clients_of_firm.new("name" => "Another Client") }
1116
1125
  assert_not_predicate company.clients_of_firm, :loaded?
1117
1126
 
1118
1127
  assert_equal "Another Client", new_client.name
@@ -1123,7 +1132,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1123
1132
  def test_build
1124
1133
  company = companies(:first_firm)
1125
1134
 
1126
- new_client = assert_queries(0) { company.clients_of_firm.build("name" => "Another Client") }
1135
+ new_client = assert_queries_count(0) { company.clients_of_firm.build("name" => "Another Client") }
1127
1136
  assert_not_predicate company.clients_of_firm, :loaded?
1128
1137
 
1129
1138
  assert_equal "Another Client", new_client.name
@@ -1181,7 +1190,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1181
1190
  def test_build_many
1182
1191
  company = companies(:first_firm)
1183
1192
 
1184
- new_clients = assert_queries(0) { company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) }
1193
+ new_clients = assert_queries_count(0) { company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) }
1185
1194
  assert_equal 2, new_clients.size
1186
1195
  end
1187
1196
 
@@ -1196,7 +1205,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1196
1205
 
1197
1206
  assert_equal 1, first_topic.replies.length
1198
1207
 
1199
- assert_queries(0) do
1208
+ assert_queries_count(0) do
1200
1209
  first_topic.replies.build(title: "Not saved", content: "Superstars")
1201
1210
  assert_equal 2, first_topic.replies.size
1202
1211
  end
@@ -1207,7 +1216,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1207
1216
  def test_build_via_block
1208
1217
  company = companies(:first_firm)
1209
1218
 
1210
- new_client = assert_queries(0) { company.clients_of_firm.build { |client| client.name = "Another Client" } }
1219
+ new_client = assert_queries_count(0) { company.clients_of_firm.build { |client| client.name = "Another Client" } }
1211
1220
  assert_not_predicate company.clients_of_firm, :loaded?
1212
1221
 
1213
1222
  assert_equal "Another Client", new_client.name
@@ -1218,7 +1227,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1218
1227
  def test_build_many_via_block
1219
1228
  company = companies(:first_firm)
1220
1229
 
1221
- new_clients = assert_queries(0) do
1230
+ new_clients = assert_queries_count(0) do
1222
1231
  company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) do |client|
1223
1232
  client.name = "changed"
1224
1233
  end
@@ -1235,7 +1244,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1235
1244
  assert_equal 2, first_firm.clients_of_firm.size
1236
1245
  first_firm.clients_of_firm.reset
1237
1246
 
1238
- assert_queries(1) do
1247
+ assert_queries_count(3) do
1239
1248
  first_firm.clients_of_firm.create(name: "Superstars")
1240
1249
  end
1241
1250
 
@@ -1282,6 +1291,40 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1282
1291
  assert_equal 0, new_firm.clients_of_firm.size
1283
1292
  end
1284
1293
 
1294
+ def test_deleting_models_with_composite_keys
1295
+ great_author = cpk_authors(:cpk_great_author)
1296
+ books = great_author.books
1297
+
1298
+ assert_equal 2, books.size
1299
+
1300
+ great_author.books.delete(books.first)
1301
+ great_author.reload
1302
+
1303
+ assert_equal 1, great_author.books.size
1304
+ end
1305
+
1306
+ def test_sharded_deleting_models
1307
+ blog_post = sharded_blog_posts(:great_post_blog_one)
1308
+ comments = blog_post.delete_comments
1309
+
1310
+ assert_equal 3, comments.size
1311
+
1312
+ comments_to_delete = [comments.first, comments.second]
1313
+
1314
+ sql = capture_sql do
1315
+ blog_post.delete_comments.delete(comments_to_delete)
1316
+ end
1317
+
1318
+ # DB2 doesn't quote composite identifiers in DELETE WHERE clauses
1319
+ expectation = /DELETE.*WHERE.* \(sharded_comments\.blog_id = .* AND sharded_comments\.id = .* OR sharded_comments\.blog_id = .* AND sharded_comments\.id = .*\)/i
1320
+
1321
+ assert_match(expectation, sql.second)
1322
+
1323
+ blog_post.reload
1324
+
1325
+ assert_equal 1, blog_post.comments.size
1326
+ end
1327
+
1285
1328
  def test_has_many_without_counter_cache_option
1286
1329
  # Ship has a conventionally named `treasures_count` column, but the counter_cache
1287
1330
  # option is not given on the association.
@@ -1290,7 +1333,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1290
1333
  assert_not_predicate Ship.reflect_on_association(:treasures), :has_cached_counter?
1291
1334
 
1292
1335
  # Count should come from sql count() of treasures rather than treasures_count attribute
1293
- assert_equal ship.treasures.size, 0
1336
+ assert_equal 0, ship.treasures.size
1294
1337
 
1295
1338
  assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed" do
1296
1339
  ship.treasures.create(name: "Gold")
@@ -1348,7 +1391,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1348
1391
  reply1 = Reply.create!(title: "re: zoom", content: "speedy quick!")
1349
1392
  reply2 = Reply.create!(title: "re: zoom 2", content: "OMG lol!")
1350
1393
 
1351
- assert_queries(4) do
1394
+ assert_queries_count(6) do
1352
1395
  topic.replies << [reply1, reply2]
1353
1396
  end
1354
1397
 
@@ -1356,6 +1399,23 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1356
1399
  assert_equal 2, topic.reload.replies_count
1357
1400
  end
1358
1401
 
1402
+ def test_counter_cache_updates_in_memory_after_create_with_overlapping_counter_cache_columns
1403
+ user = UserCommentsCount.create!
1404
+ post = PostCommentsCount.create!
1405
+
1406
+ assert_difference "user.comments_count", +1 do
1407
+ assert_no_difference "post.comments_count" do
1408
+ post.comments << CommentOverlappingCounterCache.create!(user_comments_count: user)
1409
+ end
1410
+ end
1411
+
1412
+ assert_difference "user.comments_count", +1 do
1413
+ assert_no_difference "post.comments_count" do
1414
+ user.comments << CommentOverlappingCounterCache.create!(post_comments_count: post)
1415
+ end
1416
+ end
1417
+ end
1418
+
1359
1419
  def test_counter_cache_updates_in_memory_after_update_with_inverse_of_enabled
1360
1420
  category = Category.create!(name: "Counter Cache")
1361
1421
 
@@ -1364,7 +1424,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1364
1424
  categorization1 = Categorization.create!
1365
1425
  categorization2 = Categorization.create!
1366
1426
 
1367
- assert_queries(4) do
1427
+ assert_queries_count(6) do
1368
1428
  category.categorizations << [categorization1, categorization2]
1369
1429
  end
1370
1430
 
@@ -1435,7 +1495,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1435
1495
  assert_equal original_count, topic.reload.replies_count
1436
1496
  end
1437
1497
 
1438
- def test_calling_update_changing_ids_doesnt_change_counter_cache
1498
+ def test_calling_update_changing_ids_changes_the_counter_cache
1439
1499
  topic1 = Topic.find(1)
1440
1500
  topic2 = Topic.find(3)
1441
1501
  original_count1 = topic1.replies.to_a.size
@@ -1453,6 +1513,24 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1453
1513
  assert_equal original_count2, topic2.reload.replies_count
1454
1514
  end
1455
1515
 
1516
+ def test_calling_update_changing_ids_of_inversed_association_changes_the_counter_cache
1517
+ assert_predicate Post.reflect_on_association(:comments), :has_inverse?
1518
+
1519
+ post1 = Post.first
1520
+ post2 = Post.second
1521
+
1522
+ original_count1 = post1.comments.count
1523
+ original_count2 = post2.comments.count
1524
+
1525
+ post1.comments.first.update(post_id: post2.id)
1526
+ assert_equal original_count1 - 1, post1.reload.comments_count
1527
+ assert_equal original_count2 + 1, post2.reload.comments_count
1528
+
1529
+ post2.comments.first.update(post_id: post1.id)
1530
+ assert_equal original_count1, post1.reload.comments_count
1531
+ assert_equal original_count2, post2.reload.comments_count
1532
+ end
1533
+
1456
1534
  def test_deleting_a_collection
1457
1535
  force_signal37_to_load_all_clients_of_firm
1458
1536
 
@@ -1508,7 +1586,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1508
1586
 
1509
1587
  def test_transaction_when_deleting_new_record
1510
1588
  firm = Firm.new
1511
- assert_queries(0) do
1589
+ assert_queries_count(0) do
1512
1590
  client = Client.new("name" => "New Client")
1513
1591
  firm.clients_of_firm << client
1514
1592
  firm.clients_of_firm.destroy(client)
@@ -1783,8 +1861,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1783
1861
  destroyed = companies(:first_firm).clients_of_firm.destroy_all
1784
1862
  assert_equal clients.sort_by(&:id), destroyed.sort_by(&:id)
1785
1863
  assert destroyed.all?(&:frozen?), "destroyed clients should be frozen"
1786
- assert companies(:first_firm).clients_of_firm.empty?, "37signals has no clients after destroy all"
1787
- assert companies(:first_firm).clients_of_firm.reload.empty?, "37signals has no clients after destroy all and refresh"
1864
+ assert_predicate companies(:first_firm).clients_of_firm, :empty?, "37signals has no clients after destroy all"
1865
+ assert_predicate companies(:first_firm).clients_of_firm.reload, :empty?, "37signals has no clients after destroy all and refresh"
1788
1866
  end
1789
1867
 
1790
1868
  def test_destroy_all_on_association_clears_scope
@@ -1946,6 +2024,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
1946
2024
  assert_equal true, companies(:first_firm).clients.include?(Client.find(2))
1947
2025
  end
1948
2026
 
2027
+ def test_included_in_collection_for_composite_keys
2028
+ great_author = cpk_authors(:cpk_great_author)
2029
+ book = great_author.books.first
2030
+
2031
+ assert great_author.books.include?(book)
2032
+ end
2033
+
1949
2034
  def test_included_in_collection_for_new_records
1950
2035
  client = Client.create(name: "Persisted")
1951
2036
  assert_nil client.client_of
@@ -2024,7 +2109,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2024
2109
 
2025
2110
  def test_transactions_when_replacing_on_new_record
2026
2111
  firm = Firm.new
2027
- assert_queries(0) do
2112
+ assert_queries_count(0) do
2028
2113
  firm.clients_of_firm = [Client.new("name" => "New Client")]
2029
2114
  end
2030
2115
  end
@@ -2079,7 +2164,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2079
2164
 
2080
2165
  def test_get_ids_for_association_on_new_record_does_not_try_to_find_records
2081
2166
  company = Company.new
2082
- assert_queries(0) do
2167
+ assert_queries_count(0) do
2083
2168
  company.contract_ids
2084
2169
  end
2085
2170
 
@@ -2160,7 +2245,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2160
2245
 
2161
2246
  firm.reload
2162
2247
  assert_not_predicate firm.clients, :loaded?
2163
- assert_queries(1) do
2248
+ assert_queries_count(1) do
2164
2249
  assert_equal true, firm.clients.include?(client)
2165
2250
  end
2166
2251
  assert_not_predicate firm.clients, :loaded?
@@ -2200,7 +2285,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2200
2285
  firm.clients.build(name: "Foo")
2201
2286
  assert_not_predicate firm.clients, :loaded?
2202
2287
 
2203
- assert_queries 1 do
2288
+ assert_queries_count 1 do
2204
2289
  firm.clients.first
2205
2290
  firm.clients.second
2206
2291
  firm.clients.last
@@ -2216,8 +2301,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2216
2301
 
2217
2302
  assert_not_predicate author.topics_without_type, :loaded?
2218
2303
 
2219
- assert_queries(1) do
2220
- if current_adapter?(:Mysql2Adapter, :SQLite3Adapter)
2304
+ assert_queries_count(1) do
2305
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter, :SQLite3Adapter)
2221
2306
  assert_equal fourth, author.topics_without_type.first
2222
2307
  assert_equal third, author.topics_without_type.second
2223
2308
  end
@@ -2232,7 +2317,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2232
2317
  firm.clients.create(name: "Foo")
2233
2318
  assert_not_predicate firm.clients, :loaded?
2234
2319
 
2235
- assert_queries 3 do
2320
+ assert_queries_count 3 do
2236
2321
  firm.clients.first
2237
2322
  firm.clients.second
2238
2323
  firm.clients.last
@@ -2256,7 +2341,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2256
2341
  firm.clients.create(name: "Foo")
2257
2342
  assert_not_predicate firm.clients, :loaded?
2258
2343
 
2259
- assert_queries 2 do
2344
+ assert_queries_count 2 do
2260
2345
  firm.clients.first(2)
2261
2346
  firm.clients.last(2)
2262
2347
  end
@@ -2266,7 +2351,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2266
2351
 
2267
2352
  def test_calling_many_should_count_instead_of_loading_association
2268
2353
  firm = companies(:first_firm)
2269
- assert_queries(1) do
2354
+ assert_queries_count(1) do
2270
2355
  firm.clients.many? # use count query
2271
2356
  end
2272
2357
  assert_not_predicate firm.clients, :loaded?
@@ -2275,12 +2360,20 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2275
2360
  def test_calling_many_on_loaded_association_should_not_use_query
2276
2361
  firm = companies(:first_firm)
2277
2362
  firm.clients.load # force load
2278
- assert_no_queries { assert firm.clients.many? }
2363
+ assert_no_queries { assert_predicate firm.clients, :many? }
2364
+ end
2365
+
2366
+ def test_subsequent_calls_to_many_should_use_query
2367
+ firm = companies(:first_firm)
2368
+ assert_queries_count(2) do
2369
+ firm.clients.many?
2370
+ firm.clients.many?
2371
+ end
2279
2372
  end
2280
2373
 
2281
2374
  def test_calling_many_should_defer_to_collection_if_using_a_block
2282
2375
  firm = companies(:first_firm)
2283
- assert_queries(1) do
2376
+ assert_queries_count(1) do
2284
2377
  assert_not_called(firm.clients, :size) do
2285
2378
  firm.clients.many? { true }
2286
2379
  end
@@ -2306,7 +2399,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2306
2399
 
2307
2400
  def test_calling_none_should_count_instead_of_loading_association
2308
2401
  firm = companies(:first_firm)
2309
- assert_queries(1) do
2402
+ assert_queries_count(1) do
2310
2403
  firm.clients.none? # use count query
2311
2404
  end
2312
2405
  assert_not_predicate firm.clients, :loaded?
@@ -2320,7 +2413,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2320
2413
 
2321
2414
  def test_calling_none_should_defer_to_collection_if_using_a_block
2322
2415
  firm = companies(:first_firm)
2323
- assert_queries(1) do
2416
+ assert_queries_count(1) do
2324
2417
  assert_not_called(firm.clients, :size) do
2325
2418
  firm.clients.none? { true }
2326
2419
  end
@@ -2342,7 +2435,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2342
2435
 
2343
2436
  def test_calling_one_should_count_instead_of_loading_association
2344
2437
  firm = companies(:first_firm)
2345
- assert_queries(1) do
2438
+ assert_queries_count(1) do
2346
2439
  firm.clients.one? # use count query
2347
2440
  end
2348
2441
  assert_not_predicate firm.clients, :loaded?
@@ -2354,9 +2447,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2354
2447
  assert_no_queries { assert_not firm.clients.one? }
2355
2448
  end
2356
2449
 
2450
+ def test_subsequent_calls_to_one_should_use_query
2451
+ firm = companies(:first_firm)
2452
+ assert_queries_count(2) do
2453
+ firm.clients.one?
2454
+ firm.clients.one?
2455
+ end
2456
+ end
2457
+
2357
2458
  def test_calling_one_should_defer_to_collection_if_using_a_block
2358
2459
  firm = companies(:first_firm)
2359
- assert_queries(1) do
2460
+ assert_queries_count(1) do
2360
2461
  assert_not_called(firm.clients, :size) do
2361
2462
  firm.clients.one? { true }
2362
2463
  end
@@ -2446,13 +2547,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2446
2547
 
2447
2548
  def test_attributes_are_being_set_when_initialized_from_has_many_association_with_where_clause
2448
2549
  new_comment = posts(:welcome).comments.where(body: "Some content").build
2449
- assert_equal new_comment.body, "Some content"
2550
+ assert_equal "Some content", new_comment.body
2450
2551
  end
2451
2552
 
2452
2553
  def test_attributes_are_being_set_when_initialized_from_has_many_association_with_multiple_where_clauses
2453
2554
  new_comment = posts(:welcome).comments.where(body: "Some content").where(type: "SpecialComment").build
2454
- assert_equal new_comment.body, "Some content"
2455
- assert_equal new_comment.type, "SpecialComment"
2555
+ assert_equal "Some content", new_comment.body
2556
+ assert_equal "SpecialComment", new_comment.type
2456
2557
  assert_equal new_comment.post_id, posts(:welcome).id
2457
2558
  end
2458
2559
 
@@ -2516,6 +2617,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2516
2617
  assert_equal post, image.imageable
2517
2618
  end
2518
2619
 
2620
+ def test_joining_through_a_polymorphic_association_with_a_where_clause
2621
+ writer = humans(:gordon)
2622
+ category = categories(:general)
2623
+ TypedEssay.create! category: category, writer: writer
2624
+
2625
+ assert_equal 1, Category.joins(:human_writers_of_typed_essays).count
2626
+ end
2627
+
2519
2628
  def test_build_with_polymorphic_has_many_does_not_allow_to_override_type_and_id
2520
2629
  welcome = posts(:welcome)
2521
2630
  tagging = welcome.taggings.build(taggable_id: 99, taggable_type: "ShouldNotChange")
@@ -2641,7 +2750,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2641
2750
  assert_not_predicate post.taggings_with_delete_all, :loaded?
2642
2751
 
2643
2752
  # 2 queries: one DELETE and another to update the counter cache
2644
- assert_queries(2) do
2753
+ assert_queries_count(2) do
2645
2754
  post.taggings_with_delete_all.delete_all
2646
2755
  end
2647
2756
  end
@@ -2754,7 +2863,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2754
2863
  end
2755
2864
 
2756
2865
  assert_equal [original_child], car.reload.failed_bulbs
2757
- assert_equal "Failed to destroy the record", error.message
2866
+ assert_equal "Failed to destroy FailedBulb with #{FailedBulb.primary_key}=#{original_child.id}", error.message
2758
2867
  end
2759
2868
 
2760
2869
  test "updates counter cache when default scope is given" do
@@ -2927,11 +3036,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2927
3036
 
2928
3037
  car_two = Car.create!
2929
3038
 
2930
- assert_queries(1) do
3039
+ assert_queries_count(1) do
2931
3040
  assert_equal 1, car.bulbs.size
2932
3041
  end
2933
3042
 
2934
- assert_queries(1) do
3043
+ assert_queries_count(1) do
2935
3044
  assert_equal 0, car_two.bulbs.size
2936
3045
  end
2937
3046
  end
@@ -2959,11 +3068,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
2959
3068
 
2960
3069
  car_two = Car.create!
2961
3070
 
2962
- assert_queries(1) do
3071
+ assert_queries_count(1) do
2963
3072
  assert_not_empty car.bulbs
2964
3073
  end
2965
3074
 
2966
- assert_queries(1) do
3075
+ assert_queries_count(1) do
2967
3076
  assert_empty car_two.bulbs
2968
3077
  end
2969
3078
  end
@@ -3024,7 +3133,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
3024
3133
 
3025
3134
  bulb2 = car.bulbs.create!
3026
3135
 
3027
- assert_equal [bulb.id, bulb2.id], car.bulb_ids
3136
+ assert_equal [bulb.id, bulb2.id], car.bulb_ids.sort
3028
3137
  assert_no_queries { car.bulb_ids }
3029
3138
  end
3030
3139
 
@@ -3051,6 +3160,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
3051
3160
  end
3052
3161
 
3053
3162
  def test_has_many_with_out_of_range_value
3163
+ skip "IBM DB integer primary key uses 4-byte range in this schema" if current_adapter?(:IBM_DBAdapter)
3164
+
3054
3165
  reference = Reference.create!(id: 2147483648) # out of range in the integer
3055
3166
  assert_equal [], reference.ideal_jobs
3056
3167
  end
@@ -3067,8 +3178,107 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
3067
3178
  end
3068
3179
  end
3069
3180
 
3181
+ def test_key_ensuring_owner_was_is_not_valid_without_dependent_option
3182
+ error = assert_raises(ArgumentError) do
3183
+ Class.new(ActiveRecord::Base) do
3184
+ has_many :books, ensuring_owner_was: :destroyed?
3185
+ end
3186
+ end
3187
+
3188
+ assert_match(/Unknown key: :ensuring_owner_was/, error.message)
3189
+ end
3190
+
3191
+ def test_invalid_key_raises_with_message_including_all_default_options
3192
+ error = assert_raises(ArgumentError) do
3193
+ Class.new(ActiveRecord::Base) do
3194
+ has_many :books, trough: :users
3195
+ end
3196
+ end
3197
+
3198
+ assert_equal(<<~MESSAGE.squish, error.message)
3199
+ Unknown key: :trough. Valid keys are:
3200
+ :class_name, :anonymous_class, :primary_key, :foreign_key, :dependent,
3201
+ :validate, :inverse_of, :strict_loading, :query_constraints, :autosave, :before_add,
3202
+ :after_add, :before_remove, :after_remove, :extend, :counter_cache, :join_table,
3203
+ :index_errors, :as, :through
3204
+ MESSAGE
3205
+ end
3206
+
3207
+ def test_key_ensuring_owner_was_is_valid_when_dependent_option_is_destroy_async
3208
+ assert_nothing_raised do
3209
+ Class.new(ActiveRecord::Base) do
3210
+ self.destroy_association_async_job = Class.new
3211
+
3212
+ has_many :books, dependent: :destroy_async, ensuring_owner_was: :destroyed?
3213
+ end
3214
+ end
3215
+ end
3216
+
3217
+ test "composite primary key malformed association class" do
3218
+ error = assert_raises(ActiveRecord::CompositePrimaryKeyMismatchError) do
3219
+ order = Cpk::BrokenOrder.new(id: [1, 2], books: [Cpk::Book.new(title: "Some book")])
3220
+ order.save!
3221
+ end
3222
+
3223
+ assert_equal(<<~MESSAGE.squish, error.message)
3224
+ Association Cpk::BrokenOrder#books primary key ["shop_id", "status"]
3225
+ doesn't match with foreign key broken_order_id. Please specify query_constraints, or primary_key and foreign_key values.
3226
+ MESSAGE
3227
+ end
3228
+
3229
+ test "composite primary key malformed association owner class" do
3230
+ error = assert_raises(ActiveRecord::CompositePrimaryKeyMismatchError) do
3231
+ order = Cpk::BrokenOrderWithNonCpkBooks.new(id: [1, 2], books: [Cpk::NonCpkBook.new(title: "Some book")])
3232
+ order.save!
3233
+ end
3234
+
3235
+ assert_equal(<<~MESSAGE.squish, error.message)
3236
+ Association Cpk::BrokenOrderWithNonCpkBooks#books primary key [\"shop_id\", \"status\"]
3237
+ doesn't match with foreign key broken_order_with_non_cpk_books_id. Please specify query_constraints, or primary_key and foreign_key values.
3238
+ MESSAGE
3239
+ end
3240
+
3241
+ def test_ids_reader_on_preloaded_association_with_composite_primary_key
3242
+ great_author = cpk_authors(:cpk_great_author)
3243
+
3244
+ assert_equal great_author.books.ids, Cpk::Author.preload(:books).find(great_author.id).book_ids
3245
+ end
3246
+
3070
3247
  private
3071
3248
  def force_signal37_to_load_all_clients_of_firm
3072
3249
  companies(:first_firm).clients_of_firm.load_target
3073
3250
  end
3074
3251
  end
3252
+
3253
+ class AsyncHasManyAssociationsTest < ActiveRecord::TestCase
3254
+ include WaitForAsyncTestHelper
3255
+
3256
+ self.use_transactional_tests = false
3257
+
3258
+ fixtures :companies
3259
+
3260
+ unless in_memory_db?
3261
+ def test_async_load_has_many
3262
+ firm = companies(:first_firm)
3263
+
3264
+ firm.association(:clients).async_load_target
3265
+ wait_for_async_query
3266
+
3267
+ events = []
3268
+ callback = -> (event) do
3269
+ events << event unless event.payload[:name] == "SCHEMA"
3270
+ end
3271
+
3272
+ ActiveSupport::Notifications.subscribed(callback, "sql.active_record") do
3273
+ assert_equal 3, firm.clients.size
3274
+ end
3275
+
3276
+ assert_no_queries do
3277
+ assert_not_nil firm.clients[2]
3278
+ end
3279
+
3280
+ assert_equal 1, events.size
3281
+ assert_equal true, events.first.payload[:async]
3282
+ end
3283
+ end
3284
+ end