ibm_db 5.1.0-x86-mingw32 → 5.3.2-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 (624) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +9 -0
  3. data/LICENSE +55 -18
  4. data/ext/Makefile +14 -14
  5. data/ext/extconf.rb +4 -4
  6. data/ext/ibm_db.c +62 -57
  7. data/ext/ibm_db.o +0 -0
  8. data/ext/ibm_db.so +0 -0
  9. data/ext/mkmf.log +11 -11
  10. data/ext/ruby_ibm_db_cli.c +1 -0
  11. data/ext/ruby_ibm_db_cli.o +0 -0
  12. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1463 -1279
  13. data/lib/ibm_db.so +1 -0
  14. data/lib/mswin32/ibm_db.rb +7 -3
  15. data/lib/mswin32/rb2x/i386/ruby25/ibm_db.so +0 -0
  16. data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
  17. data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
  18. data/test/activejob/destroy_association_async_test.rb +305 -0
  19. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  20. data/test/activejob/helper.rb +15 -0
  21. data/test/assets/schema_dump_5_1.yml +345 -0
  22. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  23. data/test/cases/adapter_test.rb +432 -218
  24. data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
  25. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  26. data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
  27. data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
  28. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
  29. data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
  30. data/test/cases/adapters/mysql2/connection_test.rb +48 -50
  31. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  32. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
  33. data/test/cases/adapters/mysql2/enum_test.rb +32 -11
  34. data/test/cases/adapters/mysql2/explain_test.rb +13 -11
  35. data/test/cases/adapters/mysql2/json_test.rb +17 -188
  36. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  37. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
  38. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  39. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  40. data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
  41. data/test/cases/adapters/mysql2/schema_test.rb +24 -22
  42. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  43. data/test/cases/adapters/mysql2/sp_test.rb +10 -8
  44. data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
  45. data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
  46. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  47. data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
  48. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  49. data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
  50. data/test/cases/adapters/postgresql/array_test.rb +118 -63
  51. data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
  52. data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
  53. data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
  54. data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
  55. data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
  56. data/test/cases/adapters/postgresql/citext_test.rb +58 -58
  57. data/test/cases/adapters/postgresql/collation_test.rb +17 -15
  58. data/test/cases/adapters/postgresql/composite_test.rb +25 -23
  59. data/test/cases/adapters/postgresql/connection_test.rb +73 -85
  60. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  61. data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
  62. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  63. data/test/cases/adapters/postgresql/domain_test.rb +9 -7
  64. data/test/cases/adapters/postgresql/enum_test.rb +12 -10
  65. data/test/cases/adapters/postgresql/explain_test.rb +10 -8
  66. data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
  67. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  68. data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
  69. data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
  70. data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
  71. data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
  72. data/test/cases/adapters/postgresql/integer_test.rb +2 -0
  73. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  74. data/test/cases/adapters/postgresql/json_test.rb +16 -201
  75. data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
  76. data/test/cases/adapters/postgresql/money_test.rb +47 -16
  77. data/test/cases/adapters/postgresql/network_test.rb +36 -28
  78. data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
  79. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  80. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  81. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  82. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
  83. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  84. data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
  85. data/test/cases/adapters/postgresql/range_test.rb +406 -292
  86. data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
  87. data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
  88. data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
  89. data/test/cases/adapters/postgresql/schema_test.rb +207 -91
  90. data/test/cases/adapters/postgresql/serial_test.rb +9 -7
  91. data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
  92. data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
  93. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  94. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  95. data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
  96. data/test/cases/adapters/postgresql/utils_test.rb +11 -9
  97. data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
  98. data/test/cases/adapters/postgresql/xml_test.rb +10 -14
  99. data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
  100. data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
  101. data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
  102. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  103. data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
  104. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  105. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
  106. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
  107. data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
  108. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  109. data/test/cases/aggregations_test.rb +14 -12
  110. data/test/cases/annotate_test.rb +46 -0
  111. data/test/cases/ar_schema_test.rb +153 -86
  112. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  113. data/test/cases/arel/attributes/math_test.rb +83 -0
  114. data/test/cases/arel/attributes_test.rb +27 -0
  115. data/test/cases/arel/collectors/bind_test.rb +40 -0
  116. data/test/cases/arel/collectors/composite_test.rb +47 -0
  117. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  118. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  119. data/test/cases/arel/crud_test.rb +65 -0
  120. data/test/cases/arel/delete_manager_test.rb +53 -0
  121. data/test/cases/arel/factory_methods_test.rb +46 -0
  122. data/test/cases/arel/helper.rb +45 -0
  123. data/test/cases/arel/insert_manager_test.rb +241 -0
  124. data/test/cases/arel/nodes/and_test.rb +30 -0
  125. data/test/cases/arel/nodes/as_test.rb +36 -0
  126. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  127. data/test/cases/arel/nodes/bin_test.rb +35 -0
  128. data/test/cases/arel/nodes/binary_test.rb +29 -0
  129. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  130. data/test/cases/arel/nodes/case_test.rb +96 -0
  131. data/test/cases/arel/nodes/casted_test.rb +18 -0
  132. data/test/cases/arel/nodes/comment_test.rb +22 -0
  133. data/test/cases/arel/nodes/count_test.rb +35 -0
  134. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  135. data/test/cases/arel/nodes/descending_test.rb +46 -0
  136. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  137. data/test/cases/arel/nodes/equality_test.rb +62 -0
  138. data/test/cases/arel/nodes/extract_test.rb +43 -0
  139. data/test/cases/arel/nodes/false_test.rb +21 -0
  140. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  141. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  142. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  143. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  144. data/test/cases/arel/nodes/node_test.rb +22 -0
  145. data/test/cases/arel/nodes/not_test.rb +31 -0
  146. data/test/cases/arel/nodes/or_test.rb +36 -0
  147. data/test/cases/arel/nodes/over_test.rb +69 -0
  148. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  149. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  150. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  151. data/test/cases/arel/nodes/sum_test.rb +35 -0
  152. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  153. data/test/cases/arel/nodes/true_test.rb +21 -0
  154. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  155. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  156. data/test/cases/arel/nodes/window_test.rb +81 -0
  157. data/test/cases/arel/nodes_test.rb +34 -0
  158. data/test/cases/arel/select_manager_test.rb +1238 -0
  159. data/test/cases/arel/support/fake_record.rb +135 -0
  160. data/test/cases/arel/table_test.rb +216 -0
  161. data/test/cases/arel/update_manager_test.rb +126 -0
  162. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  163. data/test/cases/arel/visitors/dot_test.rb +90 -0
  164. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  165. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  166. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  167. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  168. data/test/cases/associations/belongs_to_associations_test.rb +510 -158
  169. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
  170. data/test/cases/associations/callbacks_test.rb +56 -38
  171. data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
  172. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
  173. data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
  174. data/test/cases/associations/eager_singularization_test.rb +21 -21
  175. data/test/cases/associations/eager_test.rb +559 -415
  176. data/test/cases/associations/extension_test.rb +18 -12
  177. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
  178. data/test/cases/associations/has_many_associations_test.rb +1038 -465
  179. data/test/cases/associations/has_many_through_associations_test.rb +558 -249
  180. data/test/cases/associations/has_one_associations_test.rb +294 -129
  181. data/test/cases/associations/has_one_through_associations_test.rb +121 -75
  182. data/test/cases/associations/inner_join_association_test.rb +114 -38
  183. data/test/cases/associations/inverse_associations_test.rb +606 -398
  184. data/test/cases/associations/join_model_test.rb +158 -148
  185. data/test/cases/associations/left_outer_join_association_test.rb +59 -24
  186. data/test/cases/associations/nested_through_associations_test.rb +166 -109
  187. data/test/cases/associations/required_test.rb +35 -10
  188. data/test/cases/associations_test.rb +241 -110
  189. data/test/cases/attribute_methods/read_test.rb +11 -11
  190. data/test/cases/attribute_methods_test.rb +413 -298
  191. data/test/cases/attributes_test.rb +145 -27
  192. data/test/cases/autosave_association_test.rb +681 -436
  193. data/test/cases/base_prevent_writes_test.rb +229 -0
  194. data/test/cases/base_test.rb +599 -542
  195. data/test/cases/batches_test.rb +288 -82
  196. data/test/cases/binary_test.rb +26 -31
  197. data/test/cases/bind_parameter_test.rb +194 -21
  198. data/test/cases/boolean_test.rb +52 -0
  199. data/test/cases/cache_key_test.rb +110 -5
  200. data/test/cases/calculations_test.rb +740 -177
  201. data/test/cases/callbacks_test.rb +74 -207
  202. data/test/cases/clone_test.rb +15 -10
  203. data/test/cases/coders/json_test.rb +2 -0
  204. data/test/cases/coders/yaml_column_test.rb +16 -13
  205. data/test/cases/collection_cache_key_test.rb +177 -20
  206. data/test/cases/column_alias_test.rb +9 -7
  207. data/test/cases/column_definition_test.rb +10 -68
  208. data/test/cases/comment_test.rb +166 -107
  209. data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
  210. data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
  211. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  212. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  213. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  214. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  215. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  216. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  217. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
  218. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
  219. data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
  220. data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
  221. data/test/cases/connection_management_test.rb +13 -11
  222. data/test/cases/connection_pool_test.rb +316 -83
  223. data/test/cases/core_test.rb +82 -58
  224. data/test/cases/counter_cache_test.rb +204 -50
  225. data/test/cases/custom_locking_test.rb +5 -3
  226. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  227. data/test/cases/database_configurations/resolver_test.rb +150 -0
  228. data/test/cases/database_configurations_test.rb +145 -0
  229. data/test/cases/database_selector_test.rb +296 -0
  230. data/test/cases/database_statements_test.rb +18 -16
  231. data/test/cases/date_test.rb +8 -16
  232. data/test/cases/date_time_precision_test.rb +100 -78
  233. data/test/cases/date_time_test.rb +23 -8
  234. data/test/cases/defaults_test.rb +106 -71
  235. data/test/cases/delegated_type_test.rb +57 -0
  236. data/test/cases/dirty_test.rb +419 -223
  237. data/test/cases/disconnected_test.rb +6 -6
  238. data/test/cases/dup_test.rb +54 -27
  239. data/test/cases/enum_test.rb +461 -82
  240. data/test/cases/errors_test.rb +7 -7
  241. data/test/cases/explain_subscriber_test.rb +17 -15
  242. data/test/cases/explain_test.rb +11 -19
  243. data/test/cases/filter_attributes_test.rb +153 -0
  244. data/test/cases/finder_respond_to_test.rb +14 -14
  245. data/test/cases/finder_test.rb +669 -287
  246. data/test/cases/fixture_set/file_test.rb +34 -38
  247. data/test/cases/fixtures_test.rb +833 -176
  248. data/test/cases/forbidden_attributes_protection_test.rb +32 -67
  249. data/test/cases/habtm_destroy_order_test.rb +25 -25
  250. data/test/cases/helper.rb +78 -49
  251. data/test/cases/hot_compatibility_test.rb +33 -32
  252. data/test/cases/i18n_test.rb +18 -17
  253. data/test/cases/inheritance_test.rb +180 -115
  254. data/test/cases/insert_all_test.rb +489 -0
  255. data/test/cases/instrumentation_test.rb +101 -0
  256. data/test/cases/integration_test.rb +119 -31
  257. data/test/cases/invalid_connection_test.rb +18 -16
  258. data/test/cases/invertible_migration_test.rb +183 -43
  259. data/test/cases/json_attribute_test.rb +35 -0
  260. data/test/cases/json_serialization_test.rb +57 -58
  261. data/test/cases/json_shared_test_cases.rb +290 -0
  262. data/test/cases/locking_test.rb +413 -119
  263. data/test/cases/log_subscriber_test.rb +68 -26
  264. data/test/cases/marshal_serialization_test.rb +39 -0
  265. data/test/cases/migration/change_schema_test.rb +118 -72
  266. data/test/cases/migration/change_table_test.rb +138 -30
  267. data/test/cases/migration/check_constraint_test.rb +162 -0
  268. data/test/cases/migration/column_attributes_test.rb +45 -35
  269. data/test/cases/migration/column_positioning_test.rb +18 -6
  270. data/test/cases/migration/columns_test.rb +93 -77
  271. data/test/cases/migration/command_recorder_test.rb +121 -34
  272. data/test/cases/migration/compatibility_test.rb +578 -23
  273. data/test/cases/migration/create_join_table_test.rb +35 -25
  274. data/test/cases/migration/foreign_key_test.rb +503 -284
  275. data/test/cases/migration/helper.rb +4 -3
  276. data/test/cases/migration/index_test.rb +119 -70
  277. data/test/cases/migration/logger_test.rb +9 -6
  278. data/test/cases/migration/pending_migrations_test.rb +88 -34
  279. data/test/cases/migration/references_foreign_key_test.rb +164 -150
  280. data/test/cases/migration/references_index_test.rb +38 -19
  281. data/test/cases/migration/references_statements_test.rb +15 -14
  282. data/test/cases/migration/rename_table_test.rb +53 -30
  283. data/test/cases/migration_test.rb +637 -269
  284. data/test/cases/migrator_test.rb +191 -135
  285. data/test/cases/mixin_test.rb +7 -11
  286. data/test/cases/modules_test.rb +36 -34
  287. data/test/cases/multi_db_migrator_test.rb +223 -0
  288. data/test/cases/multiparameter_attributes_test.rb +60 -33
  289. data/test/cases/multiple_db_test.rb +16 -22
  290. data/test/cases/nested_attributes_test.rb +341 -320
  291. data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
  292. data/test/cases/null_relation_test.rb +84 -0
  293. data/test/cases/numeric_data_test.rb +93 -0
  294. data/test/cases/persistence_test.rb +361 -269
  295. data/test/cases/pooled_connections_test.rb +18 -26
  296. data/test/cases/prepared_statement_status_test.rb +48 -0
  297. data/test/cases/primary_keys_test.rb +210 -104
  298. data/test/cases/query_cache_test.rb +610 -141
  299. data/test/cases/quoting_test.rb +132 -31
  300. data/test/cases/readonly_test.rb +49 -48
  301. data/test/cases/reaper_test.rb +146 -32
  302. data/test/cases/reflection_test.rb +167 -156
  303. data/test/cases/relation/delegation_test.rb +49 -36
  304. data/test/cases/relation/delete_all_test.rb +117 -0
  305. data/test/cases/relation/merging_test.rb +319 -42
  306. data/test/cases/relation/mutation_test.rb +55 -93
  307. data/test/cases/relation/or_test.rb +129 -29
  308. data/test/cases/relation/predicate_builder_test.rb +21 -6
  309. data/test/cases/relation/record_fetch_warning_test.rb +5 -3
  310. data/test/cases/relation/select_test.rb +67 -0
  311. data/test/cases/relation/update_all_test.rb +317 -0
  312. data/test/cases/relation/where_chain_test.rb +68 -32
  313. data/test/cases/relation/where_clause_test.rb +136 -61
  314. data/test/cases/relation/where_test.rb +155 -48
  315. data/test/cases/relation_test.rb +266 -112
  316. data/test/cases/relations_test.rb +969 -744
  317. data/test/cases/reload_models_test.rb +13 -9
  318. data/test/cases/reserved_word_test.rb +141 -0
  319. data/test/cases/result_test.rb +68 -17
  320. data/test/cases/sanitize_test.rb +87 -71
  321. data/test/cases/schema_dumper_test.rb +221 -128
  322. data/test/cases/schema_loading_test.rb +3 -2
  323. data/test/cases/scoping/default_scoping_test.rb +185 -144
  324. data/test/cases/scoping/named_scoping_test.rb +177 -89
  325. data/test/cases/scoping/relation_scoping_test.rb +197 -75
  326. data/test/cases/secure_token_test.rb +18 -3
  327. data/test/cases/serialization_test.rb +30 -28
  328. data/test/cases/serialized_attribute_test.rb +133 -42
  329. data/test/cases/signed_id_test.rb +168 -0
  330. data/test/cases/statement_cache_test.rb +41 -24
  331. data/test/cases/statement_invalid_test.rb +42 -0
  332. data/test/cases/store_test.rb +180 -55
  333. data/test/cases/strict_loading_test.rb +473 -0
  334. data/test/cases/suppressor_test.rb +26 -12
  335. data/test/cases/tasks/database_tasks_test.rb +1258 -194
  336. data/test/cases/tasks/mysql_rake_test.rb +370 -298
  337. data/test/cases/tasks/postgresql_rake_test.rb +481 -251
  338. data/test/cases/tasks/sqlite_rake_test.rb +225 -178
  339. data/test/cases/test_case.rb +51 -40
  340. data/test/cases/test_databases_test.rb +79 -0
  341. data/test/cases/test_fixtures_test.rb +79 -19
  342. data/test/cases/time_precision_test.rb +98 -76
  343. data/test/cases/timestamp_test.rb +102 -99
  344. data/test/cases/touch_later_test.rb +12 -10
  345. data/test/cases/transaction_callbacks_test.rb +344 -90
  346. data/test/cases/transaction_isolation_test.rb +12 -12
  347. data/test/cases/transactions_test.rb +612 -162
  348. data/test/cases/type/adapter_specific_registry_test.rb +14 -2
  349. data/test/cases/type/date_time_test.rb +4 -2
  350. data/test/cases/type/integer_test.rb +4 -2
  351. data/test/cases/type/string_test.rb +10 -8
  352. data/test/cases/type/time_test.rb +28 -0
  353. data/test/cases/type/type_map_test.rb +29 -28
  354. data/test/cases/type/unsigned_integer_test.rb +19 -0
  355. data/test/cases/type_test.rb +2 -0
  356. data/test/cases/types_test.rb +3 -1
  357. data/test/cases/unconnected_test.rb +14 -1
  358. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  359. data/test/cases/validations/absence_validation_test.rb +19 -17
  360. data/test/cases/validations/association_validation_test.rb +30 -28
  361. data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
  362. data/test/cases/validations/i18n_validation_test.rb +22 -21
  363. data/test/cases/validations/length_validation_test.rb +34 -33
  364. data/test/cases/validations/numericality_validation_test.rb +181 -0
  365. data/test/cases/validations/presence_validation_test.rb +21 -19
  366. data/test/cases/validations/uniqueness_validation_test.rb +156 -86
  367. data/test/cases/validations_repair_helper.rb +2 -0
  368. data/test/cases/validations_test.rb +61 -26
  369. data/test/cases/view_test.rb +122 -116
  370. data/test/cases/yaml_serialization_test.rb +79 -34
  371. data/test/config.example.yml +19 -19
  372. data/test/config.rb +3 -1
  373. data/test/config.yml +16 -6
  374. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  375. data/test/fixtures/author_addresses.yml +1 -8
  376. data/test/fixtures/authors.yml +1 -7
  377. data/test/fixtures/binaries.yml +4 -0
  378. data/test/fixtures/books.yml +9 -2
  379. data/test/fixtures/categories_posts.yml +3 -0
  380. data/test/fixtures/citations.yml +5 -0
  381. data/test/fixtures/comments.yml +7 -0
  382. data/test/fixtures/companies.yml +5 -0
  383. data/test/fixtures/computers.yml +2 -0
  384. data/test/fixtures/customers.yml +10 -1
  385. data/test/fixtures/developers.yml +1 -1
  386. data/test/fixtures/essays.yml +10 -0
  387. data/test/fixtures/faces.yml +3 -3
  388. data/test/fixtures/humans.yml +5 -0
  389. data/test/fixtures/interests.yml +7 -7
  390. data/test/fixtures/memberships.yml +7 -0
  391. data/test/fixtures/minimalistics.yml +3 -0
  392. data/test/fixtures/mixed_case_monkeys.yml +2 -2
  393. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  394. data/test/fixtures/naked/yml/parrots.yml +1 -0
  395. data/test/fixtures/other_books.yml +26 -0
  396. data/test/fixtures/other_posts.yml +1 -0
  397. data/test/fixtures/parrots.yml +7 -1
  398. data/test/fixtures/pirates.yml +3 -0
  399. data/test/fixtures/posts.yml +11 -3
  400. data/test/fixtures/readers.yml +6 -0
  401. data/test/fixtures/reserved_words/values.yml +2 -2
  402. data/test/fixtures/sponsors.yml +3 -0
  403. data/test/fixtures/strict_zines.yml +2 -0
  404. data/test/fixtures/subscribers.yml +1 -1
  405. data/test/fixtures/tasks.yml +1 -1
  406. data/test/fixtures/warehouse-things.yml +3 -0
  407. data/test/migrations/10_urban/9_add_expressions.rb +2 -0
  408. data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
  409. data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
  410. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
  411. data/test/migrations/missing/1_people_have_last_names.rb +2 -0
  412. data/test/migrations/missing/3_we_need_reminders.rb +2 -0
  413. data/test/migrations/missing/4_innocent_jointable.rb +3 -1
  414. data/test/migrations/rename/1_we_need_things.rb +2 -0
  415. data/test/migrations/rename/2_rename_things.rb +2 -0
  416. data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
  417. data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
  418. data/test/migrations/to_copy2/1_create_articles.rb +2 -0
  419. data/test/migrations/to_copy2/2_create_comments.rb +3 -1
  420. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
  421. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
  422. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
  423. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
  424. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
  425. data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
  426. data/test/migrations/valid/2_we_need_reminders.rb +2 -0
  427. data/test/migrations/valid/3_innocent_jointable.rb +3 -1
  428. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
  429. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
  430. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
  431. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
  432. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
  433. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
  434. data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
  435. data/test/models/account.rb +46 -0
  436. data/test/models/admin/account.rb +3 -1
  437. data/test/models/admin/randomly_named_c1.rb +2 -0
  438. data/test/models/admin/user.rb +16 -8
  439. data/test/models/admin.rb +4 -2
  440. data/test/models/aircraft.rb +3 -1
  441. data/test/models/arunit2_model.rb +2 -0
  442. data/test/models/author.rb +153 -102
  443. data/test/models/auto_id.rb +2 -0
  444. data/test/models/autoloadable/extra_firm.rb +2 -0
  445. data/test/models/binary.rb +3 -1
  446. data/test/models/binary_field.rb +6 -0
  447. data/test/models/bird.rb +13 -1
  448. data/test/models/book.rb +14 -4
  449. data/test/models/book_destroy_async.rb +24 -0
  450. data/test/models/boolean.rb +5 -0
  451. data/test/models/bulb.rb +13 -4
  452. data/test/models/cake_designer.rb +2 -0
  453. data/test/models/car.rb +17 -10
  454. data/test/models/carrier.rb +2 -0
  455. data/test/models/cart.rb +5 -0
  456. data/test/models/cat.rb +2 -0
  457. data/test/models/categorization.rb +8 -6
  458. data/test/models/category.rb +28 -16
  459. data/test/models/chef.rb +2 -0
  460. data/test/models/citation.rb +5 -1
  461. data/test/models/club.rb +13 -10
  462. data/test/models/college.rb +4 -2
  463. data/test/models/column.rb +2 -0
  464. data/test/models/column_name.rb +2 -0
  465. data/test/models/comment.rb +32 -10
  466. data/test/models/company.rb +102 -106
  467. data/test/models/company_in_module.rb +27 -26
  468. data/test/models/computer.rb +3 -1
  469. data/test/models/contact.rb +15 -13
  470. data/test/models/content.rb +5 -3
  471. data/test/models/contract.rb +21 -3
  472. data/test/models/country.rb +2 -4
  473. data/test/models/course.rb +3 -1
  474. data/test/models/customer.rb +10 -8
  475. data/test/models/customer_carrier.rb +2 -0
  476. data/test/models/dashboard.rb +2 -0
  477. data/test/models/default.rb +2 -0
  478. data/test/models/department.rb +2 -0
  479. data/test/models/destroy_async_parent.rb +15 -0
  480. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  481. data/test/models/developer.rb +152 -85
  482. data/test/models/dl_keyed_belongs_to.rb +13 -0
  483. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  484. data/test/models/dl_keyed_has_many.rb +5 -0
  485. data/test/models/dl_keyed_has_many_through.rb +5 -0
  486. data/test/models/dl_keyed_has_one.rb +5 -0
  487. data/test/models/dl_keyed_join.rb +10 -0
  488. data/test/models/dog.rb +2 -0
  489. data/test/models/dog_lover.rb +2 -0
  490. data/test/models/doubloon.rb +3 -1
  491. data/test/models/drink_designer.rb +17 -0
  492. data/test/models/edge.rb +4 -2
  493. data/test/models/electron.rb +2 -0
  494. data/test/models/engine.rb +3 -2
  495. data/test/models/entrant.rb +2 -0
  496. data/test/models/entry.rb +5 -0
  497. data/test/models/essay.rb +6 -3
  498. data/test/models/essay_destroy_async.rb +12 -0
  499. data/test/models/event.rb +3 -1
  500. data/test/models/eye.rb +5 -3
  501. data/test/models/face.rb +14 -6
  502. data/test/models/family.rb +6 -0
  503. data/test/models/family_tree.rb +6 -0
  504. data/test/models/friendship.rb +5 -3
  505. data/test/models/frog.rb +8 -0
  506. data/test/models/guid.rb +3 -1
  507. data/test/models/guitar.rb +2 -0
  508. data/test/models/hotel.rb +5 -3
  509. data/test/models/human.rb +39 -0
  510. data/test/models/image.rb +3 -1
  511. data/test/models/interest.rb +14 -3
  512. data/test/models/invoice.rb +4 -2
  513. data/test/models/item.rb +3 -1
  514. data/test/models/job.rb +5 -3
  515. data/test/models/joke.rb +4 -2
  516. data/test/models/keyboard.rb +3 -1
  517. data/test/models/legacy_thing.rb +2 -0
  518. data/test/models/lesson.rb +2 -0
  519. data/test/models/line_item.rb +3 -1
  520. data/test/models/liquid.rb +2 -0
  521. data/test/models/matey.rb +3 -1
  522. data/test/models/measurement.rb +4 -0
  523. data/test/models/member.rb +23 -20
  524. data/test/models/member_detail.rb +3 -0
  525. data/test/models/member_type.rb +2 -0
  526. data/test/models/membership.rb +4 -1
  527. data/test/models/mentor.rb +3 -1
  528. data/test/models/message.rb +5 -0
  529. data/test/models/minimalistic.rb +2 -0
  530. data/test/models/minivan.rb +3 -2
  531. data/test/models/mixed_case_monkey.rb +3 -1
  532. data/test/models/molecule.rb +2 -0
  533. data/test/models/mouse.rb +6 -0
  534. data/test/models/movie.rb +2 -0
  535. data/test/models/node.rb +4 -2
  536. data/test/models/non_primary_key.rb +2 -0
  537. data/test/models/notification.rb +2 -0
  538. data/test/models/numeric_data.rb +12 -0
  539. data/test/models/order.rb +4 -2
  540. data/test/models/organization.rb +9 -7
  541. data/test/models/other_dog.rb +3 -1
  542. data/test/models/owner.rb +6 -4
  543. data/test/models/parrot.rb +12 -4
  544. data/test/models/person.rb +59 -54
  545. data/test/models/personal_legacy_thing.rb +3 -1
  546. data/test/models/pet.rb +4 -2
  547. data/test/models/pet_treasure.rb +2 -0
  548. data/test/models/pirate.rb +67 -43
  549. data/test/models/possession.rb +3 -1
  550. data/test/models/post.rb +184 -86
  551. data/test/models/price_estimate.rb +11 -1
  552. data/test/models/professor.rb +3 -1
  553. data/test/models/project.rb +14 -12
  554. data/test/models/publisher/article.rb +2 -0
  555. data/test/models/publisher/magazine.rb +2 -0
  556. data/test/models/publisher.rb +2 -0
  557. data/test/models/randomly_named_c1.rb +2 -0
  558. data/test/models/rating.rb +5 -1
  559. data/test/models/reader.rb +7 -5
  560. data/test/models/recipe.rb +2 -0
  561. data/test/models/record.rb +2 -0
  562. data/test/models/reference.rb +6 -3
  563. data/test/models/reply.rb +39 -21
  564. data/test/models/room.rb +6 -0
  565. data/test/models/section.rb +6 -0
  566. data/test/models/seminar.rb +6 -0
  567. data/test/models/session.rb +6 -0
  568. data/test/models/ship.rb +12 -9
  569. data/test/models/ship_part.rb +5 -3
  570. data/test/models/shop.rb +4 -2
  571. data/test/models/shop_account.rb +2 -0
  572. data/test/models/speedometer.rb +2 -0
  573. data/test/models/sponsor.rb +8 -5
  574. data/test/models/squeak.rb +6 -0
  575. data/test/models/strict_zine.rb +7 -0
  576. data/test/models/string_key_object.rb +2 -0
  577. data/test/models/student.rb +2 -0
  578. data/test/models/subscriber.rb +4 -2
  579. data/test/models/subscription.rb +5 -1
  580. data/test/models/tag.rb +6 -3
  581. data/test/models/tagging.rb +13 -6
  582. data/test/models/task.rb +2 -0
  583. data/test/models/topic.rb +54 -19
  584. data/test/models/toy.rb +4 -0
  585. data/test/models/traffic_light.rb +2 -0
  586. data/test/models/treasure.rb +5 -3
  587. data/test/models/treaty.rb +2 -4
  588. data/test/models/tree.rb +2 -0
  589. data/test/models/tuning_peg.rb +2 -0
  590. data/test/models/tyre.rb +2 -0
  591. data/test/models/user.rb +12 -4
  592. data/test/models/uuid_child.rb +2 -0
  593. data/test/models/uuid_item.rb +2 -0
  594. data/test/models/uuid_parent.rb +2 -0
  595. data/test/models/vegetables.rb +12 -3
  596. data/test/models/vertex.rb +6 -4
  597. data/test/models/warehouse_thing.rb +2 -0
  598. data/test/models/wheel.rb +3 -1
  599. data/test/models/without_table.rb +3 -1
  600. data/test/models/zine.rb +3 -1
  601. data/test/schema/mysql2_specific_schema.rb +49 -35
  602. data/test/schema/oracle_specific_schema.rb +13 -15
  603. data/test/schema/postgresql_specific_schema.rb +51 -40
  604. data/test/schema/schema.rb +334 -154
  605. data/test/schema/sqlite_specific_schema.rb +9 -16
  606. data/test/support/config.rb +26 -26
  607. data/test/support/connection.rb +14 -8
  608. data/test/support/connection_helper.rb +3 -1
  609. data/test/support/ddl_helper.rb +2 -0
  610. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  611. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  612. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  613. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  614. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  615. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  616. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  617. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  618. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  619. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  620. data/test/support/schema_dumping_helper.rb +2 -0
  621. data/test/support/stubs/strong_parameters.rb +40 -0
  622. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  623. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  624. metadata +196 -11
@@ -1,35 +1,42 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cases/helper"
2
- require 'models/post'
3
- require 'models/author'
4
- require 'models/categorization'
5
- require 'models/comment'
6
- require 'models/company'
7
- require 'models/tagging'
8
- require 'models/topic'
9
- require 'models/reply'
10
- require 'models/entrant'
11
- require 'models/project'
12
- require 'models/developer'
13
- require 'models/computer'
14
- require 'models/customer'
15
- require 'models/toy'
16
- require 'models/matey'
17
- require 'models/dog'
18
- require 'models/car'
19
- require 'models/tyre'
4
+ require "models/post"
5
+ require "models/author"
6
+ require "models/account"
7
+ require "models/categorization"
8
+ require "models/comment"
9
+ require "models/company"
10
+ require "models/tagging"
11
+ require "models/topic"
12
+ require "models/reply"
13
+ require "models/rating"
14
+ require "models/entrant"
15
+ require "models/project"
16
+ require "models/developer"
17
+ require "models/computer"
18
+ require "models/customer"
19
+ require "models/toy"
20
+ require "models/matey"
21
+ require "models/dog"
22
+ require "models/car"
23
+ require "models/tyre"
24
+ require "models/subscriber"
25
+ require "models/non_primary_key"
26
+ require "support/stubs/strong_parameters"
20
27
 
21
28
  class FinderTest < ActiveRecord::TestCase
22
29
  fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :author_addresses, :customers, :categories, :categorizations, :cars
23
30
 
24
31
  def test_find_by_id_with_hash
25
- assert_raises(ActiveRecord::StatementInvalid) do
26
- Post.find_by_id(:limit => 1)
32
+ assert_nothing_raised do
33
+ Post.find_by_id(limit: 1)
27
34
  end
28
35
  end
29
36
 
30
37
  def test_find_by_title_and_id_with_hash
31
- assert_raises(ActiveRecord::StatementInvalid) do
32
- Post.find_by_title_and_id('foo', :limit => 1)
38
+ assert_nothing_raised do
39
+ Post.find_by_title_and_id("foo", limit: 1)
33
40
  end
34
41
  end
35
42
 
@@ -37,6 +44,11 @@ class FinderTest < ActiveRecord::TestCase
37
44
  assert_equal(topics(:first).title, Topic.find(1).title)
38
45
  end
39
46
 
47
+ def test_find_with_hash_parameter
48
+ assert_raises(ActiveRecord::RecordNotFound) { Post.find(foo: "bar") }
49
+ assert_raises(ActiveRecord::RecordNotFound) { Post.find(foo: "bar", bar: "baz") }
50
+ end
51
+
40
52
  def test_find_with_proc_parameter_and_block
41
53
  exception = assert_raises(RuntimeError) do
42
54
  Topic.all.find(-> { raise "should happen" }) { |e| e.title == "non-existing-title" }
@@ -49,78 +61,91 @@ class FinderTest < ActiveRecord::TestCase
49
61
  end
50
62
 
51
63
  def test_find_with_ids_returning_ordered
52
- puts "finder_test.test_find_with_ids_returning_ordered"
53
- records = Topic.find([4,2,5])
54
- assert_equal 'The Fourth Topic of the day', records[0].title
55
- assert_equal 'The Second Topic of the day', records[1].title
56
- assert_equal 'The Fifth Topic of the day', records[2].title
64
+ records = Topic.find([4, 2, 5])
65
+ assert_equal "The Fourth Topic of the day", records[0].title
66
+ assert_equal "The Second Topic of the day", records[1].title
67
+ assert_equal "The Fifth Topic of the day", records[2].title
57
68
 
58
- records = Topic.find(4,2,5)
59
- assert_equal 'The Fourth Topic of the day', records[0].title
60
- assert_equal 'The Second Topic of the day', records[1].title
61
- assert_equal 'The Fifth Topic of the day', records[2].title
69
+ records = Topic.find(4, 2, 5)
70
+ assert_equal "The Fourth Topic of the day", records[0].title
71
+ assert_equal "The Second Topic of the day", records[1].title
72
+ assert_equal "The Fifth Topic of the day", records[2].title
62
73
 
63
- records = Topic.find(['4','2','5'])
64
- assert_equal 'The Fourth Topic of the day', records[0].title
65
- assert_equal 'The Second Topic of the day', records[1].title
66
- assert_equal 'The Fifth Topic of the day', records[2].title
74
+ records = Topic.find(["4", "2", "5"])
75
+ assert_equal "The Fourth Topic of the day", records[0].title
76
+ assert_equal "The Second Topic of the day", records[1].title
77
+ assert_equal "The Fifth Topic of the day", records[2].title
67
78
 
68
- records = Topic.find('4','2','5')
69
- assert_equal 'The Fourth Topic of the day', records[0].title
70
- assert_equal 'The Second Topic of the day', records[1].title
71
- assert_equal 'The Fifth Topic of the day', records[2].title
79
+ records = Topic.find("4", "2", "5")
80
+ assert_equal "The Fourth Topic of the day", records[0].title
81
+ assert_equal "The Second Topic of the day", records[1].title
82
+ assert_equal "The Fifth Topic of the day", records[2].title
72
83
  end
73
84
 
74
85
  def test_find_with_ids_and_order_clause
75
86
  # The order clause takes precedence over the informed ids
76
- records = Topic.order(:author_name).find([5,3,1])
77
- assert_equal 'The Third Topic of the day', records[0].title
78
- assert_equal 'The First Topic', records[1].title
79
- assert_equal 'The Fifth Topic of the day', records[2].title
87
+ records = Topic.order(:author_name).find([5, 3, 1])
88
+ assert_equal "The Third Topic of the day", records[0].title
89
+ assert_equal "The First Topic", records[1].title
90
+ assert_equal "The Fifth Topic of the day", records[2].title
80
91
 
81
- records = Topic.order(:id).find([5,3,1])
82
- assert_equal 'The First Topic', records[0].title
83
- assert_equal 'The Third Topic of the day', records[1].title
84
- assert_equal 'The Fifth Topic of the day', records[2].title
92
+ records = Topic.order(:id).find([5, 3, 1])
93
+ assert_equal "The First Topic", records[0].title
94
+ assert_equal "The Third Topic of the day", records[1].title
95
+ assert_equal "The Fifth Topic of the day", records[2].title
85
96
  end
86
97
 
87
98
  def test_find_with_ids_with_limit_and_order_clause
88
- puts "finder_test.test_find_with_ids_with_limit_and_order_clause"
89
99
  # The order clause takes precedence over the informed ids
90
- records = Topic.limit(2).order(:id).find([5,3,1])
100
+ records = Topic.limit(2).order(:id).find([5, 3, 1])
91
101
  assert_equal 2, records.size
92
- assert_equal 'The First Topic', records[0].title
93
- assert_equal 'The Third Topic of the day', records[1].title
102
+ assert_equal "The First Topic", records[0].title
103
+ assert_equal "The Third Topic of the day", records[1].title
94
104
  end
95
105
 
96
106
  def test_find_with_ids_and_limit
97
- records = Topic.limit(3).find([3,2,5,1,4])
107
+ records = Topic.limit(3).find([3, 2, 5, 1, 4])
98
108
  assert_equal 3, records.size
99
- assert_equal 'The Third Topic of the day', records[0].title
100
- assert_equal 'The Second Topic of the day', records[1].title
101
- assert_equal 'The Fifth Topic of the day', records[2].title
109
+ assert_equal "The Third Topic of the day", records[0].title
110
+ assert_equal "The Second Topic of the day", records[1].title
111
+ assert_equal "The Fifth Topic of the day", records[2].title
102
112
  end
103
113
 
104
114
  def test_find_with_ids_where_and_limit
105
115
  # Please note that Topic 1 is the only not approved so
106
116
  # if it were among the first 3 it would raise an ActiveRecord::RecordNotFound
107
- records = Topic.where(approved: true).limit(3).find([3,2,5,1,4])
117
+ records = Topic.where(approved: true).limit(3).find([3, 2, 5, 1, 4])
108
118
  assert_equal 3, records.size
109
- assert_equal 'The Third Topic of the day', records[0].title
110
- assert_equal 'The Second Topic of the day', records[1].title
111
- assert_equal 'The Fifth Topic of the day', records[2].title
119
+ assert_equal "The Third Topic of the day", records[0].title
120
+ assert_equal "The Second Topic of the day", records[1].title
121
+ assert_equal "The Fifth Topic of the day", records[2].title
112
122
  end
113
123
 
114
124
  def test_find_with_ids_and_offset
115
- records = Topic.offset(2).find([3,2,5,1,4])
125
+ records = Topic.offset(2).find([3, 2, 5, 1, 4])
116
126
  assert_equal 3, records.size
117
- assert_equal 'The Fifth Topic of the day', records[0].title
118
- assert_equal 'The First Topic', records[1].title
119
- assert_equal 'The Fourth Topic of the day', records[2].title
127
+ assert_equal "The Fifth Topic of the day", records[0].title
128
+ assert_equal "The First Topic", records[1].title
129
+ assert_equal "The Fourth Topic of the day", records[2].title
130
+ end
131
+
132
+ def test_find_with_ids_with_no_id_passed
133
+ exception = assert_raises(ActiveRecord::RecordNotFound) { Topic.find }
134
+ assert_equal exception.model, "Topic"
135
+ assert_equal exception.primary_key, "id"
120
136
  end
121
137
 
122
- def test_find_passing_active_record_object_is_deprecated
123
- assert_deprecated do
138
+ def test_find_with_ids_with_id_out_of_range
139
+ exception = assert_raises(ActiveRecord::RecordNotFound) do
140
+ Topic.find("9999999999999999999999999999999")
141
+ end
142
+
143
+ assert_equal exception.model, "Topic"
144
+ assert_equal exception.primary_key, "id"
145
+ end
146
+
147
+ def test_find_passing_active_record_object_is_not_permitted
148
+ assert_raises(ArgumentError) do
124
149
  Topic.find(Topic.last)
125
150
  end
126
151
  end
@@ -129,7 +154,7 @@ class FinderTest < ActiveRecord::TestCase
129
154
  gc_disabled = GC.disable
130
155
  Post.where("author_id" => nil) # warm up
131
156
  x = Symbol.all_symbols.count
132
- Post.where("title" => {"xxxqqqq" => "bar"})
157
+ Post.where("title" => { "xxxqqqq" => "bar" })
133
158
  assert_equal x, Symbol.all_symbols.count
134
159
  ensure
135
160
  GC.enable if gc_disabled == false
@@ -138,7 +163,7 @@ class FinderTest < ActiveRecord::TestCase
138
163
  # find should handle strings that come from URLs
139
164
  # (example: Category.find(params[:id]))
140
165
  def test_find_with_string
141
- assert_equal(Topic.find(1).title,Topic.find("1").title)
166
+ assert_equal(Topic.find(1).title, Topic.find("1").title)
142
167
  end
143
168
 
144
169
  def test_exists
@@ -146,23 +171,49 @@ class FinderTest < ActiveRecord::TestCase
146
171
  assert_equal true, Topic.exists?("1")
147
172
  assert_equal true, Topic.exists?(title: "The First Topic")
148
173
  assert_equal true, Topic.exists?(heading: "The First Topic")
149
- assert_equal true, Topic.exists?(:author_name => "Mary", :approved => true)
174
+ assert_equal true, Topic.exists?(author_name: "Mary", approved: true)
150
175
  assert_equal true, Topic.exists?(["parent_id = ?", 1])
151
176
  assert_equal true, Topic.exists?(id: [1, 9999])
152
177
 
153
178
  assert_equal false, Topic.exists?(45)
179
+ assert_equal false, Topic.exists?(9999999999999999999999999999999)
154
180
  assert_equal false, Topic.exists?(Topic.new.id)
155
181
 
156
- assert_raise(NoMethodError) { Topic.exists?([1,2]) }
182
+ assert_raise(NoMethodError) { Topic.exists?([1, 2]) }
183
+ end
184
+
185
+ def test_exists_with_scope
186
+ davids = Author.where(name: "David")
187
+ assert_equal true, davids.exists?
188
+ assert_equal true, davids.exists?(authors(:david).id)
189
+ assert_equal false, davids.exists?(authors(:mary).id)
190
+ assert_equal false, davids.exists?("42")
191
+ assert_equal false, davids.exists?(42)
192
+ assert_equal false, davids.exists?(davids.new.id)
193
+
194
+ fake = Author.where(name: "fake author")
195
+ assert_equal false, fake.exists?
196
+ assert_equal false, fake.exists?(authors(:david).id)
197
+ end
198
+
199
+ def test_exists_uses_existing_scope
200
+ post = authors(:david).posts.first
201
+ authors = Author.includes(:posts).where(name: "David", posts: { id: post.id })
202
+ assert_equal true, authors.exists?(authors(:david).id)
203
+ end
204
+
205
+ def test_any_with_scope_on_hash_includes
206
+ post = authors(:david).posts.first
207
+ categories = Categorization.includes(author: :posts).where(posts: { id: post.id })
208
+ assert_equal true, categories.exists?
157
209
  end
158
210
 
159
211
  def test_exists_with_polymorphic_relation
160
- puts "finder_test.test_exists_with_polymorphic_relation"
161
- post = Post.create!(title: 'Post', body: 'default', taggings: [Tagging.new(comment: 'tagging comment')])
162
- relation = Post.tagged_with_comment('tagging comment')
212
+ post = Post.create!(title: "Post", body: "default", taggings: [Tagging.new(comment: "tagging comment")])
213
+ relation = Post.tagged_with_comment("tagging comment")
163
214
 
164
- assert_equal true, relation.exists?(title: ['Post'])
165
- assert_equal true, relation.exists?(['title LIKE ?', 'Post%'])
215
+ assert_equal true, relation.exists?(title: ["Post"])
216
+ assert_equal true, relation.exists?(["title LIKE ?", "Post%"])
166
217
  assert_equal true, relation.exists?
167
218
  assert_equal true, relation.exists?(post.id)
168
219
  assert_equal true, relation.exists?(post.id.to_s)
@@ -170,23 +221,38 @@ class FinderTest < ActiveRecord::TestCase
170
221
  assert_equal false, relation.exists?(false)
171
222
  end
172
223
 
173
- def test_exists_passing_active_record_object_is_deprecated
174
- assert_deprecated do
175
- Topic.exists?(Topic.new)
224
+ def test_exists_with_string
225
+ assert_equal false, Subscriber.exists?("foo")
226
+ assert_equal false, Subscriber.exists?(" ")
227
+
228
+ Subscriber.create!(id: "foo")
229
+ Subscriber.create!(id: " ")
230
+
231
+ assert_equal true, Subscriber.exists?("foo")
232
+ assert_equal true, Subscriber.exists?(" ")
233
+ end
234
+
235
+ def test_exists_with_strong_parameters
236
+ assert_equal false, Subscriber.exists?(ProtectedParams.new(nick: "foo").permit!)
237
+
238
+ Subscriber.create!(nick: "foo")
239
+
240
+ assert_equal true, Subscriber.exists?(ProtectedParams.new(nick: "foo").permit!)
241
+
242
+ assert_raises(ActiveModel::ForbiddenAttributesError) do
243
+ Subscriber.exists?(ProtectedParams.new(nick: "foo"))
176
244
  end
177
245
  end
178
246
 
179
- def test_exists_fails_when_parameter_has_invalid_type
180
- puts "finder_test.test_exists_fails_when_parameter_has_invalid_type"
181
- assert_raises(ActiveModel::RangeError) do
182
- assert_equal false, Topic.exists?(("9"*53).to_i) # number that's bigger than int
247
+ def test_exists_passing_active_record_object_is_not_permitted
248
+ assert_raises(ArgumentError) do
249
+ Topic.exists?(Topic.new)
183
250
  end
184
- assert_equal false, Topic.exists?("foo")
185
251
  end
186
252
 
187
253
  def test_exists_does_not_select_columns_without_alias
188
- puts "finder_test.test_exists_does_not_select_columns_without_alias"
189
- assert_sql(/SELECT\W+1 AS one FROM ["`]topics["`]/i) do
254
+ c = Topic.connection
255
+ assert_sql(/SELECT 1 AS one FROM #{Regexp.escape(c.quote_table_name("topics"))}/i) do
190
256
  Topic.exists?
191
257
  end
192
258
  end
@@ -209,29 +275,81 @@ class FinderTest < ActiveRecord::TestCase
209
275
  assert_equal true, Topic.first.replies.exists?
210
276
  end
211
277
 
212
- # ensures +exists?+ runs valid SQL by excluding order value
213
- def test_exists_with_order
278
+ def test_exists_with_empty_hash_arg
279
+ assert_equal true, Topic.exists?({})
280
+ end
281
+
282
+ def test_exists_with_distinct_and_offset_and_joins
283
+ assert Post.left_joins(:comments).distinct.offset(10).exists?
284
+ assert_not Post.left_joins(:comments).distinct.offset(11).exists?
285
+ end
286
+
287
+ def test_exists_with_distinct_and_offset_and_select
288
+ assert Post.select(:body).distinct.offset(4).exists?
289
+ assert_not Post.select(:body).distinct.offset(5).exists?
290
+ end
291
+
292
+ def test_exists_with_distinct_and_offset_and_eagerload_and_order
293
+ assert Post.eager_load(:comments).distinct.offset(10).merge(Comment.order(post_id: :asc)).exists?
294
+ assert_not Post.eager_load(:comments).distinct.offset(11).merge(Comment.order(post_id: :asc)).exists?
295
+ end
296
+
297
+ # Ensure +exists?+ runs without an error by excluding distinct value.
298
+ # See https://github.com/rails/rails/pull/26981.
299
+ def test_exists_with_order_and_distinct
214
300
  assert_equal true, Topic.order(:id).distinct.exists?
215
301
  end
216
302
 
303
+ # Ensure +exists?+ runs without an error by excluding order value.
304
+ def test_exists_with_order
305
+ assert_equal true, Topic.order(Arel.sql("invalid sql here")).exists?
306
+ end
307
+
308
+ def test_exists_with_large_number
309
+ assert_equal true, Topic.where(id: [1, 9223372036854775808]).exists?
310
+ assert_equal true, Topic.where(id: 1..9223372036854775808).exists?
311
+ assert_equal true, Topic.where(id: -9223372036854775809..9223372036854775808).exists?
312
+ assert_equal false, Topic.where(id: 9223372036854775808..9223372036854775809).exists?
313
+ assert_equal false, Topic.where(id: -9223372036854775810..-9223372036854775809).exists?
314
+ assert_equal false, Topic.where(id: 9223372036854775808..1).exists?
315
+ assert_equal true, Topic.where(id: 1).or(Topic.where(id: 9223372036854775808)).exists?
316
+ assert_equal true, Topic.where.not(id: 9223372036854775808).exists?
317
+ end
318
+
319
+ def test_exists_with_joins
320
+ assert_equal true, Topic.joins(:replies).where(replies_topics: { approved: true }).order("replies_topics.created_at DESC").exists?
321
+ end
322
+
323
+ def test_exists_with_left_joins
324
+ assert_equal true, Topic.left_joins(:replies).where(replies_topics: { approved: true }).order("replies_topics.created_at DESC").exists?
325
+ end
326
+
327
+ def test_exists_with_eager_load
328
+ assert_equal true, Topic.eager_load(:replies).where(replies_topics: { approved: true }).order("replies_topics.created_at DESC").exists?
329
+ end
330
+
217
331
  def test_exists_with_includes_limit_and_empty_result
218
- puts "finder_test.test_exists_with_includes_limit_and_empty_result"
219
- assert_equal false, Topic.includes(:replies).limit(0).exists?
220
- assert_equal false, Topic.includes(:replies).limit(1).where('0 = 1').exists?
332
+ assert_no_queries { assert_equal false, Topic.includes(:replies).limit(0).exists? }
333
+ assert_queries(1) { assert_equal false, Topic.includes(:replies).limit(1).where("0 = 1").exists? }
221
334
  end
222
335
 
223
336
  def test_exists_with_distinct_association_includes_and_limit
224
- puts "finder_test.test_exists_with_distinct_association_includes_and_limit"
225
337
  author = Author.first
226
- assert_equal false, author.unique_categorized_posts.includes(:special_comments).limit(0).exists?
227
- assert_equal true, author.unique_categorized_posts.includes(:special_comments).limit(1).exists?
338
+ unique_categorized_posts = author.unique_categorized_posts.includes(:special_comments)
339
+ assert_no_queries { assert_equal false, unique_categorized_posts.limit(0).exists? }
340
+ assert_queries(1) { assert_equal true, unique_categorized_posts.limit(1).exists? }
228
341
  end
229
342
 
230
343
  def test_exists_with_distinct_association_includes_limit_and_order
231
- puts "finder_test.test_exists_with_distinct_association_includes_limit_and_order"
232
344
  author = Author.first
233
- assert_equal false, author.unique_categorized_posts.includes(:special_comments).order('comments.tags_count DESC').limit(0).exists?
234
- assert_equal true, author.unique_categorized_posts.includes(:special_comments).order('comments.tags_count DESC').limit(1).exists?
345
+ unique_categorized_posts = author.unique_categorized_posts.includes(:special_comments).order("comments.tags_count DESC")
346
+ assert_no_queries { assert_equal false, unique_categorized_posts.limit(0).exists? }
347
+ assert_queries(1) { assert_equal true, unique_categorized_posts.limit(1).exists? }
348
+ end
349
+
350
+ def test_exists_should_reference_correct_aliases_while_joining_tables_of_has_many_through_association
351
+ ratings = developers(:david).ratings.includes(comment: :post).where(posts: { id: 1 })
352
+ assert_queries(1) { assert_not_predicate ratings.limit(1), :exists? }
235
353
  end
236
354
 
237
355
  def test_exists_with_empty_table_and_no_args_given
@@ -241,17 +359,14 @@ class FinderTest < ActiveRecord::TestCase
241
359
 
242
360
  def test_exists_with_aggregate_having_three_mappings
243
361
  existing_address = customers(:david).address
244
- assert_equal true, Customer.exists?(:address => existing_address)
362
+ assert_equal true, Customer.exists?(address: existing_address)
245
363
  end
246
364
 
247
365
  def test_exists_with_aggregate_having_three_mappings_with_one_difference
248
366
  existing_address = customers(:david).address
249
- assert_equal false, Customer.exists?(:address =>
250
- Address.new(existing_address.street, existing_address.city, existing_address.country + "1"))
251
- assert_equal false, Customer.exists?(:address =>
252
- Address.new(existing_address.street, existing_address.city + "1", existing_address.country))
253
- assert_equal false, Customer.exists?(:address =>
254
- Address.new(existing_address.street + "1", existing_address.city, existing_address.country))
367
+ assert_equal false, Customer.exists?(address: Address.new(existing_address.street, existing_address.city, existing_address.country + "1"))
368
+ assert_equal false, Customer.exists?(address: Address.new(existing_address.street, existing_address.city + "1", existing_address.country))
369
+ assert_equal false, Customer.exists?(address: Address.new(existing_address.street + "1", existing_address.city, existing_address.country))
255
370
  end
256
371
 
257
372
  def test_exists_does_not_instantiate_records
@@ -260,6 +375,125 @@ class FinderTest < ActiveRecord::TestCase
260
375
  end
261
376
  end
262
377
 
378
+ def test_include_on_unloaded_relation_with_match
379
+ assert_sql(/1 AS one.*LIMIT/) do
380
+ assert_equal true, Customer.where(name: "David").include?(customers(:david))
381
+ end
382
+ end
383
+
384
+ def test_include_on_unloaded_relation_without_match
385
+ assert_sql(/1 AS one.*LIMIT/) do
386
+ assert_equal false, Customer.where(name: "David").include?(customers(:mary))
387
+ end
388
+ end
389
+
390
+ def test_include_on_unloaded_relation_with_mismatched_class
391
+ topic = topics(:first)
392
+ assert Customer.exists?(topic.id)
393
+
394
+ assert_no_queries do
395
+ assert_equal false, Customer.where(name: "David").include?(topic)
396
+ end
397
+ end
398
+
399
+ def test_include_on_unloaded_relation_with_offset
400
+ assert_sql(/ORDER BY name ASC/) do
401
+ assert_equal true, Customer.offset(1).order("name ASC").include?(customers(:mary))
402
+ end
403
+ end
404
+
405
+ def test_include_on_unloaded_relation_with_limit
406
+ mary = customers(:mary)
407
+ barney = customers(:barney)
408
+ david = customers(:david)
409
+
410
+ assert_equal false, Customer.order(id: :desc).limit(2).include?(david)
411
+ assert_equal true, Customer.order(id: :desc).limit(2).include?(barney)
412
+ assert_equal true, Customer.order(id: :desc).limit(2).include?(mary)
413
+ end
414
+
415
+ def test_include_on_unloaded_relation_with_having_referencing_aliased_select
416
+ skip if current_adapter?(:PostgreSQLAdapter)
417
+ bob = authors(:bob)
418
+ mary = authors(:mary)
419
+
420
+ assert_equal false, Author.select("COUNT(*) as total_posts", "authors.*").joins(:posts).group(:id).having("total_posts > 2").include?(bob)
421
+ assert_equal true, Author.select("COUNT(*) as total_posts", "authors.*").joins(:posts).group(:id).having("total_posts > 2").include?(mary)
422
+ end
423
+
424
+ def test_include_on_loaded_relation_with_match
425
+ customers = Customer.where(name: "David").load
426
+ david = customers(:david)
427
+
428
+ assert_no_queries do
429
+ assert_equal true, customers.include?(david)
430
+ end
431
+ end
432
+
433
+ def test_include_on_loaded_relation_without_match
434
+ customers = Customer.where(name: "David").load
435
+ mary = customers(:mary)
436
+
437
+ assert_no_queries do
438
+ assert_equal false, customers.include?(mary)
439
+ end
440
+ end
441
+
442
+ def test_member_on_unloaded_relation_with_match
443
+ assert_sql(/1 AS one.*LIMIT/) do
444
+ assert_equal true, Customer.where(name: "David").member?(customers(:david))
445
+ end
446
+ end
447
+
448
+ def test_member_on_unloaded_relation_without_match
449
+ assert_sql(/1 AS one.*LIMIT/) do
450
+ assert_equal false, Customer.where(name: "David").member?(customers(:mary))
451
+ end
452
+ end
453
+
454
+ def test_member_on_unloaded_relation_with_mismatched_class
455
+ topic = topics(:first)
456
+ assert Customer.exists?(topic.id)
457
+
458
+ assert_no_queries do
459
+ assert_equal false, Customer.where(name: "David").member?(topic)
460
+ end
461
+ end
462
+
463
+ def test_member_on_unloaded_relation_with_offset
464
+ assert_sql(/ORDER BY name ASC/) do
465
+ assert_equal true, Customer.offset(1).order("name ASC").member?(customers(:mary))
466
+ end
467
+ end
468
+
469
+ def test_member_on_unloaded_relation_with_limit
470
+ mary = customers(:mary)
471
+ barney = customers(:barney)
472
+ david = customers(:david)
473
+
474
+ assert_equal false, Customer.order(id: :desc).limit(2).member?(david)
475
+ assert_equal true, Customer.order(id: :desc).limit(2).member?(barney)
476
+ assert_equal true, Customer.order(id: :desc).limit(2).member?(mary)
477
+ end
478
+
479
+ def test_member_on_loaded_relation_with_match
480
+ customers = Customer.where(name: "David").load
481
+ david = customers(:david)
482
+
483
+ assert_no_queries do
484
+ assert_equal true, customers.member?(david)
485
+ end
486
+ end
487
+
488
+ def test_member_on_loaded_relation_without_match
489
+ customers = Customer.where(name: "David").load
490
+ mary = customers(:mary)
491
+
492
+ assert_no_queries do
493
+ assert_equal false, customers.member?(mary)
494
+ end
495
+ end
496
+
263
497
  def test_find_by_array_of_one_id
264
498
  assert_kind_of(Array, Topic.find([ 1 ]))
265
499
  assert_equal(1, Topic.find([ 1 ]).length)
@@ -271,47 +505,63 @@ class FinderTest < ActiveRecord::TestCase
271
505
  end
272
506
 
273
507
  def test_find_by_ids_with_limit_and_offset
274
- assert_equal 2, Entrant.limit(2).find([1,3,2]).size
275
- entrants = Entrant.limit(3).offset(2).find([1,3,2])
508
+ assert_equal 2, Entrant.limit(2).find([1, 3, 2]).size
509
+ entrants = Entrant.limit(3).offset(2).find([1, 3, 2])
276
510
  assert_equal 1, entrants.size
277
- assert_equal 'Ruby Guru', entrants.first.name
511
+ assert_equal "Ruby Guru", entrants.first.name
278
512
 
279
513
  # Also test an edge case: If you have 11 results, and you set a
280
514
  # limit of 3 and offset of 9, then you should find that there
281
515
  # will be only 2 results, regardless of the limit.
282
516
  devs = Developer.all
283
- last_devs = Developer.limit(3).offset(9).find devs.map(&:id)
517
+ last_devs = Developer.limit(3).offset(9).find(devs.map(&:id).sort)
284
518
  assert_equal 2, last_devs.size
285
- assert_equal 'fixture_10', last_devs[0].name
286
- assert_equal 'Jamis', last_devs[1].name
519
+ assert_equal "fixture_10", last_devs[0].name
520
+ assert_equal "Jamis", last_devs[1].name
287
521
  end
288
522
 
289
- unless current_adapter?(:IBM_DBAdapter)
290
- def test_find_with_large_number
291
- assert_raises(ActiveRecord::RecordNotFound) { Topic.find('9999999999999999999999999999999') }
292
- end
523
+ def test_find_with_large_number
524
+ assert_queries(0) do
525
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find("9999999999999999999999999999999") }
526
+ end
527
+ end
293
528
 
294
- def test_find_by_with_large_number
295
- assert_nil Topic.find_by(id: '9999999999999999999999999999999')
296
- end
529
+ def test_find_by_with_large_number
530
+ assert_queries(0) do
531
+ assert_nil Topic.find_by(id: "9999999999999999999999999999999")
532
+ end
533
+ end
297
534
 
298
- def test_find_by_id_with_large_number
299
- assert_nil Topic.find_by_id('9999999999999999999999999999999')
300
- end
535
+ def test_find_by_id_with_large_number
536
+ assert_queries(0) do
537
+ assert_nil Topic.find_by_id("9999999999999999999999999999999")
538
+ end
539
+ end
540
+
541
+ def test_find_on_relation_with_large_number
542
+ assert_raises(ActiveRecord::RecordNotFound) do
543
+ Topic.where("1=1").find(9999999999999999999999999999999)
544
+ end
545
+ assert_equal topics(:first), Topic.where(id: [1, 9999999999999999999999999999999]).find(1)
546
+ end
301
547
 
302
- def test_find_on_relation_with_large_number
303
- assert_nil Topic.where('1=1').find_by(id: 9999999999999999999999999999999)
304
- end
548
+ def test_find_by_on_relation_with_large_number
549
+ assert_nil Topic.where("1=1").find_by(id: 9999999999999999999999999999999)
550
+ assert_equal topics(:first), Topic.where(id: [1, 9999999999999999999999999999999]).find_by(id: 1)
551
+ end
305
552
 
306
- def test_find_by_bang_on_relation_with_large_number
307
- assert_raises(ActiveRecord::RecordNotFound) do
308
- Topic.where('1=1').find_by!(id: 9999999999999999999999999999999)
309
- end
310
- end
553
+ def test_find_by_bang_on_relation_with_large_number
554
+ assert_raises(ActiveRecord::RecordNotFound) do
555
+ Topic.where("1=1").find_by!(id: 9999999999999999999999999999999)
556
+ end
557
+ assert_equal topics(:first), Topic.where(id: [1, 9999999999999999999999999999999]).find_by!(id: 1)
311
558
  end
312
559
 
313
560
  def test_find_an_empty_array
314
- assert_equal [], Topic.find([])
561
+ empty_array = []
562
+ result = Topic.find(empty_array)
563
+ assert_equal [], result
564
+ assert_not_same empty_array, result
315
565
  end
316
566
 
317
567
  def test_find_doesnt_have_implicit_ordering
@@ -323,7 +573,7 @@ class FinderTest < ActiveRecord::TestCase
323
573
  end
324
574
 
325
575
  def test_find_with_group_and_sanitized_having_method
326
- developers = Developer.group(:salary).having("sum(salary) > ?", 10000).select('salary').to_a
576
+ developers = Developer.group(:salary).having("sum(salary) > ?", 10000).select("salary").to_a
327
577
  assert_equal 3, developers.size
328
578
  assert_equal 3, developers.map(&:salary).uniq.size
329
579
  assert developers.all? { |developer| developer.salary > 10000 }
@@ -349,18 +599,23 @@ class FinderTest < ActiveRecord::TestCase
349
599
  end
350
600
 
351
601
  def test_find_by_association_subquery
352
- author = authors(:david)
353
- assert_equal author.post, Post.find_by(author: Author.where(id: author))
354
- assert_equal author.post, Post.find_by(author_id: Author.where(id: author))
602
+ firm = companies(:first_firm)
603
+ assert_equal firm.account, Account.find_by(firm: Firm.where(id: firm))
604
+ assert_equal firm.account, Account.find_by(firm_id: Firm.where(id: firm))
355
605
  end
356
606
 
357
607
  def test_find_by_and_where_consistency_with_active_record_instance
358
- author = authors(:david)
359
- assert_equal Post.where(author_id: author).take, Post.find_by(author_id: author)
608
+ firm = companies(:first_firm)
609
+ assert_equal Account.where(firm_id: firm).take, Account.find_by(firm_id: firm)
610
+ end
611
+
612
+ def test_find_by_with_alias
613
+ account = accounts(:last_account)
614
+ assert_equal account, Account.find_by(available_credit: account.available_credit)
360
615
  end
361
616
 
362
617
  def test_take
363
- assert_equal topics(:first), Topic.take
618
+ assert_equal topics(:first), Topic.where("title = 'The First Topic'").take
364
619
  end
365
620
 
366
621
  def test_take_failing
@@ -403,6 +658,8 @@ class FinderTest < ActiveRecord::TestCase
403
658
  expected = topics(:first)
404
659
  expected.touch # PostgreSQL changes the default order if no order clause is used
405
660
  assert_equal expected, Topic.first
661
+ assert_equal expected, Topic.limit(5).first
662
+ assert_equal expected, Topic.order(nil).first
406
663
  end
407
664
 
408
665
  def test_model_class_responds_to_first_bang
@@ -414,20 +671,19 @@ class FinderTest < ActiveRecord::TestCase
414
671
  end
415
672
 
416
673
  def test_second
417
- puts "finder_test.test_second"
418
674
  assert_equal topics(:second).title, Topic.second.title
419
675
  end
420
676
 
421
677
  def test_second_with_offset
422
- puts "finder_test.test_second_with_offset"
423
678
  assert_equal topics(:fifth), Topic.offset(3).second
424
679
  end
425
680
 
426
681
  def test_second_have_primary_key_order_by_default
427
- puts "finder_test.test_second_have_primary_key_order_by_default"
428
682
  expected = topics(:second)
429
683
  expected.touch # PostgreSQL changes the default order if no order clause is used
430
684
  assert_equal expected, Topic.second
685
+ assert_equal expected, Topic.limit(5).second
686
+ assert_equal expected, Topic.order(nil).second
431
687
  end
432
688
 
433
689
  def test_model_class_responds_to_second_bang
@@ -439,20 +695,19 @@ class FinderTest < ActiveRecord::TestCase
439
695
  end
440
696
 
441
697
  def test_third
442
- puts "finder_test.test_third"
443
698
  assert_equal topics(:third).title, Topic.third.title
444
699
  end
445
700
 
446
701
  def test_third_with_offset
447
- puts "finder_test.test_third_with_offset"
448
702
  assert_equal topics(:fifth), Topic.offset(2).third
449
703
  end
450
704
 
451
705
  def test_third_have_primary_key_order_by_default
452
- puts "finder_test.test_third_have_primary_key_order_by_default"
453
706
  expected = topics(:third)
454
707
  expected.touch # PostgreSQL changes the default order if no order clause is used
455
708
  assert_equal expected, Topic.third
709
+ assert_equal expected, Topic.limit(5).third
710
+ assert_equal expected, Topic.order(nil).third
456
711
  end
457
712
 
458
713
  def test_model_class_responds_to_third_bang
@@ -464,20 +719,19 @@ class FinderTest < ActiveRecord::TestCase
464
719
  end
465
720
 
466
721
  def test_fourth
467
- puts "finder_test.test_fourth"
468
722
  assert_equal topics(:fourth).title, Topic.fourth.title
469
723
  end
470
724
 
471
725
  def test_fourth_with_offset
472
- puts "finder_test.test_fourth_with_offset"
473
726
  assert_equal topics(:fifth), Topic.offset(1).fourth
474
727
  end
475
728
 
476
729
  def test_fourth_have_primary_key_order_by_default
477
- puts "finder_test.test_fourth_have_primary_key_order_by_default"
478
730
  expected = topics(:fourth)
479
731
  expected.touch # PostgreSQL changes the default order if no order clause is used
480
732
  assert_equal expected, Topic.fourth
733
+ assert_equal expected, Topic.limit(5).fourth
734
+ assert_equal expected, Topic.order(nil).fourth
481
735
  end
482
736
 
483
737
  def test_model_class_responds_to_fourth_bang
@@ -493,15 +747,15 @@ class FinderTest < ActiveRecord::TestCase
493
747
  end
494
748
 
495
749
  def test_fifth_with_offset
496
- puts "finder_test.test_fifth_with_offset"
497
750
  assert_equal topics(:fifth), Topic.offset(0).fifth
498
751
  end
499
752
 
500
753
  def test_fifth_have_primary_key_order_by_default
501
- puts "finder_test.test_fifth_have_primary_key_order_by_default"
502
754
  expected = topics(:fifth)
503
755
  expected.touch # PostgreSQL changes the default order if no order clause is used
504
756
  assert_equal expected, Topic.fifth
757
+ assert_equal expected, Topic.limit(5).fifth
758
+ assert_equal expected, Topic.order(nil).fifth
505
759
  end
506
760
 
507
761
  def test_model_class_responds_to_fifth_bang
@@ -513,19 +767,18 @@ class FinderTest < ActiveRecord::TestCase
513
767
  end
514
768
 
515
769
  def test_second_to_last
516
- puts "finder_test.test_second_to_last"
517
770
  assert_equal topics(:fourth).title, Topic.second_to_last.title
518
771
 
519
772
  # test with offset
520
773
  assert_equal topics(:fourth), Topic.offset(1).second_to_last
521
774
  assert_equal topics(:fourth), Topic.offset(2).second_to_last
522
775
  assert_equal topics(:fourth), Topic.offset(3).second_to_last
523
- assert_equal nil, Topic.offset(4).second_to_last
524
- assert_equal nil, Topic.offset(5).second_to_last
776
+ assert_nil Topic.offset(4).second_to_last
777
+ assert_nil Topic.offset(5).second_to_last
525
778
 
526
- #test with limit
527
- # assert_equal nil, Topic.limit(1).second # TODO: currently failing
528
- assert_equal nil, Topic.limit(1).second_to_last
779
+ # test with limit
780
+ assert_nil Topic.limit(1).second
781
+ assert_nil Topic.limit(1).second_to_last
529
782
  end
530
783
 
531
784
  def test_second_to_last_have_primary_key_order_by_default
@@ -548,15 +801,15 @@ class FinderTest < ActiveRecord::TestCase
548
801
  # test with offset
549
802
  assert_equal topics(:third), Topic.offset(1).third_to_last
550
803
  assert_equal topics(:third), Topic.offset(2).third_to_last
551
- assert_equal nil, Topic.offset(3).third_to_last
552
- assert_equal nil, Topic.offset(4).third_to_last
553
- assert_equal nil, Topic.offset(5).third_to_last
804
+ assert_nil Topic.offset(3).third_to_last
805
+ assert_nil Topic.offset(4).third_to_last
806
+ assert_nil Topic.offset(5).third_to_last
554
807
 
555
808
  # test with limit
556
- # assert_equal nil, Topic.limit(1).third # TODO: currently failing
557
- assert_equal nil, Topic.limit(1).third_to_last
558
- # assert_equal nil, Topic.limit(2).third # TODO: currently failing
559
- assert_equal nil, Topic.limit(2).third_to_last
809
+ assert_nil Topic.limit(1).third
810
+ assert_nil Topic.limit(1).third_to_last
811
+ assert_nil Topic.limit(2).third
812
+ assert_nil Topic.limit(2).third_to_last
560
813
  end
561
814
 
562
815
  def test_third_to_last_have_primary_key_order_by_default
@@ -594,31 +847,29 @@ class FinderTest < ActiveRecord::TestCase
594
847
  end
595
848
 
596
849
  def test_take_and_first_and_last_with_integer_should_use_sql_limit
597
- puts "finder_test.test_take_and_first_and_last_with_integer_should_use_sql_limit"
598
850
  assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) { Topic.take(3).entries }
599
851
  assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) { Topic.first(2).entries }
600
852
  assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) { Topic.last(5).entries }
601
853
  end
602
854
 
603
855
  def test_last_with_integer_and_order_should_keep_the_order
604
- puts "finder_test.test_last_with_integer_and_order_should_keep_the_order"
605
856
  assert_equal Topic.order("title").to_a.last(2), Topic.order("title").last(2)
606
857
  end
607
858
 
608
859
  def test_last_with_integer_and_order_should_use_sql_limit
609
860
  relation = Topic.order("title")
610
861
  assert_queries(1) { relation.last(5) }
611
- assert !relation.loaded?
862
+ assert_not_predicate relation, :loaded?
612
863
  end
613
864
 
614
865
  def test_last_with_integer_and_reorder_should_use_sql_limit
615
866
  relation = Topic.reorder("title")
616
867
  assert_queries(1) { relation.last(5) }
617
- assert !relation.loaded?
868
+ assert_not_predicate relation, :loaded?
618
869
  end
619
870
 
620
871
  def test_last_on_loaded_relation_should_not_use_sql
621
- relation = Topic.limit(10).load
872
+ relation = Topic.limit(10).load
622
873
  assert_no_queries do
623
874
  relation.last
624
875
  relation.last(2)
@@ -626,25 +877,95 @@ class FinderTest < ActiveRecord::TestCase
626
877
  end
627
878
 
628
879
  def test_last_with_irreversible_order
629
- assert_deprecated do
630
- Topic.order("coalesce(author_name, title)").last
880
+ assert_raises(ActiveRecord::IrreversibleOrderError) do
881
+ Topic.order(Arel.sql("coalesce(author_name, title)")).last
631
882
  end
632
883
  end
633
884
 
634
885
  def test_last_on_relation_with_limit_and_offset
635
- post = posts('sti_comments')
886
+ post = posts("sti_comments")
636
887
 
637
888
  comments = post.comments.order(id: :asc)
638
889
  assert_equal comments.limit(2).to_a.last, comments.limit(2).last
639
890
  assert_equal comments.limit(2).to_a.last(2), comments.limit(2).last(2)
640
891
  assert_equal comments.limit(2).to_a.last(3), comments.limit(2).last(3)
641
892
 
893
+ assert_equal comments.offset(2).to_a.last, comments.offset(2).last
894
+ assert_equal comments.offset(2).to_a.last(2), comments.offset(2).last(2)
895
+ assert_equal comments.offset(2).to_a.last(3), comments.offset(2).last(3)
896
+
642
897
  comments = comments.offset(1)
643
898
  assert_equal comments.limit(2).to_a.last, comments.limit(2).last
644
899
  assert_equal comments.limit(2).to_a.last(2), comments.limit(2).last(2)
645
900
  assert_equal comments.limit(2).to_a.last(3), comments.limit(2).last(3)
646
901
  end
647
902
 
903
+ def test_first_on_relation_with_limit_and_offset
904
+ post = posts("sti_comments")
905
+
906
+ comments = post.comments.order(id: :asc)
907
+ assert_equal comments.limit(2).to_a.first, comments.limit(2).first
908
+ assert_equal comments.limit(2).to_a.first(2), comments.limit(2).first(2)
909
+ assert_equal comments.limit(2).to_a.first(3), comments.limit(2).first(3)
910
+
911
+ assert_equal comments.offset(2).to_a.first, comments.offset(2).first
912
+ assert_equal comments.offset(2).to_a.first(2), comments.offset(2).first(2)
913
+ assert_equal comments.offset(2).to_a.first(3), comments.offset(2).first(3)
914
+
915
+ comments = comments.offset(1)
916
+ assert_equal comments.limit(2).to_a.first, comments.limit(2).first
917
+ assert_equal comments.limit(2).to_a.first(2), comments.limit(2).first(2)
918
+ assert_equal comments.limit(2).to_a.first(3), comments.limit(2).first(3)
919
+ end
920
+
921
+ def test_first_have_determined_order_by_default
922
+ expected = [companies(:second_client), companies(:another_client)]
923
+ clients = Client.where(name: expected.map(&:name))
924
+
925
+ assert_equal expected, clients.first(2)
926
+ assert_equal expected, clients.limit(5).first(2)
927
+ assert_equal expected, clients.order(nil).first(2)
928
+ end
929
+
930
+ def test_implicit_order_column_is_configurable
931
+ old_implicit_order_column = Topic.implicit_order_column
932
+ Topic.implicit_order_column = "title"
933
+
934
+ assert_equal topics(:fifth), Topic.first
935
+ assert_equal topics(:third), Topic.last
936
+
937
+ c = Topic.connection
938
+ assert_sql(/ORDER BY #{Regexp.escape(c.quote_table_name("topics.title"))} DESC, #{Regexp.escape(c.quote_table_name("topics.id"))} DESC LIMIT/i) {
939
+ Topic.last
940
+ }
941
+ ensure
942
+ Topic.implicit_order_column = old_implicit_order_column
943
+ end
944
+
945
+ def test_implicit_order_set_to_primary_key
946
+ old_implicit_order_column = Topic.implicit_order_column
947
+ Topic.implicit_order_column = "id"
948
+
949
+ c = Topic.connection
950
+ assert_sql(/ORDER BY #{Regexp.escape(c.quote_table_name("topics.id"))} DESC LIMIT/i) {
951
+ Topic.last
952
+ }
953
+ ensure
954
+ Topic.implicit_order_column = old_implicit_order_column
955
+ end
956
+
957
+ def test_implicit_order_for_model_without_primary_key
958
+ old_implicit_order_column = NonPrimaryKey.implicit_order_column
959
+ NonPrimaryKey.implicit_order_column = "created_at"
960
+
961
+ c = NonPrimaryKey.connection
962
+ assert_sql(/ORDER BY #{Regexp.escape(c.quote_table_name("non_primary_keys.created_at"))} DESC LIMIT/i) {
963
+ NonPrimaryKey.last
964
+ }
965
+ ensure
966
+ NonPrimaryKey.implicit_order_column = old_implicit_order_column
967
+ end
968
+
648
969
  def test_take_and_first_and_last_with_integer_should_return_an_array
649
970
  assert_kind_of Array, Topic.take(5)
650
971
  assert_kind_of Array, Topic.first(5)
@@ -661,12 +982,12 @@ class FinderTest < ActiveRecord::TestCase
661
982
 
662
983
  def test_find_only_some_columns
663
984
  topic = Topic.select("author_name").find(1)
664
- assert_raise(ActiveModel::MissingAttributeError) {topic.title}
665
- assert_raise(ActiveModel::MissingAttributeError) {topic.title?}
985
+ assert_raise(ActiveModel::MissingAttributeError) { topic.title }
986
+ assert_raise(ActiveModel::MissingAttributeError) { topic.title? }
666
987
  assert_nil topic.read_attribute("title")
667
988
  assert_equal "David", topic.author_name
668
- assert !topic.attribute_present?("title")
669
- assert !topic.attribute_present?(:title)
989
+ assert_not topic.attribute_present?("title")
990
+ assert_not topic.attribute_present?(:title)
670
991
  assert topic.attribute_present?("author_name")
671
992
  assert_respond_to topic, "author_name"
672
993
  end
@@ -682,8 +1003,8 @@ class FinderTest < ActiveRecord::TestCase
682
1003
  end
683
1004
 
684
1005
  def test_find_on_hash_conditions_with_qualified_attribute_dot_notation_string
685
- assert Topic.where('topics.approved' => false).find(1)
686
- assert_raise(ActiveRecord::RecordNotFound) { Topic.where('topics.approved' => true).find(1) }
1006
+ assert Topic.where("topics.approved" => false).find(1)
1007
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.where("topics.approved" => true).find(1) }
687
1008
  end
688
1009
 
689
1010
  def test_find_on_hash_conditions_with_qualified_attribute_dot_notation_symbol
@@ -697,68 +1018,75 @@ class FinderTest < ActiveRecord::TestCase
697
1018
  end
698
1019
 
699
1020
  def test_find_on_combined_explicit_and_hashed_table_names
700
- assert Topic.where('topics.approved' => false, topics: { author_name: "David" }).find(1)
701
- assert_raise(ActiveRecord::RecordNotFound) { Topic.where('topics.approved' => true, topics: { author_name: "David" }).find(1) }
702
- assert_raise(ActiveRecord::RecordNotFound) { Topic.where('topics.approved' => false, topics: { author_name: "Melanie" }).find(1) }
1021
+ assert Topic.where("topics.approved" => false, topics: { author_name: "David" }).find(1)
1022
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.where("topics.approved" => true, topics: { author_name: "David" }).find(1) }
1023
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.where("topics.approved" => false, topics: { author_name: "Melanie" }).find(1) }
703
1024
  end
704
1025
 
705
1026
  def test_find_with_hash_conditions_on_joined_table
706
- firms = Firm.joins(:account).where(:accounts => { :credit_limit => 50 })
1027
+ firms = Firm.joins(:account).where(accounts: { credit_limit: 50 })
707
1028
  assert_equal 1, firms.size
708
1029
  assert_equal companies(:first_firm), firms.first
709
1030
  end
710
1031
 
711
1032
  def test_find_with_hash_conditions_on_joined_table_and_with_range
712
- firms = DependentFirm.joins(:account).where(name: 'RailsCore', accounts: { credit_limit: 55..60 })
1033
+ firms = DependentFirm.joins(:account).where(name: "RailsCore", accounts: { credit_limit: 55..60 })
713
1034
  assert_equal 1, firms.size
714
1035
  assert_equal companies(:rails_core), firms.first
715
1036
  end
716
1037
 
717
1038
  def test_find_on_hash_conditions_with_explicit_table_name_and_aggregate
718
1039
  david = customers(:david)
719
- assert Customer.where('customers.name' => david.name, :address => david.address).find(david.id)
1040
+ assert Customer.where("customers.name" => david.name, :address => david.address).find(david.id)
720
1041
  assert_raise(ActiveRecord::RecordNotFound) {
721
- Customer.where('customers.name' => david.name + "1", :address => david.address).find(david.id)
1042
+ Customer.where("customers.name" => david.name + "1", :address => david.address).find(david.id)
722
1043
  }
723
1044
  end
724
1045
 
725
1046
  def test_find_on_association_proxy_conditions
726
- assert_equal [1, 2, 3, 5, 6, 7, 8, 9, 10, 12], Comment.where(post_id: authors(:david).posts).map(&:id).sort
1047
+ assert_equal [1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 13], Comment.where(post_id: authors(:david).posts).map(&:id).sort
727
1048
  end
728
1049
 
729
1050
  def test_find_on_hash_conditions_with_range
730
- assert_equal [1,2], Topic.where(id: 1..2).to_a.map(&:id).sort
1051
+ assert_equal [1, 2], Topic.where(id: 1..2).to_a.map(&:id).sort
731
1052
  assert_raise(ActiveRecord::RecordNotFound) { Topic.where(id: 2..3).find(1) }
732
1053
  end
733
1054
 
734
1055
  def test_find_on_hash_conditions_with_end_exclusive_range
735
- assert_equal [1,2,3], Topic.where(id: 1..3).to_a.map(&:id).sort
736
- assert_equal [1,2], Topic.where(id: 1...3).to_a.map(&:id).sort
1056
+ assert_equal [1, 2, 3], Topic.where(id: 1..3).to_a.map(&:id).sort
1057
+ assert_equal [1, 2], Topic.where(id: 1...3).to_a.map(&:id).sort
737
1058
  assert_raise(ActiveRecord::RecordNotFound) { Topic.where(id: 2...3).find(3) }
738
1059
  end
739
1060
 
740
1061
  def test_find_on_hash_conditions_with_multiple_ranges
741
- assert_equal [1,2,3], Comment.where(id: 1..3, post_id: 1..2).to_a.map(&:id).sort
1062
+ assert_equal [1, 2, 3], Comment.where(id: 1..3, post_id: 1..2).to_a.map(&:id).sort
742
1063
  assert_equal [1], Comment.where(id: 1..1, post_id: 1..10).to_a.map(&:id).sort
743
1064
  end
744
1065
 
745
1066
  def test_find_on_hash_conditions_with_array_of_integers_and_ranges
746
- assert_equal [1,2,3,5,6,7,8,9], Comment.where(id: [1..2, 3, 5, 6..8, 9]).to_a.map(&:id).sort
1067
+ assert_equal [1, 2, 3, 5, 6, 7, 8, 9], Comment.where(id: [1..2, 3, 5, 6..8, 9]).to_a.map(&:id).sort
747
1068
  end
748
1069
 
749
1070
  def test_find_on_hash_conditions_with_array_of_ranges
750
- assert_equal [1,2,6,7,8], Comment.where(id: [1..2, 6..8]).to_a.map(&:id).sort
1071
+ assert_equal [1, 2, 6, 7, 8], Comment.where(id: [1..2, 6..8]).to_a.map(&:id).sort
1072
+ end
1073
+
1074
+ def test_find_on_hash_conditions_with_open_ended_range
1075
+ assert_equal [1, 2, 3], Comment.where(id: Float::INFINITY..3).to_a.map(&:id).sort
1076
+ end
1077
+
1078
+ def test_find_on_hash_conditions_with_numeric_range_for_string
1079
+ topic = Topic.create!(title: "12 Factor App")
1080
+ assert_equal [topic], Topic.where(title: 10..2).to_a
751
1081
  end
752
1082
 
753
1083
  def test_find_on_multiple_hash_conditions
754
1084
  assert Topic.where(author_name: "David", title: "The First Topic", replies_count: 1, approved: false).find(1)
755
1085
  assert_raise(ActiveRecord::RecordNotFound) { Topic.where(author_name: "David", title: "The First Topic", replies_count: 1, approved: true).find(1) }
756
1086
  assert_raise(ActiveRecord::RecordNotFound) { Topic.where(author_name: "David", title: "HHC", replies_count: 1, approved: false).find(1) }
757
- assert_raise(ActiveRecord::RecordNotFound) { Topic.where(author_name: "David", title: "The First Topic", replies_count: 1, approved: true).find(1) }
758
1087
  end
759
1088
 
760
1089
  def test_condition_interpolation
761
- puts "finder_test.test_condition_interpolation"
762
1090
  assert_kind_of Firm, Company.where("name = '%s'", "37signals").first
763
1091
  assert_nil Company.where(["name = '%s'", "37signals!"]).first
764
1092
  assert_nil Company.where(["name = '%s'", "37signals!' OR 1=1"]).first
@@ -766,7 +1094,6 @@ class FinderTest < ActiveRecord::TestCase
766
1094
  end
767
1095
 
768
1096
  def test_condition_array_interpolation
769
- puts "finder_test.test_condition_array_interpolation"
770
1097
  assert_kind_of Firm, Company.where(["name = '%s'", "37signals"]).first
771
1098
  assert_nil Company.where(["name = '%s'", "37signals!"]).first
772
1099
  assert_nil Company.where(["name = '%s'", "37signals!' OR 1=1"]).first
@@ -786,16 +1113,14 @@ class FinderTest < ActiveRecord::TestCase
786
1113
  end
787
1114
 
788
1115
  def test_hash_condition_find_with_escaped_characters
789
- puts "finder_test.test_hash_condition_find_with_escaped_characters"
790
1116
  Company.create("name" => "Ain't noth'n like' \#stuff")
791
1117
  assert Company.where(name: "Ain't noth'n like' \#stuff").first
792
1118
  end
793
1119
 
794
1120
  def test_hash_condition_find_with_array
795
- puts "finder_test.test_hash_condition_find_with_array"
796
- p1, p2 = Post.limit(2).order('id asc').to_a
797
- assert_equal [p1, p2], Post.where(id: [p1, p2]).order('id asc').to_a
798
- assert_equal [p1, p2], Post.where(id: [p1, p2.id]).order('id asc').to_a
1121
+ p1, p2 = Post.limit(2).order("id asc").to_a
1122
+ assert_equal [p1, p2], Post.where(id: [p1, p2]).order("id asc").to_a
1123
+ assert_equal [p1, p2], Post.where(id: [p1, p2.id]).order("id asc").to_a
799
1124
  end
800
1125
 
801
1126
  def test_hash_condition_find_with_nil
@@ -807,57 +1132,95 @@ class FinderTest < ActiveRecord::TestCase
807
1132
  def test_hash_condition_find_with_aggregate_having_one_mapping
808
1133
  balance = customers(:david).balance
809
1134
  assert_kind_of Money, balance
810
- found_customer = Customer.where(:balance => balance).first
1135
+ found_customer = Customer.where(balance: balance).first
811
1136
  assert_equal customers(:david), found_customer
812
1137
  end
813
1138
 
1139
+ def test_hash_condition_find_with_aggregate_having_three_mappings_array
1140
+ david_address = customers(:david).address
1141
+ zaphod_address = customers(:zaphod).address
1142
+ barney_address = customers(:barney).address
1143
+ assert_kind_of Address, david_address
1144
+ assert_kind_of Address, zaphod_address
1145
+ found_customers = Customer.where(address: [david_address, zaphod_address, barney_address])
1146
+ assert_equal [customers(:david), customers(:zaphod), customers(:barney)], found_customers.sort_by(&:id)
1147
+ end
1148
+
1149
+ def test_hash_condition_find_with_aggregate_having_one_mapping_array
1150
+ david_balance = customers(:david).balance
1151
+ zaphod_balance = customers(:zaphod).balance
1152
+ assert_kind_of Money, david_balance
1153
+ assert_kind_of Money, zaphod_balance
1154
+ found_customers = Customer.where(balance: [david_balance, zaphod_balance])
1155
+ assert_equal [customers(:david), customers(:zaphod)], found_customers.sort_by(&:id)
1156
+ assert_equal Customer.where(balance: [david_balance.amount, zaphod_balance.amount]).to_sql, found_customers.to_sql
1157
+ end
1158
+
814
1159
  def test_hash_condition_find_with_aggregate_attribute_having_same_name_as_field_and_key_value_being_aggregate
815
1160
  gps_location = customers(:david).gps_location
816
1161
  assert_kind_of GpsLocation, gps_location
817
- found_customer = Customer.where(:gps_location => gps_location).first
1162
+ found_customer = Customer.where(gps_location: gps_location).first
818
1163
  assert_equal customers(:david), found_customer
819
1164
  end
820
1165
 
821
1166
  def test_hash_condition_find_with_aggregate_having_one_mapping_and_key_value_being_attribute_value
822
1167
  balance = customers(:david).balance
823
1168
  assert_kind_of Money, balance
824
- found_customer = Customer.where(:balance => balance.amount).first
1169
+ found_customer = Customer.where(balance: balance.amount).first
825
1170
  assert_equal customers(:david), found_customer
826
1171
  end
827
1172
 
828
1173
  def test_hash_condition_find_with_aggregate_attribute_having_same_name_as_field_and_key_value_being_attribute_value
829
1174
  gps_location = customers(:david).gps_location
830
1175
  assert_kind_of GpsLocation, gps_location
831
- found_customer = Customer.where(:gps_location => gps_location.gps_location).first
1176
+ found_customer = Customer.where(gps_location: gps_location.gps_location).first
832
1177
  assert_equal customers(:david), found_customer
833
1178
  end
834
1179
 
835
1180
  def test_hash_condition_find_with_aggregate_having_three_mappings
836
1181
  address = customers(:david).address
837
1182
  assert_kind_of Address, address
838
- found_customer = Customer.where(:address => address).first
839
- assert_equal customers(:david), found_customer
1183
+ customers = Customer.where(address: address).order(:id)
1184
+ assert_equal [customers(:david)], customers
1185
+ assert_equal customers(:david, :mary), customers.unscope(where: [:address_city, :address_country])
840
1186
  end
841
1187
 
842
1188
  def test_hash_condition_find_with_one_condition_being_aggregate_and_another_not
843
1189
  address = customers(:david).address
844
1190
  assert_kind_of Address, address
845
- found_customer = Customer.where(:address => address, :name => customers(:david).name).first
1191
+ found_customer = Customer.where(address: address, name: customers(:david).name).first
846
1192
  assert_equal customers(:david), found_customer
847
1193
  end
848
1194
 
1195
+ def test_hash_condition_find_nil_with_aggregate_having_one_mapping
1196
+ assert_nil customers(:zaphod).gps_location
1197
+ found_customer = Customer.where(gps_location: nil, name: customers(:zaphod).name).first
1198
+ assert_equal customers(:zaphod), found_customer
1199
+ end
1200
+
1201
+ def test_hash_condition_find_nil_with_aggregate_having_multiple_mappings
1202
+ customers(:david).update(address: nil)
1203
+ assert_nil customers(:david).address_street
1204
+ assert_nil customers(:david).address_city
1205
+ found_customer = Customer.where(address: nil, name: customers(:david).name).first
1206
+ assert_equal customers(:david), found_customer
1207
+ end
1208
+
1209
+ def test_hash_condition_find_empty_array_with_aggregate_having_multiple_mappings
1210
+ assert_nil Customer.where(address: []).first
1211
+ end
1212
+
849
1213
  def test_condition_utc_time_interpolation_with_default_timezone_local
850
- with_env_tz 'America/New_York' do
1214
+ with_env_tz "America/New_York" do
851
1215
  with_timezone_config default: :local do
852
1216
  topic = Topic.first
853
- assert_equal topic, Topic.where(['written_on = ?', topic.written_on.getutc]).first
1217
+ assert_equal topic, Topic.where(["written_on = ?", topic.written_on.getutc]).first
854
1218
  end
855
1219
  end
856
1220
  end
857
1221
 
858
1222
  def test_hash_condition_utc_time_interpolation_with_default_timezone_local
859
- puts "finder_test.test_hash_condition_utc_time_interpolation_with_default_timezone_local"
860
- with_env_tz 'America/New_York' do
1223
+ with_env_tz "America/New_York" do
861
1224
  with_timezone_config default: :local do
862
1225
  topic = Topic.first
863
1226
  assert_equal topic, Topic.where(written_on: topic.written_on.getutc).first
@@ -866,18 +1229,16 @@ class FinderTest < ActiveRecord::TestCase
866
1229
  end
867
1230
 
868
1231
  def test_condition_local_time_interpolation_with_default_timezone_utc
869
- puts "finder_test.test_condition_local_time_interpolation_with_default_timezone_utc"
870
- with_env_tz 'America/New_York' do
1232
+ with_env_tz "America/New_York" do
871
1233
  with_timezone_config default: :utc do
872
1234
  topic = Topic.first
873
- assert_equal topic, Topic.where(['written_on = ?', topic.written_on.getlocal]).first
1235
+ assert_equal topic, Topic.where(["written_on = ?", topic.written_on.getlocal]).first
874
1236
  end
875
1237
  end
876
1238
  end
877
1239
 
878
1240
  def test_hash_condition_local_time_interpolation_with_default_timezone_utc
879
- puts "finder_test.test_hash_condition_local_time_interpolation_with_default_timezone_utc"
880
- with_env_tz 'America/New_York' do
1241
+ with_env_tz "America/New_York" do
881
1242
  with_timezone_config default: :utc do
882
1243
  topic = Topic.first
883
1244
  assert_equal topic, Topic.where(written_on: topic.written_on.getlocal).first
@@ -894,35 +1255,27 @@ class FinderTest < ActiveRecord::TestCase
894
1255
  Company.where(["id=? AND name = ?", 2]).first
895
1256
  }
896
1257
  assert_raise(ActiveRecord::PreparedStatementInvalid) {
897
- Company.where(["id=?", 2, 3, 4]).first
1258
+ Company.where(["id=?", 2, 3, 4]).first
898
1259
  }
899
1260
  end
900
1261
 
901
1262
  def test_bind_variables_with_quotes
902
- puts "finder_test.test_bind_variables_with_quotes"
903
- Company.create("name" => "37signals' go'es agains")
904
- assert Company.where(["name = ?", "37signals' go'es agains"]).first
1263
+ Company.create("name" => "37signals' go'es against")
1264
+ assert Company.where(["name = ?", "37signals' go'es against"]).first
905
1265
  end
906
1266
 
907
1267
  def test_named_bind_variables_with_quotes
908
- puts "finder_test.test_named_bind_variables_with_quotes"
909
- Company.create("name" => "37signals' go'es agains")
910
- assert Company.where(["name = :name", {name: "37signals' go'es agains"}]).first
1268
+ Company.create("name" => "37signals' go'es against")
1269
+ assert Company.where(["name = :name", { name: "37signals' go'es against" }]).first
911
1270
  end
912
1271
 
913
1272
  def test_named_bind_variables
914
- puts "finder_test.test_named_bind_variables"
915
1273
  assert_kind_of Firm, Company.where(["name = :name", { name: "37signals" }]).first
916
1274
  assert_nil Company.where(["name = :name", { name: "37signals!" }]).first
917
1275
  assert_nil Company.where(["name = :name", { name: "37signals!' OR 1=1" }]).first
918
1276
  assert_kind_of Time, Topic.where(["id = :id", { id: 1 }]).first.written_on
919
1277
  end
920
1278
 
921
- def test_string_sanitation
922
- assert_not_equal "'something ' 1=1'", ActiveRecord::Base.sanitize("something ' 1=1")
923
- assert_equal "'something; select table'", ActiveRecord::Base.sanitize("something; select table")
924
- end
925
-
926
1279
  def test_count_by_sql
927
1280
  assert_equal(0, Entrant.count_by_sql("SELECT COUNT(*) FROM entrants WHERE id > 3"))
928
1281
  assert_equal(1, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 2]))
@@ -942,8 +1295,7 @@ class FinderTest < ActiveRecord::TestCase
942
1295
  end
943
1296
 
944
1297
  def test_find_by_on_attribute_that_is_a_reserved_word
945
- puts "finder_test.test_find_by_on_attribute_that_is_a_reserved_word"
946
- dog_alias = 'Dog'
1298
+ dog_alias = "Dog"
947
1299
  dog = Dog.create(alias: dog_alias)
948
1300
 
949
1301
  assert_equal dog, Dog.find_by_alias(dog_alias)
@@ -955,13 +1307,12 @@ class FinderTest < ActiveRecord::TestCase
955
1307
  end
956
1308
 
957
1309
  def test_find_by_one_attribute_bang_with_blank_defined
958
- puts "finder_test.test_find_by_one_attribute_bang_with_blank_defined"
959
1310
  blank_topic = BlankTopic.create(title: "The Blank One")
960
1311
  assert_equal blank_topic, BlankTopic.find_by_title!("The Blank One")
961
1312
  end
962
1313
 
963
1314
  def test_find_by_one_attribute_with_conditions
964
- assert_equal accounts(:rails_core_account), Account.where('firm_id = ?', 6).find_by_credit_limit(50)
1315
+ assert_equal accounts(:rails_core_account), Account.where("firm_id = ?", 6).find_by_credit_limit(50)
965
1316
  end
966
1317
 
967
1318
  def test_find_by_one_attribute_that_is_an_aggregate
@@ -1000,13 +1351,13 @@ class FinderTest < ActiveRecord::TestCase
1000
1351
 
1001
1352
  def test_dynamic_finder_on_one_attribute_with_conditions_returns_same_results_after_caching
1002
1353
  # ensure this test can run independently of order
1003
- class << Account; self; end.send(:remove_method, :find_by_credit_limit) if Account.public_methods.include?(:find_by_credit_limit)
1004
- a = Account.where('firm_id = ?', 6).find_by_credit_limit(50)
1005
- assert_equal a, Account.where('firm_id = ?', 6).find_by_credit_limit(50) # find_by_credit_limit has been cached
1354
+ Account.singleton_class.remove_method :find_by_credit_limit if Account.public_methods.include?(:find_by_credit_limit)
1355
+ a = Account.where("firm_id = ?", 6).find_by_credit_limit(50)
1356
+ assert_equal a, Account.where("firm_id = ?", 6).find_by_credit_limit(50) # find_by_credit_limit has been cached
1006
1357
  end
1007
1358
 
1008
1359
  def test_find_by_one_attribute_with_several_options
1009
- assert_equal accounts(:unknown), Account.order('id DESC').where('id != ?', 3).find_by_credit_limit(50)
1360
+ assert_equal accounts(:unknown), Account.order("id DESC").where("id != ?", 3).find_by_credit_limit(50)
1010
1361
  end
1011
1362
 
1012
1363
  def test_find_by_one_missing_attribute
@@ -1029,16 +1380,6 @@ class FinderTest < ActiveRecord::TestCase
1029
1380
  assert_raise(ArgumentError) { Topic.find_by_title_and_author_name("The First Topic") }
1030
1381
  end
1031
1382
 
1032
- def test_find_last_with_offset
1033
- puts "finder_test.test_find_last_with_offset"
1034
- devs = Developer.order('id')
1035
-
1036
- assert_equal devs[2], Developer.offset(2).first
1037
- assert_equal devs[-3], Developer.offset(2).last
1038
- assert_equal devs[-3], Developer.offset(2).last
1039
- assert_equal devs[-3], Developer.offset(2).order('id DESC').first
1040
- end
1041
-
1042
1383
  def test_find_by_nil_attribute
1043
1384
  topic = Topic.find_by_last_read nil
1044
1385
  assert_not_nil topic
@@ -1054,20 +1395,10 @@ class FinderTest < ActiveRecord::TestCase
1054
1395
  assert_raise(ActiveRecord::StatementInvalid) { Topic.find_by_sql "select 1 from badtable" }
1055
1396
  end
1056
1397
 
1057
- def test_find_all_with_join
1058
- developers_on_project_one = Developer.
1059
- joins('LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id').
1060
- where('project_id=1').to_a
1061
- assert_equal 3, developers_on_project_one.length
1062
- developer_names = developers_on_project_one.map(&:name)
1063
- assert developer_names.include?('David')
1064
- assert developer_names.include?('Jamis')
1065
- end
1066
-
1067
1398
  def test_joins_dont_clobber_id
1068
1399
  first = Firm.
1069
- joins('INNER JOIN companies clients ON clients.firm_id = companies.id').
1070
- where('companies.id = 1').first
1400
+ joins("INNER JOIN companies clients ON clients.firm_id = companies.id").
1401
+ where("companies.id = 1").first
1071
1402
  assert_equal 1, first.id
1072
1403
  end
1073
1404
 
@@ -1081,13 +1412,12 @@ class FinderTest < ActiveRecord::TestCase
1081
1412
 
1082
1413
  def test_find_by_id_with_conditions_with_or
1083
1414
  assert_nothing_raised do
1084
- Post.where("posts.id <= 3 OR posts.#{QUOTED_TYPE} = 'Post'").find([1,2,3])
1415
+ Post.where("posts.id <= 3 OR posts.#{QUOTED_TYPE} = 'Post'").find([1, 2, 3])
1085
1416
  end
1086
1417
  end
1087
1418
 
1088
1419
  def test_find_ignores_previously_inserted_record
1089
- puts "finder_test.test_find_ignores_previously_inserted_record"
1090
- Post.create!(:title => 'test', :body => 'it out')
1420
+ Post.create!(title: "test", body: "it out")
1091
1421
  assert_equal [], Post.where(id: nil)
1092
1422
  end
1093
1423
 
@@ -1096,14 +1426,13 @@ class FinderTest < ActiveRecord::TestCase
1096
1426
  end
1097
1427
 
1098
1428
  def test_find_by_empty_in_condition
1099
- assert_equal [], Post.where('id in (?)', [])
1429
+ assert_equal [], Post.where("id in (?)", [])
1100
1430
  end
1101
1431
 
1102
1432
  def test_find_by_records
1103
- puts "finder_test.test_find_by_records"
1104
- p1, p2 = Post.limit(2).order('id asc').to_a
1105
- assert_equal [p1, p2], Post.where(['id in (?)', [p1, p2]]).order('id asc')
1106
- assert_equal [p1, p2], Post.where(['id in (?)', [p1, p2.id]]).order('id asc')
1433
+ p1, p2 = Post.limit(2).order("id asc").to_a
1434
+ assert_equal [p1, p2], Post.where(["id in (?)", [p1, p2]]).order("id asc")
1435
+ assert_equal [p1, p2], Post.where(["id in (?)", [p1, p2.id]]).order("id asc")
1107
1436
  end
1108
1437
 
1109
1438
  def test_select_value
@@ -1115,8 +1444,8 @@ class FinderTest < ActiveRecord::TestCase
1115
1444
  end
1116
1445
 
1117
1446
  def test_select_values
1118
- assert_equal ["1","2","3","4","5","6","7","8","9", "10", "11"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map!(&:to_s)
1119
- assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy", "Ex Nihilo Part Deux", "Apex"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
1447
+ assert_equal ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "15"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map!(&:to_s)
1448
+ assert_equal ["37signals", "Summit", "Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy", "Ex Nihilo Part Deux", "Apex", "RVshare"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
1120
1449
  end
1121
1450
 
1122
1451
  def test_select_rows
@@ -1124,50 +1453,72 @@ class FinderTest < ActiveRecord::TestCase
1124
1453
  [["1", "1", nil, "37signals"],
1125
1454
  ["2", "1", "2", "Summit"],
1126
1455
  ["3", "1", "1", "Microsoft"]],
1127
- Company.connection.select_rows("SELECT id, firm_id, client_of, name FROM companies WHERE id IN (1,2,3) ORDER BY id").map! {|i| i.map! {|j| j.to_s unless j.nil?}})
1456
+ Company.connection.select_rows("SELECT id, firm_id, client_of, name FROM companies WHERE id IN (1,2,3) ORDER BY id").map! { |i| i.map! { |j| j.to_s unless j.nil? } })
1128
1457
  assert_equal [["1", "37signals"], ["2", "Summit"], ["3", "Microsoft"]],
1129
- Company.connection.select_rows("SELECT id, name FROM companies WHERE id IN (1,2,3) ORDER BY id").map! {|i| i.map! {|j| j.to_s unless j.nil?}}
1458
+ Company.connection.select_rows("SELECT id, name FROM companies WHERE id IN (1,2,3) ORDER BY id").map! { |i| i.map! { |j| j.to_s unless j.nil? } }
1130
1459
  end
1131
1460
 
1132
1461
  def test_find_with_order_on_included_associations_with_construct_finder_sql_for_association_limiting_and_is_distinct
1133
- puts "finder_test.test_find_with_order_on_included_associations_with_construct_finder_sql_for_association_limiting_and_is_distinct"
1134
1462
  assert_equal 2, Post.includes(authors: :author_address).
1135
1463
  where.not(author_addresses: { id: nil }).
1136
- order('author_addresses.id DESC').limit(2).to_a.size
1464
+ order("author_addresses.id DESC").limit(2).to_a.size
1137
1465
 
1138
1466
  assert_equal 3, Post.includes(author: :author_address, authors: :author_address).
1139
1467
  where.not(author_addresses_authors: { id: nil }).
1140
- order('author_addresses_authors.id DESC').limit(3).to_a.size
1468
+ order("author_addresses_authors.id DESC").limit(3).to_a.size
1469
+ end
1470
+
1471
+ def test_find_with_eager_loading_collection_and_ordering_by_collection_primary_key
1472
+ assert_equal Post.first, Post.eager_load(comments: :ratings).
1473
+ order("posts.id, ratings.id, comments.id").first
1141
1474
  end
1142
1475
 
1143
1476
  def test_find_with_nil_inside_set_passed_for_one_attribute
1144
1477
  client_of = Company.
1145
1478
  where(client_of: [2, 1, nil],
1146
- name: ['37signals', 'Summit', 'Microsoft']).
1147
- order('client_of DESC').
1479
+ name: ["37signals", "Summit", "Microsoft"]).
1480
+ order("client_of DESC").
1148
1481
  map(&:client_of)
1149
1482
 
1150
- assert client_of.include?(nil)
1483
+ assert_includes client_of, nil
1151
1484
  assert_equal [2, 1].sort, client_of.compact.sort
1152
1485
  end
1153
1486
 
1154
1487
  def test_find_with_nil_inside_set_passed_for_attribute
1155
1488
  client_of = Company.
1156
1489
  where(client_of: [nil]).
1157
- order('client_of DESC').
1490
+ order("client_of DESC").
1158
1491
  map(&:client_of)
1159
1492
 
1160
1493
  assert_equal [], client_of.compact
1161
1494
  end
1162
1495
 
1163
1496
  def test_with_limiting_with_custom_select
1164
- puts "finder_test.test_with_limiting_with_custom_select"
1165
1497
  posts = Post.references(:authors).merge(
1166
- :includes => :author, :select => 'posts.*, authors.id as "author_id"',
1167
- :limit => 3, :order => 'posts.id'
1498
+ includes: :author, select: 'posts.*, authors.id as "author_id"',
1499
+ limit: 3, order: "posts.id"
1168
1500
  ).to_a
1169
1501
  assert_equal 3, posts.size
1170
- assert_equal [0, 1, 1], posts.map(&:author_id).sort
1502
+ assert_equal [1, 1, nil], posts.map(&:author_id)
1503
+ end
1504
+
1505
+ def test_custom_select_takes_precedence_over_original_value
1506
+ posts = Post.select("UPPER(title) AS title")
1507
+ assert_equal "WELCOME TO THE WEBLOG", posts.first.title
1508
+ assert_equal "WELCOME TO THE WEBLOG", posts.preload(:comments).first.title
1509
+ assert_equal "WELCOME TO THE WEBLOG", posts.eager_load(:comments).first.title
1510
+ end
1511
+
1512
+ def test_eager_load_for_no_has_many_with_limit_and_joins_for_has_many
1513
+ relation = Post.eager_load(:author).joins(comments: :post)
1514
+ assert_equal 5, relation.to_a.size
1515
+ assert_equal 5, relation.limit(5).to_a.size
1516
+ end
1517
+
1518
+ def test_eager_load_for_no_has_many_with_limit_and_left_joins_for_has_many
1519
+ relation = Post.eager_load(:author).left_joins(comments: :post)
1520
+ assert_equal 11, relation.to_a.size
1521
+ assert_equal 11, relation.limit(11).to_a.size
1171
1522
  end
1172
1523
 
1173
1524
  def test_find_one_message_on_primary_key
@@ -1184,9 +1535,9 @@ class FinderTest < ActiveRecord::TestCase
1184
1535
  table_with_custom_primary_key do |model|
1185
1536
  model.primary_key = :name
1186
1537
  e = assert_raises(ActiveRecord::RecordNotFound) do
1187
- model.find 'Hello World!'
1538
+ model.find "Hello World!"
1188
1539
  end
1189
- assert_equal %Q{Couldn't find MercedesCar with 'name'=Hello World!}, e.message
1540
+ assert_equal "Couldn't find MercedesCar with 'name'=Hello World!", e.message
1190
1541
  end
1191
1542
  end
1192
1543
 
@@ -1194,9 +1545,9 @@ class FinderTest < ActiveRecord::TestCase
1194
1545
  table_with_custom_primary_key do |model|
1195
1546
  model.primary_key = :name
1196
1547
  e = assert_raises(ActiveRecord::RecordNotFound) do
1197
- model.find 'Hello', 'World!'
1548
+ model.find "Hello", "World!"
1198
1549
  end
1199
- assert_equal %Q{Couldn't find all MercedesCars with 'name': (Hello, World!) (found 0 results, but was looking for 2)}, e.message
1550
+ assert_equal "Couldn't find all MercedesCars with 'name': (Hello, World!) (found 0 results, but was looking for 2).", e.message
1200
1551
  end
1201
1552
  end
1202
1553
 
@@ -1219,16 +1570,20 @@ class FinderTest < ActiveRecord::TestCase
1219
1570
  end
1220
1571
 
1221
1572
  test "find_by with multi-arg conditions returns the first matching record" do
1222
- assert_equal posts(:eager_other), Post.find_by('id = ?', posts(:eager_other).id)
1573
+ assert_equal posts(:eager_other), Post.find_by("id = ?", posts(:eager_other).id)
1574
+ end
1575
+
1576
+ test "find_by with range conditions returns the first matching record" do
1577
+ assert_equal posts(:eager_other), Post.find_by(id: posts(:eager_other).id...posts(:misc_by_bob).id)
1223
1578
  end
1224
1579
 
1225
1580
  test "find_by returns nil if the record is missing" do
1226
- assert_equal nil, Post.find_by("1 = 0")
1581
+ assert_nil Post.find_by("1 = 0")
1227
1582
  end
1228
1583
 
1229
1584
  test "find_by with associations" do
1230
1585
  assert_equal authors(:david), Post.find_by(author: authors(:david)).author
1231
- assert_equal authors(:mary) , Post.find_by(author: authors(:mary) ).author
1586
+ assert_equal authors(:mary), Post.find_by(author: authors(:mary)).author
1232
1587
  end
1233
1588
 
1234
1589
  test "find_by doesn't have implicit ordering" do
@@ -1244,7 +1599,7 @@ class FinderTest < ActiveRecord::TestCase
1244
1599
  end
1245
1600
 
1246
1601
  test "find_by! with multi-arg conditions returns the first matching record" do
1247
- assert_equal posts(:eager_other), Post.find_by!('id = ?', posts(:eager_other).id)
1602
+ assert_equal posts(:eager_other), Post.find_by!("id = ?", posts(:eager_other).id)
1248
1603
  end
1249
1604
 
1250
1605
  test "find_by! doesn't have implicit ordering" do
@@ -1277,11 +1632,39 @@ class FinderTest < ActiveRecord::TestCase
1277
1632
  assert_equal tyre2, zyke.tyres.custom_find_by(id: tyre2.id)
1278
1633
  end
1279
1634
 
1280
- protected
1635
+ test "#skip_query_cache! for #exists?" do
1636
+ Topic.cache do
1637
+ assert_queries(1) do
1638
+ Topic.exists?
1639
+ Topic.exists?
1640
+ end
1641
+
1642
+ assert_queries(2) do
1643
+ Topic.all.skip_query_cache!.exists?
1644
+ Topic.all.skip_query_cache!.exists?
1645
+ end
1646
+ end
1647
+ end
1648
+
1649
+ test "#skip_query_cache! for #exists? with a limited eager load" do
1650
+ Topic.cache do
1651
+ assert_queries(1) do
1652
+ Topic.eager_load(:replies).limit(1).exists?
1653
+ Topic.eager_load(:replies).limit(1).exists?
1654
+ end
1655
+
1656
+ assert_queries(2) do
1657
+ Topic.eager_load(:replies).limit(1).skip_query_cache!.exists?
1658
+ Topic.eager_load(:replies).limit(1).skip_query_cache!.exists?
1659
+ end
1660
+ end
1661
+ end
1662
+
1663
+ private
1281
1664
  def table_with_custom_primary_key
1282
1665
  yield(Class.new(Toy) do
1283
1666
  def self.name
1284
- 'MercedesCar'
1667
+ "MercedesCar"
1285
1668
  end
1286
1669
  end)
1287
1670
  end
@@ -1290,5 +1673,4 @@ class FinderTest < ActiveRecord::TestCase
1290
1673
  err = assert_raises(exception_class) { block.call }
1291
1674
  assert_match message, err.message
1292
1675
  end
1293
-
1294
1676
  end