ibm_db 5.2.0-x86-mingw32 → 5.4.0-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 (625) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +9 -0
  3. data/LICENSE +55 -18
  4. data/README +1 -1
  5. data/debug.log +1 -0
  6. data/ext/Makefile +28 -24
  7. data/ext/ibm_db.c +66 -65
  8. data/ext/ibm_db.o +0 -0
  9. data/ext/ibm_db.so +0 -0
  10. data/ext/mkmf.log +26 -24
  11. data/ext/ruby_ibm_db_cli.c +1 -0
  12. data/ext/ruby_ibm_db_cli.o +0 -0
  13. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1520 -1282
  14. data/lib/ibm_db.so +1 -0
  15. data/lib/mswin32/ibm_db.rb +3 -1
  16. data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
  17. data/lib/mswin32/rb3x/i386/ruby31/ibm_db.so +0 -0
  18. data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
  19. data/test/activejob/destroy_association_async_test.rb +305 -0
  20. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  21. data/test/activejob/helper.rb +15 -0
  22. data/test/assets/schema_dump_5_1.yml +345 -0
  23. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  24. data/test/cases/adapter_test.rb +432 -218
  25. data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
  26. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  27. data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
  28. data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
  29. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
  30. data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
  31. data/test/cases/adapters/mysql2/connection_test.rb +48 -50
  32. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  33. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
  34. data/test/cases/adapters/mysql2/enum_test.rb +32 -11
  35. data/test/cases/adapters/mysql2/explain_test.rb +13 -11
  36. data/test/cases/adapters/mysql2/json_test.rb +17 -188
  37. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  38. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
  39. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  40. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  41. data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
  42. data/test/cases/adapters/mysql2/schema_test.rb +24 -22
  43. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  44. data/test/cases/adapters/mysql2/sp_test.rb +10 -8
  45. data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
  46. data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
  47. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  48. data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
  49. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  50. data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
  51. data/test/cases/adapters/postgresql/array_test.rb +118 -63
  52. data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
  53. data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
  54. data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
  55. data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
  56. data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
  57. data/test/cases/adapters/postgresql/citext_test.rb +58 -58
  58. data/test/cases/adapters/postgresql/collation_test.rb +17 -15
  59. data/test/cases/adapters/postgresql/composite_test.rb +25 -23
  60. data/test/cases/adapters/postgresql/connection_test.rb +73 -85
  61. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  62. data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
  63. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  64. data/test/cases/adapters/postgresql/domain_test.rb +9 -7
  65. data/test/cases/adapters/postgresql/enum_test.rb +12 -10
  66. data/test/cases/adapters/postgresql/explain_test.rb +10 -8
  67. data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
  68. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  69. data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
  70. data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
  71. data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
  72. data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
  73. data/test/cases/adapters/postgresql/integer_test.rb +2 -0
  74. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  75. data/test/cases/adapters/postgresql/json_test.rb +16 -201
  76. data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
  77. data/test/cases/adapters/postgresql/money_test.rb +47 -16
  78. data/test/cases/adapters/postgresql/network_test.rb +36 -28
  79. data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
  80. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  81. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  82. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  83. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
  84. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  85. data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
  86. data/test/cases/adapters/postgresql/range_test.rb +406 -292
  87. data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
  88. data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
  89. data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
  90. data/test/cases/adapters/postgresql/schema_test.rb +207 -91
  91. data/test/cases/adapters/postgresql/serial_test.rb +9 -7
  92. data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
  93. data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
  94. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  95. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  96. data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
  97. data/test/cases/adapters/postgresql/utils_test.rb +11 -9
  98. data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
  99. data/test/cases/adapters/postgresql/xml_test.rb +10 -14
  100. data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
  101. data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
  102. data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
  103. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  104. data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
  105. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  106. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
  107. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
  108. data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
  109. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  110. data/test/cases/aggregations_test.rb +14 -12
  111. data/test/cases/annotate_test.rb +46 -0
  112. data/test/cases/ar_schema_test.rb +153 -86
  113. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  114. data/test/cases/arel/attributes/math_test.rb +83 -0
  115. data/test/cases/arel/attributes_test.rb +27 -0
  116. data/test/cases/arel/collectors/bind_test.rb +40 -0
  117. data/test/cases/arel/collectors/composite_test.rb +47 -0
  118. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  119. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  120. data/test/cases/arel/crud_test.rb +65 -0
  121. data/test/cases/arel/delete_manager_test.rb +53 -0
  122. data/test/cases/arel/factory_methods_test.rb +46 -0
  123. data/test/cases/arel/helper.rb +45 -0
  124. data/test/cases/arel/insert_manager_test.rb +241 -0
  125. data/test/cases/arel/nodes/and_test.rb +30 -0
  126. data/test/cases/arel/nodes/as_test.rb +36 -0
  127. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  128. data/test/cases/arel/nodes/bin_test.rb +35 -0
  129. data/test/cases/arel/nodes/binary_test.rb +29 -0
  130. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  131. data/test/cases/arel/nodes/case_test.rb +96 -0
  132. data/test/cases/arel/nodes/casted_test.rb +18 -0
  133. data/test/cases/arel/nodes/comment_test.rb +22 -0
  134. data/test/cases/arel/nodes/count_test.rb +35 -0
  135. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  136. data/test/cases/arel/nodes/descending_test.rb +46 -0
  137. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  138. data/test/cases/arel/nodes/equality_test.rb +62 -0
  139. data/test/cases/arel/nodes/extract_test.rb +43 -0
  140. data/test/cases/arel/nodes/false_test.rb +21 -0
  141. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  142. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  143. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  144. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  145. data/test/cases/arel/nodes/node_test.rb +22 -0
  146. data/test/cases/arel/nodes/not_test.rb +31 -0
  147. data/test/cases/arel/nodes/or_test.rb +36 -0
  148. data/test/cases/arel/nodes/over_test.rb +69 -0
  149. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  150. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  151. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  152. data/test/cases/arel/nodes/sum_test.rb +35 -0
  153. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  154. data/test/cases/arel/nodes/true_test.rb +21 -0
  155. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  156. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  157. data/test/cases/arel/nodes/window_test.rb +81 -0
  158. data/test/cases/arel/nodes_test.rb +34 -0
  159. data/test/cases/arel/select_manager_test.rb +1238 -0
  160. data/test/cases/arel/support/fake_record.rb +135 -0
  161. data/test/cases/arel/table_test.rb +216 -0
  162. data/test/cases/arel/update_manager_test.rb +126 -0
  163. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  164. data/test/cases/arel/visitors/dot_test.rb +90 -0
  165. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  166. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  167. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  168. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  169. data/test/cases/associations/belongs_to_associations_test.rb +510 -158
  170. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
  171. data/test/cases/associations/callbacks_test.rb +56 -38
  172. data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
  173. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
  174. data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
  175. data/test/cases/associations/eager_singularization_test.rb +21 -21
  176. data/test/cases/associations/eager_test.rb +559 -415
  177. data/test/cases/associations/extension_test.rb +18 -12
  178. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
  179. data/test/cases/associations/has_many_associations_test.rb +1038 -465
  180. data/test/cases/associations/has_many_through_associations_test.rb +558 -249
  181. data/test/cases/associations/has_one_associations_test.rb +294 -129
  182. data/test/cases/associations/has_one_through_associations_test.rb +121 -75
  183. data/test/cases/associations/inner_join_association_test.rb +114 -38
  184. data/test/cases/associations/inverse_associations_test.rb +606 -398
  185. data/test/cases/associations/join_model_test.rb +158 -148
  186. data/test/cases/associations/left_outer_join_association_test.rb +59 -24
  187. data/test/cases/associations/nested_through_associations_test.rb +166 -109
  188. data/test/cases/associations/required_test.rb +35 -10
  189. data/test/cases/associations_test.rb +241 -110
  190. data/test/cases/attribute_methods/read_test.rb +11 -11
  191. data/test/cases/attribute_methods_test.rb +413 -298
  192. data/test/cases/attributes_test.rb +145 -27
  193. data/test/cases/autosave_association_test.rb +681 -436
  194. data/test/cases/base_prevent_writes_test.rb +229 -0
  195. data/test/cases/base_test.rb +599 -542
  196. data/test/cases/batches_test.rb +288 -82
  197. data/test/cases/binary_test.rb +26 -31
  198. data/test/cases/bind_parameter_test.rb +194 -21
  199. data/test/cases/boolean_test.rb +52 -0
  200. data/test/cases/cache_key_test.rb +110 -5
  201. data/test/cases/calculations_test.rb +740 -177
  202. data/test/cases/callbacks_test.rb +74 -207
  203. data/test/cases/clone_test.rb +15 -10
  204. data/test/cases/coders/json_test.rb +2 -0
  205. data/test/cases/coders/yaml_column_test.rb +16 -13
  206. data/test/cases/collection_cache_key_test.rb +177 -20
  207. data/test/cases/column_alias_test.rb +9 -7
  208. data/test/cases/column_definition_test.rb +10 -68
  209. data/test/cases/comment_test.rb +166 -107
  210. data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
  211. data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
  212. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  213. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  214. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  215. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  216. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  217. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  218. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
  219. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
  220. data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
  221. data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
  222. data/test/cases/connection_management_test.rb +13 -11
  223. data/test/cases/connection_pool_test.rb +316 -83
  224. data/test/cases/core_test.rb +82 -58
  225. data/test/cases/counter_cache_test.rb +204 -50
  226. data/test/cases/custom_locking_test.rb +5 -3
  227. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  228. data/test/cases/database_configurations/resolver_test.rb +150 -0
  229. data/test/cases/database_configurations_test.rb +145 -0
  230. data/test/cases/database_selector_test.rb +296 -0
  231. data/test/cases/database_statements_test.rb +18 -16
  232. data/test/cases/date_test.rb +8 -16
  233. data/test/cases/date_time_precision_test.rb +100 -78
  234. data/test/cases/date_time_test.rb +23 -8
  235. data/test/cases/defaults_test.rb +106 -71
  236. data/test/cases/delegated_type_test.rb +57 -0
  237. data/test/cases/dirty_test.rb +419 -223
  238. data/test/cases/disconnected_test.rb +6 -6
  239. data/test/cases/dup_test.rb +54 -27
  240. data/test/cases/enum_test.rb +461 -82
  241. data/test/cases/errors_test.rb +7 -7
  242. data/test/cases/explain_subscriber_test.rb +17 -15
  243. data/test/cases/explain_test.rb +11 -19
  244. data/test/cases/filter_attributes_test.rb +153 -0
  245. data/test/cases/finder_respond_to_test.rb +14 -14
  246. data/test/cases/finder_test.rb +669 -287
  247. data/test/cases/fixture_set/file_test.rb +34 -38
  248. data/test/cases/fixtures_test.rb +833 -176
  249. data/test/cases/forbidden_attributes_protection_test.rb +32 -67
  250. data/test/cases/habtm_destroy_order_test.rb +25 -25
  251. data/test/cases/helper.rb +78 -49
  252. data/test/cases/hot_compatibility_test.rb +33 -32
  253. data/test/cases/i18n_test.rb +18 -17
  254. data/test/cases/inheritance_test.rb +180 -115
  255. data/test/cases/insert_all_test.rb +489 -0
  256. data/test/cases/instrumentation_test.rb +101 -0
  257. data/test/cases/integration_test.rb +119 -31
  258. data/test/cases/invalid_connection_test.rb +18 -16
  259. data/test/cases/invertible_migration_test.rb +183 -43
  260. data/test/cases/json_attribute_test.rb +35 -0
  261. data/test/cases/json_serialization_test.rb +57 -58
  262. data/test/cases/json_shared_test_cases.rb +290 -0
  263. data/test/cases/locking_test.rb +413 -119
  264. data/test/cases/log_subscriber_test.rb +68 -26
  265. data/test/cases/marshal_serialization_test.rb +39 -0
  266. data/test/cases/migration/change_schema_test.rb +118 -72
  267. data/test/cases/migration/change_table_test.rb +138 -30
  268. data/test/cases/migration/check_constraint_test.rb +162 -0
  269. data/test/cases/migration/column_attributes_test.rb +45 -35
  270. data/test/cases/migration/column_positioning_test.rb +18 -6
  271. data/test/cases/migration/columns_test.rb +93 -77
  272. data/test/cases/migration/command_recorder_test.rb +121 -34
  273. data/test/cases/migration/compatibility_test.rb +578 -23
  274. data/test/cases/migration/create_join_table_test.rb +35 -25
  275. data/test/cases/migration/foreign_key_test.rb +503 -284
  276. data/test/cases/migration/helper.rb +4 -3
  277. data/test/cases/migration/index_test.rb +119 -70
  278. data/test/cases/migration/logger_test.rb +9 -6
  279. data/test/cases/migration/pending_migrations_test.rb +88 -34
  280. data/test/cases/migration/references_foreign_key_test.rb +164 -150
  281. data/test/cases/migration/references_index_test.rb +38 -19
  282. data/test/cases/migration/references_statements_test.rb +15 -14
  283. data/test/cases/migration/rename_table_test.rb +53 -30
  284. data/test/cases/migration_test.rb +637 -269
  285. data/test/cases/migrator_test.rb +191 -135
  286. data/test/cases/mixin_test.rb +7 -11
  287. data/test/cases/modules_test.rb +36 -34
  288. data/test/cases/multi_db_migrator_test.rb +223 -0
  289. data/test/cases/multiparameter_attributes_test.rb +60 -33
  290. data/test/cases/multiple_db_test.rb +16 -22
  291. data/test/cases/nested_attributes_test.rb +341 -320
  292. data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
  293. data/test/cases/null_relation_test.rb +84 -0
  294. data/test/cases/numeric_data_test.rb +93 -0
  295. data/test/cases/persistence_test.rb +361 -269
  296. data/test/cases/pooled_connections_test.rb +18 -26
  297. data/test/cases/prepared_statement_status_test.rb +48 -0
  298. data/test/cases/primary_keys_test.rb +210 -104
  299. data/test/cases/query_cache_test.rb +610 -141
  300. data/test/cases/quoting_test.rb +132 -31
  301. data/test/cases/readonly_test.rb +49 -48
  302. data/test/cases/reaper_test.rb +146 -32
  303. data/test/cases/reflection_test.rb +167 -156
  304. data/test/cases/relation/delegation_test.rb +49 -36
  305. data/test/cases/relation/delete_all_test.rb +117 -0
  306. data/test/cases/relation/merging_test.rb +319 -42
  307. data/test/cases/relation/mutation_test.rb +55 -93
  308. data/test/cases/relation/or_test.rb +129 -29
  309. data/test/cases/relation/predicate_builder_test.rb +21 -6
  310. data/test/cases/relation/record_fetch_warning_test.rb +5 -3
  311. data/test/cases/relation/select_test.rb +67 -0
  312. data/test/cases/relation/update_all_test.rb +317 -0
  313. data/test/cases/relation/where_chain_test.rb +68 -32
  314. data/test/cases/relation/where_clause_test.rb +136 -61
  315. data/test/cases/relation/where_test.rb +155 -48
  316. data/test/cases/relation_test.rb +266 -112
  317. data/test/cases/relations_test.rb +969 -744
  318. data/test/cases/reload_models_test.rb +13 -9
  319. data/test/cases/reserved_word_test.rb +141 -0
  320. data/test/cases/result_test.rb +68 -17
  321. data/test/cases/sanitize_test.rb +87 -71
  322. data/test/cases/schema_dumper_test.rb +221 -128
  323. data/test/cases/schema_loading_test.rb +3 -2
  324. data/test/cases/scoping/default_scoping_test.rb +185 -144
  325. data/test/cases/scoping/named_scoping_test.rb +177 -89
  326. data/test/cases/scoping/relation_scoping_test.rb +197 -75
  327. data/test/cases/secure_token_test.rb +18 -3
  328. data/test/cases/serialization_test.rb +30 -28
  329. data/test/cases/serialized_attribute_test.rb +133 -42
  330. data/test/cases/signed_id_test.rb +168 -0
  331. data/test/cases/statement_cache_test.rb +41 -24
  332. data/test/cases/statement_invalid_test.rb +42 -0
  333. data/test/cases/store_test.rb +180 -55
  334. data/test/cases/strict_loading_test.rb +473 -0
  335. data/test/cases/suppressor_test.rb +26 -12
  336. data/test/cases/tasks/database_tasks_test.rb +1258 -194
  337. data/test/cases/tasks/mysql_rake_test.rb +370 -298
  338. data/test/cases/tasks/postgresql_rake_test.rb +481 -251
  339. data/test/cases/tasks/sqlite_rake_test.rb +225 -178
  340. data/test/cases/test_case.rb +51 -40
  341. data/test/cases/test_databases_test.rb +79 -0
  342. data/test/cases/test_fixtures_test.rb +79 -19
  343. data/test/cases/time_precision_test.rb +98 -76
  344. data/test/cases/timestamp_test.rb +102 -99
  345. data/test/cases/touch_later_test.rb +12 -10
  346. data/test/cases/transaction_callbacks_test.rb +344 -90
  347. data/test/cases/transaction_isolation_test.rb +12 -12
  348. data/test/cases/transactions_test.rb +612 -162
  349. data/test/cases/type/adapter_specific_registry_test.rb +14 -2
  350. data/test/cases/type/date_time_test.rb +4 -2
  351. data/test/cases/type/integer_test.rb +4 -2
  352. data/test/cases/type/string_test.rb +10 -8
  353. data/test/cases/type/time_test.rb +28 -0
  354. data/test/cases/type/type_map_test.rb +29 -28
  355. data/test/cases/type/unsigned_integer_test.rb +19 -0
  356. data/test/cases/type_test.rb +2 -0
  357. data/test/cases/types_test.rb +3 -1
  358. data/test/cases/unconnected_test.rb +14 -1
  359. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  360. data/test/cases/validations/absence_validation_test.rb +19 -17
  361. data/test/cases/validations/association_validation_test.rb +30 -28
  362. data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
  363. data/test/cases/validations/i18n_validation_test.rb +22 -21
  364. data/test/cases/validations/length_validation_test.rb +34 -33
  365. data/test/cases/validations/numericality_validation_test.rb +181 -0
  366. data/test/cases/validations/presence_validation_test.rb +21 -19
  367. data/test/cases/validations/uniqueness_validation_test.rb +156 -86
  368. data/test/cases/validations_repair_helper.rb +2 -0
  369. data/test/cases/validations_test.rb +61 -26
  370. data/test/cases/view_test.rb +122 -116
  371. data/test/cases/yaml_serialization_test.rb +79 -34
  372. data/test/config.example.yml +19 -19
  373. data/test/config.rb +3 -1
  374. data/test/config.yml +16 -6
  375. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  376. data/test/fixtures/author_addresses.yml +1 -8
  377. data/test/fixtures/authors.yml +1 -7
  378. data/test/fixtures/binaries.yml +4 -0
  379. data/test/fixtures/books.yml +9 -2
  380. data/test/fixtures/categories_posts.yml +3 -0
  381. data/test/fixtures/citations.yml +5 -0
  382. data/test/fixtures/comments.yml +7 -0
  383. data/test/fixtures/companies.yml +5 -0
  384. data/test/fixtures/computers.yml +2 -0
  385. data/test/fixtures/customers.yml +10 -1
  386. data/test/fixtures/developers.yml +1 -1
  387. data/test/fixtures/essays.yml +10 -0
  388. data/test/fixtures/faces.yml +3 -3
  389. data/test/fixtures/humans.yml +5 -0
  390. data/test/fixtures/interests.yml +7 -7
  391. data/test/fixtures/memberships.yml +7 -0
  392. data/test/fixtures/minimalistics.yml +3 -0
  393. data/test/fixtures/mixed_case_monkeys.yml +2 -2
  394. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  395. data/test/fixtures/naked/yml/parrots.yml +1 -0
  396. data/test/fixtures/other_books.yml +26 -0
  397. data/test/fixtures/other_posts.yml +1 -0
  398. data/test/fixtures/parrots.yml +7 -1
  399. data/test/fixtures/pirates.yml +3 -0
  400. data/test/fixtures/posts.yml +11 -3
  401. data/test/fixtures/readers.yml +6 -0
  402. data/test/fixtures/reserved_words/values.yml +2 -2
  403. data/test/fixtures/sponsors.yml +3 -0
  404. data/test/fixtures/strict_zines.yml +2 -0
  405. data/test/fixtures/subscribers.yml +1 -1
  406. data/test/fixtures/tasks.yml +1 -1
  407. data/test/fixtures/warehouse-things.yml +3 -0
  408. data/test/migrations/10_urban/9_add_expressions.rb +2 -0
  409. data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
  410. data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
  411. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
  412. data/test/migrations/missing/1_people_have_last_names.rb +2 -0
  413. data/test/migrations/missing/3_we_need_reminders.rb +2 -0
  414. data/test/migrations/missing/4_innocent_jointable.rb +3 -1
  415. data/test/migrations/rename/1_we_need_things.rb +2 -0
  416. data/test/migrations/rename/2_rename_things.rb +2 -0
  417. data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
  418. data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
  419. data/test/migrations/to_copy2/1_create_articles.rb +2 -0
  420. data/test/migrations/to_copy2/2_create_comments.rb +3 -1
  421. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
  422. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
  423. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
  424. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
  425. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
  426. data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
  427. data/test/migrations/valid/2_we_need_reminders.rb +2 -0
  428. data/test/migrations/valid/3_innocent_jointable.rb +3 -1
  429. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
  430. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
  431. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
  432. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
  433. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
  434. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
  435. data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
  436. data/test/models/account.rb +46 -0
  437. data/test/models/admin/account.rb +3 -1
  438. data/test/models/admin/randomly_named_c1.rb +2 -0
  439. data/test/models/admin/user.rb +16 -8
  440. data/test/models/admin.rb +4 -2
  441. data/test/models/aircraft.rb +3 -1
  442. data/test/models/arunit2_model.rb +2 -0
  443. data/test/models/author.rb +153 -102
  444. data/test/models/auto_id.rb +2 -0
  445. data/test/models/autoloadable/extra_firm.rb +2 -0
  446. data/test/models/binary.rb +3 -1
  447. data/test/models/binary_field.rb +6 -0
  448. data/test/models/bird.rb +13 -1
  449. data/test/models/book.rb +14 -4
  450. data/test/models/book_destroy_async.rb +24 -0
  451. data/test/models/boolean.rb +5 -0
  452. data/test/models/bulb.rb +13 -4
  453. data/test/models/cake_designer.rb +2 -0
  454. data/test/models/car.rb +17 -10
  455. data/test/models/carrier.rb +2 -0
  456. data/test/models/cart.rb +5 -0
  457. data/test/models/cat.rb +2 -0
  458. data/test/models/categorization.rb +8 -6
  459. data/test/models/category.rb +28 -16
  460. data/test/models/chef.rb +2 -0
  461. data/test/models/citation.rb +5 -1
  462. data/test/models/club.rb +13 -10
  463. data/test/models/college.rb +4 -2
  464. data/test/models/column.rb +2 -0
  465. data/test/models/column_name.rb +2 -0
  466. data/test/models/comment.rb +32 -10
  467. data/test/models/company.rb +102 -106
  468. data/test/models/company_in_module.rb +27 -26
  469. data/test/models/computer.rb +3 -1
  470. data/test/models/contact.rb +15 -13
  471. data/test/models/content.rb +5 -3
  472. data/test/models/contract.rb +21 -3
  473. data/test/models/country.rb +2 -4
  474. data/test/models/course.rb +3 -1
  475. data/test/models/customer.rb +10 -8
  476. data/test/models/customer_carrier.rb +2 -0
  477. data/test/models/dashboard.rb +2 -0
  478. data/test/models/default.rb +2 -0
  479. data/test/models/department.rb +2 -0
  480. data/test/models/destroy_async_parent.rb +15 -0
  481. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  482. data/test/models/developer.rb +152 -85
  483. data/test/models/dl_keyed_belongs_to.rb +13 -0
  484. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  485. data/test/models/dl_keyed_has_many.rb +5 -0
  486. data/test/models/dl_keyed_has_many_through.rb +5 -0
  487. data/test/models/dl_keyed_has_one.rb +5 -0
  488. data/test/models/dl_keyed_join.rb +10 -0
  489. data/test/models/dog.rb +2 -0
  490. data/test/models/dog_lover.rb +2 -0
  491. data/test/models/doubloon.rb +3 -1
  492. data/test/models/drink_designer.rb +17 -0
  493. data/test/models/edge.rb +4 -2
  494. data/test/models/electron.rb +2 -0
  495. data/test/models/engine.rb +3 -2
  496. data/test/models/entrant.rb +2 -0
  497. data/test/models/entry.rb +5 -0
  498. data/test/models/essay.rb +6 -3
  499. data/test/models/essay_destroy_async.rb +12 -0
  500. data/test/models/event.rb +3 -1
  501. data/test/models/eye.rb +5 -3
  502. data/test/models/face.rb +14 -6
  503. data/test/models/family.rb +6 -0
  504. data/test/models/family_tree.rb +6 -0
  505. data/test/models/friendship.rb +5 -3
  506. data/test/models/frog.rb +8 -0
  507. data/test/models/guid.rb +3 -1
  508. data/test/models/guitar.rb +2 -0
  509. data/test/models/hotel.rb +5 -3
  510. data/test/models/human.rb +39 -0
  511. data/test/models/image.rb +3 -1
  512. data/test/models/interest.rb +14 -3
  513. data/test/models/invoice.rb +4 -2
  514. data/test/models/item.rb +3 -1
  515. data/test/models/job.rb +5 -3
  516. data/test/models/joke.rb +4 -2
  517. data/test/models/keyboard.rb +3 -1
  518. data/test/models/legacy_thing.rb +2 -0
  519. data/test/models/lesson.rb +2 -0
  520. data/test/models/line_item.rb +3 -1
  521. data/test/models/liquid.rb +2 -0
  522. data/test/models/matey.rb +3 -1
  523. data/test/models/measurement.rb +4 -0
  524. data/test/models/member.rb +23 -20
  525. data/test/models/member_detail.rb +3 -0
  526. data/test/models/member_type.rb +2 -0
  527. data/test/models/membership.rb +4 -1
  528. data/test/models/mentor.rb +3 -1
  529. data/test/models/message.rb +5 -0
  530. data/test/models/minimalistic.rb +2 -0
  531. data/test/models/minivan.rb +3 -2
  532. data/test/models/mixed_case_monkey.rb +3 -1
  533. data/test/models/molecule.rb +2 -0
  534. data/test/models/mouse.rb +6 -0
  535. data/test/models/movie.rb +2 -0
  536. data/test/models/node.rb +4 -2
  537. data/test/models/non_primary_key.rb +2 -0
  538. data/test/models/notification.rb +2 -0
  539. data/test/models/numeric_data.rb +12 -0
  540. data/test/models/order.rb +4 -2
  541. data/test/models/organization.rb +9 -7
  542. data/test/models/other_dog.rb +3 -1
  543. data/test/models/owner.rb +6 -4
  544. data/test/models/parrot.rb +12 -4
  545. data/test/models/person.rb +59 -54
  546. data/test/models/personal_legacy_thing.rb +3 -1
  547. data/test/models/pet.rb +4 -2
  548. data/test/models/pet_treasure.rb +2 -0
  549. data/test/models/pirate.rb +67 -43
  550. data/test/models/possession.rb +3 -1
  551. data/test/models/post.rb +184 -86
  552. data/test/models/price_estimate.rb +11 -1
  553. data/test/models/professor.rb +3 -1
  554. data/test/models/project.rb +14 -12
  555. data/test/models/publisher/article.rb +2 -0
  556. data/test/models/publisher/magazine.rb +2 -0
  557. data/test/models/publisher.rb +2 -0
  558. data/test/models/randomly_named_c1.rb +2 -0
  559. data/test/models/rating.rb +5 -1
  560. data/test/models/reader.rb +7 -5
  561. data/test/models/recipe.rb +2 -0
  562. data/test/models/record.rb +2 -0
  563. data/test/models/reference.rb +6 -3
  564. data/test/models/reply.rb +39 -21
  565. data/test/models/room.rb +6 -0
  566. data/test/models/section.rb +6 -0
  567. data/test/models/seminar.rb +6 -0
  568. data/test/models/session.rb +6 -0
  569. data/test/models/ship.rb +12 -9
  570. data/test/models/ship_part.rb +5 -3
  571. data/test/models/shop.rb +4 -2
  572. data/test/models/shop_account.rb +2 -0
  573. data/test/models/speedometer.rb +2 -0
  574. data/test/models/sponsor.rb +8 -5
  575. data/test/models/squeak.rb +6 -0
  576. data/test/models/strict_zine.rb +7 -0
  577. data/test/models/string_key_object.rb +2 -0
  578. data/test/models/student.rb +2 -0
  579. data/test/models/subscriber.rb +4 -2
  580. data/test/models/subscription.rb +5 -1
  581. data/test/models/tag.rb +6 -3
  582. data/test/models/tagging.rb +13 -6
  583. data/test/models/task.rb +2 -0
  584. data/test/models/topic.rb +54 -19
  585. data/test/models/toy.rb +4 -0
  586. data/test/models/traffic_light.rb +2 -0
  587. data/test/models/treasure.rb +5 -3
  588. data/test/models/treaty.rb +2 -4
  589. data/test/models/tree.rb +2 -0
  590. data/test/models/tuning_peg.rb +2 -0
  591. data/test/models/tyre.rb +2 -0
  592. data/test/models/user.rb +12 -4
  593. data/test/models/uuid_child.rb +2 -0
  594. data/test/models/uuid_item.rb +2 -0
  595. data/test/models/uuid_parent.rb +2 -0
  596. data/test/models/vegetables.rb +12 -3
  597. data/test/models/vertex.rb +6 -4
  598. data/test/models/warehouse_thing.rb +2 -0
  599. data/test/models/wheel.rb +3 -1
  600. data/test/models/without_table.rb +3 -1
  601. data/test/models/zine.rb +3 -1
  602. data/test/schema/mysql2_specific_schema.rb +49 -35
  603. data/test/schema/oracle_specific_schema.rb +13 -15
  604. data/test/schema/postgresql_specific_schema.rb +51 -40
  605. data/test/schema/schema.rb +334 -154
  606. data/test/schema/sqlite_specific_schema.rb +9 -16
  607. data/test/support/config.rb +26 -26
  608. data/test/support/connection.rb +14 -8
  609. data/test/support/connection_helper.rb +3 -1
  610. data/test/support/ddl_helper.rb +2 -0
  611. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  612. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  613. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  614. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  615. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  616. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  617. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  618. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  619. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  620. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  621. data/test/support/schema_dumping_helper.rb +2 -0
  622. data/test/support/stubs/strong_parameters.rb +40 -0
  623. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  624. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  625. metadata +192 -14
@@ -1,105 +1,92 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cases/helper"
2
- require 'models/aircraft'
3
- require 'models/post'
4
- require 'models/comment'
5
- require 'models/author'
6
- require 'models/topic'
7
- require 'models/reply'
8
- require 'models/category'
9
- require 'models/company'
10
- require 'models/developer'
11
- require 'models/computer'
12
- require 'models/project'
13
- require 'models/minimalistic'
14
- require 'models/warehouse_thing'
15
- require 'models/parrot'
16
- require 'models/minivan'
17
- require 'models/owner'
18
- require 'models/person'
19
- require 'models/pet'
20
- require 'models/ship'
21
- require 'models/toy'
22
- require 'models/admin'
23
- require 'models/admin/user'
24
- require 'rexml/document'
4
+ require "models/aircraft"
5
+ require "models/post"
6
+ require "models/comment"
7
+ require "models/author"
8
+ require "models/topic"
9
+ require "models/reply"
10
+ require "models/category"
11
+ require "models/company"
12
+ require "models/developer"
13
+ require "models/computer"
14
+ require "models/project"
15
+ require "models/minimalistic"
16
+ require "models/parrot"
17
+ require "models/minivan"
18
+ require "models/person"
19
+ require "models/ship"
20
+ require "models/admin"
21
+ require "models/admin/user"
25
22
 
26
23
  class PersistenceTest < ActiveRecord::TestCase
27
- fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse_things', :authors, :author_addresses, :categorizations, :categories, :posts, :minivans, :pets, :toys
28
-
29
- # Oracle UPDATE does not support ORDER BY
30
- unless current_adapter?(:OracleAdapter)
31
- def test_update_all_ignores_order_without_limit_from_association
32
- author = authors(:david)
33
- assert_nothing_raised do
34
- assert_equal author.posts_with_comments_and_categories.length, author.posts_with_comments_and_categories.update_all([ "body = ?", "bulk update!" ])
35
- end
36
- end
37
-
38
- def test_update_all_doesnt_ignore_order
39
- assert_equal authors(:david).id + 1, authors(:mary).id # make sure there is going to be a duplicate PK error
40
- test_update_with_order_succeeds = lambda do |order|
41
- begin
42
- Author.order(order).update_all('id = id + 1')
43
- rescue ActiveRecord::ActiveRecordError
44
- false
45
- end
46
- end
47
-
48
- if test_update_with_order_succeeds.call('id DESC')
49
- assert !test_update_with_order_succeeds.call('id ASC') # test that this wasn't a fluke and using an incorrect order results in an exception
50
- else
51
- # test that we're failing because the current Arel's engine doesn't support UPDATE ORDER BY queries is using subselects instead
52
- assert_sql(/\AUPDATE .+ \(SELECT .* ORDER BY id DESC\)\Z/i) do
53
- test_update_with_order_succeeds.call('id DESC')
54
- end
55
- end
56
- end
57
-
58
- def test_update_all_with_order_and_limit_updates_subset_only
59
- author = authors(:david)
60
- assert_nothing_raised do
61
- assert_equal 1, author.posts_sorted_by_id_limited.size
62
- assert_equal 2, author.posts_sorted_by_id_limited.limit(2).to_a.size
63
- assert_equal 1, author.posts_sorted_by_id_limited.update_all([ "body = ?", "bulk update!" ])
64
- assert_equal "bulk update!", posts(:welcome).body
65
- assert_not_equal "bulk update!", posts(:thinking).body
66
- end
67
- end
68
- end
24
+ fixtures :topics, :companies, :developers, :accounts, :minimalistics, :authors, :author_addresses, :posts, :minivans
69
25
 
70
26
  def test_update_many
71
27
  topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" } }
72
28
  updated = Topic.update(topic_data.keys, topic_data.values)
73
29
 
74
- assert_equal 2, updated.size
30
+ assert_equal [1, 2], updated.map(&:id)
75
31
  assert_equal "1 updated", Topic.find(1).content
76
32
  assert_equal "2 updated", Topic.find(2).content
77
33
  end
78
34
 
79
- def test_delete_all
80
- assert Topic.count > 0
35
+ def test_update_many_with_duplicated_ids
36
+ updated = Topic.update([1, 1, 2], [
37
+ { "content" => "1 duplicated" }, { "content" => "1 updated" }, { "content" => "2 updated" }
38
+ ])
81
39
 
82
- assert_equal Topic.count, Topic.delete_all
40
+ assert_equal [1, 1, 2], updated.map(&:id)
41
+ assert_equal "1 updated", Topic.find(1).content
42
+ assert_equal "2 updated", Topic.find(2).content
83
43
  end
84
44
 
85
- def test_delete_all_with_joins_and_where_part_is_hash
86
- where_args = {:toys => {:name => 'Bone'}}
87
- count = Pet.joins(:toys).where(where_args).count
45
+ def test_update_many_with_invalid_id
46
+ topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" }, 99999 => {} }
88
47
 
89
- assert_equal count, 1
90
- assert_equal count, Pet.joins(:toys).where(where_args).delete_all
48
+ assert_raise(ActiveRecord::RecordNotFound) do
49
+ Topic.update(topic_data.keys, topic_data.values)
50
+ end
51
+
52
+ assert_not_equal "1 updated", Topic.find(1).content
53
+ assert_not_equal "2 updated", Topic.find(2).content
91
54
  end
92
55
 
93
- def test_delete_all_with_joins_and_where_part_is_not_hash
94
- where_args = ['toys.name = ?', 'Bone']
95
- count = Pet.joins(:toys).where(where_args).count
56
+ def test_class_level_update_without_ids
57
+ topics = Topic.all
58
+ assert_equal 5, topics.length
59
+ topics.each do |topic|
60
+ assert_not_equal "updated", topic.content
61
+ end
62
+
63
+ updated = Topic.update(content: "updated")
64
+ assert_equal 5, updated.length
65
+ updated.each do |topic|
66
+ assert_equal "updated", topic.content
67
+ end
68
+ end
69
+
70
+ def test_class_level_update_is_affected_by_scoping
71
+ topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" } }
72
+
73
+ assert_raise(ActiveRecord::RecordNotFound) do
74
+ Topic.where("1=0").scoping { Topic.update(topic_data.keys, topic_data.values) }
75
+ end
96
76
 
97
- assert_equal count, 1
98
- assert_equal count, Pet.joins(:toys).where(where_args).delete_all
77
+ assert_not_equal "1 updated", Topic.find(1).content
78
+ assert_not_equal "2 updated", Topic.find(2).content
79
+ end
80
+
81
+ def test_delete_all
82
+ assert Topic.count > 0
83
+
84
+ assert_equal Topic.count, Topic.delete_all
99
85
  end
100
86
 
101
87
  def test_increment_attribute
102
88
  assert_equal 50, accounts(:signals37).credit_limit
89
+
103
90
  accounts(:signals37).increment! :credit_limit
104
91
  assert_equal 51, accounts(:signals37, :reload).credit_limit
105
92
 
@@ -107,6 +94,16 @@ class PersistenceTest < ActiveRecord::TestCase
107
94
  assert_equal 53, accounts(:signals37, :reload).credit_limit
108
95
  end
109
96
 
97
+ def test_increment_aliased_attribute
98
+ assert_equal 50, accounts(:signals37).available_credit
99
+
100
+ accounts(:signals37).increment!(:available_credit)
101
+ assert_equal 51, accounts(:signals37, :reload).available_credit
102
+
103
+ accounts(:signals37).increment(:available_credit).increment!(:available_credit)
104
+ assert_equal 53, accounts(:signals37, :reload).available_credit
105
+ end
106
+
110
107
  def test_increment_nil_attribute
111
108
  assert_nil topics(:first).parent_id
112
109
  topics(:first).increment! :parent_id
@@ -131,53 +128,87 @@ class PersistenceTest < ActiveRecord::TestCase
131
128
  assert_equal initial_credit + 2, a1.reload.credit_limit
132
129
  end
133
130
 
134
- def test_destroy_all
135
- conditions = "author_name = 'Mary'"
136
- topics_by_mary = Topic.all.merge!(:where => conditions, :order => 'id').to_a
137
- assert ! topics_by_mary.empty?
131
+ def test_increment_with_touch_updates_timestamps
132
+ topic = topics(:first)
133
+ assert_equal 1, topic.replies_count
134
+ previously_updated_at = topic.updated_at
135
+ travel(1.second) do
136
+ topic.increment!(:replies_count, touch: true)
137
+ end
138
+ assert_equal 2, topic.reload.replies_count
139
+ assert_operator previously_updated_at, :<, topic.updated_at
140
+ end
138
141
 
139
- assert_difference('Topic.count', -topics_by_mary.size) do
140
- destroyed = Topic.where(conditions).destroy_all.sort_by(&:id)
141
- assert_equal topics_by_mary, destroyed
142
- assert destroyed.all?(&:frozen?), "destroyed topics should be frozen"
142
+ def test_increment_with_touch_an_attribute_updates_timestamps
143
+ topic = topics(:first)
144
+ assert_equal 1, topic.replies_count
145
+ previously_updated_at = topic.updated_at
146
+ previously_written_on = topic.written_on
147
+ travel(1.second) do
148
+ topic.increment!(:replies_count, touch: :written_on)
143
149
  end
150
+ assert_equal 2, topic.reload.replies_count
151
+ assert_operator previously_updated_at, :<, topic.updated_at
152
+ assert_operator previously_written_on, :<, topic.written_on
153
+ end
154
+
155
+ def test_increment_with_no_arg
156
+ topic = topics(:first)
157
+ assert_raises(ArgumentError) { topic.increment! }
144
158
  end
145
159
 
146
160
  def test_destroy_many
147
- clients = Client.all.merge!(:order => 'id').find([2, 3])
161
+ clients = Client.find([2, 3])
148
162
 
149
- assert_difference('Client.count', -2) do
150
- destroyed = Client.destroy([2, 3]).sort_by(&:id)
163
+ assert_difference("Client.count", -2) do
164
+ destroyed = Client.destroy([2, 3])
151
165
  assert_equal clients, destroyed
152
166
  assert destroyed.all?(&:frozen?), "destroyed clients should be frozen"
153
167
  end
154
168
  end
155
169
 
170
+ def test_destroy_many_with_invalid_id
171
+ clients = Client.find([2, 3])
172
+
173
+ assert_raise(ActiveRecord::RecordNotFound) do
174
+ Client.destroy([2, 3, 99999])
175
+ end
176
+
177
+ assert_equal clients, Client.find([2, 3])
178
+ end
179
+
156
180
  def test_becomes
157
181
  assert_kind_of Reply, topics(:first).becomes(Reply)
158
182
  assert_equal "The First Topic", topics(:first).becomes(Reply).title
159
183
  end
160
184
 
185
+ def test_becomes_after_reload_schema_from_cache
186
+ Reply.define_attribute_methods
187
+ Reply.serialize(:content) # invoke reload_schema_from_cache
188
+ assert_kind_of Reply, topics(:first).becomes(Reply)
189
+ assert_equal "The First Topic", topics(:first).becomes(Reply).title
190
+ end
191
+
161
192
  def test_becomes_includes_errors
162
- company = Company.new(:name => nil)
163
- assert !company.valid?
193
+ company = Company.new(name: nil)
194
+ assert_not_predicate company, :valid?
164
195
  original_errors = company.errors
165
196
  client = company.becomes(Client)
166
- assert_equal original_errors.keys, client.errors.keys
197
+ assert_equal assert_deprecated { original_errors.keys }, assert_deprecated { client.errors.keys }
167
198
  end
168
199
 
169
200
  def test_becomes_errors_base
170
201
  child_class = Class.new(Admin::User) do
171
202
  store_accessor :settings, :foo
172
203
 
173
- def self.name; 'Admin::ChildUser'; end
204
+ def self.name; "Admin::ChildUser"; end
174
205
  end
175
206
 
176
207
  admin = Admin::User.new
177
208
  admin.errors.add :token, :invalid
178
209
  child = admin.becomes(child_class)
179
210
 
180
- assert_equal [:token], child.errors.keys
211
+ assert_equal [:token], assert_deprecated { child.errors.keys }
181
212
  assert_nothing_raised do
182
213
  child.errors.add :foo, :invalid
183
214
  end
@@ -190,6 +221,17 @@ class PersistenceTest < ActiveRecord::TestCase
190
221
  assert_equal "The First Topic", Topic.find(copy.id).title
191
222
  end
192
223
 
224
+ def test_becomes_wont_break_mutation_tracking
225
+ topic = topics(:first)
226
+ reply = topic.becomes(Reply)
227
+
228
+ assert_equal 1, topic.id_in_database
229
+ assert_empty topic.attributes_in_database
230
+
231
+ assert_equal 1, reply.id_in_database
232
+ assert_empty reply.attributes_in_database
233
+ end
234
+
193
235
  def test_becomes_includes_changed_attributes
194
236
  company = Company.new(name: "37signals")
195
237
  client = company.becomes(Client)
@@ -222,6 +264,30 @@ class PersistenceTest < ActiveRecord::TestCase
222
264
  assert_equal 41, accounts(:signals37, :reload).credit_limit
223
265
  end
224
266
 
267
+ def test_decrement_with_touch_updates_timestamps
268
+ topic = topics(:first)
269
+ assert_equal 1, topic.replies_count
270
+ previously_updated_at = topic.updated_at
271
+ travel(1.second) do
272
+ topic.decrement!(:replies_count, touch: true)
273
+ end
274
+ assert_equal 0, topic.reload.replies_count
275
+ assert_operator previously_updated_at, :<, topic.updated_at
276
+ end
277
+
278
+ def test_decrement_with_touch_an_attribute_updates_timestamps
279
+ topic = topics(:first)
280
+ assert_equal 1, topic.replies_count
281
+ previously_updated_at = topic.updated_at
282
+ previously_written_on = topic.written_on
283
+ travel(1.second) do
284
+ topic.decrement!(:replies_count, touch: :written_on)
285
+ end
286
+ assert_equal 0, topic.reload.replies_count
287
+ assert_operator previously_updated_at, :<, topic.updated_at
288
+ assert_operator previously_written_on, :<, topic.written_on
289
+ end
290
+
225
291
  def test_create
226
292
  topic = Topic.new
227
293
  topic.title = "New Topic"
@@ -231,7 +297,7 @@ class PersistenceTest < ActiveRecord::TestCase
231
297
  end
232
298
 
233
299
  def test_save!
234
- topic = Topic.new(:title => "New Topic")
300
+ topic = Topic.new(title: "New Topic")
235
301
  assert topic.save!
236
302
 
237
303
  reply = WrongReply.new
@@ -261,7 +327,7 @@ class PersistenceTest < ActiveRecord::TestCase
261
327
  end
262
328
 
263
329
  def test_save_for_record_with_only_primary_key_that_is_provided
264
- assert_nothing_raised { Minimalistic.create!(:id => 2) }
330
+ assert_nothing_raised { Minimalistic.create!(id: 2) }
265
331
  end
266
332
 
267
333
  def test_save_with_duping_of_destroyed_object
@@ -269,8 +335,8 @@ class PersistenceTest < ActiveRecord::TestCase
269
335
  developer.destroy
270
336
  new_developer = developer.dup
271
337
  new_developer.save
272
- assert new_developer.persisted?
273
- assert_not new_developer.destroyed?
338
+ assert_predicate new_developer, :persisted?
339
+ assert_not_predicate new_developer, :destroyed?
274
340
  end
275
341
 
276
342
  def test_create_many
@@ -281,12 +347,13 @@ class PersistenceTest < ActiveRecord::TestCase
281
347
 
282
348
  def test_create_columns_not_equal_attributes
283
349
  topic = Topic.instantiate(
284
- 'attributes' => {
285
- 'title' => 'Another New Topic',
286
- 'does_not_exist' => 'test'
287
- }
350
+ "title" => "Another New Topic",
351
+ "does_not_exist" => "test"
288
352
  )
353
+ topic = topic.dup # reset @new_record
289
354
  assert_nothing_raised { topic.save }
355
+ assert_predicate topic, :persisted?
356
+ assert_equal "Another New Topic", topic.reload.title
290
357
  end
291
358
 
292
359
  def test_create_through_factory_with_block
@@ -330,9 +397,11 @@ class PersistenceTest < ActiveRecord::TestCase
330
397
  topic.title = "Still another topic"
331
398
  topic.save
332
399
 
333
- topic_reloaded = Topic.instantiate(topic.attributes.merge('does_not_exist' => 'test'))
334
- topic_reloaded.title = 'A New Topic'
400
+ topic_reloaded = Topic.instantiate(topic.attributes.merge("does_not_exist" => "test"))
401
+ topic_reloaded.title = "A New Topic"
335
402
  assert_nothing_raised { topic_reloaded.save }
403
+ assert_predicate topic_reloaded, :persisted?
404
+ assert_equal "A New Topic", topic_reloaded.reload.title
336
405
  end
337
406
 
338
407
  def test_update_for_record_with_only_primary_key
@@ -369,9 +438,25 @@ class PersistenceTest < ActiveRecord::TestCase
369
438
  assert_instance_of Reply, Reply.find(reply.id)
370
439
  end
371
440
 
441
+ def test_becomes_default_sti_subclass
442
+ original_type = Topic.columns_hash["type"].default
443
+ ActiveRecord::Base.connection.change_column_default :topics, :type, "Reply"
444
+ Topic.reset_column_information
445
+
446
+ reply = topics(:second)
447
+ assert_instance_of Reply, reply
448
+
449
+ topic = reply.becomes(Topic)
450
+ assert_instance_of Topic, topic
451
+
452
+ ensure
453
+ ActiveRecord::Base.connection.change_column_default :topics, :type, original_type
454
+ Topic.reset_column_information
455
+ end
456
+
372
457
  def test_update_after_create
373
458
  klass = Class.new(Topic) do
374
- def self.name; 'Topic'; end
459
+ def self.name; "Topic"; end
375
460
  after_create do
376
461
  update_attribute("author_name", "David")
377
462
  end
@@ -386,25 +471,23 @@ class PersistenceTest < ActiveRecord::TestCase
386
471
  end
387
472
 
388
473
  def test_update_attribute_does_not_run_sql_if_attribute_is_not_changed
389
- klass = Class.new(Topic) do
390
- def self.name; 'Topic'; end
391
- end
392
- topic = klass.create(title: 'Another New Topic')
393
- assert_queries(0) do
474
+ topic = Topic.create(title: "Another New Topic")
475
+ assert_no_queries do
394
476
  assert topic.update_attribute(:title, "Another New Topic")
395
477
  end
396
478
  end
397
479
 
398
480
  def test_update_does_not_run_sql_if_record_has_not_changed
399
481
  topic = Topic.create(title: "Another New Topic")
400
- assert_queries(0) { assert topic.update(title: "Another New Topic") }
401
- assert_queries(0) { assert topic.update_attributes(title: "Another New Topic") }
482
+ assert_no_queries do
483
+ assert topic.update(title: "Another New Topic")
484
+ end
402
485
  end
403
486
 
404
487
  def test_delete
405
488
  topic = Topic.find(1)
406
- assert_equal topic, topic.delete, 'topic.delete did not return self'
407
- assert topic.frozen?, 'topic not frozen after delete'
489
+ assert_equal topic, topic.delete, "topic.delete did not return self"
490
+ assert topic.frozen?, "topic not frozen after delete"
408
491
  assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
409
492
  end
410
493
 
@@ -413,103 +496,138 @@ class PersistenceTest < ActiveRecord::TestCase
413
496
  assert_not_nil Topic.find(2)
414
497
  end
415
498
 
499
+ def test_delete_isnt_affected_by_scoping
500
+ topic = Topic.find(1)
501
+ assert_difference("Topic.count", -1) do
502
+ Topic.where("1=0").scoping { topic.delete }
503
+ end
504
+ end
505
+
416
506
  def test_destroy
417
507
  topic = Topic.find(1)
418
- assert_equal topic, topic.destroy, 'topic.destroy did not return self'
419
- assert topic.frozen?, 'topic not frozen after destroy'
508
+ assert_equal topic, topic.destroy, "topic.destroy did not return self"
509
+ assert topic.frozen?, "topic not frozen after destroy"
420
510
  assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
421
511
  end
422
512
 
423
513
  def test_destroy!
424
514
  topic = Topic.find(1)
425
- assert_equal topic, topic.destroy!, 'topic.destroy! did not return self'
426
- assert topic.frozen?, 'topic not frozen after destroy!'
515
+ assert_equal topic, topic.destroy!, "topic.destroy! did not return self"
516
+ assert topic.frozen?, "topic not frozen after destroy!"
427
517
  assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
428
518
  end
429
519
 
430
- def test_record_not_found_exception
520
+ def test_find_raises_record_not_found_exception
431
521
  assert_raise(ActiveRecord::RecordNotFound) { Topic.find(99999) }
432
522
  end
433
523
 
524
+ def test_update_raises_record_not_found_exception
525
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.update(99999, approved: true) }
526
+ end
527
+
528
+ def test_destroy_raises_record_not_found_exception
529
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.destroy(99999) }
530
+ end
531
+
434
532
  def test_update_all
435
533
  assert_equal Topic.count, Topic.update_all("content = 'bulk updated!'")
436
534
  assert_equal "bulk updated!", Topic.find(1).content
437
535
  assert_equal "bulk updated!", Topic.find(2).content
438
536
 
439
- assert_equal Topic.count, Topic.update_all(['content = ?', 'bulk updated again!'])
537
+ assert_equal Topic.count, Topic.update_all(["content = ?", "bulk updated again!"])
440
538
  assert_equal "bulk updated again!", Topic.find(1).content
441
539
  assert_equal "bulk updated again!", Topic.find(2).content
442
540
 
443
- assert_equal Topic.count, Topic.update_all(['content = ?', nil])
541
+ assert_equal Topic.count, Topic.update_all(["content = ?", nil])
444
542
  assert_nil Topic.find(1).content
445
543
  end
446
544
 
447
545
  def test_update_all_with_hash
448
546
  assert_not_nil Topic.find(1).last_read
449
- assert_equal Topic.count, Topic.update_all(:content => 'bulk updated with hash!', :last_read => nil)
547
+ assert_equal Topic.count, Topic.update_all(content: "bulk updated with hash!", last_read: nil)
450
548
  assert_equal "bulk updated with hash!", Topic.find(1).content
451
549
  assert_equal "bulk updated with hash!", Topic.find(2).content
452
550
  assert_nil Topic.find(1).last_read
453
551
  assert_nil Topic.find(2).last_read
454
552
  end
455
553
 
456
- def test_update_all_with_non_standard_table_name
457
- assert_equal 1, WarehouseThing.where(id: 1).update_all(['value = ?', 0])
458
- assert_equal 0, WarehouseThing.find(1).value
459
- end
460
-
461
554
  def test_delete_new_record
462
- client = Client.new
555
+ client = Client.new(name: "37signals")
463
556
  client.delete
464
- assert client.frozen?
557
+ assert_predicate client, :frozen?
558
+
559
+ assert_not client.save
560
+ assert_raise(ActiveRecord::RecordNotSaved) { client.save! }
561
+
562
+ assert_predicate client, :frozen?
563
+ assert_raise(RuntimeError) { client.name = "something else" }
465
564
  end
466
565
 
467
566
  def test_delete_record_with_associations
468
567
  client = Client.find(3)
469
568
  client.delete
470
- assert client.frozen?
569
+ assert_predicate client, :frozen?
471
570
  assert_kind_of Firm, client.firm
571
+
572
+ assert_not client.save
573
+ assert_raise(ActiveRecord::RecordNotSaved) { client.save! }
574
+
575
+ assert_predicate client, :frozen?
472
576
  assert_raise(RuntimeError) { client.name = "something else" }
473
577
  end
474
578
 
475
579
  def test_destroy_new_record
476
- client = Client.new
580
+ client = Client.new(name: "37signals")
477
581
  client.destroy
478
- assert client.frozen?
582
+ assert_predicate client, :frozen?
583
+
584
+ assert_not client.save
585
+ assert_raise(ActiveRecord::RecordNotSaved) { client.save! }
586
+
587
+ assert_predicate client, :frozen?
588
+ assert_raise(RuntimeError) { client.name = "something else" }
479
589
  end
480
590
 
481
591
  def test_destroy_record_with_associations
482
592
  client = Client.find(3)
483
593
  client.destroy
484
- assert client.frozen?
594
+ assert_predicate client, :frozen?
485
595
  assert_kind_of Firm, client.firm
596
+
597
+ assert_not client.save
598
+ assert_raise(ActiveRecord::RecordNotSaved) { client.save! }
599
+
600
+ assert_predicate client, :frozen?
486
601
  assert_raise(RuntimeError) { client.name = "something else" }
487
602
  end
488
603
 
489
604
  def test_update_attribute
490
- assert !Topic.find(1).approved?
605
+ assert_not_predicate Topic.find(1), :approved?
491
606
  Topic.find(1).update_attribute("approved", true)
492
- assert Topic.find(1).approved?
607
+ assert_predicate Topic.find(1), :approved?
493
608
 
494
609
  Topic.find(1).update_attribute(:approved, false)
495
- assert !Topic.find(1).approved?
610
+ assert_not_predicate Topic.find(1), :approved?
611
+
612
+ Topic.find(1).update_attribute(:change_approved_before_save, true)
613
+ assert_predicate Topic.find(1), :approved?
496
614
  end
497
615
 
498
616
  def test_update_attribute_for_readonly_attribute
499
- minivan = Minivan.find('m1')
500
- assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_attribute(:color, 'black') }
617
+ minivan = Minivan.find("m1")
618
+ assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_attribute(:color, "black") }
501
619
  end
502
620
 
503
621
  def test_update_attribute_with_one_updated
504
622
  t = Topic.first
505
- t.update_attribute(:title, 'super_title')
506
- assert_equal 'super_title', t.title
507
- assert !t.changed?, "topic should not have changed"
508
- assert !t.title_changed?, "title should not have changed"
509
- assert_nil t.title_change, 'title change should be nil'
623
+ t.update_attribute(:title, "super_title")
624
+ assert_equal "super_title", t.title
625
+ assert_not t.changed?, "topic should not have changed"
626
+ assert_not t.title_changed?, "title should not have changed"
627
+ assert_nil t.title_change, "title change should be nil"
510
628
 
511
629
  t.reload
512
- assert_equal 'super_title', t.title
630
+ assert_equal "super_title", t.title
513
631
  end
514
632
 
515
633
  def test_update_attribute_for_updated_at_on
@@ -529,14 +647,14 @@ class PersistenceTest < ActiveRecord::TestCase
529
647
  def test_update_column
530
648
  topic = Topic.find(1)
531
649
  topic.update_column("approved", true)
532
- assert topic.approved?
650
+ assert_predicate topic, :approved?
533
651
  topic.reload
534
- assert topic.approved?
652
+ assert_predicate topic, :approved?
535
653
 
536
654
  topic.update_column(:approved, false)
537
- assert !topic.approved?
655
+ assert_not_predicate topic, :approved?
538
656
  topic.reload
539
- assert !topic.approved?
657
+ assert_not_predicate topic, :approved?
540
658
  end
541
659
 
542
660
  def test_update_column_should_not_use_setter_method
@@ -569,17 +687,17 @@ class PersistenceTest < ActiveRecord::TestCase
569
687
  end
570
688
 
571
689
  def test_update_column_with_model_having_primary_key_other_than_id
572
- minivan = Minivan.find('m1')
573
- new_name = 'sebavan'
690
+ minivan = Minivan.find("m1")
691
+ new_name = "sebavan"
574
692
 
575
693
  minivan.update_column(:name, new_name)
576
694
  assert_equal new_name, minivan.name
577
695
  end
578
696
 
579
697
  def test_update_column_for_readonly_attribute
580
- minivan = Minivan.find('m1')
698
+ minivan = Minivan.find("m1")
581
699
  prev_color = minivan.color
582
- assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_column(:color, 'black') }
700
+ assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_column(:color, "black") }
583
701
  assert_equal prev_color, minivan.color
584
702
  end
585
703
 
@@ -598,35 +716,35 @@ class PersistenceTest < ActiveRecord::TestCase
598
716
  end
599
717
 
600
718
  def test_update_column_with_one_changed_and_one_updated
601
- t = Topic.order('id').limit(1).first
719
+ t = Topic.order("id").limit(1).first
602
720
  author_name = t.author_name
603
- t.author_name = 'John'
604
- t.update_column(:title, 'super_title')
605
- assert_equal 'John', t.author_name
606
- assert_equal 'super_title', t.title
721
+ t.author_name = "John"
722
+ t.update_column(:title, "super_title")
723
+ assert_equal "John", t.author_name
724
+ assert_equal "super_title", t.title
607
725
  assert t.changed?, "topic should have changed"
608
726
  assert t.author_name_changed?, "author_name should have changed"
609
727
 
610
728
  t.reload
611
729
  assert_equal author_name, t.author_name
612
- assert_equal 'super_title', t.title
730
+ assert_equal "super_title", t.title
613
731
  end
614
732
 
615
733
  def test_update_column_with_default_scope
616
734
  developer = DeveloperCalledDavid.first
617
- developer.name = 'John'
735
+ developer.name = "John"
618
736
  developer.save!
619
737
 
620
- assert developer.update_column(:name, 'Will'), 'did not update record due to default scope'
738
+ assert developer.update_column(:name, "Will"), "did not update record due to default scope"
621
739
  end
622
740
 
623
741
  def test_update_columns
624
742
  topic = Topic.find(1)
625
- topic.update_columns({ "approved" => true, title: "Sebastian Topic" })
626
- assert topic.approved?
743
+ topic.update_columns("approved" => true, title: "Sebastian Topic")
744
+ assert_predicate topic, :approved?
627
745
  assert_equal "Sebastian Topic", topic.title
628
746
  topic.reload
629
- assert topic.approved?
747
+ assert_predicate topic, :approved?
630
748
  assert_equal "Sebastian Topic", topic.title
631
749
  end
632
750
 
@@ -643,35 +761,35 @@ class PersistenceTest < ActiveRecord::TestCase
643
761
 
644
762
  def test_update_columns_should_raise_exception_if_new_record
645
763
  topic = Topic.new
646
- assert_raises(ActiveRecord::ActiveRecordError) { topic.update_columns({ approved: false }) }
764
+ assert_raises(ActiveRecord::ActiveRecordError) { topic.update_columns(approved: false) }
647
765
  end
648
766
 
649
767
  def test_update_columns_should_not_leave_the_object_dirty
650
768
  topic = Topic.find(1)
651
- topic.update({ "content" => "--- Have a nice day\n...\n", :author_name => "Jose" })
769
+ topic.update("content" => "--- Have a nice day\n...\n", :author_name => "Jose")
652
770
 
653
771
  topic.reload
654
- topic.update_columns({ content: "--- You too\n...\n", "author_name" => "Sebastian" })
772
+ topic.update_columns(content: "--- You too\n...\n", "author_name" => "Sebastian")
655
773
  assert_equal [], topic.changed
656
774
 
657
775
  topic.reload
658
- topic.update_columns({ content: "--- Have a nice day\n...\n", author_name: "Jose" })
776
+ topic.update_columns(content: "--- Have a nice day\n...\n", author_name: "Jose")
659
777
  assert_equal [], topic.changed
660
778
  end
661
779
 
662
780
  def test_update_columns_with_model_having_primary_key_other_than_id
663
- minivan = Minivan.find('m1')
664
- new_name = 'sebavan'
781
+ minivan = Minivan.find("m1")
782
+ new_name = "sebavan"
665
783
 
666
784
  minivan.update_columns(name: new_name)
667
785
  assert_equal new_name, minivan.name
668
786
  end
669
787
 
670
788
  def test_update_columns_with_one_readonly_attribute
671
- minivan = Minivan.find('m1')
789
+ minivan = Minivan.find("m1")
672
790
  prev_color = minivan.color
673
791
  prev_name = minivan.name
674
- assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_columns({ name: "My old minivan", color: 'black' }) }
792
+ assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_columns(name: "My old minivan", color: "black") }
675
793
  assert_equal prev_color, minivan.color
676
794
  assert_equal prev_name, minivan.name
677
795
 
@@ -697,18 +815,18 @@ class PersistenceTest < ActiveRecord::TestCase
697
815
  end
698
816
 
699
817
  def test_update_columns_with_one_changed_and_one_updated
700
- t = Topic.order('id').limit(1).first
818
+ t = Topic.order("id").limit(1).first
701
819
  author_name = t.author_name
702
- t.author_name = 'John'
703
- t.update_columns(title: 'super_title')
704
- assert_equal 'John', t.author_name
705
- assert_equal 'super_title', t.title
820
+ t.author_name = "John"
821
+ t.update_columns(title: "super_title")
822
+ assert_equal "John", t.author_name
823
+ assert_equal "super_title", t.title
706
824
  assert t.changed?, "topic should have changed"
707
825
  assert t.author_name_changed?, "author_name should have changed"
708
826
 
709
827
  t.reload
710
828
  assert_equal author_name, t.author_name
711
- assert_equal 'super_title', t.title
829
+ assert_equal "super_title", t.title
712
830
  end
713
831
 
714
832
  def test_update_columns_changing_id
@@ -726,62 +844,46 @@ class PersistenceTest < ActiveRecord::TestCase
726
844
 
727
845
  def test_update_columns_with_default_scope
728
846
  developer = DeveloperCalledDavid.first
729
- developer.name = 'John'
847
+ developer.name = "John"
730
848
  developer.save!
731
849
 
732
- assert developer.update_columns(name: 'Will'), 'did not update record due to default scope'
850
+ assert developer.update_columns(name: "Will"), "did not update record due to default scope"
733
851
  end
734
852
 
735
853
  def test_update
736
854
  topic = Topic.find(1)
737
- assert !topic.approved?
855
+ assert_not_predicate topic, :approved?
738
856
  assert_equal "The First Topic", topic.title
739
857
 
740
858
  topic.update("approved" => true, "title" => "The First Topic Updated")
741
859
  topic.reload
742
- assert topic.approved?
860
+ assert_predicate topic, :approved?
743
861
  assert_equal "The First Topic Updated", topic.title
744
862
 
745
863
  topic.update(approved: false, title: "The First Topic")
746
864
  topic.reload
747
- assert !topic.approved?
748
- assert_equal "The First Topic", topic.title
749
- end
750
-
751
- def test_update_attributes
752
- topic = Topic.find(1)
753
- assert !topic.approved?
754
- assert_equal "The First Topic", topic.title
755
-
756
- topic.update_attributes("approved" => true, "title" => "The First Topic Updated")
757
- topic.reload
758
- assert topic.approved?
759
- assert_equal "The First Topic Updated", topic.title
760
-
761
- topic.update_attributes(approved: false, title: "The First Topic")
762
- topic.reload
763
- assert !topic.approved?
865
+ assert_not_predicate topic, :approved?
764
866
  assert_equal "The First Topic", topic.title
765
867
 
766
868
  error = assert_raise(ActiveRecord::RecordNotUnique, ActiveRecord::StatementInvalid) do
767
- topic.update_attributes(id: 3, title: "Hm is it possible?")
869
+ topic.update(id: 3, title: "Hm is it possible?")
768
870
  end
769
871
  assert_not_nil error.cause
770
872
  assert_not_equal "Hm is it possible?", Topic.find(3).title
771
873
 
772
- topic.update_attributes(id: 1234)
874
+ topic.update(id: 1234)
773
875
  assert_nothing_raised { topic.reload }
774
876
  assert_equal topic.title, Topic.find(1234).title
775
877
  end
776
878
 
777
- def test_update_attributes_parameters
879
+ def test_update_parameters
778
880
  topic = Topic.find(1)
779
881
  assert_nothing_raised do
780
- topic.update_attributes({})
882
+ topic.update({})
781
883
  end
782
884
 
783
885
  assert_raises(ArgumentError) do
784
- topic.update_attributes(nil)
886
+ topic.update(nil)
785
887
  end
786
888
  end
787
889
 
@@ -806,27 +908,6 @@ class PersistenceTest < ActiveRecord::TestCase
806
908
  Reply.clear_validators!
807
909
  end
808
910
 
809
- def test_update_attributes!
810
- Reply.validates_presence_of(:title)
811
- reply = Reply.find(2)
812
- assert_equal "The Second Topic of the day", reply.title
813
- assert_equal "Have a nice day", reply.content
814
-
815
- reply.update_attributes!("title" => "The Second Topic of the day updated", "content" => "Have a nice evening")
816
- reply.reload
817
- assert_equal "The Second Topic of the day updated", reply.title
818
- assert_equal "Have a nice evening", reply.content
819
-
820
- reply.update_attributes!(title: "The Second Topic of the day", content: "Have a nice day")
821
- reply.reload
822
- assert_equal "The Second Topic of the day", reply.title
823
- assert_equal "Have a nice day", reply.content
824
-
825
- assert_raise(ActiveRecord::RecordInvalid) { reply.update_attributes!(title: nil, content: "Have a nice evening") }
826
- ensure
827
- Reply.clear_validators!
828
- end
829
-
830
911
  def test_destroyed_returns_boolean
831
912
  developer = Developer.first
832
913
  assert_equal false, developer.destroyed?
@@ -840,7 +921,7 @@ class PersistenceTest < ActiveRecord::TestCase
840
921
  end
841
922
 
842
923
  def test_persisted_returns_boolean
843
- developer = Developer.new(:name => "Jose")
924
+ developer = Developer.new(name: "Jose")
844
925
  assert_equal false, developer.persisted?
845
926
  developer.save!
846
927
  assert_equal true, developer.persisted?
@@ -860,18 +941,41 @@ class PersistenceTest < ActiveRecord::TestCase
860
941
  should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
861
942
  Topic.find(1).replies << should_be_destroyed_reply
862
943
 
863
- Topic.destroy(1)
944
+ topic = Topic.destroy(1)
945
+ assert_predicate topic, :destroyed?
946
+
864
947
  assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) }
865
948
  assert_raise(ActiveRecord::RecordNotFound) { Reply.find(should_be_destroyed_reply.id) }
866
949
  end
867
950
 
951
+ def test_class_level_destroy_is_affected_by_scoping
952
+ should_not_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
953
+ Topic.find(1).replies << should_not_be_destroyed_reply
954
+
955
+ assert_raise(ActiveRecord::RecordNotFound) do
956
+ Topic.where("1=0").scoping { Topic.destroy(1) }
957
+ end
958
+
959
+ assert_nothing_raised { Topic.find(1) }
960
+ assert_nothing_raised { Reply.find(should_not_be_destroyed_reply.id) }
961
+ end
962
+
868
963
  def test_class_level_delete
869
- should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
870
- Topic.find(1).replies << should_be_destroyed_reply
964
+ should_not_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
965
+ Topic.find(1).replies << should_not_be_destroyed_reply
871
966
 
872
967
  Topic.delete(1)
873
968
  assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) }
874
- assert_nothing_raised { Reply.find(should_be_destroyed_reply.id) }
969
+ assert_nothing_raised { Reply.find(should_not_be_destroyed_reply.id) }
970
+ end
971
+
972
+ def test_class_level_delete_is_affected_by_scoping
973
+ should_not_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
974
+ Topic.find(1).replies << should_not_be_destroyed_reply
975
+
976
+ Topic.where("1=0").scoping { Topic.delete(1) }
977
+ assert_nothing_raised { Topic.find(1) }
978
+ assert_nothing_raised { Reply.find(should_not_be_destroyed_reply.id) }
875
979
  end
876
980
 
877
981
  def test_create_with_custom_timestamps
@@ -909,7 +1013,7 @@ class PersistenceTest < ActiveRecord::TestCase
909
1013
  end
910
1014
 
911
1015
  def test_reload_removes_custom_selects
912
- post = Post.select('posts.*, 1 as wibble').last!
1016
+ post = Post.select("posts.*, 1 as wibble").last!
913
1017
 
914
1018
  assert_equal 1, post[:wibble]
915
1019
  assert_nil post.reload[:wibble]
@@ -918,20 +1022,20 @@ class PersistenceTest < ActiveRecord::TestCase
918
1022
  def test_find_via_reload
919
1023
  post = Post.new
920
1024
 
921
- assert post.new_record?
1025
+ assert_predicate post, :new_record?
922
1026
 
923
1027
  post.id = 1
924
1028
  post.reload
925
1029
 
926
1030
  assert_equal "Welcome to the weblog", post.title
927
- assert_not post.new_record?
1031
+ assert_not_predicate post, :new_record?
928
1032
  end
929
1033
 
930
1034
  def test_reload_via_querycache
931
1035
  ActiveRecord::Base.connection.enable_query_cache!
932
1036
  ActiveRecord::Base.connection.clear_query_cache
933
- assert ActiveRecord::Base.connection.query_cache_enabled, 'cache should be on'
934
- parrot = Parrot.create(:name => 'Shane')
1037
+ assert ActiveRecord::Base.connection.query_cache_enabled, "cache should be on"
1038
+ parrot = Parrot.create(name: "Shane")
935
1039
 
936
1040
  # populate the cache with the SELECT result
937
1041
  found_parrot = Parrot.find(parrot.id)
@@ -940,60 +1044,48 @@ class PersistenceTest < ActiveRecord::TestCase
940
1044
  # Manually update the 'name' attribute in the DB directly
941
1045
  assert_equal 1, ActiveRecord::Base.connection.query_cache.length
942
1046
  ActiveRecord::Base.uncached do
943
- found_parrot.name = 'Mary'
1047
+ found_parrot.name = "Mary"
944
1048
  found_parrot.save
945
1049
  end
946
1050
 
947
1051
  # Now reload, and verify that it gets the DB version, and not the querycache version
948
1052
  found_parrot.reload
949
- assert_equal 'Mary', found_parrot.name
1053
+ assert_equal "Mary", found_parrot.name
950
1054
 
951
1055
  found_parrot = Parrot.find(parrot.id)
952
- assert_equal 'Mary', found_parrot.name
1056
+ assert_equal "Mary", found_parrot.name
953
1057
  ensure
954
1058
  ActiveRecord::Base.connection.disable_query_cache!
955
1059
  end
956
1060
 
957
- class SaveTest < ActiveRecord::TestCase
958
- self.use_transactional_tests = false
1061
+ def test_save_touch_false
1062
+ parrot = Parrot.create!(
1063
+ name: "Bob",
1064
+ created_at: 1.day.ago,
1065
+ updated_at: 1.day.ago)
959
1066
 
960
- def test_save_touch_false
961
- widget = Class.new(ActiveRecord::Base) do
962
- connection.create_table :widgets, force: true do |t|
963
- t.string :name
964
- t.timestamps null: false
965
- end
1067
+ created_at = parrot.created_at
1068
+ updated_at = parrot.updated_at
966
1069
 
967
- self.table_name = :widgets
968
- end
969
-
970
- instance = widget.create!({
971
- name: 'Bob',
972
- created_at: 1.day.ago,
973
- updated_at: 1.day.ago
974
- })
975
-
976
- created_at = instance.created_at
977
- updated_at = instance.updated_at
978
-
979
- instance.name = 'Barb'
980
- instance.save!(touch: false)
981
- assert_equal instance.created_at, created_at
982
- assert_equal instance.updated_at, updated_at
983
- ensure
984
- ActiveRecord::Base.connection.drop_table widget.table_name
985
- widget.reset_column_information
986
- end
1070
+ parrot.name = "Barb"
1071
+ parrot.save!(touch: false)
1072
+ assert_equal parrot.created_at, created_at
1073
+ assert_equal parrot.updated_at, updated_at
987
1074
  end
988
1075
 
989
1076
  def test_reset_column_information_resets_children
990
- child = Class.new(Topic)
991
- child.new # force schema to load
1077
+ child_class = Class.new(Topic)
1078
+ child_class.new # force schema to load
992
1079
 
993
1080
  ActiveRecord::Base.connection.add_column(:topics, :foo, :string)
994
1081
  Topic.reset_column_information
995
1082
 
996
- assert_equal "bar", child.new(foo: :bar).foo
1083
+ # this should redefine attribute methods
1084
+ child_class.new
1085
+
1086
+ assert child_class.instance_methods.include?(:foo)
1087
+ assert child_class.instance_methods.include?(:foo_changed?)
1088
+ assert_equal "bar", child_class.new(foo: :bar).foo
997
1089
  ensure
998
1090
  ActiveRecord::Base.connection.remove_column(:topics, :foo)
999
1091
  Topic.reset_column_information