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
@@ -36,12 +36,19 @@ require "models/family_tree"
36
36
  require "models/section"
37
37
  require "models/seminar"
38
38
  require "models/session"
39
+ require "models/sharded"
40
+ require "models/cpk"
41
+ require "models/zine"
42
+ require "models/interest"
43
+ require "models/human"
39
44
 
40
45
  class HasManyThroughAssociationsTest < ActiveRecord::TestCase
41
46
  fixtures :posts, :readers, :people, :comments, :authors, :categories, :taggings, :tags,
42
47
  :owners, :pets, :toys, :jobs, :references, :companies, :members, :author_addresses,
43
48
  :subscribers, :books, :subscriptions, :developers, :categorizations, :essays,
44
- :categories_posts, :clubs, :memberships, :organizations, :author_favorites
49
+ :categories_posts, :clubs, :memberships, :organizations, :author_favorites,
50
+ :sharded_blog_posts, :sharded_tags, :sharded_blog_posts_tags, :cpk_orders, :cpk_tags,
51
+ :cpk_order_tags
45
52
 
46
53
  # Dummies to force column loads so query counts are clean.
47
54
  def setup
@@ -217,11 +224,11 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
217
224
  post = posts(:thinking)
218
225
  person = people(:david)
219
226
 
220
- assert_queries(1) do
227
+ assert_queries_count(3) do
221
228
  post.people << person
222
229
  end
223
230
 
224
- assert_queries(1) do
231
+ assert_queries_count(1) do
225
232
  assert_includes post.people, person
226
233
  end
227
234
 
@@ -314,20 +321,20 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
314
321
  end
315
322
 
316
323
  def test_associating_new
317
- assert_queries(1) { posts(:thinking) }
324
+ assert_queries_count(1) { posts(:thinking) }
318
325
  new_person = nil # so block binding catches it
319
326
 
320
- assert_queries(0) do
327
+ assert_queries_count(0) do
321
328
  new_person = Person.new first_name: "bob"
322
329
  end
323
330
 
324
331
  # Associating new records always saves them
325
332
  # Thus, 1 query for the new person record, 1 query for the new join table record
326
- assert_queries(2) do
333
+ assert_queries_count(4) do
327
334
  posts(:thinking).people << new_person
328
335
  end
329
336
 
330
- assert_queries(1) do
337
+ assert_queries_count(1) do
331
338
  assert_includes posts(:thinking).people, new_person
332
339
  end
333
340
 
@@ -335,15 +342,15 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
335
342
  end
336
343
 
337
344
  def test_associate_new_by_building
338
- assert_queries(1) { posts(:thinking) }
345
+ assert_queries_count(1) { posts(:thinking) }
339
346
 
340
- assert_queries(0) do
347
+ assert_queries_count(0) do
341
348
  posts(:thinking).people.build(first_name: "Bob")
342
349
  posts(:thinking).people.new(first_name: "Ted")
343
350
  end
344
351
 
345
352
  # Should only need to load the association once
346
- assert_queries(1) do
353
+ assert_queries_count(1) do
347
354
  assert_includes posts(:thinking).people.collect(&:first_name), "Bob"
348
355
  assert_includes posts(:thinking).people.collect(&:first_name), "Ted"
349
356
  end
@@ -351,7 +358,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
351
358
  # 2 queries for each new record (1 to save the record itself, 1 for the join model)
352
359
  # * 2 new records = 4
353
360
  # + 1 query to save the actual post = 5
354
- assert_queries(5) do
361
+ assert_queries_count(7) do
355
362
  posts(:thinking).body += "-changed"
356
363
  posts(:thinking).save
357
364
  end
@@ -403,13 +410,13 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
403
410
  end
404
411
 
405
412
  def test_delete_association
406
- assert_queries(2) { posts(:welcome); people(:michael); }
413
+ assert_queries_count(2) { posts(:welcome); people(:michael) }
407
414
 
408
- assert_queries(1) do
415
+ assert_queries_count(3) do
409
416
  posts(:welcome).people.delete(people(:michael))
410
417
  end
411
418
 
412
- assert_queries(1) do
419
+ assert_queries_count(1) do
413
420
  assert_empty posts(:welcome).people
414
421
  end
415
422
 
@@ -438,6 +445,31 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
438
445
  assert_empty posts(:welcome).people.reload
439
446
  end
440
447
 
448
+ def test_destroy_all_on_composite_primary_key_model
449
+ tag = cpk_tags(:cpk_tag_loyal_customer)
450
+
451
+ assert_not_empty(tag.orders.to_a)
452
+
453
+ tag.orders.destroy_all
454
+ assert_empty(tag.orders)
455
+ assert_empty(tag.orders.reload)
456
+ end
457
+
458
+ def test_composite_primary_key_join_table
459
+ order = Cpk::Order.create(shop_id: 1, status: "open")
460
+ tag = cpk_tags(:cpk_tag_loyal_customer)
461
+
462
+ order_tag = Cpk::OrderTag.create(order_id: order.id_value, tag_id: tag.id, attached_by: "Nikita")
463
+
464
+ assert_equal(order, order_tag.order)
465
+ assert_equal(tag, order_tag.tag)
466
+ order_tag.update(attached_reason: "This is our loyal customer")
467
+
468
+ order_tag = order.order_tags.find { |order_tag| order_tag.tag_id == tag.id }
469
+
470
+ assert_equal("This is our loyal customer", order_tag.attached_reason)
471
+ end
472
+
441
473
  def test_destroy_all_on_association_clears_scope
442
474
  post = Post.create!(title: "Rails 6", body: "")
443
475
  people = post.people
@@ -630,11 +662,11 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
630
662
  end
631
663
 
632
664
  def test_replace_association
633
- assert_queries(4) { posts(:welcome); people(:david); people(:michael); posts(:welcome).people.reload }
665
+ assert_queries_count(4) { posts(:welcome); people(:david); people(:michael); posts(:welcome).people.reload }
634
666
 
635
667
  # 1 query to delete the existing reader (michael)
636
668
  # 1 query to associate the new reader (david)
637
- assert_queries(2) do
669
+ assert_queries_count(4) do
638
670
  posts(:welcome).people = [people(:david)]
639
671
  end
640
672
 
@@ -680,16 +712,16 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
680
712
  end
681
713
 
682
714
  def test_associate_with_create
683
- assert_queries(1) { posts(:thinking) }
715
+ assert_queries_count(1) { posts(:thinking) }
684
716
 
685
717
  # 1 query for the new record, 1 for the join table record
686
718
  # No need to update the actual collection yet!
687
- assert_queries(2) do
719
+ assert_queries_count(4) do
688
720
  posts(:thinking).people.create(first_name: "Jeb")
689
721
  end
690
722
 
691
723
  # *Now* we actually need the collection so it's loaded
692
- assert_queries(1) do
724
+ assert_queries_count(1) do
693
725
  assert_includes posts(:thinking).people.collect(&:first_name), "Jeb"
694
726
  end
695
727
 
@@ -759,25 +791,25 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
759
791
 
760
792
  def test_push_with_invalid_join_record
761
793
  repair_validations(Contract) do
762
- Contract.validate { |r| r.errors[:base] << "Invalid Contract" }
794
+ Contract.validate { |r| r.errors.add(:base, "Invalid Contract") }
763
795
 
764
796
  firm = companies(:first_firm)
765
797
  lifo = Developer.new(name: "lifo")
766
798
  assert_raises(ActiveRecord::RecordInvalid) do
767
- assert_deprecated { firm.developers << lifo }
799
+ assert_deprecated(ActiveRecord.deprecator) { firm.developers << lifo }
768
800
  end
769
801
 
770
802
  lifo = Developer.create!(name: "lifo")
771
803
  assert_raises(ActiveRecord::RecordInvalid) do
772
- assert_deprecated { firm.developers << lifo }
804
+ assert_deprecated(ActiveRecord.deprecator) { firm.developers << lifo }
773
805
  end
774
806
  end
775
807
  end
776
808
 
777
809
  def test_clear_associations
778
- assert_queries(2) { posts(:welcome); posts(:welcome).people.reload }
810
+ assert_queries_count(2) { posts(:welcome); posts(:welcome).people.reload }
779
811
 
780
- assert_queries(1) do
812
+ assert_queries_count(1) do
781
813
  posts(:welcome).people.clear
782
814
  end
783
815
 
@@ -892,6 +924,16 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
892
924
  end
893
925
  end
894
926
 
927
+ def test_has_many_through_uses_the_through_model_to_create_transactions
928
+ post = posts(:thinking)
929
+ person = people(:david)
930
+ other_person = people(:michael)
931
+
932
+ assert_called(Reader, :transaction) do
933
+ post.people = [person, other_person]
934
+ end
935
+ end
936
+
895
937
  def test_has_many_association_through_a_belongs_to_association_where_the_association_doesnt_exist
896
938
  post = Post.create!(title: "TITLE", body: "BODY")
897
939
  assert_equal [], post.author_favorites
@@ -1016,10 +1058,11 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
1016
1058
  end
1017
1059
 
1018
1060
  def test_collection_singular_ids_through_setter_raises_exception_when_invalid_ids_set
1061
+ skip "IBM DB formats error message values without quotes" if current_adapter?(:IBM_DBAdapter)
1019
1062
  author = authors(:david)
1020
1063
  ids = [categories(:general).name, "Unknown"]
1021
1064
  e = assert_raises(ActiveRecord::RecordNotFound) { author.essay_category_ids = ids }
1022
- msg = "Couldn't find all Categories with 'name': (General, Unknown) (found 1 results, but was looking for 2). Couldn't find Category with name Unknown."
1065
+ msg = %{Couldn't find all Categories with 'name': ("General", "Unknown") (found 1 results, but was looking for 2). Couldn't find Category with name "Unknown".}
1023
1066
  assert_equal msg, e.message
1024
1067
  end
1025
1068
 
@@ -1029,16 +1072,17 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
1029
1072
 
1030
1073
  def test_attributes_are_being_set_when_initialized_from_hm_through_association_with_where_clause
1031
1074
  new_subscriber = books(:awdr).subscribers.where(nick: "marklazz").build
1032
- assert_equal new_subscriber.nick, "marklazz"
1075
+ assert_equal "marklazz", new_subscriber.nick
1033
1076
  end
1034
1077
 
1035
1078
  def test_attributes_are_being_set_when_initialized_from_hm_through_association_with_multiple_where_clauses
1036
1079
  new_subscriber = books(:awdr).subscribers.where(nick: "marklazz").where(name: "Marcelo Giorgi").build
1037
- assert_equal new_subscriber.nick, "marklazz"
1038
- assert_equal new_subscriber.name, "Marcelo Giorgi"
1080
+ assert_equal "marklazz", new_subscriber.nick
1081
+ assert_equal "Marcelo Giorgi", new_subscriber.name
1039
1082
  end
1040
1083
 
1041
1084
  def test_include_method_in_association_through_should_return_true_for_instance_added_with_build
1085
+ skip "IBM DB adapter does not track built instances in has_many_through collections" if current_adapter?(:IBM_DBAdapter)
1042
1086
  person = Person.new
1043
1087
  reference = person.references.build
1044
1088
  job = reference.build_job
@@ -1046,6 +1090,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
1046
1090
  end
1047
1091
 
1048
1092
  def test_include_method_in_association_through_should_return_true_for_instance_added_with_nested_builds
1093
+ skip "IBM DB adapter does not track built instances in nested has_many_through collections" if current_adapter?(:IBM_DBAdapter)
1049
1094
  author = Author.new
1050
1095
  post = author.posts.build
1051
1096
  comment = post.comments.build
@@ -1189,7 +1234,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
1189
1234
  member = members(:groucho)
1190
1235
  club = member.clubs.create!
1191
1236
 
1192
- assert_equal true, club.reload.membership.favourite
1237
+ assert_equal true, club.reload.membership.favorite
1193
1238
  end
1194
1239
 
1195
1240
  def test_deleting_from_has_many_through_a_belongs_to_should_not_try_to_update_counter
@@ -1213,8 +1258,10 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
1213
1258
 
1214
1259
  def test_create_should_not_raise_exception_when_join_record_has_errors
1215
1260
  repair_validations(Categorization) do
1216
- Categorization.validate { |r| r.errors[:base] << "Invalid Categorization" }
1217
- assert_deprecated { Category.create(name: "Fishing", authors: [Author.first]) }
1261
+ Categorization.validate { |r| r.errors.add(:base, "Invalid Categorization") }
1262
+ assert_nothing_raised do
1263
+ Category.create(name: "Fishing", authors: [Author.first])
1264
+ end
1218
1265
  end
1219
1266
  end
1220
1267
 
@@ -1225,28 +1272,28 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
1225
1272
 
1226
1273
  def test_create_bang_should_raise_exception_when_join_record_has_errors
1227
1274
  repair_validations(Categorization) do
1228
- Categorization.validate { |r| r.errors[:base] << "Invalid Categorization" }
1275
+ Categorization.validate { |r| r.errors.add(:base, "Invalid Categorization") }
1229
1276
  assert_raises(ActiveRecord::RecordInvalid) do
1230
- assert_deprecated { Category.create!(name: "Fishing", authors: [Author.first]) }
1277
+ Category.create!(name: "Fishing", authors: [Author.first])
1231
1278
  end
1232
1279
  end
1233
1280
  end
1234
1281
 
1235
1282
  def test_save_bang_should_raise_exception_when_join_record_has_errors
1236
1283
  repair_validations(Categorization) do
1237
- Categorization.validate { |r| r.errors[:base] << "Invalid Categorization" }
1284
+ Categorization.validate { |r| r.errors.add(:base, "Invalid Categorization") }
1238
1285
  c = Category.new(name: "Fishing", authors: [Author.first])
1239
1286
  assert_raises(ActiveRecord::RecordInvalid) do
1240
- assert_deprecated { c.save! }
1287
+ c.save!
1241
1288
  end
1242
1289
  end
1243
1290
  end
1244
1291
 
1245
1292
  def test_save_returns_falsy_when_join_record_has_errors
1246
1293
  repair_validations(Categorization) do
1247
- Categorization.validate { |r| r.errors[:base] << "Invalid Categorization" }
1294
+ Categorization.validate { |r| r.errors.add(:base, "Invalid Categorization") }
1248
1295
  c = Category.new(name: "Fishing", authors: [Author.first])
1249
- assert_deprecated { assert_not c.save }
1296
+ assert_not c.save
1250
1297
  end
1251
1298
  end
1252
1299
 
@@ -1254,7 +1301,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
1254
1301
  person = Person.create!(first_name: "Gaga")
1255
1302
  person = Person.where(id: person.id).where("readers.id = 1 or 1=1").references(:readers).includes(:posts).to_a.first
1256
1303
 
1257
- assert person.posts.loaded?, "person.posts should be loaded"
1304
+ assert_predicate person.posts, :loaded?, "person.posts should be loaded"
1258
1305
  assert_equal [], person.posts
1259
1306
  end
1260
1307
 
@@ -1279,6 +1326,15 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
1279
1326
  assert_equal [tags(:general)], post.reload.tags
1280
1327
  end
1281
1328
 
1329
+ def test_has_many_through_with_polymorhic_join_model
1330
+ zine = Zine.create!
1331
+
1332
+ assert_nothing_raised { zine.polymorphic_humans.build.save! }
1333
+
1334
+ assert_equal 1, zine.polymorphic_humans.count
1335
+ assert_equal 1, zine.interests.count
1336
+ end
1337
+
1282
1338
  def test_has_many_through_obeys_order_on_through_association
1283
1339
  owner = owners(:blackbeard)
1284
1340
  assert_includes owner.toys.to_sql, "pets.name desc"
@@ -1306,8 +1362,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
1306
1362
 
1307
1363
  active_persons = Person.joins(:readers).joins(:posts).distinct(true).where("posts.title" => "active")
1308
1364
 
1309
- assert_equal active_persons.map(&:followers_count).reduce(:+), 10
1310
- assert_equal active_persons.sum(:followers_count), 10
1365
+ assert_equal 10, active_persons.map(&:followers_count).reduce(:+)
1366
+ assert_equal 10, active_persons.sum(:followers_count)
1311
1367
  assert_equal active_persons.sum(:followers_count), active_persons.map(&:followers_count).reduce(:+)
1312
1368
  end
1313
1369
 
@@ -1340,11 +1396,23 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
1340
1396
  member = Member.create!
1341
1397
  Membership.create!(club: club, member: member)
1342
1398
 
1343
- club.favourites << member
1344
- assert_equal [member], club.favourites
1399
+ club.favorites << member
1400
+ assert_equal [member], club.favorites
1345
1401
 
1346
1402
  club.reload
1347
- assert_equal [member], club.favourites
1403
+ assert_equal [member], club.favorites
1404
+ end
1405
+
1406
+ def test_insert_records_via_has_many_through_association_with_scope_and_association_name_different_from_the_joining_table_name
1407
+ club = Club.create!
1408
+ member = Member.create!
1409
+ Membership.create!(club: club, member: member)
1410
+
1411
+ club.custom_favorites << member
1412
+ assert_equal [member], club.custom_favorites
1413
+
1414
+ club.reload
1415
+ assert_equal [member], club.custom_favorites
1348
1416
  end
1349
1417
 
1350
1418
  def test_has_many_through_unscope_default_scope
@@ -1377,9 +1445,9 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
1377
1445
 
1378
1446
  def test_has_many_through_with_scope_that_should_not_be_fully_merged
1379
1447
  Club.has_many :distinct_memberships, -> { distinct }, class_name: "Membership"
1380
- Club.has_many :special_favourites, through: :distinct_memberships, source: :member
1448
+ Club.has_many :special_favorites, through: :distinct_memberships, source: :member
1381
1449
 
1382
- assert_nil Club.new.special_favourites.distinct_value
1450
+ assert_nil Club.new.special_favorites.distinct_value
1383
1451
  end
1384
1452
 
1385
1453
  def test_has_many_through_do_not_cache_association_reader_if_the_though_method_has_default_scopes
@@ -1559,6 +1627,65 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
1559
1627
  assert_equal sections, fall.sections.sort_by(&:id)
1560
1628
  end
1561
1629
 
1630
+ def test_post_has_many_tags_through_association_with_composite_query_constraints
1631
+ blog_post = sharded_blog_posts(:great_post_blog_one)
1632
+ expected_tag_ids = Sharded::BlogPostTag.where(blog_post_id: blog_post.id, blog_id: blog_post.blog_id).pluck(:tag_id)
1633
+ tag_ids = []
1634
+ sql = capture_sql do
1635
+ tag_ids = blog_post.tags.to_a.map(&:id)
1636
+ end.first
1637
+
1638
+ # DB2 doesn't quote composite identifiers in JOIN conditions
1639
+ assert_match(/.* ON.* sharded_tags\.blog_id = sharded_blog_posts_tags\.blog_id .* WHERE/i, sql)
1640
+ assert_match(/.* WHERE .*sharded_blog_posts_tags\.blog_id = .*/i, sql)
1641
+
1642
+ assert_not_empty(tag_ids)
1643
+ assert_equal(expected_tag_ids.sort, tag_ids.sort)
1644
+ end
1645
+
1646
+ def test_tags_has_manu_posts_through_association_with_composite_query_constraints
1647
+ tag = sharded_tags(:short_read_blog_one)
1648
+ expected_blog_post_ids = Sharded::BlogPostTag.where(tag_id: tag.id, blog_id: tag.blog_id).pluck(:blog_post_id)
1649
+ blog_post_ids = []
1650
+ sql = capture_sql do
1651
+ blog_post_ids = tag.blog_posts.to_a.map(&:id)
1652
+ end.first
1653
+
1654
+ # DB2 doesn't quote composite identifiers in JOIN conditions
1655
+ assert_match(/.* ON.* sharded_blog_posts\.blog_id = sharded_blog_posts_tags\.blog_id .* WHERE/i, sql)
1656
+ assert_match(/.* WHERE .*sharded_blog_posts_tags\.blog_id = .*/i, sql)
1657
+
1658
+ assert_not_empty(blog_post_ids)
1659
+ assert_equal(expected_blog_post_ids.sort, blog_post_ids.sort)
1660
+ end
1661
+
1662
+ def test_loading_cpk_association_with_unpersisted_owner
1663
+ order = Cpk::Order.create!(shop_id: 1)
1664
+ book = Cpk::BookWithOrderAgreements.new(id: [1, 2], order: order)
1665
+ order_agreement = Cpk::OrderAgreement.create!(order: order)
1666
+
1667
+ assert_equal([order_agreement], book.order_agreements.to_a)
1668
+ end
1669
+
1670
+ def test_cpk_stale_target
1671
+ order = Cpk::Order.create!(shop_id: 1)
1672
+ book = Cpk::BookWithOrderAgreements.create!(id: [1, 2], order: order)
1673
+ Cpk::OrderAgreement.create!(order: order)
1674
+
1675
+ book.order_agreements.load
1676
+ book.order = Cpk::Order.new
1677
+
1678
+ assert_predicate(book.association(:order_agreements), :stale_target?)
1679
+ end
1680
+
1681
+ def test_cpk_association_build_through_singular
1682
+ order = Cpk::OrderWithSingularBookChapters.create!(id: [1, 2])
1683
+ book = order.create_book!(id: [3, 4])
1684
+ chapter = order.chapters.build
1685
+
1686
+ assert_equal(chapter.book, book)
1687
+ end
1688
+
1562
1689
  private
1563
1690
  def make_model(name)
1564
1691
  Class.new(ActiveRecord::Base) { define_singleton_method(:name) { name } }
@@ -0,0 +1,197 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+
5
+ require "models/post"
6
+ require "models/author"
7
+ require "models/comment"
8
+ require "models/rating"
9
+ require "models/member"
10
+ require "models/member_type"
11
+
12
+ require "models/pirate"
13
+ require "models/treasure"
14
+ require "models/parrot"
15
+
16
+ require "models/hotel"
17
+ require "models/department"
18
+
19
+ class HasManyThroughDisableJoinsAssociationsTest < ActiveRecord::TestCase
20
+ fixtures :posts, :authors, :comments, :pirates, :author_addresses
21
+
22
+ def setup
23
+ @author = authors(:mary)
24
+ @post = @author.posts.create(title: "title", body: "body")
25
+ @member_type = MemberType.create(name: "club")
26
+ @member = Member.create(member_type: @member_type)
27
+ @comment = @post.comments.create(body: "text", origin: @member)
28
+ @post2 = @author.posts.create(title: "title", body: "body")
29
+ @member2 = Member.create(member_type: @member_type)
30
+ @comment2 = @post2.comments.create(body: "text", origin: @member2)
31
+ @rating1 = @comment.ratings.create(value: 8)
32
+ @rating2 = @comment.ratings.create(value: 9)
33
+ end
34
+
35
+ def test_counting_on_disable_joins_through
36
+ assert_equal @author.comments.count, @author.no_joins_comments.count
37
+ assert_queries_count(2) { @author.no_joins_comments.count }
38
+ assert_queries_count(1) { @author.comments.count }
39
+ end
40
+
41
+ def test_counting_on_disable_joins_through_using_custom_foreign_key
42
+ assert_equal @author.comments_with_foreign_key.count, @author.no_joins_comments_with_foreign_key.count
43
+ assert_queries_count(2) { @author.no_joins_comments_with_foreign_key.count }
44
+ assert_queries_count(1) { @author.comments_with_foreign_key.count }
45
+ end
46
+
47
+ def test_pluck_on_disable_joins_through
48
+ assert_equal @author.comments.pluck(:id).sort, @author.no_joins_comments.pluck(:id).sort
49
+ assert_queries_count(2) { @author.no_joins_comments.pluck(:id) }
50
+ assert_queries_count(1) { @author.comments.pluck(:id) }
51
+ end
52
+
53
+ def test_pluck_on_disable_joins_through_using_custom_foreign_key
54
+ assert_equal @author.comments_with_foreign_key.pluck(:id).sort, @author.no_joins_comments_with_foreign_key.pluck(:id).sort
55
+ assert_queries_count(2) { @author.no_joins_comments_with_foreign_key.pluck(:id) }
56
+ assert_queries_count(1) { @author.comments_with_foreign_key.pluck(:id) }
57
+ end
58
+
59
+ def test_fetching_on_disable_joins_through
60
+ assert_equal @author.comments.first.id, @author.no_joins_comments.first.id
61
+ assert_queries_count(2) { @author.no_joins_comments.first.id }
62
+ assert_queries_count(1) { @author.comments.first.id }
63
+ end
64
+
65
+ def test_fetching_on_disable_joins_through_using_custom_foreign_key
66
+ assert_equal @author.comments_with_foreign_key.first.id, @author.no_joins_comments_with_foreign_key.first.id
67
+ assert_queries_count(2) { @author.no_joins_comments_with_foreign_key.first.id }
68
+ assert_queries_count(1) { @author.comments_with_foreign_key.first.id }
69
+ end
70
+
71
+ def test_to_a_on_disable_joins_through
72
+ assert_equal @author.comments.sort_by(&:id), @author.no_joins_comments.sort_by(&:id)
73
+ @author.reload
74
+ assert_queries_count(2) { @author.no_joins_comments.to_a }
75
+ assert_queries_count(1) { @author.comments.to_a }
76
+ end
77
+
78
+ def test_appending_on_disable_joins_through
79
+ assert_difference(->() { @author.no_joins_comments.reload.size }) do
80
+ @post.comments.create(body: "text")
81
+ end
82
+ assert_queries_count(2) { @author.no_joins_comments.reload.size }
83
+ assert_queries_count(1) { @author.comments.reload.size }
84
+ end
85
+
86
+ def test_appending_on_disable_joins_through_using_custom_foreign_key
87
+ assert_difference(->() { @author.no_joins_comments_with_foreign_key.reload.size }) do
88
+ @post.comments.create(body: "text")
89
+ end
90
+ assert_queries_count(2) { @author.no_joins_comments_with_foreign_key.reload.size }
91
+ assert_queries_count(1) { @author.comments_with_foreign_key.reload.size }
92
+ end
93
+
94
+ def test_empty_on_disable_joins_through
95
+ empty_author = authors(:bob)
96
+ assert_equal [], assert_queries_count(0) { empty_author.comments.all }
97
+ assert_equal [], assert_queries_count(1) { empty_author.no_joins_comments.all }
98
+ end
99
+
100
+ def test_empty_on_disable_joins_through_using_custom_foreign_key
101
+ empty_author = authors(:bob)
102
+ assert_equal [], assert_queries_count(0) { empty_author.comments_with_foreign_key.all }
103
+ assert_equal [], assert_queries_count(1) { empty_author.no_joins_comments_with_foreign_key.all }
104
+ end
105
+
106
+ def test_pluck_on_disable_joins_through_a_through
107
+ rating_ids = Rating.where(comment: @comment).pluck(:id).sort
108
+ assert_equal rating_ids, assert_queries_count(1) { @author.ratings.pluck(:id).sort }
109
+ assert_equal rating_ids, assert_queries_count(3) { @author.no_joins_ratings.pluck(:id).sort }
110
+ end
111
+
112
+ def test_count_on_disable_joins_through_a_through
113
+ ratings_count = Rating.where(comment: @comment).count
114
+ assert_equal ratings_count, assert_queries_count(1) { @author.ratings.count }
115
+ assert_equal ratings_count, assert_queries_count(3) { @author.no_joins_ratings.count }
116
+ end
117
+
118
+ def test_count_on_disable_joins_using_relation_with_scope
119
+ assert_equal 2, assert_queries_count(1) { @author.good_ratings.count }
120
+ assert_equal 2, assert_queries_count(3) { @author.no_joins_good_ratings.count }
121
+ end
122
+
123
+ def test_to_a_on_disable_joins_with_multiple_scopes
124
+ assert_equal [@rating1, @rating2], assert_queries_count(1) { @author.good_ratings.to_a }
125
+ assert_equal [@rating1, @rating2], assert_queries_count(3) { @author.no_joins_good_ratings.to_a }
126
+ end
127
+
128
+ def test_preloading_has_many_through_disable_joins
129
+ assert_queries_count(3) { Author.all.preload(:good_ratings).map(&:good_ratings) }
130
+ assert_queries_count(4) { Author.all.preload(:no_joins_good_ratings).map(&:good_ratings) }
131
+ end
132
+
133
+ def test_polymophic_disable_joins_through_counting
134
+ assert_equal 2, assert_queries_count(1) { @author.ordered_members.count }
135
+ assert_equal 2, assert_queries_count(3) { @author.no_joins_ordered_members.count }
136
+ end
137
+
138
+ def test_polymophic_disable_joins_through_ordering
139
+ assert_equal [@member2, @member], assert_queries_count(1) { @author.ordered_members.to_a }
140
+ assert_equal [@member2, @member], assert_queries_count(3) { @author.no_joins_ordered_members.to_a }
141
+ end
142
+
143
+ def test_polymorphic_disable_joins_through_reordering
144
+ assert_equal [@member, @member2], assert_queries_count(1) { @author.ordered_members.reorder(id: :asc).to_a }
145
+ assert_equal [@member, @member2], assert_queries_count(3) { @author.no_joins_ordered_members.reorder(id: :asc).to_a }
146
+ end
147
+
148
+ def test_polymorphic_disable_joins_through_ordered_scopes
149
+ assert_equal [@member2, @member], assert_queries_count(1) { @author.ordered_members.unnamed.to_a }
150
+ assert_equal [@member2, @member], assert_queries_count(3) { @author.no_joins_ordered_members.unnamed.to_a }
151
+ end
152
+
153
+ def test_polymorphic_disable_joins_through_ordered_chained_scopes
154
+ member3 = Member.create(member_type: @member_type)
155
+ member4 = Member.create(member_type: @member_type, name: "named")
156
+ @post2.comments.create(body: "text", origin: member3)
157
+ @post2.comments.create(body: "text", origin: member4)
158
+
159
+ assert_equal [member3, @member2, @member], assert_queries_count(1) { @author.ordered_members.unnamed.with_member_type_id(@member_type.id).to_a }
160
+ assert_equal [member3, @member2, @member], assert_queries_count(3) { @author.no_joins_ordered_members.unnamed.with_member_type_id(@member_type.id).to_a }
161
+ end
162
+
163
+ def test_polymorphic_disable_joins_through_ordered_scope_limits
164
+ assert_equal [@member2], assert_queries_count(1) { @author.ordered_members.unnamed.limit(1).to_a }
165
+ assert_equal [@member2], assert_queries_count(3) { @author.no_joins_ordered_members.unnamed.limit(1).to_a }
166
+ end
167
+
168
+ def test_polymorphic_disable_joins_through_ordered_scope_first
169
+ assert_equal @member2, assert_queries_count(1) { @author.ordered_members.unnamed.first }
170
+ assert_equal @member2, assert_queries_count(3) { @author.no_joins_ordered_members.unnamed.first }
171
+ end
172
+
173
+ def test_order_applied_in_double_join
174
+ assert_equal [@member2, @member], assert_queries_count(1) { @author.members.to_a }
175
+ assert_equal [@member2, @member], assert_queries_count(3) { @author.no_joins_members.to_a }
176
+ end
177
+
178
+ def test_first_and_scope_applied_in_double_join
179
+ assert_equal @member2, assert_queries_count(1) { @author.members.unnamed.first }
180
+ assert_equal @member2, assert_queries_count(3) { @author.no_joins_members.unnamed.first }
181
+ end
182
+
183
+ def test_first_and_scope_in_double_join_applies_order_in_memory
184
+ disable_joins_sql = capture_sql { @author.no_joins_members.unnamed.first }
185
+ assert_no_match(/ORDER BY/, disable_joins_sql.last)
186
+ end
187
+
188
+ def test_limit_and_scope_applied_in_double_join
189
+ assert_equal [@member2], assert_queries_count(1) { @author.members.unnamed.limit(1).to_a }
190
+ assert_equal [@member2], assert_queries_count(3) { @author.no_joins_members.unnamed.limit(1) }
191
+ end
192
+
193
+ def test_limit_and_scope_in_double_join_applies_limit_in_memory
194
+ disable_joins_sql = capture_sql { @author.no_joins_members.unnamed.first }
195
+ assert_no_match(/LIMIT 1/, disable_joins_sql.last)
196
+ end
197
+ end