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,872 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "models/developer"
5
+ require "models/computer"
6
+ require "models/project"
7
+ require "models/company"
8
+ require "models/ship"
9
+ require "models/pirate"
10
+ require "models/car"
11
+ require "models/bulb"
12
+ require "models/author"
13
+ require "models/image"
14
+ require "models/post"
15
+ require "models/drink_designer"
16
+ require "models/chef"
17
+ require "models/department"
18
+ require "models/club"
19
+ require "models/membership"
20
+
21
+ class HasOneAssociationsTest < ActiveRecord::TestCase
22
+ self.use_transactional_tests = false unless supports_savepoints?
23
+ fixtures :accounts, :companies, :developers, :projects, :developers_projects,
24
+ :ships, :pirates, :authors, :author_addresses, :books, :memberships, :clubs
25
+
26
+ def setup
27
+ Account.destroyed_account_ids.clear
28
+ end
29
+
30
+ def test_has_one
31
+ firm = companies(:first_firm)
32
+ first_account = Account.find(1)
33
+ assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) do
34
+ assert_equal first_account, firm.account
35
+ assert_equal first_account.credit_limit, firm.account.credit_limit
36
+ end
37
+ end
38
+
39
+ def test_has_one_does_not_use_order_by
40
+ sql_log = capture_sql { companies(:first_firm).account }
41
+ assert sql_log.all? { |sql| !/order by/i.match?(sql) }, "ORDER BY was used in the query: #{sql_log}"
42
+ end
43
+
44
+ def test_has_one_cache_nils
45
+ firm = companies(:another_firm)
46
+ assert_queries(1) { assert_nil firm.account }
47
+ assert_no_queries { assert_nil firm.account }
48
+
49
+ firms = Firm.includes(:account).to_a
50
+ assert_no_queries { firms.each(&:account) }
51
+ end
52
+
53
+ def test_with_select
54
+ assert_equal Firm.find(1).account_with_select.attributes.size, 2
55
+ assert_equal Firm.all.merge!(includes: :account_with_select).find(1).account_with_select.attributes.size, 2
56
+ end
57
+
58
+ def test_finding_using_primary_key
59
+ firm = companies(:first_firm)
60
+ assert_equal Account.find_by_firm_id(firm.id), firm.account
61
+ firm.firm_id = companies(:rails_core).id
62
+ assert_equal accounts(:rails_core_account), firm.account_using_primary_key
63
+ end
64
+
65
+ def test_update_with_foreign_and_primary_keys
66
+ firm = companies(:first_firm)
67
+ account = firm.account_using_foreign_and_primary_keys
68
+ assert_equal Account.find_by_firm_name(firm.name), account
69
+ firm.save
70
+ firm.reload
71
+ assert_equal account, firm.account_using_foreign_and_primary_keys
72
+ end
73
+
74
+ def test_can_marshal_has_one_association_with_nil_target
75
+ firm = Firm.new
76
+ assert_nothing_raised do
77
+ assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
78
+ end
79
+
80
+ firm.account
81
+ assert_nothing_raised do
82
+ assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes
83
+ end
84
+ end
85
+
86
+ def test_proxy_assignment
87
+ company = companies(:first_firm)
88
+ assert_nothing_raised { company.account = company.account }
89
+ end
90
+
91
+ def test_type_mismatch
92
+ assert_raise(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = 1 }
93
+ assert_raise(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = Project.find(1) }
94
+ end
95
+
96
+ def test_natural_assignment
97
+ apple = Firm.create("name" => "Apple")
98
+ citibank = Account.create("credit_limit" => 10)
99
+ apple.account = citibank
100
+ assert_equal apple.id, citibank.firm_id
101
+ end
102
+
103
+ def test_natural_assignment_to_nil
104
+ old_account_id = companies(:first_firm).account.id
105
+ companies(:first_firm).account = nil
106
+ companies(:first_firm).save
107
+ assert_nil companies(:first_firm).account
108
+ # account is dependent, therefore is destroyed when reference to owner is lost
109
+ assert_raise(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
110
+ end
111
+
112
+ def test_nullification_on_association_change
113
+ firm = companies(:rails_core)
114
+ old_account_id = firm.account.id
115
+ firm.account = Account.new(credit_limit: 5)
116
+ # account is dependent with nullify, therefore its firm_id should be nil
117
+ assert_nil Account.find(old_account_id).firm_id
118
+ end
119
+
120
+ def test_nullify_on_polymorphic_association
121
+ department = Department.create!
122
+ designer = DrinkDesignerWithPolymorphicDependentNullifyChef.create!
123
+ chef = department.chefs.create!(employable: designer)
124
+
125
+ assert_equal chef.employable_id, designer.id
126
+ assert_equal chef.employable_type, designer.class.name
127
+
128
+ designer.destroy!
129
+ chef.reload
130
+
131
+ assert_nil chef.employable_id
132
+ assert_nil chef.employable_type
133
+ end
134
+
135
+ def test_nullification_on_destroyed_association
136
+ developer = Developer.create!(name: "Someone")
137
+ ship = Ship.create!(name: "Planet Caravan", developer: developer)
138
+ ship.destroy
139
+ assert_not_predicate ship, :persisted?
140
+ assert_not_predicate developer, :persisted?
141
+ end
142
+
143
+ def test_natural_assignment_to_nil_after_destroy
144
+ firm = companies(:rails_core)
145
+ old_account_id = firm.account.id
146
+ firm.account.destroy
147
+ firm.account = nil
148
+ assert_nil companies(:rails_core).account
149
+ assert_raise(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
150
+ end
151
+
152
+ def test_association_change_calls_delete
153
+ companies(:first_firm).deletable_account = Account.new(credit_limit: 5)
154
+ assert_equal [], Account.destroyed_account_ids[companies(:first_firm).id]
155
+ end
156
+
157
+ def test_association_change_calls_destroy
158
+ companies(:first_firm).account = Account.new(credit_limit: 5)
159
+ assert_equal [companies(:first_firm).id], Account.destroyed_account_ids[companies(:first_firm).id]
160
+ end
161
+
162
+ def test_natural_assignment_to_already_associated_record
163
+ company = companies(:first_firm)
164
+ account = accounts(:signals37)
165
+ assert_equal company.account, account
166
+ company.account = account
167
+ company.reload
168
+ account.reload
169
+ assert_equal company.account, account
170
+ end
171
+
172
+ def test_dependence
173
+ num_accounts = Account.count
174
+
175
+ firm = Firm.find(1)
176
+ assert_not_nil firm.account
177
+ account_id = firm.account.id
178
+ assert_equal [], Account.destroyed_account_ids[firm.id]
179
+
180
+ firm.destroy
181
+ assert_equal num_accounts - 1, Account.count
182
+ assert_equal [account_id], Account.destroyed_account_ids[firm.id]
183
+ end
184
+
185
+ def test_exclusive_dependence
186
+ num_accounts = Account.count
187
+
188
+ firm = ExclusivelyDependentFirm.find(9)
189
+ assert_not_nil firm.account
190
+ assert_equal [], Account.destroyed_account_ids[firm.id]
191
+
192
+ firm.destroy
193
+ assert_equal num_accounts - 1, Account.count
194
+ assert_equal [], Account.destroyed_account_ids[firm.id]
195
+ end
196
+
197
+ def test_dependence_with_nil_associate
198
+ firm = DependentFirm.new(name: "nullify")
199
+ firm.save!
200
+ assert_nothing_raised { firm.destroy }
201
+ end
202
+
203
+ def test_restrict_with_exception
204
+ firm = RestrictedWithExceptionFirm.create!(name: "restrict")
205
+ firm.create_account(credit_limit: 10)
206
+
207
+ assert_not_nil firm.account
208
+
209
+ assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy }
210
+ assert RestrictedWithExceptionFirm.exists?(name: "restrict")
211
+ assert_predicate firm.account, :present?
212
+ end
213
+
214
+ def test_restrict_with_error
215
+ firm = RestrictedWithErrorFirm.create!(name: "restrict")
216
+ firm.create_account(credit_limit: 10)
217
+
218
+ assert_not_nil firm.account
219
+
220
+ firm.destroy
221
+
222
+ assert_not_empty firm.errors
223
+ assert_equal "Cannot delete record because a dependent account exists", firm.errors[:base].first
224
+ assert RestrictedWithErrorFirm.exists?(name: "restrict")
225
+ assert_predicate firm.account, :present?
226
+ end
227
+
228
+ def test_restrict_with_error_with_locale
229
+ I18n.backend = I18n::Backend::Simple.new
230
+ I18n.backend.store_translations "en", activerecord: { attributes: { restricted_with_error_firm: { account: "firm account" } } }
231
+ firm = RestrictedWithErrorFirm.create!(name: "restrict")
232
+ firm.create_account(credit_limit: 10)
233
+
234
+ assert_not_nil firm.account
235
+
236
+ firm.destroy
237
+
238
+ assert_not_empty firm.errors
239
+ assert_equal "Cannot delete record because a dependent firm account exists", firm.errors[:base].first
240
+ assert RestrictedWithErrorFirm.exists?(name: "restrict")
241
+ assert_predicate firm.account, :present?
242
+ ensure
243
+ I18n.backend.reload!
244
+ end
245
+
246
+ def test_successful_build_association
247
+ firm = Firm.new("name" => "GlobalMegaCorp")
248
+ firm.save
249
+
250
+ account = firm.build_account("credit_limit" => 1000)
251
+ assert account.save
252
+ assert_equal account, firm.account
253
+ end
254
+
255
+ def test_build_association_dont_create_transaction
256
+ firm = Firm.new
257
+ assert_queries(0) do
258
+ firm.build_account
259
+ end
260
+ end
261
+
262
+ def test_building_the_associated_object_with_implicit_sti_base_class
263
+ firm = DependentFirm.new
264
+ company = firm.build_company
265
+ assert_kind_of Company, company, "Expected #{company.class} to be a Company"
266
+ end
267
+
268
+ def test_building_the_associated_object_with_explicit_sti_base_class
269
+ firm = DependentFirm.new
270
+ company = firm.build_company(type: "Company")
271
+ assert_kind_of Company, company, "Expected #{company.class} to be a Company"
272
+ end
273
+
274
+ def test_building_the_associated_object_with_sti_subclass
275
+ firm = DependentFirm.new
276
+ company = firm.build_company(type: "Client")
277
+ assert_kind_of Client, company, "Expected #{company.class} to be a Client"
278
+ end
279
+
280
+ def test_building_the_associated_object_with_an_invalid_type
281
+ firm = DependentFirm.new
282
+ assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(type: "Invalid") }
283
+ end
284
+
285
+ def test_building_the_associated_object_with_an_unrelated_type
286
+ firm = DependentFirm.new
287
+ assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(type: "Account") }
288
+ end
289
+
290
+ def test_build_and_create_should_not_happen_within_scope
291
+ pirate = pirates(:blackbeard)
292
+ scope = pirate.association(:foo_bulb).scope.where_values_hash
293
+
294
+ bulb = pirate.build_foo_bulb
295
+ assert_not_equal scope, bulb.scope_after_initialize.where_values_hash
296
+
297
+ bulb = pirate.create_foo_bulb
298
+ assert_not_equal scope, bulb.scope_after_initialize.where_values_hash
299
+
300
+ bulb = pirate.create_foo_bulb!
301
+ assert_not_equal scope, bulb.scope_after_initialize.where_values_hash
302
+ end
303
+
304
+ def test_create_association
305
+ firm = Firm.create(name: "GlobalMegaCorp")
306
+ account = firm.create_account(credit_limit: 1000)
307
+ assert_equal account, firm.reload.account
308
+ end
309
+
310
+ def test_create_association_with_bang
311
+ firm = Firm.create(name: "GlobalMegaCorp")
312
+ account = firm.create_account!(credit_limit: 1000)
313
+ assert_equal account, firm.reload.account
314
+ end
315
+
316
+ def test_create_association_with_bang_failing
317
+ firm = Firm.create(name: "GlobalMegaCorp")
318
+ assert_raise ActiveRecord::RecordInvalid do
319
+ firm.create_account!
320
+ end
321
+ account = firm.account
322
+ assert_not_nil account
323
+ account.credit_limit = 5
324
+ account.save
325
+ assert_equal account, firm.reload.account
326
+ end
327
+
328
+ def test_create_with_inexistent_foreign_key_failing
329
+ firm = Firm.create(name: "GlobalMegaCorp")
330
+
331
+ assert_raises(ActiveRecord::UnknownAttributeError) do
332
+ firm.create_account_with_inexistent_foreign_key
333
+ end
334
+ end
335
+
336
+ def test_create_when_parent_is_new_raises
337
+ firm = Firm.new
338
+ error = assert_raise(ActiveRecord::RecordNotSaved) do
339
+ firm.create_account
340
+ end
341
+
342
+ assert_equal "You cannot call create unless the parent is saved", error.message
343
+ end
344
+
345
+ def test_reload_association
346
+ odegy = companies(:odegy)
347
+
348
+ assert_equal 53, odegy.account.credit_limit
349
+ Account.where(id: odegy.account.id).update_all(credit_limit: 80)
350
+ assert_equal 53, odegy.account.credit_limit
351
+
352
+ assert_equal 80, odegy.reload_account.credit_limit
353
+ end
354
+
355
+ def test_reload_association_with_query_cache
356
+ odegy_id = companies(:odegy).id
357
+
358
+ connection = ActiveRecord::Base.connection
359
+ connection.enable_query_cache!
360
+ connection.clear_query_cache
361
+
362
+ # Populate the cache with a query
363
+ odegy = Company.find(odegy_id)
364
+ # Populate the cache with a second query
365
+ odegy.account
366
+
367
+ assert_equal 2, connection.query_cache.size
368
+
369
+ # Clear the cache and fetch the account again, populating the cache with a query
370
+ assert_queries(1) { odegy.reload_account }
371
+
372
+ # This query is not cached anymore, so it should make a real SQL query
373
+ assert_queries(1) { Company.find(odegy_id) }
374
+ ensure
375
+ ActiveRecord::Base.connection.disable_query_cache!
376
+ end
377
+
378
+ def test_build
379
+ firm = Firm.new("name" => "GlobalMegaCorp")
380
+ firm.save
381
+
382
+ firm.account = account = Account.new("credit_limit" => 1000)
383
+ assert_equal account, firm.account
384
+ assert account.save
385
+ assert_equal account, firm.account
386
+ end
387
+
388
+ def test_create
389
+ firm = Firm.new("name" => "GlobalMegaCorp")
390
+ firm.save
391
+ firm.account = account = Account.create("credit_limit" => 1000)
392
+ assert_equal account, firm.account
393
+ end
394
+
395
+ def test_create_before_save
396
+ firm = Firm.new("name" => "GlobalMegaCorp")
397
+ firm.account = account = Account.create("credit_limit" => 1000)
398
+ assert_equal account, firm.account
399
+ end
400
+
401
+ def test_dependence_with_missing_association
402
+ Account.destroy_all
403
+ firm = Firm.find(1)
404
+ assert_nil firm.account
405
+ firm.destroy
406
+ end
407
+
408
+ def test_dependence_with_missing_association_and_nullify
409
+ Account.destroy_all
410
+ firm = DependentFirm.first
411
+ assert_nil firm.account
412
+ firm.destroy
413
+ end
414
+
415
+ def test_finding_with_interpolated_condition
416
+ firm = Firm.first
417
+ superior = firm.clients.create(name: "SuperiorCo")
418
+ superior.rating = 10
419
+ superior.save
420
+ assert_equal 10, firm.clients_with_interpolated_conditions.first.rating
421
+ end
422
+
423
+ def test_assignment_before_child_saved
424
+ firm = Firm.find(1)
425
+ firm.account = a = Account.new("credit_limit" => 1000)
426
+ assert_predicate a, :persisted?
427
+ assert_equal a, firm.account
428
+ assert_equal a, firm.account
429
+ firm.association(:account).reload
430
+ assert_equal a, firm.account
431
+ end
432
+
433
+ def test_save_still_works_after_accessing_nil_has_one
434
+ jp = Company.new name: "Jaded Pixel"
435
+ jp.dummy_account.nil?
436
+
437
+ assert_nothing_raised do
438
+ jp.save!
439
+ end
440
+ end
441
+
442
+ def test_cant_save_readonly_association
443
+ assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_firm).readonly_account.save! }
444
+ assert_predicate companies(:first_firm).readonly_account, :readonly?
445
+ end
446
+
447
+ def test_has_one_proxy_should_not_respond_to_private_methods
448
+ assert_raise(NoMethodError) { accounts(:signals37).private_method }
449
+ assert_raise(NoMethodError) { companies(:first_firm).account.private_method }
450
+ end
451
+
452
+ def test_has_one_proxy_should_respond_to_private_methods_via_send
453
+ accounts(:signals37).send(:private_method)
454
+ companies(:first_firm).account.send(:private_method)
455
+ end
456
+
457
+ def test_save_of_record_with_loaded_has_one
458
+ @firm = companies(:first_firm)
459
+ assert_not_nil @firm.account
460
+
461
+ assert_nothing_raised do
462
+ Firm.find(@firm.id).save!
463
+ Firm.all.merge!(includes: :account).find(@firm.id).save!
464
+ end
465
+
466
+ @firm.account.destroy
467
+
468
+ assert_nothing_raised do
469
+ Firm.find(@firm.id).save!
470
+ Firm.all.merge!(includes: :account).find(@firm.id).save!
471
+ end
472
+ end
473
+
474
+ def test_build_respects_hash_condition
475
+ account = companies(:first_firm).build_account_limit_500_with_hash_conditions
476
+ assert account.save
477
+ assert_equal 500, account.credit_limit
478
+ end
479
+
480
+ def test_create_respects_hash_condition
481
+ account = companies(:first_firm).create_account_limit_500_with_hash_conditions
482
+ assert_predicate account, :persisted?
483
+ assert_equal 500, account.credit_limit
484
+ end
485
+
486
+ def test_attributes_are_being_set_when_initialized_from_has_one_association_with_where_clause
487
+ new_account = companies(:first_firm).build_account(firm_name: "Account")
488
+ assert_equal new_account.firm_name, "Account"
489
+ end
490
+
491
+ def test_creation_failure_without_dependent_option
492
+ pirate = pirates(:blackbeard)
493
+ orig_ship = pirate.ship
494
+
495
+ assert_equal ships(:black_pearl), orig_ship
496
+ new_ship = pirate.create_ship
497
+ assert_not_equal ships(:black_pearl), new_ship
498
+ assert_equal new_ship, pirate.ship
499
+ assert_predicate new_ship, :new_record?
500
+ assert_nil orig_ship.pirate_id
501
+ assert_not orig_ship.changed? # check it was saved
502
+ end
503
+
504
+ def test_creation_failure_with_dependent_option
505
+ pirate = pirates(:blackbeard).becomes(DestructivePirate)
506
+ orig_ship = pirate.dependent_ship
507
+
508
+ new_ship = pirate.create_dependent_ship
509
+ assert_predicate new_ship, :new_record?
510
+ assert_predicate orig_ship, :destroyed?
511
+ end
512
+
513
+ def test_creation_failure_due_to_new_record_should_raise_error
514
+ pirate = pirates(:redbeard)
515
+ new_ship = Ship.new
516
+
517
+ error = assert_raise(ActiveRecord::RecordNotSaved) do
518
+ pirate.ship = new_ship
519
+ end
520
+
521
+ assert_equal "Failed to save the new associated ship.", error.message
522
+ assert_nil pirate.ship
523
+ assert_nil new_ship.pirate_id
524
+ end
525
+
526
+ def test_replacement_failure_due_to_existing_record_should_raise_error
527
+ pirate = pirates(:blackbeard)
528
+ pirate.ship.name = nil
529
+
530
+ assert_not_predicate pirate.ship, :valid?
531
+ error = assert_raise(ActiveRecord::RecordNotSaved) do
532
+ pirate.ship = ships(:interceptor)
533
+ end
534
+
535
+ assert_equal ships(:black_pearl), pirate.ship
536
+ assert_equal pirate.id, pirate.ship.pirate_id
537
+ assert_equal "Failed to remove the existing associated ship. " \
538
+ "The record failed to save after its foreign key was set to nil.", error.message
539
+ end
540
+
541
+ def test_replacement_failure_due_to_new_record_should_raise_error
542
+ pirate = pirates(:blackbeard)
543
+ new_ship = Ship.new
544
+
545
+ error = assert_raise(ActiveRecord::RecordNotSaved) do
546
+ pirate.ship = new_ship
547
+ end
548
+
549
+ assert_equal "Failed to save the new associated ship.", error.message
550
+ assert_equal ships(:black_pearl), pirate.ship
551
+ assert_equal pirate.id, pirate.ship.pirate_id
552
+ assert_equal pirate.id, ships(:black_pearl).reload.pirate_id
553
+ assert_nil new_ship.pirate_id
554
+ end
555
+
556
+ def test_association_keys_bypass_attribute_protection
557
+ car = Car.create(name: "honda")
558
+
559
+ bulb = car.build_bulb
560
+ assert_equal car.id, bulb.car_id
561
+
562
+ bulb = car.build_bulb car_id: car.id + 1
563
+ assert_equal car.id, bulb.car_id
564
+
565
+ bulb = car.create_bulb
566
+ assert_equal car.id, bulb.car_id
567
+
568
+ bulb = car.create_bulb car_id: car.id + 1
569
+ assert_equal car.id, bulb.car_id
570
+ end
571
+
572
+ def test_association_protect_foreign_key
573
+ pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?")
574
+
575
+ ship = pirate.build_ship
576
+ assert_equal pirate.id, ship.pirate_id
577
+
578
+ ship = pirate.build_ship pirate_id: pirate.id + 1
579
+ assert_equal pirate.id, ship.pirate_id
580
+
581
+ ship = pirate.create_ship
582
+ assert_equal pirate.id, ship.pirate_id
583
+
584
+ ship = pirate.create_ship pirate_id: pirate.id + 1
585
+ assert_equal pirate.id, ship.pirate_id
586
+ end
587
+
588
+ def test_build_with_block
589
+ car = Car.create(name: "honda")
590
+
591
+ bulb = car.build_bulb { |b| b.color = "Red" }
592
+ assert_equal "RED!", bulb.color
593
+ end
594
+
595
+ def test_create_with_block
596
+ car = Car.create(name: "honda")
597
+
598
+ bulb = car.create_bulb { |b| b.color = "Red" }
599
+ assert_equal "RED!", bulb.color
600
+ end
601
+
602
+ def test_create_bang_with_block
603
+ car = Car.create(name: "honda")
604
+
605
+ bulb = car.create_bulb! { |b| b.color = "Red" }
606
+ assert_equal "RED!", bulb.color
607
+ end
608
+
609
+ def test_association_attributes_are_available_to_after_initialize
610
+ car = Car.create(name: "honda")
611
+ bulb = car.create_bulb
612
+
613
+ assert_equal car.id, bulb.attributes_after_initialize["car_id"]
614
+ end
615
+
616
+ def test_has_one_transaction
617
+ company = companies(:first_firm)
618
+ account = Account.find(1)
619
+
620
+ company.account # force loading
621
+ assert_no_queries { company.account = account }
622
+
623
+ company.account = nil
624
+ assert_no_queries { company.account = nil }
625
+ account = Account.find(2)
626
+ assert_queries { company.account = account }
627
+
628
+ assert_no_queries { Firm.new.account = account }
629
+ end
630
+
631
+ def test_has_one_assignment_dont_trigger_save_on_change_of_same_object
632
+ pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?")
633
+ ship = pirate.build_ship(name: "old name")
634
+ ship.save!
635
+
636
+ ship.name = "new name"
637
+ assert_predicate ship, :changed?
638
+ assert_queries(1) do
639
+ # One query for updating name, not triggering query for updating pirate_id
640
+ pirate.ship = ship
641
+ end
642
+
643
+ assert_equal "new name", pirate.ship.reload.name
644
+ end
645
+
646
+ def test_has_one_assignment_triggers_save_on_change_on_replacing_object
647
+ pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?")
648
+ ship = pirate.build_ship(name: "old name")
649
+ ship.save!
650
+
651
+ new_ship = Ship.create(name: "new name")
652
+ assert_queries(2) do
653
+ # One query to nullify the old ship, one query to update the new ship
654
+ pirate.ship = new_ship
655
+ end
656
+
657
+ assert_equal "new name", pirate.ship.reload.name
658
+ end
659
+
660
+ def test_has_one_autosave_with_primary_key_manually_set
661
+ post = Post.create(id: 1234, title: "Some title", body: "Some content")
662
+ author = Author.new(id: 33, name: "Hank Moody")
663
+
664
+ author.post = post
665
+ author.save
666
+ author.reload
667
+
668
+ assert_not_nil author.post
669
+ assert_equal author.post, post
670
+ end
671
+
672
+ def test_has_one_loading_for_new_record
673
+ post = Post.create!(author_id: 42, title: "foo", body: "bar")
674
+ author = Author.new(id: 42)
675
+ assert_equal post, author.post
676
+ end
677
+
678
+ def test_has_one_relationship_cannot_have_a_counter_cache
679
+ assert_raise(ArgumentError) do
680
+ Class.new(ActiveRecord::Base) do
681
+ has_one :thing, counter_cache: true
682
+ end
683
+ end
684
+ end
685
+
686
+ def test_with_polymorphic_has_one_with_custom_columns_name
687
+ post = Post.create! title: "foo", body: "bar"
688
+ image = Image.create!
689
+
690
+ post.main_image = image
691
+ post.reload
692
+
693
+ assert_equal image, post.main_image
694
+ assert_equal post, image.imageable
695
+ end
696
+
697
+ test "dangerous association name raises ArgumentError" do
698
+ [:errors, "errors", :save, "save"].each do |name|
699
+ assert_raises(ArgumentError, "Association #{name} should not be allowed") do
700
+ Class.new(ActiveRecord::Base) do
701
+ has_one name
702
+ end
703
+ end
704
+ end
705
+ end
706
+
707
+ def test_has_one_with_touch_option_on_create
708
+ assert_queries(3) {
709
+ Club.create(name: "1000 Oaks", membership_attributes: { favourite: true })
710
+ }
711
+ end
712
+
713
+ def test_polymorphic_has_one_with_touch_option_on_create_wont_cache_association_so_fetching_after_transaction_commit_works
714
+ assert_queries(4) {
715
+ chef = Chef.create(employable: DrinkDesignerWithPolymorphicTouchChef.new)
716
+ employable = chef.employable
717
+
718
+ assert_equal chef, employable.chef
719
+ }
720
+ end
721
+
722
+ def test_polymorphic_has_one_with_touch_option_on_update_will_touch_record_by_fetching_from_database_if_needed
723
+ DrinkDesignerWithPolymorphicTouchChef.create(chef: Chef.new)
724
+ designer = DrinkDesignerWithPolymorphicTouchChef.last
725
+
726
+ assert_queries(3) {
727
+ designer.update(name: "foo")
728
+ }
729
+ end
730
+
731
+ def test_has_one_with_touch_option_on_update
732
+ new_club = Club.create(name: "1000 Oaks")
733
+ new_club.create_membership
734
+
735
+ assert_queries(2) { new_club.update(name: "Effingut") }
736
+ end
737
+
738
+ def test_has_one_with_touch_option_on_touch
739
+ new_club = Club.create(name: "1000 Oaks")
740
+ new_club.create_membership
741
+
742
+ assert_queries(1) { new_club.touch }
743
+ end
744
+
745
+ def test_has_one_with_touch_option_on_destroy
746
+ new_club = Club.create(name: "1000 Oaks")
747
+ new_club.create_membership
748
+
749
+ assert_queries(2) { new_club.destroy }
750
+ end
751
+
752
+ def test_has_one_with_touch_option_on_empty_update
753
+ new_club = Club.create(name: "1000 Oaks")
754
+ new_club.create_membership
755
+
756
+ assert_no_queries { new_club.save }
757
+ end
758
+
759
+ class SpecialBook < ActiveRecord::Base
760
+ self.table_name = "books"
761
+ belongs_to :author, class_name: "SpecialAuthor"
762
+ has_one :subscription, class_name: "SpecialSupscription", foreign_key: "subscriber_id"
763
+
764
+ enum status: [:proposed, :written, :published]
765
+ end
766
+
767
+ class SpecialAuthor < ActiveRecord::Base
768
+ self.table_name = "authors"
769
+ has_one :book, class_name: "SpecialBook", foreign_key: "author_id"
770
+ end
771
+
772
+ class SpecialSupscription < ActiveRecord::Base
773
+ self.table_name = "subscriptions"
774
+ belongs_to :book, class_name: "SpecialBook"
775
+ end
776
+
777
+ def test_association_enum_works_properly
778
+ author = SpecialAuthor.create!(name: "Test")
779
+ book = SpecialBook.create!(status: "published")
780
+ author.book = book
781
+
782
+ assert_equal "published", book.status
783
+ assert_not_equal 0, SpecialAuthor.joins(:book).where(books: { status: "published" }).count
784
+ end
785
+
786
+ def test_association_enum_works_properly_with_nested_join
787
+ author = SpecialAuthor.create!(name: "Test")
788
+ book = SpecialBook.create!(status: "published")
789
+ author.book = book
790
+
791
+ where_clause = { books: { subscriptions: { subscriber_id: nil } } }
792
+ assert_nothing_raised do
793
+ SpecialAuthor.joins(book: :subscription).where.not(where_clause)
794
+ end
795
+ end
796
+
797
+ class DestroyByParentBook < ActiveRecord::Base
798
+ self.table_name = "books"
799
+ belongs_to :author, class_name: "DestroyByParentAuthor"
800
+ before_destroy :dont, unless: :destroyed_by_association
801
+
802
+ def dont
803
+ throw(:abort)
804
+ end
805
+ end
806
+
807
+ class DestroyByParentAuthor < ActiveRecord::Base
808
+ self.table_name = "authors"
809
+ has_one :book, class_name: "DestroyByParentBook", foreign_key: "author_id", dependent: :destroy
810
+ end
811
+
812
+ test "destroyed_by_association set in child destroy callback on parent destroy" do
813
+ author = DestroyByParentAuthor.create!(name: "Test")
814
+ book = DestroyByParentBook.create!(author: author)
815
+
816
+ author.destroy
817
+
818
+ assert_not DestroyByParentBook.exists?(book.id)
819
+ end
820
+
821
+ test "destroyed_by_association set in child destroy callback on replace" do
822
+ author = DestroyByParentAuthor.create!(name: "Test")
823
+ book = DestroyByParentBook.create!(author: author)
824
+
825
+ author.book = DestroyByParentBook.create!
826
+ author.save!
827
+
828
+ assert_not DestroyByParentBook.exists?(book.id)
829
+ end
830
+
831
+ class UndestroyableBook < ActiveRecord::Base
832
+ self.table_name = "books"
833
+ belongs_to :author, class_name: "DestroyableAuthor"
834
+ before_destroy :dont
835
+
836
+ def dont
837
+ throw(:abort)
838
+ end
839
+ end
840
+
841
+ class DestroyableAuthor < ActiveRecord::Base
842
+ self.table_name = "authors"
843
+ has_one :book, class_name: "UndestroyableBook", foreign_key: "author_id", dependent: :destroy
844
+ end
845
+
846
+ def test_dependency_should_halt_parent_destruction
847
+ author = DestroyableAuthor.create!(name: "Test")
848
+ UndestroyableBook.create!(author: author)
849
+
850
+ assert_no_difference ["DestroyableAuthor.count", "UndestroyableBook.count"] do
851
+ assert_not author.destroy
852
+ end
853
+ end
854
+
855
+ class SpecialCar < ActiveRecord::Base
856
+ self.table_name = "cars"
857
+ has_one :special_bulb, inverse_of: :car, dependent: :destroy, class_name: "SpecialBulb", foreign_key: "car_id"
858
+ end
859
+
860
+ class SpecialBulb < ActiveRecord::Base
861
+ self.table_name = "bulbs"
862
+ belongs_to :car, inverse_of: :special_bulb, touch: true, class_name: "SpecialCar"
863
+ end
864
+
865
+ def test_has_one_with_touch_option_on_nonpersisted_built_associations_doesnt_update_parent
866
+ car = SpecialCar.create(name: "honda")
867
+ assert_queries(1) do
868
+ car.build_special_bulb
869
+ car.build_special_bulb
870
+ end
871
+ end
872
+ end