ibm_db 3.0.5-x86-mingw32 → 4.0.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 (586) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +4 -0
  3. data/LICENSE +1 -1
  4. data/MANIFEST +14 -14
  5. data/ParameterizedQueries README +6 -6
  6. data/README +208 -225
  7. data/ext/Makefile.nt32 +181 -181
  8. data/ext/Makefile.nt32.191 +212 -212
  9. data/ext/extconf.rb +291 -291
  10. data/ext/ibm_db.c +11887 -11887
  11. data/ext/ruby_ibm_db.h +241 -241
  12. data/ext/ruby_ibm_db_cli.c +866 -866
  13. data/ext/ruby_ibm_db_cli.h +500 -500
  14. data/init.rb +41 -41
  15. data/lib/IBM_DB.rb +27 -27
  16. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3452 -3177
  17. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +5 -2
  18. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
  19. data/lib/mswin32/ibm_db.rb +91 -123
  20. data/lib/mswin32/rb2x/i386/ibm_db.so +0 -0
  21. data/test/active_record/connection_adapters/fake_adapter.rb +49 -46
  22. data/test/assets/example.log +1 -1
  23. data/test/assets/test.txt +1 -1
  24. data/test/cases/adapter_test.rb +351 -276
  25. data/test/cases/adapters/mysql2/active_schema_test.rb +193 -0
  26. data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -0
  27. data/test/cases/adapters/mysql2/boolean_test.rb +100 -0
  28. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -0
  29. data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -0
  30. data/test/cases/adapters/mysql2/connection_test.rb +210 -0
  31. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -0
  32. data/test/cases/adapters/mysql2/enum_test.rb +26 -0
  33. data/test/cases/adapters/mysql2/explain_test.rb +21 -0
  34. data/test/cases/adapters/mysql2/json_test.rb +195 -0
  35. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -0
  36. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -0
  37. data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -0
  38. data/test/cases/adapters/mysql2/schema_test.rb +126 -0
  39. data/test/cases/adapters/mysql2/sp_test.rb +36 -0
  40. data/test/cases/adapters/mysql2/sql_types_test.rb +14 -0
  41. data/test/cases/adapters/mysql2/table_options_test.rb +42 -0
  42. data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -0
  43. data/test/cases/adapters/postgresql/active_schema_test.rb +98 -0
  44. data/test/cases/adapters/postgresql/array_test.rb +339 -0
  45. data/test/cases/adapters/postgresql/bit_string_test.rb +82 -0
  46. data/test/cases/adapters/postgresql/bytea_test.rb +134 -0
  47. data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -0
  48. data/test/cases/adapters/postgresql/change_schema_test.rb +38 -0
  49. data/test/cases/adapters/postgresql/cidr_test.rb +25 -0
  50. data/test/cases/adapters/postgresql/citext_test.rb +78 -0
  51. data/test/cases/adapters/postgresql/collation_test.rb +53 -0
  52. data/test/cases/adapters/postgresql/composite_test.rb +132 -0
  53. data/test/cases/adapters/postgresql/connection_test.rb +257 -0
  54. data/test/cases/adapters/postgresql/datatype_test.rb +92 -0
  55. data/test/cases/adapters/postgresql/domain_test.rb +47 -0
  56. data/test/cases/adapters/postgresql/enum_test.rb +91 -0
  57. data/test/cases/adapters/postgresql/explain_test.rb +20 -0
  58. data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -0
  59. data/test/cases/adapters/postgresql/full_text_test.rb +44 -0
  60. data/test/cases/adapters/postgresql/geometric_test.rb +378 -0
  61. data/test/cases/adapters/postgresql/hstore_test.rb +382 -0
  62. data/test/cases/adapters/postgresql/infinity_test.rb +69 -0
  63. data/test/cases/adapters/postgresql/integer_test.rb +25 -0
  64. data/test/cases/adapters/postgresql/json_test.rb +237 -0
  65. data/test/cases/adapters/postgresql/ltree_test.rb +53 -0
  66. data/test/cases/adapters/postgresql/money_test.rb +96 -0
  67. data/test/cases/adapters/postgresql/network_test.rb +94 -0
  68. data/test/cases/adapters/postgresql/numbers_test.rb +49 -0
  69. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -0
  70. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
  71. data/test/cases/adapters/postgresql/quoting_test.rb +44 -0
  72. data/test/cases/adapters/postgresql/range_test.rb +343 -0
  73. data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -0
  74. data/test/cases/adapters/postgresql/rename_table_test.rb +34 -0
  75. data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -0
  76. data/test/cases/adapters/postgresql/schema_test.rb +597 -0
  77. data/test/cases/adapters/postgresql/serial_test.rb +154 -0
  78. data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -0
  79. data/test/cases/adapters/postgresql/timestamp_test.rb +90 -0
  80. data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -0
  81. data/test/cases/adapters/postgresql/utils_test.rb +62 -0
  82. data/test/cases/adapters/postgresql/uuid_test.rb +294 -0
  83. data/test/cases/adapters/postgresql/xml_test.rb +54 -0
  84. data/test/cases/adapters/sqlite3/collation_test.rb +53 -0
  85. data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -0
  86. data/test/cases/adapters/sqlite3/explain_test.rb +21 -0
  87. data/test/cases/adapters/sqlite3/quoting_test.rb +101 -0
  88. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -0
  89. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -0
  90. data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -0
  91. data/test/cases/aggregations_test.rb +168 -158
  92. data/test/cases/ar_schema_test.rb +146 -161
  93. data/test/cases/associations/association_scope_test.rb +16 -21
  94. data/test/cases/associations/belongs_to_associations_test.rb +1141 -1029
  95. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -0
  96. data/test/cases/associations/callbacks_test.rb +190 -192
  97. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  98. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  99. data/test/cases/associations/eager_load_nested_include_test.rb +126 -128
  100. data/test/cases/associations/eager_singularization_test.rb +148 -148
  101. data/test/cases/associations/eager_test.rb +1514 -1429
  102. data/test/cases/associations/extension_test.rb +87 -82
  103. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +1004 -972
  104. data/test/cases/associations/has_many_associations_test.rb +2501 -2182
  105. data/test/cases/associations/has_many_through_associations_test.rb +1271 -1204
  106. data/test/cases/associations/has_one_associations_test.rb +707 -610
  107. data/test/cases/associations/has_one_through_associations_test.rb +383 -380
  108. data/test/cases/associations/inner_join_association_test.rb +139 -139
  109. data/test/cases/associations/inverse_associations_test.rb +733 -706
  110. data/test/cases/associations/join_model_test.rb +777 -754
  111. data/test/cases/associations/left_outer_join_association_test.rb +88 -0
  112. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  113. data/test/cases/associations/required_test.rb +102 -82
  114. data/test/cases/associations_test.rb +385 -380
  115. data/test/cases/attribute_decorators_test.rb +125 -125
  116. data/test/cases/attribute_methods/read_test.rb +60 -60
  117. data/test/cases/attribute_methods_test.rb +1009 -952
  118. data/test/cases/attribute_set_test.rb +270 -210
  119. data/test/cases/attribute_test.rb +246 -180
  120. data/test/cases/attributes_test.rb +253 -136
  121. data/test/cases/autosave_association_test.rb +1708 -1595
  122. data/test/cases/base_test.rb +1713 -1664
  123. data/test/cases/batches_test.rb +489 -212
  124. data/test/cases/binary_test.rb +44 -52
  125. data/test/cases/bind_parameter_test.rb +110 -100
  126. data/test/cases/cache_key_test.rb +25 -0
  127. data/test/cases/calculations_test.rb +798 -646
  128. data/test/cases/callbacks_test.rb +636 -543
  129. data/test/cases/clone_test.rb +40 -40
  130. data/test/cases/coders/json_test.rb +15 -0
  131. data/test/cases/coders/yaml_column_test.rb +63 -63
  132. data/test/cases/collection_cache_key_test.rb +115 -0
  133. data/test/cases/column_alias_test.rb +17 -17
  134. data/test/cases/column_definition_test.rb +92 -123
  135. data/test/cases/comment_test.rb +143 -0
  136. data/test/cases/connection_adapters/adapter_leasing_test.rb +56 -54
  137. data/test/cases/connection_adapters/connection_handler_test.rb +160 -53
  138. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  139. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +255 -293
  140. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +69 -65
  141. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  142. data/test/cases/connection_adapters/schema_cache_test.rb +61 -56
  143. data/test/cases/connection_adapters/type_lookup_test.rb +118 -110
  144. data/test/cases/connection_management_test.rb +112 -122
  145. data/test/cases/connection_pool_test.rb +521 -346
  146. data/test/cases/connection_specification/resolver_test.rb +131 -116
  147. data/test/cases/core_test.rb +112 -112
  148. data/test/cases/counter_cache_test.rb +214 -209
  149. data/test/cases/custom_locking_test.rb +17 -17
  150. data/test/cases/database_statements_test.rb +34 -19
  151. data/test/cases/{invalid_date_test.rb → date_test.rb} +44 -32
  152. data/test/cases/date_time_precision_test.rb +106 -0
  153. data/test/cases/date_time_test.rb +61 -61
  154. data/test/cases/defaults_test.rb +218 -223
  155. data/test/cases/dirty_test.rb +763 -785
  156. data/test/cases/disconnected_test.rb +30 -28
  157. data/test/cases/dup_test.rb +157 -157
  158. data/test/cases/enum_test.rb +444 -290
  159. data/test/cases/errors_test.rb +16 -0
  160. data/test/cases/explain_subscriber_test.rb +64 -64
  161. data/test/cases/explain_test.rb +87 -76
  162. data/test/cases/finder_respond_to_test.rb +60 -60
  163. data/test/cases/finder_test.rb +1294 -1169
  164. data/test/cases/fixture_set/file_test.rb +156 -138
  165. data/test/cases/fixtures_test.rb +988 -908
  166. data/test/cases/forbidden_attributes_protection_test.rb +165 -99
  167. data/test/cases/habtm_destroy_order_test.rb +61 -61
  168. data/test/cases/helper.rb +204 -210
  169. data/test/cases/hot_compatibility_test.rb +142 -54
  170. data/test/cases/i18n_test.rb +45 -45
  171. data/test/cases/inheritance_test.rb +606 -375
  172. data/test/cases/integration_test.rb +155 -139
  173. data/test/cases/invalid_connection_test.rb +24 -22
  174. data/test/cases/invertible_migration_test.rb +387 -295
  175. data/test/cases/json_serialization_test.rb +311 -302
  176. data/test/cases/locking_test.rb +493 -477
  177. data/test/cases/log_subscriber_test.rb +225 -136
  178. data/test/cases/migration/change_schema_test.rb +458 -512
  179. data/test/cases/migration/change_table_test.rb +256 -224
  180. data/test/cases/migration/column_attributes_test.rb +176 -192
  181. data/test/cases/migration/column_positioning_test.rb +56 -56
  182. data/test/cases/migration/columns_test.rb +310 -304
  183. data/test/cases/migration/command_recorder_test.rb +350 -305
  184. data/test/cases/migration/compatibility_test.rb +118 -0
  185. data/test/cases/migration/create_join_table_test.rb +157 -148
  186. data/test/cases/migration/foreign_key_test.rb +360 -328
  187. data/test/cases/migration/helper.rb +39 -39
  188. data/test/cases/migration/index_test.rb +218 -216
  189. data/test/cases/migration/logger_test.rb +36 -36
  190. data/test/cases/migration/pending_migrations_test.rb +52 -53
  191. data/test/cases/migration/references_foreign_key_test.rb +216 -169
  192. data/test/cases/migration/references_index_test.rb +101 -101
  193. data/test/cases/migration/references_statements_test.rb +136 -116
  194. data/test/cases/migration/rename_table_test.rb +93 -93
  195. data/test/cases/migration_test.rb +1157 -959
  196. data/test/cases/migrator_test.rb +470 -388
  197. data/test/cases/mixin_test.rb +68 -70
  198. data/test/cases/modules_test.rb +172 -173
  199. data/test/cases/multiparameter_attributes_test.rb +372 -350
  200. data/test/cases/multiple_db_test.rb +122 -115
  201. data/test/cases/nested_attributes_test.rb +1098 -1070
  202. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  203. data/test/cases/persistence_test.rb +1001 -909
  204. data/test/cases/pooled_connections_test.rb +81 -81
  205. data/test/cases/primary_keys_test.rb +376 -237
  206. data/test/cases/query_cache_test.rb +446 -326
  207. data/test/cases/quoting_test.rb +202 -156
  208. data/test/cases/readonly_test.rb +119 -118
  209. data/test/cases/reaper_test.rb +85 -85
  210. data/test/cases/reflection_test.rb +509 -463
  211. data/test/cases/relation/delegation_test.rb +63 -68
  212. data/test/cases/relation/merging_test.rb +157 -161
  213. data/test/cases/relation/mutation_test.rb +183 -165
  214. data/test/cases/relation/or_test.rb +92 -0
  215. data/test/cases/relation/predicate_builder_test.rb +16 -14
  216. data/test/cases/relation/record_fetch_warning_test.rb +40 -0
  217. data/test/cases/relation/where_chain_test.rb +105 -181
  218. data/test/cases/relation/where_clause_test.rb +182 -0
  219. data/test/cases/relation/where_test.rb +322 -300
  220. data/test/cases/relation_test.rb +328 -319
  221. data/test/cases/relations_test.rb +2026 -1815
  222. data/test/cases/reload_models_test.rb +22 -22
  223. data/test/cases/result_test.rb +90 -80
  224. data/test/cases/sanitize_test.rb +176 -83
  225. data/test/cases/schema_dumper_test.rb +457 -463
  226. data/test/cases/schema_loading_test.rb +52 -0
  227. data/test/cases/scoping/default_scoping_test.rb +528 -454
  228. data/test/cases/scoping/named_scoping_test.rb +561 -524
  229. data/test/cases/scoping/relation_scoping_test.rb +400 -357
  230. data/test/cases/secure_token_test.rb +32 -0
  231. data/test/cases/serialization_test.rb +104 -104
  232. data/test/cases/serialized_attribute_test.rb +364 -277
  233. data/test/cases/statement_cache_test.rb +136 -98
  234. data/test/cases/store_test.rb +195 -194
  235. data/test/cases/suppressor_test.rb +63 -0
  236. data/test/cases/tasks/database_tasks_test.rb +462 -398
  237. data/test/cases/tasks/mysql_rake_test.rb +345 -324
  238. data/test/cases/tasks/postgresql_rake_test.rb +304 -250
  239. data/test/cases/tasks/sqlite_rake_test.rb +220 -193
  240. data/test/cases/test_case.rb +131 -123
  241. data/test/cases/test_fixtures_test.rb +36 -0
  242. data/test/cases/time_precision_test.rb +102 -0
  243. data/test/cases/timestamp_test.rb +501 -467
  244. data/test/cases/touch_later_test.rb +121 -0
  245. data/test/cases/transaction_callbacks_test.rb +518 -452
  246. data/test/cases/transaction_isolation_test.rb +106 -106
  247. data/test/cases/transactions_test.rb +834 -817
  248. data/test/cases/type/adapter_specific_registry_test.rb +133 -0
  249. data/test/cases/type/date_time_test.rb +14 -0
  250. data/test/cases/type/integer_test.rb +27 -121
  251. data/test/cases/type/string_test.rb +22 -36
  252. data/test/cases/type/type_map_test.rb +177 -177
  253. data/test/cases/type_test.rb +39 -0
  254. data/test/cases/types_test.rb +24 -141
  255. data/test/cases/unconnected_test.rb +33 -33
  256. data/test/cases/validations/absence_validation_test.rb +73 -0
  257. data/test/cases/validations/association_validation_test.rb +97 -86
  258. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  259. data/test/cases/validations/i18n_validation_test.rb +86 -90
  260. data/test/cases/validations/length_validation_test.rb +79 -47
  261. data/test/cases/validations/presence_validation_test.rb +103 -68
  262. data/test/cases/validations/uniqueness_validation_test.rb +548 -457
  263. data/test/cases/validations_repair_helper.rb +19 -23
  264. data/test/cases/validations_test.rb +194 -165
  265. data/test/cases/view_test.rb +216 -119
  266. data/test/cases/yaml_serialization_test.rb +121 -126
  267. data/test/config.example.yml +97 -0
  268. data/test/config.rb +5 -5
  269. data/test/fixtures/accounts.yml +29 -29
  270. data/test/fixtures/admin/accounts.yml +2 -2
  271. data/test/fixtures/admin/users.yml +10 -10
  272. data/test/fixtures/author_addresses.original +11 -0
  273. data/test/fixtures/author_addresses.yml +17 -17
  274. data/test/fixtures/author_favorites.yml +3 -3
  275. data/test/fixtures/authors.original +17 -0
  276. data/test/fixtures/authors.yml +23 -23
  277. data/test/fixtures/bad_posts.yml +9 -0
  278. data/test/fixtures/binaries.yml +133 -133
  279. data/test/fixtures/books.yml +31 -11
  280. data/test/fixtures/bulbs.yml +5 -5
  281. data/test/fixtures/cars.yml +9 -9
  282. data/test/fixtures/categories.yml +19 -19
  283. data/test/fixtures/categories/special_categories.yml +9 -9
  284. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  285. data/test/fixtures/categories_ordered.yml +7 -7
  286. data/test/fixtures/categories_posts.yml +31 -31
  287. data/test/fixtures/categorizations.yml +23 -23
  288. data/test/fixtures/clubs.yml +8 -8
  289. data/test/fixtures/collections.yml +3 -3
  290. data/test/fixtures/colleges.yml +3 -3
  291. data/test/fixtures/comments.yml +65 -65
  292. data/test/fixtures/companies.yml +67 -67
  293. data/test/fixtures/computers.yml +10 -10
  294. data/test/fixtures/content.yml +3 -0
  295. data/test/fixtures/content_positions.yml +3 -0
  296. data/test/fixtures/courses.yml +8 -8
  297. data/test/fixtures/customers.yml +25 -25
  298. data/test/fixtures/dashboards.yml +6 -6
  299. data/test/fixtures/dead_parrots.yml +5 -0
  300. data/test/fixtures/developers.yml +22 -22
  301. data/test/fixtures/developers_projects.yml +16 -16
  302. data/test/fixtures/dog_lovers.yml +7 -7
  303. data/test/fixtures/dogs.yml +4 -4
  304. data/test/fixtures/doubloons.yml +3 -3
  305. data/test/fixtures/edges.yml +5 -5
  306. data/test/fixtures/entrants.yml +14 -14
  307. data/test/fixtures/essays.yml +6 -6
  308. data/test/fixtures/faces.yml +11 -11
  309. data/test/fixtures/fk_test_has_fk.yml +3 -3
  310. data/test/fixtures/fk_test_has_pk.yml +1 -1
  311. data/test/fixtures/friendships.yml +4 -4
  312. data/test/fixtures/funny_jokes.yml +10 -10
  313. data/test/fixtures/interests.yml +33 -33
  314. data/test/fixtures/items.yml +3 -3
  315. data/test/fixtures/jobs.yml +7 -7
  316. data/test/fixtures/legacy_things.yml +3 -3
  317. data/test/fixtures/live_parrots.yml +4 -0
  318. data/test/fixtures/mateys.yml +4 -4
  319. data/test/fixtures/member_details.yml +8 -8
  320. data/test/fixtures/member_types.yml +6 -6
  321. data/test/fixtures/members.yml +11 -11
  322. data/test/fixtures/memberships.yml +34 -34
  323. data/test/fixtures/men.yml +5 -5
  324. data/test/fixtures/minimalistics.yml +2 -2
  325. data/test/fixtures/minivans.yml +5 -5
  326. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  327. data/test/fixtures/mixins.yml +29 -29
  328. data/test/fixtures/movies.yml +7 -7
  329. data/test/fixtures/naked/yml/accounts.yml +1 -1
  330. data/test/fixtures/naked/yml/companies.yml +1 -1
  331. data/test/fixtures/naked/yml/courses.yml +1 -1
  332. data/test/fixtures/naked/yml/parrots.yml +2 -0
  333. data/test/fixtures/naked/yml/trees.yml +3 -0
  334. data/test/fixtures/nodes.yml +29 -0
  335. data/test/fixtures/organizations.yml +5 -5
  336. data/test/fixtures/other_comments.yml +6 -0
  337. data/test/fixtures/other_dogs.yml +2 -0
  338. data/test/fixtures/other_posts.yml +7 -0
  339. data/test/fixtures/other_topics.yml +42 -42
  340. data/test/fixtures/owners.yml +9 -9
  341. data/test/fixtures/parrots.yml +27 -27
  342. data/test/fixtures/parrots_pirates.yml +7 -7
  343. data/test/fixtures/people.yml +24 -24
  344. data/test/fixtures/peoples_treasures.yml +3 -3
  345. data/test/fixtures/pets.yml +19 -19
  346. data/test/fixtures/pirates.yml +15 -12
  347. data/test/fixtures/posts.yml +80 -80
  348. data/test/fixtures/price_estimates.yml +16 -7
  349. data/test/fixtures/products.yml +4 -4
  350. data/test/fixtures/projects.yml +7 -7
  351. data/test/fixtures/ratings.yml +14 -14
  352. data/test/fixtures/readers.yml +11 -11
  353. data/test/fixtures/references.yml +17 -17
  354. data/test/fixtures/reserved_words/distinct.yml +5 -5
  355. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  356. data/test/fixtures/reserved_words/group.yml +14 -14
  357. data/test/fixtures/reserved_words/select.yml +8 -8
  358. data/test/fixtures/reserved_words/values.yml +7 -7
  359. data/test/fixtures/ships.yml +6 -6
  360. data/test/fixtures/speedometers.yml +8 -8
  361. data/test/fixtures/sponsors.yml +12 -12
  362. data/test/fixtures/string_key_objects.yml +7 -7
  363. data/test/fixtures/subscribers.yml +10 -10
  364. data/test/fixtures/subscriptions.yml +12 -12
  365. data/test/fixtures/taggings.yml +78 -78
  366. data/test/fixtures/tags.yml +11 -11
  367. data/test/fixtures/tasks.yml +7 -7
  368. data/test/fixtures/teapots.yml +3 -3
  369. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  370. data/test/fixtures/to_be_linked/users.yml +10 -10
  371. data/test/fixtures/topics.yml +49 -49
  372. data/test/fixtures/toys.yml +14 -14
  373. data/test/fixtures/traffic_lights.yml +9 -9
  374. data/test/fixtures/treasures.yml +10 -10
  375. data/test/fixtures/trees.yml +3 -0
  376. data/test/fixtures/uuid_children.yml +3 -3
  377. data/test/fixtures/uuid_parents.yml +2 -2
  378. data/test/fixtures/variants.yml +4 -4
  379. data/test/fixtures/vegetables.yml +19 -19
  380. data/test/fixtures/vertices.yml +3 -3
  381. data/test/fixtures/warehouse_things.yml +2 -2
  382. data/test/fixtures/zines.yml +5 -5
  383. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  384. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  385. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  386. data/test/migrations/missing/1000_people_have_middle_names.rb +9 -9
  387. data/test/migrations/missing/1_people_have_last_names.rb +9 -9
  388. data/test/migrations/missing/3_we_need_reminders.rb +12 -12
  389. data/test/migrations/missing/4_innocent_jointable.rb +12 -12
  390. data/test/migrations/rename/1_we_need_things.rb +11 -11
  391. data/test/migrations/rename/2_rename_things.rb +9 -9
  392. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  393. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  394. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  395. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  396. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  397. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  398. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  399. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  400. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  401. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  402. data/test/migrations/valid/2_we_need_reminders.rb +12 -12
  403. data/test/migrations/valid/3_innocent_jointable.rb +12 -12
  404. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  405. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +12 -12
  406. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +12 -12
  407. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  408. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  409. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  410. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  411. data/test/models/admin.rb +5 -5
  412. data/test/models/admin/account.rb +3 -3
  413. data/test/models/admin/randomly_named_c1.rb +6 -2
  414. data/test/models/admin/user.rb +40 -40
  415. data/test/models/aircraft.rb +5 -4
  416. data/test/models/arunit2_model.rb +3 -3
  417. data/test/models/author.rb +209 -212
  418. data/test/models/auto_id.rb +4 -4
  419. data/test/models/autoloadable/extra_firm.rb +2 -2
  420. data/test/models/binary.rb +2 -2
  421. data/test/models/bird.rb +12 -12
  422. data/test/models/book.rb +23 -18
  423. data/test/models/boolean.rb +2 -2
  424. data/test/models/bulb.rb +52 -51
  425. data/test/models/cake_designer.rb +3 -3
  426. data/test/models/car.rb +29 -26
  427. data/test/models/carrier.rb +2 -2
  428. data/test/models/cat.rb +10 -0
  429. data/test/models/categorization.rb +19 -19
  430. data/test/models/category.rb +35 -35
  431. data/test/models/chef.rb +8 -7
  432. data/test/models/citation.rb +3 -3
  433. data/test/models/club.rb +25 -23
  434. data/test/models/college.rb +10 -10
  435. data/test/models/column.rb +3 -3
  436. data/test/models/column_name.rb +3 -3
  437. data/test/models/comment.rb +76 -64
  438. data/test/models/company.rb +230 -228
  439. data/test/models/company_in_module.rb +98 -98
  440. data/test/models/computer.rb +3 -3
  441. data/test/models/contact.rb +41 -41
  442. data/test/models/content.rb +40 -0
  443. data/test/models/contract.rb +20 -20
  444. data/test/models/country.rb +7 -7
  445. data/test/models/course.rb +6 -6
  446. data/test/models/customer.rb +83 -77
  447. data/test/models/customer_carrier.rb +14 -14
  448. data/test/models/dashboard.rb +3 -3
  449. data/test/models/default.rb +2 -2
  450. data/test/models/department.rb +4 -4
  451. data/test/models/developer.rb +274 -255
  452. data/test/models/dog.rb +5 -5
  453. data/test/models/dog_lover.rb +5 -5
  454. data/test/models/doubloon.rb +12 -12
  455. data/test/models/drink_designer.rb +3 -3
  456. data/test/models/edge.rb +5 -5
  457. data/test/models/electron.rb +5 -5
  458. data/test/models/engine.rb +4 -4
  459. data/test/models/entrant.rb +3 -3
  460. data/test/models/essay.rb +5 -5
  461. data/test/models/event.rb +3 -3
  462. data/test/models/eye.rb +37 -37
  463. data/test/models/face.rb +9 -9
  464. data/test/models/friendship.rb +6 -6
  465. data/test/models/guid.rb +2 -2
  466. data/test/models/guitar.rb +4 -0
  467. data/test/models/hotel.rb +11 -9
  468. data/test/models/image.rb +3 -3
  469. data/test/models/interest.rb +5 -5
  470. data/test/models/invoice.rb +4 -4
  471. data/test/models/item.rb +7 -7
  472. data/test/models/job.rb +7 -7
  473. data/test/models/joke.rb +7 -7
  474. data/test/models/keyboard.rb +3 -3
  475. data/test/models/legacy_thing.rb +3 -3
  476. data/test/models/lesson.rb +11 -11
  477. data/test/models/line_item.rb +3 -3
  478. data/test/models/liquid.rb +4 -4
  479. data/test/models/man.rb +11 -11
  480. data/test/models/matey.rb +4 -4
  481. data/test/models/member.rb +42 -41
  482. data/test/models/member_detail.rb +8 -7
  483. data/test/models/member_type.rb +3 -3
  484. data/test/models/membership.rb +35 -35
  485. data/test/models/mentor.rb +3 -0
  486. data/test/models/minimalistic.rb +2 -2
  487. data/test/models/minivan.rb +9 -9
  488. data/test/models/mixed_case_monkey.rb +3 -3
  489. data/test/models/mocktail_designer.rb +2 -0
  490. data/test/models/molecule.rb +6 -6
  491. data/test/models/movie.rb +5 -5
  492. data/test/models/node.rb +5 -0
  493. data/test/models/non_primary_key.rb +2 -0
  494. data/test/models/notification.rb +3 -0
  495. data/test/models/order.rb +4 -4
  496. data/test/models/organization.rb +14 -14
  497. data/test/models/other_dog.rb +5 -0
  498. data/test/models/owner.rb +37 -34
  499. data/test/models/parrot.rb +28 -29
  500. data/test/models/person.rb +142 -143
  501. data/test/models/personal_legacy_thing.rb +4 -4
  502. data/test/models/pet.rb +18 -15
  503. data/test/models/pet_treasure.rb +6 -0
  504. data/test/models/pirate.rb +92 -92
  505. data/test/models/possession.rb +3 -3
  506. data/test/models/post.rb +273 -264
  507. data/test/models/price_estimate.rb +4 -4
  508. data/test/models/professor.rb +5 -5
  509. data/test/models/project.rb +40 -31
  510. data/test/models/publisher.rb +2 -2
  511. data/test/models/publisher/article.rb +4 -4
  512. data/test/models/publisher/magazine.rb +3 -3
  513. data/test/models/randomly_named_c1.rb +1 -1
  514. data/test/models/rating.rb +4 -4
  515. data/test/models/reader.rb +23 -23
  516. data/test/models/recipe.rb +3 -0
  517. data/test/models/record.rb +2 -2
  518. data/test/models/reference.rb +22 -22
  519. data/test/models/reply.rb +61 -61
  520. data/test/models/ship.rb +39 -33
  521. data/test/models/ship_part.rb +8 -8
  522. data/test/models/shop.rb +17 -17
  523. data/test/models/shop_account.rb +6 -6
  524. data/test/models/speedometer.rb +6 -6
  525. data/test/models/sponsor.rb +7 -7
  526. data/test/models/string_key_object.rb +3 -3
  527. data/test/models/student.rb +4 -4
  528. data/test/models/subject.rb +16 -16
  529. data/test/models/subscriber.rb +8 -8
  530. data/test/models/subscription.rb +4 -4
  531. data/test/models/tag.rb +13 -7
  532. data/test/models/tagging.rb +13 -13
  533. data/test/models/task.rb +5 -5
  534. data/test/models/topic.rb +118 -124
  535. data/test/models/toy.rb +6 -6
  536. data/test/models/traffic_light.rb +4 -4
  537. data/test/models/treasure.rb +14 -14
  538. data/test/models/treaty.rb +7 -7
  539. data/test/models/tree.rb +3 -0
  540. data/test/models/tuning_peg.rb +4 -0
  541. data/test/models/tyre.rb +11 -11
  542. data/test/models/user.rb +14 -0
  543. data/test/models/uuid_child.rb +3 -3
  544. data/test/models/uuid_item.rb +6 -0
  545. data/test/models/uuid_parent.rb +3 -3
  546. data/test/models/vegetables.rb +24 -24
  547. data/test/models/vehicle.rb +6 -6
  548. data/test/models/vertex.rb +9 -9
  549. data/test/models/warehouse_thing.rb +5 -5
  550. data/test/models/wheel.rb +3 -3
  551. data/test/models/without_table.rb +3 -3
  552. data/test/models/zine.rb +3 -3
  553. data/test/schema/mysql2_specific_schema.rb +68 -58
  554. data/test/schema/oracle_specific_schema.rb +40 -43
  555. data/test/schema/postgresql_specific_schema.rb +114 -202
  556. data/test/schema/schema.rb +1057 -952
  557. data/test/schema/schema.rb.original +1057 -0
  558. data/test/schema/sqlite_specific_schema.rb +18 -22
  559. data/test/support/config.rb +43 -43
  560. data/test/support/connection.rb +23 -22
  561. data/test/support/connection_helper.rb +14 -14
  562. data/test/support/ddl_helper.rb +8 -8
  563. data/test/support/schema_dumping_helper.rb +20 -20
  564. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
  565. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -0
  566. metadata +129 -28
  567. data/lib/mswin32/rb19x/ibm_db.so +0 -0
  568. data/lib/mswin32/rb21x/i386/ibm_db.so +0 -0
  569. data/lib/mswin32/rb22x/i386/ibm_db.so +0 -0
  570. data/lib/mswin32/rb23x/i386/ibm_db.so +0 -0
  571. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +0 -26
  572. data/test/cases/attribute_methods/serialization_test.rb +0 -29
  573. data/test/cases/migration/change_schema_test - Copy.rb +0 -448
  574. data/test/cases/migration/foreign_key_test - Changed.rb +0 -325
  575. data/test/cases/migration/table_and_index_test.rb +0 -24
  576. data/test/cases/relation/where_test2.rb +0 -36
  577. data/test/cases/type/decimal_test.rb +0 -56
  578. data/test/cases/type/unsigned_integer_test.rb +0 -18
  579. data/test/cases/xml_serialization_test.rb +0 -457
  580. data/test/connections/native_ibm_db/connection.rb +0 -44
  581. data/test/fixtures/naked/csv/accounts.csv +0 -1
  582. data/test/schema/i5/ibm_db_specific_schema.rb +0 -137
  583. data/test/schema/ids/ibm_db_specific_schema.rb +0 -140
  584. data/test/schema/luw/ibm_db_specific_schema.rb +0 -137
  585. data/test/schema/mysql_specific_schema.rb +0 -70
  586. data/test/schema/zOS/ibm_db_specific_schema.rb +0 -208
@@ -0,0 +1,121 @@
1
+ require 'cases/helper'
2
+ require 'models/invoice'
3
+ require 'models/line_item'
4
+ require 'models/topic'
5
+ require 'models/node'
6
+ require 'models/tree'
7
+
8
+ class TouchLaterTest < ActiveRecord::TestCase
9
+ fixtures :nodes, :trees
10
+
11
+ def test_touch_laster_raise_if_non_persisted
12
+ invoice = Invoice.new
13
+ Invoice.transaction do
14
+ assert_not invoice.persisted?
15
+ assert_raises(ActiveRecord::ActiveRecordError) do
16
+ invoice.touch_later
17
+ end
18
+ end
19
+ end
20
+
21
+ def test_touch_later_dont_set_dirty_attributes
22
+ invoice = Invoice.create!
23
+ invoice.touch_later
24
+ assert_not invoice.changed?
25
+ end
26
+
27
+ def test_touch_later_respects_no_touching_policy
28
+ time = Time.now.utc - 25.days
29
+ topic = Topic.create!(updated_at: time, created_at: time)
30
+ Topic.no_touching do
31
+ topic.touch_later
32
+ end
33
+ assert_equal time.to_i, topic.updated_at.to_i
34
+ end
35
+
36
+ def test_touch_later_update_the_attributes
37
+ time = Time.now.utc - 25.days
38
+ topic = Topic.create!(updated_at: time, created_at: time)
39
+ assert_equal time.to_i, topic.updated_at.to_i
40
+ assert_equal time.to_i, topic.created_at.to_i
41
+
42
+ Topic.transaction do
43
+ topic.touch_later(:created_at)
44
+ assert_not_equal time.to_i, topic.updated_at.to_i
45
+ assert_not_equal time.to_i, topic.created_at.to_i
46
+
47
+ assert_equal time.to_i, topic.reload.updated_at.to_i
48
+ assert_equal time.to_i, topic.reload.created_at.to_i
49
+ end
50
+ assert_not_equal time.to_i, topic.reload.updated_at.to_i
51
+ assert_not_equal time.to_i, topic.reload.created_at.to_i
52
+ end
53
+
54
+ def test_touch_touches_immediately
55
+ time = Time.now.utc - 25.days
56
+ topic = Topic.create!(updated_at: time, created_at: time)
57
+ assert_equal time.to_i, topic.updated_at.to_i
58
+ assert_equal time.to_i, topic.created_at.to_i
59
+
60
+ Topic.transaction do
61
+ topic.touch_later(:created_at)
62
+ topic.touch
63
+
64
+ assert_not_equal time, topic.reload.updated_at
65
+ assert_not_equal time, topic.reload.created_at
66
+ end
67
+ end
68
+
69
+ def test_touch_later_an_association_dont_autosave_parent
70
+ time = Time.now.utc - 25.days
71
+ line_item = LineItem.create!(amount: 1)
72
+ invoice = Invoice.create!(line_items: [line_item])
73
+ invoice.touch(time: time)
74
+
75
+ Invoice.transaction do
76
+ line_item.update(amount: 2)
77
+ assert_equal time.to_i, invoice.reload.updated_at.to_i
78
+ end
79
+
80
+ assert_not_equal time.to_i, invoice.updated_at.to_i
81
+ end
82
+
83
+ def test_touch_touches_immediately_with_a_custom_time
84
+ time = (Time.now.utc - 25.days).change(nsec: 0)
85
+ topic = Topic.create!(updated_at: time, created_at: time)
86
+ assert_equal time, topic.updated_at
87
+ assert_equal time, topic.created_at
88
+
89
+ Topic.transaction do
90
+ topic.touch_later(:created_at)
91
+ time = Time.now.utc - 2.days
92
+ topic.touch(time: time)
93
+
94
+ assert_equal time.to_i, topic.reload.updated_at.to_i
95
+ assert_equal time.to_i, topic.reload.created_at.to_i
96
+ end
97
+ end
98
+
99
+ def test_touch_later_dont_hit_the_db
100
+ invoice = Invoice.create!
101
+ assert_queries(0) do
102
+ invoice.touch_later
103
+ end
104
+ end
105
+
106
+ def test_touching_three_deep
107
+ previous_tree_updated_at = trees(:root).updated_at
108
+ previous_grandparent_updated_at = nodes(:grandparent).updated_at
109
+ previous_parent_updated_at = nodes(:parent_a).updated_at
110
+ previous_child_updated_at = nodes(:child_one_of_a).updated_at
111
+
112
+ travel 5.seconds do
113
+ Node.create! parent: nodes(:child_one_of_a), tree: trees(:root)
114
+ end
115
+
116
+ assert_not_equal nodes(:child_one_of_a).reload.updated_at, previous_child_updated_at
117
+ assert_not_equal nodes(:parent_a).reload.updated_at, previous_parent_updated_at
118
+ assert_not_equal nodes(:grandparent).reload.updated_at, previous_grandparent_updated_at
119
+ assert_not_equal trees(:root).reload.updated_at, previous_tree_updated_at
120
+ end
121
+ end
@@ -1,452 +1,518 @@
1
- require "cases/helper"
2
- require 'models/owner'
3
- require 'models/pet'
4
- require 'models/topic'
5
-
6
- class TransactionCallbacksTest < ActiveRecord::TestCase
7
- self.use_transactional_fixtures = false
8
- fixtures :topics, :owners, :pets
9
-
10
- class ReplyWithCallbacks < ActiveRecord::Base
11
- self.table_name = :topics
12
-
13
- belongs_to :topic, foreign_key: "parent_id"
14
-
15
- validates_presence_of :content
16
-
17
- after_commit :do_after_commit, on: :create
18
-
19
- attr_accessor :save_on_after_create
20
- after_create do
21
- self.save! if save_on_after_create
22
- end
23
-
24
- def history
25
- @history ||= []
26
- end
27
-
28
- def do_after_commit
29
- history << :commit_on_create
30
- end
31
- end
32
-
33
- class TopicWithCallbacks < ActiveRecord::Base
34
- self.table_name = :topics
35
-
36
- has_many :replies, class_name: "ReplyWithCallbacks", foreign_key: "parent_id"
37
-
38
- after_commit { |record| record.do_after_commit(nil) }
39
- after_commit(on: :create) { |record| record.do_after_commit(:create) }
40
- after_commit(on: :update) { |record| record.do_after_commit(:update) }
41
- after_commit(on: :destroy) { |record| record.do_after_commit(:destroy) }
42
- after_rollback { |record| record.do_after_rollback(nil) }
43
- after_rollback(on: :create) { |record| record.do_after_rollback(:create) }
44
- after_rollback(on: :update) { |record| record.do_after_rollback(:update) }
45
- after_rollback(on: :destroy) { |record| record.do_after_rollback(:destroy) }
46
-
47
- def history
48
- @history ||= []
49
- end
50
-
51
- def after_commit_block(on = nil, &block)
52
- @after_commit ||= {}
53
- @after_commit[on] ||= []
54
- @after_commit[on] << block
55
- end
56
-
57
- def after_rollback_block(on = nil, &block)
58
- @after_rollback ||= {}
59
- @after_rollback[on] ||= []
60
- @after_rollback[on] << block
61
- end
62
-
63
- def do_after_commit(on)
64
- blocks = @after_commit[on] if defined?(@after_commit)
65
- blocks.each{|b| b.call(self)} if blocks
66
- end
67
-
68
- def do_after_rollback(on)
69
- blocks = @after_rollback[on] if defined?(@after_rollback)
70
- blocks.each{|b| b.call(self)} if blocks
71
- end
72
- end
73
-
74
- def setup
75
- @first = TopicWithCallbacks.find(1)
76
- end
77
-
78
- def test_call_after_commit_after_transaction_commits
79
- @first.after_commit_block{|r| r.history << :after_commit}
80
- @first.after_rollback_block{|r| r.history << :after_rollback}
81
-
82
- @first.save!
83
- assert_equal [:after_commit], @first.history
84
- end
85
-
86
- def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record
87
- add_transaction_execution_blocks @first
88
-
89
- @first.save!
90
- assert_equal [:commit_on_update], @first.history
91
- end
92
-
93
- def test_only_call_after_commit_on_destroy_after_transaction_commits_for_destroyed_record
94
- add_transaction_execution_blocks @first
95
-
96
- @first.destroy
97
- assert_equal [:commit_on_destroy], @first.history
98
- end
99
-
100
- def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record
101
- unless current_adapter?(:IBM_DBAdapter)
102
- @new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
103
- else
104
- @new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Time.now)
105
- end
106
- add_transaction_execution_blocks new_record
107
-
108
- new_record.save!
109
- assert_equal [:commit_on_create], new_record.history
110
- end
111
-
112
- def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record_if_create_succeeds_creating_through_association
113
- topic = TopicWithCallbacks.create!(:title => "New topic", :written_on => Date.today)
114
- reply = topic.replies.create
115
-
116
- assert_equal [], reply.history
117
- end
118
-
119
- def test_only_call_after_commit_on_create_and_doesnt_leaky
120
- r = ReplyWithCallbacks.new(content: 'foo')
121
- r.save_on_after_create = true
122
- r.save!
123
- r.content = 'bar'
124
- r.save!
125
- r.save!
126
- assert_equal [:commit_on_create], r.history
127
- end
128
-
129
- def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record_on_touch
130
- add_transaction_execution_blocks @first
131
-
132
- @first.touch
133
- assert_equal [:commit_on_update], @first.history
134
- end
135
-
136
- def test_only_call_after_commit_on_top_level_transactions
137
- @first.after_commit_block{|r| r.history << :after_commit}
138
- assert @first.history.empty?
139
-
140
- @first.transaction do
141
- @first.transaction(requires_new: true) do
142
- @first.touch
143
- end
144
- assert @first.history.empty?
145
- end
146
- assert_equal [:after_commit], @first.history
147
- end
148
-
149
- def test_call_after_rollback_after_transaction_rollsback
150
- @first.after_commit_block{|r| r.history << :after_commit}
151
- @first.after_rollback_block{|r| r.history << :after_rollback}
152
-
153
- Topic.transaction do
154
- @first.save!
155
- raise ActiveRecord::Rollback
156
- end
157
-
158
- assert_equal [:after_rollback], @first.history
159
- end
160
-
161
- def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record
162
- add_transaction_execution_blocks @first
163
-
164
- Topic.transaction do
165
- @first.save!
166
- raise ActiveRecord::Rollback
167
- end
168
-
169
- assert_equal [:rollback_on_update], @first.history
170
- end
171
-
172
- def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record_on_touch
173
- add_transaction_execution_blocks @first
174
-
175
- Topic.transaction do
176
- @first.touch
177
- raise ActiveRecord::Rollback
178
- end
179
-
180
- assert_equal [:rollback_on_update], @first.history
181
- end
182
-
183
- def test_only_call_after_rollback_on_destroy_after_transaction_rollsback_for_destroyed_record
184
- add_transaction_execution_blocks @first
185
-
186
- Topic.transaction do
187
- @first.destroy
188
- raise ActiveRecord::Rollback
189
- end
190
-
191
- assert_equal [:rollback_on_destroy], @first.history
192
- end
193
-
194
- def test_only_call_after_rollback_on_create_after_transaction_rollsback_for_new_record
195
- unless current_adapter?(:IBM_DBAdapter)
196
- @new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
197
- else
198
- @new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Time.now)
199
- end
200
- add_transaction_execution_blocks new_record
201
-
202
- Topic.transaction do
203
- new_record.save!
204
- raise ActiveRecord::Rollback
205
- end
206
-
207
- assert_equal [:rollback_on_create], new_record.history
208
- end
209
-
210
- def test_call_after_rollback_when_commit_fails
211
- @first.class.connection.singleton_class.send(:alias_method, :real_method_commit_db_transaction, :commit_db_transaction)
212
- begin
213
- @first.class.connection.singleton_class.class_eval do
214
- def commit_db_transaction; raise "boom!"; end
215
- end
216
-
217
- @first.after_commit_block{|r| r.history << :after_commit}
218
- @first.after_rollback_block{|r| r.history << :after_rollback}
219
-
220
- assert !@first.save rescue nil
221
- assert_equal [:after_rollback], @first.history
222
- ensure
223
- @first.class.connection.singleton_class.send(:remove_method, :commit_db_transaction)
224
- @first.class.connection.singleton_class.send(:alias_method, :commit_db_transaction, :real_method_commit_db_transaction)
225
- end
226
- end
227
-
228
- def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint
229
- def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
230
- def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
231
- @first.after_rollback_block{|r| r.rollbacks(1)}
232
- @first.after_commit_block{|r| r.commits(1)}
233
-
234
- second = TopicWithCallbacks.find(3)
235
- def second.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
236
- def second.commits(i=0); @commits ||= 0; @commits += i if i; end
237
- second.after_rollback_block{|r| r.rollbacks(1)}
238
- second.after_commit_block{|r| r.commits(1)}
239
-
240
- Topic.transaction do
241
- @first.save!
242
- Topic.transaction(:requires_new => true) do
243
- second.save!
244
- raise ActiveRecord::Rollback
245
- end
246
- end
247
-
248
- assert_equal 1, @first.commits
249
- assert_equal 0, @first.rollbacks
250
- assert_equal 0, second.commits
251
- assert_equal 1, second.rollbacks
252
- end
253
-
254
- def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint_when_release_savepoint_fails
255
- def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
256
- def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
257
-
258
- @first.after_rollback_block{|r| r.rollbacks(1)}
259
- @first.after_commit_block{|r| r.commits(1)}
260
-
261
- Topic.transaction do
262
- @first.save
263
- Topic.transaction(:requires_new => true) do
264
- @first.save!
265
- raise ActiveRecord::Rollback
266
- end
267
- Topic.transaction(:requires_new => true) do
268
- @first.save!
269
- raise ActiveRecord::Rollback
270
- end
271
- end
272
-
273
- assert_equal 1, @first.commits
274
- assert_equal 2, @first.rollbacks
275
- end
276
-
277
- def test_after_transaction_callbacks_should_prevent_callbacks_from_being_called
278
- old_transaction_config = ActiveRecord::Base.raise_in_transactional_callbacks
279
- ActiveRecord::Base.raise_in_transactional_callbacks = false
280
-
281
- def @first.last_after_transaction_error=(e); @last_transaction_error = e; end
282
- def @first.last_after_transaction_error; @last_transaction_error; end
283
- @first.after_commit_block{|r| r.last_after_transaction_error = :commit; raise "fail!";}
284
- @first.after_rollback_block{|r| r.last_after_transaction_error = :rollback; raise "fail!";}
285
-
286
- second = TopicWithCallbacks.find(3)
287
- second.after_commit_block{|r| r.history << :after_commit}
288
- second.after_rollback_block{|r| r.history << :after_rollback}
289
-
290
- Topic.transaction do
291
- @first.save!
292
- second.save!
293
- end
294
- assert_equal :commit, @first.last_after_transaction_error
295
- assert_equal [:after_commit], second.history
296
-
297
- second.history.clear
298
- Topic.transaction do
299
- @first.save!
300
- second.save!
301
- raise ActiveRecord::Rollback
302
- end
303
- assert_equal :rollback, @first.last_after_transaction_error
304
- assert_equal [:after_rollback], second.history
305
- ensure
306
- ActiveRecord::Base.raise_in_transactional_callbacks = old_transaction_config
307
- end
308
-
309
- def test_after_commit_should_not_raise_when_raise_in_transactional_callbacks_false
310
- old_transaction_config = ActiveRecord::Base.raise_in_transactional_callbacks
311
- ActiveRecord::Base.raise_in_transactional_callbacks = false
312
- @first.after_commit_block{ fail "boom" }
313
- Topic.transaction { @first.save! }
314
- ensure
315
- ActiveRecord::Base.raise_in_transactional_callbacks = old_transaction_config
316
- end
317
-
318
- def test_after_commit_callback_should_not_swallow_errors
319
- @first.after_commit_block{ fail "boom" }
320
- assert_raises(RuntimeError) do
321
- Topic.transaction do
322
- @first.save!
323
- end
324
- end
325
- end
326
-
327
- def test_after_commit_callback_when_raise_should_not_restore_state
328
- first = TopicWithCallbacks.new
329
- second = TopicWithCallbacks.new
330
- first.after_commit_block{ fail "boom" }
331
- second.after_commit_block{ fail "boom" }
332
-
333
- begin
334
- Topic.transaction do
335
- first.save!
336
- assert_not_nil first.id
337
- second.save!
338
- assert_not_nil second.id
339
- end
340
- rescue
341
- end
342
- assert_not_nil first.id
343
- assert_not_nil second.id
344
- assert first.reload
345
- end
346
-
347
- def test_after_rollback_callback_should_not_swallow_errors_when_set_to_raise
348
- error_class = Class.new(StandardError)
349
- @first.after_rollback_block{ raise error_class }
350
- assert_raises(error_class) do
351
- Topic.transaction do
352
- @first.save!
353
- raise ActiveRecord::Rollback
354
- end
355
- end
356
- end
357
-
358
- def test_after_rollback_callback_when_raise_should_restore_state
359
- error_class = Class.new(StandardError)
360
-
361
- first = TopicWithCallbacks.new
362
- second = TopicWithCallbacks.new
363
- first.after_rollback_block{ raise error_class }
364
- second.after_rollback_block{ raise error_class }
365
-
366
- begin
367
- Topic.transaction do
368
- first.save!
369
- assert_not_nil first.id
370
- second.save!
371
- assert_not_nil second.id
372
- raise ActiveRecord::Rollback
373
- end
374
- rescue error_class
375
- end
376
- assert_nil first.id
377
- assert_nil second.id
378
- end
379
-
380
- def test_after_rollback_callbacks_should_validate_on_condition
381
- assert_raise(ArgumentError) { Topic.after_rollback(on: :save) }
382
- e = assert_raise(ArgumentError) { Topic.after_rollback(on: 'create') }
383
- assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
384
- end
385
-
386
- def test_after_commit_callbacks_should_validate_on_condition
387
- assert_raise(ArgumentError) { Topic.after_commit(on: :save) }
388
- e = assert_raise(ArgumentError) { Topic.after_commit(on: 'create') }
389
- assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
390
- end
391
-
392
- def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_call_callbacks_on_the_parent_object
393
- pet = Pet.first
394
- owner = pet.owner
395
- flag = false
396
-
397
- owner.on_after_commit do
398
- flag = true
399
- end
400
-
401
- pet.name = "Fluffy the Third"
402
- pet.save
403
-
404
- assert flag
405
- end
406
-
407
- private
408
-
409
- def add_transaction_execution_blocks(record)
410
- record.after_commit_block(:create) { |r| r.history << :commit_on_create }
411
- record.after_commit_block(:update) { |r| r.history << :commit_on_update }
412
- record.after_commit_block(:destroy) { |r| r.history << :commit_on_destroy }
413
- record.after_rollback_block(:create) { |r| r.history << :rollback_on_create }
414
- record.after_rollback_block(:update) { |r| r.history << :rollback_on_update }
415
- record.after_rollback_block(:destroy) { |r| r.history << :rollback_on_destroy }
416
- end
417
- end
418
-
419
- class CallbacksOnMultipleActionsTest < ActiveRecord::TestCase
420
- self.use_transactional_fixtures = false
421
-
422
- class TopicWithCallbacksOnMultipleActions < ActiveRecord::Base
423
- self.table_name = :topics
424
-
425
- after_commit(on: [:create, :destroy]) { |record| record.history << :create_and_destroy }
426
- after_commit(on: [:create, :update]) { |record| record.history << :create_and_update }
427
- after_commit(on: [:update, :destroy]) { |record| record.history << :update_and_destroy }
428
-
429
- def clear_history
430
- @history = []
431
- end
432
-
433
- def history
434
- @history ||= []
435
- end
436
- end
437
-
438
- def test_after_commit_on_multiple_actions
439
- topic = TopicWithCallbacksOnMultipleActions.new
440
- topic.save
441
- assert_equal [:create_and_update, :create_and_destroy], topic.history
442
-
443
- topic.clear_history
444
- topic.approved = true
445
- topic.save
446
- assert_equal [:update_and_destroy, :create_and_update], topic.history
447
-
448
- topic.clear_history
449
- topic.destroy
450
- assert_equal [:update_and_destroy, :create_and_destroy], topic.history
451
- end
452
- end
1
+ require "cases/helper"
2
+ require 'models/owner'
3
+ require 'models/pet'
4
+ require 'models/topic'
5
+
6
+ class TransactionCallbacksTest < ActiveRecord::TestCase
7
+ fixtures :topics, :owners, :pets
8
+
9
+ class ReplyWithCallbacks < ActiveRecord::Base
10
+ self.table_name = :topics
11
+
12
+ belongs_to :topic, foreign_key: "parent_id"
13
+
14
+ validates_presence_of :content
15
+
16
+ after_commit :do_after_commit, on: :create
17
+
18
+ attr_accessor :save_on_after_create
19
+ after_create do
20
+ self.save! if save_on_after_create
21
+ end
22
+
23
+ def history
24
+ @history ||= []
25
+ end
26
+
27
+ def do_after_commit
28
+ history << :commit_on_create
29
+ end
30
+ end
31
+
32
+ class TopicWithCallbacks < ActiveRecord::Base
33
+ self.table_name = :topics
34
+
35
+ has_many :replies, class_name: "ReplyWithCallbacks", foreign_key: "parent_id"
36
+
37
+ before_commit { |record| record.do_before_commit(nil) }
38
+ after_commit { |record| record.do_after_commit(nil) }
39
+ after_create_commit { |record| record.do_after_commit(:create) }
40
+ after_update_commit { |record| record.do_after_commit(:update) }
41
+ after_destroy_commit { |record| record.do_after_commit(:destroy) }
42
+ after_rollback { |record| record.do_after_rollback(nil) }
43
+ after_rollback(on: :create) { |record| record.do_after_rollback(:create) }
44
+ after_rollback(on: :update) { |record| record.do_after_rollback(:update) }
45
+ after_rollback(on: :destroy) { |record| record.do_after_rollback(:destroy) }
46
+
47
+ def history
48
+ @history ||= []
49
+ end
50
+
51
+ def before_commit_block(on = nil, &block)
52
+ @before_commit ||= {}
53
+ @before_commit[on] ||= []
54
+ @before_commit[on] << block
55
+ end
56
+
57
+ def after_commit_block(on = nil, &block)
58
+ @after_commit ||= {}
59
+ @after_commit[on] ||= []
60
+ @after_commit[on] << block
61
+ end
62
+
63
+ def after_rollback_block(on = nil, &block)
64
+ @after_rollback ||= {}
65
+ @after_rollback[on] ||= []
66
+ @after_rollback[on] << block
67
+ end
68
+
69
+ def do_before_commit(on)
70
+ blocks = @before_commit[on] if defined?(@before_commit)
71
+ blocks.each{|b| b.call(self)} if blocks
72
+ end
73
+
74
+ def do_after_commit(on)
75
+ blocks = @after_commit[on] if defined?(@after_commit)
76
+ blocks.each{|b| b.call(self)} if blocks
77
+ end
78
+
79
+ def do_after_rollback(on)
80
+ blocks = @after_rollback[on] if defined?(@after_rollback)
81
+ blocks.each{|b| b.call(self)} if blocks
82
+ end
83
+ end
84
+
85
+ def setup
86
+ @first = TopicWithCallbacks.find(1)
87
+ end
88
+
89
+ # FIXME: Test behavior, not implementation.
90
+ def test_before_commit_exception_should_pop_transaction_stack
91
+ @first.before_commit_block { raise 'better pop this txn from the stack!' }
92
+
93
+ original_txn = @first.class.connection.current_transaction
94
+
95
+ begin
96
+ @first.save!
97
+ fail
98
+ rescue
99
+ assert_equal original_txn, @first.class.connection.current_transaction
100
+ end
101
+ end
102
+
103
+ def test_call_after_commit_after_transaction_commits
104
+ @first.after_commit_block{|r| r.history << :after_commit}
105
+ @first.after_rollback_block{|r| r.history << :after_rollback}
106
+
107
+ @first.save!
108
+ assert_equal [:after_commit], @first.history
109
+ end
110
+
111
+ def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record
112
+ add_transaction_execution_blocks @first
113
+
114
+ @first.save!
115
+ assert_equal [:commit_on_update], @first.history
116
+ end
117
+
118
+ def test_only_call_after_commit_on_destroy_after_transaction_commits_for_destroyed_record
119
+ add_transaction_execution_blocks @first
120
+
121
+ @first.destroy
122
+ assert_equal [:commit_on_destroy], @first.history
123
+ end
124
+
125
+ def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record
126
+ unless current_adapter?(:IBM_DBAdapter)
127
+ new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
128
+ else
129
+ new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Time.now)
130
+ end
131
+ add_transaction_execution_blocks new_record
132
+
133
+ new_record.save!
134
+ assert_equal [:commit_on_create], new_record.history
135
+ end
136
+
137
+ def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record_if_create_succeeds_creating_through_association
138
+ topic = TopicWithCallbacks.create!(:title => "New topic", :written_on => Date.today)
139
+ reply = topic.replies.create
140
+
141
+ assert_equal [], reply.history
142
+ end
143
+
144
+ def test_only_call_after_commit_on_create_and_doesnt_leaky
145
+ r = ReplyWithCallbacks.new(content: 'foo')
146
+ r.save_on_after_create = true
147
+ r.save!
148
+ r.content = 'bar'
149
+ r.save!
150
+ r.save!
151
+ assert_equal [:commit_on_create], r.history
152
+ end
153
+
154
+ def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record_on_touch
155
+ add_transaction_execution_blocks @first
156
+
157
+ @first.touch
158
+ assert_equal [:commit_on_update], @first.history
159
+ end
160
+
161
+ def test_only_call_after_commit_on_top_level_transactions
162
+ @first.after_commit_block{|r| r.history << :after_commit}
163
+ assert @first.history.empty?
164
+
165
+ @first.transaction do
166
+ @first.transaction(requires_new: true) do
167
+ @first.touch
168
+ end
169
+ assert @first.history.empty?
170
+ end
171
+ assert_equal [:after_commit], @first.history
172
+ end
173
+
174
+ def test_call_after_rollback_after_transaction_rollsback
175
+ @first.after_commit_block{|r| r.history << :after_commit}
176
+ @first.after_rollback_block{|r| r.history << :after_rollback}
177
+
178
+ Topic.transaction do
179
+ @first.save!
180
+ raise ActiveRecord::Rollback
181
+ end
182
+
183
+ assert_equal [:after_rollback], @first.history
184
+ end
185
+
186
+ def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record
187
+ add_transaction_execution_blocks @first
188
+
189
+ Topic.transaction do
190
+ @first.save!
191
+ raise ActiveRecord::Rollback
192
+ end
193
+
194
+ assert_equal [:rollback_on_update], @first.history
195
+ end
196
+
197
+ def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record_on_touch
198
+ add_transaction_execution_blocks @first
199
+
200
+ Topic.transaction do
201
+ @first.touch
202
+ raise ActiveRecord::Rollback
203
+ end
204
+
205
+ assert_equal [:rollback_on_update], @first.history
206
+ end
207
+
208
+ def test_only_call_after_rollback_on_destroy_after_transaction_rollsback_for_destroyed_record
209
+ add_transaction_execution_blocks @first
210
+
211
+ Topic.transaction do
212
+ @first.destroy
213
+ raise ActiveRecord::Rollback
214
+ end
215
+
216
+ assert_equal [:rollback_on_destroy], @first.history
217
+ end
218
+
219
+ def test_only_call_after_rollback_on_create_after_transaction_rollsback_for_new_record
220
+ unless current_adapter?(:IBM_DBAdapter)
221
+ new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
222
+ else
223
+ new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Time.now)
224
+ end
225
+ add_transaction_execution_blocks new_record
226
+
227
+ Topic.transaction do
228
+ new_record.save!
229
+ raise ActiveRecord::Rollback
230
+ end
231
+
232
+ assert_equal [:rollback_on_create], new_record.history
233
+ end
234
+
235
+ def test_call_after_rollback_when_commit_fails
236
+ @first.after_commit_block { |r| r.history << :after_commit }
237
+ @first.after_rollback_block { |r| r.history << :after_rollback }
238
+
239
+ assert_raises RuntimeError do
240
+ @first.transaction do
241
+ tx = @first.class.connection.transaction_manager.current_transaction
242
+ def tx.commit
243
+ raise
244
+ end
245
+
246
+ @first.save
247
+ end
248
+ end
249
+
250
+ assert_equal [:after_rollback], @first.history
251
+ end
252
+
253
+ def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint
254
+ def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
255
+ def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
256
+ @first.after_rollback_block{|r| r.rollbacks(1)}
257
+ @first.after_commit_block{|r| r.commits(1)}
258
+
259
+ second = TopicWithCallbacks.find(3)
260
+ def second.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
261
+ def second.commits(i=0); @commits ||= 0; @commits += i if i; end
262
+ second.after_rollback_block{|r| r.rollbacks(1)}
263
+ second.after_commit_block{|r| r.commits(1)}
264
+
265
+ Topic.transaction do
266
+ @first.save!
267
+ Topic.transaction(:requires_new => true) do
268
+ second.save!
269
+ raise ActiveRecord::Rollback
270
+ end
271
+ end
272
+
273
+ assert_equal 1, @first.commits
274
+ assert_equal 0, @first.rollbacks
275
+ assert_equal 0, second.commits
276
+ assert_equal 1, second.rollbacks
277
+ end
278
+
279
+ def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint_when_release_savepoint_fails
280
+ def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
281
+ def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
282
+
283
+ @first.after_rollback_block{|r| r.rollbacks(1)}
284
+ @first.after_commit_block{|r| r.commits(1)}
285
+
286
+ Topic.transaction do
287
+ @first.save
288
+ Topic.transaction(:requires_new => true) do
289
+ @first.save!
290
+ raise ActiveRecord::Rollback
291
+ end
292
+ Topic.transaction(:requires_new => true) do
293
+ @first.save!
294
+ raise ActiveRecord::Rollback
295
+ end
296
+ end
297
+
298
+ assert_equal 1, @first.commits
299
+ assert_equal 2, @first.rollbacks
300
+ end
301
+
302
+ def test_after_commit_callback_should_not_swallow_errors
303
+ @first.after_commit_block{ fail "boom" }
304
+ assert_raises(RuntimeError) do
305
+ Topic.transaction do
306
+ @first.save!
307
+ end
308
+ end
309
+ end
310
+
311
+ def test_after_commit_callback_when_raise_should_not_restore_state
312
+ first = TopicWithCallbacks.new
313
+ second = TopicWithCallbacks.new
314
+ first.after_commit_block{ fail "boom" }
315
+ second.after_commit_block{ fail "boom" }
316
+
317
+ begin
318
+ Topic.transaction do
319
+ first.save!
320
+ assert_not_nil first.id
321
+ second.save!
322
+ assert_not_nil second.id
323
+ end
324
+ rescue
325
+ end
326
+ assert_not_nil first.id
327
+ assert_not_nil second.id
328
+ assert first.reload
329
+ end
330
+
331
+ def test_after_rollback_callback_should_not_swallow_errors_when_set_to_raise
332
+ error_class = Class.new(StandardError)
333
+ @first.after_rollback_block{ raise error_class }
334
+ assert_raises(error_class) do
335
+ Topic.transaction do
336
+ @first.save!
337
+ raise ActiveRecord::Rollback
338
+ end
339
+ end
340
+ end
341
+
342
+ def test_after_rollback_callback_when_raise_should_restore_state
343
+ error_class = Class.new(StandardError)
344
+
345
+ first = TopicWithCallbacks.new
346
+ second = TopicWithCallbacks.new
347
+ first.after_rollback_block{ raise error_class }
348
+ second.after_rollback_block{ raise error_class }
349
+
350
+ begin
351
+ Topic.transaction do
352
+ first.save!
353
+ assert_not_nil first.id
354
+ second.save!
355
+ assert_not_nil second.id
356
+ raise ActiveRecord::Rollback
357
+ end
358
+ rescue error_class
359
+ end
360
+ assert_nil first.id
361
+ assert_nil second.id
362
+ end
363
+
364
+ def test_after_rollback_callbacks_should_validate_on_condition
365
+ assert_raise(ArgumentError) { Topic.after_rollback(on: :save) }
366
+ e = assert_raise(ArgumentError) { Topic.after_rollback(on: 'create') }
367
+ assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
368
+ end
369
+
370
+ def test_after_commit_callbacks_should_validate_on_condition
371
+ assert_raise(ArgumentError) { Topic.after_commit(on: :save) }
372
+ e = assert_raise(ArgumentError) { Topic.after_commit(on: 'create') }
373
+ assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message)
374
+ end
375
+
376
+ def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_call_callbacks_on_the_parent_object
377
+ pet = Pet.first
378
+ owner = pet.owner
379
+ flag = false
380
+
381
+ owner.on_after_commit do
382
+ flag = true
383
+ end
384
+
385
+ pet.name = "Fluffy the Third"
386
+ pet.save
387
+
388
+ assert flag
389
+ end
390
+
391
+ private
392
+
393
+ def add_transaction_execution_blocks(record)
394
+ record.after_commit_block(:create) { |r| r.history << :commit_on_create }
395
+ record.after_commit_block(:update) { |r| r.history << :commit_on_update }
396
+ record.after_commit_block(:destroy) { |r| r.history << :commit_on_destroy }
397
+ record.after_rollback_block(:create) { |r| r.history << :rollback_on_create }
398
+ record.after_rollback_block(:update) { |r| r.history << :rollback_on_update }
399
+ record.after_rollback_block(:destroy) { |r| r.history << :rollback_on_destroy }
400
+ end
401
+ end
402
+
403
+ class CallbacksOnMultipleActionsTest < ActiveRecord::TestCase
404
+ self.use_transactional_tests = false
405
+
406
+ class TopicWithCallbacksOnMultipleActions < ActiveRecord::Base
407
+ self.table_name = :topics
408
+
409
+ after_commit(on: [:create, :destroy]) { |record| record.history << :create_and_destroy }
410
+ after_commit(on: [:create, :update]) { |record| record.history << :create_and_update }
411
+ after_commit(on: [:update, :destroy]) { |record| record.history << :update_and_destroy }
412
+
413
+ before_commit(if: :save_before_commit_history) { |record| record.history << :before_commit }
414
+ before_commit(if: :update_title) { |record| record.update(title: "before commit title") }
415
+
416
+ def clear_history
417
+ @history = []
418
+ end
419
+
420
+ def history
421
+ @history ||= []
422
+ end
423
+
424
+ attr_accessor :save_before_commit_history, :update_title
425
+ end
426
+
427
+ def test_after_commit_on_multiple_actions
428
+ topic = TopicWithCallbacksOnMultipleActions.new
429
+ topic.save
430
+ assert_equal [:create_and_update, :create_and_destroy], topic.history
431
+
432
+ topic.clear_history
433
+ topic.approved = true
434
+ topic.save
435
+ assert_equal [:update_and_destroy, :create_and_update], topic.history
436
+
437
+ topic.clear_history
438
+ topic.destroy
439
+ assert_equal [:update_and_destroy, :create_and_destroy], topic.history
440
+ end
441
+
442
+ def test_before_commit_actions
443
+ topic = TopicWithCallbacksOnMultipleActions.new
444
+ topic.save_before_commit_history = true
445
+ topic.save
446
+
447
+ assert_equal [:before_commit, :create_and_update, :create_and_destroy], topic.history
448
+ end
449
+
450
+ def test_before_commit_update_in_same_transaction
451
+ topic = TopicWithCallbacksOnMultipleActions.new
452
+ topic.update_title = true
453
+ topic.save
454
+
455
+ assert_equal "before commit title", topic.title
456
+ assert_equal "before commit title", topic.reload.title
457
+ end
458
+ end
459
+
460
+
461
+ class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase
462
+
463
+ class TopicWithoutTransactionalEnrollmentCallbacks < ActiveRecord::Base
464
+ self.table_name = :topics
465
+
466
+ before_commit_without_transaction_enrollment { |r| r.history << :before_commit }
467
+ after_commit_without_transaction_enrollment { |r| r.history << :after_commit }
468
+ after_rollback_without_transaction_enrollment { |r| r.history << :rollback }
469
+
470
+ def history
471
+ @history ||= []
472
+ end
473
+ end
474
+
475
+ def setup
476
+ @topic = TopicWithoutTransactionalEnrollmentCallbacks.create!
477
+ end
478
+
479
+ def test_commit_does_not_run_transactions_callbacks_without_enrollment
480
+ @topic.transaction do
481
+ @topic.content = 'foo'
482
+ @topic.save!
483
+ end
484
+ assert @topic.history.empty?
485
+ end
486
+
487
+ def test_commit_run_transactions_callbacks_with_explicit_enrollment
488
+ @topic.transaction do
489
+ 2.times do
490
+ @topic.content = 'foo'
491
+ @topic.save!
492
+ end
493
+ @topic.class.connection.add_transaction_record(@topic)
494
+ end
495
+ assert_equal [:before_commit, :after_commit], @topic.history
496
+ end
497
+
498
+ def test_rollback_does_not_run_transactions_callbacks_without_enrollment
499
+ @topic.transaction do
500
+ @topic.content = 'foo'
501
+ @topic.save!
502
+ raise ActiveRecord::Rollback
503
+ end
504
+ assert @topic.history.empty?
505
+ end
506
+
507
+ def test_rollback_run_transactions_callbacks_with_explicit_enrollment
508
+ @topic.transaction do
509
+ 2.times do
510
+ @topic.content = 'foo'
511
+ @topic.save!
512
+ end
513
+ @topic.class.connection.add_transaction_record(@topic)
514
+ raise ActiveRecord::Rollback
515
+ end
516
+ assert_equal [:rollback], @topic.history
517
+ end
518
+ end