ibm_db 5.2.0-x86-mingw32 → 5.4.0-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (625) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +9 -0
  3. data/LICENSE +55 -18
  4. data/README +1 -1
  5. data/debug.log +1 -0
  6. data/ext/Makefile +28 -24
  7. data/ext/ibm_db.c +66 -65
  8. data/ext/ibm_db.o +0 -0
  9. data/ext/ibm_db.so +0 -0
  10. data/ext/mkmf.log +26 -24
  11. data/ext/ruby_ibm_db_cli.c +1 -0
  12. data/ext/ruby_ibm_db_cli.o +0 -0
  13. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1520 -1282
  14. data/lib/ibm_db.so +1 -0
  15. data/lib/mswin32/ibm_db.rb +3 -1
  16. data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
  17. data/lib/mswin32/rb3x/i386/ruby31/ibm_db.so +0 -0
  18. data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
  19. data/test/activejob/destroy_association_async_test.rb +305 -0
  20. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  21. data/test/activejob/helper.rb +15 -0
  22. data/test/assets/schema_dump_5_1.yml +345 -0
  23. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  24. data/test/cases/adapter_test.rb +432 -218
  25. data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
  26. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  27. data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
  28. data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
  29. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
  30. data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
  31. data/test/cases/adapters/mysql2/connection_test.rb +48 -50
  32. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  33. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
  34. data/test/cases/adapters/mysql2/enum_test.rb +32 -11
  35. data/test/cases/adapters/mysql2/explain_test.rb +13 -11
  36. data/test/cases/adapters/mysql2/json_test.rb +17 -188
  37. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  38. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
  39. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  40. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  41. data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
  42. data/test/cases/adapters/mysql2/schema_test.rb +24 -22
  43. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  44. data/test/cases/adapters/mysql2/sp_test.rb +10 -8
  45. data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
  46. data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
  47. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  48. data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
  49. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  50. data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
  51. data/test/cases/adapters/postgresql/array_test.rb +118 -63
  52. data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
  53. data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
  54. data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
  55. data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
  56. data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
  57. data/test/cases/adapters/postgresql/citext_test.rb +58 -58
  58. data/test/cases/adapters/postgresql/collation_test.rb +17 -15
  59. data/test/cases/adapters/postgresql/composite_test.rb +25 -23
  60. data/test/cases/adapters/postgresql/connection_test.rb +73 -85
  61. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  62. data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
  63. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  64. data/test/cases/adapters/postgresql/domain_test.rb +9 -7
  65. data/test/cases/adapters/postgresql/enum_test.rb +12 -10
  66. data/test/cases/adapters/postgresql/explain_test.rb +10 -8
  67. data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
  68. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  69. data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
  70. data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
  71. data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
  72. data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
  73. data/test/cases/adapters/postgresql/integer_test.rb +2 -0
  74. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  75. data/test/cases/adapters/postgresql/json_test.rb +16 -201
  76. data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
  77. data/test/cases/adapters/postgresql/money_test.rb +47 -16
  78. data/test/cases/adapters/postgresql/network_test.rb +36 -28
  79. data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
  80. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  81. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  82. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  83. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
  84. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  85. data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
  86. data/test/cases/adapters/postgresql/range_test.rb +406 -292
  87. data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
  88. data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
  89. data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
  90. data/test/cases/adapters/postgresql/schema_test.rb +207 -91
  91. data/test/cases/adapters/postgresql/serial_test.rb +9 -7
  92. data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
  93. data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
  94. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  95. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  96. data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
  97. data/test/cases/adapters/postgresql/utils_test.rb +11 -9
  98. data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
  99. data/test/cases/adapters/postgresql/xml_test.rb +10 -14
  100. data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
  101. data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
  102. data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
  103. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  104. data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
  105. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  106. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
  107. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
  108. data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
  109. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  110. data/test/cases/aggregations_test.rb +14 -12
  111. data/test/cases/annotate_test.rb +46 -0
  112. data/test/cases/ar_schema_test.rb +153 -86
  113. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  114. data/test/cases/arel/attributes/math_test.rb +83 -0
  115. data/test/cases/arel/attributes_test.rb +27 -0
  116. data/test/cases/arel/collectors/bind_test.rb +40 -0
  117. data/test/cases/arel/collectors/composite_test.rb +47 -0
  118. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  119. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  120. data/test/cases/arel/crud_test.rb +65 -0
  121. data/test/cases/arel/delete_manager_test.rb +53 -0
  122. data/test/cases/arel/factory_methods_test.rb +46 -0
  123. data/test/cases/arel/helper.rb +45 -0
  124. data/test/cases/arel/insert_manager_test.rb +241 -0
  125. data/test/cases/arel/nodes/and_test.rb +30 -0
  126. data/test/cases/arel/nodes/as_test.rb +36 -0
  127. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  128. data/test/cases/arel/nodes/bin_test.rb +35 -0
  129. data/test/cases/arel/nodes/binary_test.rb +29 -0
  130. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  131. data/test/cases/arel/nodes/case_test.rb +96 -0
  132. data/test/cases/arel/nodes/casted_test.rb +18 -0
  133. data/test/cases/arel/nodes/comment_test.rb +22 -0
  134. data/test/cases/arel/nodes/count_test.rb +35 -0
  135. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  136. data/test/cases/arel/nodes/descending_test.rb +46 -0
  137. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  138. data/test/cases/arel/nodes/equality_test.rb +62 -0
  139. data/test/cases/arel/nodes/extract_test.rb +43 -0
  140. data/test/cases/arel/nodes/false_test.rb +21 -0
  141. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  142. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  143. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  144. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  145. data/test/cases/arel/nodes/node_test.rb +22 -0
  146. data/test/cases/arel/nodes/not_test.rb +31 -0
  147. data/test/cases/arel/nodes/or_test.rb +36 -0
  148. data/test/cases/arel/nodes/over_test.rb +69 -0
  149. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  150. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  151. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  152. data/test/cases/arel/nodes/sum_test.rb +35 -0
  153. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  154. data/test/cases/arel/nodes/true_test.rb +21 -0
  155. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  156. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  157. data/test/cases/arel/nodes/window_test.rb +81 -0
  158. data/test/cases/arel/nodes_test.rb +34 -0
  159. data/test/cases/arel/select_manager_test.rb +1238 -0
  160. data/test/cases/arel/support/fake_record.rb +135 -0
  161. data/test/cases/arel/table_test.rb +216 -0
  162. data/test/cases/arel/update_manager_test.rb +126 -0
  163. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  164. data/test/cases/arel/visitors/dot_test.rb +90 -0
  165. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  166. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  167. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  168. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  169. data/test/cases/associations/belongs_to_associations_test.rb +510 -158
  170. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
  171. data/test/cases/associations/callbacks_test.rb +56 -38
  172. data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
  173. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
  174. data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
  175. data/test/cases/associations/eager_singularization_test.rb +21 -21
  176. data/test/cases/associations/eager_test.rb +559 -415
  177. data/test/cases/associations/extension_test.rb +18 -12
  178. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
  179. data/test/cases/associations/has_many_associations_test.rb +1038 -465
  180. data/test/cases/associations/has_many_through_associations_test.rb +558 -249
  181. data/test/cases/associations/has_one_associations_test.rb +294 -129
  182. data/test/cases/associations/has_one_through_associations_test.rb +121 -75
  183. data/test/cases/associations/inner_join_association_test.rb +114 -38
  184. data/test/cases/associations/inverse_associations_test.rb +606 -398
  185. data/test/cases/associations/join_model_test.rb +158 -148
  186. data/test/cases/associations/left_outer_join_association_test.rb +59 -24
  187. data/test/cases/associations/nested_through_associations_test.rb +166 -109
  188. data/test/cases/associations/required_test.rb +35 -10
  189. data/test/cases/associations_test.rb +241 -110
  190. data/test/cases/attribute_methods/read_test.rb +11 -11
  191. data/test/cases/attribute_methods_test.rb +413 -298
  192. data/test/cases/attributes_test.rb +145 -27
  193. data/test/cases/autosave_association_test.rb +681 -436
  194. data/test/cases/base_prevent_writes_test.rb +229 -0
  195. data/test/cases/base_test.rb +599 -542
  196. data/test/cases/batches_test.rb +288 -82
  197. data/test/cases/binary_test.rb +26 -31
  198. data/test/cases/bind_parameter_test.rb +194 -21
  199. data/test/cases/boolean_test.rb +52 -0
  200. data/test/cases/cache_key_test.rb +110 -5
  201. data/test/cases/calculations_test.rb +740 -177
  202. data/test/cases/callbacks_test.rb +74 -207
  203. data/test/cases/clone_test.rb +15 -10
  204. data/test/cases/coders/json_test.rb +2 -0
  205. data/test/cases/coders/yaml_column_test.rb +16 -13
  206. data/test/cases/collection_cache_key_test.rb +177 -20
  207. data/test/cases/column_alias_test.rb +9 -7
  208. data/test/cases/column_definition_test.rb +10 -68
  209. data/test/cases/comment_test.rb +166 -107
  210. data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
  211. data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
  212. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  213. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  214. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  215. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  216. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  217. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  218. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
  219. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
  220. data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
  221. data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
  222. data/test/cases/connection_management_test.rb +13 -11
  223. data/test/cases/connection_pool_test.rb +316 -83
  224. data/test/cases/core_test.rb +82 -58
  225. data/test/cases/counter_cache_test.rb +204 -50
  226. data/test/cases/custom_locking_test.rb +5 -3
  227. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  228. data/test/cases/database_configurations/resolver_test.rb +150 -0
  229. data/test/cases/database_configurations_test.rb +145 -0
  230. data/test/cases/database_selector_test.rb +296 -0
  231. data/test/cases/database_statements_test.rb +18 -16
  232. data/test/cases/date_test.rb +8 -16
  233. data/test/cases/date_time_precision_test.rb +100 -78
  234. data/test/cases/date_time_test.rb +23 -8
  235. data/test/cases/defaults_test.rb +106 -71
  236. data/test/cases/delegated_type_test.rb +57 -0
  237. data/test/cases/dirty_test.rb +419 -223
  238. data/test/cases/disconnected_test.rb +6 -6
  239. data/test/cases/dup_test.rb +54 -27
  240. data/test/cases/enum_test.rb +461 -82
  241. data/test/cases/errors_test.rb +7 -7
  242. data/test/cases/explain_subscriber_test.rb +17 -15
  243. data/test/cases/explain_test.rb +11 -19
  244. data/test/cases/filter_attributes_test.rb +153 -0
  245. data/test/cases/finder_respond_to_test.rb +14 -14
  246. data/test/cases/finder_test.rb +669 -287
  247. data/test/cases/fixture_set/file_test.rb +34 -38
  248. data/test/cases/fixtures_test.rb +833 -176
  249. data/test/cases/forbidden_attributes_protection_test.rb +32 -67
  250. data/test/cases/habtm_destroy_order_test.rb +25 -25
  251. data/test/cases/helper.rb +78 -49
  252. data/test/cases/hot_compatibility_test.rb +33 -32
  253. data/test/cases/i18n_test.rb +18 -17
  254. data/test/cases/inheritance_test.rb +180 -115
  255. data/test/cases/insert_all_test.rb +489 -0
  256. data/test/cases/instrumentation_test.rb +101 -0
  257. data/test/cases/integration_test.rb +119 -31
  258. data/test/cases/invalid_connection_test.rb +18 -16
  259. data/test/cases/invertible_migration_test.rb +183 -43
  260. data/test/cases/json_attribute_test.rb +35 -0
  261. data/test/cases/json_serialization_test.rb +57 -58
  262. data/test/cases/json_shared_test_cases.rb +290 -0
  263. data/test/cases/locking_test.rb +413 -119
  264. data/test/cases/log_subscriber_test.rb +68 -26
  265. data/test/cases/marshal_serialization_test.rb +39 -0
  266. data/test/cases/migration/change_schema_test.rb +118 -72
  267. data/test/cases/migration/change_table_test.rb +138 -30
  268. data/test/cases/migration/check_constraint_test.rb +162 -0
  269. data/test/cases/migration/column_attributes_test.rb +45 -35
  270. data/test/cases/migration/column_positioning_test.rb +18 -6
  271. data/test/cases/migration/columns_test.rb +93 -77
  272. data/test/cases/migration/command_recorder_test.rb +121 -34
  273. data/test/cases/migration/compatibility_test.rb +578 -23
  274. data/test/cases/migration/create_join_table_test.rb +35 -25
  275. data/test/cases/migration/foreign_key_test.rb +503 -284
  276. data/test/cases/migration/helper.rb +4 -3
  277. data/test/cases/migration/index_test.rb +119 -70
  278. data/test/cases/migration/logger_test.rb +9 -6
  279. data/test/cases/migration/pending_migrations_test.rb +88 -34
  280. data/test/cases/migration/references_foreign_key_test.rb +164 -150
  281. data/test/cases/migration/references_index_test.rb +38 -19
  282. data/test/cases/migration/references_statements_test.rb +15 -14
  283. data/test/cases/migration/rename_table_test.rb +53 -30
  284. data/test/cases/migration_test.rb +637 -269
  285. data/test/cases/migrator_test.rb +191 -135
  286. data/test/cases/mixin_test.rb +7 -11
  287. data/test/cases/modules_test.rb +36 -34
  288. data/test/cases/multi_db_migrator_test.rb +223 -0
  289. data/test/cases/multiparameter_attributes_test.rb +60 -33
  290. data/test/cases/multiple_db_test.rb +16 -22
  291. data/test/cases/nested_attributes_test.rb +341 -320
  292. data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
  293. data/test/cases/null_relation_test.rb +84 -0
  294. data/test/cases/numeric_data_test.rb +93 -0
  295. data/test/cases/persistence_test.rb +361 -269
  296. data/test/cases/pooled_connections_test.rb +18 -26
  297. data/test/cases/prepared_statement_status_test.rb +48 -0
  298. data/test/cases/primary_keys_test.rb +210 -104
  299. data/test/cases/query_cache_test.rb +610 -141
  300. data/test/cases/quoting_test.rb +132 -31
  301. data/test/cases/readonly_test.rb +49 -48
  302. data/test/cases/reaper_test.rb +146 -32
  303. data/test/cases/reflection_test.rb +167 -156
  304. data/test/cases/relation/delegation_test.rb +49 -36
  305. data/test/cases/relation/delete_all_test.rb +117 -0
  306. data/test/cases/relation/merging_test.rb +319 -42
  307. data/test/cases/relation/mutation_test.rb +55 -93
  308. data/test/cases/relation/or_test.rb +129 -29
  309. data/test/cases/relation/predicate_builder_test.rb +21 -6
  310. data/test/cases/relation/record_fetch_warning_test.rb +5 -3
  311. data/test/cases/relation/select_test.rb +67 -0
  312. data/test/cases/relation/update_all_test.rb +317 -0
  313. data/test/cases/relation/where_chain_test.rb +68 -32
  314. data/test/cases/relation/where_clause_test.rb +136 -61
  315. data/test/cases/relation/where_test.rb +155 -48
  316. data/test/cases/relation_test.rb +266 -112
  317. data/test/cases/relations_test.rb +969 -744
  318. data/test/cases/reload_models_test.rb +13 -9
  319. data/test/cases/reserved_word_test.rb +141 -0
  320. data/test/cases/result_test.rb +68 -17
  321. data/test/cases/sanitize_test.rb +87 -71
  322. data/test/cases/schema_dumper_test.rb +221 -128
  323. data/test/cases/schema_loading_test.rb +3 -2
  324. data/test/cases/scoping/default_scoping_test.rb +185 -144
  325. data/test/cases/scoping/named_scoping_test.rb +177 -89
  326. data/test/cases/scoping/relation_scoping_test.rb +197 -75
  327. data/test/cases/secure_token_test.rb +18 -3
  328. data/test/cases/serialization_test.rb +30 -28
  329. data/test/cases/serialized_attribute_test.rb +133 -42
  330. data/test/cases/signed_id_test.rb +168 -0
  331. data/test/cases/statement_cache_test.rb +41 -24
  332. data/test/cases/statement_invalid_test.rb +42 -0
  333. data/test/cases/store_test.rb +180 -55
  334. data/test/cases/strict_loading_test.rb +473 -0
  335. data/test/cases/suppressor_test.rb +26 -12
  336. data/test/cases/tasks/database_tasks_test.rb +1258 -194
  337. data/test/cases/tasks/mysql_rake_test.rb +370 -298
  338. data/test/cases/tasks/postgresql_rake_test.rb +481 -251
  339. data/test/cases/tasks/sqlite_rake_test.rb +225 -178
  340. data/test/cases/test_case.rb +51 -40
  341. data/test/cases/test_databases_test.rb +79 -0
  342. data/test/cases/test_fixtures_test.rb +79 -19
  343. data/test/cases/time_precision_test.rb +98 -76
  344. data/test/cases/timestamp_test.rb +102 -99
  345. data/test/cases/touch_later_test.rb +12 -10
  346. data/test/cases/transaction_callbacks_test.rb +344 -90
  347. data/test/cases/transaction_isolation_test.rb +12 -12
  348. data/test/cases/transactions_test.rb +612 -162
  349. data/test/cases/type/adapter_specific_registry_test.rb +14 -2
  350. data/test/cases/type/date_time_test.rb +4 -2
  351. data/test/cases/type/integer_test.rb +4 -2
  352. data/test/cases/type/string_test.rb +10 -8
  353. data/test/cases/type/time_test.rb +28 -0
  354. data/test/cases/type/type_map_test.rb +29 -28
  355. data/test/cases/type/unsigned_integer_test.rb +19 -0
  356. data/test/cases/type_test.rb +2 -0
  357. data/test/cases/types_test.rb +3 -1
  358. data/test/cases/unconnected_test.rb +14 -1
  359. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  360. data/test/cases/validations/absence_validation_test.rb +19 -17
  361. data/test/cases/validations/association_validation_test.rb +30 -28
  362. data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
  363. data/test/cases/validations/i18n_validation_test.rb +22 -21
  364. data/test/cases/validations/length_validation_test.rb +34 -33
  365. data/test/cases/validations/numericality_validation_test.rb +181 -0
  366. data/test/cases/validations/presence_validation_test.rb +21 -19
  367. data/test/cases/validations/uniqueness_validation_test.rb +156 -86
  368. data/test/cases/validations_repair_helper.rb +2 -0
  369. data/test/cases/validations_test.rb +61 -26
  370. data/test/cases/view_test.rb +122 -116
  371. data/test/cases/yaml_serialization_test.rb +79 -34
  372. data/test/config.example.yml +19 -19
  373. data/test/config.rb +3 -1
  374. data/test/config.yml +16 -6
  375. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  376. data/test/fixtures/author_addresses.yml +1 -8
  377. data/test/fixtures/authors.yml +1 -7
  378. data/test/fixtures/binaries.yml +4 -0
  379. data/test/fixtures/books.yml +9 -2
  380. data/test/fixtures/categories_posts.yml +3 -0
  381. data/test/fixtures/citations.yml +5 -0
  382. data/test/fixtures/comments.yml +7 -0
  383. data/test/fixtures/companies.yml +5 -0
  384. data/test/fixtures/computers.yml +2 -0
  385. data/test/fixtures/customers.yml +10 -1
  386. data/test/fixtures/developers.yml +1 -1
  387. data/test/fixtures/essays.yml +10 -0
  388. data/test/fixtures/faces.yml +3 -3
  389. data/test/fixtures/humans.yml +5 -0
  390. data/test/fixtures/interests.yml +7 -7
  391. data/test/fixtures/memberships.yml +7 -0
  392. data/test/fixtures/minimalistics.yml +3 -0
  393. data/test/fixtures/mixed_case_monkeys.yml +2 -2
  394. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  395. data/test/fixtures/naked/yml/parrots.yml +1 -0
  396. data/test/fixtures/other_books.yml +26 -0
  397. data/test/fixtures/other_posts.yml +1 -0
  398. data/test/fixtures/parrots.yml +7 -1
  399. data/test/fixtures/pirates.yml +3 -0
  400. data/test/fixtures/posts.yml +11 -3
  401. data/test/fixtures/readers.yml +6 -0
  402. data/test/fixtures/reserved_words/values.yml +2 -2
  403. data/test/fixtures/sponsors.yml +3 -0
  404. data/test/fixtures/strict_zines.yml +2 -0
  405. data/test/fixtures/subscribers.yml +1 -1
  406. data/test/fixtures/tasks.yml +1 -1
  407. data/test/fixtures/warehouse-things.yml +3 -0
  408. data/test/migrations/10_urban/9_add_expressions.rb +2 -0
  409. data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
  410. data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
  411. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
  412. data/test/migrations/missing/1_people_have_last_names.rb +2 -0
  413. data/test/migrations/missing/3_we_need_reminders.rb +2 -0
  414. data/test/migrations/missing/4_innocent_jointable.rb +3 -1
  415. data/test/migrations/rename/1_we_need_things.rb +2 -0
  416. data/test/migrations/rename/2_rename_things.rb +2 -0
  417. data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
  418. data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
  419. data/test/migrations/to_copy2/1_create_articles.rb +2 -0
  420. data/test/migrations/to_copy2/2_create_comments.rb +3 -1
  421. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
  422. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
  423. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
  424. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
  425. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
  426. data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
  427. data/test/migrations/valid/2_we_need_reminders.rb +2 -0
  428. data/test/migrations/valid/3_innocent_jointable.rb +3 -1
  429. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
  430. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
  431. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
  432. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
  433. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
  434. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
  435. data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
  436. data/test/models/account.rb +46 -0
  437. data/test/models/admin/account.rb +3 -1
  438. data/test/models/admin/randomly_named_c1.rb +2 -0
  439. data/test/models/admin/user.rb +16 -8
  440. data/test/models/admin.rb +4 -2
  441. data/test/models/aircraft.rb +3 -1
  442. data/test/models/arunit2_model.rb +2 -0
  443. data/test/models/author.rb +153 -102
  444. data/test/models/auto_id.rb +2 -0
  445. data/test/models/autoloadable/extra_firm.rb +2 -0
  446. data/test/models/binary.rb +3 -1
  447. data/test/models/binary_field.rb +6 -0
  448. data/test/models/bird.rb +13 -1
  449. data/test/models/book.rb +14 -4
  450. data/test/models/book_destroy_async.rb +24 -0
  451. data/test/models/boolean.rb +5 -0
  452. data/test/models/bulb.rb +13 -4
  453. data/test/models/cake_designer.rb +2 -0
  454. data/test/models/car.rb +17 -10
  455. data/test/models/carrier.rb +2 -0
  456. data/test/models/cart.rb +5 -0
  457. data/test/models/cat.rb +2 -0
  458. data/test/models/categorization.rb +8 -6
  459. data/test/models/category.rb +28 -16
  460. data/test/models/chef.rb +2 -0
  461. data/test/models/citation.rb +5 -1
  462. data/test/models/club.rb +13 -10
  463. data/test/models/college.rb +4 -2
  464. data/test/models/column.rb +2 -0
  465. data/test/models/column_name.rb +2 -0
  466. data/test/models/comment.rb +32 -10
  467. data/test/models/company.rb +102 -106
  468. data/test/models/company_in_module.rb +27 -26
  469. data/test/models/computer.rb +3 -1
  470. data/test/models/contact.rb +15 -13
  471. data/test/models/content.rb +5 -3
  472. data/test/models/contract.rb +21 -3
  473. data/test/models/country.rb +2 -4
  474. data/test/models/course.rb +3 -1
  475. data/test/models/customer.rb +10 -8
  476. data/test/models/customer_carrier.rb +2 -0
  477. data/test/models/dashboard.rb +2 -0
  478. data/test/models/default.rb +2 -0
  479. data/test/models/department.rb +2 -0
  480. data/test/models/destroy_async_parent.rb +15 -0
  481. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  482. data/test/models/developer.rb +152 -85
  483. data/test/models/dl_keyed_belongs_to.rb +13 -0
  484. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  485. data/test/models/dl_keyed_has_many.rb +5 -0
  486. data/test/models/dl_keyed_has_many_through.rb +5 -0
  487. data/test/models/dl_keyed_has_one.rb +5 -0
  488. data/test/models/dl_keyed_join.rb +10 -0
  489. data/test/models/dog.rb +2 -0
  490. data/test/models/dog_lover.rb +2 -0
  491. data/test/models/doubloon.rb +3 -1
  492. data/test/models/drink_designer.rb +17 -0
  493. data/test/models/edge.rb +4 -2
  494. data/test/models/electron.rb +2 -0
  495. data/test/models/engine.rb +3 -2
  496. data/test/models/entrant.rb +2 -0
  497. data/test/models/entry.rb +5 -0
  498. data/test/models/essay.rb +6 -3
  499. data/test/models/essay_destroy_async.rb +12 -0
  500. data/test/models/event.rb +3 -1
  501. data/test/models/eye.rb +5 -3
  502. data/test/models/face.rb +14 -6
  503. data/test/models/family.rb +6 -0
  504. data/test/models/family_tree.rb +6 -0
  505. data/test/models/friendship.rb +5 -3
  506. data/test/models/frog.rb +8 -0
  507. data/test/models/guid.rb +3 -1
  508. data/test/models/guitar.rb +2 -0
  509. data/test/models/hotel.rb +5 -3
  510. data/test/models/human.rb +39 -0
  511. data/test/models/image.rb +3 -1
  512. data/test/models/interest.rb +14 -3
  513. data/test/models/invoice.rb +4 -2
  514. data/test/models/item.rb +3 -1
  515. data/test/models/job.rb +5 -3
  516. data/test/models/joke.rb +4 -2
  517. data/test/models/keyboard.rb +3 -1
  518. data/test/models/legacy_thing.rb +2 -0
  519. data/test/models/lesson.rb +2 -0
  520. data/test/models/line_item.rb +3 -1
  521. data/test/models/liquid.rb +2 -0
  522. data/test/models/matey.rb +3 -1
  523. data/test/models/measurement.rb +4 -0
  524. data/test/models/member.rb +23 -20
  525. data/test/models/member_detail.rb +3 -0
  526. data/test/models/member_type.rb +2 -0
  527. data/test/models/membership.rb +4 -1
  528. data/test/models/mentor.rb +3 -1
  529. data/test/models/message.rb +5 -0
  530. data/test/models/minimalistic.rb +2 -0
  531. data/test/models/minivan.rb +3 -2
  532. data/test/models/mixed_case_monkey.rb +3 -1
  533. data/test/models/molecule.rb +2 -0
  534. data/test/models/mouse.rb +6 -0
  535. data/test/models/movie.rb +2 -0
  536. data/test/models/node.rb +4 -2
  537. data/test/models/non_primary_key.rb +2 -0
  538. data/test/models/notification.rb +2 -0
  539. data/test/models/numeric_data.rb +12 -0
  540. data/test/models/order.rb +4 -2
  541. data/test/models/organization.rb +9 -7
  542. data/test/models/other_dog.rb +3 -1
  543. data/test/models/owner.rb +6 -4
  544. data/test/models/parrot.rb +12 -4
  545. data/test/models/person.rb +59 -54
  546. data/test/models/personal_legacy_thing.rb +3 -1
  547. data/test/models/pet.rb +4 -2
  548. data/test/models/pet_treasure.rb +2 -0
  549. data/test/models/pirate.rb +67 -43
  550. data/test/models/possession.rb +3 -1
  551. data/test/models/post.rb +184 -86
  552. data/test/models/price_estimate.rb +11 -1
  553. data/test/models/professor.rb +3 -1
  554. data/test/models/project.rb +14 -12
  555. data/test/models/publisher/article.rb +2 -0
  556. data/test/models/publisher/magazine.rb +2 -0
  557. data/test/models/publisher.rb +2 -0
  558. data/test/models/randomly_named_c1.rb +2 -0
  559. data/test/models/rating.rb +5 -1
  560. data/test/models/reader.rb +7 -5
  561. data/test/models/recipe.rb +2 -0
  562. data/test/models/record.rb +2 -0
  563. data/test/models/reference.rb +6 -3
  564. data/test/models/reply.rb +39 -21
  565. data/test/models/room.rb +6 -0
  566. data/test/models/section.rb +6 -0
  567. data/test/models/seminar.rb +6 -0
  568. data/test/models/session.rb +6 -0
  569. data/test/models/ship.rb +12 -9
  570. data/test/models/ship_part.rb +5 -3
  571. data/test/models/shop.rb +4 -2
  572. data/test/models/shop_account.rb +2 -0
  573. data/test/models/speedometer.rb +2 -0
  574. data/test/models/sponsor.rb +8 -5
  575. data/test/models/squeak.rb +6 -0
  576. data/test/models/strict_zine.rb +7 -0
  577. data/test/models/string_key_object.rb +2 -0
  578. data/test/models/student.rb +2 -0
  579. data/test/models/subscriber.rb +4 -2
  580. data/test/models/subscription.rb +5 -1
  581. data/test/models/tag.rb +6 -3
  582. data/test/models/tagging.rb +13 -6
  583. data/test/models/task.rb +2 -0
  584. data/test/models/topic.rb +54 -19
  585. data/test/models/toy.rb +4 -0
  586. data/test/models/traffic_light.rb +2 -0
  587. data/test/models/treasure.rb +5 -3
  588. data/test/models/treaty.rb +2 -4
  589. data/test/models/tree.rb +2 -0
  590. data/test/models/tuning_peg.rb +2 -0
  591. data/test/models/tyre.rb +2 -0
  592. data/test/models/user.rb +12 -4
  593. data/test/models/uuid_child.rb +2 -0
  594. data/test/models/uuid_item.rb +2 -0
  595. data/test/models/uuid_parent.rb +2 -0
  596. data/test/models/vegetables.rb +12 -3
  597. data/test/models/vertex.rb +6 -4
  598. data/test/models/warehouse_thing.rb +2 -0
  599. data/test/models/wheel.rb +3 -1
  600. data/test/models/without_table.rb +3 -1
  601. data/test/models/zine.rb +3 -1
  602. data/test/schema/mysql2_specific_schema.rb +49 -35
  603. data/test/schema/oracle_specific_schema.rb +13 -15
  604. data/test/schema/postgresql_specific_schema.rb +51 -40
  605. data/test/schema/schema.rb +334 -154
  606. data/test/schema/sqlite_specific_schema.rb +9 -16
  607. data/test/support/config.rb +26 -26
  608. data/test/support/connection.rb +14 -8
  609. data/test/support/connection_helper.rb +3 -1
  610. data/test/support/ddl_helper.rb +2 -0
  611. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  612. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  613. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  614. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  615. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  616. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  617. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  618. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  619. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  620. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  621. data/test/support/schema_dumping_helper.rb +2 -0
  622. data/test/support/stubs/strong_parameters.rb +40 -0
  623. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  624. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  625. metadata +192 -14
@@ -1,43 +1,47 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cases/helper"
2
- require 'models/man'
3
- require 'models/face'
4
- require 'models/interest'
5
- require 'models/zine'
6
- require 'models/club'
7
- require 'models/sponsor'
8
- require 'models/rating'
9
- require 'models/comment'
10
- require 'models/car'
11
- require 'models/bulb'
12
- require 'models/mixed_case_monkey'
13
- require 'models/admin'
14
- require 'models/admin/account'
15
- require 'models/admin/user'
16
- require 'models/developer'
17
- require 'models/company'
18
- require 'models/project'
4
+ require "models/human"
5
+ require "models/face"
6
+ require "models/interest"
7
+ require "models/zine"
8
+ require "models/club"
9
+ require "models/sponsor"
10
+ require "models/rating"
11
+ require "models/post"
12
+ require "models/comment"
13
+ require "models/car"
14
+ require "models/bulb"
15
+ require "models/mixed_case_monkey"
16
+ require "models/admin"
17
+ require "models/admin/account"
18
+ require "models/admin/user"
19
+ require "models/developer"
20
+ require "models/company"
21
+ require "models/project"
22
+ require "models/author"
23
+ require "models/post"
24
+ require "models/user"
25
+ require "models/room"
19
26
 
20
27
  class AutomaticInverseFindingTests < ActiveRecord::TestCase
21
28
  fixtures :ratings, :comments, :cars
22
29
 
23
30
  def test_has_one_and_belongs_to_should_find_inverse_automatically_on_multiple_word_name
24
- monkey_reflection = MixedCaseMonkey.reflect_on_association(:man)
25
- man_reflection = Man.reflect_on_association(:mixed_case_monkey)
31
+ monkey_reflection = MixedCaseMonkey.reflect_on_association(:human)
32
+ human_reflection = Human.reflect_on_association(:mixed_case_monkey)
26
33
 
27
- assert_respond_to monkey_reflection, :has_inverse?
28
34
  assert monkey_reflection.has_inverse?, "The monkey reflection should have an inverse"
29
- assert_equal man_reflection, monkey_reflection.inverse_of, "The monkey reflection's inverse should be the man reflection"
35
+ assert_equal human_reflection, monkey_reflection.inverse_of, "The monkey reflection's inverse should be the human reflection"
30
36
 
31
- assert_respond_to man_reflection, :has_inverse?
32
- assert man_reflection.has_inverse?, "The man reflection should have an inverse"
33
- assert_equal monkey_reflection, man_reflection.inverse_of, "The man reflection's inverse should be the monkey reflection"
37
+ assert human_reflection.has_inverse?, "The human reflection should have an inverse"
38
+ assert_equal monkey_reflection, human_reflection.inverse_of, "The human reflection's inverse should be the monkey reflection"
34
39
  end
35
40
 
36
41
  def test_has_many_and_belongs_to_should_find_inverse_automatically_for_model_in_module
37
42
  account_reflection = Admin::Account.reflect_on_association(:users)
38
43
  user_reflection = Admin::User.reflect_on_association(:account)
39
44
 
40
- assert_respond_to account_reflection, :has_inverse?
41
45
  assert account_reflection.has_inverse?, "The Admin::Account reflection should have an inverse"
42
46
  assert_equal user_reflection, account_reflection.inverse_of, "The Admin::Account reflection's inverse should be the Admin::User reflection"
43
47
  end
@@ -46,11 +50,9 @@ class AutomaticInverseFindingTests < ActiveRecord::TestCase
46
50
  car_reflection = Car.reflect_on_association(:bulb)
47
51
  bulb_reflection = Bulb.reflect_on_association(:car)
48
52
 
49
- assert_respond_to car_reflection, :has_inverse?
50
53
  assert car_reflection.has_inverse?, "The Car reflection should have an inverse"
51
54
  assert_equal bulb_reflection, car_reflection.inverse_of, "The Car reflection's inverse should be the Bulb reflection"
52
55
 
53
- assert_respond_to bulb_reflection, :has_inverse?
54
56
  assert bulb_reflection.has_inverse?, "The Bulb reflection should have an inverse"
55
57
  assert_equal car_reflection, bulb_reflection.inverse_of, "The Bulb reflection's inverse should be the Car reflection"
56
58
  end
@@ -59,11 +61,55 @@ class AutomaticInverseFindingTests < ActiveRecord::TestCase
59
61
  comment_reflection = Comment.reflect_on_association(:ratings)
60
62
  rating_reflection = Rating.reflect_on_association(:comment)
61
63
 
62
- assert_respond_to comment_reflection, :has_inverse?
63
64
  assert comment_reflection.has_inverse?, "The Comment reflection should have an inverse"
64
65
  assert_equal rating_reflection, comment_reflection.inverse_of, "The Comment reflection's inverse should be the Rating reflection"
65
66
  end
66
67
 
68
+ def test_has_many_and_belongs_to_should_find_inverse_automatically_for_extension_block
69
+ comment_reflection = Comment.reflect_on_association(:post)
70
+ post_reflection = Post.reflect_on_association(:comments)
71
+
72
+ assert_predicate post_reflection, :has_inverse?
73
+ assert_equal comment_reflection, post_reflection.inverse_of
74
+ end
75
+
76
+ def test_has_many_and_belongs_to_should_find_inverse_automatically_for_sti
77
+ author_reflection = Author.reflect_on_association(:posts)
78
+ author_child_reflection = Author.reflect_on_association(:special_posts)
79
+ post_reflection = Post.reflect_on_association(:author)
80
+
81
+ assert_respond_to author_reflection, :has_inverse?
82
+ assert author_reflection.has_inverse?, "The Author reflection should have an inverse"
83
+ assert_equal post_reflection, author_reflection.inverse_of, "The Author reflection's inverse should be the Post reflection"
84
+
85
+ assert_respond_to author_child_reflection, :has_inverse?
86
+ assert author_child_reflection.has_inverse?, "The Author reflection should have an inverse"
87
+ assert_equal post_reflection, author_child_reflection.inverse_of, "The Author reflection's inverse should be the Post reflection"
88
+ end
89
+
90
+ def test_has_one_and_belongs_to_with_non_default_foreign_key_should_not_find_inverse_automatically
91
+ user = User.create!
92
+ owned_room = Room.create!(owner: user)
93
+
94
+ assert_nil user.room
95
+ assert_nil owned_room.user
96
+
97
+ assert_equal user, owned_room.owner
98
+ assert_equal owned_room, user.owned_room
99
+ end
100
+
101
+ def test_has_one_and_belongs_to_with_custom_association_name_should_not_find_wrong_inverse_automatically
102
+ user_reflection = Room.reflect_on_association(:user)
103
+ owner_reflection = Room.reflect_on_association(:owner)
104
+ room_reflection = User.reflect_on_association(:room)
105
+
106
+ assert_predicate user_reflection, :has_inverse?
107
+ assert_equal room_reflection, user_reflection.inverse_of
108
+
109
+ assert_not_predicate owner_reflection, :has_inverse?
110
+ assert_not_equal room_reflection, owner_reflection.inverse_of
111
+ end
112
+
67
113
  def test_has_one_and_belongs_to_automatic_inverse_shares_objects
68
114
  car = Car.first
69
115
  bulb = Bulb.create!(car: car)
@@ -107,88 +153,64 @@ class AutomaticInverseFindingTests < ActiveRecord::TestCase
107
153
  def test_polymorphic_and_has_many_through_relationships_should_not_have_inverses
108
154
  sponsor_reflection = Sponsor.reflect_on_association(:sponsorable)
109
155
 
110
- assert_respond_to sponsor_reflection, :has_inverse?
111
- assert !sponsor_reflection.has_inverse?, "A polymorphic association should not find an inverse automatically"
156
+ assert_not sponsor_reflection.has_inverse?, "A polymorphic association should not find an inverse automatically"
112
157
 
113
158
  club_reflection = Club.reflect_on_association(:members)
114
159
 
115
- assert_respond_to club_reflection, :has_inverse?
116
- assert !club_reflection.has_inverse?, "A has_many_through association should not find an inverse automatically"
160
+ assert_not club_reflection.has_inverse?, "A has_many_through association should not find an inverse automatically"
117
161
  end
118
162
 
119
- def test_polymorphic_relationships_should_still_not_have_inverses_when_non_polymorphic_relationship_has_the_same_name
120
- man_reflection = Man.reflect_on_association(:polymorphic_face_without_inverse)
121
- face_reflection = Face.reflect_on_association(:man)
163
+ def test_polymorphic_has_one_should_find_inverse_automatically
164
+ human_reflection = Human.reflect_on_association(:polymorphic_face_without_inverse)
122
165
 
123
- assert_respond_to face_reflection, :has_inverse?
124
- assert face_reflection.has_inverse?, "For this test, the non-polymorphic association must have an inverse"
125
-
126
- assert_respond_to man_reflection, :has_inverse?
127
- assert !man_reflection.has_inverse?, "The target of a polymorphic association should not find an inverse automatically"
166
+ assert_predicate human_reflection, :has_inverse?
128
167
  end
129
168
  end
130
169
 
131
170
  class InverseAssociationTests < ActiveRecord::TestCase
132
171
  def test_should_allow_for_inverse_of_options_in_associations
133
172
  assert_nothing_raised do
134
- Class.new(ActiveRecord::Base).has_many(:wheels, :inverse_of => :car)
173
+ Class.new(ActiveRecord::Base).has_many(:wheels, inverse_of: :car)
135
174
  end
136
175
 
137
176
  assert_nothing_raised do
138
- Class.new(ActiveRecord::Base).has_one(:engine, :inverse_of => :car)
177
+ Class.new(ActiveRecord::Base).has_one(:engine, inverse_of: :car)
139
178
  end
140
179
 
141
180
  assert_nothing_raised do
142
- Class.new(ActiveRecord::Base).belongs_to(:car, :inverse_of => :driver)
181
+ Class.new(ActiveRecord::Base).belongs_to(:car, inverse_of: :driver)
143
182
  end
144
183
  end
145
184
 
146
185
  def test_should_be_able_to_ask_a_reflection_if_it_has_an_inverse
147
- has_one_with_inverse_ref = Man.reflect_on_association(:face)
148
- assert_respond_to has_one_with_inverse_ref, :has_inverse?
149
- assert has_one_with_inverse_ref.has_inverse?
186
+ has_one_with_inverse_ref = Human.reflect_on_association(:face)
187
+ assert_predicate has_one_with_inverse_ref, :has_inverse?
150
188
 
151
- has_many_with_inverse_ref = Man.reflect_on_association(:interests)
152
- assert_respond_to has_many_with_inverse_ref, :has_inverse?
153
- assert has_many_with_inverse_ref.has_inverse?
189
+ has_many_with_inverse_ref = Human.reflect_on_association(:interests)
190
+ assert_predicate has_many_with_inverse_ref, :has_inverse?
154
191
 
155
- belongs_to_with_inverse_ref = Face.reflect_on_association(:man)
156
- assert_respond_to belongs_to_with_inverse_ref, :has_inverse?
157
- assert belongs_to_with_inverse_ref.has_inverse?
192
+ belongs_to_with_inverse_ref = Face.reflect_on_association(:human)
193
+ assert_predicate belongs_to_with_inverse_ref, :has_inverse?
158
194
 
159
195
  has_one_without_inverse_ref = Club.reflect_on_association(:sponsor)
160
- assert_respond_to has_one_without_inverse_ref, :has_inverse?
161
- assert !has_one_without_inverse_ref.has_inverse?
196
+ assert_not_predicate has_one_without_inverse_ref, :has_inverse?
162
197
 
163
198
  has_many_without_inverse_ref = Club.reflect_on_association(:memberships)
164
- assert_respond_to has_many_without_inverse_ref, :has_inverse?
165
- assert !has_many_without_inverse_ref.has_inverse?
199
+ assert_not_predicate has_many_without_inverse_ref, :has_inverse?
166
200
 
167
201
  belongs_to_without_inverse_ref = Sponsor.reflect_on_association(:sponsor_club)
168
- assert_respond_to belongs_to_without_inverse_ref, :has_inverse?
169
- assert !belongs_to_without_inverse_ref.has_inverse?
170
- end
171
-
172
- def test_should_be_able_to_ask_a_reflection_what_it_is_the_inverse_of
173
- has_one_ref = Man.reflect_on_association(:face)
174
- assert_respond_to has_one_ref, :inverse_of
175
-
176
- has_many_ref = Man.reflect_on_association(:interests)
177
- assert_respond_to has_many_ref, :inverse_of
178
-
179
- belongs_to_ref = Face.reflect_on_association(:man)
180
- assert_respond_to belongs_to_ref, :inverse_of
202
+ assert_not_predicate belongs_to_without_inverse_ref, :has_inverse?
181
203
  end
182
204
 
183
205
  def test_inverse_of_method_should_supply_the_actual_reflection_instance_it_is_the_inverse_of
184
- has_one_ref = Man.reflect_on_association(:face)
185
- assert_equal Face.reflect_on_association(:man), has_one_ref.inverse_of
206
+ has_one_ref = Human.reflect_on_association(:face)
207
+ assert_equal Face.reflect_on_association(:human), has_one_ref.inverse_of
186
208
 
187
- has_many_ref = Man.reflect_on_association(:interests)
188
- assert_equal Interest.reflect_on_association(:man), has_many_ref.inverse_of
209
+ has_many_ref = Human.reflect_on_association(:interests)
210
+ assert_equal Interest.reflect_on_association(:human), has_many_ref.inverse_of
189
211
 
190
- belongs_to_ref = Face.reflect_on_association(:man)
191
- assert_equal Man.reflect_on_association(:face), belongs_to_ref.inverse_of
212
+ belongs_to_ref = Face.reflect_on_association(:human)
213
+ assert_equal Human.reflect_on_association(:face), belongs_to_ref.inverse_of
192
214
  end
193
215
 
194
216
  def test_associations_with_no_inverse_of_should_return_nil
@@ -202,10 +224,20 @@ class InverseAssociationTests < ActiveRecord::TestCase
202
224
  assert_nil belongs_to_ref.inverse_of
203
225
  end
204
226
 
227
+ def test_polymorphic_associations_dont_attempt_to_find_inverse_of
228
+ belongs_to_ref = Sponsor.reflect_on_association(:sponsor)
229
+ assert_raise(ArgumentError) { belongs_to_ref.klass }
230
+ assert_nil belongs_to_ref.inverse_of
231
+
232
+ belongs_to_ref = Face.reflect_on_association(:super_human)
233
+ assert_raise(ArgumentError) { belongs_to_ref.klass }
234
+ assert_nil belongs_to_ref.inverse_of
235
+ end
236
+
205
237
  def test_this_inverse_stuff
206
- firm = Firm.create!(name: 'Adequate Holdings')
207
- Project.create!(name: 'Project 1', firm: firm)
208
- Developer.create!(name: 'Gorbypuff', firm: firm)
238
+ firm = Firm.create!(name: "Adequate Holdings")
239
+ Project.create!(name: "Project 1", firm: firm)
240
+ Developer.create!(name: "Gorbypuff", firm: firm)
209
241
 
210
242
  new_project = Project.last
211
243
  assert Project.reflect_on_association(:lead_developer).inverse_of.present?, "Expected inverse of to be present"
@@ -214,249 +246,310 @@ class InverseAssociationTests < ActiveRecord::TestCase
214
246
  end
215
247
 
216
248
  class InverseHasOneTests < ActiveRecord::TestCase
217
- fixtures :men, :faces
249
+ fixtures :humans, :faces
218
250
 
219
251
  def test_parent_instance_should_be_shared_with_child_on_find
220
- m = men(:gordon)
221
- f = m.face
222
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
223
- m.name = 'Bongo'
224
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
225
- f.man.name = 'Mungo'
226
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance"
252
+ human = humans(:gordon)
253
+ face = human.face
254
+ assert_equal human.name, face.human.name, "Name of human should be the same before changes to parent instance"
255
+ human.name = "Bongo"
256
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to parent instance"
257
+ face.human.name = "Mungo"
258
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to child-owned instance"
227
259
  end
228
260
 
229
-
230
261
  def test_parent_instance_should_be_shared_with_eager_loaded_child_on_find
231
- m = Man.all.merge!(:where => {:name => 'Gordon'}, :includes => :face).first
232
- f = m.face
233
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
234
- m.name = 'Bongo'
235
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
236
- f.man.name = 'Mungo'
237
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance"
238
-
239
- m = Man.all.merge!(:where => {:name => 'Gordon'}, :includes => :face, :order => 'faces.id').first
240
- f = m.face
241
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
242
- m.name = 'Bongo'
243
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
244
- f.man.name = 'Mungo'
245
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance"
262
+ human = Human.all.merge!(where: { name: "Gordon" }, includes: :face).first
263
+ face = human.face
264
+ assert_equal human.name, face.human.name, "Name of human should be the same before changes to parent instance"
265
+ human.name = "Bongo"
266
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to parent instance"
267
+ face.human.name = "Mungo"
268
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to child-owned instance"
269
+
270
+ human = Human.all.merge!(where: { name: "Gordon" }, includes: :face, order: "faces.id").first
271
+ face = human.face
272
+ assert_equal human.name, face.human.name, "Name of human should be the same before changes to parent instance"
273
+ human.name = "Bongo"
274
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to parent instance"
275
+ face.human.name = "Mungo"
276
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to child-owned instance"
246
277
  end
247
278
 
248
279
  def test_parent_instance_should_be_shared_with_newly_built_child
249
- m = Man.first
250
- f = m.build_face(:description => 'haunted')
251
- assert_not_nil f.man
252
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
253
- m.name = 'Bongo'
254
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
255
- f.man.name = 'Mungo'
256
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to just-built-child-owned instance"
280
+ human = Human.first
281
+ face = human.build_face(description: "haunted")
282
+ assert_not_nil face.human
283
+ assert_equal human.name, face.human.name, "Name of human should be the same before changes to parent instance"
284
+ human.name = "Bongo"
285
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to parent instance"
286
+ face.human.name = "Mungo"
287
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to just-built-child-owned instance"
257
288
  end
258
289
 
259
290
  def test_parent_instance_should_be_shared_with_newly_created_child
260
- m = Man.first
261
- f = m.create_face(:description => 'haunted')
262
- assert_not_nil f.man
263
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
264
- m.name = 'Bongo'
265
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
266
- f.man.name = 'Mungo'
267
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
291
+ human = Human.first
292
+ face = human.create_face(description: "haunted")
293
+ assert_not_nil face.human
294
+ assert_equal human.name, face.human.name, "Name of human should be the same before changes to parent instance"
295
+ human.name = "Bongo"
296
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to parent instance"
297
+ face.human.name = "Mungo"
298
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to newly-created-child-owned instance"
268
299
  end
269
300
 
270
301
  def test_parent_instance_should_be_shared_with_newly_created_child_via_bang_method
271
- m = Man.first
272
- f = m.create_face!(:description => 'haunted')
273
- assert_not_nil f.man
274
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
275
- m.name = 'Bongo'
276
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
277
- f.man.name = 'Mungo'
278
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
302
+ human = Human.first
303
+ face = human.create_face!(description: "haunted")
304
+ assert_not_nil face.human
305
+ assert_equal human.name, face.human.name, "Name of human should be the same before changes to parent instance"
306
+ human.name = "Bongo"
307
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to parent instance"
308
+ face.human.name = "Mungo"
309
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to newly-created-child-owned instance"
279
310
  end
280
311
 
281
312
  def test_parent_instance_should_be_shared_with_replaced_via_accessor_child
282
- m = Man.first
283
- f = Face.new(:description => 'haunted')
284
- m.face = f
285
- assert_not_nil f.man
286
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
287
- m.name = 'Bongo'
288
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
289
- f.man.name = 'Mungo'
290
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to replaced-child-owned instance"
313
+ human = Human.first
314
+ face = Face.new(description: "haunted")
315
+ human.face = face
316
+ assert_not_nil face.human
317
+ assert_equal human.name, face.human.name, "Name of human should be the same before changes to parent instance"
318
+ human.name = "Bongo"
319
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to parent instance"
320
+ face.human.name = "Mungo"
321
+ assert_equal human.name, face.human.name, "Name of human should be the same after changes to replaced-child-owned instance"
322
+ end
323
+
324
+ def test_child_instance_should_be_shared_with_replaced_via_accessor_parent
325
+ human = Human.first
326
+ face = Face.create!(description: "haunted", human: Human.last)
327
+ face.human = human
328
+ assert_equal face, human.face
329
+ assert_equal face.description, human.face.description, "Description of the face should be the same before changes to child instance"
330
+ face.description = "Bongo"
331
+ assert_equal face.description, human.face.description, "Description of the face should be the same after changes to chield instance"
332
+ human.face.description = "Mungo"
333
+ assert_equal face.description, human.face.description, "Description of the face should be the same after changes to replaced-parent-owned instance"
291
334
  end
292
335
 
293
336
  def test_trying_to_use_inverses_that_dont_exist_should_raise_an_error
294
- assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Man.first.dirty_face }
337
+ assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Human.first.confused_face }
338
+ end
339
+
340
+ if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
341
+ def test_trying_to_use_inverses_that_dont_exist_should_have_suggestions_for_fix
342
+ error = assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) {
343
+ Human.first.confused_face
344
+ }
345
+
346
+ assert_match "Did you mean?", error.message
347
+ assert_equal "super_human", error.corrections.first
348
+ end
295
349
  end
296
350
  end
297
351
 
298
352
  class InverseHasManyTests < ActiveRecord::TestCase
299
- fixtures :men, :interests
353
+ fixtures :humans, :interests, :posts, :authors, :author_addresses, :comments
300
354
 
301
355
  def test_parent_instance_should_be_shared_with_every_child_on_find
302
- m = men(:gordon)
303
- is = m.interests
304
- is.each do |i|
305
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
306
- m.name = 'Bongo'
307
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
308
- i.man.name = 'Mungo'
309
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to child-owned instance"
356
+ human = humans(:gordon)
357
+ interests = human.interests
358
+ interests.each do |interest|
359
+ assert_equal human.name, interest.human.name, "Name of human should be the same before changes to parent instance"
360
+ human.name = "Bongo"
361
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to parent instance"
362
+ interest.human.name = "Mungo"
363
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to child-owned instance"
364
+ end
365
+ end
366
+
367
+ def test_parent_instance_should_be_shared_with_every_child_on_find_for_sti
368
+ author = authors(:david)
369
+ posts = author.posts
370
+ posts.each do |post|
371
+ assert_equal author.name, post.author.name, "Name of human should be the same before changes to parent instance"
372
+ author.name = "Bongo"
373
+ assert_equal author.name, post.author.name, "Name of human should be the same after changes to parent instance"
374
+ post.author.name = "Mungo"
375
+ assert_equal author.name, post.author.name, "Name of human should be the same after changes to child-owned instance"
376
+ end
377
+
378
+ special_posts = author.special_posts
379
+ special_posts.each do |post|
380
+ assert_equal author.name, post.author.name, "Name of human should be the same before changes to parent instance"
381
+ author.name = "Bongo"
382
+ assert_equal author.name, post.author.name, "Name of human should be the same after changes to parent instance"
383
+ post.author.name = "Mungo"
384
+ assert_equal author.name, post.author.name, "Name of human should be the same after changes to child-owned instance"
310
385
  end
311
386
  end
312
387
 
313
388
  def test_parent_instance_should_be_shared_with_eager_loaded_children
314
- m = Man.all.merge!(:where => {:name => 'Gordon'}, :includes => :interests).first
315
- is = m.interests
316
- is.each do |i|
317
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
318
- m.name = 'Bongo'
319
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
320
- i.man.name = 'Mungo'
321
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to child-owned instance"
389
+ human = Human.all.merge!(where: { name: "Gordon" }, includes: :interests).first
390
+ interests = human.interests
391
+ interests.each do |interest|
392
+ assert_equal human.name, interest.human.name, "Name of human should be the same before changes to parent instance"
393
+ human.name = "Bongo"
394
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to parent instance"
395
+ interest.human.name = "Mungo"
396
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to child-owned instance"
322
397
  end
323
398
 
324
- m = Man.all.merge!(:where => {:name => 'Gordon'}, :includes => :interests, :order => 'interests.id').first
325
- is = m.interests
326
- is.each do |i|
327
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
328
- m.name = 'Bongo'
329
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
330
- i.man.name = 'Mungo'
331
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to child-owned instance"
399
+ human = Human.all.merge!(where: { name: "Gordon" }, includes: :interests, order: "interests.id").first
400
+ interests = human.interests
401
+ interests.each do |interest|
402
+ assert_equal human.name, interest.human.name, "Name of human should be the same before changes to parent instance"
403
+ human.name = "Bongo"
404
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to parent instance"
405
+ interest.human.name = "Mungo"
406
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to child-owned instance"
332
407
  end
333
408
  end
334
409
 
335
410
  def test_parent_instance_should_be_shared_with_newly_block_style_built_child
336
- m = Man.first
337
- i = m.interests.build {|ii| ii.topic = 'Industrial Revolution Re-enactment'}
338
- assert_not_nil i.topic, "Child attributes supplied to build via blocks should be populated"
339
- assert_not_nil i.man
340
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
341
- m.name = 'Bongo'
342
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
343
- i.man.name = 'Mungo'
344
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to just-built-child-owned instance"
411
+ human = Human.first
412
+ interest = human.interests.build { |ii| ii.topic = "Industrial Revolution Re-enactment" }
413
+ assert_not_nil interest.topic, "Child attributes supplied to build via blocks should be populated"
414
+ assert_not_nil interest.human
415
+ assert_equal human.name, interest.human.name, "Name of human should be the same before changes to parent instance"
416
+ human.name = "Bongo"
417
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to parent instance"
418
+ interest.human.name = "Mungo"
419
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to just-built-child-owned instance"
345
420
  end
346
421
 
347
422
  def test_parent_instance_should_be_shared_with_newly_created_via_bang_method_child
348
- m = Man.first
349
- i = m.interests.create!(:topic => 'Industrial Revolution Re-enactment')
350
- assert_not_nil i.man
351
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
352
- m.name = 'Bongo'
353
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
354
- i.man.name = 'Mungo'
355
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
423
+ human = Human.first
424
+ interest = human.interests.create!(topic: "Industrial Revolution Re-enactment")
425
+ assert_not_nil interest.human
426
+ assert_equal human.name, interest.human.name, "Name of human should be the same before changes to parent instance"
427
+ human.name = "Bongo"
428
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to parent instance"
429
+ interest.human.name = "Mungo"
430
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to newly-created-child-owned instance"
356
431
  end
357
432
 
358
433
  def test_parent_instance_should_be_shared_with_newly_block_style_created_child
359
- m = Man.first
360
- i = m.interests.create {|ii| ii.topic = 'Industrial Revolution Re-enactment'}
361
- assert_not_nil i.topic, "Child attributes supplied to create via blocks should be populated"
362
- assert_not_nil i.man
363
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
364
- m.name = 'Bongo'
365
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
366
- i.man.name = 'Mungo'
367
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
434
+ human = Human.first
435
+ interest = human.interests.create { |ii| ii.topic = "Industrial Revolution Re-enactment" }
436
+ assert_not_nil interest.topic, "Child attributes supplied to create via blocks should be populated"
437
+ assert_not_nil interest.human
438
+ assert_equal human.name, interest.human.name, "Name of human should be the same before changes to parent instance"
439
+ human.name = "Bongo"
440
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to parent instance"
441
+ interest.human.name = "Mungo"
442
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to newly-created-child-owned instance"
368
443
  end
369
444
 
370
445
  def test_parent_instance_should_be_shared_within_create_block_of_new_child
371
- man = Man.first
372
- interest = man.interests.create do |i|
373
- assert i.man.equal?(man), "Man of child should be the same instance as a parent"
446
+ human = Human.first
447
+ interest = human.interests.create do |i|
448
+ assert i.human.equal?(human), "Human of child should be the same instance as a parent"
374
449
  end
375
- assert interest.man.equal?(man), "Man of the child should still be the same instance as a parent"
450
+ assert interest.human.equal?(human), "Human of the child should still be the same instance as a parent"
376
451
  end
377
452
 
378
453
  def test_parent_instance_should_be_shared_within_build_block_of_new_child
379
- man = Man.first
380
- interest = man.interests.build do |i|
381
- assert i.man.equal?(man), "Man of child should be the same instance as a parent"
454
+ human = Human.first
455
+ interest = human.interests.build do |i|
456
+ assert i.human.equal?(human), "Human of child should be the same instance as a parent"
382
457
  end
383
- assert interest.man.equal?(man), "Man of the child should still be the same instance as a parent"
458
+ assert interest.human.equal?(human), "Human of the child should still be the same instance as a parent"
384
459
  end
385
460
 
386
461
  def test_parent_instance_should_be_shared_with_poked_in_child
387
- m = men(:gordon)
388
- i = Interest.create(:topic => 'Industrial Revolution Re-enactment')
389
- m.interests << i
390
- assert_not_nil i.man
391
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
392
- m.name = 'Bongo'
393
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
394
- i.man.name = 'Mungo'
395
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
462
+ human = humans(:gordon)
463
+ interest = Interest.create(topic: "Industrial Revolution Re-enactment")
464
+ human.interests << interest
465
+ assert_not_nil interest.human
466
+ assert_equal human.name, interest.human.name, "Name of human should be the same before changes to parent instance"
467
+ human.name = "Bongo"
468
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to parent instance"
469
+ interest.human.name = "Mungo"
470
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to newly-created-child-owned instance"
396
471
  end
397
472
 
398
473
  def test_parent_instance_should_be_shared_with_replaced_via_accessor_children
399
- m = Man.first
400
- i = Interest.new(:topic => 'Industrial Revolution Re-enactment')
401
- m.interests = [i]
402
- assert_not_nil i.man
403
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
404
- m.name = 'Bongo'
405
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
406
- i.man.name = 'Mungo'
407
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to replaced-child-owned instance"
474
+ human = Human.first
475
+ interest = Interest.new(topic: "Industrial Revolution Re-enactment")
476
+ human.interests = [interest]
477
+ assert_not_nil interest.human
478
+ assert_equal human.name, interest.human.name, "Name of human should be the same before changes to parent instance"
479
+ human.name = "Bongo"
480
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to parent instance"
481
+ interest.human.name = "Mungo"
482
+ assert_equal human.name, interest.human.name, "Name of human should be the same after changes to replaced-child-owned instance"
408
483
  end
409
484
 
410
485
  def test_parent_instance_should_be_shared_with_first_and_last_child
411
- man = Man.first
486
+ human = Human.first
412
487
 
413
- assert man.interests.first.man.equal? man
414
- assert man.interests.last.man.equal? man
488
+ assert human.interests.first.human.equal? human
489
+ assert human.interests.last.human.equal? human
415
490
  end
416
491
 
417
492
  def test_parent_instance_should_be_shared_with_first_n_and_last_n_children
418
- man = Man.first
493
+ human = Human.first
419
494
 
420
- interests = man.interests.first(2)
421
- assert interests[0].man.equal? man
422
- assert interests[1].man.equal? man
495
+ interests = human.interests.first(2)
496
+ assert interests[0].human.equal? human
497
+ assert interests[1].human.equal? human
423
498
 
424
- interests = man.interests.last(2)
425
- assert interests[0].man.equal? man
426
- assert interests[1].man.equal? man
499
+ interests = human.interests.last(2)
500
+ assert interests[0].human.equal? human
501
+ assert interests[1].human.equal? human
427
502
  end
428
503
 
429
504
  def test_parent_instance_should_find_child_instance_using_child_instance_id
430
- man = Man.create!
505
+ human = Human.create!
431
506
  interest = Interest.create!
432
- man.interests = [interest]
507
+ human.interests = [interest]
433
508
 
434
- assert interest.equal?(man.interests.first), "The inverse association should use the interest already created and held in memory"
435
- assert interest.equal?(man.interests.find(interest.id)), "The inverse association should use the interest already created and held in memory"
436
- assert man.equal?(man.interests.first.man), "Two inversion should lead back to the same object that was originally held"
437
- assert man.equal?(man.interests.find(interest.id).man), "Two inversions should lead back to the same object that was originally held"
509
+ assert interest.equal?(human.interests.first), "The inverse association should use the interest already created and held in memory"
510
+ assert interest.equal?(human.interests.find(interest.id)), "The inverse association should use the interest already created and held in memory"
511
+ assert human.equal?(human.interests.first.human), "Two inversion should lead back to the same object that was originally held"
512
+ assert human.equal?(human.interests.find(interest.id).human), "Two inversions should lead back to the same object that was originally held"
438
513
  end
439
514
 
440
515
  def test_parent_instance_should_find_child_instance_using_child_instance_id_when_created
441
- man = Man.create!
442
- interest = Interest.create!(man: man)
516
+ human = Human.create!
517
+ interest = Interest.create!(human: human)
443
518
 
444
- assert man.equal?(man.interests.first.man), "Two inverses should lead back to the same object that was originally held"
445
- assert man.equal?(man.interests.find(interest.id).man), "Two inversions should lead back to the same object that was originally held"
519
+ assert human.equal?(human.interests.first.human), "Two inverses should lead back to the same object that was originally held"
520
+ assert human.equal?(human.interests.find(interest.id).human), "Two inversions should lead back to the same object that was originally held"
446
521
 
447
- assert_equal man.name, man.interests.find(interest.id).man.name, "The name of the man should match before the name is changed"
448
- man.name = "Ben Bitdiddle"
449
- assert_equal man.name, man.interests.find(interest.id).man.name, "The name of the man should match after the parent name is changed"
450
- man.interests.find(interest.id).man.name = "Alyssa P. Hacker"
451
- assert_equal man.name, man.interests.find(interest.id).man.name, "The name of the man should match after the child name is changed"
522
+ assert_nil human.interests.find(interest.id).human.name, "The name of the human should match before the name is changed"
523
+ human.name = "Ben Bitdiddle"
524
+ assert_equal human.name, human.interests.find(interest.id).human.name, "The name of the human should match after the parent name is changed"
525
+ human.interests.find(interest.id).human.name = "Alyssa P. Hacker"
526
+ assert_equal human.name, human.interests.find(interest.id).human.name, "The name of the human should match after the child name is changed"
452
527
  end
453
528
 
454
529
  def test_find_on_child_instance_with_id_should_not_load_all_child_records
455
- man = Man.create!
456
- interest = Interest.create!(man: man)
530
+ human = Human.create!
531
+ interest = Interest.create!(human: human)
532
+
533
+ human.interests.find(interest.id)
534
+ assert_not_predicate human.interests, :loaded?
535
+ end
536
+
537
+ def test_find_on_child_instance_with_id_should_set_inverse_instances
538
+ human = Human.create!
539
+ interest = Interest.create!(human: human)
457
540
 
458
- man.interests.find(interest.id)
459
- assert_not man.interests.loaded?
541
+ child = human.interests.find(interest.id)
542
+ assert_predicate child.association(:human), :loaded?
543
+ end
544
+
545
+ def test_find_on_child_instances_with_ids_should_set_inverse_instances
546
+ human = Human.create!
547
+ interests = Array.new(2) { Interest.create!(human: human) }
548
+
549
+ children = human.interests.find(interests.pluck(:id))
550
+ children.each do |child|
551
+ assert_predicate child.association(:human), :loaded?
552
+ end
460
553
  end
461
554
 
462
555
  def test_raise_record_not_found_error_when_invalid_ids_are_passed
@@ -464,270 +557,385 @@ class InverseHasManyTests < ActiveRecord::TestCase
464
557
  # are indeed invalid.
465
558
  Interest.delete_all
466
559
 
467
- man = Man.create!
560
+ human = Human.create!
468
561
 
469
562
  invalid_id = 245324523
470
- assert_raise(ActiveRecord::RecordNotFound) { man.interests.find(invalid_id) }
563
+ assert_raise(ActiveRecord::RecordNotFound) { human.interests.find(invalid_id) }
471
564
 
472
565
  invalid_ids = [8432342, 2390102913, 2453245234523452]
473
- assert_raise(ActiveRecord::RecordNotFound) { man.interests.find(invalid_ids) }
566
+ assert_raise(ActiveRecord::RecordNotFound) { human.interests.find(invalid_ids) }
474
567
  end
475
568
 
476
569
  def test_raise_record_not_found_error_when_no_ids_are_passed
477
- man = Man.create!
570
+ human = Human.create!
571
+
572
+ exception = assert_raise(ActiveRecord::RecordNotFound) { human.interests.load.find() }
478
573
 
479
- assert_raise(ActiveRecord::RecordNotFound) { man.interests.find() }
574
+ assert_equal exception.model, "Interest"
575
+ assert_equal exception.primary_key, "id"
480
576
  end
481
577
 
482
578
  def test_trying_to_use_inverses_that_dont_exist_should_raise_an_error
483
- assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Man.first.secret_interests }
579
+ assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Human.first.secret_interests }
484
580
  end
485
581
 
486
582
  def test_child_instance_should_point_to_parent_without_saving
487
- man = Man.new
488
- i = Interest.create(:topic => 'Industrial Revolution Re-enactment')
583
+ human = Human.new
584
+ interest = Interest.create(topic: "Industrial Revolution Re-enactment")
489
585
 
490
- man.interests << i
491
- assert_not_nil i.man
586
+ human.interests << interest
587
+ assert_not_nil interest.human
492
588
 
493
- i.man.name = "Charles"
494
- assert_equal i.man.name, man.name
589
+ interest.human.name = "Charles"
590
+ assert_equal interest.human.name, human.name
495
591
 
496
- assert !man.persisted?
592
+ assert_not_predicate human, :persisted?
497
593
  end
498
594
 
499
595
  def test_inverse_instance_should_be_set_before_find_callbacks_are_run
500
596
  reset_callbacks(Interest, :find) do
501
- Interest.after_find { raise unless association(:man).loaded? && man.present? }
597
+ Interest.after_find { raise unless association(:human).loaded? && human.present? }
502
598
 
503
- assert Man.first.interests.reload.any?
504
- assert Man.includes(:interests).first.interests.any?
505
- assert Man.joins(:interests).includes(:interests).first.interests.any?
599
+ assert_predicate Human.first.interests.reload, :any?
600
+ assert_predicate Human.includes(:interests).first.interests, :any?
601
+ assert_predicate Human.joins(:interests).includes(:interests).first.interests, :any?
506
602
  end
507
603
  end
508
604
 
509
605
  def test_inverse_instance_should_be_set_before_initialize_callbacks_are_run
510
606
  reset_callbacks(Interest, :initialize) do
511
- Interest.after_initialize { raise unless association(:man).loaded? && man.present? }
607
+ Interest.after_initialize { raise unless association(:human).loaded? && human.present? }
512
608
 
513
- assert Man.first.interests.reload.any?
514
- assert Man.includes(:interests).first.interests.any?
515
- assert Man.joins(:interests).includes(:interests).first.interests.any?
609
+ assert_predicate Human.first.interests.reload, :any?
610
+ assert_predicate Human.includes(:interests).first.interests, :any?
611
+ assert_predicate Human.joins(:interests).includes(:interests).first.interests, :any?
516
612
  end
517
613
  end
518
614
 
519
- def reset_callbacks(target, type)
520
- old_callbacks = target.send(:get_callbacks, type).deep_dup
521
- yield
522
- ensure
523
- target.send(:set_callbacks, type, old_callbacks) if old_callbacks
615
+ def test_inverse_works_when_the_association_self_references_the_same_object
616
+ comment = comments(:greetings)
617
+ Comment.create!(parent: comment, post_id: comment.post_id, body: "New Comment")
618
+
619
+ comment.body = "OMG"
620
+ assert_equal comment.body, comment.children.first.parent.body
524
621
  end
525
622
  end
526
623
 
527
624
  class InverseBelongsToTests < ActiveRecord::TestCase
528
- fixtures :men, :faces, :interests
625
+ fixtures :humans, :faces, :interests
529
626
 
530
627
  def test_child_instance_should_be_shared_with_parent_on_find
531
- f = faces(:trusting)
532
- m = f.man
533
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
534
- f.description = 'gormless'
535
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
536
- m.face.description = 'pleasing'
537
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance"
628
+ face = faces(:trusting)
629
+ human = face.human
630
+ assert_equal face.description, human.face.description, "Description of face should be the same before changes to child instance"
631
+ face.description = "gormless"
632
+ assert_equal face.description, human.face.description, "Description of face should be the same after changes to child instance"
633
+ human.face.description = "pleasing"
634
+ assert_equal face.description, human.face.description, "Description of face should be the same after changes to parent-owned instance"
538
635
  end
539
636
 
540
637
  def test_eager_loaded_child_instance_should_be_shared_with_parent_on_find
541
- f = Face.all.merge!(:includes => :man, :where => {:description => 'trusting'}).first
542
- m = f.man
543
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
544
- f.description = 'gormless'
545
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
546
- m.face.description = 'pleasing'
547
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance"
548
-
549
- f = Face.all.merge!(:includes => :man, :order => 'men.id', :where => {:description => 'trusting'}).first
550
- m = f.man
551
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
552
- f.description = 'gormless'
553
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
554
- m.face.description = 'pleasing'
555
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance"
638
+ face = Face.all.merge!(includes: :human, where: { description: "trusting" }).first
639
+ human = face.human
640
+ assert_equal face.description, human.face.description, "Description of face should be the same before changes to child instance"
641
+ face.description = "gormless"
642
+ assert_equal face.description, human.face.description, "Description of face should be the same after changes to child instance"
643
+ human.face.description = "pleasing"
644
+ assert_equal face.description, human.face.description, "Description of face should be the same after changes to parent-owned instance"
645
+
646
+ face = Face.all.merge!(includes: :human, order: "humans.id", where: { description: "trusting" }).first
647
+ human = face.human
648
+ assert_equal face.description, human.face.description, "Description of face should be the same before changes to child instance"
649
+ face.description = "gormless"
650
+ assert_equal face.description, human.face.description, "Description of face should be the same after changes to child instance"
651
+ human.face.description = "pleasing"
652
+ assert_equal face.description, human.face.description, "Description of face should be the same after changes to parent-owned instance"
556
653
  end
557
654
 
558
655
  def test_child_instance_should_be_shared_with_newly_built_parent
559
- f = faces(:trusting)
560
- m = f.build_man(:name => 'Charles')
561
- assert_not_nil m.face
562
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
563
- f.description = 'gormless'
564
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
565
- m.face.description = 'pleasing'
566
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to just-built-parent-owned instance"
656
+ face = faces(:trusting)
657
+ human = face.build_human(name: "Charles")
658
+ assert_not_nil human.face
659
+ assert_equal face.description, human.face.description, "Description of face should be the same before changes to child instance"
660
+ face.description = "gormless"
661
+ assert_equal face.description, human.face.description, "Description of face should be the same after changes to child instance"
662
+ human.face.description = "pleasing"
663
+ assert_equal face.description, human.face.description, "Description of face should be the same after changes to just-built-parent-owned instance"
567
664
  end
568
665
 
569
666
  def test_child_instance_should_be_shared_with_newly_created_parent
570
- f = faces(:trusting)
571
- m = f.create_man(:name => 'Charles')
572
- assert_not_nil m.face
573
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
574
- f.description = 'gormless'
575
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
576
- m.face.description = 'pleasing'
577
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to newly-created-parent-owned instance"
667
+ face = faces(:trusting)
668
+ human = face.create_human(name: "Charles")
669
+ assert_not_nil human.face
670
+ assert_equal face.description, human.face.description, "Description of face should be the same before changes to child instance"
671
+ face.description = "gormless"
672
+ assert_equal face.description, human.face.description, "Description of face should be the same after changes to child instance"
673
+ human.face.description = "pleasing"
674
+ assert_equal face.description, human.face.description, "Description of face should be the same after changes to newly-created-parent-owned instance"
578
675
  end
579
676
 
580
677
  def test_should_not_try_to_set_inverse_instances_when_the_inverse_is_a_has_many
581
- i = interests(:trainspotting)
582
- m = i.man
583
- assert_not_nil m.interests
584
- iz = m.interests.detect { |_iz| _iz.id == i.id}
678
+ interest = interests(:trainspotting)
679
+ human = interest.human
680
+ assert_not_nil human.interests
681
+ iz = human.interests.detect { |_iz| _iz.id == interest.id }
585
682
  assert_not_nil iz
586
- assert_equal i.topic, iz.topic, "Interest topics should be the same before changes to child"
587
- i.topic = 'Eating cheese with a spoon'
588
- assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to child"
589
- iz.topic = 'Cow tipping'
590
- assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to parent-owned instance"
683
+ assert_equal interest.topic, iz.topic, "Interest topics should be the same before changes to child"
684
+ interest.topic = "Eating cheese with a spoon"
685
+ assert_not_equal interest.topic, iz.topic, "Interest topics should not be the same after changes to child"
686
+ iz.topic = "Cow tipping"
687
+ assert_not_equal interest.topic, iz.topic, "Interest topics should not be the same after changes to parent-owned instance"
688
+ end
689
+
690
+ def test_with_has_many_inversing_should_try_to_set_inverse_instances_when_the_inverse_is_a_has_many
691
+ with_has_many_inversing do
692
+ interest = interests(:trainspotting)
693
+ human = interest.human
694
+ assert_not_nil human.interests
695
+ iz = human.interests.detect { |_iz| _iz.id == interest.id }
696
+ assert_not_nil iz
697
+ assert_equal interest.topic, iz.topic, "Interest topics should be the same before changes to child"
698
+ interest.topic = "Eating cheese with a spoon"
699
+ assert_equal interest.topic, iz.topic, "Interest topics should be the same after changes to child"
700
+ iz.topic = "Cow tipping"
701
+ assert_equal interest.topic, iz.topic, "Interest topics should be the same after changes to parent-owned instance"
702
+ end
703
+ end
704
+
705
+ def test_with_has_many_inversing_should_have_single_record_when_setting_record_through_attribute_in_build_method
706
+ with_has_many_inversing do
707
+ human = Human.create!
708
+ human.interests.build(
709
+ human: human
710
+ )
711
+ assert_equal 1, human.interests.size
712
+ human.save!
713
+ assert_equal 1, human.interests.size
714
+ end
715
+ end
716
+
717
+ def test_with_has_many_inversing_does_not_trigger_association_callbacks_on_set_when_the_inverse_is_a_has_many
718
+ with_has_many_inversing do
719
+ human = interests(:trainspotting).human_with_callbacks
720
+ assert_not_predicate human, :add_callback_called?
721
+ end
722
+ end
723
+
724
+ def test_with_hash_many_inversing_does_not_add_duplicate_associated_objects
725
+ with_has_many_inversing do
726
+ human = Human.new
727
+ interest = Interest.new(human: human)
728
+ human.interests << interest
729
+ assert_equal 1, human.interests.size
730
+ end
731
+ end
732
+
733
+ def test_unscope_does_not_set_inverse_when_incorrect
734
+ interest = interests(:trainspotting)
735
+ human = interest.human
736
+ created_human = Human.create(name: "wrong human")
737
+ found_interest = created_human.interests.or(human.interests).detect { |this_interest| interest.id == this_interest.id }
738
+
739
+ assert_equal human, found_interest.human
740
+ end
741
+
742
+ def test_or_does_not_set_inverse_when_incorrect
743
+ interest = interests(:trainspotting)
744
+ human = interest.human
745
+ created_human = Human.create(name: "wrong human")
746
+ found_interest = created_human.interests.unscope(:where).detect { |this_interest| interest.id == this_interest.id }
747
+
748
+ assert_equal human, found_interest.human
591
749
  end
592
750
 
593
751
  def test_child_instance_should_be_shared_with_replaced_via_accessor_parent
594
- f = Face.first
595
- m = Man.new(:name => 'Charles')
596
- f.man = m
597
- assert_not_nil m.face
598
- assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance"
599
- f.description = 'gormless'
600
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance"
601
- m.face.description = 'pleasing'
602
- assert_equal f.description, m.face.description, "Description of face should be the same after changes to replaced-parent-owned instance"
752
+ face = Face.first
753
+ human = Human.new(name: "Charles")
754
+ face.human = human
755
+ assert_not_nil human.face
756
+ assert_equal face.description, human.face.description, "Description of face should be the same before changes to child instance"
757
+ face.description = "gormless"
758
+ assert_equal face.description, human.face.description, "Description of face should be the same after changes to child instance"
759
+ human.face.description = "pleasing"
760
+ assert_equal face.description, human.face.description, "Description of face should be the same after changes to replaced-parent-owned instance"
603
761
  end
604
762
 
605
763
  def test_trying_to_use_inverses_that_dont_exist_should_raise_an_error
606
- assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Face.first.horrible_man }
764
+ assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Face.first.puzzled_human }
765
+ end
766
+
767
+ if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
768
+ def test_trying_to_use_inverses_that_dont_exist_should_have_suggestions_for_fix
769
+ error = assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) {
770
+ Face.first.puzzled_human
771
+ }
772
+
773
+ assert_match "Did you mean?", error.message
774
+ assert_equal "confused_face", error.corrections.first
775
+ end
776
+ end
777
+
778
+ def test_building_has_many_parent_association_inverses_one_record
779
+ with_has_many_inversing do
780
+ interest = Interest.new
781
+ interest.build_human
782
+ assert_equal 1, interest.human.interests.size
783
+ interest.save!
784
+ assert_equal 1, interest.human.interests.size
785
+ end
607
786
  end
608
787
  end
609
788
 
610
789
  class InversePolymorphicBelongsToTests < ActiveRecord::TestCase
611
- fixtures :men, :faces, :interests
790
+ fixtures :humans, :faces, :interests
612
791
 
613
792
  def test_child_instance_should_be_shared_with_parent_on_find
614
- f = Face.all.merge!(:where => {:description => 'confused'}).first
615
- m = f.polymorphic_man
616
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same before changes to child instance"
617
- f.description = 'gormless'
618
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to child instance"
619
- m.polymorphic_face.description = 'pleasing'
620
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to parent-owned instance"
793
+ face = Face.all.merge!(where: { description: "confused" }).first
794
+ human = face.polymorphic_human
795
+ assert_equal face.description, human.polymorphic_face.description, "Description of face should be the same before changes to child instance"
796
+ face.description = "gormless"
797
+ assert_equal face.description, human.polymorphic_face.description, "Description of face should be the same after changes to child instance"
798
+ human.polymorphic_face.description = "pleasing"
799
+ assert_equal face.description, human.polymorphic_face.description, "Description of face should be the same after changes to parent-owned instance"
621
800
  end
622
801
 
623
802
  def test_eager_loaded_child_instance_should_be_shared_with_parent_on_find
624
- f = Face.all.merge!(:where => {:description => 'confused'}, :includes => :man).first
625
- m = f.polymorphic_man
626
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same before changes to child instance"
627
- f.description = 'gormless'
628
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to child instance"
629
- m.polymorphic_face.description = 'pleasing'
630
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to parent-owned instance"
631
-
632
- f = Face.all.merge!(:where => {:description => 'confused'}, :includes => :man, :order => 'men.id').first
633
- m = f.polymorphic_man
634
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same before changes to child instance"
635
- f.description = 'gormless'
636
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to child instance"
637
- m.polymorphic_face.description = 'pleasing'
638
- assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to parent-owned instance"
803
+ face = Face.all.merge!(where: { description: "confused" }, includes: :human).first
804
+ human = face.polymorphic_human
805
+ assert_equal face.description, human.polymorphic_face.description, "Description of face should be the same before changes to child instance"
806
+ face.description = "gormless"
807
+ assert_equal face.description, human.polymorphic_face.description, "Description of face should be the same after changes to child instance"
808
+ human.polymorphic_face.description = "pleasing"
809
+ assert_equal face.description, human.polymorphic_face.description, "Description of face should be the same after changes to parent-owned instance"
810
+
811
+ face = Face.all.merge!(where: { description: "confused" }, includes: :human, order: "humans.id").first
812
+ human = face.polymorphic_human
813
+ assert_equal face.description, human.polymorphic_face.description, "Description of face should be the same before changes to child instance"
814
+ face.description = "gormless"
815
+ assert_equal face.description, human.polymorphic_face.description, "Description of face should be the same after changes to child instance"
816
+ human.polymorphic_face.description = "pleasing"
817
+ assert_equal face.description, human.polymorphic_face.description, "Description of face should be the same after changes to parent-owned instance"
639
818
  end
640
819
 
641
820
  def test_child_instance_should_be_shared_with_replaced_via_accessor_parent
642
821
  face = faces(:confused)
643
- new_man = Man.new
822
+ new_human = Human.new
644
823
 
645
- assert_not_nil face.polymorphic_man
646
- face.polymorphic_man = new_man
824
+ assert_not_nil face.polymorphic_human
825
+ face.polymorphic_human = new_human
647
826
 
648
- assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same before changes to parent instance"
649
- face.description = 'Bongo'
650
- assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same after changes to parent instance"
651
- new_man.polymorphic_face.description = 'Mungo'
652
- assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same after changes to replaced-parent-owned instance"
827
+ assert_equal face.description, new_human.polymorphic_face.description, "Description of face should be the same before changes to parent instance"
828
+ face.description = "Bongo"
829
+ assert_equal face.description, new_human.polymorphic_face.description, "Description of face should be the same after changes to parent instance"
830
+ new_human.polymorphic_face.description = "Mungo"
831
+ assert_equal face.description, new_human.polymorphic_face.description, "Description of face should be the same after changes to replaced-parent-owned instance"
653
832
  end
654
833
 
655
- def test_child_instance_should_be_shared_with_replaced_via_method_parent
656
- face = faces(:confused)
657
- new_man = Man.new
834
+ def test_inversed_instance_should_not_be_reloaded_after_stale_state_changed
835
+ new_human = Human.new
836
+ face = Face.new
837
+ new_human.face = face
658
838
 
659
- assert_not_nil face.polymorphic_man
660
- face.polymorphic_man = new_man
839
+ old_inversed_human = face.human
840
+ new_human.save!
841
+ new_inversed_human = face.human
661
842
 
662
- assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same before changes to parent instance"
663
- face.description = 'Bongo'
664
- assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same after changes to parent instance"
665
- new_man.polymorphic_face.description = 'Mungo'
666
- assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same after changes to replaced-parent-owned instance"
843
+ assert_same old_inversed_human, new_inversed_human
667
844
  end
668
845
 
669
- def test_inversed_instance_should_not_be_reloaded_after_stale_state_changed
670
- new_man = Man.new
671
- face = Face.new
672
- new_man.face = face
846
+ def test_inversed_instance_should_not_be_reloaded_after_stale_state_changed_with_validation
847
+ face = Face.new human: Human.new
848
+
849
+ old_inversed_human = face.human
850
+ face.save!
851
+ new_inversed_human = face.human
852
+
853
+ assert_same old_inversed_human, new_inversed_human
854
+ end
673
855
 
674
- old_inversed_man = face.man
675
- new_man.save!
676
- new_inversed_man = face.man
856
+ def test_inversed_instance_should_load_after_autosave_if_it_is_not_already_loaded
857
+ human = Human.create!
858
+ human.create_autosave_face!
677
859
 
678
- assert_equal old_inversed_man.object_id, new_inversed_man.object_id
860
+ human.autosave_face.reload # clear cached load of autosave_human
861
+ human.autosave_face.description = "new description"
862
+ human.save!
863
+
864
+ assert_not_nil human.autosave_face.autosave_human
679
865
  end
680
866
 
681
867
  def test_should_not_try_to_set_inverse_instances_when_the_inverse_is_a_has_many
682
- i = interests(:llama_wrangling)
683
- m = i.polymorphic_man
684
- assert_not_nil m.polymorphic_interests
685
- iz = m.polymorphic_interests.detect { |_iz| _iz.id == i.id}
868
+ interest = interests(:llama_wrangling)
869
+ human = interest.polymorphic_human
870
+ assert_not_nil human.polymorphic_interests
871
+ iz = human.polymorphic_interests.detect { |_iz| _iz.id == interest.id }
686
872
  assert_not_nil iz
687
- assert_equal i.topic, iz.topic, "Interest topics should be the same before changes to child"
688
- i.topic = 'Eating cheese with a spoon'
689
- assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to child"
690
- iz.topic = 'Cow tipping'
691
- assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to parent-owned instance"
873
+ assert_equal interest.topic, iz.topic, "Interest topics should be the same before changes to child"
874
+ interest.topic = "Eating cheese with a spoon"
875
+ assert_not_equal interest.topic, iz.topic, "Interest topics should not be the same after changes to child"
876
+ iz.topic = "Cow tipping"
877
+ assert_not_equal interest.topic, iz.topic, "Interest topics should not be the same after changes to parent-owned instance"
878
+ end
879
+
880
+ def test_with_has_many_inversing_should_try_to_set_inverse_instances_when_the_inverse_is_a_has_many
881
+ with_has_many_inversing do
882
+ interest = interests(:llama_wrangling)
883
+ human = interest.polymorphic_human
884
+ assert_not_nil human.polymorphic_interests
885
+ iz = human.polymorphic_interests.detect { |_iz| _iz.id == interest.id }
886
+ assert_not_nil iz
887
+ assert_equal interest.topic, iz.topic, "Interest topics should be the same before changes to child"
888
+ interest.topic = "Eating cheese with a spoon"
889
+ assert_equal interest.topic, iz.topic, "Interest topics should be the same after changes to child"
890
+ iz.topic = "Cow tipping"
891
+ assert_equal interest.topic, iz.topic, "Interest topics should be the same after changes to parent-owned instance"
892
+ end
893
+ end
894
+
895
+ def test_with_has_many_inversing_does_not_trigger_association_callbacks_on_set_when_the_inverse_is_a_has_many
896
+ with_has_many_inversing do
897
+ human = interests(:llama_wrangling).polymorphic_human_with_callbacks
898
+ assert_not_predicate human, :add_callback_called?
899
+ end
692
900
  end
693
901
 
694
902
  def test_trying_to_access_inverses_that_dont_exist_shouldnt_raise_an_error
695
903
  # Ideally this would, if only for symmetry's sake with other association types
696
- assert_nothing_raised { Face.first.horrible_polymorphic_man }
904
+ assert_nothing_raised { Face.first.puzzled_polymorphic_human }
697
905
  end
698
906
 
699
907
  def test_trying_to_set_polymorphic_inverses_that_dont_exist_at_all_should_raise_an_error
700
- # fails because no class has the correct inverse_of for horrible_polymorphic_man
701
- assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Face.first.horrible_polymorphic_man = Man.first }
908
+ # fails because no class has the correct inverse_of for puzzled_polymorphic_human
909
+ assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Face.first.puzzled_polymorphic_human = Human.first }
702
910
  end
703
911
 
704
912
  def test_trying_to_set_polymorphic_inverses_that_dont_exist_on_the_instance_being_set_should_raise_an_error
705
- # passes because Man does have the correct inverse_of
706
- assert_nothing_raised { Face.first.polymorphic_man = Man.first }
913
+ # passes because Human does have the correct inverse_of
914
+ assert_nothing_raised { Face.first.polymorphic_human = Human.first }
707
915
  # fails because Interest does have the correct inverse_of
708
- assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Face.first.polymorphic_man = Interest.first }
916
+ assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Face.first.polymorphic_human = Interest.first }
709
917
  end
710
918
  end
711
919
 
712
920
  # NOTE - these tests might not be meaningful, ripped as they were from the parental_control plugin
713
921
  # which would guess the inverse rather than look for an explicit configuration option.
714
922
  class InverseMultipleHasManyInversesForSameModel < ActiveRecord::TestCase
715
- fixtures :men, :interests, :zines
923
+ fixtures :humans, :interests, :zines
716
924
 
717
925
  def test_that_we_can_load_associations_that_have_the_same_reciprocal_name_from_different_models
718
926
  assert_nothing_raised do
719
- i = Interest.first
720
- i.zine
721
- i.man
927
+ interest = Interest.first
928
+ interest.zine
929
+ interest.human
722
930
  end
723
931
  end
724
932
 
725
933
  def test_that_we_can_create_associations_that_have_the_same_reciprocal_name_from_different_models
726
934
  assert_nothing_raised do
727
- i = Interest.first
728
- i.build_zine(:title => 'Get Some in Winter! 2008')
729
- i.build_man(:name => 'Gordon')
730
- i.save!
935
+ interest = Interest.first
936
+ interest.build_zine(title: "Get Some in Winter! 2008")
937
+ interest.build_human(name: "Gordon")
938
+ interest.save!
731
939
  end
732
940
  end
733
941
  end