ibm_db 3.0.4 → 5.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (351) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +8 -1
  3. data/LICENSE +1 -1
  4. data/ParameterizedQueries README +6 -6
  5. data/README +38 -55
  6. data/ext/Makefile +266 -0
  7. data/ext/extconf.rb +34 -3
  8. data/ext/gil_release_version +3 -0
  9. data/ext/ibm_db.c +106 -111
  10. data/ext/ibm_db.o +0 -0
  11. data/ext/ibm_db.so +0 -0
  12. data/ext/mkmf.log +103 -0
  13. data/ext/ruby_ibm_db_cli.o +0 -0
  14. data/ext/unicode_support_version +3 -0
  15. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +911 -527
  16. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +4 -1
  17. data/test/active_record/connection_adapters/fake_adapter.rb +8 -5
  18. data/test/cases/adapter_test.rb +148 -58
  19. data/test/cases/adapters/mysql2/active_schema_test.rb +193 -0
  20. data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -0
  21. data/test/cases/adapters/mysql2/boolean_test.rb +100 -0
  22. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -0
  23. data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -0
  24. data/test/cases/adapters/mysql2/connection_test.rb +210 -0
  25. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -0
  26. data/test/cases/adapters/mysql2/enum_test.rb +26 -0
  27. data/test/cases/adapters/mysql2/explain_test.rb +21 -0
  28. data/test/cases/adapters/mysql2/json_test.rb +195 -0
  29. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -0
  30. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -0
  31. data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -0
  32. data/test/cases/adapters/mysql2/schema_test.rb +126 -0
  33. data/test/cases/adapters/mysql2/sp_test.rb +36 -0
  34. data/test/cases/adapters/mysql2/sql_types_test.rb +14 -0
  35. data/test/cases/adapters/mysql2/table_options_test.rb +42 -0
  36. data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -0
  37. data/test/cases/adapters/postgresql/active_schema_test.rb +98 -0
  38. data/test/cases/adapters/postgresql/array_test.rb +339 -0
  39. data/test/cases/adapters/postgresql/bit_string_test.rb +82 -0
  40. data/test/cases/adapters/postgresql/bytea_test.rb +134 -0
  41. data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -0
  42. data/test/cases/adapters/postgresql/change_schema_test.rb +38 -0
  43. data/test/cases/adapters/postgresql/cidr_test.rb +25 -0
  44. data/test/cases/adapters/postgresql/citext_test.rb +78 -0
  45. data/test/cases/adapters/postgresql/collation_test.rb +53 -0
  46. data/test/cases/adapters/postgresql/composite_test.rb +132 -0
  47. data/test/cases/adapters/postgresql/connection_test.rb +257 -0
  48. data/test/cases/adapters/postgresql/datatype_test.rb +92 -0
  49. data/test/cases/adapters/postgresql/domain_test.rb +47 -0
  50. data/test/cases/adapters/postgresql/enum_test.rb +91 -0
  51. data/test/cases/adapters/postgresql/explain_test.rb +20 -0
  52. data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -0
  53. data/test/cases/adapters/postgresql/full_text_test.rb +44 -0
  54. data/test/cases/adapters/postgresql/geometric_test.rb +378 -0
  55. data/test/cases/adapters/postgresql/hstore_test.rb +382 -0
  56. data/test/cases/adapters/postgresql/infinity_test.rb +69 -0
  57. data/test/cases/adapters/postgresql/integer_test.rb +25 -0
  58. data/test/cases/adapters/postgresql/json_test.rb +237 -0
  59. data/test/cases/adapters/postgresql/ltree_test.rb +53 -0
  60. data/test/cases/adapters/postgresql/money_test.rb +96 -0
  61. data/test/cases/adapters/postgresql/network_test.rb +94 -0
  62. data/test/cases/adapters/postgresql/numbers_test.rb +49 -0
  63. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -0
  64. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
  65. data/test/cases/adapters/postgresql/quoting_test.rb +44 -0
  66. data/test/cases/adapters/postgresql/range_test.rb +343 -0
  67. data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -0
  68. data/test/cases/adapters/postgresql/rename_table_test.rb +34 -0
  69. data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -0
  70. data/test/cases/adapters/postgresql/schema_test.rb +597 -0
  71. data/test/cases/adapters/postgresql/serial_test.rb +154 -0
  72. data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -0
  73. data/test/cases/adapters/postgresql/timestamp_test.rb +90 -0
  74. data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -0
  75. data/test/cases/adapters/postgresql/utils_test.rb +62 -0
  76. data/test/cases/adapters/postgresql/uuid_test.rb +294 -0
  77. data/test/cases/adapters/postgresql/xml_test.rb +54 -0
  78. data/test/cases/adapters/sqlite3/collation_test.rb +53 -0
  79. data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -0
  80. data/test/cases/adapters/sqlite3/explain_test.rb +21 -0
  81. data/test/cases/adapters/sqlite3/quoting_test.rb +101 -0
  82. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -0
  83. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -0
  84. data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -0
  85. data/test/cases/aggregations_test.rb +11 -1
  86. data/test/cases/ar_schema_test.rb +35 -50
  87. data/test/cases/associations/association_scope_test.rb +1 -6
  88. data/test/cases/associations/belongs_to_associations_test.rb +122 -10
  89. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -0
  90. data/test/cases/associations/callbacks_test.rb +5 -7
  91. data/test/cases/associations/cascaded_eager_loading_test.rb +1 -1
  92. data/test/cases/associations/eager_load_nested_include_test.rb +1 -3
  93. data/test/cases/associations/eager_test.rb +176 -73
  94. data/test/cases/associations/extension_test.rb +7 -2
  95. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +104 -32
  96. data/test/cases/associations/has_many_associations_test.rb +382 -43
  97. data/test/cases/associations/has_many_through_associations_test.rb +108 -41
  98. data/test/cases/associations/has_one_associations_test.rb +105 -8
  99. data/test/cases/associations/has_one_through_associations_test.rb +6 -3
  100. data/test/cases/associations/inner_join_association_test.rb +3 -3
  101. data/test/cases/associations/inverse_associations_test.rb +51 -11
  102. data/test/cases/associations/join_model_test.rb +59 -36
  103. data/test/cases/associations/left_outer_join_association_test.rb +88 -0
  104. data/test/cases/associations/nested_through_associations_test.rb +2 -2
  105. data/test/cases/associations/required_test.rb +25 -5
  106. data/test/cases/associations_test.rb +39 -34
  107. data/test/cases/attribute_decorators_test.rb +9 -8
  108. data/test/cases/attribute_methods/read_test.rb +5 -5
  109. data/test/cases/attribute_methods_test.rb +97 -40
  110. data/test/cases/attribute_set_test.rb +74 -4
  111. data/test/cases/attribute_test.rb +84 -18
  112. data/test/cases/attributes_test.rb +151 -34
  113. data/test/cases/autosave_association_test.rb +149 -36
  114. data/test/cases/base_test.rb +311 -236
  115. data/test/cases/batches_test.rb +299 -22
  116. data/test/cases/binary_test.rb +2 -10
  117. data/test/cases/bind_parameter_test.rb +76 -66
  118. data/test/cases/cache_key_test.rb +26 -0
  119. data/test/cases/calculations_test.rb +167 -15
  120. data/test/cases/callbacks_test.rb +161 -68
  121. data/test/cases/coders/json_test.rb +15 -0
  122. data/test/cases/collection_cache_key_test.rb +115 -0
  123. data/test/cases/column_definition_test.rb +26 -57
  124. data/test/cases/comment_test.rb +145 -0
  125. data/test/cases/connection_adapters/adapter_leasing_test.rb +5 -3
  126. data/test/cases/connection_adapters/connection_handler_test.rb +128 -21
  127. data/test/cases/connection_adapters/connection_specification_test.rb +1 -1
  128. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +0 -38
  129. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -1
  130. data/test/cases/connection_adapters/schema_cache_test.rb +8 -3
  131. data/test/cases/connection_adapters/type_lookup_test.rb +15 -7
  132. data/test/cases/connection_management_test.rb +46 -56
  133. data/test/cases/connection_pool_test.rb +195 -20
  134. data/test/cases/connection_specification/resolver_test.rb +15 -0
  135. data/test/cases/counter_cache_test.rb +10 -5
  136. data/test/cases/custom_locking_test.rb +1 -1
  137. data/test/cases/database_statements_test.rb +18 -3
  138. data/test/cases/{invalid_date_test.rb → date_test.rb} +13 -1
  139. data/test/cases/date_time_precision_test.rb +107 -0
  140. data/test/cases/defaults_test.rb +85 -89
  141. data/test/cases/dirty_test.rb +32 -44
  142. data/test/cases/disconnected_test.rb +4 -2
  143. data/test/cases/enum_test.rb +178 -24
  144. data/test/cases/errors_test.rb +16 -0
  145. data/test/cases/explain_test.rb +32 -21
  146. data/test/cases/finder_test.rb +279 -151
  147. data/test/cases/fixture_set/file_test.rb +18 -0
  148. data/test/cases/fixtures_test.rb +123 -32
  149. data/test/cases/forbidden_attributes_protection_test.rb +69 -3
  150. data/test/cases/helper.rb +10 -16
  151. data/test/cases/hot_compatibility_test.rb +89 -1
  152. data/test/cases/inheritance_test.rb +284 -53
  153. data/test/cases/integration_test.rb +23 -7
  154. data/test/cases/invalid_connection_test.rb +4 -2
  155. data/test/cases/invertible_migration_test.rb +124 -32
  156. data/test/cases/json_serialization_test.rb +11 -2
  157. data/test/cases/locking_test.rb +22 -6
  158. data/test/cases/log_subscriber_test.rb +106 -17
  159. data/test/cases/migration/change_schema_test.rb +118 -132
  160. data/test/cases/migration/change_table_test.rb +34 -2
  161. data/test/cases/migration/column_attributes_test.rb +7 -23
  162. data/test/cases/migration/column_positioning_test.rb +8 -8
  163. data/test/cases/migration/columns_test.rb +17 -11
  164. data/test/cases/migration/command_recorder_test.rb +47 -2
  165. data/test/cases/migration/compatibility_test.rb +118 -0
  166. data/test/cases/migration/create_join_table_test.rb +21 -12
  167. data/test/cases/migration/foreign_key_test.rb +68 -66
  168. data/test/cases/migration/index_test.rb +14 -12
  169. data/test/cases/migration/logger_test.rb +1 -1
  170. data/test/cases/migration/pending_migrations_test.rb +0 -1
  171. data/test/cases/migration/references_foreign_key_test.rb +114 -107
  172. data/test/cases/migration/references_index_test.rb +4 -4
  173. data/test/cases/migration/references_statements_test.rb +26 -6
  174. data/test/cases/migration/rename_table_test.rb +25 -25
  175. data/test/cases/migration_test.rb +279 -81
  176. data/test/cases/migrator_test.rb +91 -8
  177. data/test/cases/mixin_test.rb +0 -2
  178. data/test/cases/modules_test.rb +3 -4
  179. data/test/cases/multiparameter_attributes_test.rb +24 -2
  180. data/test/cases/multiple_db_test.rb +18 -11
  181. data/test/cases/nested_attributes_test.rb +74 -33
  182. data/test/cases/persistence_test.rb +102 -10
  183. data/test/cases/pooled_connections_test.rb +3 -3
  184. data/test/cases/primary_keys_test.rb +170 -31
  185. data/test/cases/query_cache_test.rb +216 -96
  186. data/test/cases/quoting_test.rb +65 -19
  187. data/test/cases/readonly_test.rb +2 -1
  188. data/test/cases/reflection_test.rb +77 -22
  189. data/test/cases/relation/delegation_test.rb +3 -8
  190. data/test/cases/relation/merging_test.rb +10 -14
  191. data/test/cases/relation/mutation_test.rb +42 -24
  192. data/test/cases/relation/or_test.rb +92 -0
  193. data/test/cases/relation/predicate_builder_test.rb +4 -2
  194. data/test/cases/relation/record_fetch_warning_test.rb +40 -0
  195. data/test/cases/relation/where_chain_test.rb +23 -99
  196. data/test/cases/relation/where_clause_test.rb +182 -0
  197. data/test/cases/relation/where_test.rb +45 -23
  198. data/test/cases/relation_test.rb +89 -58
  199. data/test/cases/relations_test.rb +249 -38
  200. data/test/cases/result_test.rb +10 -0
  201. data/test/cases/sanitize_test.rb +108 -15
  202. data/test/cases/schema_dumper_test.rb +119 -125
  203. data/test/cases/schema_loading_test.rb +52 -0
  204. data/test/cases/scoping/default_scoping_test.rb +113 -39
  205. data/test/cases/scoping/named_scoping_test.rb +46 -9
  206. data/test/cases/scoping/relation_scoping_test.rb +47 -4
  207. data/test/cases/secure_token_test.rb +32 -0
  208. data/test/cases/serialization_test.rb +1 -1
  209. data/test/cases/serialized_attribute_test.rb +93 -6
  210. data/test/cases/statement_cache_test.rb +38 -0
  211. data/test/cases/store_test.rb +2 -1
  212. data/test/cases/suppressor_test.rb +63 -0
  213. data/test/cases/tasks/database_tasks_test.rb +74 -8
  214. data/test/cases/tasks/mysql_rake_test.rb +143 -109
  215. data/test/cases/tasks/postgresql_rake_test.rb +71 -12
  216. data/test/cases/tasks/sqlite_rake_test.rb +30 -3
  217. data/test/cases/test_case.rb +28 -20
  218. data/test/cases/test_fixtures_test.rb +36 -0
  219. data/test/cases/time_precision_test.rb +103 -0
  220. data/test/cases/timestamp_test.rb +47 -14
  221. data/test/cases/touch_later_test.rb +121 -0
  222. data/test/cases/transaction_callbacks_test.rb +128 -62
  223. data/test/cases/transaction_isolation_test.rb +2 -2
  224. data/test/cases/transactions_test.rb +61 -43
  225. data/test/cases/type/adapter_specific_registry_test.rb +133 -0
  226. data/test/cases/type/date_time_test.rb +14 -0
  227. data/test/cases/type/integer_test.rb +2 -96
  228. data/test/cases/type/string_test.rb +0 -14
  229. data/test/cases/type_test.rb +39 -0
  230. data/test/cases/types_test.rb +1 -118
  231. data/test/cases/unconnected_test.rb +1 -1
  232. data/test/cases/validations/absence_validation_test.rb +73 -0
  233. data/test/cases/validations/association_validation_test.rb +13 -2
  234. data/test/cases/validations/i18n_validation_test.rb +6 -10
  235. data/test/cases/validations/length_validation_test.rb +62 -30
  236. data/test/cases/validations/presence_validation_test.rb +36 -1
  237. data/test/cases/validations/uniqueness_validation_test.rb +150 -36
  238. data/test/cases/validations_repair_helper.rb +2 -6
  239. data/test/cases/validations_test.rb +36 -7
  240. data/test/cases/view_test.rb +108 -5
  241. data/test/cases/yaml_serialization_test.rb +36 -1
  242. data/test/config.example.yml +97 -0
  243. data/test/fixtures/bad_posts.yml +9 -0
  244. data/test/fixtures/books.yml +20 -0
  245. data/test/fixtures/content.yml +3 -0
  246. data/test/fixtures/content_positions.yml +3 -0
  247. data/test/fixtures/dead_parrots.yml +5 -0
  248. data/test/fixtures/live_parrots.yml +4 -0
  249. data/test/fixtures/naked/yml/parrots.yml +2 -0
  250. data/test/fixtures/naked/yml/trees.yml +3 -0
  251. data/test/fixtures/nodes.yml +29 -0
  252. data/test/fixtures/other_comments.yml +6 -0
  253. data/test/fixtures/other_dogs.yml +2 -0
  254. data/test/fixtures/other_posts.yml +7 -0
  255. data/test/fixtures/price_estimates.yml +10 -1
  256. data/test/fixtures/trees.yml +3 -0
  257. data/test/migrations/10_urban/9_add_expressions.rb +1 -1
  258. data/test/migrations/decimal/1_give_me_big_numbers.rb +1 -1
  259. data/test/migrations/magic/1_currencies_have_symbols.rb +1 -1
  260. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -2
  261. data/test/migrations/missing/1_people_have_last_names.rb +2 -2
  262. data/test/migrations/missing/3_we_need_reminders.rb +2 -2
  263. data/test/migrations/missing/4_innocent_jointable.rb +2 -2
  264. data/test/migrations/rename/1_we_need_things.rb +2 -2
  265. data/test/migrations/rename/2_rename_things.rb +2 -2
  266. data/test/migrations/to_copy/1_people_have_hobbies.rb +1 -1
  267. data/test/migrations/to_copy/2_people_have_descriptions.rb +1 -1
  268. data/test/migrations/to_copy2/1_create_articles.rb +1 -1
  269. data/test/migrations/to_copy2/2_create_comments.rb +1 -1
  270. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +1 -1
  271. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +1 -1
  272. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +1 -1
  273. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +1 -1
  274. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +1 -1
  275. data/test/migrations/valid/1_valid_people_have_last_names.rb +1 -1
  276. data/test/migrations/valid/2_we_need_reminders.rb +2 -2
  277. data/test/migrations/valid/3_innocent_jointable.rb +2 -2
  278. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +1 -1
  279. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -2
  280. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +2 -2
  281. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +1 -1
  282. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +1 -1
  283. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +1 -1
  284. data/test/migrations/version_check/20131219224947_migration_version_check.rb +1 -1
  285. data/test/models/admin/randomly_named_c1.rb +6 -2
  286. data/test/models/aircraft.rb +1 -0
  287. data/test/models/author.rb +4 -7
  288. data/test/models/bird.rb +1 -1
  289. data/test/models/book.rb +5 -0
  290. data/test/models/bulb.rb +2 -1
  291. data/test/models/car.rb +3 -0
  292. data/test/models/cat.rb +10 -0
  293. data/test/models/chef.rb +5 -0
  294. data/test/models/club.rb +2 -0
  295. data/test/models/comment.rb +17 -5
  296. data/test/models/company.rb +7 -2
  297. data/test/models/company_in_module.rb +1 -1
  298. data/test/models/contact.rb +1 -1
  299. data/test/models/content.rb +40 -0
  300. data/test/models/customer.rb +8 -2
  301. data/test/models/developer.rb +22 -0
  302. data/test/models/face.rb +1 -1
  303. data/test/models/guitar.rb +4 -0
  304. data/test/models/hotel.rb +5 -0
  305. data/test/models/member.rb +1 -0
  306. data/test/models/member_detail.rb +4 -3
  307. data/test/models/mentor.rb +3 -0
  308. data/test/models/mocktail_designer.rb +2 -0
  309. data/test/models/node.rb +5 -0
  310. data/test/models/non_primary_key.rb +2 -0
  311. data/test/models/notification.rb +3 -0
  312. data/test/models/other_dog.rb +5 -0
  313. data/test/models/owner.rb +4 -1
  314. data/test/models/parrot.rb +6 -7
  315. data/test/models/person.rb +0 -1
  316. data/test/models/pet.rb +3 -0
  317. data/test/models/pet_treasure.rb +6 -0
  318. data/test/models/pirate.rb +3 -3
  319. data/test/models/post.rb +18 -9
  320. data/test/models/project.rb +11 -0
  321. data/test/models/randomly_named_c1.rb +1 -1
  322. data/test/models/recipe.rb +3 -0
  323. data/test/models/ship.rb +8 -2
  324. data/test/models/tag.rb +6 -0
  325. data/test/models/topic.rb +2 -8
  326. data/test/models/tree.rb +3 -0
  327. data/test/models/tuning_peg.rb +4 -0
  328. data/test/models/user.rb +14 -0
  329. data/test/models/uuid_item.rb +6 -0
  330. data/test/schema/mysql2_specific_schema.rb +33 -23
  331. data/test/schema/oracle_specific_schema.rb +1 -4
  332. data/test/schema/postgresql_specific_schema.rb +36 -124
  333. data/test/schema/schema.rb +183 -64
  334. data/test/schema/schema.rb.original +1057 -0
  335. data/test/schema/sqlite_specific_schema.rb +1 -5
  336. data/test/support/connection.rb +1 -0
  337. data/test/support/schema_dumping_helper.rb +1 -1
  338. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
  339. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -0
  340. metadata +145 -26
  341. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +0 -26
  342. data/test/cases/attribute_methods/serialization_test.rb +0 -29
  343. data/test/cases/migration/change_schema_test - Copy.rb +0 -448
  344. data/test/cases/migration/foreign_key_test - Changed.rb +0 -325
  345. data/test/cases/migration/table_and_index_test.rb +0 -24
  346. data/test/cases/relation/where_test2.rb +0 -36
  347. data/test/cases/type/decimal_test.rb +0 -51
  348. data/test/cases/type/unsigned_integer_test.rb +0 -18
  349. data/test/cases/xml_serialization_test.rb +0 -457
  350. data/test/fixtures/naked/csv/accounts.csv +0 -1
  351. data/test/schema/mysql_specific_schema.rb +0 -70
@@ -0,0 +1,16 @@
1
+ require_relative "../cases/helper"
2
+
3
+ class ErrorsTest < ActiveRecord::TestCase
4
+ def test_can_be_instantiated_with_no_args
5
+ base = ActiveRecord::ActiveRecordError
6
+ error_klasses = ObjectSpace.each_object(Class).select { |klass| klass < base }
7
+
8
+ error_klasses.each do |error_klass|
9
+ begin
10
+ error_klass.new.inspect
11
+ rescue ArgumentError
12
+ raise "Instance of #{error_klass} can't be initialized with no arguments"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -28,7 +28,7 @@ if ActiveRecord::Base.connection.supports_explain?
28
28
  assert_match "SELECT", sql
29
29
  if binds.any?
30
30
  assert_equal 1, binds.length
31
- assert_equal "honda", binds.flatten.last
31
+ assert_equal "honda", binds.last.value
32
32
  else
33
33
  assert_match 'honda', sql
34
34
  end
@@ -39,38 +39,49 @@ if ActiveRecord::Base.connection.supports_explain?
39
39
  binds = [[], []]
40
40
  queries = sqls.zip(binds)
41
41
 
42
- connection.stubs(:explain).returns('query plan foo', 'query plan bar')
43
- expected = sqls.map {|sql| "EXPLAIN for: #{sql}\nquery plan #{sql}"}.join("\n")
44
- assert_equal expected, base.exec_explain(queries)
42
+ stub_explain_for_query_plans do
43
+ expected = sqls.map {|sql| "EXPLAIN for: #{sql}\nquery plan #{sql}"}.join("\n")
44
+ assert_equal expected, base.exec_explain(queries)
45
+ end
45
46
  end
46
47
 
47
48
  def test_exec_explain_with_binds
48
- cols = [Object.new, Object.new]
49
- cols[0].expects(:name).returns('wadus')
50
- cols[1].expects(:name).returns('chaflan')
51
-
52
49
  sqls = %w(foo bar)
53
- binds = [[[cols[0], 1]], [[cols[1], 2]]]
50
+ binds = [[bind_param("wadus", 1)], [bind_param("chaflan", 2)]]
54
51
  queries = sqls.zip(binds)
55
52
 
56
- connection.stubs(:explain).returns("query plan foo\n", "query plan bar\n")
57
- expected = <<-SQL.strip_heredoc
58
- EXPLAIN for: #{sqls[0]} [["wadus", 1]]
59
- query plan foo
53
+ stub_explain_for_query_plans(["query plan foo\n", "query plan bar\n"]) do
54
+ expected = <<-SQL.strip_heredoc
55
+ EXPLAIN for: #{sqls[0]} [["wadus", 1]]
56
+ query plan foo
60
57
 
61
- EXPLAIN for: #{sqls[1]} [["chaflan", 2]]
62
- query plan bar
63
- SQL
64
- assert_equal expected, base.exec_explain(queries)
58
+ EXPLAIN for: #{sqls[1]} [["chaflan", 2]]
59
+ query plan bar
60
+ SQL
61
+ assert_equal expected, base.exec_explain(queries)
62
+ end
65
63
  end
66
64
 
67
65
  def test_unsupported_connection_adapter
68
- connection.stubs(:supports_explain?).returns(false)
66
+ connection.stub(:supports_explain?, false) do
67
+ assert_not_called(base.logger, :warn) do
68
+ Car.where(:name => 'honda').to_a
69
+ end
70
+ end
71
+ end
69
72
 
70
- base.logger.expects(:warn).never
73
+ private
71
74
 
72
- Car.where(:name => 'honda').to_a
73
- end
75
+ def stub_explain_for_query_plans(query_plans = ['query plan foo', 'query plan bar'])
76
+ explain_called = 0
77
+
78
+ connection.stub(:explain, proc{ explain_called += 1; query_plans[explain_called - 1] }) do
79
+ yield
80
+ end
81
+ end
74
82
 
83
+ def bind_param(name, value)
84
+ ActiveRecord::Relation::QueryAttribute.new(name, value, ActiveRecord::Type::Value.new)
85
+ end
75
86
  end
76
87
  end
@@ -19,7 +19,7 @@ require 'models/car'
19
19
  require 'models/tyre'
20
20
 
21
21
  class FinderTest < ActiveRecord::TestCase
22
- fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers, :categories, :categorizations, :cars, :author_addresses
22
+ fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :author_addresses, :customers, :categories, :categorizations, :cars
23
23
 
24
24
  def test_find_by_id_with_hash
25
25
  assert_raises(ActiveRecord::StatementInvalid) do
@@ -43,11 +43,82 @@ class FinderTest < ActiveRecord::TestCase
43
43
  end
44
44
  assert_equal "should happen", exception.message
45
45
 
46
- assert_nothing_raised(RuntimeError) do
46
+ assert_nothing_raised do
47
47
  Topic.all.find(-> { raise "should not happen" }) { |e| e.title == topics(:first).title }
48
48
  end
49
49
  end
50
50
 
51
+ 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
57
+
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
62
+
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
67
+
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
72
+ end
73
+
74
+ def test_find_with_ids_and_order_clause
75
+ # 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
80
+
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
85
+ end
86
+
87
+ def test_find_with_ids_with_limit_and_order_clause
88
+ puts "finder_test.test_find_with_ids_with_limit_and_order_clause"
89
+ # The order clause takes precedence over the informed ids
90
+ records = Topic.limit(2).order(:id).find([5,3,1])
91
+ 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
94
+ end
95
+
96
+ def test_find_with_ids_and_limit
97
+ records = Topic.limit(3).find([3,2,5,1,4])
98
+ 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
102
+ end
103
+
104
+ def test_find_with_ids_where_and_limit
105
+ # Please note that Topic 1 is the only not approved so
106
+ # 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])
108
+ 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
112
+ end
113
+
114
+ def test_find_with_ids_and_offset
115
+ records = Topic.offset(2).find([3,2,5,1,4])
116
+ 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
120
+ end
121
+
51
122
  def test_find_passing_active_record_object_is_deprecated
52
123
  assert_deprecated do
53
124
  Topic.find(Topic.last)
@@ -86,6 +157,7 @@ class FinderTest < ActiveRecord::TestCase
86
157
  end
87
158
 
88
159
  def test_exists_with_polymorphic_relation
160
+ puts "finder_test.test_exists_with_polymorphic_relation"
89
161
  post = Post.create!(title: 'Post', body: 'default', taggings: [Tagging.new(comment: 'tagging comment')])
90
162
  relation = Post.tagged_with_comment('tagging comment')
91
163
 
@@ -105,13 +177,15 @@ class FinderTest < ActiveRecord::TestCase
105
177
  end
106
178
 
107
179
  def test_exists_fails_when_parameter_has_invalid_type
108
- assert_raises(RangeError) do
180
+ puts "finder_test.test_exists_fails_when_parameter_has_invalid_type"
181
+ assert_raises(ActiveModel::RangeError) do
109
182
  assert_equal false, Topic.exists?(("9"*53).to_i) # number that's bigger than int
110
183
  end
111
184
  assert_equal false, Topic.exists?("foo")
112
185
  end
113
186
 
114
187
  def test_exists_does_not_select_columns_without_alias
188
+ puts "finder_test.test_exists_does_not_select_columns_without_alias"
115
189
  assert_sql(/SELECT\W+1 AS one FROM ["`]topics["`]/i) do
116
190
  Topic.exists?
117
191
  end
@@ -141,17 +215,20 @@ class FinderTest < ActiveRecord::TestCase
141
215
  end
142
216
 
143
217
  def test_exists_with_includes_limit_and_empty_result
218
+ puts "finder_test.test_exists_with_includes_limit_and_empty_result"
144
219
  assert_equal false, Topic.includes(:replies).limit(0).exists?
145
220
  assert_equal false, Topic.includes(:replies).limit(1).where('0 = 1').exists?
146
221
  end
147
222
 
148
223
  def test_exists_with_distinct_association_includes_and_limit
224
+ puts "finder_test.test_exists_with_distinct_association_includes_and_limit"
149
225
  author = Author.first
150
226
  assert_equal false, author.unique_categorized_posts.includes(:special_comments).limit(0).exists?
151
227
  assert_equal true, author.unique_categorized_posts.includes(:special_comments).limit(1).exists?
152
228
  end
153
229
 
154
230
  def test_exists_with_distinct_association_includes_limit_and_order
231
+ puts "finder_test.test_exists_with_distinct_association_includes_limit_and_order"
155
232
  author = Author.first
156
233
  assert_equal false, author.unique_categorized_posts.includes(:special_comments).order('comments.tags_count DESC').limit(0).exists?
157
234
  assert_equal true, author.unique_categorized_posts.includes(:special_comments).order('comments.tags_count DESC').limit(1).exists?
@@ -178,8 +255,9 @@ class FinderTest < ActiveRecord::TestCase
178
255
  end
179
256
 
180
257
  def test_exists_does_not_instantiate_records
181
- Developer.expects(:instantiate).never
182
- Developer.exists?
258
+ assert_not_called(Developer, :instantiate) do
259
+ Developer.exists?
260
+ end
183
261
  end
184
262
 
185
263
  def test_find_by_array_of_one_id
@@ -194,7 +272,9 @@ class FinderTest < ActiveRecord::TestCase
194
272
 
195
273
  def test_find_by_ids_with_limit_and_offset
196
274
  assert_equal 2, Entrant.limit(2).find([1,3,2]).size
197
- assert_equal 1, Entrant.limit(3).offset(2).find([1,3,2]).size
275
+ entrants = Entrant.limit(3).offset(2).find([1,3,2])
276
+ assert_equal 1, entrants.size
277
+ assert_equal 'Ruby Guru', entrants.first.name
198
278
 
199
279
  # Also test an edge case: If you have 11 results, and you set a
200
280
  # limit of 3 and offset of 9, then you should find that there
@@ -202,28 +282,32 @@ class FinderTest < ActiveRecord::TestCase
202
282
  devs = Developer.all
203
283
  last_devs = Developer.limit(3).offset(9).find devs.map(&:id)
204
284
  assert_equal 2, last_devs.size
285
+ assert_equal 'fixture_10', last_devs[0].name
286
+ assert_equal 'Jamis', last_devs[1].name
205
287
  end
206
288
 
207
- def test_find_with_large_number
208
- assert_raises(ActiveRecord::RecordNotFound) { Topic.find('9999999999999999999999999999999') }
209
- end
289
+ unless current_adapter?(:IBM_DBAdapter)
290
+ def test_find_with_large_number
291
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find('9999999999999999999999999999999') }
292
+ end
210
293
 
211
- def test_find_by_with_large_number
212
- assert_nil Topic.find_by(id: '9999999999999999999999999999999')
213
- end
294
+ def test_find_by_with_large_number
295
+ assert_nil Topic.find_by(id: '9999999999999999999999999999999')
296
+ end
214
297
 
215
- def test_find_by_id_with_large_number
216
- assert_nil Topic.find_by_id('9999999999999999999999999999999')
217
- end
298
+ def test_find_by_id_with_large_number
299
+ assert_nil Topic.find_by_id('9999999999999999999999999999999')
300
+ end
218
301
 
219
- def test_find_on_relation_with_large_number
220
- assert_nil Topic.where('1=1').find_by(id: 9999999999999999999999999999999)
221
- end
302
+ def test_find_on_relation_with_large_number
303
+ assert_nil Topic.where('1=1').find_by(id: 9999999999999999999999999999999)
304
+ end
222
305
 
223
- def test_find_by_bang_on_relation_with_large_number
224
- assert_raises(ActiveRecord::RecordNotFound) do
225
- Topic.where('1=1').find_by!(id: 9999999999999999999999999999999)
226
- end
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
227
311
  end
228
312
 
229
313
  def test_find_an_empty_array
@@ -264,6 +348,17 @@ class FinderTest < ActiveRecord::TestCase
264
348
  assert_equal [Account], accounts.collect(&:class).uniq
265
349
  end
266
350
 
351
+ 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))
355
+ end
356
+
357
+ 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)
360
+ end
361
+
267
362
  def test_take
268
363
  assert_equal topics(:first), Topic.take
269
364
  end
@@ -319,14 +414,17 @@ class FinderTest < ActiveRecord::TestCase
319
414
  end
320
415
 
321
416
  def test_second
417
+ puts "finder_test.test_second"
322
418
  assert_equal topics(:second).title, Topic.second.title
323
419
  end
324
420
 
325
421
  def test_second_with_offset
422
+ puts "finder_test.test_second_with_offset"
326
423
  assert_equal topics(:fifth), Topic.offset(3).second
327
424
  end
328
425
 
329
426
  def test_second_have_primary_key_order_by_default
427
+ puts "finder_test.test_second_have_primary_key_order_by_default"
330
428
  expected = topics(:second)
331
429
  expected.touch # PostgreSQL changes the default order if no order clause is used
332
430
  assert_equal expected, Topic.second
@@ -341,14 +439,17 @@ class FinderTest < ActiveRecord::TestCase
341
439
  end
342
440
 
343
441
  def test_third
442
+ puts "finder_test.test_third"
344
443
  assert_equal topics(:third).title, Topic.third.title
345
444
  end
346
445
 
347
446
  def test_third_with_offset
447
+ puts "finder_test.test_third_with_offset"
348
448
  assert_equal topics(:fifth), Topic.offset(2).third
349
449
  end
350
450
 
351
451
  def test_third_have_primary_key_order_by_default
452
+ puts "finder_test.test_third_have_primary_key_order_by_default"
352
453
  expected = topics(:third)
353
454
  expected.touch # PostgreSQL changes the default order if no order clause is used
354
455
  assert_equal expected, Topic.third
@@ -363,14 +464,17 @@ class FinderTest < ActiveRecord::TestCase
363
464
  end
364
465
 
365
466
  def test_fourth
467
+ puts "finder_test.test_fourth"
366
468
  assert_equal topics(:fourth).title, Topic.fourth.title
367
469
  end
368
470
 
369
471
  def test_fourth_with_offset
472
+ puts "finder_test.test_fourth_with_offset"
370
473
  assert_equal topics(:fifth), Topic.offset(1).fourth
371
474
  end
372
475
 
373
476
  def test_fourth_have_primary_key_order_by_default
477
+ puts "finder_test.test_fourth_have_primary_key_order_by_default"
374
478
  expected = topics(:fourth)
375
479
  expected.touch # PostgreSQL changes the default order if no order clause is used
376
480
  assert_equal expected, Topic.fourth
@@ -389,10 +493,12 @@ class FinderTest < ActiveRecord::TestCase
389
493
  end
390
494
 
391
495
  def test_fifth_with_offset
496
+ puts "finder_test.test_fifth_with_offset"
392
497
  assert_equal topics(:fifth), Topic.offset(0).fifth
393
498
  end
394
499
 
395
500
  def test_fifth_have_primary_key_order_by_default
501
+ puts "finder_test.test_fifth_have_primary_key_order_by_default"
396
502
  expected = topics(:fifth)
397
503
  expected.touch # PostgreSQL changes the default order if no order clause is used
398
504
  assert_equal expected, Topic.fifth
@@ -406,6 +512,67 @@ class FinderTest < ActiveRecord::TestCase
406
512
  end
407
513
  end
408
514
 
515
+ def test_second_to_last
516
+ puts "finder_test.test_second_to_last"
517
+ assert_equal topics(:fourth).title, Topic.second_to_last.title
518
+
519
+ # test with offset
520
+ assert_equal topics(:fourth), Topic.offset(1).second_to_last
521
+ assert_equal topics(:fourth), Topic.offset(2).second_to_last
522
+ 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
525
+
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
529
+ end
530
+
531
+ def test_second_to_last_have_primary_key_order_by_default
532
+ expected = topics(:fourth)
533
+ expected.touch # PostgreSQL changes the default order if no order clause is used
534
+ assert_equal expected, Topic.second_to_last
535
+ end
536
+
537
+ def test_model_class_responds_to_second_to_last_bang
538
+ assert Topic.second_to_last!
539
+ Topic.delete_all
540
+ assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
541
+ Topic.second_to_last!
542
+ end
543
+ end
544
+
545
+ def test_third_to_last
546
+ assert_equal topics(:third).title, Topic.third_to_last.title
547
+
548
+ # test with offset
549
+ assert_equal topics(:third), Topic.offset(1).third_to_last
550
+ 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
554
+
555
+ # 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
560
+ end
561
+
562
+ def test_third_to_last_have_primary_key_order_by_default
563
+ expected = topics(:third)
564
+ expected.touch # PostgreSQL changes the default order if no order clause is used
565
+ assert_equal expected, Topic.third_to_last
566
+ end
567
+
568
+ def test_model_class_responds_to_third_to_last_bang
569
+ assert Topic.third_to_last!
570
+ Topic.delete_all
571
+ assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
572
+ Topic.third_to_last!
573
+ end
574
+ end
575
+
409
576
  def test_last_bang_present
410
577
  assert_nothing_raised do
411
578
  assert_equal topics(:second), Topic.where("title = 'The Second Topic of the day'").last!
@@ -427,25 +594,55 @@ class FinderTest < ActiveRecord::TestCase
427
594
  end
428
595
 
429
596
  def test_take_and_first_and_last_with_integer_should_use_sql_limit
430
- assert_sql(/LIMIT 3|ROWNUM <= 3/) { Topic.take(3).entries }
431
- assert_sql(/LIMIT 2|ROWNUM <= 2/) { Topic.first(2).entries }
432
- assert_sql(/LIMIT 5|ROWNUM <= 5/) { Topic.last(5).entries }
597
+ puts "finder_test.test_take_and_first_and_last_with_integer_should_use_sql_limit"
598
+ assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) { Topic.take(3).entries }
599
+ assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) { Topic.first(2).entries }
600
+ assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) { Topic.last(5).entries }
433
601
  end
434
602
 
435
603
  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"
436
605
  assert_equal Topic.order("title").to_a.last(2), Topic.order("title").last(2)
437
606
  end
438
607
 
439
- def test_last_with_integer_and_order_should_not_use_sql_limit
440
- query = assert_sql { Topic.order("title").last(5).entries }
441
- assert_equal 1, query.length
442
- assert_no_match(/LIMIT/, query.first)
608
+ def test_last_with_integer_and_order_should_use_sql_limit
609
+ relation = Topic.order("title")
610
+ assert_queries(1) { relation.last(5) }
611
+ assert !relation.loaded?
612
+ end
613
+
614
+ def test_last_with_integer_and_reorder_should_use_sql_limit
615
+ relation = Topic.reorder("title")
616
+ assert_queries(1) { relation.last(5) }
617
+ assert !relation.loaded?
443
618
  end
444
619
 
445
- def test_last_with_integer_and_reorder_should_not_use_sql_limit
446
- query = assert_sql { Topic.reorder("title").last(5).entries }
447
- assert_equal 1, query.length
448
- assert_no_match(/LIMIT/, query.first)
620
+ def test_last_on_loaded_relation_should_not_use_sql
621
+ relation = Topic.limit(10).load
622
+ assert_no_queries do
623
+ relation.last
624
+ relation.last(2)
625
+ end
626
+ end
627
+
628
+ def test_last_with_irreversible_order
629
+ assert_deprecated do
630
+ Topic.order("coalesce(author_name, title)").last
631
+ end
632
+ end
633
+
634
+ def test_last_on_relation_with_limit_and_offset
635
+ post = posts('sti_comments')
636
+
637
+ comments = post.comments.order(id: :asc)
638
+ assert_equal comments.limit(2).to_a.last, comments.limit(2).last
639
+ assert_equal comments.limit(2).to_a.last(2), comments.limit(2).last(2)
640
+ assert_equal comments.limit(2).to_a.last(3), comments.limit(2).last(3)
641
+
642
+ comments = comments.offset(1)
643
+ assert_equal comments.limit(2).to_a.last, comments.limit(2).last
644
+ assert_equal comments.limit(2).to_a.last(2), comments.limit(2).last(2)
645
+ assert_equal comments.limit(2).to_a.last(3), comments.limit(2).last(3)
449
646
  end
450
647
 
451
648
  def test_take_and_first_and_last_with_integer_should_return_an_array
@@ -484,16 +681,27 @@ class FinderTest < ActiveRecord::TestCase
484
681
  assert_raise(ActiveRecord::RecordNotFound) { Topic.where(approved: true).find(1) }
485
682
  end
486
683
 
487
- def test_find_on_hash_conditions_with_explicit_table_name
684
+ def test_find_on_hash_conditions_with_qualified_attribute_dot_notation_string
488
685
  assert Topic.where('topics.approved' => false).find(1)
489
686
  assert_raise(ActiveRecord::RecordNotFound) { Topic.where('topics.approved' => true).find(1) }
490
687
  end
491
688
 
689
+ def test_find_on_hash_conditions_with_qualified_attribute_dot_notation_symbol
690
+ assert Topic.where('topics.approved': false).find(1)
691
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.where('topics.approved': true).find(1) }
692
+ end
693
+
492
694
  def test_find_on_hash_conditions_with_hashed_table_name
493
695
  assert Topic.where(topics: { approved: false }).find(1)
494
696
  assert_raise(ActiveRecord::RecordNotFound) { Topic.where(topics: { approved: true }).find(1) }
495
697
  end
496
698
 
699
+ 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) }
703
+ end
704
+
497
705
  def test_find_with_hash_conditions_on_joined_table
498
706
  firms = Firm.joins(:account).where(:accounts => { :credit_limit => 50 })
499
707
  assert_equal 1, firms.size
@@ -542,30 +750,6 @@ class FinderTest < ActiveRecord::TestCase
542
750
  assert_equal [1,2,6,7,8], Comment.where(id: [1..2, 6..8]).to_a.map(&:id).sort
543
751
  end
544
752
 
545
- def test_find_on_hash_conditions_with_nested_array_of_integers_and_ranges
546
- assert_deprecated do
547
- 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
548
- end
549
- end
550
-
551
- def test_find_on_hash_conditions_with_array_of_integers_and_arrays
552
- assert_deprecated do
553
- assert_equal [1,2,3,5,6,7,8,9], Comment.where(id: [[1, 2], 3, 5, [6, [7], 8], 9]).to_a.map(&:id).sort
554
- end
555
- end
556
-
557
- def test_find_on_hash_conditions_with_nested_array_of_integers_and_ranges_and_nils
558
- assert_deprecated do
559
- assert_equal [1,3,4,5], Topic.where(parent_id: [[2..6], nil]).to_a.map(&:id).sort
560
- end
561
- end
562
-
563
- def test_find_on_hash_conditions_with_nested_array_of_integers_and_ranges_and_more_nils
564
- assert_deprecated do
565
- assert_equal [], Topic.where(parent_id: [[7..10, nil, [nil]], [nil]]).to_a.map(&:id).sort
566
- end
567
- end
568
-
569
753
  def test_find_on_multiple_hash_conditions
570
754
  assert Topic.where(author_name: "David", title: "The First Topic", replies_count: 1, approved: false).find(1)
571
755
  assert_raise(ActiveRecord::RecordNotFound) { Topic.where(author_name: "David", title: "The First Topic", replies_count: 1, approved: true).find(1) }
@@ -574,6 +758,7 @@ class FinderTest < ActiveRecord::TestCase
574
758
  end
575
759
 
576
760
  def test_condition_interpolation
761
+ puts "finder_test.test_condition_interpolation"
577
762
  assert_kind_of Firm, Company.where("name = '%s'", "37signals").first
578
763
  assert_nil Company.where(["name = '%s'", "37signals!"]).first
579
764
  assert_nil Company.where(["name = '%s'", "37signals!' OR 1=1"]).first
@@ -581,6 +766,7 @@ class FinderTest < ActiveRecord::TestCase
581
766
  end
582
767
 
583
768
  def test_condition_array_interpolation
769
+ puts "finder_test.test_condition_array_interpolation"
584
770
  assert_kind_of Firm, Company.where(["name = '%s'", "37signals"]).first
585
771
  assert_nil Company.where(["name = '%s'", "37signals!"]).first
586
772
  assert_nil Company.where(["name = '%s'", "37signals!' OR 1=1"]).first
@@ -600,11 +786,13 @@ class FinderTest < ActiveRecord::TestCase
600
786
  end
601
787
 
602
788
  def test_hash_condition_find_with_escaped_characters
789
+ puts "finder_test.test_hash_condition_find_with_escaped_characters"
603
790
  Company.create("name" => "Ain't noth'n like' \#stuff")
604
791
  assert Company.where(name: "Ain't noth'n like' \#stuff").first
605
792
  end
606
793
 
607
794
  def test_hash_condition_find_with_array
795
+ puts "finder_test.test_hash_condition_find_with_array"
608
796
  p1, p2 = Post.limit(2).order('id asc').to_a
609
797
  assert_equal [p1, p2], Post.where(id: [p1, p2]).order('id asc').to_a
610
798
  assert_equal [p1, p2], Post.where(id: [p1, p2.id]).order('id asc').to_a
@@ -668,6 +856,7 @@ class FinderTest < ActiveRecord::TestCase
668
856
  end
669
857
 
670
858
  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"
671
860
  with_env_tz 'America/New_York' do
672
861
  with_timezone_config default: :local do
673
862
  topic = Topic.first
@@ -677,6 +866,7 @@ class FinderTest < ActiveRecord::TestCase
677
866
  end
678
867
 
679
868
  def test_condition_local_time_interpolation_with_default_timezone_utc
869
+ puts "finder_test.test_condition_local_time_interpolation_with_default_timezone_utc"
680
870
  with_env_tz 'America/New_York' do
681
871
  with_timezone_config default: :utc do
682
872
  topic = Topic.first
@@ -686,6 +876,7 @@ class FinderTest < ActiveRecord::TestCase
686
876
  end
687
877
 
688
878
  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"
689
880
  with_env_tz 'America/New_York' do
690
881
  with_timezone_config default: :utc do
691
882
  topic = Topic.first
@@ -708,99 +899,25 @@ class FinderTest < ActiveRecord::TestCase
708
899
  end
709
900
 
710
901
  def test_bind_variables_with_quotes
902
+ puts "finder_test.test_bind_variables_with_quotes"
711
903
  Company.create("name" => "37signals' go'es agains")
712
904
  assert Company.where(["name = ?", "37signals' go'es agains"]).first
713
905
  end
714
906
 
715
907
  def test_named_bind_variables_with_quotes
908
+ puts "finder_test.test_named_bind_variables_with_quotes"
716
909
  Company.create("name" => "37signals' go'es agains")
717
910
  assert Company.where(["name = :name", {name: "37signals' go'es agains"}]).first
718
911
  end
719
912
 
720
- def test_bind_arity
721
- assert_nothing_raised { bind '' }
722
- assert_raise(ActiveRecord::PreparedStatementInvalid) { bind '', 1 }
723
-
724
- assert_raise(ActiveRecord::PreparedStatementInvalid) { bind '?' }
725
- assert_nothing_raised { bind '?', 1 }
726
- assert_raise(ActiveRecord::PreparedStatementInvalid) { bind '?', 1, 1 }
727
- end
728
-
729
913
  def test_named_bind_variables
730
- assert_equal '1', bind(':a', :a => 1) # ' ruby-mode
731
- assert_equal '1 1', bind(':a :a', :a => 1) # ' ruby-mode
732
-
733
- assert_nothing_raised { bind("'+00:00'", :foo => "bar") }
734
-
914
+ puts "finder_test.test_named_bind_variables"
735
915
  assert_kind_of Firm, Company.where(["name = :name", { name: "37signals" }]).first
736
916
  assert_nil Company.where(["name = :name", { name: "37signals!" }]).first
737
917
  assert_nil Company.where(["name = :name", { name: "37signals!' OR 1=1" }]).first
738
918
  assert_kind_of Time, Topic.where(["id = :id", { id: 1 }]).first.written_on
739
919
  end
740
920
 
741
- class SimpleEnumerable
742
- include Enumerable
743
-
744
- def initialize(ary)
745
- @ary = ary
746
- end
747
-
748
- def each(&b)
749
- @ary.each(&b)
750
- end
751
- end
752
-
753
- def test_bind_enumerable
754
- quoted_abc = %(#{ActiveRecord::Base.connection.quote('a')},#{ActiveRecord::Base.connection.quote('b')},#{ActiveRecord::Base.connection.quote('c')})
755
-
756
- assert_equal '1,2,3', bind('?', [1, 2, 3])
757
- assert_equal quoted_abc, bind('?', %w(a b c))
758
-
759
- assert_equal '1,2,3', bind(':a', :a => [1, 2, 3])
760
- assert_equal quoted_abc, bind(':a', :a => %w(a b c)) # '
761
-
762
- assert_equal '1,2,3', bind('?', SimpleEnumerable.new([1, 2, 3]))
763
- assert_equal quoted_abc, bind('?', SimpleEnumerable.new(%w(a b c)))
764
-
765
- assert_equal '1,2,3', bind(':a', :a => SimpleEnumerable.new([1, 2, 3]))
766
- assert_equal quoted_abc, bind(':a', :a => SimpleEnumerable.new(%w(a b c))) # '
767
- end
768
-
769
- def test_bind_empty_enumerable
770
- quoted_nil = ActiveRecord::Base.connection.quote(nil)
771
- assert_equal quoted_nil, bind('?', [])
772
- assert_equal " in (#{quoted_nil})", bind(' in (?)', [])
773
- assert_equal "foo in (#{quoted_nil})", bind('foo in (?)', [])
774
- end
775
-
776
- def test_bind_empty_string
777
- quoted_empty = ActiveRecord::Base.connection.quote('')
778
- assert_equal quoted_empty, bind('?', '')
779
- end
780
-
781
- def test_bind_chars
782
- quoted_bambi = ActiveRecord::Base.connection.quote("Bambi")
783
- quoted_bambi_and_thumper = ActiveRecord::Base.connection.quote("Bambi\nand\nThumper")
784
- assert_equal "name=#{quoted_bambi}", bind('name=?', "Bambi")
785
- assert_equal "name=#{quoted_bambi_and_thumper}", bind('name=?', "Bambi\nand\nThumper")
786
- assert_equal "name=#{quoted_bambi}", bind('name=?', "Bambi".mb_chars)
787
- assert_equal "name=#{quoted_bambi_and_thumper}", bind('name=?', "Bambi\nand\nThumper".mb_chars)
788
- end
789
-
790
- def test_bind_record
791
- o = Struct.new(:quoted_id).new(1)
792
- assert_equal '1', bind('?', o)
793
-
794
- os = [o] * 3
795
- assert_equal '1,1,1', bind('?', os)
796
- end
797
-
798
- def test_named_bind_with_postgresql_type_casts
799
- l = Proc.new { bind(":a::integer '2009-01-01'::date", :a => '10') }
800
- assert_nothing_raised(&l)
801
- assert_equal "#{ActiveRecord::Base.connection.quote('10')}::integer '2009-01-01'::date", l.call
802
- end
803
-
804
921
  def test_string_sanitation
805
922
  assert_not_equal "'something ' 1=1'", ActiveRecord::Base.sanitize("something ' 1=1")
806
923
  assert_equal "'something; select table'", ActiveRecord::Base.sanitize("something; select table")
@@ -825,6 +942,7 @@ class FinderTest < ActiveRecord::TestCase
825
942
  end
826
943
 
827
944
  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"
828
946
  dog_alias = 'Dog'
829
947
  dog = Dog.create(alias: dog_alias)
830
948
 
@@ -837,6 +955,7 @@ class FinderTest < ActiveRecord::TestCase
837
955
  end
838
956
 
839
957
  def test_find_by_one_attribute_bang_with_blank_defined
958
+ puts "finder_test.test_find_by_one_attribute_bang_with_blank_defined"
840
959
  blank_topic = BlankTopic.create(title: "The Blank One")
841
960
  assert_equal blank_topic, BlankTopic.find_by_title!("The Blank One")
842
961
  end
@@ -911,6 +1030,7 @@ class FinderTest < ActiveRecord::TestCase
911
1030
  end
912
1031
 
913
1032
  def test_find_last_with_offset
1033
+ puts "finder_test.test_find_last_with_offset"
914
1034
  devs = Developer.order('id')
915
1035
 
916
1036
  assert_equal devs[2], Developer.offset(2).first
@@ -939,7 +1059,7 @@ class FinderTest < ActiveRecord::TestCase
939
1059
  joins('LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id').
940
1060
  where('project_id=1').to_a
941
1061
  assert_equal 3, developers_on_project_one.length
942
- developer_names = developers_on_project_one.map { |d| d.name }
1062
+ developer_names = developers_on_project_one.map(&:name)
943
1063
  assert developer_names.include?('David')
944
1064
  assert developer_names.include?('Jamis')
945
1065
  end
@@ -965,8 +1085,8 @@ class FinderTest < ActiveRecord::TestCase
965
1085
  end
966
1086
  end
967
1087
 
968
- # http://dev.rubyonrails.org/ticket/6778
969
1088
  def test_find_ignores_previously_inserted_record
1089
+ puts "finder_test.test_find_ignores_previously_inserted_record"
970
1090
  Post.create!(:title => 'test', :body => 'it out')
971
1091
  assert_equal [], Post.where(id: nil)
972
1092
  end
@@ -980,6 +1100,7 @@ class FinderTest < ActiveRecord::TestCase
980
1100
  end
981
1101
 
982
1102
  def test_find_by_records
1103
+ puts "finder_test.test_find_by_records"
983
1104
  p1, p2 = Post.limit(2).order('id asc').to_a
984
1105
  assert_equal [p1, p2], Post.where(['id in (?)', [p1, p2]]).order('id asc')
985
1106
  assert_equal [p1, p2], Post.where(['id in (?)', [p1, p2.id]]).order('id asc')
@@ -994,7 +1115,7 @@ class FinderTest < ActiveRecord::TestCase
994
1115
  end
995
1116
 
996
1117
  def test_select_values
997
- 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! { |i| i.to_s }
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)
998
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")
999
1120
  end
1000
1121
 
@@ -1009,10 +1130,14 @@ class FinderTest < ActiveRecord::TestCase
1009
1130
  end
1010
1131
 
1011
1132
  def test_find_with_order_on_included_associations_with_construct_finder_sql_for_association_limiting_and_is_distinct
1012
- assert_equal 2, Post.includes(authors: :author_address).order('author_addresses.id DESC ').limit(2).to_a.size
1133
+ puts "finder_test.test_find_with_order_on_included_associations_with_construct_finder_sql_for_association_limiting_and_is_distinct"
1134
+ assert_equal 2, Post.includes(authors: :author_address).
1135
+ where.not(author_addresses: { id: nil }).
1136
+ order('author_addresses.id DESC').limit(2).to_a.size
1013
1137
 
1014
1138
  assert_equal 3, Post.includes(author: :author_address, authors: :author_address).
1015
- order('author_addresses_authors.id DESC ').limit(3).to_a.size
1139
+ where.not(author_addresses_authors: { id: nil }).
1140
+ order('author_addresses_authors.id DESC').limit(3).to_a.size
1016
1141
  end
1017
1142
 
1018
1143
  def test_find_with_nil_inside_set_passed_for_one_attribute
@@ -1020,7 +1145,7 @@ class FinderTest < ActiveRecord::TestCase
1020
1145
  where(client_of: [2, 1, nil],
1021
1146
  name: ['37signals', 'Summit', 'Microsoft']).
1022
1147
  order('client_of DESC').
1023
- map { |x| x.client_of }
1148
+ map(&:client_of)
1024
1149
 
1025
1150
  assert client_of.include?(nil)
1026
1151
  assert_equal [2, 1].sort, client_of.compact.sort
@@ -1030,12 +1155,13 @@ class FinderTest < ActiveRecord::TestCase
1030
1155
  client_of = Company.
1031
1156
  where(client_of: [nil]).
1032
1157
  order('client_of DESC').
1033
- map { |x| x.client_of }
1158
+ map(&:client_of)
1034
1159
 
1035
1160
  assert_equal [], client_of.compact
1036
1161
  end
1037
1162
 
1038
1163
  def test_with_limiting_with_custom_select
1164
+ puts "finder_test.test_with_limiting_with_custom_select"
1039
1165
  posts = Post.references(:authors).merge(
1040
1166
  :includes => :author, :select => 'posts.*, authors.id as "author_id"',
1041
1167
  :limit => 3, :order => 'posts.id'
@@ -1044,6 +1170,16 @@ class FinderTest < ActiveRecord::TestCase
1044
1170
  assert_equal [0, 1, 1], posts.map(&:author_id).sort
1045
1171
  end
1046
1172
 
1173
+ def test_find_one_message_on_primary_key
1174
+ e = assert_raises(ActiveRecord::RecordNotFound) do
1175
+ Car.find(0)
1176
+ end
1177
+ assert_equal 0, e.id
1178
+ assert_equal "id", e.primary_key
1179
+ assert_equal "Car", e.model
1180
+ assert_equal "Couldn't find Car with 'id'=0", e.message
1181
+ end
1182
+
1047
1183
  def test_find_one_message_with_custom_primary_key
1048
1184
  table_with_custom_primary_key do |model|
1049
1185
  model.primary_key = :name
@@ -1071,7 +1207,7 @@ class FinderTest < ActiveRecord::TestCase
1071
1207
  end
1072
1208
 
1073
1209
  def test_finder_with_offset_string
1074
- assert_nothing_raised(ActiveRecord::StatementInvalid) { Topic.offset("3").to_a }
1210
+ assert_nothing_raised { Topic.offset("3").to_a }
1075
1211
  end
1076
1212
 
1077
1213
  test "find_by with hash conditions returns the first matching record" do
@@ -1142,14 +1278,6 @@ class FinderTest < ActiveRecord::TestCase
1142
1278
  end
1143
1279
 
1144
1280
  protected
1145
- def bind(statement, *vars)
1146
- if vars.first.is_a?(Hash)
1147
- ActiveRecord::Base.send(:replace_named_bind_variables, statement, vars.first)
1148
- else
1149
- ActiveRecord::Base.send(:replace_bind_variables, statement, vars)
1150
- end
1151
- end
1152
-
1153
1281
  def table_with_custom_primary_key
1154
1282
  yield(Class.new(Toy) do
1155
1283
  def self.name