ibm_db 5.1.0-x86-mingw32 → 5.3.2-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (624) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +9 -0
  3. data/LICENSE +55 -18
  4. data/ext/Makefile +14 -14
  5. data/ext/extconf.rb +4 -4
  6. data/ext/ibm_db.c +62 -57
  7. data/ext/ibm_db.o +0 -0
  8. data/ext/ibm_db.so +0 -0
  9. data/ext/mkmf.log +11 -11
  10. data/ext/ruby_ibm_db_cli.c +1 -0
  11. data/ext/ruby_ibm_db_cli.o +0 -0
  12. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1463 -1279
  13. data/lib/ibm_db.so +1 -0
  14. data/lib/mswin32/ibm_db.rb +7 -3
  15. data/lib/mswin32/rb2x/i386/ruby25/ibm_db.so +0 -0
  16. data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
  17. data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
  18. data/test/activejob/destroy_association_async_test.rb +305 -0
  19. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  20. data/test/activejob/helper.rb +15 -0
  21. data/test/assets/schema_dump_5_1.yml +345 -0
  22. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  23. data/test/cases/adapter_test.rb +432 -218
  24. data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
  25. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  26. data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
  27. data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
  28. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
  29. data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
  30. data/test/cases/adapters/mysql2/connection_test.rb +48 -50
  31. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  32. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
  33. data/test/cases/adapters/mysql2/enum_test.rb +32 -11
  34. data/test/cases/adapters/mysql2/explain_test.rb +13 -11
  35. data/test/cases/adapters/mysql2/json_test.rb +17 -188
  36. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  37. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
  38. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  39. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  40. data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
  41. data/test/cases/adapters/mysql2/schema_test.rb +24 -22
  42. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  43. data/test/cases/adapters/mysql2/sp_test.rb +10 -8
  44. data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
  45. data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
  46. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  47. data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
  48. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  49. data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
  50. data/test/cases/adapters/postgresql/array_test.rb +118 -63
  51. data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
  52. data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
  53. data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
  54. data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
  55. data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
  56. data/test/cases/adapters/postgresql/citext_test.rb +58 -58
  57. data/test/cases/adapters/postgresql/collation_test.rb +17 -15
  58. data/test/cases/adapters/postgresql/composite_test.rb +25 -23
  59. data/test/cases/adapters/postgresql/connection_test.rb +73 -85
  60. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  61. data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
  62. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  63. data/test/cases/adapters/postgresql/domain_test.rb +9 -7
  64. data/test/cases/adapters/postgresql/enum_test.rb +12 -10
  65. data/test/cases/adapters/postgresql/explain_test.rb +10 -8
  66. data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
  67. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  68. data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
  69. data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
  70. data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
  71. data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
  72. data/test/cases/adapters/postgresql/integer_test.rb +2 -0
  73. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  74. data/test/cases/adapters/postgresql/json_test.rb +16 -201
  75. data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
  76. data/test/cases/adapters/postgresql/money_test.rb +47 -16
  77. data/test/cases/adapters/postgresql/network_test.rb +36 -28
  78. data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
  79. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  80. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  81. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  82. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
  83. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  84. data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
  85. data/test/cases/adapters/postgresql/range_test.rb +406 -292
  86. data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
  87. data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
  88. data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
  89. data/test/cases/adapters/postgresql/schema_test.rb +207 -91
  90. data/test/cases/adapters/postgresql/serial_test.rb +9 -7
  91. data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
  92. data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
  93. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  94. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  95. data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
  96. data/test/cases/adapters/postgresql/utils_test.rb +11 -9
  97. data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
  98. data/test/cases/adapters/postgresql/xml_test.rb +10 -14
  99. data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
  100. data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
  101. data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
  102. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  103. data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
  104. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  105. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
  106. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
  107. data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
  108. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  109. data/test/cases/aggregations_test.rb +14 -12
  110. data/test/cases/annotate_test.rb +46 -0
  111. data/test/cases/ar_schema_test.rb +153 -86
  112. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  113. data/test/cases/arel/attributes/math_test.rb +83 -0
  114. data/test/cases/arel/attributes_test.rb +27 -0
  115. data/test/cases/arel/collectors/bind_test.rb +40 -0
  116. data/test/cases/arel/collectors/composite_test.rb +47 -0
  117. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  118. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  119. data/test/cases/arel/crud_test.rb +65 -0
  120. data/test/cases/arel/delete_manager_test.rb +53 -0
  121. data/test/cases/arel/factory_methods_test.rb +46 -0
  122. data/test/cases/arel/helper.rb +45 -0
  123. data/test/cases/arel/insert_manager_test.rb +241 -0
  124. data/test/cases/arel/nodes/and_test.rb +30 -0
  125. data/test/cases/arel/nodes/as_test.rb +36 -0
  126. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  127. data/test/cases/arel/nodes/bin_test.rb +35 -0
  128. data/test/cases/arel/nodes/binary_test.rb +29 -0
  129. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  130. data/test/cases/arel/nodes/case_test.rb +96 -0
  131. data/test/cases/arel/nodes/casted_test.rb +18 -0
  132. data/test/cases/arel/nodes/comment_test.rb +22 -0
  133. data/test/cases/arel/nodes/count_test.rb +35 -0
  134. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  135. data/test/cases/arel/nodes/descending_test.rb +46 -0
  136. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  137. data/test/cases/arel/nodes/equality_test.rb +62 -0
  138. data/test/cases/arel/nodes/extract_test.rb +43 -0
  139. data/test/cases/arel/nodes/false_test.rb +21 -0
  140. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  141. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  142. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  143. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  144. data/test/cases/arel/nodes/node_test.rb +22 -0
  145. data/test/cases/arel/nodes/not_test.rb +31 -0
  146. data/test/cases/arel/nodes/or_test.rb +36 -0
  147. data/test/cases/arel/nodes/over_test.rb +69 -0
  148. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  149. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  150. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  151. data/test/cases/arel/nodes/sum_test.rb +35 -0
  152. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  153. data/test/cases/arel/nodes/true_test.rb +21 -0
  154. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  155. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  156. data/test/cases/arel/nodes/window_test.rb +81 -0
  157. data/test/cases/arel/nodes_test.rb +34 -0
  158. data/test/cases/arel/select_manager_test.rb +1238 -0
  159. data/test/cases/arel/support/fake_record.rb +135 -0
  160. data/test/cases/arel/table_test.rb +216 -0
  161. data/test/cases/arel/update_manager_test.rb +126 -0
  162. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  163. data/test/cases/arel/visitors/dot_test.rb +90 -0
  164. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  165. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  166. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  167. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  168. data/test/cases/associations/belongs_to_associations_test.rb +510 -158
  169. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
  170. data/test/cases/associations/callbacks_test.rb +56 -38
  171. data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
  172. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
  173. data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
  174. data/test/cases/associations/eager_singularization_test.rb +21 -21
  175. data/test/cases/associations/eager_test.rb +559 -415
  176. data/test/cases/associations/extension_test.rb +18 -12
  177. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
  178. data/test/cases/associations/has_many_associations_test.rb +1038 -465
  179. data/test/cases/associations/has_many_through_associations_test.rb +558 -249
  180. data/test/cases/associations/has_one_associations_test.rb +294 -129
  181. data/test/cases/associations/has_one_through_associations_test.rb +121 -75
  182. data/test/cases/associations/inner_join_association_test.rb +114 -38
  183. data/test/cases/associations/inverse_associations_test.rb +606 -398
  184. data/test/cases/associations/join_model_test.rb +158 -148
  185. data/test/cases/associations/left_outer_join_association_test.rb +59 -24
  186. data/test/cases/associations/nested_through_associations_test.rb +166 -109
  187. data/test/cases/associations/required_test.rb +35 -10
  188. data/test/cases/associations_test.rb +241 -110
  189. data/test/cases/attribute_methods/read_test.rb +11 -11
  190. data/test/cases/attribute_methods_test.rb +413 -298
  191. data/test/cases/attributes_test.rb +145 -27
  192. data/test/cases/autosave_association_test.rb +681 -436
  193. data/test/cases/base_prevent_writes_test.rb +229 -0
  194. data/test/cases/base_test.rb +599 -542
  195. data/test/cases/batches_test.rb +288 -82
  196. data/test/cases/binary_test.rb +26 -31
  197. data/test/cases/bind_parameter_test.rb +194 -21
  198. data/test/cases/boolean_test.rb +52 -0
  199. data/test/cases/cache_key_test.rb +110 -5
  200. data/test/cases/calculations_test.rb +740 -177
  201. data/test/cases/callbacks_test.rb +74 -207
  202. data/test/cases/clone_test.rb +15 -10
  203. data/test/cases/coders/json_test.rb +2 -0
  204. data/test/cases/coders/yaml_column_test.rb +16 -13
  205. data/test/cases/collection_cache_key_test.rb +177 -20
  206. data/test/cases/column_alias_test.rb +9 -7
  207. data/test/cases/column_definition_test.rb +10 -68
  208. data/test/cases/comment_test.rb +166 -107
  209. data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
  210. data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
  211. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  212. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  213. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  214. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  215. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  216. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  217. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
  218. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
  219. data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
  220. data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
  221. data/test/cases/connection_management_test.rb +13 -11
  222. data/test/cases/connection_pool_test.rb +316 -83
  223. data/test/cases/core_test.rb +82 -58
  224. data/test/cases/counter_cache_test.rb +204 -50
  225. data/test/cases/custom_locking_test.rb +5 -3
  226. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  227. data/test/cases/database_configurations/resolver_test.rb +150 -0
  228. data/test/cases/database_configurations_test.rb +145 -0
  229. data/test/cases/database_selector_test.rb +296 -0
  230. data/test/cases/database_statements_test.rb +18 -16
  231. data/test/cases/date_test.rb +8 -16
  232. data/test/cases/date_time_precision_test.rb +100 -78
  233. data/test/cases/date_time_test.rb +23 -8
  234. data/test/cases/defaults_test.rb +106 -71
  235. data/test/cases/delegated_type_test.rb +57 -0
  236. data/test/cases/dirty_test.rb +419 -223
  237. data/test/cases/disconnected_test.rb +6 -6
  238. data/test/cases/dup_test.rb +54 -27
  239. data/test/cases/enum_test.rb +461 -82
  240. data/test/cases/errors_test.rb +7 -7
  241. data/test/cases/explain_subscriber_test.rb +17 -15
  242. data/test/cases/explain_test.rb +11 -19
  243. data/test/cases/filter_attributes_test.rb +153 -0
  244. data/test/cases/finder_respond_to_test.rb +14 -14
  245. data/test/cases/finder_test.rb +669 -287
  246. data/test/cases/fixture_set/file_test.rb +34 -38
  247. data/test/cases/fixtures_test.rb +833 -176
  248. data/test/cases/forbidden_attributes_protection_test.rb +32 -67
  249. data/test/cases/habtm_destroy_order_test.rb +25 -25
  250. data/test/cases/helper.rb +78 -49
  251. data/test/cases/hot_compatibility_test.rb +33 -32
  252. data/test/cases/i18n_test.rb +18 -17
  253. data/test/cases/inheritance_test.rb +180 -115
  254. data/test/cases/insert_all_test.rb +489 -0
  255. data/test/cases/instrumentation_test.rb +101 -0
  256. data/test/cases/integration_test.rb +119 -31
  257. data/test/cases/invalid_connection_test.rb +18 -16
  258. data/test/cases/invertible_migration_test.rb +183 -43
  259. data/test/cases/json_attribute_test.rb +35 -0
  260. data/test/cases/json_serialization_test.rb +57 -58
  261. data/test/cases/json_shared_test_cases.rb +290 -0
  262. data/test/cases/locking_test.rb +413 -119
  263. data/test/cases/log_subscriber_test.rb +68 -26
  264. data/test/cases/marshal_serialization_test.rb +39 -0
  265. data/test/cases/migration/change_schema_test.rb +118 -72
  266. data/test/cases/migration/change_table_test.rb +138 -30
  267. data/test/cases/migration/check_constraint_test.rb +162 -0
  268. data/test/cases/migration/column_attributes_test.rb +45 -35
  269. data/test/cases/migration/column_positioning_test.rb +18 -6
  270. data/test/cases/migration/columns_test.rb +93 -77
  271. data/test/cases/migration/command_recorder_test.rb +121 -34
  272. data/test/cases/migration/compatibility_test.rb +578 -23
  273. data/test/cases/migration/create_join_table_test.rb +35 -25
  274. data/test/cases/migration/foreign_key_test.rb +503 -284
  275. data/test/cases/migration/helper.rb +4 -3
  276. data/test/cases/migration/index_test.rb +119 -70
  277. data/test/cases/migration/logger_test.rb +9 -6
  278. data/test/cases/migration/pending_migrations_test.rb +88 -34
  279. data/test/cases/migration/references_foreign_key_test.rb +164 -150
  280. data/test/cases/migration/references_index_test.rb +38 -19
  281. data/test/cases/migration/references_statements_test.rb +15 -14
  282. data/test/cases/migration/rename_table_test.rb +53 -30
  283. data/test/cases/migration_test.rb +637 -269
  284. data/test/cases/migrator_test.rb +191 -135
  285. data/test/cases/mixin_test.rb +7 -11
  286. data/test/cases/modules_test.rb +36 -34
  287. data/test/cases/multi_db_migrator_test.rb +223 -0
  288. data/test/cases/multiparameter_attributes_test.rb +60 -33
  289. data/test/cases/multiple_db_test.rb +16 -22
  290. data/test/cases/nested_attributes_test.rb +341 -320
  291. data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
  292. data/test/cases/null_relation_test.rb +84 -0
  293. data/test/cases/numeric_data_test.rb +93 -0
  294. data/test/cases/persistence_test.rb +361 -269
  295. data/test/cases/pooled_connections_test.rb +18 -26
  296. data/test/cases/prepared_statement_status_test.rb +48 -0
  297. data/test/cases/primary_keys_test.rb +210 -104
  298. data/test/cases/query_cache_test.rb +610 -141
  299. data/test/cases/quoting_test.rb +132 -31
  300. data/test/cases/readonly_test.rb +49 -48
  301. data/test/cases/reaper_test.rb +146 -32
  302. data/test/cases/reflection_test.rb +167 -156
  303. data/test/cases/relation/delegation_test.rb +49 -36
  304. data/test/cases/relation/delete_all_test.rb +117 -0
  305. data/test/cases/relation/merging_test.rb +319 -42
  306. data/test/cases/relation/mutation_test.rb +55 -93
  307. data/test/cases/relation/or_test.rb +129 -29
  308. data/test/cases/relation/predicate_builder_test.rb +21 -6
  309. data/test/cases/relation/record_fetch_warning_test.rb +5 -3
  310. data/test/cases/relation/select_test.rb +67 -0
  311. data/test/cases/relation/update_all_test.rb +317 -0
  312. data/test/cases/relation/where_chain_test.rb +68 -32
  313. data/test/cases/relation/where_clause_test.rb +136 -61
  314. data/test/cases/relation/where_test.rb +155 -48
  315. data/test/cases/relation_test.rb +266 -112
  316. data/test/cases/relations_test.rb +969 -744
  317. data/test/cases/reload_models_test.rb +13 -9
  318. data/test/cases/reserved_word_test.rb +141 -0
  319. data/test/cases/result_test.rb +68 -17
  320. data/test/cases/sanitize_test.rb +87 -71
  321. data/test/cases/schema_dumper_test.rb +221 -128
  322. data/test/cases/schema_loading_test.rb +3 -2
  323. data/test/cases/scoping/default_scoping_test.rb +185 -144
  324. data/test/cases/scoping/named_scoping_test.rb +177 -89
  325. data/test/cases/scoping/relation_scoping_test.rb +197 -75
  326. data/test/cases/secure_token_test.rb +18 -3
  327. data/test/cases/serialization_test.rb +30 -28
  328. data/test/cases/serialized_attribute_test.rb +133 -42
  329. data/test/cases/signed_id_test.rb +168 -0
  330. data/test/cases/statement_cache_test.rb +41 -24
  331. data/test/cases/statement_invalid_test.rb +42 -0
  332. data/test/cases/store_test.rb +180 -55
  333. data/test/cases/strict_loading_test.rb +473 -0
  334. data/test/cases/suppressor_test.rb +26 -12
  335. data/test/cases/tasks/database_tasks_test.rb +1258 -194
  336. data/test/cases/tasks/mysql_rake_test.rb +370 -298
  337. data/test/cases/tasks/postgresql_rake_test.rb +481 -251
  338. data/test/cases/tasks/sqlite_rake_test.rb +225 -178
  339. data/test/cases/test_case.rb +51 -40
  340. data/test/cases/test_databases_test.rb +79 -0
  341. data/test/cases/test_fixtures_test.rb +79 -19
  342. data/test/cases/time_precision_test.rb +98 -76
  343. data/test/cases/timestamp_test.rb +102 -99
  344. data/test/cases/touch_later_test.rb +12 -10
  345. data/test/cases/transaction_callbacks_test.rb +344 -90
  346. data/test/cases/transaction_isolation_test.rb +12 -12
  347. data/test/cases/transactions_test.rb +612 -162
  348. data/test/cases/type/adapter_specific_registry_test.rb +14 -2
  349. data/test/cases/type/date_time_test.rb +4 -2
  350. data/test/cases/type/integer_test.rb +4 -2
  351. data/test/cases/type/string_test.rb +10 -8
  352. data/test/cases/type/time_test.rb +28 -0
  353. data/test/cases/type/type_map_test.rb +29 -28
  354. data/test/cases/type/unsigned_integer_test.rb +19 -0
  355. data/test/cases/type_test.rb +2 -0
  356. data/test/cases/types_test.rb +3 -1
  357. data/test/cases/unconnected_test.rb +14 -1
  358. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  359. data/test/cases/validations/absence_validation_test.rb +19 -17
  360. data/test/cases/validations/association_validation_test.rb +30 -28
  361. data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
  362. data/test/cases/validations/i18n_validation_test.rb +22 -21
  363. data/test/cases/validations/length_validation_test.rb +34 -33
  364. data/test/cases/validations/numericality_validation_test.rb +181 -0
  365. data/test/cases/validations/presence_validation_test.rb +21 -19
  366. data/test/cases/validations/uniqueness_validation_test.rb +156 -86
  367. data/test/cases/validations_repair_helper.rb +2 -0
  368. data/test/cases/validations_test.rb +61 -26
  369. data/test/cases/view_test.rb +122 -116
  370. data/test/cases/yaml_serialization_test.rb +79 -34
  371. data/test/config.example.yml +19 -19
  372. data/test/config.rb +3 -1
  373. data/test/config.yml +16 -6
  374. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  375. data/test/fixtures/author_addresses.yml +1 -8
  376. data/test/fixtures/authors.yml +1 -7
  377. data/test/fixtures/binaries.yml +4 -0
  378. data/test/fixtures/books.yml +9 -2
  379. data/test/fixtures/categories_posts.yml +3 -0
  380. data/test/fixtures/citations.yml +5 -0
  381. data/test/fixtures/comments.yml +7 -0
  382. data/test/fixtures/companies.yml +5 -0
  383. data/test/fixtures/computers.yml +2 -0
  384. data/test/fixtures/customers.yml +10 -1
  385. data/test/fixtures/developers.yml +1 -1
  386. data/test/fixtures/essays.yml +10 -0
  387. data/test/fixtures/faces.yml +3 -3
  388. data/test/fixtures/humans.yml +5 -0
  389. data/test/fixtures/interests.yml +7 -7
  390. data/test/fixtures/memberships.yml +7 -0
  391. data/test/fixtures/minimalistics.yml +3 -0
  392. data/test/fixtures/mixed_case_monkeys.yml +2 -2
  393. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  394. data/test/fixtures/naked/yml/parrots.yml +1 -0
  395. data/test/fixtures/other_books.yml +26 -0
  396. data/test/fixtures/other_posts.yml +1 -0
  397. data/test/fixtures/parrots.yml +7 -1
  398. data/test/fixtures/pirates.yml +3 -0
  399. data/test/fixtures/posts.yml +11 -3
  400. data/test/fixtures/readers.yml +6 -0
  401. data/test/fixtures/reserved_words/values.yml +2 -2
  402. data/test/fixtures/sponsors.yml +3 -0
  403. data/test/fixtures/strict_zines.yml +2 -0
  404. data/test/fixtures/subscribers.yml +1 -1
  405. data/test/fixtures/tasks.yml +1 -1
  406. data/test/fixtures/warehouse-things.yml +3 -0
  407. data/test/migrations/10_urban/9_add_expressions.rb +2 -0
  408. data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
  409. data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
  410. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
  411. data/test/migrations/missing/1_people_have_last_names.rb +2 -0
  412. data/test/migrations/missing/3_we_need_reminders.rb +2 -0
  413. data/test/migrations/missing/4_innocent_jointable.rb +3 -1
  414. data/test/migrations/rename/1_we_need_things.rb +2 -0
  415. data/test/migrations/rename/2_rename_things.rb +2 -0
  416. data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
  417. data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
  418. data/test/migrations/to_copy2/1_create_articles.rb +2 -0
  419. data/test/migrations/to_copy2/2_create_comments.rb +3 -1
  420. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
  421. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
  422. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
  423. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
  424. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
  425. data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
  426. data/test/migrations/valid/2_we_need_reminders.rb +2 -0
  427. data/test/migrations/valid/3_innocent_jointable.rb +3 -1
  428. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
  429. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
  430. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
  431. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
  432. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
  433. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
  434. data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
  435. data/test/models/account.rb +46 -0
  436. data/test/models/admin/account.rb +3 -1
  437. data/test/models/admin/randomly_named_c1.rb +2 -0
  438. data/test/models/admin/user.rb +16 -8
  439. data/test/models/admin.rb +4 -2
  440. data/test/models/aircraft.rb +3 -1
  441. data/test/models/arunit2_model.rb +2 -0
  442. data/test/models/author.rb +153 -102
  443. data/test/models/auto_id.rb +2 -0
  444. data/test/models/autoloadable/extra_firm.rb +2 -0
  445. data/test/models/binary.rb +3 -1
  446. data/test/models/binary_field.rb +6 -0
  447. data/test/models/bird.rb +13 -1
  448. data/test/models/book.rb +14 -4
  449. data/test/models/book_destroy_async.rb +24 -0
  450. data/test/models/boolean.rb +5 -0
  451. data/test/models/bulb.rb +13 -4
  452. data/test/models/cake_designer.rb +2 -0
  453. data/test/models/car.rb +17 -10
  454. data/test/models/carrier.rb +2 -0
  455. data/test/models/cart.rb +5 -0
  456. data/test/models/cat.rb +2 -0
  457. data/test/models/categorization.rb +8 -6
  458. data/test/models/category.rb +28 -16
  459. data/test/models/chef.rb +2 -0
  460. data/test/models/citation.rb +5 -1
  461. data/test/models/club.rb +13 -10
  462. data/test/models/college.rb +4 -2
  463. data/test/models/column.rb +2 -0
  464. data/test/models/column_name.rb +2 -0
  465. data/test/models/comment.rb +32 -10
  466. data/test/models/company.rb +102 -106
  467. data/test/models/company_in_module.rb +27 -26
  468. data/test/models/computer.rb +3 -1
  469. data/test/models/contact.rb +15 -13
  470. data/test/models/content.rb +5 -3
  471. data/test/models/contract.rb +21 -3
  472. data/test/models/country.rb +2 -4
  473. data/test/models/course.rb +3 -1
  474. data/test/models/customer.rb +10 -8
  475. data/test/models/customer_carrier.rb +2 -0
  476. data/test/models/dashboard.rb +2 -0
  477. data/test/models/default.rb +2 -0
  478. data/test/models/department.rb +2 -0
  479. data/test/models/destroy_async_parent.rb +15 -0
  480. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  481. data/test/models/developer.rb +152 -85
  482. data/test/models/dl_keyed_belongs_to.rb +13 -0
  483. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  484. data/test/models/dl_keyed_has_many.rb +5 -0
  485. data/test/models/dl_keyed_has_many_through.rb +5 -0
  486. data/test/models/dl_keyed_has_one.rb +5 -0
  487. data/test/models/dl_keyed_join.rb +10 -0
  488. data/test/models/dog.rb +2 -0
  489. data/test/models/dog_lover.rb +2 -0
  490. data/test/models/doubloon.rb +3 -1
  491. data/test/models/drink_designer.rb +17 -0
  492. data/test/models/edge.rb +4 -2
  493. data/test/models/electron.rb +2 -0
  494. data/test/models/engine.rb +3 -2
  495. data/test/models/entrant.rb +2 -0
  496. data/test/models/entry.rb +5 -0
  497. data/test/models/essay.rb +6 -3
  498. data/test/models/essay_destroy_async.rb +12 -0
  499. data/test/models/event.rb +3 -1
  500. data/test/models/eye.rb +5 -3
  501. data/test/models/face.rb +14 -6
  502. data/test/models/family.rb +6 -0
  503. data/test/models/family_tree.rb +6 -0
  504. data/test/models/friendship.rb +5 -3
  505. data/test/models/frog.rb +8 -0
  506. data/test/models/guid.rb +3 -1
  507. data/test/models/guitar.rb +2 -0
  508. data/test/models/hotel.rb +5 -3
  509. data/test/models/human.rb +39 -0
  510. data/test/models/image.rb +3 -1
  511. data/test/models/interest.rb +14 -3
  512. data/test/models/invoice.rb +4 -2
  513. data/test/models/item.rb +3 -1
  514. data/test/models/job.rb +5 -3
  515. data/test/models/joke.rb +4 -2
  516. data/test/models/keyboard.rb +3 -1
  517. data/test/models/legacy_thing.rb +2 -0
  518. data/test/models/lesson.rb +2 -0
  519. data/test/models/line_item.rb +3 -1
  520. data/test/models/liquid.rb +2 -0
  521. data/test/models/matey.rb +3 -1
  522. data/test/models/measurement.rb +4 -0
  523. data/test/models/member.rb +23 -20
  524. data/test/models/member_detail.rb +3 -0
  525. data/test/models/member_type.rb +2 -0
  526. data/test/models/membership.rb +4 -1
  527. data/test/models/mentor.rb +3 -1
  528. data/test/models/message.rb +5 -0
  529. data/test/models/minimalistic.rb +2 -0
  530. data/test/models/minivan.rb +3 -2
  531. data/test/models/mixed_case_monkey.rb +3 -1
  532. data/test/models/molecule.rb +2 -0
  533. data/test/models/mouse.rb +6 -0
  534. data/test/models/movie.rb +2 -0
  535. data/test/models/node.rb +4 -2
  536. data/test/models/non_primary_key.rb +2 -0
  537. data/test/models/notification.rb +2 -0
  538. data/test/models/numeric_data.rb +12 -0
  539. data/test/models/order.rb +4 -2
  540. data/test/models/organization.rb +9 -7
  541. data/test/models/other_dog.rb +3 -1
  542. data/test/models/owner.rb +6 -4
  543. data/test/models/parrot.rb +12 -4
  544. data/test/models/person.rb +59 -54
  545. data/test/models/personal_legacy_thing.rb +3 -1
  546. data/test/models/pet.rb +4 -2
  547. data/test/models/pet_treasure.rb +2 -0
  548. data/test/models/pirate.rb +67 -43
  549. data/test/models/possession.rb +3 -1
  550. data/test/models/post.rb +184 -86
  551. data/test/models/price_estimate.rb +11 -1
  552. data/test/models/professor.rb +3 -1
  553. data/test/models/project.rb +14 -12
  554. data/test/models/publisher/article.rb +2 -0
  555. data/test/models/publisher/magazine.rb +2 -0
  556. data/test/models/publisher.rb +2 -0
  557. data/test/models/randomly_named_c1.rb +2 -0
  558. data/test/models/rating.rb +5 -1
  559. data/test/models/reader.rb +7 -5
  560. data/test/models/recipe.rb +2 -0
  561. data/test/models/record.rb +2 -0
  562. data/test/models/reference.rb +6 -3
  563. data/test/models/reply.rb +39 -21
  564. data/test/models/room.rb +6 -0
  565. data/test/models/section.rb +6 -0
  566. data/test/models/seminar.rb +6 -0
  567. data/test/models/session.rb +6 -0
  568. data/test/models/ship.rb +12 -9
  569. data/test/models/ship_part.rb +5 -3
  570. data/test/models/shop.rb +4 -2
  571. data/test/models/shop_account.rb +2 -0
  572. data/test/models/speedometer.rb +2 -0
  573. data/test/models/sponsor.rb +8 -5
  574. data/test/models/squeak.rb +6 -0
  575. data/test/models/strict_zine.rb +7 -0
  576. data/test/models/string_key_object.rb +2 -0
  577. data/test/models/student.rb +2 -0
  578. data/test/models/subscriber.rb +4 -2
  579. data/test/models/subscription.rb +5 -1
  580. data/test/models/tag.rb +6 -3
  581. data/test/models/tagging.rb +13 -6
  582. data/test/models/task.rb +2 -0
  583. data/test/models/topic.rb +54 -19
  584. data/test/models/toy.rb +4 -0
  585. data/test/models/traffic_light.rb +2 -0
  586. data/test/models/treasure.rb +5 -3
  587. data/test/models/treaty.rb +2 -4
  588. data/test/models/tree.rb +2 -0
  589. data/test/models/tuning_peg.rb +2 -0
  590. data/test/models/tyre.rb +2 -0
  591. data/test/models/user.rb +12 -4
  592. data/test/models/uuid_child.rb +2 -0
  593. data/test/models/uuid_item.rb +2 -0
  594. data/test/models/uuid_parent.rb +2 -0
  595. data/test/models/vegetables.rb +12 -3
  596. data/test/models/vertex.rb +6 -4
  597. data/test/models/warehouse_thing.rb +2 -0
  598. data/test/models/wheel.rb +3 -1
  599. data/test/models/without_table.rb +3 -1
  600. data/test/models/zine.rb +3 -1
  601. data/test/schema/mysql2_specific_schema.rb +49 -35
  602. data/test/schema/oracle_specific_schema.rb +13 -15
  603. data/test/schema/postgresql_specific_schema.rb +51 -40
  604. data/test/schema/schema.rb +334 -154
  605. data/test/schema/sqlite_specific_schema.rb +9 -16
  606. data/test/support/config.rb +26 -26
  607. data/test/support/connection.rb +14 -8
  608. data/test/support/connection_helper.rb +3 -1
  609. data/test/support/ddl_helper.rb +2 -0
  610. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  611. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  612. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  613. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  614. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  615. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  616. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  617. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  618. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  619. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  620. data/test/support/schema_dumping_helper.rb +2 -0
  621. data/test/support/stubs/strong_parameters.rb +40 -0
  622. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  623. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  624. metadata +196 -11
@@ -1,38 +1,77 @@
1
- require 'cases/helper'
2
- require 'models/developer'
3
- require 'models/project'
4
- require 'models/company'
5
- require 'models/topic'
6
- require 'models/reply'
7
- require 'models/computer'
8
- require 'models/post'
9
- require 'models/author'
10
- require 'models/tag'
11
- require 'models/tagging'
12
- require 'models/comment'
13
- require 'models/sponsor'
14
- require 'models/member'
15
- require 'models/essay'
16
- require 'models/toy'
17
- require 'models/invoice'
18
- require 'models/line_item'
19
- require 'models/column'
20
- require 'models/record'
21
- require 'models/admin'
22
- require 'models/admin/user'
23
- require 'models/ship'
24
- require 'models/treasure'
25
- require 'models/parrot'
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "models/developer"
5
+ require "models/project"
6
+ require "models/company"
7
+ require "models/topic"
8
+ require "models/reply"
9
+ require "models/computer"
10
+ require "models/post"
11
+ require "models/author"
12
+ require "models/tag"
13
+ require "models/tagging"
14
+ require "models/comment"
15
+ require "models/sponsor"
16
+ require "models/member"
17
+ require "models/essay"
18
+ require "models/toy"
19
+ require "models/invoice"
20
+ require "models/line_item"
21
+ require "models/column"
22
+ require "models/record"
23
+ require "models/admin"
24
+ require "models/admin/user"
25
+ require "models/ship"
26
+ require "models/treasure"
27
+ require "models/parrot"
28
+ require "models/book"
29
+ require "models/citation"
26
30
 
27
31
  class BelongsToAssociationsTest < ActiveRecord::TestCase
28
32
  fixtures :accounts, :companies, :developers, :projects, :topics,
29
33
  :developers_projects, :computers, :authors, :author_addresses,
30
- :posts, :tags, :taggings, :comments, :sponsors, :members
34
+ :essays, :posts, :tags, :taggings, :comments, :sponsors, :members
31
35
 
32
36
  def test_belongs_to
33
- firm = Client.find(3).firm
34
- assert_not_nil firm
35
- assert_equal companies(:first_firm).name, firm.name
37
+ client = Client.find(3)
38
+ first_firm = companies(:first_firm)
39
+ assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) do
40
+ assert_equal first_firm, client.firm
41
+ assert_equal first_firm.name, client.firm.name
42
+ end
43
+ end
44
+
45
+ def test_where_with_custom_primary_key
46
+ assert_equal [authors(:david)], Author.where(owned_essay: essays(:david_modest_proposal))
47
+ end
48
+
49
+ def test_find_by_with_custom_primary_key
50
+ assert_equal authors(:david), Author.find_by(owned_essay: essays(:david_modest_proposal))
51
+ end
52
+
53
+ def test_where_on_polymorphic_association_with_nil
54
+ assert_equal comments(:greetings), Comment.where(author: nil).first
55
+ assert_equal comments(:greetings), Comment.where(author: [nil]).first
56
+ end
57
+
58
+ def test_where_on_polymorphic_association_with_empty_array
59
+ assert_empty Comment.where(author: [])
60
+ end
61
+
62
+ def test_assigning_belongs_to_on_destroyed_object
63
+ client = Client.create!(name: "Client")
64
+ client.destroy!
65
+ assert_raise(FrozenError) { client.firm = nil }
66
+ assert_raise(FrozenError) { client.firm = Firm.new(name: "Firm") }
67
+ end
68
+
69
+ def test_eager_loading_wont_mutate_owner_record
70
+ client = Client.eager_load(:firm_with_basic_id).first
71
+ assert_not_predicate client, :firm_id_came_from_user?
72
+
73
+ client = Client.preload(:firm_with_basic_id).first
74
+ assert_not_predicate client, :firm_id_came_from_user?
36
75
  end
37
76
 
38
77
  def test_missing_attribute_error_is_raised_when_no_foreign_key_attribute
@@ -40,14 +79,12 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
40
79
  end
41
80
 
42
81
  def test_belongs_to_does_not_use_order_by
43
- ActiveRecord::SQLCounter.clear_log
44
- Client.find(3).firm
45
- ensure
46
- assert ActiveRecord::SQLCounter.log_all.all? { |sql| /order by/i !~ sql }, 'ORDER BY was used in the query'
82
+ sql_log = capture_sql { Client.find(3).firm }
83
+ assert sql_log.all? { |sql| !/order by/i.match?(sql) }, "ORDER BY was used in the query: #{sql_log}"
47
84
  end
48
85
 
49
86
  def test_belongs_to_with_primary_key
50
- client = Client.create(:name => "Primary key client", :firm_name => companies(:first_firm).name)
87
+ client = Client.create(name: "Primary key client", firm_name: companies(:first_firm).name)
51
88
  assert_equal companies(:first_firm).name, client.firm_with_primary_key.name
52
89
  end
53
90
 
@@ -60,16 +97,39 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
60
97
  # on Oracle aliases are truncated to 30 characters and are quoted in uppercase
61
98
  assert_no_match(/"firm_with_primary_keys_compani"\."id"/i, sql)
62
99
  assert_match(/"firm_with_primary_keys_compani"\."name"/i, sql)
63
- elsif current_adapter?(:IBM_DBAdapter)
64
- # Quoting of column names is not necessary for IBM_DB
65
- assert_no_match(/firm_with_primary_keys_companies\.id/i, sql)
66
- assert_match(/firm_with_primary_keys_companies\.name/i, sql)
67
100
  else
68
- assert_no_match(/"firm_with_primary_keys_companies"\."id"/, sql)
69
- assert_match(/"firm_with_primary_keys_companies"\."name"/, sql)
101
+ assert_no_match(/firm_with_primary_keys_companies\.id/, sql)
102
+ assert_match(/firm_with_primary_keys_companies\.name/, sql)
70
103
  end
71
104
  end
72
105
 
106
+ def test_optional_relation_can_be_set_per_model
107
+ model1 = Class.new(ActiveRecord::Base) do
108
+ self.table_name = "accounts"
109
+ self.belongs_to_required_by_default = false
110
+
111
+ belongs_to :company
112
+
113
+ def self.name
114
+ "FirstModel"
115
+ end
116
+ end.new
117
+
118
+ model2 = Class.new(ActiveRecord::Base) do
119
+ self.table_name = "accounts"
120
+ self.belongs_to_required_by_default = true
121
+
122
+ belongs_to :company
123
+
124
+ def self.name
125
+ "SecondModel"
126
+ end
127
+ end.new
128
+
129
+ assert_predicate model1, :valid?
130
+ assert_not_predicate model2, :valid?
131
+ end
132
+
73
133
  def test_optional_relation
74
134
  original_value = ActiveRecord::Base.belongs_to_required_by_default
75
135
  ActiveRecord::Base.belongs_to_required_by_default = true
@@ -81,7 +141,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
81
141
  end
82
142
 
83
143
  account = model.new
84
- assert account.valid?
144
+ assert_predicate account, :valid?
85
145
  ensure
86
146
  ActiveRecord::Base.belongs_to_required_by_default = original_value
87
147
  end
@@ -97,8 +157,8 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
97
157
  end
98
158
 
99
159
  account = model.new
100
- assert_not account.valid?
101
- assert_equal [{error: :blank}], account.errors.details[:company]
160
+ assert_not_predicate account, :valid?
161
+ assert_equal [{ error: :blank }], account.errors.details[:company]
102
162
  ensure
103
163
  ActiveRecord::Base.belongs_to_required_by_default = original_value
104
164
  end
@@ -114,31 +174,69 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
114
174
  end
115
175
 
116
176
  account = model.new
117
- assert_not account.valid?
118
- assert_equal [{error: :blank}], account.errors.details[:company]
177
+ assert_not_predicate account, :valid?
178
+ assert_equal [{ error: :blank }], account.errors.details[:company]
119
179
  ensure
120
180
  ActiveRecord::Base.belongs_to_required_by_default = original_value
121
181
  end
122
182
 
183
+ def test_default
184
+ david = developers(:david)
185
+ jamis = developers(:jamis)
186
+
187
+ model = Class.new(ActiveRecord::Base) do
188
+ self.table_name = "ships"
189
+ def self.name; "Temp"; end
190
+ belongs_to :developer, default: -> { david }
191
+ end
192
+
193
+ ship = model.create!
194
+ assert_equal david, ship.developer
195
+
196
+ ship = model.create!(developer: jamis)
197
+ assert_equal jamis, ship.developer
198
+
199
+ ship.update!(developer: nil)
200
+ assert_equal david, ship.developer
201
+ end
202
+
203
+ def test_default_with_lambda
204
+ model = Class.new(ActiveRecord::Base) do
205
+ self.table_name = "ships"
206
+ def self.name; "Temp"; end
207
+ belongs_to :developer, default: -> { default_developer }
208
+
209
+ def default_developer
210
+ Developer.first
211
+ end
212
+ end
213
+
214
+ ship = model.create!
215
+ assert_equal developers(:david), ship.developer
216
+
217
+ ship = model.create!(developer: developers(:jamis))
218
+ assert_equal developers(:jamis), ship.developer
219
+ end
220
+
123
221
  def test_default_scope_on_relations_is_not_cached
124
222
  counter = 0
125
223
 
126
224
  comments = Class.new(ActiveRecord::Base) {
127
- self.table_name = 'comments'
128
- self.inheritance_column = 'not_there'
225
+ self.table_name = "comments"
226
+ self.inheritance_column = "not_there"
129
227
 
130
228
  posts = Class.new(ActiveRecord::Base) {
131
- self.table_name = 'posts'
132
- self.inheritance_column = 'not_there'
229
+ self.table_name = "posts"
230
+ self.inheritance_column = "not_there"
133
231
 
134
232
  default_scope -> {
135
233
  counter += 1
136
- where("id = :inc", :inc => counter)
234
+ where("id = :inc", inc: counter)
137
235
  }
138
236
 
139
- has_many :comments, :anonymous_class => comments
237
+ has_many :comments, anonymous_class: comments
140
238
  }
141
- belongs_to :post, :anonymous_class => posts, :inverse_of => false
239
+ belongs_to :post, anonymous_class: posts, inverse_of: false
142
240
  }
143
241
 
144
242
  assert_equal 0, counter
@@ -163,16 +261,16 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
163
261
  assert_nil defined?(Region), "This test requires that there is no top-level Region class"
164
262
 
165
263
  ActiveRecord::Base.connection.instance_eval do
166
- create_table(:admin_regions) { |t| t.string :name }
264
+ create_table(:admin_regions, force: true) { |t| t.string :name }
167
265
  add_column :admin_users, :region_id, :integer
168
266
  end
169
267
  Admin.const_set "RegionalUser", Class.new(Admin::User) { belongs_to(:region) }
170
268
  Admin.const_set "Region", Class.new(ActiveRecord::Base)
171
269
 
172
270
  e = assert_raise(ActiveRecord::AssociationTypeMismatch) {
173
- Admin::RegionalUser.new(region: 'wrong value')
271
+ Admin::RegionalUser.new(region: "wrong value")
174
272
  }
175
- assert_match(/^Region\([^)]+\) expected, got String\([^)]+\)$/, e.message)
273
+ assert_match(/^Region\([^)]+\) expected, got "wrong value" which is an instance of String\([^)]+\)$/, e.message)
176
274
  ensure
177
275
  Admin.send :remove_const, "Region" if Admin.const_defined?("Region")
178
276
  Admin.send :remove_const, "RegionalUser" if Admin.const_defined?("RegionalUser")
@@ -181,6 +279,8 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
181
279
  remove_column :admin_users, :region_id if column_exists?(:admin_users, :region_id)
182
280
  drop_table :admin_regions, if_exists: true
183
281
  end
282
+
283
+ Admin::User.reset_column_information
184
284
  end
185
285
 
186
286
  def test_natural_assignment
@@ -207,15 +307,15 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
207
307
  def test_eager_loading_with_primary_key
208
308
  Firm.create("name" => "Apple")
209
309
  Client.create("name" => "Citibank", :firm_name => "Apple")
210
- citibank_result = Client.all.merge!(:where => {:name => "Citibank"}, :includes => :firm_with_primary_key).first
211
- assert citibank_result.association(:firm_with_primary_key).loaded?
310
+ citibank_result = Client.all.merge!(where: { name: "Citibank" }, includes: :firm_with_primary_key).first
311
+ assert_predicate citibank_result.association(:firm_with_primary_key), :loaded?
212
312
  end
213
313
 
214
314
  def test_eager_loading_with_primary_key_as_symbol
215
315
  Firm.create("name" => "Apple")
216
316
  Client.create("name" => "Citibank", :firm_name => "Apple")
217
- citibank_result = Client.all.merge!(:where => {:name => "Citibank"}, :includes => :firm_with_primary_key_symbols).first
218
- assert citibank_result.association(:firm_with_primary_key_symbols).loaded?
317
+ citibank_result = Client.all.merge!(where: { name: "Citibank" }, includes: :firm_with_primary_key_symbols).first
318
+ assert_predicate citibank_result.association(:firm_with_primary_key_symbols), :loaded?
219
319
  end
220
320
 
221
321
  def test_creating_the_belonging_object
@@ -227,8 +327,17 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
227
327
  assert_equal apple, citibank.firm
228
328
  end
229
329
 
330
+ def test_creating_the_belonging_object_from_new_record
331
+ citibank = Account.new("credit_limit" => 10)
332
+ apple = citibank.create_firm("name" => "Apple")
333
+ assert_equal apple, citibank.firm
334
+ citibank.save
335
+ citibank.reload
336
+ assert_equal apple, citibank.firm
337
+ end
338
+
230
339
  def test_creating_the_belonging_object_with_primary_key
231
- client = Client.create(:name => "Primary key client")
340
+ client = Client.create(name: "Primary key client")
232
341
  apple = client.create_firm_with_primary_key("name" => "Apple")
233
342
  assert_equal apple, client.firm_with_primary_key
234
343
  client.save
@@ -251,48 +360,48 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
251
360
 
252
361
  def test_building_the_belonging_object_with_explicit_sti_base_class
253
362
  account = Account.new
254
- company = account.build_firm(:type => "Company")
363
+ company = account.build_firm(type: "Company")
255
364
  assert_kind_of Company, company, "Expected #{company.class} to be a Company"
256
365
  end
257
366
 
258
367
  def test_building_the_belonging_object_with_sti_subclass
259
368
  account = Account.new
260
- company = account.build_firm(:type => "Firm")
369
+ company = account.build_firm(type: "Firm")
261
370
  assert_kind_of Firm, company, "Expected #{company.class} to be a Firm"
262
371
  end
263
372
 
264
373
  def test_building_the_belonging_object_with_an_invalid_type
265
374
  account = Account.new
266
- assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(:type => "InvalidType") }
375
+ assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(type: "InvalidType") }
267
376
  end
268
377
 
269
378
  def test_building_the_belonging_object_with_an_unrelated_type
270
379
  account = Account.new
271
- assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(:type => "Account") }
380
+ assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(type: "Account") }
272
381
  end
273
382
 
274
383
  def test_building_the_belonging_object_with_primary_key
275
- client = Client.create(:name => "Primary key client")
384
+ client = Client.create(name: "Primary key client")
276
385
  apple = client.build_firm_with_primary_key("name" => "Apple")
277
386
  client.save
278
387
  assert_equal apple.name, client.firm_name
279
388
  end
280
389
 
281
390
  def test_create!
282
- client = Client.create!(:name => "Jimmy")
283
- account = client.create_account!(:credit_limit => 10)
391
+ client = Client.create!(name: "Jimmy")
392
+ account = client.create_account!(credit_limit: 10)
284
393
  assert_equal account, client.account
285
- assert account.persisted?
394
+ assert_predicate account, :persisted?
286
395
  client.save
287
396
  client.reload
288
397
  assert_equal account, client.account
289
398
  end
290
399
 
291
400
  def test_failing_create!
292
- client = Client.create!(:name => "Jimmy")
401
+ client = Client.create!(name: "Jimmy")
293
402
  assert_raise(ActiveRecord::RecordInvalid) { client.create_account! }
294
403
  assert_not_nil client.account
295
- assert client.account.new_record?
404
+ assert_predicate client.account, :new_record?
296
405
  end
297
406
 
298
407
  def test_reloading_the_belonging_object
@@ -305,6 +414,30 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
305
414
  assert_equal "ODEGY", odegy_account.reload_firm.name
306
415
  end
307
416
 
417
+ def test_reload_the_belonging_object_with_query_cache
418
+ odegy_account_id = accounts(:odegy_account).id
419
+
420
+ connection = ActiveRecord::Base.connection
421
+ connection.enable_query_cache!
422
+ connection.clear_query_cache
423
+
424
+ # Populate the cache with a query
425
+ odegy_account = Account.find(odegy_account_id)
426
+
427
+ # Populate the cache with a second query
428
+ odegy_account.firm
429
+
430
+ assert_equal 2, connection.query_cache.size
431
+
432
+ # Clear the cache and fetch the firm again, populating the cache with a query
433
+ assert_queries(1) { odegy_account.reload_firm }
434
+
435
+ # This query is not cached anymore, so it should make a real SQL query
436
+ assert_queries(1) { Account.find(odegy_account_id) }
437
+ ensure
438
+ ActiveRecord::Base.connection.disable_query_cache!
439
+ end
440
+
308
441
  def test_natural_assignment_to_nil
309
442
  client = Client.find(3)
310
443
  client.firm = nil
@@ -315,7 +448,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
315
448
  end
316
449
 
317
450
  def test_natural_assignment_to_nil_with_primary_key
318
- client = Client.create(:name => "Primary key client", :firm_name => companies(:first_firm).name)
451
+ client = Client.create(name: "Primary key client", firm_name: companies(:first_firm).name)
319
452
  client.firm_with_primary_key = nil
320
453
  client.save
321
454
  client.association(:firm_with_primary_key).reload
@@ -335,41 +468,52 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
335
468
 
336
469
  def test_polymorphic_association_class
337
470
  sponsor = Sponsor.new
338
- assert_nil sponsor.association(:sponsorable).send(:klass)
471
+ assert_nil sponsor.association(:sponsorable).klass
339
472
  sponsor.association(:sponsorable).reload
340
473
  assert_nil sponsor.sponsorable
341
474
 
342
- sponsor.sponsorable_type = '' # the column doesn't have to be declared NOT NULL
343
- assert_nil sponsor.association(:sponsorable).send(:klass)
475
+ sponsor.sponsorable_type = "" # the column doesn't have to be declared NOT NULL
476
+ assert_nil sponsor.association(:sponsorable).klass
344
477
  sponsor.association(:sponsorable).reload
345
478
  assert_nil sponsor.sponsorable
346
479
 
347
- sponsor.sponsorable = Member.new :name => "Bert"
348
- assert_equal Member, sponsor.association(:sponsorable).send(:klass)
349
- assert_equal "members", sponsor.association(:sponsorable).aliased_table_name
480
+ sponsor.sponsorable = Member.new name: "Bert"
481
+ assert_equal Member, sponsor.association(:sponsorable).klass
350
482
  end
351
483
 
352
484
  def test_with_polymorphic_and_condition
353
485
  sponsor = Sponsor.create
354
- member = Member.create :name => "Bert"
486
+ member = Member.create name: "Bert"
487
+
355
488
  sponsor.sponsorable = member
489
+ sponsor.save!
490
+
491
+ assert_equal member, sponsor.sponsorable
492
+ assert_nil sponsor.sponsorable_with_conditions
493
+
494
+ sponsor = Sponsor.preload(:sponsorable, :sponsorable_with_conditions).last
356
495
 
357
496
  assert_equal member, sponsor.sponsorable
358
497
  assert_nil sponsor.sponsorable_with_conditions
359
498
  end
360
499
 
361
500
  def test_with_select
362
- assert_equal 1, Company.find(2).firm_with_select.attributes.size
363
- assert_equal 1, Company.all.merge!(:includes => :firm_with_select ).find(2).firm_with_select.attributes.size
501
+ assert_equal 1, Post.find(2).author_with_select.attributes.size
502
+ assert_equal 1, Post.includes(:author_with_select).find(2).author_with_select.attributes.size
503
+ end
504
+
505
+ def test_custom_attribute_with_select
506
+ assert_equal 2, Company.find(2).firm_with_select.attributes.size
507
+ assert_equal 2, Company.includes(:firm_with_select).find(2).firm_with_select.attributes.size
364
508
  end
365
509
 
366
510
  def test_belongs_to_without_counter_cache_option
367
511
  # Ship has a conventionally named `treasures_count` column, but the counter_cache
368
512
  # option is not given on the association.
369
- ship = Ship.create(name: 'Countless')
513
+ ship = Ship.create(name: "Countless")
370
514
 
371
515
  assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed unless counter_cache is given on the relation" do
372
- treasure = Treasure.new(name: 'Gold', ship: ship)
516
+ treasure = Treasure.new(name: "Gold", ship: ship)
373
517
  treasure.save
374
518
  end
375
519
 
@@ -391,31 +535,70 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
391
535
  end
392
536
 
393
537
  def test_belongs_to_counter_with_assigning_nil
394
- post = Post.find(1)
395
- comment = Comment.find(1)
538
+ topic = Topic.create!(title: "debate")
539
+ reply = Reply.create!(title: "blah!", content: "world around!", topic: topic)
540
+
541
+ assert_equal topic.id, reply.parent_id
542
+ assert_equal 1, topic.reload.replies.size
396
543
 
397
- assert_equal post.id, comment.post_id
398
- assert_equal 2, Post.find(post.id).comments.size
544
+ reply.topic = nil
545
+ reply.reload
399
546
 
400
- comment.post = nil
547
+ assert_equal topic.id, reply.parent_id
548
+ assert_equal 1, topic.reload.replies.size
401
549
 
402
- assert_equal 1, Post.find(post.id).comments.size
550
+ reply.topic = nil
551
+ reply.save!
552
+
553
+ assert_equal 0, topic.reload.replies.size
554
+ end
555
+
556
+ def test_belongs_to_counter_with_assigning_new_object
557
+ topic = Topic.create!(title: "debate")
558
+ reply = Reply.create!(title: "blah!", content: "world around!", topic: topic)
559
+
560
+ assert_equal topic.id, reply.parent_id
561
+ assert_equal 1, topic.reload.replies_count
562
+
563
+ topic2 = reply.build_topic(title: "debate2")
564
+ reply.save!
565
+
566
+ assert_not_equal topic.id, reply.parent_id
567
+ assert_equal topic2.id, reply.parent_id
568
+
569
+ assert_equal 0, topic.reload.replies_count
570
+ assert_equal 1, topic2.reload.replies_count
403
571
  end
404
572
 
405
573
  def test_belongs_to_with_primary_key_counter
406
574
  debate = Topic.create("title" => "debate")
407
575
  debate2 = Topic.create("title" => "debate2")
408
- reply = Reply.create("title" => "blah!", "content" => "world around!", "parent_title" => "debate")
576
+ reply = Reply.create("title" => "blah!", "content" => "world around!", "parent_title" => "debate2")
577
+
578
+ assert_equal 0, debate.reload.replies_count
579
+ assert_equal 1, debate2.reload.replies_count
580
+
581
+ reply.parent_title = "debate"
582
+ reply.save!
583
+
584
+ assert_equal 1, debate.reload.replies_count
585
+ assert_equal 0, debate2.reload.replies_count
586
+
587
+ assert_no_queries do
588
+ reply.topic_with_primary_key = debate
589
+ end
409
590
 
410
591
  assert_equal 1, debate.reload.replies_count
411
592
  assert_equal 0, debate2.reload.replies_count
412
593
 
413
594
  reply.topic_with_primary_key = debate2
595
+ reply.save!
414
596
 
415
597
  assert_equal 0, debate.reload.replies_count
416
598
  assert_equal 1, debate2.reload.replies_count
417
599
 
418
600
  reply.topic_with_primary_key = nil
601
+ reply.save!
419
602
 
420
603
  assert_equal 0, debate.reload.replies_count
421
604
  assert_equal 0, debate2.reload.replies_count
@@ -442,11 +625,13 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
442
625
  assert_equal 1, Topic.find(topic2.id).replies.size
443
626
 
444
627
  reply1.topic = nil
628
+ reply1.save!
445
629
 
446
630
  assert_equal 0, Topic.find(topic1.id).replies.size
447
631
  assert_equal 0, Topic.find(topic2.id).replies.size
448
632
 
449
633
  reply1.topic = topic1
634
+ reply1.save!
450
635
 
451
636
  assert_equal 1, Topic.find(topic1.id).replies.size
452
637
  assert_equal 0, Topic.find(topic2.id).replies.size
@@ -475,14 +660,65 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
475
660
  end
476
661
 
477
662
  def test_belongs_to_counter_after_save
478
- topic = Topic.create!(:title => "monday night")
479
- topic.replies.create!(:title => "re: monday night", :content => "football")
663
+ topic = Topic.create!(title: "monday night")
664
+
665
+ assert_queries(2) do
666
+ topic.replies.create!(title: "re: monday night", content: "football")
667
+ end
668
+
480
669
  assert_equal 1, Topic.find(topic.id)[:replies_count]
481
670
 
482
671
  topic.save!
483
672
  assert_equal 1, Topic.find(topic.id)[:replies_count]
484
673
  end
485
674
 
675
+ def test_belongs_to_counter_after_touch
676
+ topic = Topic.create!(title: "topic")
677
+
678
+ assert_equal 0, topic.replies_count
679
+ assert_equal 0, topic.after_touch_called
680
+
681
+ reply = Reply.create!(title: "blah!", content: "world around!", topic_with_primary_key: topic)
682
+
683
+ assert_equal 1, topic.replies_count
684
+ assert_equal 1, topic.after_touch_called
685
+
686
+ reply.destroy!
687
+
688
+ assert_equal 0, topic.replies_count
689
+ assert_equal 2, topic.after_touch_called
690
+ end
691
+
692
+ def test_belongs_to_touch_with_reassigning
693
+ debate = Topic.create!(title: "debate")
694
+ debate2 = Topic.create!(title: "debate2")
695
+ reply = Reply.create!(title: "blah!", content: "world around!", parent_title: "debate2")
696
+
697
+ time = 1.day.ago
698
+
699
+ debate.touch(time: time)
700
+ debate2.touch(time: time)
701
+
702
+ assert_queries(3) do
703
+ reply.parent_title = "debate"
704
+ reply.save!
705
+ end
706
+
707
+ assert_operator debate.reload.updated_at, :>, time
708
+ assert_operator debate2.reload.updated_at, :>, time
709
+
710
+ debate.touch(time: time)
711
+ debate2.touch(time: time)
712
+
713
+ assert_queries(3) do
714
+ reply.topic_with_primary_key = debate2
715
+ reply.save!
716
+ end
717
+
718
+ assert_operator debate.reload.updated_at, :>, time
719
+ assert_operator debate2.reload.updated_at, :>, time
720
+ end
721
+
486
722
  def test_belongs_to_with_touch_option_on_touch
487
723
  line_item = LineItem.create!
488
724
  Invoice.create!(line_items: [line_item])
@@ -541,7 +777,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
541
777
  line_item = LineItem.create!
542
778
  Invoice.create!(line_items: [line_item])
543
779
 
544
- assert_queries(0) { line_item.save }
780
+ assert_no_queries { line_item.save }
545
781
  end
546
782
 
547
783
  def test_belongs_to_with_touch_option_on_destroy
@@ -578,8 +814,8 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
578
814
  end
579
815
 
580
816
  def test_belongs_to_counter_when_update_columns
581
- topic = Topic.create!(:title => "37s")
582
- topic.replies.create!(:title => "re: 37s", :content => "rails")
817
+ topic = Topic.create!(title: "37s")
818
+ topic.replies.create!(title: "re: 37s", content: "rails")
583
819
  assert_equal 1, Topic.find(topic.id)[:replies_count]
584
820
 
585
821
  topic.update_columns(content: "rails is wonderful")
@@ -590,10 +826,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
590
826
  final_cut = Client.new("name" => "Final Cut")
591
827
  firm = Firm.find(1)
592
828
  final_cut.firm = firm
593
- assert !final_cut.persisted?
829
+ assert_not_predicate final_cut, :persisted?
594
830
  assert final_cut.save
595
- assert final_cut.persisted?
596
- assert firm.persisted?
831
+ assert_predicate final_cut, :persisted?
832
+ assert_predicate firm, :persisted?
597
833
  assert_equal firm, final_cut.firm
598
834
  final_cut.association(:firm).reload
599
835
  assert_equal firm, final_cut.firm
@@ -603,10 +839,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
603
839
  final_cut = Client.new("name" => "Final Cut")
604
840
  firm = Firm.find(1)
605
841
  final_cut.firm_with_primary_key = firm
606
- assert !final_cut.persisted?
842
+ assert_not_predicate final_cut, :persisted?
607
843
  assert final_cut.save
608
- assert final_cut.persisted?
609
- assert firm.persisted?
844
+ assert_predicate final_cut, :persisted?
845
+ assert_predicate firm, :persisted?
610
846
  assert_equal firm, final_cut.firm_with_primary_key
611
847
  final_cut.association(:firm_with_primary_key).reload
612
848
  assert_equal firm, final_cut.firm_with_primary_key
@@ -614,8 +850,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
614
850
 
615
851
  def test_new_record_with_foreign_key_but_no_object
616
852
  client = Client.new("firm_id" => 1)
617
- # sometimes tests on Oracle fail if ORDER BY is not provided therefore add always :order with :first
618
- assert_equal Firm.all.merge!(:order => "id").first, client.firm_with_basic_id
853
+ assert_equal Firm.first, client.firm_with_basic_id
619
854
  end
620
855
 
621
856
  def test_setting_foreign_key_after_nil_target_loaded
@@ -637,7 +872,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
637
872
 
638
873
  def test_dont_find_target_when_foreign_key_is_null
639
874
  tagging = taggings(:thinking_general)
640
- assert_queries(0) { tagging.super_tag }
875
+ assert_no_queries { tagging.super_tag }
641
876
  end
642
877
 
643
878
  def test_dont_find_target_when_saving_foreign_key_after_stale_association_loaded
@@ -652,11 +887,12 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
652
887
  end
653
888
 
654
889
  def test_counter_cache
655
- topic = Topic.create :title => "Zoom-zoom-zoom"
890
+ topic = Topic.create title: "Zoom-zoom-zoom"
656
891
  assert_equal 0, topic[:replies_count]
657
892
 
658
- reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
893
+ reply = Reply.create(title: "re: zoom", content: "speedy quick!")
659
894
  reply.topic = topic
895
+ reply.save!
660
896
 
661
897
  assert_equal 1, topic.reload[:replies_count]
662
898
  assert_equal 1, topic.replies.size
@@ -666,10 +902,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
666
902
  end
667
903
 
668
904
  def test_counter_cache_double_destroy
669
- topic = Topic.create :title => "Zoom-zoom-zoom"
905
+ topic = Topic.create title: "Zoom-zoom-zoom"
670
906
 
671
907
  5.times do
672
- topic.replies.create(:title => "re: zoom", :content => "speedy quick!")
908
+ topic.replies.create(title: "re: zoom", content: "speedy quick!")
673
909
  end
674
910
 
675
911
  assert_equal 5, topic.reload[:replies_count]
@@ -686,10 +922,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
686
922
  end
687
923
 
688
924
  def test_concurrent_counter_cache_double_destroy
689
- topic = Topic.create :title => "Zoom-zoom-zoom"
925
+ topic = Topic.create title: "Zoom-zoom-zoom"
690
926
 
691
927
  5.times do
692
- topic.replies.create(:title => "re: zoom", :content => "speedy quick!")
928
+ topic.replies.create(title: "re: zoom", content: "speedy quick!")
693
929
  end
694
930
 
695
931
  assert_equal 5, topic.reload[:replies_count]
@@ -707,11 +943,12 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
707
943
  end
708
944
 
709
945
  def test_custom_counter_cache
710
- reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
946
+ reply = Reply.create(title: "re: zoom", content: "speedy quick!")
711
947
  assert_equal 0, reply[:replies_count]
712
948
 
713
- silly = SillyReply.create(:title => "gaga", :content => "boo-boo")
949
+ silly = SillyReply.create(title: "gaga", content: "boo-boo")
714
950
  silly.reply = reply
951
+ silly.save!
715
952
 
716
953
  assert_equal 1, reply.reload[:replies_count]
717
954
  assert_equal 1, reply.replies.size
@@ -734,7 +971,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
734
971
  def test_association_assignment_sticks
735
972
  post = Post.first
736
973
 
737
- author1, author2 = Author.all.merge!(:limit => 2).to_a
974
+ author1, author2 = Author.all.merge!(limit: 2).to_a
738
975
  assert_not_nil author1
739
976
  assert_not_nil author2
740
977
 
@@ -754,7 +991,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
754
991
 
755
992
  def test_cant_save_readonly_association
756
993
  assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_client).readonly_firm.save! }
757
- assert companies(:first_client).readonly_firm.readonly?
994
+ assert_predicate companies(:first_client).readonly_firm, :readonly?
758
995
  end
759
996
 
760
997
  def test_polymorphic_assignment_foreign_key_type_string
@@ -787,7 +1024,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
787
1024
  def test_polymorphic_assignment_with_primary_key_foreign_type_field_updating
788
1025
  # should update when assigning a saved record
789
1026
  essay = Essay.new
790
- writer = Author.create(:name => "David")
1027
+ writer = Author.create(name: "David")
791
1028
  essay.writer = writer
792
1029
  assert_equal "Author", essay.writer_type
793
1030
 
@@ -812,7 +1049,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
812
1049
 
813
1050
  def test_assignment_updates_foreign_id_field_for_new_and_saved_records
814
1051
  client = Client.new
815
- saved_firm = Firm.create :name => "Saved"
1052
+ saved_firm = Firm.create name: "Saved"
816
1053
  new_firm = Firm.new
817
1054
 
818
1055
  client.firm = saved_firm
@@ -824,7 +1061,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
824
1061
 
825
1062
  def test_polymorphic_assignment_with_primary_key_updates_foreign_id_field_for_new_and_saved_records
826
1063
  essay = Essay.new
827
- saved_writer = Author.create(:name => "David")
1064
+ saved_writer = Author.create(name: "David")
828
1065
  new_writer = Author.new
829
1066
 
830
1067
  essay.writer = saved_writer
@@ -840,7 +1077,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
840
1077
  assert_nil essay.writer_type
841
1078
 
842
1079
  essay.writer_id = 1
843
- essay.writer_type = 'Author'
1080
+ essay.writer_type = "Author"
844
1081
 
845
1082
  essay.writer = nil
846
1083
  assert_nil essay.writer_id
@@ -862,14 +1099,14 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
862
1099
 
863
1100
  assert_nothing_raised do
864
1101
  Account.find(@account.id).save!
865
- Account.all.merge!(:includes => :firm).find(@account.id).save!
1102
+ Account.all.merge!(includes: :firm).find(@account.id).save!
866
1103
  end
867
1104
 
868
1105
  @account.firm.delete
869
1106
 
870
1107
  assert_nothing_raised do
871
1108
  Account.find(@account.id).save!
872
- Account.all.merge!(:includes => :firm).find(@account.id).save!
1109
+ Account.all.merge!(includes: :firm).find(@account.id).save!
873
1110
  end
874
1111
  end
875
1112
 
@@ -890,18 +1127,58 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
890
1127
 
891
1128
  def test_belongs_to_invalid_dependent_option_raises_exception
892
1129
  error = assert_raise ArgumentError do
893
- Class.new(Author).belongs_to :special_author_address, :dependent => :nullify
1130
+ Class.new(Author).belongs_to :special_author_address, dependent: :nullify
1131
+ end
1132
+ assert_equal error.message, "The :dependent option must be one of [:destroy, :delete, :destroy_async], but is :nullify"
1133
+ end
1134
+
1135
+ class EssayDestroy < ActiveRecord::Base
1136
+ self.table_name = "essays"
1137
+ belongs_to :book, dependent: :destroy, class_name: "DestroyableBook"
1138
+ end
1139
+
1140
+ class DestroyableBook < ActiveRecord::Base
1141
+ self.table_name = "books"
1142
+ belongs_to :author, class_name: "UndestroyableAuthor", dependent: :destroy
1143
+ end
1144
+
1145
+ class UndestroyableAuthor < ActiveRecord::Base
1146
+ self.table_name = "authors"
1147
+ has_one :book, class_name: "DestroyableBook", foreign_key: "author_id"
1148
+ before_destroy :dont
1149
+
1150
+ def dont
1151
+ throw(:abort)
1152
+ end
1153
+ end
1154
+
1155
+ def test_dependency_should_halt_parent_destruction
1156
+ author = UndestroyableAuthor.create!(name: "Test")
1157
+ book = DestroyableBook.create!(author: author)
1158
+
1159
+ assert_no_difference ["UndestroyableAuthor.count", "DestroyableBook.count"] do
1160
+ assert_not book.destroy
1161
+ end
1162
+ end
1163
+
1164
+ def test_dependency_should_halt_parent_destruction_with_cascaded_three_levels
1165
+ author = UndestroyableAuthor.create!(name: "Test")
1166
+ book = DestroyableBook.create!(author: author)
1167
+ essay = EssayDestroy.create!(book: book)
1168
+
1169
+ assert_no_difference ["UndestroyableAuthor.count", "DestroyableBook.count", "EssayDestroy.count"] do
1170
+ assert_not essay.destroy
1171
+ assert_not essay.destroyed?
894
1172
  end
895
- assert_equal error.message, 'The :dependent option must be one of [:destroy, :delete], but is :nullify'
896
1173
  end
897
1174
 
898
1175
  def test_attributes_are_being_set_when_initialized_from_belongs_to_association_with_where_clause
899
- new_firm = accounts(:signals37).build_firm(:name => 'Apple')
1176
+ new_firm = accounts(:signals37).build_firm(name: "Apple")
900
1177
  assert_equal new_firm.name, "Apple"
901
1178
  end
902
1179
 
903
1180
  def test_attributes_are_set_without_error_when_initialized_from_belongs_to_association_with_array_in_where_clause
904
- new_account = Account.where(:credit_limit => [ 50, 60 ]).new
1181
+ new_account = Account.where(credit_limit: [ 50, 60 ]).new
905
1182
  assert_nil new_account.credit_limit
906
1183
  end
907
1184
 
@@ -913,31 +1190,42 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
913
1190
  firm_proxy = client.send(:association_instance_get, :firm)
914
1191
  firm_with_condition_proxy = client.send(:association_instance_get, :firm_with_condition)
915
1192
 
916
- assert !firm_proxy.stale_target?
917
- assert !firm_with_condition_proxy.stale_target?
1193
+ assert_not_predicate firm_proxy, :stale_target?
1194
+ assert_not_predicate firm_with_condition_proxy, :stale_target?
918
1195
  assert_equal companies(:first_firm), client.firm
919
1196
  assert_equal companies(:first_firm), client.firm_with_condition
920
1197
 
921
1198
  client.client_of = companies(:another_firm).id
922
1199
 
923
- assert firm_proxy.stale_target?
924
- assert firm_with_condition_proxy.stale_target?
1200
+ assert_predicate firm_proxy, :stale_target?
1201
+ assert_predicate firm_with_condition_proxy, :stale_target?
925
1202
  assert_equal companies(:another_firm), client.firm
926
1203
  assert_equal companies(:another_firm), client.firm_with_condition
927
1204
  end
928
1205
 
1206
+ def test_destroying_child_with_unloaded_parent_and_foreign_key_and_touch_is_possible_with_has_many_inversing
1207
+ with_has_many_inversing do
1208
+ book = Book.create!
1209
+ citation = book.citations.create!
1210
+
1211
+ assert_difference "Citation.count", -1 do
1212
+ Citation.find(citation.id).destroy
1213
+ end
1214
+ end
1215
+ end
1216
+
929
1217
  def test_polymorphic_reassignment_of_associated_id_updates_the_object
930
1218
  sponsor = sponsors(:moustache_club_sponsor_for_groucho)
931
1219
 
932
1220
  sponsor.sponsorable
933
1221
  proxy = sponsor.send(:association_instance_get, :sponsorable)
934
1222
 
935
- assert !proxy.stale_target?
1223
+ assert_not_predicate proxy, :stale_target?
936
1224
  assert_equal members(:groucho), sponsor.sponsorable
937
1225
 
938
1226
  sponsor.sponsorable_id = members(:some_other_guy).id
939
1227
 
940
- assert proxy.stale_target?
1228
+ assert_predicate proxy, :stale_target?
941
1229
  assert_equal members(:some_other_guy), sponsor.sponsorable
942
1230
  end
943
1231
 
@@ -947,12 +1235,12 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
947
1235
  sponsor.sponsorable
948
1236
  proxy = sponsor.send(:association_instance_get, :sponsorable)
949
1237
 
950
- assert !proxy.stale_target?
1238
+ assert_not_predicate proxy, :stale_target?
951
1239
  assert_equal members(:groucho), sponsor.sponsorable
952
1240
 
953
- sponsor.sponsorable_type = 'Firm'
1241
+ sponsor.sponsorable_type = "Firm"
954
1242
 
955
- assert proxy.stale_target?
1243
+ assert_predicate proxy, :stale_target?
956
1244
  assert_equal companies(:first_firm), sponsor.sponsorable
957
1245
  end
958
1246
 
@@ -974,9 +1262,20 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
974
1262
  post = posts(:welcome)
975
1263
  comment = comments(:greetings)
976
1264
 
977
- assert_difference lambda { post.reload.tags_count }, -1 do
978
- assert_difference 'comment.reload.tags_count', +1 do
1265
+ assert_equal post.id, comment.id
1266
+
1267
+ assert_difference "post.reload.tags_count", -1 do
1268
+ assert_difference "comment.reload.tags_count", +1 do
979
1269
  tagging.taggable = comment
1270
+ tagging.save!
1271
+ end
1272
+ end
1273
+
1274
+ assert_difference "comment.reload.tags_count", -1 do
1275
+ assert_difference "post.reload.tags_count", +1 do
1276
+ tagging.taggable_type = post.class.polymorphic_name
1277
+ tagging.taggable_id = post.id
1278
+ tagging.save!
980
1279
  end
981
1280
  end
982
1281
  end
@@ -1022,46 +1321,46 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
1022
1321
  end
1023
1322
 
1024
1323
  def test_build_with_block
1025
- client = Client.create(:name => 'Client Company')
1324
+ client = Client.create(name: "Client Company")
1026
1325
 
1027
- firm = client.build_firm{ |f| f.name = 'Agency Company' }
1028
- assert_equal 'Agency Company', firm.name
1326
+ firm = client.build_firm { |f| f.name = "Agency Company" }
1327
+ assert_equal "Agency Company", firm.name
1029
1328
  end
1030
1329
 
1031
1330
  def test_create_with_block
1032
- client = Client.create(:name => 'Client Company')
1331
+ client = Client.create(name: "Client Company")
1033
1332
 
1034
- firm = client.create_firm{ |f| f.name = 'Agency Company' }
1035
- assert_equal 'Agency Company', firm.name
1333
+ firm = client.create_firm { |f| f.name = "Agency Company" }
1334
+ assert_equal "Agency Company", firm.name
1036
1335
  end
1037
1336
 
1038
1337
  def test_create_bang_with_block
1039
- client = Client.create(:name => 'Client Company')
1338
+ client = Client.create(name: "Client Company")
1040
1339
 
1041
- firm = client.create_firm!{ |f| f.name = 'Agency Company' }
1042
- assert_equal 'Agency Company', firm.name
1340
+ firm = client.create_firm! { |f| f.name = "Agency Company" }
1341
+ assert_equal "Agency Company", firm.name
1043
1342
  end
1044
1343
 
1045
1344
  def test_should_set_foreign_key_on_create_association
1046
- client = Client.create! :name => "fuu"
1345
+ client = Client.create! name: "fuu"
1047
1346
 
1048
- firm = client.create_firm :name => "baa"
1347
+ firm = client.create_firm name: "baa"
1049
1348
  assert_equal firm.id, client.client_of
1050
1349
  end
1051
1350
 
1052
1351
  def test_should_set_foreign_key_on_create_association!
1053
- client = Client.create! :name => "fuu"
1352
+ client = Client.create! name: "fuu"
1054
1353
 
1055
- firm = client.create_firm! :name => "baa"
1354
+ firm = client.create_firm! name: "baa"
1056
1355
  assert_equal firm.id, client.client_of
1057
1356
  end
1058
1357
 
1059
1358
  def test_self_referential_belongs_to_with_counter_cache_assigning_nil
1060
- comment = Comment.create! :post => posts(:thinking), :body => "fuu"
1359
+ comment = Comment.create! post: posts(:thinking), body: "fuu"
1061
1360
  comment.parent = nil
1062
1361
  comment.save!
1063
1362
 
1064
- assert_equal nil, comment.reload.parent
1363
+ assert_nil comment.reload.parent
1065
1364
  assert_equal 0, comments(:greetings).reload.children_count
1066
1365
  end
1067
1366
 
@@ -1076,13 +1375,51 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
1076
1375
  assert_equal 1, parent.reload.children_count
1077
1376
  end
1078
1377
 
1378
+ def test_belongs_to_with_out_of_range_value_assigning
1379
+ model = Class.new(Author) do
1380
+ def self.name; "Temp"; end
1381
+ validates :author_address, presence: true
1382
+ end
1383
+
1384
+ author = model.new
1385
+ author.author_address_id = 9223372036854775808 # out of range in the bigint
1386
+
1387
+ assert_nil author.author_address
1388
+ assert_not_predicate author, :valid?
1389
+ assert_equal [{ error: :blank }], author.errors.details[:author_address]
1390
+ end
1391
+
1079
1392
  def test_polymorphic_with_custom_primary_key
1080
1393
  toy = Toy.create!
1081
- sponsor = Sponsor.create!(:sponsorable => toy)
1394
+ sponsor = Sponsor.create!(sponsorable: toy)
1082
1395
 
1083
1396
  assert_equal toy, sponsor.reload.sponsorable
1084
1397
  end
1085
1398
 
1399
+ class SponsorWithTouchInverse < Sponsor
1400
+ belongs_to :sponsorable, polymorphic: true, inverse_of: :sponsors, touch: true
1401
+ end
1402
+
1403
+ def test_destroying_polymorphic_child_with_unloaded_parent_and_touch_is_possible_with_has_many_inversing
1404
+ with_has_many_inversing do
1405
+ toy = Toy.create!
1406
+ sponsor = toy.sponsors.create!
1407
+
1408
+ assert_difference "Sponsor.count", -1 do
1409
+ SponsorWithTouchInverse.find(sponsor.id).destroy
1410
+ end
1411
+ end
1412
+ end
1413
+
1414
+ def test_polymorphic_with_false
1415
+ assert_nothing_raised do
1416
+ Class.new(ActiveRecord::Base) do
1417
+ def self.name; "Post"; end
1418
+ belongs_to :category, polymorphic: false
1419
+ end
1420
+ end
1421
+ end
1422
+
1086
1423
  test "stale tracking doesn't care about the type" do
1087
1424
  apple = Firm.create("name" => "Apple")
1088
1425
  citibank = Account.create("credit_limit" => 10)
@@ -1092,12 +1429,12 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
1092
1429
 
1093
1430
  citibank.firm_id = apple.id.to_s
1094
1431
 
1095
- assert !citibank.association(:firm).stale_target?
1432
+ assert_not_predicate citibank.association(:firm), :stale_target?
1096
1433
  end
1097
1434
 
1098
1435
  def test_reflect_the_most_recent_change
1099
1436
  author1, author2 = Author.limit(2)
1100
- post = Post.new(:title => "foo", :body=> "bar")
1437
+ post = Post.new(title: "foo", body: "bar")
1101
1438
 
1102
1439
  post.author = author1
1103
1440
  post.author_id = author2.id
@@ -1106,8 +1443,8 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
1106
1443
  assert_equal post.author_id, author2.id
1107
1444
  end
1108
1445
 
1109
- test 'dangerous association name raises ArgumentError' do
1110
- [:errors, 'errors', :save, 'save'].each do |name|
1446
+ test "dangerous association name raises ArgumentError" do
1447
+ [:errors, "errors", :save, "save"].each do |name|
1111
1448
  assert_raises(ArgumentError, "Association #{name} should not be allowed") do
1112
1449
  Class.new(ActiveRecord::Base) do
1113
1450
  belongs_to name
@@ -1116,16 +1453,31 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
1116
1453
  end
1117
1454
  end
1118
1455
 
1119
- test 'belongs_to works with model called Record' do
1456
+ test "belongs_to works with model called Record" do
1120
1457
  record = Record.create!
1121
1458
  Column.create! record: record
1122
1459
  assert_equal 1, Column.count
1123
1460
  end
1124
1461
 
1125
- def test_association_force_reload_with_only_true_is_deprecated
1126
- client = Client.find(3)
1462
+ def test_multiple_counter_cache_with_after_create_update
1463
+ post = posts(:welcome)
1464
+ parent = comments(:greetings)
1465
+
1466
+ assert_difference "parent.reload.children_count", +1 do
1467
+ assert_difference "post.reload.comments_count", +1 do
1468
+ CommentWithAfterCreateUpdate.create(body: "foo", post: post, parent: parent)
1469
+ end
1470
+ end
1471
+ end
1472
+
1473
+ test "assigning an association doesn't result in duplicate objects" do
1474
+ post = Post.create!(title: "title", body: "body")
1475
+ post.comments = [post.comments.build(body: "body")]
1476
+ post.save!
1127
1477
 
1128
- assert_deprecated { client.firm(true) }
1478
+ assert_equal 1, post.comments.size
1479
+ assert_equal 1, Comment.where(post_id: post.id).count
1480
+ assert_equal post.id, Comment.last.post.id
1129
1481
  end
1130
1482
  end
1131
1483