ibm_db 5.2.0 → 5.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (622) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +6 -0
  3. data/LICENSE +55 -18
  4. data/ext/Makefile +12 -12
  5. data/ext/ibm_db.c +62 -57
  6. data/ext/ibm_db.o +0 -0
  7. data/ext/ibm_db.so +0 -0
  8. data/ext/mkmf.log +11 -11
  9. data/ext/ruby_ibm_db_cli.c +1 -0
  10. data/ext/ruby_ibm_db_cli.o +0 -0
  11. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1458 -1279
  12. data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
  13. data/test/activejob/destroy_association_async_test.rb +305 -0
  14. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  15. data/test/activejob/helper.rb +15 -0
  16. data/test/assets/schema_dump_5_1.yml +345 -0
  17. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  18. data/test/cases/adapter_test.rb +432 -218
  19. data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
  20. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  21. data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
  22. data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
  23. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
  24. data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
  25. data/test/cases/adapters/mysql2/connection_test.rb +48 -50
  26. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  27. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
  28. data/test/cases/adapters/mysql2/enum_test.rb +32 -11
  29. data/test/cases/adapters/mysql2/explain_test.rb +13 -11
  30. data/test/cases/adapters/mysql2/json_test.rb +17 -188
  31. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  32. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
  33. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  34. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  35. data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
  36. data/test/cases/adapters/mysql2/schema_test.rb +24 -22
  37. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  38. data/test/cases/adapters/mysql2/sp_test.rb +10 -8
  39. data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
  40. data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
  41. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  42. data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
  43. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  44. data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
  45. data/test/cases/adapters/postgresql/array_test.rb +118 -63
  46. data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
  47. data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
  48. data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
  49. data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
  50. data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
  51. data/test/cases/adapters/postgresql/citext_test.rb +58 -58
  52. data/test/cases/adapters/postgresql/collation_test.rb +17 -15
  53. data/test/cases/adapters/postgresql/composite_test.rb +25 -23
  54. data/test/cases/adapters/postgresql/connection_test.rb +73 -85
  55. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  56. data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
  57. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  58. data/test/cases/adapters/postgresql/domain_test.rb +9 -7
  59. data/test/cases/adapters/postgresql/enum_test.rb +12 -10
  60. data/test/cases/adapters/postgresql/explain_test.rb +10 -8
  61. data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
  62. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  63. data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
  64. data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
  65. data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
  66. data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
  67. data/test/cases/adapters/postgresql/integer_test.rb +2 -0
  68. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  69. data/test/cases/adapters/postgresql/json_test.rb +16 -201
  70. data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
  71. data/test/cases/adapters/postgresql/money_test.rb +47 -16
  72. data/test/cases/adapters/postgresql/network_test.rb +36 -28
  73. data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
  74. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  75. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  76. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  77. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
  78. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  79. data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
  80. data/test/cases/adapters/postgresql/range_test.rb +406 -292
  81. data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
  82. data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
  83. data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
  84. data/test/cases/adapters/postgresql/schema_test.rb +207 -91
  85. data/test/cases/adapters/postgresql/serial_test.rb +9 -7
  86. data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
  87. data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
  88. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  89. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  90. data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
  91. data/test/cases/adapters/postgresql/utils_test.rb +11 -9
  92. data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
  93. data/test/cases/adapters/postgresql/xml_test.rb +10 -14
  94. data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
  95. data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
  96. data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
  97. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  98. data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
  99. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  100. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
  101. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
  102. data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
  103. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  104. data/test/cases/aggregations_test.rb +14 -12
  105. data/test/cases/annotate_test.rb +46 -0
  106. data/test/cases/ar_schema_test.rb +153 -86
  107. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  108. data/test/cases/arel/attributes/math_test.rb +83 -0
  109. data/test/cases/arel/attributes_test.rb +27 -0
  110. data/test/cases/arel/collectors/bind_test.rb +40 -0
  111. data/test/cases/arel/collectors/composite_test.rb +47 -0
  112. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  113. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  114. data/test/cases/arel/crud_test.rb +65 -0
  115. data/test/cases/arel/delete_manager_test.rb +53 -0
  116. data/test/cases/arel/factory_methods_test.rb +46 -0
  117. data/test/cases/arel/helper.rb +45 -0
  118. data/test/cases/arel/insert_manager_test.rb +241 -0
  119. data/test/cases/arel/nodes/and_test.rb +30 -0
  120. data/test/cases/arel/nodes/as_test.rb +36 -0
  121. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  122. data/test/cases/arel/nodes/bin_test.rb +35 -0
  123. data/test/cases/arel/nodes/binary_test.rb +29 -0
  124. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  125. data/test/cases/arel/nodes/case_test.rb +96 -0
  126. data/test/cases/arel/nodes/casted_test.rb +18 -0
  127. data/test/cases/arel/nodes/comment_test.rb +22 -0
  128. data/test/cases/arel/nodes/count_test.rb +35 -0
  129. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  130. data/test/cases/arel/nodes/descending_test.rb +46 -0
  131. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  132. data/test/cases/arel/nodes/equality_test.rb +62 -0
  133. data/test/cases/arel/nodes/extract_test.rb +43 -0
  134. data/test/cases/arel/nodes/false_test.rb +21 -0
  135. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  136. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  137. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  138. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  139. data/test/cases/arel/nodes/node_test.rb +22 -0
  140. data/test/cases/arel/nodes/not_test.rb +31 -0
  141. data/test/cases/arel/nodes/or_test.rb +36 -0
  142. data/test/cases/arel/nodes/over_test.rb +69 -0
  143. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  144. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  145. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  146. data/test/cases/arel/nodes/sum_test.rb +35 -0
  147. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  148. data/test/cases/arel/nodes/true_test.rb +21 -0
  149. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  150. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  151. data/test/cases/arel/nodes/window_test.rb +81 -0
  152. data/test/cases/arel/nodes_test.rb +34 -0
  153. data/test/cases/arel/select_manager_test.rb +1238 -0
  154. data/test/cases/arel/support/fake_record.rb +135 -0
  155. data/test/cases/arel/table_test.rb +216 -0
  156. data/test/cases/arel/update_manager_test.rb +126 -0
  157. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  158. data/test/cases/arel/visitors/dot_test.rb +90 -0
  159. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  160. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  161. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  162. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  163. data/test/cases/associations/belongs_to_associations_test.rb +510 -158
  164. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
  165. data/test/cases/associations/callbacks_test.rb +56 -38
  166. data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
  167. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
  168. data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
  169. data/test/cases/associations/eager_singularization_test.rb +21 -21
  170. data/test/cases/associations/eager_test.rb +559 -415
  171. data/test/cases/associations/extension_test.rb +18 -12
  172. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
  173. data/test/cases/associations/has_many_associations_test.rb +1038 -465
  174. data/test/cases/associations/has_many_through_associations_test.rb +558 -249
  175. data/test/cases/associations/has_one_associations_test.rb +294 -129
  176. data/test/cases/associations/has_one_through_associations_test.rb +121 -75
  177. data/test/cases/associations/inner_join_association_test.rb +114 -38
  178. data/test/cases/associations/inverse_associations_test.rb +606 -398
  179. data/test/cases/associations/join_model_test.rb +158 -148
  180. data/test/cases/associations/left_outer_join_association_test.rb +59 -24
  181. data/test/cases/associations/nested_through_associations_test.rb +166 -109
  182. data/test/cases/associations/required_test.rb +35 -10
  183. data/test/cases/associations_test.rb +241 -110
  184. data/test/cases/attribute_methods/read_test.rb +11 -11
  185. data/test/cases/attribute_methods_test.rb +413 -298
  186. data/test/cases/attributes_test.rb +145 -27
  187. data/test/cases/autosave_association_test.rb +681 -436
  188. data/test/cases/base_prevent_writes_test.rb +229 -0
  189. data/test/cases/base_test.rb +599 -542
  190. data/test/cases/batches_test.rb +288 -82
  191. data/test/cases/binary_test.rb +26 -31
  192. data/test/cases/bind_parameter_test.rb +194 -21
  193. data/test/cases/boolean_test.rb +52 -0
  194. data/test/cases/cache_key_test.rb +110 -5
  195. data/test/cases/calculations_test.rb +737 -174
  196. data/test/cases/callbacks_test.rb +74 -207
  197. data/test/cases/clone_test.rb +15 -10
  198. data/test/cases/coders/json_test.rb +2 -0
  199. data/test/cases/coders/yaml_column_test.rb +16 -13
  200. data/test/cases/collection_cache_key_test.rb +177 -20
  201. data/test/cases/column_alias_test.rb +9 -7
  202. data/test/cases/column_definition_test.rb +10 -68
  203. data/test/cases/comment_test.rb +166 -107
  204. data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
  205. data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
  206. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  207. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  208. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  209. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  210. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  211. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  212. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
  213. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
  214. data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
  215. data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
  216. data/test/cases/connection_management_test.rb +13 -11
  217. data/test/cases/connection_pool_test.rb +316 -83
  218. data/test/cases/core_test.rb +82 -58
  219. data/test/cases/counter_cache_test.rb +204 -50
  220. data/test/cases/custom_locking_test.rb +5 -3
  221. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  222. data/test/cases/database_configurations/resolver_test.rb +150 -0
  223. data/test/cases/database_configurations_test.rb +145 -0
  224. data/test/cases/database_selector_test.rb +296 -0
  225. data/test/cases/database_statements_test.rb +18 -16
  226. data/test/cases/date_test.rb +8 -16
  227. data/test/cases/date_time_precision_test.rb +100 -78
  228. data/test/cases/date_time_test.rb +23 -8
  229. data/test/cases/defaults_test.rb +106 -71
  230. data/test/cases/delegated_type_test.rb +57 -0
  231. data/test/cases/dirty_test.rb +419 -223
  232. data/test/cases/disconnected_test.rb +6 -6
  233. data/test/cases/dup_test.rb +54 -27
  234. data/test/cases/enum_test.rb +461 -82
  235. data/test/cases/errors_test.rb +7 -7
  236. data/test/cases/explain_subscriber_test.rb +17 -15
  237. data/test/cases/explain_test.rb +11 -19
  238. data/test/cases/filter_attributes_test.rb +153 -0
  239. data/test/cases/finder_respond_to_test.rb +14 -14
  240. data/test/cases/finder_test.rb +669 -287
  241. data/test/cases/fixture_set/file_test.rb +34 -38
  242. data/test/cases/fixtures_test.rb +833 -176
  243. data/test/cases/forbidden_attributes_protection_test.rb +32 -67
  244. data/test/cases/habtm_destroy_order_test.rb +25 -25
  245. data/test/cases/helper.rb +78 -49
  246. data/test/cases/hot_compatibility_test.rb +33 -32
  247. data/test/cases/i18n_test.rb +18 -17
  248. data/test/cases/inheritance_test.rb +180 -115
  249. data/test/cases/insert_all_test.rb +489 -0
  250. data/test/cases/instrumentation_test.rb +101 -0
  251. data/test/cases/integration_test.rb +119 -31
  252. data/test/cases/invalid_connection_test.rb +18 -16
  253. data/test/cases/invertible_migration_test.rb +183 -43
  254. data/test/cases/json_attribute_test.rb +35 -0
  255. data/test/cases/json_serialization_test.rb +57 -58
  256. data/test/cases/json_shared_test_cases.rb +290 -0
  257. data/test/cases/locking_test.rb +413 -119
  258. data/test/cases/log_subscriber_test.rb +68 -26
  259. data/test/cases/marshal_serialization_test.rb +39 -0
  260. data/test/cases/migration/change_schema_test.rb +118 -72
  261. data/test/cases/migration/change_table_test.rb +138 -30
  262. data/test/cases/migration/check_constraint_test.rb +162 -0
  263. data/test/cases/migration/column_attributes_test.rb +45 -35
  264. data/test/cases/migration/column_positioning_test.rb +18 -6
  265. data/test/cases/migration/columns_test.rb +93 -77
  266. data/test/cases/migration/command_recorder_test.rb +121 -34
  267. data/test/cases/migration/compatibility_test.rb +578 -23
  268. data/test/cases/migration/create_join_table_test.rb +35 -25
  269. data/test/cases/migration/foreign_key_test.rb +503 -284
  270. data/test/cases/migration/helper.rb +4 -3
  271. data/test/cases/migration/index_test.rb +119 -70
  272. data/test/cases/migration/logger_test.rb +9 -6
  273. data/test/cases/migration/pending_migrations_test.rb +88 -34
  274. data/test/cases/migration/references_foreign_key_test.rb +164 -150
  275. data/test/cases/migration/references_index_test.rb +38 -19
  276. data/test/cases/migration/references_statements_test.rb +15 -14
  277. data/test/cases/migration/rename_table_test.rb +53 -30
  278. data/test/cases/migration_test.rb +637 -269
  279. data/test/cases/migrator_test.rb +191 -135
  280. data/test/cases/mixin_test.rb +7 -11
  281. data/test/cases/modules_test.rb +36 -34
  282. data/test/cases/multi_db_migrator_test.rb +223 -0
  283. data/test/cases/multiparameter_attributes_test.rb +60 -33
  284. data/test/cases/multiple_db_test.rb +16 -22
  285. data/test/cases/nested_attributes_test.rb +341 -320
  286. data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
  287. data/test/cases/null_relation_test.rb +84 -0
  288. data/test/cases/numeric_data_test.rb +93 -0
  289. data/test/cases/persistence_test.rb +361 -269
  290. data/test/cases/pooled_connections_test.rb +18 -26
  291. data/test/cases/prepared_statement_status_test.rb +48 -0
  292. data/test/cases/primary_keys_test.rb +210 -104
  293. data/test/cases/query_cache_test.rb +610 -141
  294. data/test/cases/quoting_test.rb +132 -31
  295. data/test/cases/readonly_test.rb +49 -48
  296. data/test/cases/reaper_test.rb +146 -32
  297. data/test/cases/reflection_test.rb +167 -156
  298. data/test/cases/relation/delegation_test.rb +49 -36
  299. data/test/cases/relation/delete_all_test.rb +117 -0
  300. data/test/cases/relation/merging_test.rb +319 -42
  301. data/test/cases/relation/mutation_test.rb +55 -93
  302. data/test/cases/relation/or_test.rb +129 -29
  303. data/test/cases/relation/predicate_builder_test.rb +21 -6
  304. data/test/cases/relation/record_fetch_warning_test.rb +5 -3
  305. data/test/cases/relation/select_test.rb +67 -0
  306. data/test/cases/relation/update_all_test.rb +317 -0
  307. data/test/cases/relation/where_chain_test.rb +68 -32
  308. data/test/cases/relation/where_clause_test.rb +136 -61
  309. data/test/cases/relation/where_test.rb +155 -48
  310. data/test/cases/relation_test.rb +266 -112
  311. data/test/cases/relations_test.rb +969 -744
  312. data/test/cases/reload_models_test.rb +13 -9
  313. data/test/cases/reserved_word_test.rb +141 -0
  314. data/test/cases/result_test.rb +68 -17
  315. data/test/cases/sanitize_test.rb +87 -71
  316. data/test/cases/schema_dumper_test.rb +221 -128
  317. data/test/cases/schema_loading_test.rb +3 -2
  318. data/test/cases/scoping/default_scoping_test.rb +185 -144
  319. data/test/cases/scoping/named_scoping_test.rb +177 -89
  320. data/test/cases/scoping/relation_scoping_test.rb +197 -75
  321. data/test/cases/secure_token_test.rb +18 -3
  322. data/test/cases/serialization_test.rb +30 -28
  323. data/test/cases/serialized_attribute_test.rb +133 -42
  324. data/test/cases/signed_id_test.rb +168 -0
  325. data/test/cases/statement_cache_test.rb +41 -24
  326. data/test/cases/statement_invalid_test.rb +42 -0
  327. data/test/cases/store_test.rb +180 -55
  328. data/test/cases/strict_loading_test.rb +473 -0
  329. data/test/cases/suppressor_test.rb +26 -12
  330. data/test/cases/tasks/database_tasks_test.rb +1258 -194
  331. data/test/cases/tasks/mysql_rake_test.rb +370 -298
  332. data/test/cases/tasks/postgresql_rake_test.rb +481 -251
  333. data/test/cases/tasks/sqlite_rake_test.rb +225 -178
  334. data/test/cases/test_case.rb +51 -40
  335. data/test/cases/test_databases_test.rb +79 -0
  336. data/test/cases/test_fixtures_test.rb +79 -19
  337. data/test/cases/time_precision_test.rb +98 -76
  338. data/test/cases/timestamp_test.rb +102 -99
  339. data/test/cases/touch_later_test.rb +12 -10
  340. data/test/cases/transaction_callbacks_test.rb +344 -90
  341. data/test/cases/transaction_isolation_test.rb +12 -12
  342. data/test/cases/transactions_test.rb +612 -162
  343. data/test/cases/type/adapter_specific_registry_test.rb +14 -2
  344. data/test/cases/type/date_time_test.rb +4 -2
  345. data/test/cases/type/integer_test.rb +4 -2
  346. data/test/cases/type/string_test.rb +10 -8
  347. data/test/cases/type/time_test.rb +28 -0
  348. data/test/cases/type/type_map_test.rb +29 -28
  349. data/test/cases/type/unsigned_integer_test.rb +19 -0
  350. data/test/cases/type_test.rb +2 -0
  351. data/test/cases/types_test.rb +3 -1
  352. data/test/cases/unconnected_test.rb +14 -1
  353. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  354. data/test/cases/validations/absence_validation_test.rb +19 -17
  355. data/test/cases/validations/association_validation_test.rb +30 -28
  356. data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
  357. data/test/cases/validations/i18n_validation_test.rb +22 -21
  358. data/test/cases/validations/length_validation_test.rb +34 -33
  359. data/test/cases/validations/numericality_validation_test.rb +181 -0
  360. data/test/cases/validations/presence_validation_test.rb +21 -19
  361. data/test/cases/validations/uniqueness_validation_test.rb +156 -86
  362. data/test/cases/validations_repair_helper.rb +2 -0
  363. data/test/cases/validations_test.rb +61 -26
  364. data/test/cases/view_test.rb +122 -116
  365. data/test/cases/yaml_serialization_test.rb +79 -34
  366. data/test/config.example.yml +19 -19
  367. data/test/config.rb +3 -1
  368. data/test/config.yml +16 -6
  369. data/test/fixtures/admin/randomly_named_a9.yml +7 -7
  370. data/test/fixtures/admin/randomly_named_b0.yml +7 -7
  371. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  372. data/test/fixtures/author_addresses.yml +1 -8
  373. data/test/fixtures/authors.yml +1 -7
  374. data/test/fixtures/binaries.yml +4 -0
  375. data/test/fixtures/books.yml +9 -2
  376. data/test/fixtures/categories_posts.yml +3 -0
  377. data/test/fixtures/citations.yml +5 -0
  378. data/test/fixtures/comments.yml +7 -0
  379. data/test/fixtures/companies.yml +5 -0
  380. data/test/fixtures/computers.yml +2 -0
  381. data/test/fixtures/customers.yml +10 -1
  382. data/test/fixtures/developers.yml +1 -1
  383. data/test/fixtures/essays.yml +10 -0
  384. data/test/fixtures/faces.yml +3 -3
  385. data/test/fixtures/humans.yml +5 -0
  386. data/test/fixtures/interests.yml +7 -7
  387. data/test/fixtures/memberships.yml +7 -0
  388. data/test/fixtures/minimalistics.yml +3 -0
  389. data/test/fixtures/mixed_case_monkeys.yml +2 -2
  390. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  391. data/test/fixtures/naked/yml/parrots.yml +1 -0
  392. data/test/fixtures/other_books.yml +26 -0
  393. data/test/fixtures/other_posts.yml +1 -0
  394. data/test/fixtures/parrots.yml +7 -1
  395. data/test/fixtures/pirates.yml +3 -0
  396. data/test/fixtures/posts.yml +11 -3
  397. data/test/fixtures/randomly_named_a9.yml +7 -7
  398. data/test/fixtures/readers.yml +6 -0
  399. data/test/fixtures/reserved_words/values.yml +2 -2
  400. data/test/fixtures/sponsors.yml +3 -0
  401. data/test/fixtures/strict_zines.yml +2 -0
  402. data/test/fixtures/subscribers.yml +1 -1
  403. data/test/fixtures/tasks.yml +1 -1
  404. data/test/fixtures/warehouse-things.yml +3 -0
  405. data/test/migrations/10_urban/9_add_expressions.rb +2 -0
  406. data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
  407. data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
  408. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
  409. data/test/migrations/missing/1_people_have_last_names.rb +2 -0
  410. data/test/migrations/missing/3_we_need_reminders.rb +2 -0
  411. data/test/migrations/missing/4_innocent_jointable.rb +3 -1
  412. data/test/migrations/rename/1_we_need_things.rb +2 -0
  413. data/test/migrations/rename/2_rename_things.rb +2 -0
  414. data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
  415. data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
  416. data/test/migrations/to_copy2/1_create_articles.rb +2 -0
  417. data/test/migrations/to_copy2/2_create_comments.rb +3 -1
  418. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
  419. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
  420. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
  421. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
  422. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
  423. data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
  424. data/test/migrations/valid/2_we_need_reminders.rb +2 -0
  425. data/test/migrations/valid/3_innocent_jointable.rb +3 -1
  426. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
  427. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
  428. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
  429. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
  430. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
  431. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
  432. data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
  433. data/test/models/account.rb +46 -0
  434. data/test/models/admin/account.rb +3 -1
  435. data/test/models/admin/randomly_named_c1.rb +2 -0
  436. data/test/models/admin/user.rb +16 -8
  437. data/test/models/admin.rb +4 -2
  438. data/test/models/aircraft.rb +3 -1
  439. data/test/models/arunit2_model.rb +2 -0
  440. data/test/models/author.rb +153 -102
  441. data/test/models/auto_id.rb +2 -0
  442. data/test/models/autoloadable/extra_firm.rb +2 -0
  443. data/test/models/binary.rb +3 -1
  444. data/test/models/binary_field.rb +6 -0
  445. data/test/models/bird.rb +13 -1
  446. data/test/models/book.rb +14 -4
  447. data/test/models/book_destroy_async.rb +24 -0
  448. data/test/models/boolean.rb +5 -0
  449. data/test/models/bulb.rb +13 -4
  450. data/test/models/cake_designer.rb +2 -0
  451. data/test/models/car.rb +17 -10
  452. data/test/models/carrier.rb +2 -0
  453. data/test/models/cart.rb +5 -0
  454. data/test/models/cat.rb +2 -0
  455. data/test/models/categorization.rb +8 -6
  456. data/test/models/category.rb +28 -16
  457. data/test/models/chef.rb +2 -0
  458. data/test/models/citation.rb +5 -1
  459. data/test/models/club.rb +13 -10
  460. data/test/models/college.rb +4 -2
  461. data/test/models/column.rb +2 -0
  462. data/test/models/column_name.rb +2 -0
  463. data/test/models/comment.rb +32 -10
  464. data/test/models/company.rb +102 -106
  465. data/test/models/company_in_module.rb +27 -26
  466. data/test/models/computer.rb +3 -1
  467. data/test/models/contact.rb +15 -13
  468. data/test/models/content.rb +5 -3
  469. data/test/models/contract.rb +21 -3
  470. data/test/models/country.rb +2 -4
  471. data/test/models/course.rb +3 -1
  472. data/test/models/customer.rb +10 -8
  473. data/test/models/customer_carrier.rb +2 -0
  474. data/test/models/dashboard.rb +2 -0
  475. data/test/models/default.rb +2 -0
  476. data/test/models/department.rb +2 -0
  477. data/test/models/destroy_async_parent.rb +15 -0
  478. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  479. data/test/models/developer.rb +152 -85
  480. data/test/models/dl_keyed_belongs_to.rb +13 -0
  481. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  482. data/test/models/dl_keyed_has_many.rb +5 -0
  483. data/test/models/dl_keyed_has_many_through.rb +5 -0
  484. data/test/models/dl_keyed_has_one.rb +5 -0
  485. data/test/models/dl_keyed_join.rb +10 -0
  486. data/test/models/dog.rb +2 -0
  487. data/test/models/dog_lover.rb +2 -0
  488. data/test/models/doubloon.rb +3 -1
  489. data/test/models/drink_designer.rb +17 -0
  490. data/test/models/edge.rb +4 -2
  491. data/test/models/electron.rb +2 -0
  492. data/test/models/engine.rb +3 -2
  493. data/test/models/entrant.rb +2 -0
  494. data/test/models/entry.rb +5 -0
  495. data/test/models/essay.rb +6 -3
  496. data/test/models/essay_destroy_async.rb +12 -0
  497. data/test/models/event.rb +3 -1
  498. data/test/models/eye.rb +5 -3
  499. data/test/models/face.rb +14 -6
  500. data/test/models/family.rb +6 -0
  501. data/test/models/family_tree.rb +6 -0
  502. data/test/models/friendship.rb +5 -3
  503. data/test/models/frog.rb +8 -0
  504. data/test/models/guid.rb +3 -1
  505. data/test/models/guitar.rb +2 -0
  506. data/test/models/hotel.rb +5 -3
  507. data/test/models/human.rb +39 -0
  508. data/test/models/image.rb +3 -1
  509. data/test/models/interest.rb +14 -3
  510. data/test/models/invoice.rb +4 -2
  511. data/test/models/item.rb +3 -1
  512. data/test/models/job.rb +5 -3
  513. data/test/models/joke.rb +4 -2
  514. data/test/models/keyboard.rb +3 -1
  515. data/test/models/legacy_thing.rb +2 -0
  516. data/test/models/lesson.rb +2 -0
  517. data/test/models/line_item.rb +3 -1
  518. data/test/models/liquid.rb +2 -0
  519. data/test/models/matey.rb +3 -1
  520. data/test/models/measurement.rb +4 -0
  521. data/test/models/member.rb +23 -20
  522. data/test/models/member_detail.rb +3 -0
  523. data/test/models/member_type.rb +2 -0
  524. data/test/models/membership.rb +4 -1
  525. data/test/models/mentor.rb +3 -1
  526. data/test/models/message.rb +5 -0
  527. data/test/models/minimalistic.rb +2 -0
  528. data/test/models/minivan.rb +3 -2
  529. data/test/models/mixed_case_monkey.rb +3 -1
  530. data/test/models/molecule.rb +2 -0
  531. data/test/models/mouse.rb +6 -0
  532. data/test/models/movie.rb +2 -0
  533. data/test/models/node.rb +4 -2
  534. data/test/models/non_primary_key.rb +2 -0
  535. data/test/models/notification.rb +2 -0
  536. data/test/models/numeric_data.rb +12 -0
  537. data/test/models/order.rb +4 -2
  538. data/test/models/organization.rb +9 -7
  539. data/test/models/other_dog.rb +3 -1
  540. data/test/models/owner.rb +6 -4
  541. data/test/models/parrot.rb +12 -4
  542. data/test/models/person.rb +59 -54
  543. data/test/models/personal_legacy_thing.rb +3 -1
  544. data/test/models/pet.rb +4 -2
  545. data/test/models/pet_treasure.rb +2 -0
  546. data/test/models/pirate.rb +67 -43
  547. data/test/models/possession.rb +3 -1
  548. data/test/models/post.rb +184 -86
  549. data/test/models/price_estimate.rb +11 -1
  550. data/test/models/professor.rb +3 -1
  551. data/test/models/project.rb +14 -12
  552. data/test/models/publisher/article.rb +2 -0
  553. data/test/models/publisher/magazine.rb +2 -0
  554. data/test/models/publisher.rb +2 -0
  555. data/test/models/randomly_named_c1.rb +2 -0
  556. data/test/models/rating.rb +5 -1
  557. data/test/models/reader.rb +7 -5
  558. data/test/models/recipe.rb +2 -0
  559. data/test/models/record.rb +2 -0
  560. data/test/models/reference.rb +6 -3
  561. data/test/models/reply.rb +39 -21
  562. data/test/models/room.rb +6 -0
  563. data/test/models/section.rb +6 -0
  564. data/test/models/seminar.rb +6 -0
  565. data/test/models/session.rb +6 -0
  566. data/test/models/ship.rb +12 -9
  567. data/test/models/ship_part.rb +5 -3
  568. data/test/models/shop.rb +4 -2
  569. data/test/models/shop_account.rb +2 -0
  570. data/test/models/speedometer.rb +2 -0
  571. data/test/models/sponsor.rb +8 -5
  572. data/test/models/squeak.rb +6 -0
  573. data/test/models/strict_zine.rb +7 -0
  574. data/test/models/string_key_object.rb +2 -0
  575. data/test/models/student.rb +2 -0
  576. data/test/models/subscriber.rb +4 -2
  577. data/test/models/subscription.rb +5 -1
  578. data/test/models/tag.rb +6 -3
  579. data/test/models/tagging.rb +13 -6
  580. data/test/models/task.rb +2 -0
  581. data/test/models/topic.rb +54 -19
  582. data/test/models/toy.rb +4 -0
  583. data/test/models/traffic_light.rb +2 -0
  584. data/test/models/treasure.rb +5 -3
  585. data/test/models/treaty.rb +2 -4
  586. data/test/models/tree.rb +2 -0
  587. data/test/models/tuning_peg.rb +2 -0
  588. data/test/models/tyre.rb +2 -0
  589. data/test/models/user.rb +12 -4
  590. data/test/models/uuid_child.rb +2 -0
  591. data/test/models/uuid_item.rb +2 -0
  592. data/test/models/uuid_parent.rb +2 -0
  593. data/test/models/vegetables.rb +12 -3
  594. data/test/models/vertex.rb +6 -4
  595. data/test/models/warehouse_thing.rb +2 -0
  596. data/test/models/wheel.rb +3 -1
  597. data/test/models/without_table.rb +3 -1
  598. data/test/models/zine.rb +3 -1
  599. data/test/schema/mysql2_specific_schema.rb +49 -35
  600. data/test/schema/oracle_specific_schema.rb +13 -15
  601. data/test/schema/postgresql_specific_schema.rb +51 -40
  602. data/test/schema/schema.rb +334 -154
  603. data/test/schema/sqlite_specific_schema.rb +9 -16
  604. data/test/support/config.rb +26 -26
  605. data/test/support/connection.rb +14 -8
  606. data/test/support/connection_helper.rb +3 -1
  607. data/test/support/ddl_helper.rb +2 -0
  608. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  609. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  610. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  611. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  612. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  613. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  614. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  615. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  616. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  617. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  618. data/test/support/schema_dumping_helper.rb +2 -0
  619. data/test/support/stubs/strong_parameters.rb +40 -0
  620. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  621. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  622. metadata +185 -4
@@ -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