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,39 +1,160 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cases/helper"
2
- require 'models/topic'
3
- require 'models/reply'
4
- require 'models/developer'
5
- require 'models/computer'
6
- require 'models/book'
7
- require 'models/author'
8
- require 'models/post'
9
- require 'models/movie'
4
+ require "models/topic"
5
+ require "models/reply"
6
+ require "models/developer"
7
+ require "models/computer"
8
+ require "models/book"
9
+ require "models/author"
10
+ require "models/post"
11
+ require "models/movie"
10
12
 
11
13
  class TransactionTest < ActiveRecord::TestCase
12
14
  self.use_transactional_tests = false
13
- fixtures :topics, :developers, :authors, :posts, :author_addresses
15
+ fixtures :topics, :developers, :authors, :author_addresses, :posts
14
16
 
15
17
  def setup
16
18
  @first, @second = Topic.find(1, 2).sort_by(&:id)
17
19
  end
18
20
 
21
+ def test_rollback_dirty_changes
22
+ topic = topics(:fifth)
23
+
24
+ ActiveRecord::Base.transaction do
25
+ topic.update(title: "Ruby on Rails")
26
+ raise ActiveRecord::Rollback
27
+ end
28
+
29
+ title_change = ["The Fifth Topic of the day", "Ruby on Rails"]
30
+ assert_equal title_change, topic.changes["title"]
31
+ end
32
+
33
+ if !in_memory_db?
34
+ def test_rollback_dirty_changes_even_with_raise_during_rollback_removes_from_pool
35
+ topic = topics(:fifth)
36
+
37
+ connection = Topic.connection
38
+
39
+ Topic.connection.class_eval do
40
+ alias :real_exec_rollback_db_transaction :exec_rollback_db_transaction
41
+ define_method(:exec_rollback_db_transaction) do
42
+ raise
43
+ end
44
+ end
45
+
46
+ ActiveRecord::Base.transaction do
47
+ topic.update(title: "Rails is broken")
48
+ raise ActiveRecord::Rollback
49
+ end
50
+
51
+ assert_not connection.active?
52
+ assert_not Topic.connection_pool.connections.include?(connection)
53
+ end
54
+
55
+ def test_rollback_dirty_changes_even_with_raise_during_rollback_doesnt_commit_transaction
56
+ topic = topics(:fifth)
57
+
58
+ Topic.connection.class_eval do
59
+ alias :real_exec_rollback_db_transaction :exec_rollback_db_transaction
60
+ define_method(:exec_rollback_db_transaction) do
61
+ raise
62
+ end
63
+ end
64
+
65
+ ActiveRecord::Base.transaction do
66
+ topic.update(title: "Rails is broken")
67
+ raise ActiveRecord::Rollback
68
+ end
69
+
70
+ topic.reload
71
+
72
+ ActiveRecord::Base.transaction do
73
+ topic.update(content: "Ruby on Rails - modified")
74
+ end
75
+
76
+ assert_equal "The Fifth Topic of the day", topic.reload.title
77
+ end
78
+ end
79
+
80
+ def test_rollback_dirty_changes_multiple_saves
81
+ topic = topics(:fifth)
82
+
83
+ ActiveRecord::Base.transaction do
84
+ topic.update(title: "Ruby on Rails")
85
+ topic.update(title: "Another Title")
86
+ raise ActiveRecord::Rollback
87
+ end
88
+
89
+ title_change = ["The Fifth Topic of the day", "Another Title"]
90
+ assert_equal title_change, topic.changes["title"]
91
+ end
92
+
93
+ def test_rollback_dirty_changes_then_retry_save
94
+ topic = topics(:fifth)
95
+
96
+ ActiveRecord::Base.transaction do
97
+ topic.update(title: "Ruby on Rails")
98
+ raise ActiveRecord::Rollback
99
+ end
100
+
101
+ title_change = ["The Fifth Topic of the day", "Ruby on Rails"]
102
+ assert_equal title_change, topic.changes["title"]
103
+
104
+ assert topic.save
105
+
106
+ assert_equal title_change, topic.saved_changes["title"]
107
+ assert_equal topic.title, topic.reload.title
108
+ end
109
+
110
+ def test_rollback_dirty_changes_then_retry_save_on_new_record
111
+ topic = Topic.new(title: "Ruby on Rails")
112
+
113
+ ActiveRecord::Base.transaction do
114
+ topic.save
115
+ raise ActiveRecord::Rollback
116
+ end
117
+
118
+ title_change = [nil, "Ruby on Rails"]
119
+ assert_equal title_change, topic.changes["title"]
120
+
121
+ assert topic.save
122
+
123
+ assert_equal title_change, topic.saved_changes["title"]
124
+ assert_equal topic.title, topic.reload.title
125
+ end
126
+
127
+ def test_rollback_dirty_changes_then_retry_save_on_new_record_with_autosave_association
128
+ author = Author.new(name: "DHH")
129
+ book = Book.create!
130
+ author.books << book
131
+
132
+ author.transaction do
133
+ author.save!
134
+ raise ActiveRecord::Rollback
135
+ end
136
+
137
+ author.save!
138
+ assert_equal author, book.reload.author
139
+ end
140
+
19
141
  def test_persisted_in_a_model_with_custom_primary_key_after_failed_save
20
142
  movie = Movie.create
21
- assert !movie.persisted?
143
+ assert_not_predicate movie, :persisted?
22
144
  end
23
145
 
24
146
  def test_raise_after_destroy
25
- assert_not @first.frozen?
147
+ assert_not_predicate @first, :frozen?
26
148
 
27
- assert_raises(RuntimeError) {
149
+ assert_raises(RuntimeError) do
28
150
  Topic.transaction do
29
151
  @first.destroy
30
- assert @first.frozen?
152
+ assert_predicate @first, :frozen?
31
153
  raise
32
154
  end
33
- }
155
+ end
34
156
 
35
- assert @first.reload
36
- assert_not @first.frozen?
157
+ assert_not_predicate @first, :frozen?
37
158
  end
38
159
 
39
160
  def test_successful
@@ -44,8 +165,8 @@ class TransactionTest < ActiveRecord::TestCase
44
165
  @second.save
45
166
  end
46
167
 
47
- assert Topic.find(1).approved?, "First should have been approved"
48
- assert !Topic.find(2).approved?, "Second should have been unapproved"
168
+ assert_predicate Topic.find(1), :approved?, "First should have been approved"
169
+ assert_not_predicate Topic.find(2), :approved?, "Second should have been unapproved"
49
170
  end
50
171
 
51
172
  def transaction_with_return
@@ -60,7 +181,7 @@ class TransactionTest < ActiveRecord::TestCase
60
181
 
61
182
  def test_add_to_null_transaction
62
183
  topic = Topic.new
63
- topic.add_to_transaction
184
+ topic.send(:add_to_transaction)
64
185
  end
65
186
 
66
187
  def test_successful_with_return
@@ -74,11 +195,13 @@ class TransactionTest < ActiveRecord::TestCase
74
195
  end
75
196
  end
76
197
 
77
- transaction_with_return
198
+ assert_deprecated do
199
+ transaction_with_return
200
+ end
78
201
  assert committed
79
202
 
80
- assert Topic.find(1).approved?, "First should have been approved"
81
- assert !Topic.find(2).approved?, "Second should have been unapproved"
203
+ assert_predicate Topic.find(1), :approved?, "First should have been approved"
204
+ assert_not_predicate Topic.find(2), :approved?, "Second should have been unapproved"
82
205
  ensure
83
206
  Topic.connection.class_eval do
84
207
  remove_method :commit_db_transaction
@@ -86,6 +209,29 @@ class TransactionTest < ActiveRecord::TestCase
86
209
  end
87
210
  end
88
211
 
212
+ def test_deprecation_on_ruby_timeout
213
+ assert_deprecated do
214
+ catch do |timeout|
215
+ Topic.transaction do
216
+ @first.approved = true
217
+ @first.save!
218
+
219
+ throw timeout
220
+ end
221
+ end
222
+ end
223
+
224
+ assert Topic.find(1).approved?, "First should have been approved"
225
+ end
226
+
227
+ def test_early_return_from_transaction
228
+ assert_not_deprecated do
229
+ @first.with_lock do
230
+ break
231
+ end
232
+ end
233
+ end
234
+
89
235
  def test_number_of_transactions_in_commit
90
236
  num = nil
91
237
 
@@ -98,7 +244,7 @@ class TransactionTest < ActiveRecord::TestCase
98
244
  end
99
245
 
100
246
  Topic.transaction do
101
- @first.approved = true
247
+ @first.approved = true
102
248
  @first.save!
103
249
  end
104
250
 
@@ -118,8 +264,8 @@ class TransactionTest < ActiveRecord::TestCase
118
264
  @second.save
119
265
  end
120
266
 
121
- assert Topic.find(1).approved?, "First should have been approved"
122
- assert !Topic.find(2).approved?, "Second should have been unapproved"
267
+ assert_predicate Topic.find(1), :approved?, "First should have been approved"
268
+ assert_not_predicate Topic.find(2), :approved?, "Second should have been unapproved"
123
269
  end
124
270
 
125
271
  def test_failing_on_exception
@@ -135,56 +281,58 @@ class TransactionTest < ActiveRecord::TestCase
135
281
  # caught it
136
282
  end
137
283
 
138
- assert @first.approved?, "First should still be changed in the objects"
139
- assert !@second.approved?, "Second should still be changed in the objects"
284
+ assert_predicate @first, :approved?, "First should still be changed in the objects"
285
+ assert_not_predicate @second, :approved?, "Second should still be changed in the objects"
140
286
 
141
- assert !Topic.find(1).approved?, "First shouldn't have been approved"
142
- assert Topic.find(2).approved?, "Second should still be approved"
287
+ assert_not_predicate Topic.find(1), :approved?, "First shouldn't have been approved"
288
+ assert_predicate Topic.find(2), :approved?, "Second should still be approved"
143
289
  end
144
290
 
145
291
  def test_raising_exception_in_callback_rollbacks_in_save
146
292
  def @first.after_save_for_transaction
147
- raise 'Make the transaction rollback'
293
+ raise "Make the transaction rollback"
148
294
  end
149
295
 
150
296
  @first.approved = true
151
297
  e = assert_raises(RuntimeError) { @first.save }
152
298
  assert_equal "Make the transaction rollback", e.message
153
- assert !Topic.find(1).approved?
299
+ assert_not_predicate Topic.find(1), :approved?
154
300
  end
155
301
 
156
302
  def test_rolling_back_in_a_callback_rollbacks_before_save
157
303
  def @first.before_save_for_transaction
158
304
  raise ActiveRecord::Rollback
159
305
  end
160
- assert !@first.approved
306
+ assert_not_predicate @first, :approved?
161
307
 
162
- Topic.transaction do
163
- @first.approved = true
164
- @first.save!
308
+ assert_not_called(@first, :rolledback!) do
309
+ Topic.transaction do
310
+ @first.approved = true
311
+ @first.save!
312
+ end
165
313
  end
166
- assert !Topic.find(@first.id).approved?, "Should not commit the approved flag"
314
+ assert_not_predicate Topic.find(@first.id), :approved?, "Should not commit the approved flag"
167
315
  end
168
316
 
169
317
  def test_raising_exception_in_nested_transaction_restore_state_in_save
170
318
  topic = Topic.new
171
319
 
172
320
  def topic.after_save_for_transaction
173
- raise 'Make the transaction rollback'
321
+ raise "Make the transaction rollback"
174
322
  end
175
323
 
176
324
  assert_raises(RuntimeError) do
177
325
  Topic.transaction { topic.save }
178
326
  end
179
327
 
180
- assert topic.new_record?, "#{topic.inspect} should be new record"
328
+ assert_predicate topic, :new_record?, "#{topic.inspect} should be new record"
181
329
  end
182
330
 
183
331
  def test_transaction_state_is_cleared_when_record_is_persisted
184
- author = Author.create! name: 'foo'
332
+ author = Author.create! name: "foo"
185
333
  author.name = nil
186
334
  assert_not author.save
187
- assert_not author.new_record?
335
+ assert_not_predicate author, :new_record?
188
336
  end
189
337
 
190
338
  def test_update_should_rollback_on_failure
@@ -192,7 +340,7 @@ class TransactionTest < ActiveRecord::TestCase
192
340
  posts_count = author.posts.size
193
341
  assert posts_count > 0
194
342
  status = author.update(name: nil, post_ids: [])
195
- assert !status
343
+ assert_not status
196
344
  assert_equal posts_count, author.posts.reload.size
197
345
  end
198
346
 
@@ -206,21 +354,11 @@ class TransactionTest < ActiveRecord::TestCase
206
354
  assert_equal posts_count, author.posts.reload.size
207
355
  end
208
356
 
209
- def test_cancellation_from_returning_false_in_before_filter
210
- def @first.before_save_for_transaction
211
- false
212
- end
213
-
214
- assert_deprecated do
215
- @first.save
216
- end
217
- end
218
-
219
357
  def test_cancellation_from_before_destroy_rollbacks_in_destroy
220
358
  add_cancelling_before_destroy_with_db_side_effect_to_topic @first
221
359
  nbooks_before_destroy = Book.count
222
360
  status = @first.destroy
223
- assert !status
361
+ assert_not status
224
362
  @first.reload
225
363
  assert_equal nbooks_before_destroy, Book.count
226
364
  end
@@ -230,9 +368,9 @@ class TransactionTest < ActiveRecord::TestCase
230
368
  send("add_cancelling_before_#{filter}_with_db_side_effect_to_topic", @first)
231
369
  nbooks_before_save = Book.count
232
370
  original_author_name = @first.author_name
233
- @first.author_name += '_this_should_not_end_up_in_the_db'
371
+ @first.author_name += "_this_should_not_end_up_in_the_db"
234
372
  status = @first.save
235
- assert !status
373
+ assert_not status
236
374
  assert_equal original_author_name, @first.reload.author_name
237
375
  assert_equal nbooks_before_save, Book.count
238
376
  end
@@ -241,7 +379,7 @@ class TransactionTest < ActiveRecord::TestCase
241
379
  send("add_cancelling_before_#{filter}_with_db_side_effect_to_topic", @first)
242
380
  nbooks_before_save = Book.count
243
381
  original_author_name = @first.author_name
244
- @first.author_name += '_this_should_not_end_up_in_the_db'
382
+ @first.author_name += "_this_should_not_end_up_in_the_db"
245
383
 
246
384
  begin
247
385
  @first.save!
@@ -256,18 +394,18 @@ class TransactionTest < ActiveRecord::TestCase
256
394
  def test_callback_rollback_in_create
257
395
  topic = Class.new(Topic) {
258
396
  def after_create_for_transaction
259
- raise 'Make the transaction rollback'
397
+ raise "Make the transaction rollback"
260
398
  end
261
399
  }
262
400
 
263
- new_topic = topic.new(:title => "A new topic",
264
- :author_name => "Ben",
265
- :author_email_address => "ben@example.com",
266
- :written_on => "2003-07-16t15:28:11.2233+01:00",
267
- :last_read => "2004-04-15",
268
- :bonus_time => "2005-01-30t15:28:00.00+01:00",
269
- :content => "Have a nice day",
270
- :approved => false)
401
+ new_topic = topic.new(title: "A new topic",
402
+ author_name: "Ben",
403
+ author_email_address: "ben@example.com",
404
+ written_on: "2003-07-16t15:28:11.2233+01:00",
405
+ last_read: "2004-04-15",
406
+ bonus_time: "2005-01-30t15:28:00.00+01:00",
407
+ content: "Have a nice day",
408
+ approved: false)
271
409
 
272
410
  new_record_snapshot = !new_topic.persisted?
273
411
  id_present = new_topic.has_attribute?(Topic.primary_key)
@@ -279,7 +417,11 @@ class TransactionTest < ActiveRecord::TestCase
279
417
  e = assert_raises(RuntimeError) { new_topic.save }
280
418
  assert_equal "Make the transaction rollback", e.message
281
419
  assert_equal new_record_snapshot, !new_topic.persisted?, "The topic should have its old persisted value"
282
- assert_equal id_snapshot, new_topic.id, "The topic should have its old id"
420
+ if id_snapshot.nil?
421
+ assert_nil new_topic.id, "The topic should have its old id"
422
+ else
423
+ assert_equal id_snapshot, new_topic.id, "The topic should have its old id"
424
+ end
283
425
  assert_equal id_present, new_topic.has_attribute?(Topic.primary_key)
284
426
  end
285
427
  end
@@ -291,8 +433,20 @@ class TransactionTest < ActiveRecord::TestCase
291
433
  end
292
434
  }
293
435
 
294
- new_topic = topic.create(:title => "A new topic")
295
- assert !new_topic.persisted?, "The topic should not be persisted"
436
+ new_topic = topic.create(title: "A new topic")
437
+ assert_not new_topic.persisted?, "The topic should not be persisted"
438
+ assert_nil new_topic.id, "The topic should not have an ID"
439
+ end
440
+
441
+ def test_callback_rollback_in_create_with_rollback_exception
442
+ topic = Class.new(Topic) {
443
+ def after_create_for_transaction
444
+ raise ActiveRecord::Rollback
445
+ end
446
+ }
447
+
448
+ new_topic = topic.create(title: "A new topic")
449
+ assert_not new_topic.persisted?, "The topic should not be persisted"
296
450
  assert_nil new_topic.id, "The topic should not have an ID"
297
451
  end
298
452
 
@@ -307,7 +461,77 @@ class TransactionTest < ActiveRecord::TestCase
307
461
  end
308
462
 
309
463
  assert Topic.find(1).approved?, "First should have been approved"
310
- assert !Topic.find(2).approved?, "Second should have been unapproved"
464
+ assert_not Topic.find(2).approved?, "Second should have been unapproved"
465
+ end
466
+
467
+ def test_nested_transaction_with_new_transaction_applies_parent_state_on_rollback
468
+ topic_one = Topic.new(title: "A new topic")
469
+ topic_two = Topic.new(title: "Another new topic")
470
+
471
+ Topic.transaction do
472
+ topic_one.save
473
+
474
+ Topic.transaction(requires_new: true) do
475
+ topic_two.save
476
+
477
+ assert_predicate topic_one, :persisted?
478
+ assert_predicate topic_two, :persisted?
479
+ end
480
+
481
+ raise ActiveRecord::Rollback
482
+ end
483
+
484
+ assert_not_predicate topic_one, :persisted?
485
+ assert_not_predicate topic_two, :persisted?
486
+ end
487
+
488
+ def test_nested_transaction_without_new_transaction_applies_parent_state_on_rollback
489
+ topic_one = Topic.new(title: "A new topic")
490
+ topic_two = Topic.new(title: "Another new topic")
491
+
492
+ Topic.transaction do
493
+ topic_one.save
494
+
495
+ Topic.transaction do
496
+ topic_two.save
497
+
498
+ assert_predicate topic_one, :persisted?
499
+ assert_predicate topic_two, :persisted?
500
+ end
501
+
502
+ raise ActiveRecord::Rollback
503
+ end
504
+
505
+ assert_not_predicate topic_one, :persisted?
506
+ assert_not_predicate topic_two, :persisted?
507
+ end
508
+
509
+ def test_double_nested_transaction_applies_parent_state_on_rollback
510
+ topic_one = Topic.new(title: "A new topic")
511
+ topic_two = Topic.new(title: "Another new topic")
512
+ topic_three = Topic.new(title: "Another new topic of course")
513
+
514
+ Topic.transaction do
515
+ topic_one.save
516
+
517
+ Topic.transaction do
518
+ topic_two.save
519
+
520
+ Topic.transaction do
521
+ topic_three.save
522
+ end
523
+ end
524
+
525
+ assert_predicate topic_one, :persisted?
526
+ assert_predicate topic_two, :persisted?
527
+ assert_predicate topic_three, :persisted?
528
+
529
+ raise ActiveRecord::Rollback
530
+ end
531
+
532
+ assert_not_predicate topic_one, :persisted?
533
+ assert_not_predicate topic_two, :persisted?
534
+ assert_not_predicate topic_three, :persisted?
311
535
  end
312
536
 
313
537
  def test_manually_rolling_back_a_transaction
@@ -321,15 +545,15 @@ class TransactionTest < ActiveRecord::TestCase
321
545
  end
322
546
 
323
547
  assert @first.approved?, "First should still be changed in the objects"
324
- assert !@second.approved?, "Second should still be changed in the objects"
548
+ assert_not @second.approved?, "Second should still be changed in the objects"
325
549
 
326
- assert !Topic.find(1).approved?, "First shouldn't have been approved"
550
+ assert_not Topic.find(1).approved?, "First shouldn't have been approved"
327
551
  assert Topic.find(2).approved?, "Second should still be approved"
328
552
  end
329
553
 
330
554
  def test_invalid_keys_for_transaction
331
555
  assert_raise ArgumentError do
332
- Topic.transaction :nested => true do
556
+ Topic.transaction nested: true do
333
557
  end
334
558
  end
335
559
  end
@@ -342,8 +566,8 @@ class TransactionTest < ActiveRecord::TestCase
342
566
  @second.save!
343
567
 
344
568
  begin
345
- Topic.transaction :requires_new => true do
346
- @first.happy = false
569
+ Topic.transaction requires_new: true do
570
+ @first.approved = false
347
571
  @first.save!
348
572
  raise
349
573
  end
@@ -351,8 +575,8 @@ class TransactionTest < ActiveRecord::TestCase
351
575
  end
352
576
  end
353
577
 
354
- assert @first.reload.approved?
355
- assert !@second.reload.approved?
578
+ assert_predicate @first.reload, :approved?
579
+ assert_not_predicate @second.reload, :approved?
356
580
  end if Topic.connection.supports_savepoints?
357
581
 
358
582
  def test_force_savepoint_on_instance
@@ -363,8 +587,8 @@ class TransactionTest < ActiveRecord::TestCase
363
587
  @second.save!
364
588
 
365
589
  begin
366
- @second.transaction :requires_new => true do
367
- @first.happy = false
590
+ @second.transaction requires_new: true do
591
+ @first.approved = false
368
592
  @first.save!
369
593
  raise
370
594
  end
@@ -372,8 +596,8 @@ class TransactionTest < ActiveRecord::TestCase
372
596
  end
373
597
  end
374
598
 
375
- assert @first.reload.approved?
376
- assert !@second.reload.approved?
599
+ assert_predicate @first.reload, :approved?
600
+ assert_not_predicate @second.reload, :approved?
377
601
  end if Topic.connection.supports_savepoints?
378
602
 
379
603
  def test_no_savepoint_in_nested_transaction_without_force
@@ -393,8 +617,8 @@ class TransactionTest < ActiveRecord::TestCase
393
617
  end
394
618
  end
395
619
 
396
- assert !@first.reload.approved?
397
- assert !@second.reload.approved?
620
+ assert_not_predicate @first.reload, :approved?
621
+ assert_not_predicate @second.reload, :approved?
398
622
  end if Topic.connection.supports_savepoints?
399
623
 
400
624
  def test_many_savepoints
@@ -403,17 +627,17 @@ class TransactionTest < ActiveRecord::TestCase
403
627
  @first.save!
404
628
 
405
629
  begin
406
- Topic.transaction :requires_new => true do
630
+ Topic.transaction requires_new: true do
407
631
  @first.content = "Two"
408
632
  @first.save!
409
633
 
410
634
  begin
411
- Topic.transaction :requires_new => true do
635
+ Topic.transaction requires_new: true do
412
636
  @first.content = "Three"
413
637
  @first.save!
414
638
 
415
639
  begin
416
- Topic.transaction :requires_new => true do
640
+ Topic.transaction requires_new: true do
417
641
  @first.content = "Four"
418
642
  @first.save!
419
643
  raise
@@ -443,19 +667,19 @@ class TransactionTest < ActiveRecord::TestCase
443
667
 
444
668
  def test_using_named_savepoints
445
669
  Topic.transaction do
446
- @first.approved = true
670
+ @first.approved = true
447
671
  @first.save!
448
672
  Topic.connection.create_savepoint("first")
449
673
 
450
- @first.approved = false
674
+ @first.approved = false
451
675
  @first.save!
452
676
  Topic.connection.rollback_to_savepoint("first")
453
- assert @first.reload.approved?
677
+ assert_predicate @first.reload, :approved?
454
678
 
455
- @first.approved = false
679
+ @first.approved = false
456
680
  @first.save!
457
681
  Topic.connection.release_savepoint("first")
458
- assert_not @first.reload.approved?
682
+ assert_not_predicate @first.reload, :approved?
459
683
  end
460
684
  end if Topic.connection.supports_savepoints?
461
685
 
@@ -493,31 +717,30 @@ class TransactionTest < ActiveRecord::TestCase
493
717
 
494
718
  def test_rollback_when_commit_raises
495
719
  assert_called(Topic.connection, :begin_db_transaction) do
496
- Topic.connection.stub(:commit_db_transaction, ->{ raise('OH NOES') }) do
720
+ Topic.connection.stub(:commit_db_transaction, -> { raise("OH NOES") }) do
497
721
  assert_called(Topic.connection, :rollback_db_transaction) do
498
-
499
722
  e = assert_raise RuntimeError do
500
723
  Topic.transaction do
501
- # do nothing
724
+ Topic.connection.materialize_transactions
502
725
  end
503
726
  end
504
- assert_equal 'OH NOES', e.message
727
+ assert_equal "OH NOES", e.message
505
728
  end
506
729
  end
507
730
  end
508
731
  end
509
732
 
510
733
  def test_rollback_when_saving_a_frozen_record
511
- topic = Topic.new(:title => 'test')
734
+ topic = Topic.new(title: "test")
512
735
  topic.freeze
513
- e = assert_raise(frozen_error_class) { topic.save }
736
+ e = assert_raise(FrozenError) { topic.save }
514
737
  # Not good enough, but we can't do much
515
738
  # about it since there is no specific error
516
739
  # for frozen objects.
517
740
  assert_match(/frozen/i, e.message)
518
- assert !topic.persisted?, "not persisted"
741
+ assert_not topic.persisted?, "not persisted"
519
742
  assert_nil topic.id
520
- assert topic.frozen?, 'not frozen'
743
+ assert topic.frozen?, "not frozen"
521
744
  end
522
745
 
523
746
  def test_rollback_when_thread_killed
@@ -542,20 +765,20 @@ class TransactionTest < ActiveRecord::TestCase
542
765
  thread.join
543
766
 
544
767
  assert @first.approved?, "First should still be changed in the objects"
545
- assert !@second.approved?, "Second should still be changed in the objects"
768
+ assert_not @second.approved?, "Second should still be changed in the objects"
546
769
 
547
- assert !Topic.find(1).approved?, "First shouldn't have been approved"
770
+ assert_not Topic.find(1).approved?, "First shouldn't have been approved"
548
771
  assert Topic.find(2).approved?, "Second should still be approved"
549
772
  end
550
773
 
551
774
  def test_restore_active_record_state_for_all_records_in_a_transaction
552
775
  topic_without_callbacks = Class.new(ActiveRecord::Base) do
553
- self.table_name = 'topics'
776
+ self.table_name = "topics"
554
777
  end
555
778
 
556
- topic_1 = Topic.new(:title => 'test_1')
557
- topic_2 = Topic.new(:title => 'test_2')
558
- topic_3 = topic_without_callbacks.new(:title => 'test_3')
779
+ topic_1 = Topic.new(title: "test_1")
780
+ topic_2 = Topic.new(title: "test_2")
781
+ topic_3 = topic_without_callbacks.new(title: "test_3")
559
782
 
560
783
  Topic.transaction do
561
784
  assert topic_1.save
@@ -563,27 +786,27 @@ class TransactionTest < ActiveRecord::TestCase
563
786
  assert topic_3.save
564
787
  @first.save
565
788
  @second.destroy
566
- assert topic_1.persisted?, 'persisted'
789
+ assert topic_1.persisted?, "persisted"
567
790
  assert_not_nil topic_1.id
568
- assert topic_2.persisted?, 'persisted'
791
+ assert topic_2.persisted?, "persisted"
569
792
  assert_not_nil topic_2.id
570
- assert topic_3.persisted?, 'persisted'
793
+ assert topic_3.persisted?, "persisted"
571
794
  assert_not_nil topic_3.id
572
- assert @first.persisted?, 'persisted'
795
+ assert @first.persisted?, "persisted"
573
796
  assert_not_nil @first.id
574
- assert @second.destroyed?, 'destroyed'
797
+ assert @second.destroyed?, "destroyed"
575
798
  raise ActiveRecord::Rollback
576
799
  end
577
800
 
578
- assert !topic_1.persisted?, 'not persisted'
801
+ assert_not topic_1.persisted?, "not persisted"
579
802
  assert_nil topic_1.id
580
- assert !topic_2.persisted?, 'not persisted'
803
+ assert_not topic_2.persisted?, "not persisted"
581
804
  assert_nil topic_2.id
582
- assert !topic_3.persisted?, 'not persisted'
805
+ assert_not topic_3.persisted?, "not persisted"
583
806
  assert_nil topic_3.id
584
- assert @first.persisted?, 'persisted'
807
+ assert @first.persisted?, "persisted"
585
808
  assert_not_nil @first.id
586
- assert !@second.destroyed?, 'not destroyed'
809
+ assert_not @second.destroyed?, "not destroyed"
587
810
  end
588
811
 
589
812
  def test_restore_frozen_state_after_double_destroy
@@ -597,8 +820,142 @@ class TransactionTest < ActiveRecord::TestCase
597
820
  raise ActiveRecord::Rollback
598
821
  end
599
822
 
600
- assert_not reply.frozen?
601
- assert_not topic.frozen?
823
+ assert_not_predicate reply, :frozen?
824
+ assert_not_predicate topic, :frozen?
825
+ end
826
+
827
+ def test_restore_new_record_after_double_save
828
+ topic = Topic.new
829
+
830
+ Topic.transaction do
831
+ topic.save!
832
+ topic.save!
833
+ raise ActiveRecord::Rollback
834
+ end
835
+
836
+ assert_nil topic.id
837
+ assert_predicate topic, :new_record?
838
+ end
839
+
840
+ def test_dont_restore_new_record_in_subsequent_transaction
841
+ topic = Topic.new
842
+
843
+ Topic.transaction do
844
+ topic.save!
845
+ topic.save!
846
+ end
847
+
848
+ Topic.transaction do
849
+ topic.save!
850
+ raise ActiveRecord::Rollback
851
+ end
852
+
853
+ assert_predicate topic, :persisted?
854
+ assert_not_predicate topic, :new_record?
855
+ end
856
+
857
+ def test_restore_previously_new_record_after_double_save
858
+ topic = Topic.create!
859
+
860
+ Topic.transaction do
861
+ topic.save!
862
+ topic.save!
863
+ raise ActiveRecord::Rollback
864
+ end
865
+
866
+ assert_predicate topic, :previously_new_record?
867
+ end
868
+
869
+ def test_restore_id_after_rollback
870
+ topic = Topic.new
871
+
872
+ Topic.transaction do
873
+ topic.save!
874
+ raise ActiveRecord::Rollback
875
+ end
876
+
877
+ assert_nil topic.id
878
+ end
879
+
880
+ def test_restore_custom_primary_key_after_rollback
881
+ movie = Movie.new(name: "foo")
882
+
883
+ Movie.transaction do
884
+ movie.save!
885
+ raise ActiveRecord::Rollback
886
+ end
887
+
888
+ assert_nil movie.movieid
889
+ end
890
+
891
+ def test_assign_id_after_rollback
892
+ topic = Topic.create!
893
+
894
+ Topic.transaction do
895
+ topic.save!
896
+ raise ActiveRecord::Rollback
897
+ end
898
+
899
+ topic.id = nil
900
+ assert_nil topic.id
901
+ end
902
+
903
+ def test_assign_custom_primary_key_after_rollback
904
+ movie = Movie.create!(name: "foo")
905
+
906
+ Movie.transaction do
907
+ movie.save!
908
+ raise ActiveRecord::Rollback
909
+ end
910
+
911
+ movie.movieid = nil
912
+ assert_nil movie.movieid
913
+ end
914
+
915
+ def test_read_attribute_after_rollback
916
+ topic = Topic.new
917
+
918
+ Topic.transaction do
919
+ topic.save!
920
+ raise ActiveRecord::Rollback
921
+ end
922
+
923
+ assert_nil topic.read_attribute(:id)
924
+ end
925
+
926
+ def test_read_attribute_with_custom_primary_key_after_rollback
927
+ movie = Movie.new(name: "foo")
928
+
929
+ Movie.transaction do
930
+ movie.save!
931
+ raise ActiveRecord::Rollback
932
+ end
933
+
934
+ assert_nil movie.read_attribute(:movieid)
935
+ end
936
+
937
+ def test_write_attribute_after_rollback
938
+ topic = Topic.create!
939
+
940
+ Topic.transaction do
941
+ topic.save!
942
+ raise ActiveRecord::Rollback
943
+ end
944
+
945
+ topic.write_attribute(:id, nil)
946
+ assert_nil topic.id
947
+ end
948
+
949
+ def test_write_attribute_with_custom_primary_key_after_rollback
950
+ movie = Movie.create!(name: "foo")
951
+
952
+ Movie.transaction do
953
+ movie.save!
954
+ raise ActiveRecord::Rollback
955
+ end
956
+
957
+ movie.write_attribute(:movieid, nil)
958
+ assert_nil movie.movieid
602
959
  end
603
960
 
604
961
  def test_rollback_of_frozen_records
@@ -607,7 +964,7 @@ class TransactionTest < ActiveRecord::TestCase
607
964
  topic.destroy
608
965
  raise ActiveRecord::Rollback
609
966
  end
610
- assert topic.frozen?, 'frozen'
967
+ assert topic.frozen?, "frozen"
611
968
  end
612
969
 
613
970
  def test_rollback_for_freshly_persisted_records
@@ -616,7 +973,7 @@ class TransactionTest < ActiveRecord::TestCase
616
973
  topic.destroy
617
974
  raise ActiveRecord::Rollback
618
975
  end
619
- assert topic.persisted?, 'persisted'
976
+ assert topic.persisted?, "persisted"
620
977
  end
621
978
 
622
979
  def test_sqlite_add_column_in_transaction
@@ -630,27 +987,27 @@ class TransactionTest < ActiveRecord::TestCase
630
987
 
631
988
  assert_nothing_raised do
632
989
  Topic.reset_column_information
633
- Topic.connection.add_column('topics', 'stuff', :string)
634
- assert Topic.column_names.include?('stuff')
990
+ Topic.connection.add_column("topics", "stuff", :string)
991
+ assert_includes Topic.column_names, "stuff"
635
992
 
636
993
  Topic.reset_column_information
637
- Topic.connection.remove_column('topics', 'stuff')
638
- assert !Topic.column_names.include?('stuff')
994
+ Topic.connection.remove_column("topics", "stuff")
995
+ assert_not_includes Topic.column_names, "stuff"
639
996
  end
640
997
 
641
998
  if Topic.connection.supports_ddl_transactions?
642
999
  assert_nothing_raised do
643
- Topic.transaction { Topic.connection.add_column('topics', 'stuff', :string) }
1000
+ Topic.transaction { Topic.connection.add_column("topics", "stuff", :string) }
644
1001
  end
645
1002
  else
646
1003
  Topic.transaction do
647
- assert_raise(ActiveRecord::StatementInvalid) { Topic.connection.add_column('topics', 'stuff', :string) }
1004
+ assert_raise(ActiveRecord::StatementInvalid) { Topic.connection.add_column("topics", "stuff", :string) }
648
1005
  raise ActiveRecord::Rollback
649
1006
  end
650
1007
  end
651
1008
  ensure
652
1009
  begin
653
- Topic.connection.remove_column('topics', 'stuff')
1010
+ Topic.connection.remove_column("topics", "stuff")
654
1011
  rescue
655
1012
  ensure
656
1013
  Topic.reset_column_information
@@ -661,38 +1018,65 @@ class TransactionTest < ActiveRecord::TestCase
661
1018
  connection = Topic.connection
662
1019
  transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction
663
1020
 
664
- assert transaction.open?
665
- assert !transaction.state.rolledback?
666
- assert !transaction.state.committed?
1021
+ assert_predicate transaction, :open?
1022
+ assert_not_predicate transaction.state, :rolledback?
1023
+ assert_not_predicate transaction.state, :committed?
667
1024
 
668
1025
  transaction.rollback
669
1026
 
670
- assert transaction.state.rolledback?
671
- assert !transaction.state.committed?
1027
+ assert_predicate transaction.state, :rolledback?
1028
+ assert_not_predicate transaction.state, :committed?
672
1029
  end
673
1030
 
674
1031
  def test_transactions_state_from_commit
675
1032
  connection = Topic.connection
676
1033
  transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction
677
1034
 
678
- assert transaction.open?
679
- assert !transaction.state.rolledback?
680
- assert !transaction.state.committed?
1035
+ assert_predicate transaction, :open?
1036
+ assert_not_predicate transaction.state, :rolledback?
1037
+ assert_not_predicate transaction.state, :committed?
1038
+
1039
+ transaction.commit
1040
+
1041
+ assert_not_predicate transaction.state, :rolledback?
1042
+ assert_predicate transaction.state, :committed?
1043
+ end
1044
+
1045
+ def test_mark_transaction_state_as_committed
1046
+ connection = Topic.connection
1047
+ transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction
1048
+
1049
+ transaction.rollback
1050
+
1051
+ assert_equal :committed, transaction.state.commit!
1052
+ end
1053
+
1054
+ def test_mark_transaction_state_as_rolledback
1055
+ connection = Topic.connection
1056
+ transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction
681
1057
 
682
1058
  transaction.commit
683
1059
 
684
- assert !transaction.state.rolledback?
685
- assert transaction.state.committed?
1060
+ assert_equal :rolledback, transaction.state.rollback!
1061
+ end
1062
+
1063
+ def test_mark_transaction_state_as_nil
1064
+ connection = Topic.connection
1065
+ transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction
1066
+
1067
+ transaction.commit
1068
+
1069
+ assert_nil transaction.state.nullify!
686
1070
  end
687
1071
 
688
1072
  def test_transaction_rollback_with_primarykeyless_tables
689
1073
  connection = ActiveRecord::Base.connection
690
1074
  connection.create_table(:transaction_without_primary_keys, force: true, id: false) do |t|
691
- t.integer :thing_id
1075
+ t.integer :thing_id
692
1076
  end
693
1077
 
694
1078
  klass = Class.new(ActiveRecord::Base) do
695
- self.table_name = 'transaction_without_primary_keys'
1079
+ self.table_name = "transaction_without_primary_keys"
696
1080
  after_commit { } # necessary to trigger the has_transactional_callbacks branch
697
1081
  end
698
1082
 
@@ -703,21 +1087,89 @@ class TransactionTest < ActiveRecord::TestCase
703
1087
  end
704
1088
  end
705
1089
  ensure
706
- connection.drop_table 'transaction_without_primary_keys'
707
- #, if_exists: true
1090
+ connection.drop_table "transaction_without_primary_keys", if_exists: true
708
1091
  end
709
1092
 
710
- private
1093
+ def test_empty_transaction_is_not_materialized
1094
+ assert_no_queries do
1095
+ Topic.transaction { }
1096
+ end
1097
+ end
1098
+
1099
+ def test_unprepared_statement_materializes_transaction
1100
+ assert_sql(/BEGIN/i, /COMMIT/i) do
1101
+ Topic.transaction { Topic.where("1=1").first }
1102
+ end
1103
+ end
1104
+
1105
+ if ActiveRecord::Base.connection.prepared_statements
1106
+ def test_prepared_statement_materializes_transaction
1107
+ Topic.first
1108
+
1109
+ assert_sql(/BEGIN/i, /COMMIT/i) do
1110
+ Topic.transaction { Topic.first }
1111
+ end
1112
+ end
1113
+ end
1114
+
1115
+ def test_savepoint_does_not_materialize_transaction
1116
+ assert_no_queries do
1117
+ Topic.transaction do
1118
+ Topic.transaction(requires_new: true) { }
1119
+ end
1120
+ end
1121
+ end
1122
+
1123
+ def test_raising_does_not_materialize_transaction
1124
+ assert_raise(RuntimeError) do
1125
+ assert_no_queries do
1126
+ Topic.transaction { raise }
1127
+ end
1128
+ end
1129
+ end
1130
+
1131
+ def test_accessing_raw_connection_materializes_transaction
1132
+ assert_sql(/BEGIN/i, /COMMIT/i) do
1133
+ Topic.transaction { Topic.connection.raw_connection }
1134
+ end
1135
+ end
1136
+
1137
+ def test_accessing_raw_connection_disables_lazy_transactions
1138
+ Topic.connection.raw_connection
711
1139
 
712
- %w(validation save destroy).each do |filter|
713
- define_method("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") do |topic|
714
- meta = class << topic; self; end
715
- meta.send("define_method", "before_#{filter}_for_transaction") do
716
- Book.create
717
- throw(:abort)
1140
+ assert_sql(/BEGIN/i, /COMMIT/i) do
1141
+ Topic.transaction { }
1142
+ end
1143
+ end
1144
+
1145
+ def test_checking_in_connection_reenables_lazy_transactions
1146
+ connection = Topic.connection_pool.checkout
1147
+ connection.raw_connection
1148
+ Topic.connection_pool.checkin connection
1149
+
1150
+ assert_no_queries do
1151
+ connection.transaction { }
1152
+ end
1153
+ end
1154
+
1155
+ def test_transactions_can_be_manually_materialized
1156
+ assert_sql(/BEGIN/i, /COMMIT/i) do
1157
+ Topic.transaction do
1158
+ Topic.connection.materialize_transactions
718
1159
  end
719
1160
  end
720
1161
  end
1162
+
1163
+ private
1164
+ %w(validation save destroy).each do |filter|
1165
+ define_method("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") do |topic|
1166
+ meta = class << topic; self; end
1167
+ meta.define_method "before_#{filter}_for_transaction" do
1168
+ Book.create
1169
+ throw(:abort)
1170
+ end
1171
+ end
1172
+ end
721
1173
  end
722
1174
 
723
1175
  class TransactionsWithTransactionalFixturesTest < ActiveRecord::TestCase
@@ -734,7 +1186,7 @@ class TransactionsWithTransactionalFixturesTest < ActiveRecord::TestCase
734
1186
  raise
735
1187
  end
736
1188
  rescue
737
- assert !@first.reload.approved?
1189
+ assert_not_predicate @first.reload, :approved?
738
1190
  end
739
1191
  end
740
1192
 
@@ -755,31 +1207,29 @@ class TransactionsWithTransactionalFixturesTest < ActiveRecord::TestCase
755
1207
  end
756
1208
  end
757
1209
 
758
- assert !@first.reload.approved?
1210
+ assert_not_predicate @first.reload, :approved?
759
1211
  end
760
1212
  end if Topic.connection.supports_savepoints?
761
1213
 
762
- if current_adapter?(:PostgreSQLAdapter)
1214
+ if ActiveRecord::Base.connection.supports_transaction_isolation? && !current_adapter?(:SQLite3Adapter)
763
1215
  class ConcurrentTransactionTest < TransactionTest
764
1216
  # This will cause transactions to overlap and fail unless they are performed on
765
1217
  # separate database connections.
766
- unless in_memory_db?
767
- def test_transaction_per_thread
768
- threads = 3.times.map do
769
- Thread.new do
770
- Topic.transaction do
771
- topic = Topic.find(1)
772
- topic.approved = !topic.approved?
773
- assert topic.save!
774
- topic.approved = !topic.approved?
775
- assert topic.save!
776
- end
777
- Topic.connection.close
1218
+ def test_transaction_per_thread
1219
+ threads = 3.times.map do
1220
+ Thread.new do
1221
+ Topic.transaction do
1222
+ topic = Topic.find(1)
1223
+ topic.approved = !topic.approved?
1224
+ assert topic.save!
1225
+ topic.approved = !topic.approved?
1226
+ assert topic.save!
778
1227
  end
1228
+ Topic.connection.close
779
1229
  end
780
-
781
- threads.each(&:join)
782
1230
  end
1231
+
1232
+ threads.each(&:join)
783
1233
  end
784
1234
 
785
1235
  # Test for dirty reads among simultaneous transactions.