ibm_db 3.0.5 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (580) 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/test/active_record/connection_adapters/fake_adapter.rb +49 -46
  20. data/test/assets/example.log +1 -1
  21. data/test/assets/test.txt +1 -1
  22. data/test/cases/adapter_test.rb +351 -276
  23. data/test/cases/adapters/mysql2/active_schema_test.rb +193 -0
  24. data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -0
  25. data/test/cases/adapters/mysql2/boolean_test.rb +100 -0
  26. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -0
  27. data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -0
  28. data/test/cases/adapters/mysql2/connection_test.rb +210 -0
  29. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -0
  30. data/test/cases/adapters/mysql2/enum_test.rb +26 -0
  31. data/test/cases/adapters/mysql2/explain_test.rb +21 -0
  32. data/test/cases/adapters/mysql2/json_test.rb +195 -0
  33. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -0
  34. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -0
  35. data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -0
  36. data/test/cases/adapters/mysql2/schema_test.rb +126 -0
  37. data/test/cases/adapters/mysql2/sp_test.rb +36 -0
  38. data/test/cases/adapters/mysql2/sql_types_test.rb +14 -0
  39. data/test/cases/adapters/mysql2/table_options_test.rb +42 -0
  40. data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -0
  41. data/test/cases/adapters/postgresql/active_schema_test.rb +98 -0
  42. data/test/cases/adapters/postgresql/array_test.rb +339 -0
  43. data/test/cases/adapters/postgresql/bit_string_test.rb +82 -0
  44. data/test/cases/adapters/postgresql/bytea_test.rb +134 -0
  45. data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -0
  46. data/test/cases/adapters/postgresql/change_schema_test.rb +38 -0
  47. data/test/cases/adapters/postgresql/cidr_test.rb +25 -0
  48. data/test/cases/adapters/postgresql/citext_test.rb +78 -0
  49. data/test/cases/adapters/postgresql/collation_test.rb +53 -0
  50. data/test/cases/adapters/postgresql/composite_test.rb +132 -0
  51. data/test/cases/adapters/postgresql/connection_test.rb +257 -0
  52. data/test/cases/adapters/postgresql/datatype_test.rb +92 -0
  53. data/test/cases/adapters/postgresql/domain_test.rb +47 -0
  54. data/test/cases/adapters/postgresql/enum_test.rb +91 -0
  55. data/test/cases/adapters/postgresql/explain_test.rb +20 -0
  56. data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -0
  57. data/test/cases/adapters/postgresql/full_text_test.rb +44 -0
  58. data/test/cases/adapters/postgresql/geometric_test.rb +378 -0
  59. data/test/cases/adapters/postgresql/hstore_test.rb +382 -0
  60. data/test/cases/adapters/postgresql/infinity_test.rb +69 -0
  61. data/test/cases/adapters/postgresql/integer_test.rb +25 -0
  62. data/test/cases/adapters/postgresql/json_test.rb +237 -0
  63. data/test/cases/adapters/postgresql/ltree_test.rb +53 -0
  64. data/test/cases/adapters/postgresql/money_test.rb +96 -0
  65. data/test/cases/adapters/postgresql/network_test.rb +94 -0
  66. data/test/cases/adapters/postgresql/numbers_test.rb +49 -0
  67. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -0
  68. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
  69. data/test/cases/adapters/postgresql/quoting_test.rb +44 -0
  70. data/test/cases/adapters/postgresql/range_test.rb +343 -0
  71. data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -0
  72. data/test/cases/adapters/postgresql/rename_table_test.rb +34 -0
  73. data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -0
  74. data/test/cases/adapters/postgresql/schema_test.rb +597 -0
  75. data/test/cases/adapters/postgresql/serial_test.rb +154 -0
  76. data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -0
  77. data/test/cases/adapters/postgresql/timestamp_test.rb +90 -0
  78. data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -0
  79. data/test/cases/adapters/postgresql/utils_test.rb +62 -0
  80. data/test/cases/adapters/postgresql/uuid_test.rb +294 -0
  81. data/test/cases/adapters/postgresql/xml_test.rb +54 -0
  82. data/test/cases/adapters/sqlite3/collation_test.rb +53 -0
  83. data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -0
  84. data/test/cases/adapters/sqlite3/explain_test.rb +21 -0
  85. data/test/cases/adapters/sqlite3/quoting_test.rb +101 -0
  86. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -0
  87. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -0
  88. data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -0
  89. data/test/cases/aggregations_test.rb +168 -158
  90. data/test/cases/ar_schema_test.rb +146 -161
  91. data/test/cases/associations/association_scope_test.rb +16 -21
  92. data/test/cases/associations/belongs_to_associations_test.rb +1141 -1029
  93. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -0
  94. data/test/cases/associations/callbacks_test.rb +190 -192
  95. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  96. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  97. data/test/cases/associations/eager_load_nested_include_test.rb +126 -128
  98. data/test/cases/associations/eager_singularization_test.rb +148 -148
  99. data/test/cases/associations/eager_test.rb +1514 -1429
  100. data/test/cases/associations/extension_test.rb +87 -82
  101. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +1004 -972
  102. data/test/cases/associations/has_many_associations_test.rb +2501 -2182
  103. data/test/cases/associations/has_many_through_associations_test.rb +1271 -1204
  104. data/test/cases/associations/has_one_associations_test.rb +707 -610
  105. data/test/cases/associations/has_one_through_associations_test.rb +383 -380
  106. data/test/cases/associations/inner_join_association_test.rb +139 -139
  107. data/test/cases/associations/inverse_associations_test.rb +733 -706
  108. data/test/cases/associations/join_model_test.rb +777 -754
  109. data/test/cases/associations/left_outer_join_association_test.rb +88 -0
  110. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  111. data/test/cases/associations/required_test.rb +102 -82
  112. data/test/cases/associations_test.rb +385 -380
  113. data/test/cases/attribute_decorators_test.rb +125 -125
  114. data/test/cases/attribute_methods/read_test.rb +60 -60
  115. data/test/cases/attribute_methods_test.rb +1009 -952
  116. data/test/cases/attribute_set_test.rb +270 -210
  117. data/test/cases/attribute_test.rb +246 -180
  118. data/test/cases/attributes_test.rb +253 -136
  119. data/test/cases/autosave_association_test.rb +1708 -1595
  120. data/test/cases/base_test.rb +1713 -1664
  121. data/test/cases/batches_test.rb +489 -212
  122. data/test/cases/binary_test.rb +44 -52
  123. data/test/cases/bind_parameter_test.rb +110 -100
  124. data/test/cases/cache_key_test.rb +25 -0
  125. data/test/cases/calculations_test.rb +798 -646
  126. data/test/cases/callbacks_test.rb +636 -543
  127. data/test/cases/clone_test.rb +40 -40
  128. data/test/cases/coders/json_test.rb +15 -0
  129. data/test/cases/coders/yaml_column_test.rb +63 -63
  130. data/test/cases/collection_cache_key_test.rb +115 -0
  131. data/test/cases/column_alias_test.rb +17 -17
  132. data/test/cases/column_definition_test.rb +92 -123
  133. data/test/cases/comment_test.rb +143 -0
  134. data/test/cases/connection_adapters/adapter_leasing_test.rb +56 -54
  135. data/test/cases/connection_adapters/connection_handler_test.rb +160 -53
  136. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  137. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +255 -293
  138. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +69 -65
  139. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  140. data/test/cases/connection_adapters/schema_cache_test.rb +61 -56
  141. data/test/cases/connection_adapters/type_lookup_test.rb +118 -110
  142. data/test/cases/connection_management_test.rb +112 -122
  143. data/test/cases/connection_pool_test.rb +521 -346
  144. data/test/cases/connection_specification/resolver_test.rb +131 -116
  145. data/test/cases/core_test.rb +112 -112
  146. data/test/cases/counter_cache_test.rb +214 -209
  147. data/test/cases/custom_locking_test.rb +17 -17
  148. data/test/cases/database_statements_test.rb +34 -19
  149. data/test/cases/{invalid_date_test.rb → date_test.rb} +44 -32
  150. data/test/cases/date_time_precision_test.rb +106 -0
  151. data/test/cases/date_time_test.rb +61 -61
  152. data/test/cases/defaults_test.rb +218 -223
  153. data/test/cases/dirty_test.rb +763 -785
  154. data/test/cases/disconnected_test.rb +30 -28
  155. data/test/cases/dup_test.rb +157 -157
  156. data/test/cases/enum_test.rb +444 -290
  157. data/test/cases/errors_test.rb +16 -0
  158. data/test/cases/explain_subscriber_test.rb +64 -64
  159. data/test/cases/explain_test.rb +87 -76
  160. data/test/cases/finder_respond_to_test.rb +60 -60
  161. data/test/cases/finder_test.rb +1294 -1169
  162. data/test/cases/fixture_set/file_test.rb +156 -138
  163. data/test/cases/fixtures_test.rb +988 -908
  164. data/test/cases/forbidden_attributes_protection_test.rb +165 -99
  165. data/test/cases/habtm_destroy_order_test.rb +61 -61
  166. data/test/cases/helper.rb +204 -210
  167. data/test/cases/hot_compatibility_test.rb +142 -54
  168. data/test/cases/i18n_test.rb +45 -45
  169. data/test/cases/inheritance_test.rb +606 -375
  170. data/test/cases/integration_test.rb +155 -139
  171. data/test/cases/invalid_connection_test.rb +24 -22
  172. data/test/cases/invertible_migration_test.rb +387 -295
  173. data/test/cases/json_serialization_test.rb +311 -302
  174. data/test/cases/locking_test.rb +493 -477
  175. data/test/cases/log_subscriber_test.rb +225 -136
  176. data/test/cases/migration/change_schema_test.rb +458 -512
  177. data/test/cases/migration/change_table_test.rb +256 -224
  178. data/test/cases/migration/column_attributes_test.rb +176 -192
  179. data/test/cases/migration/column_positioning_test.rb +56 -56
  180. data/test/cases/migration/columns_test.rb +310 -304
  181. data/test/cases/migration/command_recorder_test.rb +350 -305
  182. data/test/cases/migration/compatibility_test.rb +118 -0
  183. data/test/cases/migration/create_join_table_test.rb +157 -148
  184. data/test/cases/migration/foreign_key_test.rb +360 -328
  185. data/test/cases/migration/helper.rb +39 -39
  186. data/test/cases/migration/index_test.rb +218 -216
  187. data/test/cases/migration/logger_test.rb +36 -36
  188. data/test/cases/migration/pending_migrations_test.rb +52 -53
  189. data/test/cases/migration/references_foreign_key_test.rb +216 -169
  190. data/test/cases/migration/references_index_test.rb +101 -101
  191. data/test/cases/migration/references_statements_test.rb +136 -116
  192. data/test/cases/migration/rename_table_test.rb +93 -93
  193. data/test/cases/migration_test.rb +1157 -959
  194. data/test/cases/migrator_test.rb +470 -388
  195. data/test/cases/mixin_test.rb +68 -70
  196. data/test/cases/modules_test.rb +172 -173
  197. data/test/cases/multiparameter_attributes_test.rb +372 -350
  198. data/test/cases/multiple_db_test.rb +122 -115
  199. data/test/cases/nested_attributes_test.rb +1098 -1070
  200. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  201. data/test/cases/persistence_test.rb +1001 -909
  202. data/test/cases/pooled_connections_test.rb +81 -81
  203. data/test/cases/primary_keys_test.rb +376 -237
  204. data/test/cases/query_cache_test.rb +446 -326
  205. data/test/cases/quoting_test.rb +202 -156
  206. data/test/cases/readonly_test.rb +119 -118
  207. data/test/cases/reaper_test.rb +85 -85
  208. data/test/cases/reflection_test.rb +509 -463
  209. data/test/cases/relation/delegation_test.rb +63 -68
  210. data/test/cases/relation/merging_test.rb +157 -161
  211. data/test/cases/relation/mutation_test.rb +183 -165
  212. data/test/cases/relation/or_test.rb +92 -0
  213. data/test/cases/relation/predicate_builder_test.rb +16 -14
  214. data/test/cases/relation/record_fetch_warning_test.rb +40 -0
  215. data/test/cases/relation/where_chain_test.rb +105 -181
  216. data/test/cases/relation/where_clause_test.rb +182 -0
  217. data/test/cases/relation/where_test.rb +322 -300
  218. data/test/cases/relation_test.rb +328 -319
  219. data/test/cases/relations_test.rb +2026 -1815
  220. data/test/cases/reload_models_test.rb +22 -22
  221. data/test/cases/result_test.rb +90 -80
  222. data/test/cases/sanitize_test.rb +176 -83
  223. data/test/cases/schema_dumper_test.rb +457 -463
  224. data/test/cases/schema_loading_test.rb +52 -0
  225. data/test/cases/scoping/default_scoping_test.rb +528 -454
  226. data/test/cases/scoping/named_scoping_test.rb +561 -524
  227. data/test/cases/scoping/relation_scoping_test.rb +400 -357
  228. data/test/cases/secure_token_test.rb +32 -0
  229. data/test/cases/serialization_test.rb +104 -104
  230. data/test/cases/serialized_attribute_test.rb +364 -277
  231. data/test/cases/statement_cache_test.rb +136 -98
  232. data/test/cases/store_test.rb +195 -194
  233. data/test/cases/suppressor_test.rb +63 -0
  234. data/test/cases/tasks/database_tasks_test.rb +462 -398
  235. data/test/cases/tasks/mysql_rake_test.rb +345 -324
  236. data/test/cases/tasks/postgresql_rake_test.rb +304 -250
  237. data/test/cases/tasks/sqlite_rake_test.rb +220 -193
  238. data/test/cases/test_case.rb +131 -123
  239. data/test/cases/test_fixtures_test.rb +36 -0
  240. data/test/cases/time_precision_test.rb +102 -0
  241. data/test/cases/timestamp_test.rb +501 -467
  242. data/test/cases/touch_later_test.rb +121 -0
  243. data/test/cases/transaction_callbacks_test.rb +518 -452
  244. data/test/cases/transaction_isolation_test.rb +106 -106
  245. data/test/cases/transactions_test.rb +834 -817
  246. data/test/cases/type/adapter_specific_registry_test.rb +133 -0
  247. data/test/cases/type/date_time_test.rb +14 -0
  248. data/test/cases/type/integer_test.rb +27 -121
  249. data/test/cases/type/string_test.rb +22 -36
  250. data/test/cases/type/type_map_test.rb +177 -177
  251. data/test/cases/type_test.rb +39 -0
  252. data/test/cases/types_test.rb +24 -141
  253. data/test/cases/unconnected_test.rb +33 -33
  254. data/test/cases/validations/absence_validation_test.rb +73 -0
  255. data/test/cases/validations/association_validation_test.rb +97 -86
  256. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  257. data/test/cases/validations/i18n_validation_test.rb +86 -90
  258. data/test/cases/validations/length_validation_test.rb +79 -47
  259. data/test/cases/validations/presence_validation_test.rb +103 -68
  260. data/test/cases/validations/uniqueness_validation_test.rb +548 -457
  261. data/test/cases/validations_repair_helper.rb +19 -23
  262. data/test/cases/validations_test.rb +194 -165
  263. data/test/cases/view_test.rb +216 -119
  264. data/test/cases/yaml_serialization_test.rb +121 -126
  265. data/test/config.example.yml +97 -0
  266. data/test/config.rb +5 -5
  267. data/test/fixtures/accounts.yml +29 -29
  268. data/test/fixtures/admin/accounts.yml +2 -2
  269. data/test/fixtures/admin/users.yml +10 -10
  270. data/test/fixtures/author_addresses.original +11 -0
  271. data/test/fixtures/author_addresses.yml +17 -17
  272. data/test/fixtures/author_favorites.yml +3 -3
  273. data/test/fixtures/authors.original +17 -0
  274. data/test/fixtures/authors.yml +23 -23
  275. data/test/fixtures/bad_posts.yml +9 -0
  276. data/test/fixtures/binaries.yml +133 -133
  277. data/test/fixtures/books.yml +31 -11
  278. data/test/fixtures/bulbs.yml +5 -5
  279. data/test/fixtures/cars.yml +9 -9
  280. data/test/fixtures/categories.yml +19 -19
  281. data/test/fixtures/categories/special_categories.yml +9 -9
  282. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  283. data/test/fixtures/categories_ordered.yml +7 -7
  284. data/test/fixtures/categories_posts.yml +31 -31
  285. data/test/fixtures/categorizations.yml +23 -23
  286. data/test/fixtures/clubs.yml +8 -8
  287. data/test/fixtures/collections.yml +3 -3
  288. data/test/fixtures/colleges.yml +3 -3
  289. data/test/fixtures/comments.yml +65 -65
  290. data/test/fixtures/companies.yml +67 -67
  291. data/test/fixtures/computers.yml +10 -10
  292. data/test/fixtures/content.yml +3 -0
  293. data/test/fixtures/content_positions.yml +3 -0
  294. data/test/fixtures/courses.yml +8 -8
  295. data/test/fixtures/customers.yml +25 -25
  296. data/test/fixtures/dashboards.yml +6 -6
  297. data/test/fixtures/dead_parrots.yml +5 -0
  298. data/test/fixtures/developers.yml +22 -22
  299. data/test/fixtures/developers_projects.yml +16 -16
  300. data/test/fixtures/dog_lovers.yml +7 -7
  301. data/test/fixtures/dogs.yml +4 -4
  302. data/test/fixtures/doubloons.yml +3 -3
  303. data/test/fixtures/edges.yml +5 -5
  304. data/test/fixtures/entrants.yml +14 -14
  305. data/test/fixtures/essays.yml +6 -6
  306. data/test/fixtures/faces.yml +11 -11
  307. data/test/fixtures/fk_test_has_fk.yml +3 -3
  308. data/test/fixtures/fk_test_has_pk.yml +1 -1
  309. data/test/fixtures/friendships.yml +4 -4
  310. data/test/fixtures/funny_jokes.yml +10 -10
  311. data/test/fixtures/interests.yml +33 -33
  312. data/test/fixtures/items.yml +3 -3
  313. data/test/fixtures/jobs.yml +7 -7
  314. data/test/fixtures/legacy_things.yml +3 -3
  315. data/test/fixtures/live_parrots.yml +4 -0
  316. data/test/fixtures/mateys.yml +4 -4
  317. data/test/fixtures/member_details.yml +8 -8
  318. data/test/fixtures/member_types.yml +6 -6
  319. data/test/fixtures/members.yml +11 -11
  320. data/test/fixtures/memberships.yml +34 -34
  321. data/test/fixtures/men.yml +5 -5
  322. data/test/fixtures/minimalistics.yml +2 -2
  323. data/test/fixtures/minivans.yml +5 -5
  324. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  325. data/test/fixtures/mixins.yml +29 -29
  326. data/test/fixtures/movies.yml +7 -7
  327. data/test/fixtures/naked/yml/accounts.yml +1 -1
  328. data/test/fixtures/naked/yml/companies.yml +1 -1
  329. data/test/fixtures/naked/yml/courses.yml +1 -1
  330. data/test/fixtures/naked/yml/parrots.yml +2 -0
  331. data/test/fixtures/naked/yml/trees.yml +3 -0
  332. data/test/fixtures/nodes.yml +29 -0
  333. data/test/fixtures/organizations.yml +5 -5
  334. data/test/fixtures/other_comments.yml +6 -0
  335. data/test/fixtures/other_dogs.yml +2 -0
  336. data/test/fixtures/other_posts.yml +7 -0
  337. data/test/fixtures/other_topics.yml +42 -42
  338. data/test/fixtures/owners.yml +9 -9
  339. data/test/fixtures/parrots.yml +27 -27
  340. data/test/fixtures/parrots_pirates.yml +7 -7
  341. data/test/fixtures/people.yml +24 -24
  342. data/test/fixtures/peoples_treasures.yml +3 -3
  343. data/test/fixtures/pets.yml +19 -19
  344. data/test/fixtures/pirates.yml +15 -12
  345. data/test/fixtures/posts.yml +80 -80
  346. data/test/fixtures/price_estimates.yml +16 -7
  347. data/test/fixtures/products.yml +4 -4
  348. data/test/fixtures/projects.yml +7 -7
  349. data/test/fixtures/ratings.yml +14 -14
  350. data/test/fixtures/readers.yml +11 -11
  351. data/test/fixtures/references.yml +17 -17
  352. data/test/fixtures/reserved_words/distinct.yml +5 -5
  353. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  354. data/test/fixtures/reserved_words/group.yml +14 -14
  355. data/test/fixtures/reserved_words/select.yml +8 -8
  356. data/test/fixtures/reserved_words/values.yml +7 -7
  357. data/test/fixtures/ships.yml +6 -6
  358. data/test/fixtures/speedometers.yml +8 -8
  359. data/test/fixtures/sponsors.yml +12 -12
  360. data/test/fixtures/string_key_objects.yml +7 -7
  361. data/test/fixtures/subscribers.yml +10 -10
  362. data/test/fixtures/subscriptions.yml +12 -12
  363. data/test/fixtures/taggings.yml +78 -78
  364. data/test/fixtures/tags.yml +11 -11
  365. data/test/fixtures/tasks.yml +7 -7
  366. data/test/fixtures/teapots.yml +3 -3
  367. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  368. data/test/fixtures/to_be_linked/users.yml +10 -10
  369. data/test/fixtures/topics.yml +49 -49
  370. data/test/fixtures/toys.yml +14 -14
  371. data/test/fixtures/traffic_lights.yml +9 -9
  372. data/test/fixtures/treasures.yml +10 -10
  373. data/test/fixtures/trees.yml +3 -0
  374. data/test/fixtures/uuid_children.yml +3 -3
  375. data/test/fixtures/uuid_parents.yml +2 -2
  376. data/test/fixtures/variants.yml +4 -4
  377. data/test/fixtures/vegetables.yml +19 -19
  378. data/test/fixtures/vertices.yml +3 -3
  379. data/test/fixtures/warehouse_things.yml +2 -2
  380. data/test/fixtures/zines.yml +5 -5
  381. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  382. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  383. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  384. data/test/migrations/missing/1000_people_have_middle_names.rb +9 -9
  385. data/test/migrations/missing/1_people_have_last_names.rb +9 -9
  386. data/test/migrations/missing/3_we_need_reminders.rb +12 -12
  387. data/test/migrations/missing/4_innocent_jointable.rb +12 -12
  388. data/test/migrations/rename/1_we_need_things.rb +11 -11
  389. data/test/migrations/rename/2_rename_things.rb +9 -9
  390. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  391. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  392. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  393. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  394. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  395. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  396. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  397. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  398. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  399. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  400. data/test/migrations/valid/2_we_need_reminders.rb +12 -12
  401. data/test/migrations/valid/3_innocent_jointable.rb +12 -12
  402. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  403. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +12 -12
  404. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +12 -12
  405. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  406. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  407. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  408. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  409. data/test/models/admin.rb +5 -5
  410. data/test/models/admin/account.rb +3 -3
  411. data/test/models/admin/randomly_named_c1.rb +6 -2
  412. data/test/models/admin/user.rb +40 -40
  413. data/test/models/aircraft.rb +5 -4
  414. data/test/models/arunit2_model.rb +3 -3
  415. data/test/models/author.rb +209 -212
  416. data/test/models/auto_id.rb +4 -4
  417. data/test/models/autoloadable/extra_firm.rb +2 -2
  418. data/test/models/binary.rb +2 -2
  419. data/test/models/bird.rb +12 -12
  420. data/test/models/book.rb +23 -18
  421. data/test/models/boolean.rb +2 -2
  422. data/test/models/bulb.rb +52 -51
  423. data/test/models/cake_designer.rb +3 -3
  424. data/test/models/car.rb +29 -26
  425. data/test/models/carrier.rb +2 -2
  426. data/test/models/cat.rb +10 -0
  427. data/test/models/categorization.rb +19 -19
  428. data/test/models/category.rb +35 -35
  429. data/test/models/chef.rb +8 -7
  430. data/test/models/citation.rb +3 -3
  431. data/test/models/club.rb +25 -23
  432. data/test/models/college.rb +10 -10
  433. data/test/models/column.rb +3 -3
  434. data/test/models/column_name.rb +3 -3
  435. data/test/models/comment.rb +76 -64
  436. data/test/models/company.rb +230 -228
  437. data/test/models/company_in_module.rb +98 -98
  438. data/test/models/computer.rb +3 -3
  439. data/test/models/contact.rb +41 -41
  440. data/test/models/content.rb +40 -0
  441. data/test/models/contract.rb +20 -20
  442. data/test/models/country.rb +7 -7
  443. data/test/models/course.rb +6 -6
  444. data/test/models/customer.rb +83 -77
  445. data/test/models/customer_carrier.rb +14 -14
  446. data/test/models/dashboard.rb +3 -3
  447. data/test/models/default.rb +2 -2
  448. data/test/models/department.rb +4 -4
  449. data/test/models/developer.rb +274 -255
  450. data/test/models/dog.rb +5 -5
  451. data/test/models/dog_lover.rb +5 -5
  452. data/test/models/doubloon.rb +12 -12
  453. data/test/models/drink_designer.rb +3 -3
  454. data/test/models/edge.rb +5 -5
  455. data/test/models/electron.rb +5 -5
  456. data/test/models/engine.rb +4 -4
  457. data/test/models/entrant.rb +3 -3
  458. data/test/models/essay.rb +5 -5
  459. data/test/models/event.rb +3 -3
  460. data/test/models/eye.rb +37 -37
  461. data/test/models/face.rb +9 -9
  462. data/test/models/friendship.rb +6 -6
  463. data/test/models/guid.rb +2 -2
  464. data/test/models/guitar.rb +4 -0
  465. data/test/models/hotel.rb +11 -9
  466. data/test/models/image.rb +3 -3
  467. data/test/models/interest.rb +5 -5
  468. data/test/models/invoice.rb +4 -4
  469. data/test/models/item.rb +7 -7
  470. data/test/models/job.rb +7 -7
  471. data/test/models/joke.rb +7 -7
  472. data/test/models/keyboard.rb +3 -3
  473. data/test/models/legacy_thing.rb +3 -3
  474. data/test/models/lesson.rb +11 -11
  475. data/test/models/line_item.rb +3 -3
  476. data/test/models/liquid.rb +4 -4
  477. data/test/models/man.rb +11 -11
  478. data/test/models/matey.rb +4 -4
  479. data/test/models/member.rb +42 -41
  480. data/test/models/member_detail.rb +8 -7
  481. data/test/models/member_type.rb +3 -3
  482. data/test/models/membership.rb +35 -35
  483. data/test/models/mentor.rb +3 -0
  484. data/test/models/minimalistic.rb +2 -2
  485. data/test/models/minivan.rb +9 -9
  486. data/test/models/mixed_case_monkey.rb +3 -3
  487. data/test/models/mocktail_designer.rb +2 -0
  488. data/test/models/molecule.rb +6 -6
  489. data/test/models/movie.rb +5 -5
  490. data/test/models/node.rb +5 -0
  491. data/test/models/non_primary_key.rb +2 -0
  492. data/test/models/notification.rb +3 -0
  493. data/test/models/order.rb +4 -4
  494. data/test/models/organization.rb +14 -14
  495. data/test/models/other_dog.rb +5 -0
  496. data/test/models/owner.rb +37 -34
  497. data/test/models/parrot.rb +28 -29
  498. data/test/models/person.rb +142 -143
  499. data/test/models/personal_legacy_thing.rb +4 -4
  500. data/test/models/pet.rb +18 -15
  501. data/test/models/pet_treasure.rb +6 -0
  502. data/test/models/pirate.rb +92 -92
  503. data/test/models/possession.rb +3 -3
  504. data/test/models/post.rb +273 -264
  505. data/test/models/price_estimate.rb +4 -4
  506. data/test/models/professor.rb +5 -5
  507. data/test/models/project.rb +40 -31
  508. data/test/models/publisher.rb +2 -2
  509. data/test/models/publisher/article.rb +4 -4
  510. data/test/models/publisher/magazine.rb +3 -3
  511. data/test/models/randomly_named_c1.rb +1 -1
  512. data/test/models/rating.rb +4 -4
  513. data/test/models/reader.rb +23 -23
  514. data/test/models/recipe.rb +3 -0
  515. data/test/models/record.rb +2 -2
  516. data/test/models/reference.rb +22 -22
  517. data/test/models/reply.rb +61 -61
  518. data/test/models/ship.rb +39 -33
  519. data/test/models/ship_part.rb +8 -8
  520. data/test/models/shop.rb +17 -17
  521. data/test/models/shop_account.rb +6 -6
  522. data/test/models/speedometer.rb +6 -6
  523. data/test/models/sponsor.rb +7 -7
  524. data/test/models/string_key_object.rb +3 -3
  525. data/test/models/student.rb +4 -4
  526. data/test/models/subject.rb +16 -16
  527. data/test/models/subscriber.rb +8 -8
  528. data/test/models/subscription.rb +4 -4
  529. data/test/models/tag.rb +13 -7
  530. data/test/models/tagging.rb +13 -13
  531. data/test/models/task.rb +5 -5
  532. data/test/models/topic.rb +118 -124
  533. data/test/models/toy.rb +6 -6
  534. data/test/models/traffic_light.rb +4 -4
  535. data/test/models/treasure.rb +14 -14
  536. data/test/models/treaty.rb +7 -7
  537. data/test/models/tree.rb +3 -0
  538. data/test/models/tuning_peg.rb +4 -0
  539. data/test/models/tyre.rb +11 -11
  540. data/test/models/user.rb +14 -0
  541. data/test/models/uuid_child.rb +3 -3
  542. data/test/models/uuid_item.rb +6 -0
  543. data/test/models/uuid_parent.rb +3 -3
  544. data/test/models/vegetables.rb +24 -24
  545. data/test/models/vehicle.rb +6 -6
  546. data/test/models/vertex.rb +9 -9
  547. data/test/models/warehouse_thing.rb +5 -5
  548. data/test/models/wheel.rb +3 -3
  549. data/test/models/without_table.rb +3 -3
  550. data/test/models/zine.rb +3 -3
  551. data/test/schema/mysql2_specific_schema.rb +68 -58
  552. data/test/schema/oracle_specific_schema.rb +40 -43
  553. data/test/schema/postgresql_specific_schema.rb +114 -202
  554. data/test/schema/schema.rb +1057 -952
  555. data/test/schema/schema.rb.original +1057 -0
  556. data/test/schema/sqlite_specific_schema.rb +18 -22
  557. data/test/support/config.rb +43 -43
  558. data/test/support/connection.rb +23 -22
  559. data/test/support/connection_helper.rb +14 -14
  560. data/test/support/ddl_helper.rb +8 -8
  561. data/test/support/schema_dumping_helper.rb +20 -20
  562. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
  563. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -0
  564. metadata +129 -24
  565. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +0 -26
  566. data/test/cases/attribute_methods/serialization_test.rb +0 -29
  567. data/test/cases/migration/change_schema_test - Copy.rb +0 -448
  568. data/test/cases/migration/foreign_key_test - Changed.rb +0 -325
  569. data/test/cases/migration/table_and_index_test.rb +0 -24
  570. data/test/cases/relation/where_test2.rb +0 -36
  571. data/test/cases/type/decimal_test.rb +0 -56
  572. data/test/cases/type/unsigned_integer_test.rb +0 -18
  573. data/test/cases/xml_serialization_test.rb +0 -457
  574. data/test/connections/native_ibm_db/connection.rb +0 -44
  575. data/test/fixtures/naked/csv/accounts.csv +0 -1
  576. data/test/schema/i5/ibm_db_specific_schema.rb +0 -137
  577. data/test/schema/ids/ibm_db_specific_schema.rb +0 -140
  578. data/test/schema/luw/ibm_db_specific_schema.rb +0 -137
  579. data/test/schema/mysql_specific_schema.rb +0 -70
  580. data/test/schema/zOS/ibm_db_specific_schema.rb +0 -208
@@ -0,0 +1,36 @@
1
+ require 'cases/helper'
2
+
3
+ class TestFixturesTest < ActiveRecord::TestCase
4
+ setup do
5
+ @klass = Class.new
6
+ @klass.send(:include, ActiveRecord::TestFixtures)
7
+ end
8
+
9
+ def test_deprecated_use_transactional_fixtures=
10
+ assert_deprecated 'use use_transactional_tests= instead' do
11
+ @klass.use_transactional_fixtures = true
12
+ end
13
+ end
14
+
15
+ def test_use_transactional_tests_prefers_use_transactional_fixtures
16
+ ActiveSupport::Deprecation.silence do
17
+ @klass.use_transactional_fixtures = false
18
+ end
19
+
20
+ assert_equal false, @klass.use_transactional_tests
21
+ end
22
+
23
+ def test_use_transactional_tests_defaults_to_true
24
+ ActiveSupport::Deprecation.silence do
25
+ @klass.use_transactional_fixtures = nil
26
+ end
27
+
28
+ assert_equal true, @klass.use_transactional_tests
29
+ end
30
+
31
+ def test_use_transactional_tests_can_be_overridden
32
+ @klass.use_transactional_tests = "foobar"
33
+
34
+ assert_equal "foobar", @klass.use_transactional_tests
35
+ end
36
+ end
@@ -0,0 +1,102 @@
1
+ require 'cases/helper'
2
+ require 'support/schema_dumping_helper'
3
+
4
+ if subsecond_precision_supported?
5
+ class TimePrecisionTest < ActiveRecord::TestCase
6
+ include SchemaDumpingHelper
7
+ self.use_transactional_tests = false
8
+
9
+ class Foo < ActiveRecord::Base; end
10
+
11
+ setup do
12
+ @connection = ActiveRecord::Base.connection
13
+ Foo.reset_column_information
14
+ end
15
+
16
+ teardown do
17
+ @connection.drop_table :foos, if_exists: true
18
+ end
19
+
20
+ def test_time_data_type_with_precision
21
+ @connection.create_table(:foos, force: true)
22
+ @connection.add_column :foos, :start, :time, precision: 3
23
+ @connection.add_column :foos, :finish, :time, precision: 6
24
+ assert_equal 3, Foo.columns_hash['start'].precision
25
+ assert_equal 6, Foo.columns_hash['finish'].precision
26
+ end
27
+
28
+ def test_time_precision_is_truncated_on_assignment
29
+ @connection.create_table(:foos, force: true)
30
+ @connection.add_column :foos, :start, :time, precision: 0
31
+ @connection.add_column :foos, :finish, :time, precision: 6
32
+
33
+ time = ::Time.now.change(nsec: 123456789)
34
+ foo = Foo.new(start: time, finish: time)
35
+
36
+ assert_equal 0, foo.start.nsec
37
+ assert_equal 123456000, foo.finish.nsec
38
+
39
+ foo.save!
40
+ foo.reload
41
+
42
+ assert_equal 0, foo.start.nsec
43
+ assert_equal 123456000, foo.finish.nsec
44
+ end
45
+
46
+ def test_passing_precision_to_time_does_not_set_limit
47
+ @connection.create_table(:foos, force: true) do |t|
48
+ t.time :start, precision: 3
49
+ t.time :finish, precision: 6
50
+ end
51
+ assert_nil Foo.columns_hash['start'].limit
52
+ assert_nil Foo.columns_hash['finish'].limit
53
+ end
54
+
55
+ def test_invalid_time_precision_raises_error
56
+ assert_raises ActiveRecord::ActiveRecordError do
57
+ @connection.create_table(:foos, force: true) do |t|
58
+ t.time :start, precision: 7
59
+ t.time :finish, precision: 7
60
+ end
61
+ end
62
+ end
63
+
64
+ def test_formatting_time_according_to_precision
65
+ @connection.create_table(:foos, force: true) do |t|
66
+ t.time :start, precision: 0
67
+ t.time :finish, precision: 4
68
+ end
69
+ time = ::Time.utc(2000, 1, 1, 12, 30, 0, 999999)
70
+ Foo.create!(start: time, finish: time)
71
+ assert foo = Foo.find_by(start: time)
72
+ assert_equal 1, Foo.where(finish: time).count
73
+ assert_equal time.to_s, foo.start.to_s
74
+ assert_equal time.to_s, foo.finish.to_s
75
+ assert_equal 000000, foo.start.usec
76
+ assert_equal 999900, foo.finish.usec
77
+ end
78
+
79
+ def test_schema_dump_includes_time_precision
80
+ @connection.create_table(:foos, force: true) do |t|
81
+ t.time :start, precision: 4
82
+ t.time :finish, precision: 6
83
+ end
84
+ output = dump_table_schema("foos")
85
+ assert_match %r{t\.time\s+"start",\s+precision: 4$}, output
86
+ assert_match %r{t\.time\s+"finish",\s+precision: 6$}, output
87
+ end
88
+
89
+ if current_adapter?(:PostgreSQLAdapter, :SQLServerAdapter)
90
+ def test_time_precision_with_zero_should_be_dumped
91
+ @connection.create_table(:foos, force: true) do |t|
92
+ t.time :start, precision: 0
93
+ t.time :finish, precision: 0
94
+ end
95
+ output = dump_table_schema("foos")
96
+ assert_match %r{t\.time\s+"start",\s+precision: 0$}, output
97
+ assert_match %r{t\.time\s+"finish",\s+precision: 0$}, output
98
+ end
99
+ end
100
+
101
+ end
102
+ end
@@ -1,467 +1,501 @@
1
- require 'cases/helper'
2
- require 'support/ddl_helper'
3
- require 'models/developer'
4
- require 'models/computer'
5
- require 'models/owner'
6
- require 'models/pet'
7
- require 'models/toy'
8
- require 'models/car'
9
- require 'models/task'
10
-
11
- class TimestampTest < ActiveRecord::TestCase
12
- fixtures :developers, :owners, :pets, :toys, :cars, :tasks
13
-
14
- def setup
15
- @developer = Developer.first
16
- @owner = Owner.first
17
- @developer.update_columns(updated_at: Time.now.prev_month)
18
- @previously_updated_at = @developer.updated_at
19
- end
20
-
21
- def test_saving_a_changed_record_updates_its_timestamp
22
- @developer.name = "Jack Bauer"
23
- @developer.save!
24
-
25
- assert_not_equal @previously_updated_at, @developer.updated_at
26
- end
27
-
28
- def test_saving_a_unchanged_record_doesnt_update_its_timestamp
29
- @developer.save!
30
-
31
- assert_equal @previously_updated_at, @developer.updated_at
32
- end
33
-
34
- def test_touching_a_record_updates_its_timestamp
35
- previous_salary = @developer.salary
36
- @developer.salary = previous_salary + 10000
37
- @developer.touch
38
-
39
- assert_not_equal @previously_updated_at, @developer.updated_at
40
- assert_equal previous_salary + 10000, @developer.salary
41
- assert @developer.salary_changed?, 'developer salary should have changed'
42
- assert @developer.changed?, 'developer should be marked as changed'
43
- @developer.reload
44
- assert_equal previous_salary, @developer.salary
45
- end
46
-
47
- def test_touching_a_record_with_default_scope_that_excludes_it_updates_its_timestamp
48
- developer = @developer.becomes(DeveloperCalledJamis)
49
-
50
- developer.touch
51
- assert_not_equal @previously_updated_at, developer.updated_at
52
- developer.reload
53
- assert_not_equal @previously_updated_at, developer.updated_at
54
- end
55
-
56
- def test_saving_when_record_timestamps_is_false_doesnt_update_its_timestamp
57
- Developer.record_timestamps = false
58
- @developer.name = "John Smith"
59
- @developer.save!
60
-
61
- assert_equal @previously_updated_at, @developer.updated_at
62
- ensure
63
- Developer.record_timestamps = true
64
- end
65
-
66
- def test_saving_when_instance_record_timestamps_is_false_doesnt_update_its_timestamp
67
- @developer.record_timestamps = false
68
- assert Developer.record_timestamps
69
-
70
- @developer.name = "John Smith"
71
- @developer.save!
72
-
73
- assert_equal @previously_updated_at, @developer.updated_at
74
- end
75
-
76
- def test_touching_an_attribute_updates_timestamp
77
- previously_created_at = @developer.created_at
78
- @developer.touch(:created_at)
79
-
80
- assert !@developer.created_at_changed? , 'created_at should not be changed'
81
- assert !@developer.changed?, 'record should not be changed'
82
- assert_not_equal previously_created_at, @developer.created_at
83
- assert_not_equal @previously_updated_at, @developer.updated_at
84
- end
85
-
86
- def test_touching_an_attribute_updates_it
87
- task = Task.first
88
- previous_value = task.ending
89
- task.touch(:ending)
90
- assert_not_equal previous_value, task.ending
91
- assert_in_delta Time.now, task.ending, 1
92
- end
93
-
94
- def test_touching_many_attributes_updates_them
95
- task = Task.first
96
- previous_starting = task.starting
97
- previous_ending = task.ending
98
- task.touch(:starting, :ending)
99
-
100
- assert_not_equal previous_starting, task.starting
101
- assert_not_equal previous_ending, task.ending
102
- assert_in_delta Time.now, task.starting, 1
103
- assert_in_delta Time.now, task.ending, 1
104
- end
105
-
106
- def test_touching_a_record_without_timestamps_is_unexceptional
107
- assert_nothing_raised { Car.first.touch }
108
- end
109
-
110
- def test_touching_a_no_touching_object
111
- Developer.no_touching do
112
- assert @developer.no_touching?
113
- assert !@owner.no_touching?
114
- @developer.touch
115
- end
116
-
117
- assert !@developer.no_touching?
118
- assert !@owner.no_touching?
119
- assert_equal @previously_updated_at, @developer.updated_at
120
- end
121
-
122
- def test_touching_related_objects
123
- @owner = Owner.first
124
- @previously_updated_at = @owner.updated_at
125
-
126
- Owner.no_touching do
127
- @owner.pets.first.touch
128
- end
129
-
130
- assert_equal @previously_updated_at, @owner.updated_at
131
- end
132
-
133
- def test_global_no_touching
134
- ActiveRecord::Base.no_touching do
135
- assert @developer.no_touching?
136
- assert @owner.no_touching?
137
- @developer.touch
138
- end
139
-
140
- assert !@developer.no_touching?
141
- assert !@owner.no_touching?
142
- assert_equal @previously_updated_at, @developer.updated_at
143
- end
144
-
145
- def test_no_touching_threadsafe
146
- Thread.new do
147
- Developer.no_touching do
148
- assert @developer.no_touching?
149
-
150
- sleep(1)
151
- end
152
- end
153
-
154
- assert !@developer.no_touching?
155
- end
156
-
157
- def test_no_touching_with_callbacks
158
- klass = Class.new(ActiveRecord::Base) do
159
- self.table_name = "developers"
160
-
161
- attr_accessor :after_touch_called
162
-
163
- after_touch do |user|
164
- user.after_touch_called = true
165
- end
166
- end
167
-
168
- developer = klass.first
169
-
170
- klass.no_touching do
171
- developer.touch
172
- assert_not developer.after_touch_called
173
- end
174
- end
175
-
176
- def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_update_the_parent_updated_at
177
- pet = Pet.first
178
- owner = pet.owner
179
- previously_owner_updated_at = owner.updated_at
180
-
181
- pet.name = "Fluffy the Third"
182
- pet.save
183
-
184
- assert_not_equal previously_owner_updated_at, pet.owner.updated_at
185
- end
186
-
187
- def test_destroying_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_update_the_parent_updated_at
188
- pet = Pet.first
189
- owner = pet.owner
190
- previously_owner_updated_at = owner.updated_at
191
-
192
- pet.destroy
193
-
194
- assert_not_equal previously_owner_updated_at, pet.owner.updated_at
195
- end
196
-
197
- def test_saving_a_new_record_belonging_to_invalid_parent_with_touch_should_not_raise_exception
198
- klass = Class.new(Owner) do
199
- def self.name; 'Owner'; end
200
- validate { errors.add(:base, :invalid) }
201
- end
202
-
203
- pet = Pet.new(owner: klass.new)
204
- pet.save!
205
-
206
- assert pet.owner.new_record?
207
- end
208
-
209
- def test_saving_a_record_with_a_belongs_to_that_specifies_touching_a_specific_attribute_the_parent_should_update_that_attribute
210
- klass = Class.new(ActiveRecord::Base) do
211
- def self.name; 'Pet'; end
212
- belongs_to :owner, :touch => :happy_at
213
- end
214
-
215
- pet = klass.first
216
- owner = pet.owner
217
- previously_owner_happy_at = owner.happy_at
218
-
219
- pet.name = "Fluffy the Third"
220
- pet.save
221
-
222
- assert_not_equal previously_owner_happy_at, pet.owner.happy_at
223
- end
224
-
225
- def test_touching_a_record_with_a_belongs_to_that_uses_a_counter_cache_should_update_the_parent
226
- klass = Class.new(ActiveRecord::Base) do
227
- def self.name; 'Pet'; end
228
- belongs_to :owner, :counter_cache => :use_count, :touch => true
229
- end
230
-
231
- pet = klass.first
232
- owner = pet.owner
233
- owner.update_columns(happy_at: 3.days.ago)
234
- previously_owner_updated_at = owner.updated_at
235
-
236
- pet.name = "I'm a parrot"
237
- pet.save
238
-
239
- assert_not_equal previously_owner_updated_at, pet.owner.updated_at
240
- end
241
-
242
- def test_touching_a_record_touches_parent_record_and_grandparent_record
243
- klass = Class.new(ActiveRecord::Base) do
244
- def self.name; 'Toy'; end
245
- belongs_to :pet, :touch => true
246
- end
247
-
248
- toy = klass.first
249
- pet = toy.pet
250
- owner = pet.owner
251
- time = 3.days.ago
252
-
253
- owner.update_columns(updated_at: time)
254
- toy.touch
255
- owner.reload
256
-
257
- assert_not_equal time, owner.updated_at
258
- end
259
-
260
- def test_touching_a_record_touches_polymorphic_record
261
- klass = Class.new(ActiveRecord::Base) do
262
- def self.name; 'Toy'; end
263
- end
264
-
265
- wheel_klass = Class.new(ActiveRecord::Base) do
266
- def self.name; 'Wheel'; end
267
- belongs_to :wheelable, :polymorphic => true, :touch => true
268
- end
269
-
270
- toy = klass.first
271
- time = 3.days.ago
272
- toy.update_columns(updated_at: time)
273
-
274
- wheel = wheel_klass.new
275
- wheel.wheelable = toy
276
- wheel.save
277
- wheel.touch
278
-
279
- assert_not_equal time, toy.updated_at
280
- end
281
-
282
- def test_changing_parent_of_a_record_touches_both_new_and_old_parent_record
283
- klass = Class.new(ActiveRecord::Base) do
284
- def self.name; 'Toy'; end
285
- belongs_to :pet, touch: true
286
- end
287
-
288
- toy1 = klass.find(1)
289
- old_pet = toy1.pet
290
-
291
- toy2 = klass.find(2)
292
- new_pet = toy2.pet
293
- time = 3.days.ago.at_beginning_of_hour
294
-
295
- old_pet.update_columns(updated_at: time)
296
- new_pet.update_columns(updated_at: time)
297
-
298
- toy1.pet = new_pet
299
- toy1.save!
300
-
301
- old_pet.reload
302
- new_pet.reload
303
-
304
- assert_not_equal time, new_pet.updated_at
305
- assert_not_equal time, old_pet.updated_at
306
- end
307
-
308
- def test_changing_parent_of_a_record_touches_both_new_and_old_polymorphic_parent_record_changes_within_same_class
309
- car_class = Class.new(ActiveRecord::Base) do
310
- def self.name; 'Car'; end
311
- end
312
-
313
- wheel_class = Class.new(ActiveRecord::Base) do
314
- def self.name; 'Wheel'; end
315
- belongs_to :wheelable, :polymorphic => true, :touch => true
316
- end
317
-
318
- car1 = car_class.find(1)
319
- car2 = car_class.find(2)
320
-
321
- wheel = wheel_class.create!(wheelable: car1)
322
-
323
- time = 3.days.ago.at_beginning_of_hour
324
-
325
- car1.update_columns(updated_at: time)
326
- car2.update_columns(updated_at: time)
327
-
328
- wheel.wheelable = car2
329
- wheel.save!
330
-
331
- assert_not_equal time, car1.reload.updated_at
332
- assert_not_equal time, car2.reload.updated_at
333
- end
334
-
335
- def test_changing_parent_of_a_record_touches_both_new_and_old_polymorphic_parent_record_changes_with_other_class
336
- car_class = Class.new(ActiveRecord::Base) do
337
- def self.name; 'Car'; end
338
- end
339
-
340
- toy_class = Class.new(ActiveRecord::Base) do
341
- def self.name; 'Toy'; end
342
- end
343
-
344
- wheel_class = Class.new(ActiveRecord::Base) do
345
- def self.name; 'Wheel'; end
346
- belongs_to :wheelable, :polymorphic => true, :touch => true
347
- end
348
-
349
- car = car_class.find(1)
350
- toy = toy_class.find(3)
351
-
352
- wheel = wheel_class.create!(wheelable: car)
353
-
354
- time = 3.days.ago.at_beginning_of_hour
355
-
356
- car.update_columns(updated_at: time)
357
- toy.update_columns(updated_at: time)
358
-
359
- wheel.wheelable = toy
360
- wheel.save!
361
-
362
- assert_not_equal time, car.reload.updated_at
363
- assert_not_equal time, toy.reload.updated_at
364
- end
365
-
366
- def test_clearing_association_touches_the_old_record
367
- klass = Class.new(ActiveRecord::Base) do
368
- def self.name; 'Toy'; end
369
- belongs_to :pet, touch: true
370
- end
371
-
372
- toy = klass.find(1)
373
- pet = toy.pet
374
- time = 3.days.ago.at_beginning_of_hour
375
-
376
- pet.update_columns(updated_at: time)
377
-
378
- toy.pet = nil
379
- toy.save!
380
-
381
- pet.reload
382
-
383
- assert_not_equal time, pet.updated_at
384
- end
385
-
386
- def test_timestamp_column_values_are_present_in_the_callbacks
387
- klass = Class.new(ActiveRecord::Base) do
388
- self.table_name = 'people'
389
-
390
- before_create do
391
- self.born_at = self.created_at
392
- end
393
- end
394
-
395
- person = klass.create first_name: 'David'
396
- assert_not_equal person.born_at, nil
397
- end
398
-
399
- def test_timestamp_attributes_for_create
400
- toy = Toy.first
401
- assert_equal [:created_at, :created_on], toy.send(:timestamp_attributes_for_create)
402
- end
403
-
404
- def test_timestamp_attributes_for_update
405
- toy = Toy.first
406
- assert_equal [:updated_at, :updated_on], toy.send(:timestamp_attributes_for_update)
407
- end
408
-
409
- def test_all_timestamp_attributes
410
- toy = Toy.first
411
- assert_equal [:created_at, :created_on, :updated_at, :updated_on], toy.send(:all_timestamp_attributes)
412
- end
413
-
414
- def test_timestamp_attributes_for_create_in_model
415
- toy = Toy.first
416
- assert_equal [:created_at], toy.send(:timestamp_attributes_for_create_in_model)
417
- end
418
-
419
- def test_timestamp_attributes_for_update_in_model
420
- toy = Toy.first
421
- assert_equal [:updated_at], toy.send(:timestamp_attributes_for_update_in_model)
422
- end
423
-
424
- def test_all_timestamp_attributes_in_model
425
- toy = Toy.first
426
- assert_equal [:created_at, :updated_at], toy.send(:all_timestamp_attributes_in_model)
427
- end
428
-
429
- def test_index_is_created_for_both_timestamps
430
- ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
431
- t.timestamps(:foos, null: true, index: true)
432
- end
433
-
434
- indexes = ActiveRecord::Base.connection.indexes('foos')
435
- assert_equal ['created_at', 'updated_at'], indexes.flat_map(&:columns).sort
436
- ensure
437
- ActiveRecord::Base.connection.drop_table(:foos)
438
- end
439
- end
440
-
441
- class TimestampsWithoutTransactionTest < ActiveRecord::TestCase
442
- include DdlHelper
443
- self.use_transactional_fixtures = false
444
-
445
- class TimestampAttributePost < ActiveRecord::Base
446
- attr_accessor :created_at, :updated_at
447
- end
448
-
449
- def test_do_not_write_timestamps_on_save_if_they_are_not_attributes
450
- if current_adapter?(:IBM_DBAdapter)
451
- ActiveRecord::Base.connection.create_table :timestamp_attribute_posts, force: true, id: false do |t|
452
- t.primary_key :id
453
- end
454
- post = TimestampAttributePost.new(id: 1)
455
- post.save! # should not try to assign and persist created_at, updated_at
456
- assert_nil post.created_at
457
- assert_nil post.updated_at
458
- else
459
- with_example_table ActiveRecord::Base.connection, "timestamp_attribute_posts", "id integer primary key" do
460
- post = TimestampAttributePost.new(id: 1)
461
- post.save! # should not try to assign and persist created_at, updated_at
462
- assert_nil post.created_at
463
- assert_nil post.updated_at
464
- end
465
- end
466
- end
467
- end
1
+ require 'cases/helper'
2
+ require 'support/ddl_helper'
3
+ require 'models/developer'
4
+ require 'models/computer'
5
+ require 'models/owner'
6
+ require 'models/pet'
7
+ require 'models/toy'
8
+ require 'models/car'
9
+ require 'models/task'
10
+
11
+ class TimestampTest < ActiveRecord::TestCase
12
+ fixtures :developers, :owners, :pets, :toys, :cars, :tasks
13
+
14
+ def setup
15
+ @developer = Developer.first
16
+ @owner = Owner.first
17
+ @developer.update_columns(updated_at: Time.now.prev_month)
18
+ @previously_updated_at = @developer.updated_at
19
+ end
20
+
21
+ def test_saving_a_changed_record_updates_its_timestamp
22
+ @developer.name = "Jack Bauer"
23
+ @developer.save!
24
+
25
+ assert_not_equal @previously_updated_at, @developer.updated_at
26
+ end
27
+
28
+ def test_saving_a_unchanged_record_doesnt_update_its_timestamp
29
+ @developer.save!
30
+
31
+ assert_equal @previously_updated_at, @developer.updated_at
32
+ end
33
+
34
+ def test_touching_a_record_updates_its_timestamp
35
+ previous_salary = @developer.salary
36
+ @developer.salary = previous_salary + 10000
37
+ @developer.touch
38
+
39
+ assert_not_equal @previously_updated_at, @developer.updated_at
40
+ assert_equal previous_salary + 10000, @developer.salary
41
+ assert @developer.salary_changed?, 'developer salary should have changed'
42
+ assert @developer.changed?, 'developer should be marked as changed'
43
+ @developer.reload
44
+ assert_equal previous_salary, @developer.salary
45
+ end
46
+
47
+ def test_touching_a_record_with_default_scope_that_excludes_it_updates_its_timestamp
48
+ developer = @developer.becomes(DeveloperCalledJamis)
49
+
50
+ developer.touch
51
+ assert_not_equal @previously_updated_at, developer.updated_at
52
+ developer.reload
53
+ assert_not_equal @previously_updated_at, developer.updated_at
54
+ end
55
+
56
+ def test_saving_when_record_timestamps_is_false_doesnt_update_its_timestamp
57
+ Developer.record_timestamps = false
58
+ @developer.name = "John Smith"
59
+ @developer.save!
60
+
61
+ assert_equal @previously_updated_at, @developer.updated_at
62
+ ensure
63
+ Developer.record_timestamps = true
64
+ end
65
+
66
+ def test_saving_when_instance_record_timestamps_is_false_doesnt_update_its_timestamp
67
+ @developer.record_timestamps = false
68
+ assert Developer.record_timestamps
69
+
70
+ @developer.name = "John Smith"
71
+ @developer.save!
72
+
73
+ assert_equal @previously_updated_at, @developer.updated_at
74
+ end
75
+
76
+ def test_touching_updates_timestamp_with_given_time
77
+ previously_updated_at = @developer.updated_at
78
+ new_time = Time.utc(2015, 2, 16, 0, 0, 0)
79
+ @developer.touch(time: new_time)
80
+
81
+ assert_not_equal previously_updated_at, @developer.updated_at
82
+ assert_equal new_time, @developer.updated_at
83
+ end
84
+
85
+ def test_touching_an_attribute_updates_timestamp
86
+ previously_created_at = @developer.created_at
87
+ travel(1.second) do
88
+ @developer.touch(:created_at)
89
+ end
90
+
91
+ assert !@developer.created_at_changed? , 'created_at should not be changed'
92
+ assert !@developer.changed?, 'record should not be changed'
93
+ assert_not_equal previously_created_at, @developer.created_at
94
+ assert_not_equal @previously_updated_at, @developer.updated_at
95
+ end
96
+
97
+ def test_touching_an_attribute_updates_it
98
+ task = Task.first
99
+ previous_value = task.ending
100
+ task.touch(:ending)
101
+
102
+ now = Time.now.change(usec: 0)
103
+
104
+ assert_not_equal previous_value, task.ending
105
+ assert_in_delta now, task.ending, 1
106
+ end
107
+
108
+ def test_touching_an_attribute_updates_timestamp_with_given_time
109
+ previously_updated_at = @developer.updated_at
110
+ previously_created_at = @developer.created_at
111
+ new_time = Time.utc(2015, 2, 16, 4, 54, 0)
112
+ @developer.touch(:created_at, time: new_time)
113
+
114
+ assert_not_equal previously_created_at, @developer.created_at
115
+ assert_not_equal previously_updated_at, @developer.updated_at
116
+ assert_equal new_time, @developer.created_at
117
+ assert_equal new_time, @developer.updated_at
118
+ end
119
+
120
+ def test_touching_many_attributes_updates_them
121
+ task = Task.first
122
+ previous_starting = task.starting
123
+ previous_ending = task.ending
124
+ task.touch(:starting, :ending)
125
+
126
+ now = Time.now.change(usec: 0)
127
+
128
+ assert_not_equal previous_starting, task.starting
129
+ assert_not_equal previous_ending, task.ending
130
+ assert_in_delta now, task.starting, 1
131
+ assert_in_delta now, task.ending, 1
132
+ end
133
+
134
+ def test_touching_a_record_without_timestamps_is_unexceptional
135
+ assert_nothing_raised { Car.first.touch }
136
+ end
137
+
138
+ def test_touching_a_no_touching_object
139
+ Developer.no_touching do
140
+ assert @developer.no_touching?
141
+ assert !@owner.no_touching?
142
+ @developer.touch
143
+ end
144
+
145
+ assert !@developer.no_touching?
146
+ assert !@owner.no_touching?
147
+ assert_equal @previously_updated_at, @developer.updated_at
148
+ end
149
+
150
+ def test_touching_related_objects
151
+ @owner = Owner.first
152
+ @previously_updated_at = @owner.updated_at
153
+
154
+ Owner.no_touching do
155
+ @owner.pets.first.touch
156
+ end
157
+
158
+ assert_equal @previously_updated_at, @owner.updated_at
159
+ end
160
+
161
+ def test_global_no_touching
162
+ ActiveRecord::Base.no_touching do
163
+ assert @developer.no_touching?
164
+ assert @owner.no_touching?
165
+ @developer.touch
166
+ end
167
+
168
+ assert !@developer.no_touching?
169
+ assert !@owner.no_touching?
170
+ assert_equal @previously_updated_at, @developer.updated_at
171
+ end
172
+
173
+ def test_no_touching_threadsafe
174
+ Thread.new do
175
+ Developer.no_touching do
176
+ assert @developer.no_touching?
177
+
178
+ sleep(1)
179
+ end
180
+ end
181
+
182
+ assert !@developer.no_touching?
183
+ end
184
+
185
+ def test_no_touching_with_callbacks
186
+ klass = Class.new(ActiveRecord::Base) do
187
+ self.table_name = "developers"
188
+
189
+ attr_accessor :after_touch_called
190
+
191
+ after_touch do |user|
192
+ user.after_touch_called = true
193
+ end
194
+ end
195
+
196
+ developer = klass.first
197
+
198
+ klass.no_touching do
199
+ developer.touch
200
+ assert_not developer.after_touch_called
201
+ end
202
+ end
203
+
204
+ def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_update_the_parent_updated_at
205
+ pet = Pet.first
206
+ owner = pet.owner
207
+ previously_owner_updated_at = owner.updated_at
208
+
209
+ travel(1.second) do
210
+ pet.name = "Fluffy the Third"
211
+ pet.save
212
+ end
213
+
214
+ assert_not_equal previously_owner_updated_at, pet.owner.updated_at
215
+ end
216
+
217
+ def test_destroying_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_update_the_parent_updated_at
218
+ pet = Pet.first
219
+ owner = pet.owner
220
+ previously_owner_updated_at = owner.updated_at
221
+
222
+ travel(1.second) do
223
+ pet.destroy
224
+ end
225
+
226
+ assert_not_equal previously_owner_updated_at, pet.owner.updated_at
227
+ end
228
+
229
+ def test_saving_a_new_record_belonging_to_invalid_parent_with_touch_should_not_raise_exception
230
+ klass = Class.new(Owner) do
231
+ def self.name; 'Owner'; end
232
+ validate { errors.add(:base, :invalid) }
233
+ end
234
+
235
+ pet = Pet.new(owner: klass.new)
236
+ pet.save!
237
+
238
+ assert pet.owner.new_record?
239
+ end
240
+
241
+ def test_saving_a_record_with_a_belongs_to_that_specifies_touching_a_specific_attribute_the_parent_should_update_that_attribute
242
+ klass = Class.new(ActiveRecord::Base) do
243
+ def self.name; 'Pet'; end
244
+ belongs_to :owner, :touch => :happy_at
245
+ end
246
+
247
+ pet = klass.first
248
+ owner = pet.owner
249
+ previously_owner_happy_at = owner.happy_at
250
+
251
+ pet.name = "Fluffy the Third"
252
+ pet.save
253
+
254
+ assert_not_equal previously_owner_happy_at, pet.owner.happy_at
255
+ end
256
+
257
+ def test_touching_a_record_with_a_belongs_to_that_uses_a_counter_cache_should_update_the_parent
258
+ klass = Class.new(ActiveRecord::Base) do
259
+ def self.name; 'Pet'; end
260
+ belongs_to :owner, :counter_cache => :use_count, :touch => true
261
+ end
262
+
263
+ pet = klass.first
264
+ owner = pet.owner
265
+ owner.update_columns(happy_at: 3.days.ago)
266
+ previously_owner_updated_at = owner.updated_at
267
+
268
+ travel(1.second) do
269
+ pet.name = "I'm a parrot"
270
+ pet.save
271
+ end
272
+
273
+ assert_not_equal previously_owner_updated_at, pet.owner.updated_at
274
+ end
275
+
276
+ def test_touching_a_record_touches_parent_record_and_grandparent_record
277
+ klass = Class.new(ActiveRecord::Base) do
278
+ def self.name; 'Toy'; end
279
+ belongs_to :pet, :touch => true
280
+ end
281
+
282
+ toy = klass.first
283
+ pet = toy.pet
284
+ owner = pet.owner
285
+ time = 3.days.ago
286
+
287
+ owner.update_columns(updated_at: time)
288
+ toy.touch
289
+ owner.reload
290
+
291
+ assert_not_equal time, owner.updated_at
292
+ end
293
+
294
+ def test_touching_a_record_touches_polymorphic_record
295
+ klass = Class.new(ActiveRecord::Base) do
296
+ def self.name; 'Toy'; end
297
+ end
298
+
299
+ wheel_klass = Class.new(ActiveRecord::Base) do
300
+ def self.name; 'Wheel'; end
301
+ belongs_to :wheelable, :polymorphic => true, :touch => true
302
+ end
303
+
304
+ toy = klass.first
305
+ time = 3.days.ago
306
+ toy.update_columns(updated_at: time)
307
+
308
+ wheel = wheel_klass.new
309
+ wheel.wheelable = toy
310
+ wheel.save
311
+ wheel.touch
312
+
313
+ assert_not_equal time, toy.updated_at
314
+ end
315
+
316
+ def test_changing_parent_of_a_record_touches_both_new_and_old_parent_record
317
+ klass = Class.new(ActiveRecord::Base) do
318
+ def self.name; 'Toy'; end
319
+ belongs_to :pet, touch: true
320
+ end
321
+
322
+ toy1 = klass.find(1)
323
+ old_pet = toy1.pet
324
+
325
+ toy2 = klass.find(2)
326
+ new_pet = toy2.pet
327
+ time = 3.days.ago.at_beginning_of_hour
328
+
329
+ old_pet.update_columns(updated_at: time)
330
+ new_pet.update_columns(updated_at: time)
331
+
332
+ toy1.pet = new_pet
333
+ toy1.save!
334
+
335
+ old_pet.reload
336
+ new_pet.reload
337
+
338
+ assert_not_equal time, new_pet.updated_at
339
+ assert_not_equal time, old_pet.updated_at
340
+ end
341
+
342
+ def test_changing_parent_of_a_record_touches_both_new_and_old_polymorphic_parent_record_changes_within_same_class
343
+ car_class = Class.new(ActiveRecord::Base) do
344
+ def self.name; 'Car'; end
345
+ end
346
+
347
+ wheel_class = Class.new(ActiveRecord::Base) do
348
+ def self.name; 'Wheel'; end
349
+ belongs_to :wheelable, :polymorphic => true, :touch => true
350
+ end
351
+
352
+ car1 = car_class.find(1)
353
+ car2 = car_class.find(2)
354
+
355
+ wheel = wheel_class.create!(wheelable: car1)
356
+
357
+ time = 3.days.ago.at_beginning_of_hour
358
+
359
+ car1.update_columns(updated_at: time)
360
+ car2.update_columns(updated_at: time)
361
+
362
+ wheel.wheelable = car2
363
+ wheel.save!
364
+
365
+ assert_not_equal time, car1.reload.updated_at
366
+ assert_not_equal time, car2.reload.updated_at
367
+ end
368
+
369
+ def test_changing_parent_of_a_record_touches_both_new_and_old_polymorphic_parent_record_changes_with_other_class
370
+ car_class = Class.new(ActiveRecord::Base) do
371
+ def self.name; 'Car'; end
372
+ end
373
+
374
+ toy_class = Class.new(ActiveRecord::Base) do
375
+ def self.name; 'Toy'; end
376
+ end
377
+
378
+ wheel_class = Class.new(ActiveRecord::Base) do
379
+ def self.name; 'Wheel'; end
380
+ belongs_to :wheelable, :polymorphic => true, :touch => true
381
+ end
382
+
383
+ car = car_class.find(1)
384
+ toy = toy_class.find(3)
385
+
386
+ wheel = wheel_class.create!(wheelable: car)
387
+
388
+ time = 3.days.ago.at_beginning_of_hour
389
+
390
+ car.update_columns(updated_at: time)
391
+ toy.update_columns(updated_at: time)
392
+
393
+ wheel.wheelable = toy
394
+ wheel.save!
395
+
396
+ assert_not_equal time, car.reload.updated_at
397
+ assert_not_equal time, toy.reload.updated_at
398
+ end
399
+
400
+ def test_clearing_association_touches_the_old_record
401
+ klass = Class.new(ActiveRecord::Base) do
402
+ def self.name; 'Toy'; end
403
+ belongs_to :pet, touch: true
404
+ end
405
+
406
+ toy = klass.find(1)
407
+ pet = toy.pet
408
+ time = 3.days.ago.at_beginning_of_hour
409
+
410
+ pet.update_columns(updated_at: time)
411
+
412
+ toy.pet = nil
413
+ toy.save!
414
+
415
+ pet.reload
416
+
417
+ assert_not_equal time, pet.updated_at
418
+ end
419
+
420
+ def test_timestamp_column_values_are_present_in_the_callbacks
421
+ klass = Class.new(ActiveRecord::Base) do
422
+ self.table_name = 'people'
423
+
424
+ before_create do
425
+ self.born_at = self.created_at
426
+ end
427
+ end
428
+
429
+ person = klass.create first_name: 'David'
430
+ assert_not_equal person.born_at, nil
431
+ end
432
+
433
+ def test_timestamp_attributes_for_create
434
+ toy = Toy.first
435
+ assert_equal [:created_at, :created_on], toy.send(:timestamp_attributes_for_create)
436
+ end
437
+
438
+ def test_timestamp_attributes_for_update
439
+ toy = Toy.first
440
+ assert_equal [:updated_at, :updated_on], toy.send(:timestamp_attributes_for_update)
441
+ end
442
+
443
+ def test_all_timestamp_attributes
444
+ toy = Toy.first
445
+ assert_equal [:created_at, :created_on, :updated_at, :updated_on], toy.send(:all_timestamp_attributes)
446
+ end
447
+
448
+ def test_timestamp_attributes_for_create_in_model
449
+ toy = Toy.first
450
+ assert_equal [:created_at], toy.send(:timestamp_attributes_for_create_in_model)
451
+ end
452
+
453
+ def test_timestamp_attributes_for_update_in_model
454
+ toy = Toy.first
455
+ assert_equal [:updated_at], toy.send(:timestamp_attributes_for_update_in_model)
456
+ end
457
+
458
+ def test_all_timestamp_attributes_in_model
459
+ toy = Toy.first
460
+ assert_equal [:created_at, :updated_at], toy.send(:all_timestamp_attributes_in_model)
461
+ end
462
+
463
+ def test_index_is_created_for_both_timestamps
464
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
465
+ t.timestamps(:foos, null: true, index: true)
466
+ end
467
+
468
+ indexes = ActiveRecord::Base.connection.indexes('foos')
469
+ assert_equal ['created_at', 'updated_at'], indexes.flat_map(&:columns).sort
470
+ ensure
471
+ ActiveRecord::Base.connection.drop_table(:foos)
472
+ end
473
+ end
474
+
475
+ class TimestampsWithoutTransactionTest < ActiveRecord::TestCase
476
+ include DdlHelper
477
+ self.use_transactional_tests = false
478
+
479
+ class TimestampAttributePost < ActiveRecord::Base
480
+ attr_accessor :created_at, :updated_at
481
+ end
482
+
483
+ def test_do_not_write_timestamps_on_save_if_they_are_not_attributes
484
+ if current_adapter?(:IBM_DBAdapter)
485
+ ActiveRecord::Base.connection.create_table :timestamp_attribute_posts, force: true, id: false do |t|
486
+ t.primary_key :id
487
+ end
488
+ post = TimestampAttributePost.new(id: 1)
489
+ post.save! # should not try to assign and persist created_at, updated_at
490
+ assert_nil post.created_at
491
+ assert_nil post.updated_at
492
+ else
493
+ with_example_table ActiveRecord::Base.connection, "timestamp_attribute_posts", "id integer primary key" do
494
+ post = TimestampAttributePost.new(id: 1)
495
+ post.save! # should not try to assign and persist created_at, updated_at
496
+ assert_nil post.created_at
497
+ assert_nil post.updated_at
498
+ end
499
+ end
500
+ end
501
+ end