ibm_db 5.6.1-arm64-darwin-24

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 (753) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +299 -0
  3. data/LICENSE +55 -0
  4. data/MANIFEST +14 -0
  5. data/ParameterizedQueries README +39 -0
  6. data/README +210 -0
  7. data/ext/Makefile +270 -0
  8. data/ext/Makefile.nt32 +181 -0
  9. data/ext/Makefile.nt32.191 +212 -0
  10. data/ext/extconf.rb +320 -0
  11. data/ext/gil_release_version.h +3 -0
  12. data/ext/ibm_db.bundle +0 -0
  13. data/ext/ibm_db.c +11865 -0
  14. data/ext/ibm_db.o +0 -0
  15. data/ext/mkmf.log +98 -0
  16. data/ext/ruby_ibm_db.h +241 -0
  17. data/ext/ruby_ibm_db_cli.c +867 -0
  18. data/ext/ruby_ibm_db_cli.h +508 -0
  19. data/ext/ruby_ibm_db_cli.o +0 -0
  20. data/ext/unicode_support_version.h +3 -0
  21. data/init.rb +42 -0
  22. data/lib/IBM_DB.rb +27 -0
  23. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +4407 -0
  24. data/lib/active_record/connection_adapters/ibm_db_pstmt.rb +1965 -0
  25. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +5 -0
  26. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -0
  27. data/lib/ibm_db.bundle +0 -0
  28. data/test/active_record/connection_adapters/fake_adapter.rb +52 -0
  29. data/test/activejob/destroy_association_async_test.rb +305 -0
  30. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  31. data/test/activejob/helper.rb +15 -0
  32. data/test/assets/example.log +1 -0
  33. data/test/assets/flowers.jpg +0 -0
  34. data/test/assets/schema_dump_5_1.yml +345 -0
  35. data/test/assets/test.txt +1 -0
  36. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  37. data/test/cases/adapter_test.rb +565 -0
  38. data/test/cases/adapters/mysql2/active_schema_test.rb +203 -0
  39. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  40. data/test/cases/adapters/mysql2/bind_parameter_test.rb +52 -0
  41. data/test/cases/adapters/mysql2/boolean_test.rb +102 -0
  42. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +65 -0
  43. data/test/cases/adapters/mysql2/charset_collation_test.rb +57 -0
  44. data/test/cases/adapters/mysql2/connection_test.rb +208 -0
  45. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  46. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +49 -0
  47. data/test/cases/adapters/mysql2/enum_test.rb +47 -0
  48. data/test/cases/adapters/mysql2/explain_test.rb +23 -0
  49. data/test/cases/adapters/mysql2/json_test.rb +24 -0
  50. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  51. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +238 -0
  52. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  53. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  54. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -0
  55. data/test/cases/adapters/mysql2/schema_migrations_test.rb +64 -0
  56. data/test/cases/adapters/mysql2/schema_test.rb +128 -0
  57. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  58. data/test/cases/adapters/mysql2/sp_test.rb +38 -0
  59. data/test/cases/adapters/mysql2/sql_types_test.rb +16 -0
  60. data/test/cases/adapters/mysql2/table_options_test.rb +125 -0
  61. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  62. data/test/cases/adapters/mysql2/unsigned_type_test.rb +68 -0
  63. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  64. data/test/cases/adapters/postgresql/active_schema_test.rb +113 -0
  65. data/test/cases/adapters/postgresql/array_test.rb +394 -0
  66. data/test/cases/adapters/postgresql/bit_string_test.rb +84 -0
  67. data/test/cases/adapters/postgresql/bytea_test.rb +135 -0
  68. data/test/cases/adapters/postgresql/case_insensitive_test.rb +27 -0
  69. data/test/cases/adapters/postgresql/change_schema_test.rb +40 -0
  70. data/test/cases/adapters/postgresql/cidr_test.rb +27 -0
  71. data/test/cases/adapters/postgresql/citext_test.rb +78 -0
  72. data/test/cases/adapters/postgresql/collation_test.rb +55 -0
  73. data/test/cases/adapters/postgresql/composite_test.rb +134 -0
  74. data/test/cases/adapters/postgresql/connection_test.rb +245 -0
  75. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  76. data/test/cases/adapters/postgresql/datatype_test.rb +89 -0
  77. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  78. data/test/cases/adapters/postgresql/domain_test.rb +49 -0
  79. data/test/cases/adapters/postgresql/enum_test.rb +93 -0
  80. data/test/cases/adapters/postgresql/explain_test.rb +22 -0
  81. data/test/cases/adapters/postgresql/extension_migration_test.rb +64 -0
  82. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  83. data/test/cases/adapters/postgresql/full_text_test.rb +46 -0
  84. data/test/cases/adapters/postgresql/geometric_test.rb +372 -0
  85. data/test/cases/adapters/postgresql/hstore_test.rb +390 -0
  86. data/test/cases/adapters/postgresql/infinity_test.rb +108 -0
  87. data/test/cases/adapters/postgresql/integer_test.rb +27 -0
  88. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  89. data/test/cases/adapters/postgresql/json_test.rb +52 -0
  90. data/test/cases/adapters/postgresql/ltree_test.rb +51 -0
  91. data/test/cases/adapters/postgresql/money_test.rb +127 -0
  92. data/test/cases/adapters/postgresql/network_test.rb +102 -0
  93. data/test/cases/adapters/postgresql/numbers_test.rb +51 -0
  94. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  95. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  96. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  97. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +447 -0
  98. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  99. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
  100. data/test/cases/adapters/postgresql/quoting_test.rb +50 -0
  101. data/test/cases/adapters/postgresql/range_test.rb +457 -0
  102. data/test/cases/adapters/postgresql/referential_integrity_test.rb +112 -0
  103. data/test/cases/adapters/postgresql/rename_table_test.rb +35 -0
  104. data/test/cases/adapters/postgresql/schema_authorization_test.rb +110 -0
  105. data/test/cases/adapters/postgresql/schema_test.rb +713 -0
  106. data/test/cases/adapters/postgresql/serial_test.rb +156 -0
  107. data/test/cases/adapters/postgresql/statement_pool_test.rb +61 -0
  108. data/test/cases/adapters/postgresql/timestamp_test.rb +92 -0
  109. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  110. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  111. data/test/cases/adapters/postgresql/type_lookup_test.rb +35 -0
  112. data/test/cases/adapters/postgresql/utils_test.rb +64 -0
  113. data/test/cases/adapters/postgresql/uuid_test.rb +411 -0
  114. data/test/cases/adapters/postgresql/xml_test.rb +50 -0
  115. data/test/cases/adapters/sqlite3/collation_test.rb +64 -0
  116. data/test/cases/adapters/sqlite3/copy_table_test.rb +101 -0
  117. data/test/cases/adapters/sqlite3/explain_test.rb +23 -0
  118. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  119. data/test/cases/adapters/sqlite3/quoting_test.rb +79 -0
  120. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  121. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +628 -0
  122. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -0
  123. data/test/cases/adapters/sqlite3/statement_pool_test.rb +21 -0
  124. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  125. data/test/cases/aggregations_test.rb +170 -0
  126. data/test/cases/annotate_test.rb +46 -0
  127. data/test/cases/ar_schema_test.rb +213 -0
  128. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  129. data/test/cases/arel/attributes/math_test.rb +83 -0
  130. data/test/cases/arel/attributes_test.rb +27 -0
  131. data/test/cases/arel/collectors/bind_test.rb +40 -0
  132. data/test/cases/arel/collectors/composite_test.rb +47 -0
  133. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  134. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  135. data/test/cases/arel/crud_test.rb +65 -0
  136. data/test/cases/arel/delete_manager_test.rb +53 -0
  137. data/test/cases/arel/factory_methods_test.rb +46 -0
  138. data/test/cases/arel/helper.rb +45 -0
  139. data/test/cases/arel/insert_manager_test.rb +241 -0
  140. data/test/cases/arel/nodes/and_test.rb +30 -0
  141. data/test/cases/arel/nodes/as_test.rb +36 -0
  142. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  143. data/test/cases/arel/nodes/bin_test.rb +35 -0
  144. data/test/cases/arel/nodes/binary_test.rb +29 -0
  145. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  146. data/test/cases/arel/nodes/case_test.rb +96 -0
  147. data/test/cases/arel/nodes/casted_test.rb +18 -0
  148. data/test/cases/arel/nodes/comment_test.rb +22 -0
  149. data/test/cases/arel/nodes/count_test.rb +35 -0
  150. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  151. data/test/cases/arel/nodes/descending_test.rb +46 -0
  152. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  153. data/test/cases/arel/nodes/equality_test.rb +62 -0
  154. data/test/cases/arel/nodes/extract_test.rb +43 -0
  155. data/test/cases/arel/nodes/false_test.rb +21 -0
  156. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  157. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  158. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  159. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  160. data/test/cases/arel/nodes/node_test.rb +22 -0
  161. data/test/cases/arel/nodes/not_test.rb +31 -0
  162. data/test/cases/arel/nodes/or_test.rb +36 -0
  163. data/test/cases/arel/nodes/over_test.rb +69 -0
  164. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  165. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  166. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  167. data/test/cases/arel/nodes/sum_test.rb +35 -0
  168. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  169. data/test/cases/arel/nodes/true_test.rb +21 -0
  170. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  171. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  172. data/test/cases/arel/nodes/window_test.rb +81 -0
  173. data/test/cases/arel/nodes_test.rb +34 -0
  174. data/test/cases/arel/select_manager_test.rb +1238 -0
  175. data/test/cases/arel/support/fake_record.rb +135 -0
  176. data/test/cases/arel/table_test.rb +216 -0
  177. data/test/cases/arel/update_manager_test.rb +126 -0
  178. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  179. data/test/cases/arel/visitors/dot_test.rb +90 -0
  180. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  181. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  182. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  183. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  184. data/test/cases/associations/association_scope_test.rb +16 -0
  185. data/test/cases/associations/belongs_to_associations_test.rb +1493 -0
  186. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +43 -0
  187. data/test/cases/associations/callbacks_test.rb +208 -0
  188. data/test/cases/associations/cascaded_eager_loading_test.rb +245 -0
  189. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +156 -0
  190. data/test/cases/associations/eager_load_nested_include_test.rb +127 -0
  191. data/test/cases/associations/eager_singularization_test.rb +148 -0
  192. data/test/cases/associations/eager_test.rb +1658 -0
  193. data/test/cases/associations/extension_test.rb +93 -0
  194. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +1025 -0
  195. data/test/cases/associations/has_many_associations_test.rb +3074 -0
  196. data/test/cases/associations/has_many_through_associations_test.rb +1580 -0
  197. data/test/cases/associations/has_one_associations_test.rb +872 -0
  198. data/test/cases/associations/has_one_through_associations_test.rb +429 -0
  199. data/test/cases/associations/inner_join_association_test.rb +215 -0
  200. data/test/cases/associations/inverse_associations_test.rb +941 -0
  201. data/test/cases/associations/join_model_test.rb +787 -0
  202. data/test/cases/associations/left_outer_join_association_test.rb +123 -0
  203. data/test/cases/associations/nested_through_associations_test.rb +636 -0
  204. data/test/cases/associations/required_test.rb +127 -0
  205. data/test/cases/associations_test.rb +516 -0
  206. data/test/cases/attribute_decorators_test.rb +126 -0
  207. data/test/cases/attribute_methods/read_test.rb +60 -0
  208. data/test/cases/attribute_methods_test.rb +1124 -0
  209. data/test/cases/attribute_set_test.rb +270 -0
  210. data/test/cases/attribute_test.rb +246 -0
  211. data/test/cases/attributes_test.rb +371 -0
  212. data/test/cases/autosave_association_test.rb +1953 -0
  213. data/test/cases/base_prevent_writes_test.rb +229 -0
  214. data/test/cases/base_test.rb +1770 -0
  215. data/test/cases/batches_test.rb +695 -0
  216. data/test/cases/binary_test.rb +39 -0
  217. data/test/cases/bind_parameter_test.rb +283 -0
  218. data/test/cases/boolean_test.rb +52 -0
  219. data/test/cases/cache_key_test.rb +131 -0
  220. data/test/cases/calculations_test.rb +1361 -0
  221. data/test/cases/callbacks_test.rb +503 -0
  222. data/test/cases/clone_test.rb +45 -0
  223. data/test/cases/coders/json_test.rb +17 -0
  224. data/test/cases/coders/yaml_column_test.rb +66 -0
  225. data/test/cases/collection_cache_key_test.rb +272 -0
  226. data/test/cases/column_alias_test.rb +19 -0
  227. data/test/cases/column_definition_test.rb +34 -0
  228. data/test/cases/comment_test.rb +204 -0
  229. data/test/cases/connection_adapters/adapter_leasing_test.rb +60 -0
  230. data/test/cases/connection_adapters/connection_handler_test.rb +467 -0
  231. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  232. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  233. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  234. data/test/cases/connection_adapters/connection_specification_test.rb +12 -0
  235. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  236. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  237. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  238. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +436 -0
  239. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +81 -0
  240. data/test/cases/connection_adapters/quoting_test.rb +13 -0
  241. data/test/cases/connection_adapters/schema_cache_test.rb +294 -0
  242. data/test/cases/connection_adapters/type_lookup_test.rb +119 -0
  243. data/test/cases/connection_management_test.rb +114 -0
  244. data/test/cases/connection_pool_test.rb +754 -0
  245. data/test/cases/connection_specification/resolver_test.rb +131 -0
  246. data/test/cases/core_test.rb +136 -0
  247. data/test/cases/counter_cache_test.rb +368 -0
  248. data/test/cases/custom_locking_test.rb +19 -0
  249. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  250. data/test/cases/database_configurations/resolver_test.rb +150 -0
  251. data/test/cases/database_configurations_test.rb +145 -0
  252. data/test/cases/database_selector_test.rb +296 -0
  253. data/test/cases/database_statements_test.rb +36 -0
  254. data/test/cases/date_test.rb +36 -0
  255. data/test/cases/date_time_precision_test.rb +129 -0
  256. data/test/cases/date_time_test.rb +76 -0
  257. data/test/cases/defaults_test.rb +254 -0
  258. data/test/cases/delegated_type_test.rb +57 -0
  259. data/test/cases/dirty_test.rb +959 -0
  260. data/test/cases/disconnected_test.rb +30 -0
  261. data/test/cases/dup_test.rb +184 -0
  262. data/test/cases/enum_test.rb +823 -0
  263. data/test/cases/errors_test.rb +16 -0
  264. data/test/cases/explain_subscriber_test.rb +66 -0
  265. data/test/cases/explain_test.rb +79 -0
  266. data/test/cases/filter_attributes_test.rb +153 -0
  267. data/test/cases/finder_respond_to_test.rb +60 -0
  268. data/test/cases/finder_test.rb +1676 -0
  269. data/test/cases/fixture_set/file_test.rb +152 -0
  270. data/test/cases/fixtures_test.rb +1645 -0
  271. data/test/cases/forbidden_attributes_protection_test.rb +130 -0
  272. data/test/cases/habtm_destroy_order_test.rb +61 -0
  273. data/test/cases/helper.rb +233 -0
  274. data/test/cases/hot_compatibility_test.rb +143 -0
  275. data/test/cases/i18n_test.rb +46 -0
  276. data/test/cases/inheritance_test.rb +671 -0
  277. data/test/cases/insert_all_test.rb +489 -0
  278. data/test/cases/instrumentation_test.rb +101 -0
  279. data/test/cases/integration_test.rb +243 -0
  280. data/test/cases/invalid_connection_test.rb +26 -0
  281. data/test/cases/invertible_migration_test.rb +527 -0
  282. data/test/cases/json_attribute_test.rb +35 -0
  283. data/test/cases/json_serialization_test.rb +310 -0
  284. data/test/cases/json_shared_test_cases.rb +290 -0
  285. data/test/cases/locking_test.rb +787 -0
  286. data/test/cases/log_subscriber_test.rb +267 -0
  287. data/test/cases/marshal_serialization_test.rb +39 -0
  288. data/test/cases/migration/change_schema_test.rb +504 -0
  289. data/test/cases/migration/change_table_test.rb +364 -0
  290. data/test/cases/migration/check_constraint_test.rb +162 -0
  291. data/test/cases/migration/column_attributes_test.rb +186 -0
  292. data/test/cases/migration/column_positioning_test.rb +68 -0
  293. data/test/cases/migration/columns_test.rb +326 -0
  294. data/test/cases/migration/command_recorder_test.rb +437 -0
  295. data/test/cases/migration/compatibility_test.rb +673 -0
  296. data/test/cases/migration/create_join_table_test.rb +167 -0
  297. data/test/cases/migration/foreign_key_test.rb +581 -0
  298. data/test/cases/migration/helper.rb +40 -0
  299. data/test/cases/migration/index_test.rb +267 -0
  300. data/test/cases/migration/logger_test.rb +39 -0
  301. data/test/cases/migration/pending_migrations_test.rb +106 -0
  302. data/test/cases/migration/references_foreign_key_test.rb +235 -0
  303. data/test/cases/migration/references_index_test.rb +120 -0
  304. data/test/cases/migration/references_statements_test.rb +137 -0
  305. data/test/cases/migration/rename_table_test.rb +116 -0
  306. data/test/cases/migration_test.rb +1525 -0
  307. data/test/cases/migrator_test.rb +527 -0
  308. data/test/cases/mixin_test.rb +64 -0
  309. data/test/cases/modules_test.rb +174 -0
  310. data/test/cases/multi_db_migrator_test.rb +223 -0
  311. data/test/cases/multiparameter_attributes_test.rb +399 -0
  312. data/test/cases/multiple_db_test.rb +116 -0
  313. data/test/cases/nested_attributes_test.rb +1119 -0
  314. data/test/cases/nested_attributes_with_callbacks_test.rb +146 -0
  315. data/test/cases/null_relation_test.rb +84 -0
  316. data/test/cases/numeric_data_test.rb +93 -0
  317. data/test/cases/persistence_test.rb +1093 -0
  318. data/test/cases/pooled_connections_test.rb +73 -0
  319. data/test/cases/prepared_statement_status_test.rb +48 -0
  320. data/test/cases/primary_keys_test.rb +482 -0
  321. data/test/cases/query_cache_test.rb +915 -0
  322. data/test/cases/quoting_test.rb +303 -0
  323. data/test/cases/readonly_test.rb +120 -0
  324. data/test/cases/reaper_test.rb +199 -0
  325. data/test/cases/reflection_test.rb +520 -0
  326. data/test/cases/relation/delegation_test.rb +76 -0
  327. data/test/cases/relation/delete_all_test.rb +117 -0
  328. data/test/cases/relation/merging_test.rb +434 -0
  329. data/test/cases/relation/mutation_test.rb +145 -0
  330. data/test/cases/relation/or_test.rb +192 -0
  331. data/test/cases/relation/predicate_builder_test.rb +31 -0
  332. data/test/cases/relation/record_fetch_warning_test.rb +42 -0
  333. data/test/cases/relation/select_test.rb +67 -0
  334. data/test/cases/relation/update_all_test.rb +317 -0
  335. data/test/cases/relation/where_chain_test.rb +141 -0
  336. data/test/cases/relation/where_clause_test.rb +257 -0
  337. data/test/cases/relation/where_test.rb +429 -0
  338. data/test/cases/relation_test.rb +482 -0
  339. data/test/cases/relations_test.rb +2251 -0
  340. data/test/cases/reload_models_test.rb +26 -0
  341. data/test/cases/reserved_word_test.rb +141 -0
  342. data/test/cases/result_test.rb +141 -0
  343. data/test/cases/sanitize_test.rb +192 -0
  344. data/test/cases/schema_dumper_test.rb +550 -0
  345. data/test/cases/schema_loading_test.rb +53 -0
  346. data/test/cases/scoping/default_scoping_test.rb +569 -0
  347. data/test/cases/scoping/named_scoping_test.rb +649 -0
  348. data/test/cases/scoping/relation_scoping_test.rb +522 -0
  349. data/test/cases/secure_token_test.rb +47 -0
  350. data/test/cases/serialization_test.rb +106 -0
  351. data/test/cases/serialized_attribute_test.rb +455 -0
  352. data/test/cases/signed_id_test.rb +168 -0
  353. data/test/cases/statement_cache_test.rb +153 -0
  354. data/test/cases/statement_invalid_test.rb +42 -0
  355. data/test/cases/store_test.rb +320 -0
  356. data/test/cases/strict_loading_test.rb +473 -0
  357. data/test/cases/suppressor_test.rb +77 -0
  358. data/test/cases/tasks/database_tasks_test.rb +1526 -0
  359. data/test/cases/tasks/mysql_rake_test.rb +417 -0
  360. data/test/cases/tasks/postgresql_rake_test.rb +534 -0
  361. data/test/cases/tasks/sqlite_rake_test.rb +267 -0
  362. data/test/cases/test_case.rb +142 -0
  363. data/test/cases/test_databases_test.rb +79 -0
  364. data/test/cases/test_fixtures_test.rb +96 -0
  365. data/test/cases/time_precision_test.rb +125 -0
  366. data/test/cases/timestamp_test.rb +504 -0
  367. data/test/cases/touch_later_test.rb +123 -0
  368. data/test/cases/transaction_callbacks_test.rb +772 -0
  369. data/test/cases/transaction_isolation_test.rb +106 -0
  370. data/test/cases/transactions_test.rb +1285 -0
  371. data/test/cases/type/adapter_specific_registry_test.rb +145 -0
  372. data/test/cases/type/date_time_test.rb +16 -0
  373. data/test/cases/type/integer_test.rb +29 -0
  374. data/test/cases/type/string_test.rb +24 -0
  375. data/test/cases/type/time_test.rb +28 -0
  376. data/test/cases/type/type_map_test.rb +178 -0
  377. data/test/cases/type/unsigned_integer_test.rb +19 -0
  378. data/test/cases/type_test.rb +41 -0
  379. data/test/cases/types_test.rb +26 -0
  380. data/test/cases/unconnected_test.rb +46 -0
  381. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  382. data/test/cases/validations/absence_validation_test.rb +75 -0
  383. data/test/cases/validations/association_validation_test.rb +99 -0
  384. data/test/cases/validations/i18n_generate_message_validation_test.rb +102 -0
  385. data/test/cases/validations/i18n_validation_test.rb +87 -0
  386. data/test/cases/validations/length_validation_test.rb +80 -0
  387. data/test/cases/validations/numericality_validation_test.rb +181 -0
  388. data/test/cases/validations/presence_validation_test.rb +105 -0
  389. data/test/cases/validations/uniqueness_validation_test.rb +618 -0
  390. data/test/cases/validations_repair_helper.rb +21 -0
  391. data/test/cases/validations_test.rb +229 -0
  392. data/test/cases/view_test.rb +222 -0
  393. data/test/cases/yaml_serialization_test.rb +166 -0
  394. data/test/config.example.yml +97 -0
  395. data/test/config.rb +7 -0
  396. data/test/config.yml +220 -0
  397. data/test/connections/native_ibm_db/connection.rb +44 -0
  398. data/test/fixtures/accounts.yml +29 -0
  399. data/test/fixtures/admin/accounts.yml +2 -0
  400. data/test/fixtures/admin/randomly_named_a9.yml +7 -0
  401. data/test/fixtures/admin/randomly_named_b0.yml +7 -0
  402. data/test/fixtures/admin/users.yml +10 -0
  403. data/test/fixtures/all/admin +1 -0
  404. data/test/fixtures/all/developers.yml +0 -0
  405. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  406. data/test/fixtures/all/people.yml +0 -0
  407. data/test/fixtures/all/tasks.yml +0 -0
  408. data/test/fixtures/author_addresses.yml +11 -0
  409. data/test/fixtures/author_favorites.yml +4 -0
  410. data/test/fixtures/authors.yml +17 -0
  411. data/test/fixtures/bad_posts.yml +9 -0
  412. data/test/fixtures/binaries.yml +137 -0
  413. data/test/fixtures/books.yml +38 -0
  414. data/test/fixtures/bulbs.yml +5 -0
  415. data/test/fixtures/cars.yml +9 -0
  416. data/test/fixtures/categories/special_categories.yml +9 -0
  417. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
  418. data/test/fixtures/categories.yml +19 -0
  419. data/test/fixtures/categories_ordered.yml +7 -0
  420. data/test/fixtures/categories_posts.yml +34 -0
  421. data/test/fixtures/categorizations.yml +23 -0
  422. data/test/fixtures/citations.yml +5 -0
  423. data/test/fixtures/clubs.yml +8 -0
  424. data/test/fixtures/collections.yml +3 -0
  425. data/test/fixtures/colleges.yml +3 -0
  426. data/test/fixtures/comments.yml +72 -0
  427. data/test/fixtures/companies.yml +72 -0
  428. data/test/fixtures/computers.yml +12 -0
  429. data/test/fixtures/content.yml +3 -0
  430. data/test/fixtures/content_positions.yml +3 -0
  431. data/test/fixtures/courses.yml +8 -0
  432. data/test/fixtures/customers.yml +35 -0
  433. data/test/fixtures/dashboards.yml +6 -0
  434. data/test/fixtures/dead_parrots.yml +5 -0
  435. data/test/fixtures/developers.yml +22 -0
  436. data/test/fixtures/developers_projects.yml +17 -0
  437. data/test/fixtures/dog_lovers.yml +7 -0
  438. data/test/fixtures/dogs.yml +4 -0
  439. data/test/fixtures/doubloons.yml +3 -0
  440. data/test/fixtures/edges.yml +5 -0
  441. data/test/fixtures/entrants.yml +14 -0
  442. data/test/fixtures/essays.yml +16 -0
  443. data/test/fixtures/faces.yml +11 -0
  444. data/test/fixtures/fk_test_has_fk.yml +3 -0
  445. data/test/fixtures/fk_test_has_pk.yml +2 -0
  446. data/test/fixtures/friendships.yml +4 -0
  447. data/test/fixtures/funny_jokes.yml +10 -0
  448. data/test/fixtures/humans.yml +5 -0
  449. data/test/fixtures/interests.yml +33 -0
  450. data/test/fixtures/items.yml +3 -0
  451. data/test/fixtures/jobs.yml +7 -0
  452. data/test/fixtures/legacy_things.yml +3 -0
  453. data/test/fixtures/live_parrots.yml +4 -0
  454. data/test/fixtures/mateys.yml +4 -0
  455. data/test/fixtures/member_details.yml +8 -0
  456. data/test/fixtures/member_types.yml +6 -0
  457. data/test/fixtures/members.yml +11 -0
  458. data/test/fixtures/memberships.yml +41 -0
  459. data/test/fixtures/men.yml +5 -0
  460. data/test/fixtures/minimalistics.yml +5 -0
  461. data/test/fixtures/minivans.yml +5 -0
  462. data/test/fixtures/mixed_case_monkeys.yml +6 -0
  463. data/test/fixtures/mixins.yml +29 -0
  464. data/test/fixtures/movies.yml +7 -0
  465. data/test/fixtures/naked/yml/accounts.yml +1 -0
  466. data/test/fixtures/naked/yml/companies.yml +1 -0
  467. data/test/fixtures/naked/yml/courses.yml +1 -0
  468. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  469. data/test/fixtures/naked/yml/parrots.yml +3 -0
  470. data/test/fixtures/naked/yml/trees.yml +3 -0
  471. data/test/fixtures/nodes.yml +29 -0
  472. data/test/fixtures/organizations.yml +5 -0
  473. data/test/fixtures/other_books.yml +26 -0
  474. data/test/fixtures/other_comments.yml +6 -0
  475. data/test/fixtures/other_dogs.yml +2 -0
  476. data/test/fixtures/other_posts.yml +8 -0
  477. data/test/fixtures/other_topics.yml +42 -0
  478. data/test/fixtures/owners.yml +9 -0
  479. data/test/fixtures/parrots.yml +33 -0
  480. data/test/fixtures/parrots_pirates.yml +7 -0
  481. data/test/fixtures/people.yml +24 -0
  482. data/test/fixtures/peoples_treasures.yml +3 -0
  483. data/test/fixtures/pets.yml +19 -0
  484. data/test/fixtures/pirates.yml +15 -0
  485. data/test/fixtures/posts.yml +88 -0
  486. data/test/fixtures/price_estimates.yml +16 -0
  487. data/test/fixtures/products.yml +4 -0
  488. data/test/fixtures/projects.yml +7 -0
  489. data/test/fixtures/randomly_named_a9.yml +7 -0
  490. data/test/fixtures/ratings.yml +14 -0
  491. data/test/fixtures/readers.yml +17 -0
  492. data/test/fixtures/references.yml +17 -0
  493. data/test/fixtures/reserved_words/distinct.yml +5 -0
  494. data/test/fixtures/reserved_words/distinct_select.yml +11 -0
  495. data/test/fixtures/reserved_words/group.yml +14 -0
  496. data/test/fixtures/reserved_words/select.yml +8 -0
  497. data/test/fixtures/reserved_words/values.yml +7 -0
  498. data/test/fixtures/ships.yml +6 -0
  499. data/test/fixtures/speedometers.yml +8 -0
  500. data/test/fixtures/sponsors.yml +15 -0
  501. data/test/fixtures/strict_zines.yml +2 -0
  502. data/test/fixtures/string_key_objects.yml +7 -0
  503. data/test/fixtures/subscribers.yml +11 -0
  504. data/test/fixtures/subscriptions.yml +12 -0
  505. data/test/fixtures/taggings.yml +78 -0
  506. data/test/fixtures/tags.yml +11 -0
  507. data/test/fixtures/tasks.yml +7 -0
  508. data/test/fixtures/teapots.yml +3 -0
  509. data/test/fixtures/to_be_linked/accounts.yml +2 -0
  510. data/test/fixtures/to_be_linked/users.yml +10 -0
  511. data/test/fixtures/topics.yml +49 -0
  512. data/test/fixtures/toys.yml +14 -0
  513. data/test/fixtures/traffic_lights.yml +10 -0
  514. data/test/fixtures/treasures.yml +10 -0
  515. data/test/fixtures/trees.yml +3 -0
  516. data/test/fixtures/uuid_children.yml +3 -0
  517. data/test/fixtures/uuid_parents.yml +2 -0
  518. data/test/fixtures/variants.yml +4 -0
  519. data/test/fixtures/vegetables.yml +20 -0
  520. data/test/fixtures/vertices.yml +4 -0
  521. data/test/fixtures/warehouse-things.yml +3 -0
  522. data/test/fixtures/warehouse_things.yml +3 -0
  523. data/test/fixtures/zines.yml +5 -0
  524. data/test/ibm_db_test.rb +25 -0
  525. data/test/migrations/10_urban/9_add_expressions.rb +13 -0
  526. data/test/migrations/decimal/1_give_me_big_numbers.rb +17 -0
  527. data/test/migrations/magic/1_currencies_have_symbols.rb +13 -0
  528. data/test/migrations/missing/1000_people_have_middle_names.rb +11 -0
  529. data/test/migrations/missing/1_people_have_last_names.rb +11 -0
  530. data/test/migrations/missing/3_we_need_reminders.rb +14 -0
  531. data/test/migrations/missing/4_innocent_jointable.rb +14 -0
  532. data/test/migrations/rename/1_we_need_things.rb +13 -0
  533. data/test/migrations/rename/2_rename_things.rb +11 -0
  534. data/test/migrations/to_copy/1_people_have_hobbies.rb +11 -0
  535. data/test/migrations/to_copy/2_people_have_descriptions.rb +11 -0
  536. data/test/migrations/to_copy2/1_create_articles.rb +9 -0
  537. data/test/migrations/to_copy2/2_create_comments.rb +9 -0
  538. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +11 -0
  539. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +11 -0
  540. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +11 -0
  541. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +9 -0
  542. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +9 -0
  543. data/test/migrations/valid/1_valid_people_have_last_names.rb +11 -0
  544. data/test/migrations/valid/2_we_need_reminders.rb +14 -0
  545. data/test/migrations/valid/3_innocent_jointable.rb +14 -0
  546. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +11 -0
  547. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +14 -0
  548. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +14 -0
  549. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +11 -0
  550. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +14 -0
  551. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +14 -0
  552. data/test/migrations/version_check/20131219224947_migration_version_check.rb +10 -0
  553. data/test/models/account.rb +46 -0
  554. data/test/models/admin/account.rb +5 -0
  555. data/test/models/admin/randomly_named_c1.rb +9 -0
  556. data/test/models/admin/user.rb +48 -0
  557. data/test/models/admin.rb +7 -0
  558. data/test/models/aircraft.rb +7 -0
  559. data/test/models/arunit2_model.rb +5 -0
  560. data/test/models/author.rb +260 -0
  561. data/test/models/auto_id.rb +6 -0
  562. data/test/models/autoloadable/extra_firm.rb +4 -0
  563. data/test/models/binary.rb +4 -0
  564. data/test/models/binary_field.rb +6 -0
  565. data/test/models/bird.rb +24 -0
  566. data/test/models/book.rb +33 -0
  567. data/test/models/book_destroy_async.rb +24 -0
  568. data/test/models/boolean.rb +7 -0
  569. data/test/models/bulb.rb +61 -0
  570. data/test/models/cake_designer.rb +5 -0
  571. data/test/models/car.rb +36 -0
  572. data/test/models/carrier.rb +4 -0
  573. data/test/models/cart.rb +5 -0
  574. data/test/models/cat.rb +12 -0
  575. data/test/models/categorization.rb +21 -0
  576. data/test/models/category.rb +47 -0
  577. data/test/models/chef.rb +10 -0
  578. data/test/models/citation.rb +7 -0
  579. data/test/models/club.rb +28 -0
  580. data/test/models/college.rb +12 -0
  581. data/test/models/column.rb +5 -0
  582. data/test/models/column_name.rb +5 -0
  583. data/test/models/comment.rb +98 -0
  584. data/test/models/company.rb +226 -0
  585. data/test/models/company_in_module.rb +99 -0
  586. data/test/models/computer.rb +5 -0
  587. data/test/models/contact.rb +43 -0
  588. data/test/models/content.rb +42 -0
  589. data/test/models/contract.rb +38 -0
  590. data/test/models/country.rb +5 -0
  591. data/test/models/course.rb +8 -0
  592. data/test/models/customer.rb +85 -0
  593. data/test/models/customer_carrier.rb +16 -0
  594. data/test/models/dashboard.rb +5 -0
  595. data/test/models/default.rb +4 -0
  596. data/test/models/department.rb +6 -0
  597. data/test/models/destroy_async_parent.rb +15 -0
  598. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  599. data/test/models/developer.rb +341 -0
  600. data/test/models/dl_keyed_belongs_to.rb +13 -0
  601. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  602. data/test/models/dl_keyed_has_many.rb +5 -0
  603. data/test/models/dl_keyed_has_many_through.rb +5 -0
  604. data/test/models/dl_keyed_has_one.rb +5 -0
  605. data/test/models/dl_keyed_join.rb +10 -0
  606. data/test/models/dog.rb +7 -0
  607. data/test/models/dog_lover.rb +7 -0
  608. data/test/models/doubloon.rb +14 -0
  609. data/test/models/drink_designer.rb +20 -0
  610. data/test/models/edge.rb +7 -0
  611. data/test/models/electron.rb +7 -0
  612. data/test/models/engine.rb +5 -0
  613. data/test/models/entrant.rb +5 -0
  614. data/test/models/entry.rb +5 -0
  615. data/test/models/essay.rb +8 -0
  616. data/test/models/essay_destroy_async.rb +12 -0
  617. data/test/models/event.rb +5 -0
  618. data/test/models/eye.rb +39 -0
  619. data/test/models/face.rb +17 -0
  620. data/test/models/family.rb +6 -0
  621. data/test/models/family_tree.rb +6 -0
  622. data/test/models/friendship.rb +8 -0
  623. data/test/models/frog.rb +8 -0
  624. data/test/models/guid.rb +4 -0
  625. data/test/models/guitar.rb +6 -0
  626. data/test/models/hotel.rb +13 -0
  627. data/test/models/human.rb +39 -0
  628. data/test/models/image.rb +5 -0
  629. data/test/models/interest.rb +16 -0
  630. data/test/models/invoice.rb +6 -0
  631. data/test/models/item.rb +9 -0
  632. data/test/models/job.rb +9 -0
  633. data/test/models/joke.rb +9 -0
  634. data/test/models/keyboard.rb +5 -0
  635. data/test/models/legacy_thing.rb +5 -0
  636. data/test/models/lesson.rb +13 -0
  637. data/test/models/line_item.rb +5 -0
  638. data/test/models/liquid.rb +6 -0
  639. data/test/models/man.rb +11 -0
  640. data/test/models/matey.rb +6 -0
  641. data/test/models/measurement.rb +4 -0
  642. data/test/models/member.rb +45 -0
  643. data/test/models/member_detail.rb +11 -0
  644. data/test/models/member_type.rb +5 -0
  645. data/test/models/membership.rb +38 -0
  646. data/test/models/mentor.rb +5 -0
  647. data/test/models/message.rb +5 -0
  648. data/test/models/minimalistic.rb +4 -0
  649. data/test/models/minivan.rb +10 -0
  650. data/test/models/mixed_case_monkey.rb +5 -0
  651. data/test/models/mocktail_designer.rb +2 -0
  652. data/test/models/molecule.rb +8 -0
  653. data/test/models/mouse.rb +6 -0
  654. data/test/models/movie.rb +7 -0
  655. data/test/models/node.rb +7 -0
  656. data/test/models/non_primary_key.rb +4 -0
  657. data/test/models/notification.rb +5 -0
  658. data/test/models/numeric_data.rb +12 -0
  659. data/test/models/order.rb +6 -0
  660. data/test/models/organization.rb +16 -0
  661. data/test/models/other_dog.rb +7 -0
  662. data/test/models/owner.rb +39 -0
  663. data/test/models/parrot.rb +36 -0
  664. data/test/models/person.rb +147 -0
  665. data/test/models/personal_legacy_thing.rb +6 -0
  666. data/test/models/pet.rb +20 -0
  667. data/test/models/pet_treasure.rb +8 -0
  668. data/test/models/pirate.rb +116 -0
  669. data/test/models/possession.rb +5 -0
  670. data/test/models/post.rb +371 -0
  671. data/test/models/price_estimate.rb +14 -0
  672. data/test/models/professor.rb +7 -0
  673. data/test/models/project.rb +42 -0
  674. data/test/models/publisher/article.rb +6 -0
  675. data/test/models/publisher/magazine.rb +5 -0
  676. data/test/models/publisher.rb +4 -0
  677. data/test/models/randomly_named_c1.rb +5 -0
  678. data/test/models/rating.rb +8 -0
  679. data/test/models/reader.rb +25 -0
  680. data/test/models/recipe.rb +5 -0
  681. data/test/models/record.rb +4 -0
  682. data/test/models/reference.rb +25 -0
  683. data/test/models/reply.rb +79 -0
  684. data/test/models/room.rb +6 -0
  685. data/test/models/section.rb +6 -0
  686. data/test/models/seminar.rb +6 -0
  687. data/test/models/session.rb +6 -0
  688. data/test/models/ship.rb +42 -0
  689. data/test/models/ship_part.rb +10 -0
  690. data/test/models/shop.rb +19 -0
  691. data/test/models/shop_account.rb +8 -0
  692. data/test/models/speedometer.rb +8 -0
  693. data/test/models/sponsor.rb +10 -0
  694. data/test/models/squeak.rb +6 -0
  695. data/test/models/strict_zine.rb +7 -0
  696. data/test/models/string_key_object.rb +5 -0
  697. data/test/models/student.rb +6 -0
  698. data/test/models/subject.rb +16 -0
  699. data/test/models/subscriber.rb +10 -0
  700. data/test/models/subscription.rb +8 -0
  701. data/test/models/tag.rb +16 -0
  702. data/test/models/tagging.rb +20 -0
  703. data/test/models/task.rb +7 -0
  704. data/test/models/topic.rb +153 -0
  705. data/test/models/toy.rb +10 -0
  706. data/test/models/traffic_light.rb +6 -0
  707. data/test/models/treasure.rb +16 -0
  708. data/test/models/treaty.rb +5 -0
  709. data/test/models/tree.rb +5 -0
  710. data/test/models/tuning_peg.rb +6 -0
  711. data/test/models/tyre.rb +13 -0
  712. data/test/models/user.rb +22 -0
  713. data/test/models/uuid_child.rb +5 -0
  714. data/test/models/uuid_item.rb +8 -0
  715. data/test/models/uuid_parent.rb +5 -0
  716. data/test/models/vegetables.rb +33 -0
  717. data/test/models/vehicle.rb +7 -0
  718. data/test/models/vertex.rb +11 -0
  719. data/test/models/warehouse_thing.rb +7 -0
  720. data/test/models/wheel.rb +5 -0
  721. data/test/models/without_table.rb +5 -0
  722. data/test/models/zine.rb +5 -0
  723. data/test/schema/i5/ibm_db_specific_schema.rb +137 -0
  724. data/test/schema/ids/ibm_db_specific_schema.rb +140 -0
  725. data/test/schema/luw/ibm_db_specific_schema.rb +137 -0
  726. data/test/schema/mysql2_specific_schema.rb +82 -0
  727. data/test/schema/oracle_specific_schema.rb +38 -0
  728. data/test/schema/postgresql_specific_schema.rb +125 -0
  729. data/test/schema/schema.rb +1237 -0
  730. data/test/schema/schema.rb.original +1057 -0
  731. data/test/schema/sqlite_specific_schema.rb +11 -0
  732. data/test/schema/zOS/ibm_db_specific_schema.rb +208 -0
  733. data/test/support/config.rb +43 -0
  734. data/test/support/connection.rb +29 -0
  735. data/test/support/connection_helper.rb +16 -0
  736. data/test/support/ddl_helper.rb +10 -0
  737. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  738. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  739. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  740. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  741. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  742. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  743. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  744. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  745. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  746. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  747. data/test/support/schema_dumping_helper.rb +22 -0
  748. data/test/support/stubs/strong_parameters.rb +40 -0
  749. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
  750. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -0
  751. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  752. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  753. metadata +876 -0
@@ -0,0 +1,1124 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "models/minimalistic"
5
+ require "models/developer"
6
+ require "models/auto_id"
7
+ require "models/boolean"
8
+ require "models/computer"
9
+ require "models/topic"
10
+ require "models/company"
11
+ require "models/category"
12
+ require "models/reply"
13
+ require "models/contact"
14
+ require "models/keyboard"
15
+ require "models/numeric_data"
16
+
17
+ class AttributeMethodsTest < ActiveRecord::TestCase
18
+ include InTimeZone
19
+
20
+ fixtures :topics, :developers, :companies, :computers
21
+
22
+ def setup
23
+ @old_matchers = ActiveRecord::Base.send(:attribute_method_matchers).dup
24
+ @target = Class.new(ActiveRecord::Base)
25
+ @target.table_name = "topics"
26
+ end
27
+
28
+ teardown do
29
+ ActiveRecord::Base.send(:attribute_method_matchers).clear
30
+ ActiveRecord::Base.send(:attribute_method_matchers).concat(@old_matchers)
31
+ end
32
+
33
+ test "attribute_for_inspect with a string" do
34
+ t = topics(:first)
35
+ t.title = "The First Topic Now Has A Title With\nNewlines And More Than 50 Characters"
36
+
37
+ assert_equal '"The First Topic Now Has A Title With\nNewlines And ..."', t.attribute_for_inspect(:title)
38
+ assert_equal '"The First Topic Now Has A Title With\nNewlines And ..."', t.attribute_for_inspect(:heading)
39
+ end
40
+
41
+ test "attribute_for_inspect with a date" do
42
+ t = topics(:first)
43
+
44
+ assert_equal %("#{t.written_on.to_s(:inspect)}"), t.attribute_for_inspect(:written_on)
45
+ end
46
+
47
+ test "attribute_for_inspect with an array" do
48
+ t = topics(:first)
49
+ t.content = [Object.new]
50
+
51
+ assert_match %r(\[#<Object:0x[0-9a-f]+>\]), t.attribute_for_inspect(:content)
52
+ end
53
+
54
+ test "attribute_for_inspect with a long array" do
55
+ t = topics(:first)
56
+ t.content = (1..11).to_a
57
+
58
+ assert_equal "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]", t.attribute_for_inspect(:content)
59
+ end
60
+
61
+ test "attribute_for_inspect with a non-primary key id attribute" do
62
+ t = topics(:first).becomes(TitlePrimaryKeyTopic)
63
+ t.title = "The First Topic Now Has A Title With\nNewlines And More Than 50 Characters"
64
+
65
+ assert_equal "1", t.attribute_for_inspect(:id)
66
+ end
67
+
68
+ test "attribute_present" do
69
+ t = Topic.new
70
+ t.title = "hello there!"
71
+ t.written_on = Time.now
72
+ t.author_name = ""
73
+ assert t.attribute_present?("title")
74
+ assert t.attribute_present?("heading")
75
+ assert t.attribute_present?("written_on")
76
+ assert_not t.attribute_present?("content")
77
+ assert_not t.attribute_present?("author_name")
78
+ end
79
+
80
+ test "attribute_present with booleans" do
81
+ b1 = Boolean.new
82
+ b1.value = false
83
+ assert b1.attribute_present?(:value)
84
+
85
+ b2 = Boolean.new
86
+ b2.value = true
87
+ assert b2.attribute_present?(:value)
88
+
89
+ b3 = Boolean.new
90
+ assert_not b3.attribute_present?(:value)
91
+
92
+ b4 = Boolean.new
93
+ b4.value = false
94
+ b4.save!
95
+ assert Boolean.find(b4.id).attribute_present?(:value)
96
+ end
97
+
98
+ test "caching a nil primary key" do
99
+ klass = Class.new(Minimalistic)
100
+ assert_called(klass, :reset_primary_key, returns: nil) do
101
+ 2.times { klass.primary_key }
102
+ end
103
+ end
104
+
105
+ test "attribute keys on a new instance" do
106
+ t = Topic.new
107
+ assert_nil t.title, "The topics table has a title column, so it should be nil"
108
+ assert_raise(NoMethodError) { t.title2 }
109
+ end
110
+
111
+ test "boolean attributes" do
112
+ assert_not_predicate Topic.find(1), :approved?
113
+ assert_predicate Topic.find(2), :approved?
114
+ end
115
+
116
+ test "set attributes" do
117
+ topic = Topic.find(1)
118
+ topic.attributes = { title: "Budget", author_name: "Jason" }
119
+ topic.save
120
+ assert_equal("Budget", topic.title)
121
+ assert_equal("Jason", topic.author_name)
122
+ assert_equal(topics(:first).author_email_address, Topic.find(1).author_email_address)
123
+ end
124
+
125
+ test "set attributes without a hash" do
126
+ topic = Topic.new
127
+ assert_raise(ArgumentError) { topic.attributes = "" }
128
+ end
129
+
130
+ test "integers as nil" do
131
+ test = AutoId.create(value: "")
132
+ assert_nil AutoId.find(test.id).value
133
+ end
134
+
135
+ test "set attributes with a block" do
136
+ topic = Topic.new do |t|
137
+ t.title = "Budget"
138
+ t.author_name = "Jason"
139
+ end
140
+
141
+ assert_equal("Budget", topic.title)
142
+ assert_equal("Jason", topic.author_name)
143
+ end
144
+
145
+ test "respond_to?" do
146
+ topic = Topic.find(1)
147
+ assert_respond_to topic, "title"
148
+ assert_respond_to topic, "title?"
149
+ assert_respond_to topic, "title="
150
+ assert_respond_to topic, :title
151
+ assert_respond_to topic, :title?
152
+ assert_respond_to topic, :title=
153
+ assert_respond_to topic, "author_name"
154
+ assert_respond_to topic, "attribute_names"
155
+ assert_not_respond_to topic, "nothingness"
156
+ assert_not_respond_to topic, :nothingness
157
+ end
158
+
159
+ test "respond_to? with a custom primary key" do
160
+ keyboard = Keyboard.create
161
+ assert_not_nil keyboard.key_number
162
+ assert_equal keyboard.key_number, keyboard.id
163
+ assert_respond_to keyboard, "key_number"
164
+ assert_respond_to keyboard, "id"
165
+ end
166
+
167
+ test "id_before_type_cast with a custom primary key" do
168
+ keyboard = Keyboard.create
169
+ keyboard.key_number = "10"
170
+ assert_equal "10", keyboard.id_before_type_cast
171
+ assert_nil keyboard.read_attribute_before_type_cast("id")
172
+ assert_equal "10", keyboard.read_attribute_before_type_cast("key_number")
173
+ assert_equal "10", keyboard.read_attribute_before_type_cast(:key_number)
174
+ end
175
+
176
+ # IRB inspects the return value of MyModel.allocate.
177
+ test "allocated objects can be inspected" do
178
+ topic = Topic.allocate
179
+ assert_equal "#<Topic not initialized>", topic.inspect
180
+ end
181
+
182
+ test "array content" do
183
+ content = %w( one two three )
184
+ topic = Topic.new
185
+ topic.content = content
186
+ topic.save
187
+
188
+ assert_equal content, Topic.find(topic.id).content
189
+ end
190
+
191
+ test "read attributes_before_type_cast" do
192
+ category = Category.new(name: "Test category", type: nil)
193
+ category_attrs = { "name" => "Test category", "id" => nil, "type" => nil, "categorizations_count" => nil }
194
+ assert_equal category_attrs, category.attributes_before_type_cast
195
+ end
196
+
197
+ if current_adapter?(:Mysql2Adapter)
198
+ test "read attributes_before_type_cast on a boolean" do
199
+ bool = Boolean.create!("value" => false)
200
+ assert_equal 0, bool.reload.attributes_before_type_cast["value"]
201
+ end
202
+ end
203
+
204
+ test "read attributes_before_type_cast on a datetime" do
205
+ in_time_zone "Pacific Time (US & Canada)" do
206
+ record = @target.new
207
+
208
+ record.written_on = "345643456"
209
+ assert_equal "345643456", record.written_on_before_type_cast
210
+ assert_nil record.written_on
211
+
212
+ record.written_on = "2009-10-11 12:13:14"
213
+ assert_equal "2009-10-11 12:13:14", record.written_on_before_type_cast
214
+ assert_equal Time.zone.parse("2009-10-11 12:13:14"), record.written_on
215
+ assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.written_on.time_zone
216
+ end
217
+ end
218
+
219
+ test "read attributes_after_type_cast on a date" do
220
+ tz = "Pacific Time (US & Canada)"
221
+
222
+ in_time_zone tz do
223
+ record = @target.new
224
+
225
+ date_string = "2011-03-24"
226
+ time = Time.zone.parse date_string
227
+
228
+ record.written_on = date_string
229
+ assert_equal date_string, record.written_on_before_type_cast
230
+ assert_equal time, record.written_on
231
+ assert_equal ActiveSupport::TimeZone[tz], record.written_on.time_zone
232
+
233
+ record.save
234
+ record.reload
235
+
236
+ assert_equal time, record.written_on
237
+ end
238
+ end
239
+
240
+ test "hash content" do
241
+ topic = Topic.new
242
+ topic.content = { "one" => 1, "two" => 2 }
243
+ topic.save
244
+
245
+ assert_equal 2, Topic.find(topic.id).content["two"]
246
+
247
+ topic.content_will_change!
248
+ topic.content["three"] = 3
249
+ topic.save
250
+
251
+ assert_equal 3, Topic.find(topic.id).content["three"]
252
+ end
253
+
254
+ test "update array content" do
255
+ topic = Topic.new
256
+ topic.content = %w( one two three )
257
+
258
+ topic.content.push "four"
259
+ assert_equal(%w( one two three four ), topic.content)
260
+
261
+ topic.save
262
+
263
+ topic = Topic.find(topic.id)
264
+ topic.content << "five"
265
+ assert_equal(%w( one two three four five ), topic.content)
266
+ end
267
+
268
+ test "case-sensitive attributes hash" do
269
+ assert_equal @loaded_fixtures["computers"]["workstation"].to_hash, Computer.first.attributes
270
+ end
271
+
272
+ test "attributes without primary key" do
273
+ klass = Class.new(ActiveRecord::Base) do
274
+ self.table_name = "developers_projects"
275
+ end
276
+
277
+ assert_equal klass.column_names, klass.new.attributes.keys
278
+ assert_not klass.new.has_attribute?("id")
279
+ end
280
+
281
+ test "hashes are not mangled" do
282
+ new_topic = { title: "New Topic", content: { key: "First value" } }
283
+ new_topic_values = { title: "AnotherTopic", content: { key: "Second value" } }
284
+
285
+ topic = Topic.new(new_topic)
286
+ assert_equal new_topic[:title], topic.title
287
+ assert_equal new_topic[:content], topic.content
288
+
289
+ topic.attributes = new_topic_values
290
+ assert_equal new_topic_values[:title], topic.title
291
+ assert_equal new_topic_values[:content], topic.content
292
+ end
293
+
294
+ test "create through factory" do
295
+ topic = Topic.create(title: "New Topic")
296
+ topicReloaded = Topic.find(topic.id)
297
+ assert_equal(topic, topicReloaded)
298
+ end
299
+
300
+ test "write_attribute" do
301
+ topic = Topic.new
302
+ topic.write_attribute :title, "Still another topic"
303
+ assert_equal "Still another topic", topic.title
304
+
305
+ topic[:title] = "Still another topic: part 2"
306
+ assert_equal "Still another topic: part 2", topic.title
307
+
308
+ topic.write_attribute "title", "Still another topic: part 3"
309
+ assert_equal "Still another topic: part 3", topic.title
310
+
311
+ topic["title"] = "Still another topic: part 4"
312
+ assert_equal "Still another topic: part 4", topic.title
313
+ end
314
+
315
+ test "write_attribute can write aliased attributes as well" do
316
+ topic = Topic.new(title: "Don't change the topic")
317
+ topic.write_attribute :heading, "New topic"
318
+
319
+ assert_equal "New topic", topic.title
320
+ end
321
+
322
+ test "write_attribute raises ActiveModel::MissingAttributeError when the attribute does not exist" do
323
+ topic = Topic.first
324
+ assert_raises(ActiveModel::MissingAttributeError) { topic.update_columns(no_column_exists: "Hello!") }
325
+ assert_raises(ActiveModel::UnknownAttributeError) { topic.update(no_column_exists: "Hello!") }
326
+ end
327
+
328
+ test "write_attribute allows writing to aliased attributes" do
329
+ topic = Topic.first
330
+ assert_nothing_raised { topic.update_columns(heading: "Hello!") }
331
+ assert_nothing_raised { topic.update(heading: "Hello!") }
332
+ end
333
+
334
+ test "read_attribute" do
335
+ topic = Topic.new
336
+ topic.title = "Don't change the topic"
337
+ assert_equal "Don't change the topic", topic.read_attribute("title")
338
+ assert_equal "Don't change the topic", topic["title"]
339
+
340
+ assert_equal "Don't change the topic", topic.read_attribute(:title)
341
+ assert_equal "Don't change the topic", topic[:title]
342
+ end
343
+
344
+ test "read_attribute can read aliased attributes as well" do
345
+ topic = Topic.new(title: "Don't change the topic")
346
+
347
+ assert_equal "Don't change the topic", topic.read_attribute("heading")
348
+ assert_equal "Don't change the topic", topic["heading"]
349
+
350
+ assert_equal "Don't change the topic", topic.read_attribute(:heading)
351
+ assert_equal "Don't change the topic", topic[:heading]
352
+ end
353
+
354
+ test "read_attribute raises ActiveModel::MissingAttributeError when the attribute does not exist" do
355
+ computer = Computer.select("id").first
356
+ assert_raises(ActiveModel::MissingAttributeError) { computer[:developer] }
357
+ assert_raises(ActiveModel::MissingAttributeError) { computer[:extendedwarranty] }
358
+ assert_raises(ActiveModel::MissingAttributeError) { computer[:no_column_exists] = "Hello!" }
359
+ assert_nothing_raised { computer[:developer] = "Hello!" }
360
+ end
361
+
362
+ test "read_attribute when false" do
363
+ topic = topics(:first)
364
+ topic.approved = false
365
+ assert_not topic.approved?, "approved should be false"
366
+ topic.approved = "false"
367
+ assert_not topic.approved?, "approved should be false"
368
+ end
369
+
370
+ test "read_attribute when true" do
371
+ topic = topics(:first)
372
+ topic.approved = true
373
+ assert topic.approved?, "approved should be true"
374
+ topic.approved = "true"
375
+ assert topic.approved?, "approved should be true"
376
+ end
377
+
378
+ test "boolean attributes writing and reading" do
379
+ topic = Topic.new
380
+ topic.approved = "false"
381
+ assert_not topic.approved?, "approved should be false"
382
+
383
+ topic.approved = "false"
384
+ assert_not topic.approved?, "approved should be false"
385
+
386
+ topic.approved = "true"
387
+ assert topic.approved?, "approved should be true"
388
+
389
+ topic.approved = "true"
390
+ assert topic.approved?, "approved should be true"
391
+ end
392
+
393
+ test "overridden write_attribute" do
394
+ topic = Topic.new
395
+ def topic.write_attribute(attr_name, value)
396
+ super(attr_name, value.downcase)
397
+ end
398
+
399
+ topic.write_attribute :title, "Yet another topic"
400
+ assert_equal "yet another topic", topic.title
401
+
402
+ topic[:title] = "Yet another topic: part 2"
403
+ assert_equal "yet another topic: part 2", topic.title
404
+
405
+ topic.write_attribute "title", "Yet another topic: part 3"
406
+ assert_equal "yet another topic: part 3", topic.title
407
+
408
+ topic["title"] = "Yet another topic: part 4"
409
+ assert_equal "yet another topic: part 4", topic.title
410
+ end
411
+
412
+ test "overridden read_attribute" do
413
+ topic = Topic.new
414
+ topic.title = "Stop changing the topic"
415
+ def topic.read_attribute(attr_name)
416
+ super(attr_name).upcase
417
+ end
418
+
419
+ assert_equal "STOP CHANGING THE TOPIC", topic.read_attribute("title")
420
+ assert_equal "STOP CHANGING THE TOPIC", topic["title"]
421
+
422
+ assert_equal "STOP CHANGING THE TOPIC", topic.read_attribute(:title)
423
+ assert_equal "STOP CHANGING THE TOPIC", topic[:title]
424
+ end
425
+
426
+ test "read overridden attribute" do
427
+ topic = Topic.new(title: "a")
428
+ def topic.title() "b" end
429
+ assert_equal "a", topic[:title]
430
+ end
431
+
432
+ test "string attribute predicate" do
433
+ [nil, "", " "].each do |value|
434
+ assert_equal false, Topic.new(author_name: value).author_name?
435
+ end
436
+
437
+ assert_equal true, Topic.new(author_name: "Name").author_name?
438
+
439
+ ActiveModel::Type::Boolean::FALSE_VALUES.each do |value|
440
+ assert_predicate Topic.new(author_name: value), :author_name?
441
+ end
442
+ end
443
+
444
+ test "number attribute predicate" do
445
+ [nil, 0, "0"].each do |value|
446
+ assert_equal false, Developer.new(salary: value).salary?
447
+ end
448
+
449
+ assert_equal true, Developer.new(salary: 1).salary?
450
+ assert_equal true, Developer.new(salary: "1").salary?
451
+ end
452
+
453
+ test "boolean attribute predicate" do
454
+ [nil, "", false, "false", "f", 0].each do |value|
455
+ assert_equal false, Topic.new(approved: value).approved?
456
+ end
457
+
458
+ [true, "true", "1", 1].each do |value|
459
+ assert_equal true, Topic.new(approved: value).approved?
460
+ end
461
+ end
462
+
463
+ test "user-defined text attribute predicate" do
464
+ klass = Class.new(ActiveRecord::Base) do
465
+ self.table_name = Topic.table_name
466
+
467
+ attribute :user_defined_text, :text
468
+ end
469
+
470
+ topic = klass.new(user_defined_text: "text")
471
+ assert_predicate topic, :user_defined_text?
472
+
473
+ ActiveModel::Type::Boolean::FALSE_VALUES.each do |value|
474
+ topic = klass.new(user_defined_text: value)
475
+ assert_predicate topic, :user_defined_text?
476
+ end
477
+ end
478
+
479
+ test "user-defined date attribute predicate" do
480
+ klass = Class.new(ActiveRecord::Base) do
481
+ self.table_name = Topic.table_name
482
+
483
+ attribute :user_defined_date, :date
484
+ end
485
+
486
+ topic = klass.new(user_defined_date: Date.current)
487
+ assert_predicate topic, :user_defined_date?
488
+ end
489
+
490
+ test "user-defined datetime attribute predicate" do
491
+ klass = Class.new(ActiveRecord::Base) do
492
+ self.table_name = Topic.table_name
493
+
494
+ attribute :user_defined_datetime, :datetime
495
+ end
496
+
497
+ topic = klass.new(user_defined_datetime: Time.current)
498
+ assert_predicate topic, :user_defined_datetime?
499
+ end
500
+
501
+ test "user-defined time attribute predicate" do
502
+ klass = Class.new(ActiveRecord::Base) do
503
+ self.table_name = Topic.table_name
504
+
505
+ attribute :user_defined_time, :time
506
+ end
507
+
508
+ topic = klass.new(user_defined_time: Time.current)
509
+ assert_predicate topic, :user_defined_time?
510
+ end
511
+
512
+ test "user-defined json attribute predicate" do
513
+ klass = Class.new(ActiveRecord::Base) do
514
+ self.table_name = Topic.table_name
515
+
516
+ attribute :user_defined_json, :json
517
+ end
518
+
519
+ topic = klass.new(user_defined_json: { key: "value" })
520
+ assert_predicate topic, :user_defined_json?
521
+
522
+ topic = klass.new(user_defined_json: {})
523
+ assert_not_predicate topic, :user_defined_json?
524
+ end
525
+
526
+ test "custom field attribute predicate" do
527
+ object = Company.find_by_sql(<<~SQL).first
528
+ SELECT c1.*, c2.type as string_value, c2.rating as int_value
529
+ FROM companies c1, companies c2
530
+ WHERE c1.firm_id = c2.id
531
+ AND c1.id = 2
532
+ SQL
533
+
534
+ assert_equal "Firm", object.string_value
535
+ assert_predicate object, :string_value?
536
+
537
+ object.string_value = " "
538
+ assert_not_predicate object, :string_value?
539
+
540
+ assert_equal 1, object.int_value.to_i
541
+ assert_predicate object, :int_value?
542
+
543
+ object.int_value = "0"
544
+ assert_not_predicate object, :int_value?
545
+ end
546
+
547
+ test "non-attribute read and write" do
548
+ topic = Topic.new
549
+ assert_not_respond_to topic, "mumbo"
550
+ assert_raise(NoMethodError) { topic.mumbo }
551
+ assert_raise(NoMethodError) { topic.mumbo = 5 }
552
+ end
553
+
554
+ test "undeclared attribute method does not affect respond_to? and method_missing" do
555
+ topic = @target.new(title: "Budget")
556
+ assert_respond_to topic, "title"
557
+ assert_equal "Budget", topic.title
558
+ assert_not_respond_to topic, "title_hello_world"
559
+ assert_raise(NoMethodError) { topic.title_hello_world }
560
+ end
561
+
562
+ test "declared prefixed attribute method affects respond_to? and method_missing" do
563
+ topic = @target.new(title: "Budget")
564
+ %w(default_ title_).each do |prefix|
565
+ @target.class_eval "def #{prefix}attribute(*args) args end"
566
+ @target.attribute_method_prefix prefix
567
+
568
+ meth = "#{prefix}title"
569
+ assert_respond_to topic, meth
570
+ assert_equal ["title"], topic.public_send(meth)
571
+ assert_equal ["title", "a"], topic.public_send(meth, "a")
572
+ assert_equal ["title", 1, 2, 3], topic.public_send(meth, 1, 2, 3)
573
+ end
574
+ end
575
+
576
+ test "declared suffixed attribute method affects respond_to? and method_missing" do
577
+ %w(_default _title_default _it! _candidate= able?).each do |suffix|
578
+ @target.class_eval "def attribute#{suffix}(*args) args end"
579
+ @target.attribute_method_suffix suffix
580
+ topic = @target.new(title: "Budget")
581
+
582
+ meth = "title#{suffix}"
583
+ assert_respond_to topic, meth
584
+ assert_equal ["title"], topic.public_send(meth)
585
+ assert_equal ["title", "a"], topic.public_send(meth, "a")
586
+ assert_equal ["title", 1, 2, 3], topic.public_send(meth, 1, 2, 3)
587
+ end
588
+ end
589
+
590
+ test "declared affixed attribute method affects respond_to? and method_missing" do
591
+ [["mark_", "_for_update"], ["reset_", "!"], ["default_", "_value?"]].each do |prefix, suffix|
592
+ @target.class_eval "def #{prefix}attribute#{suffix}(*args) args end"
593
+ @target.attribute_method_affix(prefix: prefix, suffix: suffix)
594
+ topic = @target.new(title: "Budget")
595
+
596
+ meth = "#{prefix}title#{suffix}"
597
+ assert_respond_to topic, meth
598
+ assert_equal ["title"], topic.public_send(meth)
599
+ assert_equal ["title", "a"], topic.public_send(meth, "a")
600
+ assert_equal ["title", 1, 2, 3], topic.public_send(meth, 1, 2, 3)
601
+ end
602
+ end
603
+
604
+ test "should unserialize attributes for frozen records" do
605
+ myobj = { value1: :value2 }
606
+ topic = Topic.create(content: myobj)
607
+ topic.freeze
608
+ assert_equal myobj, topic.content
609
+ end
610
+
611
+ test "typecast attribute from select to false" do
612
+ Topic.create(title: "Budget")
613
+ # Oracle does not support boolean expressions in SELECT.
614
+ if current_adapter?(:OracleAdapter) or current_adapter?(:IBM_DBAdapter)
615
+ topic = Topic.all.merge!(select: "topics.*, 0 as is_test").first
616
+ else
617
+ topic = Topic.all.merge!(select: "topics.*, 1=2 as is_test").first
618
+ end
619
+ assert_not_predicate topic, :is_test?
620
+ end
621
+
622
+ test "typecast attribute from select to true" do
623
+ Topic.create(title: "Budget")
624
+ # Oracle does not support boolean expressions in SELECT.
625
+ if current_adapter?(:OracleAdapter) or current_adapter?(:IBM_DBAdapter)
626
+ topic = Topic.all.merge!(select: "topics.*, 1 as is_test").first
627
+ else
628
+ topic = Topic.all.merge!(select: "topics.*, 2=2 as is_test").first
629
+ end
630
+ assert_predicate topic, :is_test?
631
+ end
632
+
633
+ test "raises ActiveRecord::DangerousAttributeError when defining an AR method in a model" do
634
+ %w(save create_or_update).each do |method|
635
+ klass = Class.new(ActiveRecord::Base)
636
+ klass.class_eval "def #{method}() 'defined #{method}' end"
637
+ assert_raise ActiveRecord::DangerousAttributeError do
638
+ klass.instance_method_already_implemented?(method)
639
+ end
640
+ end
641
+ end
642
+
643
+ test "converted values are returned after assignment" do
644
+ developer = Developer.new(name: 1337, salary: "50000")
645
+
646
+ assert_equal "50000", developer.salary_before_type_cast
647
+ assert_equal 1337, developer.name_before_type_cast
648
+
649
+ assert_equal 50000, developer.salary
650
+ assert_equal "1337", developer.name
651
+
652
+ developer.save!
653
+
654
+ assert_equal 50000, developer.salary
655
+ assert_equal "1337", developer.name
656
+ end
657
+
658
+ test "write nil to time attribute" do
659
+ in_time_zone "Pacific Time (US & Canada)" do
660
+ record = @target.new
661
+ record.written_on = nil
662
+ assert_nil record.written_on
663
+ end
664
+ end
665
+
666
+ test "write time to date attribute" do
667
+ in_time_zone "Pacific Time (US & Canada)" do
668
+ record = @target.new
669
+ record.last_read = Time.utc(2010, 1, 1, 10)
670
+ assert_equal Date.civil(2010, 1, 1), record.last_read
671
+ end
672
+ end
673
+
674
+ test "time attributes are retrieved in the current time zone" do
675
+ in_time_zone "Pacific Time (US & Canada)" do
676
+ utc_time = Time.utc(2008, 1, 1)
677
+ record = @target.new
678
+ record[:written_on] = utc_time
679
+ assert_equal utc_time, record.written_on # record.written on is equal to (i.e., simultaneous with) utc_time
680
+ assert_kind_of ActiveSupport::TimeWithZone, record.written_on # but is a TimeWithZone
681
+ assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.written_on.time_zone # and is in the current Time.zone
682
+ assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time # and represents time values adjusted accordingly
683
+ end
684
+ end
685
+
686
+ test "setting a time zone-aware attribute to UTC" do
687
+ in_time_zone "Pacific Time (US & Canada)" do
688
+ utc_time = Time.utc(2008, 1, 1)
689
+ record = @target.new
690
+ record.written_on = utc_time
691
+ assert_equal utc_time, record.written_on
692
+ assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.written_on.time_zone
693
+ assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time
694
+ end
695
+ end
696
+
697
+ test "setting time zone-aware attribute in other time zone" do
698
+ utc_time = Time.utc(2008, 1, 1)
699
+ cst_time = utc_time.in_time_zone("Central Time (US & Canada)")
700
+ in_time_zone "Pacific Time (US & Canada)" do
701
+ record = @target.new
702
+ record.written_on = cst_time
703
+ assert_equal utc_time, record.written_on
704
+ assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.written_on.time_zone
705
+ assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time
706
+ end
707
+ end
708
+
709
+ test "setting time zone-aware read attribute" do
710
+ utc_time = Time.utc(2008, 1, 1)
711
+ cst_time = utc_time.in_time_zone("Central Time (US & Canada)")
712
+ in_time_zone "Pacific Time (US & Canada)" do
713
+ record = @target.create(written_on: cst_time).reload
714
+ assert_equal utc_time, record[:written_on]
715
+ assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record[:written_on].time_zone
716
+ assert_equal Time.utc(2007, 12, 31, 16), record[:written_on].time
717
+ end
718
+ end
719
+
720
+ test "setting time zone-aware attribute with a string" do
721
+ utc_time = Time.utc(2008, 1, 1)
722
+ (-11..13).each do |timezone_offset|
723
+ time_string = utc_time.in_time_zone(timezone_offset).to_s
724
+ in_time_zone "Pacific Time (US & Canada)" do
725
+ record = @target.new
726
+ record.written_on = time_string
727
+ assert_equal Time.zone.parse(time_string), record.written_on
728
+ assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.written_on.time_zone
729
+ assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time
730
+ end
731
+ end
732
+ end
733
+
734
+ test "time zone-aware attribute saved" do
735
+ in_time_zone 1 do
736
+ record = @target.create(written_on: "2012-02-20 10:00")
737
+
738
+ record.written_on = "2012-02-20 09:00"
739
+ record.save
740
+ assert_equal Time.zone.local(2012, 02, 20, 9), record.reload.written_on
741
+ end
742
+ end
743
+
744
+ test "setting a time zone-aware attribute to a blank string returns nil" do
745
+ in_time_zone "Pacific Time (US & Canada)" do
746
+ record = @target.new
747
+ record.written_on = " "
748
+ assert_nil record.written_on
749
+ assert_nil record[:written_on]
750
+ end
751
+ end
752
+
753
+ test "setting a time zone-aware attribute interprets time zone-unaware string in time zone" do
754
+ time_string = "Tue Jan 01 00:00:00 2008"
755
+ (-11..13).each do |timezone_offset|
756
+ in_time_zone timezone_offset do
757
+ record = @target.new
758
+ record.written_on = time_string
759
+ assert_equal Time.zone.parse(time_string), record.written_on
760
+ assert_equal ActiveSupport::TimeZone[timezone_offset], record.written_on.time_zone
761
+ assert_equal Time.utc(2008, 1, 1), record.written_on.time
762
+ end
763
+ end
764
+ end
765
+
766
+ test "setting a time zone-aware datetime in the current time zone" do
767
+ utc_time = Time.utc(2008, 1, 1)
768
+ in_time_zone "Pacific Time (US & Canada)" do
769
+ record = @target.new
770
+ record.written_on = utc_time.in_time_zone
771
+ assert_equal utc_time, record.written_on
772
+ assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.written_on.time_zone
773
+ assert_equal Time.utc(2007, 12, 31, 16), record.written_on.time
774
+ end
775
+ end
776
+
777
+ test "YAML dumping a record with time zone-aware attribute" do
778
+ in_time_zone "Pacific Time (US & Canada)" do
779
+ record = Topic.new(id: 1)
780
+ record.written_on = "Jan 01 00:00:00 2014"
781
+ payload = YAML.dump(record)
782
+ assert_equal record, YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(payload) : YAML.load(payload)
783
+ end
784
+ ensure
785
+ # NOTE: Reset column info because global topics
786
+ # don't have tz-aware attributes by default.
787
+ Topic.reset_column_information
788
+ end
789
+
790
+ test "setting a time zone-aware time in the current time zone" do
791
+ in_time_zone "Pacific Time (US & Canada)" do
792
+ record = @target.new
793
+ time_string = "10:00:00"
794
+ expected_time = Time.zone.parse("2000-01-01 #{time_string}")
795
+
796
+ record.bonus_time = time_string
797
+ assert_equal expected_time, record.bonus_time
798
+ assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.bonus_time.time_zone
799
+
800
+ record.bonus_time = ""
801
+ assert_nil record.bonus_time
802
+ end
803
+ end
804
+
805
+ test "setting a time zone-aware time with DST" do
806
+ in_time_zone "Pacific Time (US & Canada)" do
807
+ current_time = Time.zone.local(2014, 06, 15, 10)
808
+ record = @target.new(bonus_time: current_time)
809
+ time_before_save = record.bonus_time
810
+
811
+ record.save
812
+ record.reload
813
+
814
+ assert_equal time_before_save, record.bonus_time
815
+ assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.bonus_time.time_zone
816
+ end
817
+ end
818
+
819
+ test "setting invalid string to a zone-aware time attribute" do
820
+ in_time_zone "Pacific Time (US & Canada)" do
821
+ record = @target.new
822
+ time_string = "ABC"
823
+
824
+ record.bonus_time = time_string
825
+ assert_nil record.bonus_time
826
+ end
827
+ end
828
+
829
+ test "removing time zone-aware types" do
830
+ with_time_zone_aware_types(:datetime) do
831
+ in_time_zone "Pacific Time (US & Canada)" do
832
+ record = @target.new(bonus_time: "10:00:00")
833
+ expected_time = Time.utc(2000, 01, 01, 10)
834
+
835
+ assert_equal expected_time, record.bonus_time
836
+ assert_predicate record.bonus_time, :utc?
837
+ end
838
+ end
839
+ end
840
+
841
+ test "time zone-aware attributes do not recurse infinitely on invalid values" do
842
+ in_time_zone "Pacific Time (US & Canada)" do
843
+ record = @target.new(bonus_time: [])
844
+ assert_nil record.bonus_time
845
+ end
846
+ end
847
+
848
+ test "setting a time_zone_conversion_for_attributes should write the value on a class variable" do
849
+ Topic.skip_time_zone_conversion_for_attributes = [:field_a]
850
+ Minimalistic.skip_time_zone_conversion_for_attributes = [:field_b]
851
+
852
+ assert_equal [:field_a], Topic.skip_time_zone_conversion_for_attributes
853
+ assert_equal [:field_b], Minimalistic.skip_time_zone_conversion_for_attributes
854
+ end
855
+
856
+ test "attribute readers respect access control" do
857
+ privatize("title")
858
+
859
+ topic = @target.new(title: "The pros and cons of programming naked.")
860
+ assert_not_respond_to topic, :title
861
+ exception = assert_raise(NoMethodError) { topic.title }
862
+ assert_includes exception.message, "private method"
863
+ assert_equal "I'm private", topic.send(:title)
864
+ end
865
+
866
+ test "attribute writers respect access control" do
867
+ privatize("title=(value)")
868
+
869
+ topic = @target.new
870
+ assert_not_respond_to topic, :title=
871
+ exception = assert_raise(NoMethodError) { topic.title = "Pants" }
872
+ assert_includes exception.message, "private method"
873
+ topic.send(:title=, "Very large pants")
874
+ end
875
+
876
+ test "attribute predicates respect access control" do
877
+ privatize("title?")
878
+
879
+ topic = @target.new(title: "Isaac Newton's pants")
880
+ assert_not_respond_to topic, :title?
881
+ exception = assert_raise(NoMethodError) { topic.title? }
882
+ assert_includes exception.message, "private method"
883
+ assert topic.send(:title?)
884
+ end
885
+
886
+ test "bulk updates respect access control" do
887
+ privatize("title=(value)")
888
+
889
+ assert_raise(ActiveRecord::UnknownAttributeError) { @target.new(title: "Rants about pants") }
890
+ assert_raise(ActiveRecord::UnknownAttributeError) { @target.new.attributes = { title: "Ants in pants" } }
891
+ end
892
+
893
+ test "bulk update raises ActiveRecord::UnknownAttributeError" do
894
+ error = assert_raises(ActiveRecord::UnknownAttributeError) {
895
+ Topic.new(hello: "world")
896
+ }
897
+ assert_instance_of Topic, error.record
898
+ assert_equal "hello", error.attribute
899
+ assert_match "unknown attribute 'hello' for Topic.", error.message
900
+ end
901
+
902
+ test "method overrides in multi-level subclasses" do
903
+ klass = Class.new(Developer) do
904
+ def name
905
+ "dev:#{read_attribute(:name)}"
906
+ end
907
+ end
908
+
909
+ 2.times { klass = Class.new(klass) }
910
+ dev = klass.new(name: "arthurnn")
911
+ dev.save!
912
+ assert_equal "dev:arthurnn", dev.reload.name
913
+ end
914
+
915
+ test "global methods are overwritten" do
916
+ klass = Class.new(ActiveRecord::Base) do
917
+ self.table_name = "computers"
918
+ end
919
+
920
+ assert_not klass.instance_method_already_implemented?(:system)
921
+ computer = klass.new
922
+ assert_nil computer.system
923
+ end
924
+
925
+ test "global methods are overwritten when subclassing" do
926
+ klass = Class.new(ActiveRecord::Base) do
927
+ self.abstract_class = true
928
+ end
929
+
930
+ subklass = Class.new(klass) do
931
+ self.table_name = "computers"
932
+ end
933
+
934
+ assert_not klass.instance_method_already_implemented?(:system)
935
+ assert_not subklass.instance_method_already_implemented?(:system)
936
+ computer = subklass.new
937
+ assert_nil computer.system
938
+ end
939
+
940
+ test "instance methods should be defined on the base class" do
941
+ subklass = Class.new(Topic)
942
+
943
+ Topic.define_attribute_methods
944
+
945
+ instance = subklass.new
946
+ instance.id = 5
947
+ assert_equal 5, instance.id
948
+ assert subklass.method_defined?(:id), "subklass is missing id method"
949
+
950
+ Topic.undefine_attribute_methods
951
+
952
+ assert_equal 5, instance.id
953
+ assert subklass.method_defined?(:id), "subklass is missing id method"
954
+ end
955
+
956
+ test "define_attribute_method works with both symbol and string" do
957
+ klass = Class.new(ActiveRecord::Base)
958
+
959
+ assert_nothing_raised { klass.define_attribute_method(:foo) }
960
+ assert_nothing_raised { klass.define_attribute_method("bar") }
961
+ end
962
+
963
+ test "read_attribute with nil should not asplode" do
964
+ assert_nil Topic.new.read_attribute(nil)
965
+ end
966
+
967
+ # If B < A, and A defines an accessor for 'foo', we don't want to override
968
+ # that by defining a 'foo' method in the generated methods module for B.
969
+ # (That module will be inserted between the two, e.g. [B, <GeneratedAttributes>, A].)
970
+ test "inherited custom accessors" do
971
+ klass = new_topic_like_ar_class do
972
+ self.abstract_class = true
973
+ def title; "omg"; end
974
+ def title=(val); self.author_name = val; end
975
+ end
976
+ subklass = Class.new(klass)
977
+ [klass, subklass].each(&:define_attribute_methods)
978
+
979
+ topic = subklass.find(1)
980
+ assert_equal "omg", topic.title
981
+
982
+ topic.title = "lol"
983
+ assert_equal "lol", topic.author_name
984
+ end
985
+
986
+ test "inherited custom accessors with reserved names" do
987
+ klass = Class.new(ActiveRecord::Base) do
988
+ self.table_name = "computers"
989
+ self.abstract_class = true
990
+ def system; "omg"; end
991
+ def system=(val); self.developer = val; end
992
+ end
993
+
994
+ subklass = Class.new(klass)
995
+ [klass, subklass].each(&:define_attribute_methods)
996
+
997
+ computer = subklass.find(1)
998
+ assert_equal "omg", computer.system
999
+
1000
+ computer.developer = 99
1001
+ assert_equal 99, computer.developer
1002
+ end
1003
+
1004
+ test "on_the_fly_super_invokable_generated_attribute_methods_via_method_missing" do
1005
+ klass = new_topic_like_ar_class do
1006
+ def title
1007
+ super + "!"
1008
+ end
1009
+ end
1010
+
1011
+ real_topic = topics(:first)
1012
+ assert_equal real_topic.title + "!", klass.find(real_topic.id).title
1013
+ end
1014
+
1015
+ test "on-the-fly super-invokable generated attribute predicates via method_missing" do
1016
+ klass = new_topic_like_ar_class do
1017
+ def title?
1018
+ !super
1019
+ end
1020
+ end
1021
+
1022
+ real_topic = topics(:first)
1023
+ assert_equal !real_topic.title?, klass.find(real_topic.id).title?
1024
+ end
1025
+
1026
+ test "calling super when the parent does not define method raises NoMethodError" do
1027
+ klass = new_topic_like_ar_class do
1028
+ def some_method_that_is_not_on_super
1029
+ super
1030
+ end
1031
+ end
1032
+
1033
+ assert_raise(NoMethodError) do
1034
+ klass.new.some_method_that_is_not_on_super
1035
+ end
1036
+ end
1037
+
1038
+ test "attribute_method?" do
1039
+ assert @target.attribute_method?(:title)
1040
+ assert @target.attribute_method?(:title=)
1041
+ assert_not @target.attribute_method?(:wibble)
1042
+ end
1043
+
1044
+ test "attribute_method? returns false if the table does not exist" do
1045
+ @target.table_name = "wibble"
1046
+ assert_not @target.attribute_method?(:title)
1047
+ end
1048
+
1049
+ test "attribute_names on a new record" do
1050
+ model = @target.new
1051
+
1052
+ assert_equal @target.column_names, model.attribute_names
1053
+ end
1054
+
1055
+ test "attribute_names on a queried record" do
1056
+ model = @target.last!
1057
+
1058
+ assert_equal @target.column_names, model.attribute_names
1059
+ end
1060
+
1061
+ test "attribute_names with a custom select" do
1062
+ model = @target.select("id").last!
1063
+
1064
+ assert_equal ["id"], model.attribute_names
1065
+ # Sanity check, make sure other columns exist.
1066
+ assert_not_equal ["id"], @target.column_names
1067
+ end
1068
+
1069
+ test "came_from_user?" do
1070
+ model = @target.first
1071
+
1072
+ assert_not_predicate model, :id_came_from_user?
1073
+ model.id = "omg"
1074
+ assert_predicate model, :id_came_from_user?
1075
+ end
1076
+
1077
+ test "accessed_fields" do
1078
+ model = @target.first
1079
+
1080
+ assert_equal [], model.accessed_fields
1081
+
1082
+ model.title
1083
+
1084
+ assert_equal ["title"], model.accessed_fields
1085
+ end
1086
+
1087
+ test "generated attribute methods ancestors have correct module" do
1088
+ mod = Topic.send(:generated_attribute_methods)
1089
+ assert_equal "Topic::GeneratedAttributeMethods", mod.inspect
1090
+ end
1091
+
1092
+ test "read_attribute_before_type_cast with aliased attribute" do
1093
+ model = NumericData.new(new_bank_balance: "abcd")
1094
+ assert_equal "abcd", model.read_attribute_before_type_cast("new_bank_balance")
1095
+ end
1096
+
1097
+ private
1098
+ def new_topic_like_ar_class(&block)
1099
+ klass = Class.new(ActiveRecord::Base) do
1100
+ self.table_name = "topics"
1101
+ class_eval(&block)
1102
+ end
1103
+
1104
+ assert_empty klass.send(:generated_attribute_methods).instance_methods(false)
1105
+ klass
1106
+ end
1107
+
1108
+ def with_time_zone_aware_types(*types)
1109
+ old_types = ActiveRecord::Base.time_zone_aware_types
1110
+ ActiveRecord::Base.time_zone_aware_types = types
1111
+ yield
1112
+ ensure
1113
+ ActiveRecord::Base.time_zone_aware_types = old_types
1114
+ end
1115
+
1116
+ def privatize(method_signature)
1117
+ @target.class_eval(<<-private_method, __FILE__, __LINE__ + 1)
1118
+ private
1119
+ def #{method_signature}
1120
+ "I'm private"
1121
+ end
1122
+ private_method
1123
+ end
1124
+ end