ibm_db 4.0.0-x86-mingw32 → 5.1.0-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (576) hide show
  1. checksums.yaml +5 -5
  2. data/MANIFEST +14 -14
  3. data/README +208 -208
  4. data/ext/Makefile +269 -0
  5. data/ext/Makefile.nt32 +181 -181
  6. data/ext/Makefile.nt32.191 +212 -212
  7. data/ext/extconf.rb +322 -291
  8. data/ext/gil_release_version.h +3 -0
  9. data/ext/ibm_db-i386-mingw32.def +2 -0
  10. data/ext/ibm_db.c +11879 -11887
  11. data/ext/ibm_db.o +0 -0
  12. data/ext/ibm_db.so +0 -0
  13. data/ext/mkmf.log +110 -0
  14. data/ext/ruby_ibm_db.h +241 -241
  15. data/ext/ruby_ibm_db_cli.c +866 -866
  16. data/ext/ruby_ibm_db_cli.h +500 -500
  17. data/ext/ruby_ibm_db_cli.o +0 -0
  18. data/ext/unicode_support_version.h +3 -0
  19. data/init.rb +41 -41
  20. data/lib/IBM_DB.rb +27 -27
  21. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3593 -3452
  22. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +5 -5
  23. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
  24. data/lib/mswin32/ibm_db.rb +94 -90
  25. data/lib/mswin32/rb2x/i386/ruby26/ibm_db.so +0 -0
  26. data/lib/mswin32/rb2x/i386/ruby27/ibm_db.so +0 -0
  27. data/test/active_record/connection_adapters/fake_adapter.rb +49 -49
  28. data/test/assets/example.log +1 -1
  29. data/test/assets/test.txt +1 -1
  30. data/test/cases/adapter_test.rb +351 -351
  31. data/test/cases/adapters/mysql2/active_schema_test.rb +193 -193
  32. data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -50
  33. data/test/cases/adapters/mysql2/boolean_test.rb +100 -100
  34. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -63
  35. data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -54
  36. data/test/cases/adapters/mysql2/connection_test.rb +210 -210
  37. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -45
  38. data/test/cases/adapters/mysql2/enum_test.rb +26 -26
  39. data/test/cases/adapters/mysql2/explain_test.rb +21 -21
  40. data/test/cases/adapters/mysql2/json_test.rb +195 -195
  41. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -83
  42. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -152
  43. data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -59
  44. data/test/cases/adapters/mysql2/schema_test.rb +126 -126
  45. data/test/cases/adapters/mysql2/sp_test.rb +36 -36
  46. data/test/cases/adapters/mysql2/sql_types_test.rb +14 -14
  47. data/test/cases/adapters/mysql2/table_options_test.rb +42 -42
  48. data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -66
  49. data/test/cases/adapters/postgresql/active_schema_test.rb +98 -98
  50. data/test/cases/adapters/postgresql/array_test.rb +339 -339
  51. data/test/cases/adapters/postgresql/bit_string_test.rb +82 -82
  52. data/test/cases/adapters/postgresql/bytea_test.rb +134 -134
  53. data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -26
  54. data/test/cases/adapters/postgresql/change_schema_test.rb +38 -38
  55. data/test/cases/adapters/postgresql/cidr_test.rb +25 -25
  56. data/test/cases/adapters/postgresql/citext_test.rb +78 -78
  57. data/test/cases/adapters/postgresql/collation_test.rb +53 -53
  58. data/test/cases/adapters/postgresql/composite_test.rb +132 -132
  59. data/test/cases/adapters/postgresql/connection_test.rb +257 -257
  60. data/test/cases/adapters/postgresql/datatype_test.rb +92 -92
  61. data/test/cases/adapters/postgresql/domain_test.rb +47 -47
  62. data/test/cases/adapters/postgresql/enum_test.rb +91 -91
  63. data/test/cases/adapters/postgresql/explain_test.rb +20 -20
  64. data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -63
  65. data/test/cases/adapters/postgresql/full_text_test.rb +44 -44
  66. data/test/cases/adapters/postgresql/geometric_test.rb +378 -378
  67. data/test/cases/adapters/postgresql/hstore_test.rb +382 -382
  68. data/test/cases/adapters/postgresql/infinity_test.rb +69 -69
  69. data/test/cases/adapters/postgresql/integer_test.rb +25 -25
  70. data/test/cases/adapters/postgresql/json_test.rb +237 -237
  71. data/test/cases/adapters/postgresql/ltree_test.rb +53 -53
  72. data/test/cases/adapters/postgresql/money_test.rb +96 -96
  73. data/test/cases/adapters/postgresql/network_test.rb +94 -94
  74. data/test/cases/adapters/postgresql/numbers_test.rb +49 -49
  75. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -405
  76. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -22
  77. data/test/cases/adapters/postgresql/quoting_test.rb +44 -44
  78. data/test/cases/adapters/postgresql/range_test.rb +343 -343
  79. data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -111
  80. data/test/cases/adapters/postgresql/rename_table_test.rb +34 -34
  81. data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -119
  82. data/test/cases/adapters/postgresql/schema_test.rb +597 -597
  83. data/test/cases/adapters/postgresql/serial_test.rb +154 -154
  84. data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -41
  85. data/test/cases/adapters/postgresql/timestamp_test.rb +90 -90
  86. data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -33
  87. data/test/cases/adapters/postgresql/utils_test.rb +62 -62
  88. data/test/cases/adapters/postgresql/uuid_test.rb +294 -294
  89. data/test/cases/adapters/postgresql/xml_test.rb +54 -54
  90. data/test/cases/adapters/sqlite3/collation_test.rb +53 -53
  91. data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -98
  92. data/test/cases/adapters/sqlite3/explain_test.rb +21 -21
  93. data/test/cases/adapters/sqlite3/quoting_test.rb +101 -101
  94. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -441
  95. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -24
  96. data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -20
  97. data/test/cases/aggregations_test.rb +168 -168
  98. data/test/cases/ar_schema_test.rb +146 -146
  99. data/test/cases/associations/association_scope_test.rb +16 -16
  100. data/test/cases/associations/belongs_to_associations_test.rb +1141 -1141
  101. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -41
  102. data/test/cases/associations/callbacks_test.rb +190 -190
  103. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  104. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  105. data/test/cases/associations/eager_load_nested_include_test.rb +126 -126
  106. data/test/cases/associations/eager_singularization_test.rb +148 -148
  107. data/test/cases/associations/eager_test.rb +1514 -1514
  108. data/test/cases/associations/extension_test.rb +87 -87
  109. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +1004 -1004
  110. data/test/cases/associations/has_many_associations_test.rb +2501 -2501
  111. data/test/cases/associations/has_many_through_associations_test.rb +1271 -1271
  112. data/test/cases/associations/has_one_associations_test.rb +707 -707
  113. data/test/cases/associations/has_one_through_associations_test.rb +383 -383
  114. data/test/cases/associations/inner_join_association_test.rb +139 -139
  115. data/test/cases/associations/inverse_associations_test.rb +733 -733
  116. data/test/cases/associations/join_model_test.rb +777 -777
  117. data/test/cases/associations/left_outer_join_association_test.rb +88 -88
  118. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  119. data/test/cases/associations/required_test.rb +102 -102
  120. data/test/cases/associations_test.rb +385 -385
  121. data/test/cases/attribute_decorators_test.rb +126 -125
  122. data/test/cases/attribute_methods/read_test.rb +60 -60
  123. data/test/cases/attribute_methods_test.rb +1009 -1009
  124. data/test/cases/attribute_set_test.rb +270 -270
  125. data/test/cases/attribute_test.rb +246 -246
  126. data/test/cases/attributes_test.rb +253 -253
  127. data/test/cases/autosave_association_test.rb +1708 -1708
  128. data/test/cases/base_test.rb +1713 -1713
  129. data/test/cases/batches_test.rb +489 -489
  130. data/test/cases/binary_test.rb +44 -44
  131. data/test/cases/bind_parameter_test.rb +110 -110
  132. data/test/cases/cache_key_test.rb +26 -25
  133. data/test/cases/calculations_test.rb +798 -798
  134. data/test/cases/callbacks_test.rb +636 -636
  135. data/test/cases/clone_test.rb +40 -40
  136. data/test/cases/coders/json_test.rb +15 -15
  137. data/test/cases/coders/yaml_column_test.rb +63 -63
  138. data/test/cases/collection_cache_key_test.rb +115 -115
  139. data/test/cases/column_alias_test.rb +17 -17
  140. data/test/cases/column_definition_test.rb +92 -92
  141. data/test/cases/comment_test.rb +145 -143
  142. data/test/cases/connection_adapters/adapter_leasing_test.rb +56 -56
  143. data/test/cases/connection_adapters/connection_handler_test.rb +160 -160
  144. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  145. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +255 -255
  146. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +69 -69
  147. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  148. data/test/cases/connection_adapters/schema_cache_test.rb +61 -61
  149. data/test/cases/connection_adapters/type_lookup_test.rb +118 -118
  150. data/test/cases/connection_management_test.rb +112 -112
  151. data/test/cases/connection_pool_test.rb +521 -521
  152. data/test/cases/connection_specification/resolver_test.rb +131 -131
  153. data/test/cases/core_test.rb +112 -112
  154. data/test/cases/counter_cache_test.rb +214 -214
  155. data/test/cases/custom_locking_test.rb +17 -17
  156. data/test/cases/database_statements_test.rb +34 -34
  157. data/test/cases/date_test.rb +44 -44
  158. data/test/cases/date_time_precision_test.rb +107 -106
  159. data/test/cases/date_time_test.rb +61 -61
  160. data/test/cases/defaults_test.rb +219 -218
  161. data/test/cases/dirty_test.rb +763 -763
  162. data/test/cases/disconnected_test.rb +30 -30
  163. data/test/cases/dup_test.rb +157 -157
  164. data/test/cases/enum_test.rb +444 -444
  165. data/test/cases/errors_test.rb +16 -16
  166. data/test/cases/explain_subscriber_test.rb +64 -64
  167. data/test/cases/explain_test.rb +87 -87
  168. data/test/cases/finder_respond_to_test.rb +60 -60
  169. data/test/cases/finder_test.rb +1294 -1294
  170. data/test/cases/fixture_set/file_test.rb +156 -156
  171. data/test/cases/fixtures_test.rb +988 -988
  172. data/test/cases/forbidden_attributes_protection_test.rb +165 -165
  173. data/test/cases/habtm_destroy_order_test.rb +61 -61
  174. data/test/cases/helper.rb +204 -204
  175. data/test/cases/hot_compatibility_test.rb +142 -142
  176. data/test/cases/i18n_test.rb +45 -45
  177. data/test/cases/inheritance_test.rb +606 -606
  178. data/test/cases/integration_test.rb +155 -155
  179. data/test/cases/invalid_connection_test.rb +24 -24
  180. data/test/cases/invertible_migration_test.rb +387 -387
  181. data/test/cases/json_serialization_test.rb +311 -311
  182. data/test/cases/locking_test.rb +493 -493
  183. data/test/cases/log_subscriber_test.rb +225 -225
  184. data/test/cases/migration/change_schema_test.rb +458 -458
  185. data/test/cases/migration/change_table_test.rb +256 -256
  186. data/test/cases/migration/column_attributes_test.rb +176 -176
  187. data/test/cases/migration/column_positioning_test.rb +56 -56
  188. data/test/cases/migration/columns_test.rb +310 -310
  189. data/test/cases/migration/command_recorder_test.rb +350 -350
  190. data/test/cases/migration/compatibility_test.rb +118 -118
  191. data/test/cases/migration/create_join_table_test.rb +157 -157
  192. data/test/cases/migration/foreign_key_test.rb +362 -360
  193. data/test/cases/migration/helper.rb +39 -39
  194. data/test/cases/migration/index_test.rb +218 -218
  195. data/test/cases/migration/logger_test.rb +36 -36
  196. data/test/cases/migration/pending_migrations_test.rb +52 -52
  197. data/test/cases/migration/references_foreign_key_test.rb +221 -216
  198. data/test/cases/migration/references_index_test.rb +101 -101
  199. data/test/cases/migration/references_statements_test.rb +136 -136
  200. data/test/cases/migration/rename_table_test.rb +93 -93
  201. data/test/cases/migration_test.rb +1157 -1157
  202. data/test/cases/migrator_test.rb +471 -470
  203. data/test/cases/mixin_test.rb +68 -68
  204. data/test/cases/modules_test.rb +172 -172
  205. data/test/cases/multiparameter_attributes_test.rb +372 -372
  206. data/test/cases/multiple_db_test.rb +122 -122
  207. data/test/cases/nested_attributes_test.rb +1098 -1098
  208. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  209. data/test/cases/persistence_test.rb +1001 -1001
  210. data/test/cases/pooled_connections_test.rb +81 -81
  211. data/test/cases/primary_keys_test.rb +376 -376
  212. data/test/cases/query_cache_test.rb +446 -446
  213. data/test/cases/quoting_test.rb +202 -202
  214. data/test/cases/readonly_test.rb +119 -119
  215. data/test/cases/reaper_test.rb +85 -85
  216. data/test/cases/reflection_test.rb +509 -509
  217. data/test/cases/relation/delegation_test.rb +63 -63
  218. data/test/cases/relation/merging_test.rb +157 -157
  219. data/test/cases/relation/mutation_test.rb +183 -183
  220. data/test/cases/relation/or_test.rb +92 -92
  221. data/test/cases/relation/predicate_builder_test.rb +16 -16
  222. data/test/cases/relation/record_fetch_warning_test.rb +40 -40
  223. data/test/cases/relation/where_chain_test.rb +105 -105
  224. data/test/cases/relation/where_clause_test.rb +182 -182
  225. data/test/cases/relation/where_test.rb +322 -322
  226. data/test/cases/relation_test.rb +328 -328
  227. data/test/cases/relations_test.rb +2026 -2026
  228. data/test/cases/reload_models_test.rb +22 -22
  229. data/test/cases/result_test.rb +90 -90
  230. data/test/cases/sanitize_test.rb +176 -176
  231. data/test/cases/schema_dumper_test.rb +457 -457
  232. data/test/cases/schema_loading_test.rb +52 -52
  233. data/test/cases/scoping/default_scoping_test.rb +528 -528
  234. data/test/cases/scoping/named_scoping_test.rb +561 -561
  235. data/test/cases/scoping/relation_scoping_test.rb +400 -400
  236. data/test/cases/secure_token_test.rb +32 -32
  237. data/test/cases/serialization_test.rb +104 -104
  238. data/test/cases/serialized_attribute_test.rb +364 -364
  239. data/test/cases/statement_cache_test.rb +136 -136
  240. data/test/cases/store_test.rb +195 -195
  241. data/test/cases/suppressor_test.rb +63 -63
  242. data/test/cases/tasks/database_tasks_test.rb +462 -462
  243. data/test/cases/tasks/mysql_rake_test.rb +345 -345
  244. data/test/cases/tasks/postgresql_rake_test.rb +304 -304
  245. data/test/cases/tasks/sqlite_rake_test.rb +220 -220
  246. data/test/cases/test_case.rb +131 -131
  247. data/test/cases/test_fixtures_test.rb +36 -36
  248. data/test/cases/time_precision_test.rb +103 -102
  249. data/test/cases/timestamp_test.rb +501 -501
  250. data/test/cases/touch_later_test.rb +121 -121
  251. data/test/cases/transaction_callbacks_test.rb +518 -518
  252. data/test/cases/transaction_isolation_test.rb +106 -106
  253. data/test/cases/transactions_test.rb +835 -834
  254. data/test/cases/type/adapter_specific_registry_test.rb +133 -133
  255. data/test/cases/type/date_time_test.rb +14 -14
  256. data/test/cases/type/integer_test.rb +27 -27
  257. data/test/cases/type/string_test.rb +22 -22
  258. data/test/cases/type/type_map_test.rb +177 -177
  259. data/test/cases/type_test.rb +39 -39
  260. data/test/cases/types_test.rb +24 -24
  261. data/test/cases/unconnected_test.rb +33 -33
  262. data/test/cases/validations/absence_validation_test.rb +73 -73
  263. data/test/cases/validations/association_validation_test.rb +97 -97
  264. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  265. data/test/cases/validations/i18n_validation_test.rb +86 -86
  266. data/test/cases/validations/length_validation_test.rb +79 -79
  267. data/test/cases/validations/presence_validation_test.rb +103 -103
  268. data/test/cases/validations/uniqueness_validation_test.rb +548 -548
  269. data/test/cases/validations_repair_helper.rb +19 -19
  270. data/test/cases/validations_test.rb +194 -194
  271. data/test/cases/view_test.rb +216 -216
  272. data/test/cases/yaml_serialization_test.rb +121 -121
  273. data/test/config.example.yml +97 -97
  274. data/test/config.rb +5 -5
  275. data/test/connections/native_ibm_db/connection.rb +44 -0
  276. data/test/fixtures/accounts.yml +29 -29
  277. data/test/fixtures/admin/accounts.yml +2 -2
  278. data/test/fixtures/admin/users.yml +10 -10
  279. data/test/fixtures/author_addresses.yml +17 -17
  280. data/test/fixtures/author_favorites.yml +3 -3
  281. data/test/fixtures/authors.yml +23 -23
  282. data/test/fixtures/bad_posts.yml +9 -9
  283. data/test/fixtures/binaries.yml +133 -133
  284. data/test/fixtures/books.yml +31 -31
  285. data/test/fixtures/bulbs.yml +5 -5
  286. data/test/fixtures/cars.yml +9 -9
  287. data/test/fixtures/categories.yml +19 -19
  288. data/test/fixtures/categories/special_categories.yml +9 -9
  289. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  290. data/test/fixtures/categories_ordered.yml +7 -7
  291. data/test/fixtures/categories_posts.yml +31 -31
  292. data/test/fixtures/categorizations.yml +23 -23
  293. data/test/fixtures/clubs.yml +8 -8
  294. data/test/fixtures/collections.yml +3 -3
  295. data/test/fixtures/colleges.yml +3 -3
  296. data/test/fixtures/comments.yml +65 -65
  297. data/test/fixtures/companies.yml +67 -67
  298. data/test/fixtures/computers.yml +10 -10
  299. data/test/fixtures/content.yml +3 -3
  300. data/test/fixtures/content_positions.yml +3 -3
  301. data/test/fixtures/courses.yml +8 -8
  302. data/test/fixtures/customers.yml +25 -25
  303. data/test/fixtures/dashboards.yml +6 -6
  304. data/test/fixtures/dead_parrots.yml +5 -5
  305. data/test/fixtures/developers.yml +22 -22
  306. data/test/fixtures/developers_projects.yml +16 -16
  307. data/test/fixtures/dog_lovers.yml +7 -7
  308. data/test/fixtures/dogs.yml +4 -4
  309. data/test/fixtures/doubloons.yml +3 -3
  310. data/test/fixtures/edges.yml +5 -5
  311. data/test/fixtures/entrants.yml +14 -14
  312. data/test/fixtures/essays.yml +6 -6
  313. data/test/fixtures/faces.yml +11 -11
  314. data/test/fixtures/fk_test_has_fk.yml +3 -3
  315. data/test/fixtures/fk_test_has_pk.yml +1 -1
  316. data/test/fixtures/friendships.yml +4 -4
  317. data/test/fixtures/funny_jokes.yml +10 -10
  318. data/test/fixtures/interests.yml +33 -33
  319. data/test/fixtures/items.yml +3 -3
  320. data/test/fixtures/jobs.yml +7 -7
  321. data/test/fixtures/legacy_things.yml +3 -3
  322. data/test/fixtures/live_parrots.yml +4 -4
  323. data/test/fixtures/mateys.yml +4 -4
  324. data/test/fixtures/member_details.yml +8 -8
  325. data/test/fixtures/member_types.yml +6 -6
  326. data/test/fixtures/members.yml +11 -11
  327. data/test/fixtures/memberships.yml +34 -34
  328. data/test/fixtures/men.yml +5 -5
  329. data/test/fixtures/minimalistics.yml +2 -2
  330. data/test/fixtures/minivans.yml +5 -5
  331. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  332. data/test/fixtures/mixins.yml +29 -29
  333. data/test/fixtures/movies.yml +7 -7
  334. data/test/fixtures/naked/yml/accounts.yml +1 -1
  335. data/test/fixtures/naked/yml/companies.yml +1 -1
  336. data/test/fixtures/naked/yml/courses.yml +1 -1
  337. data/test/fixtures/naked/yml/parrots.yml +2 -2
  338. data/test/fixtures/naked/yml/trees.yml +3 -3
  339. data/test/fixtures/nodes.yml +29 -29
  340. data/test/fixtures/organizations.yml +5 -5
  341. data/test/fixtures/other_comments.yml +6 -6
  342. data/test/fixtures/other_dogs.yml +2 -2
  343. data/test/fixtures/other_posts.yml +7 -7
  344. data/test/fixtures/other_topics.yml +42 -42
  345. data/test/fixtures/owners.yml +9 -9
  346. data/test/fixtures/parrots.yml +27 -27
  347. data/test/fixtures/parrots_pirates.yml +7 -7
  348. data/test/fixtures/people.yml +24 -24
  349. data/test/fixtures/peoples_treasures.yml +3 -3
  350. data/test/fixtures/pets.yml +19 -19
  351. data/test/fixtures/pirates.yml +12 -15
  352. data/test/fixtures/posts.yml +80 -80
  353. data/test/fixtures/price_estimates.yml +16 -16
  354. data/test/fixtures/products.yml +4 -4
  355. data/test/fixtures/projects.yml +7 -7
  356. data/test/fixtures/ratings.yml +14 -14
  357. data/test/fixtures/readers.yml +11 -11
  358. data/test/fixtures/references.yml +17 -17
  359. data/test/fixtures/reserved_words/distinct.yml +5 -5
  360. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  361. data/test/fixtures/reserved_words/group.yml +14 -14
  362. data/test/fixtures/reserved_words/select.yml +8 -8
  363. data/test/fixtures/reserved_words/values.yml +7 -7
  364. data/test/fixtures/ships.yml +6 -6
  365. data/test/fixtures/speedometers.yml +8 -8
  366. data/test/fixtures/sponsors.yml +12 -12
  367. data/test/fixtures/string_key_objects.yml +7 -7
  368. data/test/fixtures/subscribers.yml +10 -10
  369. data/test/fixtures/subscriptions.yml +12 -12
  370. data/test/fixtures/taggings.yml +78 -78
  371. data/test/fixtures/tags.yml +11 -11
  372. data/test/fixtures/tasks.yml +7 -7
  373. data/test/fixtures/teapots.yml +3 -3
  374. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  375. data/test/fixtures/to_be_linked/users.yml +10 -10
  376. data/test/fixtures/topics.yml +49 -49
  377. data/test/fixtures/toys.yml +14 -14
  378. data/test/fixtures/traffic_lights.yml +9 -9
  379. data/test/fixtures/treasures.yml +10 -10
  380. data/test/fixtures/trees.yml +3 -3
  381. data/test/fixtures/uuid_children.yml +3 -3
  382. data/test/fixtures/uuid_parents.yml +2 -2
  383. data/test/fixtures/variants.yml +4 -4
  384. data/test/fixtures/vegetables.yml +19 -19
  385. data/test/fixtures/vertices.yml +3 -3
  386. data/test/fixtures/warehouse_things.yml +2 -2
  387. data/test/fixtures/zines.yml +5 -5
  388. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  389. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  390. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  391. data/test/migrations/missing/1000_people_have_middle_names.rb +9 -9
  392. data/test/migrations/missing/1_people_have_last_names.rb +9 -9
  393. data/test/migrations/missing/3_we_need_reminders.rb +12 -12
  394. data/test/migrations/missing/4_innocent_jointable.rb +12 -12
  395. data/test/migrations/rename/1_we_need_things.rb +11 -11
  396. data/test/migrations/rename/2_rename_things.rb +9 -9
  397. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  398. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  399. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  400. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  401. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  402. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  403. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  404. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  405. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  406. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  407. data/test/migrations/valid/2_we_need_reminders.rb +12 -12
  408. data/test/migrations/valid/3_innocent_jointable.rb +12 -12
  409. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  410. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +12 -12
  411. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +12 -12
  412. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  413. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  414. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  415. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  416. data/test/models/admin.rb +5 -5
  417. data/test/models/admin/account.rb +3 -3
  418. data/test/models/admin/user.rb +40 -40
  419. data/test/models/aircraft.rb +5 -5
  420. data/test/models/arunit2_model.rb +3 -3
  421. data/test/models/author.rb +209 -209
  422. data/test/models/auto_id.rb +4 -4
  423. data/test/models/autoloadable/extra_firm.rb +2 -2
  424. data/test/models/binary.rb +2 -2
  425. data/test/models/bird.rb +12 -12
  426. data/test/models/book.rb +23 -23
  427. data/test/models/boolean.rb +2 -2
  428. data/test/models/bulb.rb +52 -52
  429. data/test/models/cake_designer.rb +3 -3
  430. data/test/models/car.rb +29 -29
  431. data/test/models/carrier.rb +2 -2
  432. data/test/models/cat.rb +10 -10
  433. data/test/models/categorization.rb +19 -19
  434. data/test/models/category.rb +35 -35
  435. data/test/models/chef.rb +8 -8
  436. data/test/models/citation.rb +3 -3
  437. data/test/models/club.rb +25 -25
  438. data/test/models/college.rb +10 -10
  439. data/test/models/column.rb +3 -3
  440. data/test/models/column_name.rb +3 -3
  441. data/test/models/comment.rb +76 -76
  442. data/test/models/company.rb +230 -230
  443. data/test/models/company_in_module.rb +98 -98
  444. data/test/models/computer.rb +3 -3
  445. data/test/models/contact.rb +41 -41
  446. data/test/models/content.rb +40 -40
  447. data/test/models/contract.rb +20 -20
  448. data/test/models/country.rb +7 -7
  449. data/test/models/course.rb +6 -6
  450. data/test/models/customer.rb +83 -83
  451. data/test/models/customer_carrier.rb +14 -14
  452. data/test/models/dashboard.rb +3 -3
  453. data/test/models/default.rb +2 -2
  454. data/test/models/department.rb +4 -4
  455. data/test/models/developer.rb +274 -274
  456. data/test/models/dog.rb +5 -5
  457. data/test/models/dog_lover.rb +5 -5
  458. data/test/models/doubloon.rb +12 -12
  459. data/test/models/drink_designer.rb +3 -3
  460. data/test/models/edge.rb +5 -5
  461. data/test/models/electron.rb +5 -5
  462. data/test/models/engine.rb +4 -4
  463. data/test/models/entrant.rb +3 -3
  464. data/test/models/essay.rb +5 -5
  465. data/test/models/event.rb +3 -3
  466. data/test/models/eye.rb +37 -37
  467. data/test/models/face.rb +9 -9
  468. data/test/models/friendship.rb +6 -6
  469. data/test/models/guid.rb +2 -2
  470. data/test/models/guitar.rb +4 -4
  471. data/test/models/hotel.rb +11 -11
  472. data/test/models/image.rb +3 -3
  473. data/test/models/interest.rb +5 -5
  474. data/test/models/invoice.rb +4 -4
  475. data/test/models/item.rb +7 -7
  476. data/test/models/job.rb +7 -7
  477. data/test/models/joke.rb +7 -7
  478. data/test/models/keyboard.rb +3 -3
  479. data/test/models/legacy_thing.rb +3 -3
  480. data/test/models/lesson.rb +11 -11
  481. data/test/models/line_item.rb +3 -3
  482. data/test/models/liquid.rb +4 -4
  483. data/test/models/man.rb +11 -11
  484. data/test/models/matey.rb +4 -4
  485. data/test/models/member.rb +42 -42
  486. data/test/models/member_detail.rb +8 -8
  487. data/test/models/member_type.rb +3 -3
  488. data/test/models/membership.rb +35 -35
  489. data/test/models/mentor.rb +2 -2
  490. data/test/models/minimalistic.rb +2 -2
  491. data/test/models/minivan.rb +9 -9
  492. data/test/models/mixed_case_monkey.rb +3 -3
  493. data/test/models/mocktail_designer.rb +2 -2
  494. data/test/models/molecule.rb +6 -6
  495. data/test/models/movie.rb +5 -5
  496. data/test/models/node.rb +5 -5
  497. data/test/models/non_primary_key.rb +2 -2
  498. data/test/models/notification.rb +3 -3
  499. data/test/models/order.rb +4 -4
  500. data/test/models/organization.rb +14 -14
  501. data/test/models/other_dog.rb +5 -5
  502. data/test/models/owner.rb +37 -37
  503. data/test/models/parrot.rb +28 -28
  504. data/test/models/person.rb +142 -142
  505. data/test/models/personal_legacy_thing.rb +4 -4
  506. data/test/models/pet.rb +18 -18
  507. data/test/models/pet_treasure.rb +6 -6
  508. data/test/models/pirate.rb +92 -92
  509. data/test/models/possession.rb +3 -3
  510. data/test/models/post.rb +273 -273
  511. data/test/models/price_estimate.rb +4 -4
  512. data/test/models/professor.rb +5 -5
  513. data/test/models/project.rb +40 -40
  514. data/test/models/publisher.rb +2 -2
  515. data/test/models/publisher/article.rb +4 -4
  516. data/test/models/publisher/magazine.rb +3 -3
  517. data/test/models/rating.rb +4 -4
  518. data/test/models/reader.rb +23 -23
  519. data/test/models/recipe.rb +3 -3
  520. data/test/models/record.rb +2 -2
  521. data/test/models/reference.rb +22 -22
  522. data/test/models/reply.rb +61 -61
  523. data/test/models/ship.rb +39 -39
  524. data/test/models/ship_part.rb +8 -8
  525. data/test/models/shop.rb +17 -17
  526. data/test/models/shop_account.rb +6 -6
  527. data/test/models/speedometer.rb +6 -6
  528. data/test/models/sponsor.rb +7 -7
  529. data/test/models/string_key_object.rb +3 -3
  530. data/test/models/student.rb +4 -4
  531. data/test/models/subject.rb +16 -16
  532. data/test/models/subscriber.rb +8 -8
  533. data/test/models/subscription.rb +4 -4
  534. data/test/models/tag.rb +13 -13
  535. data/test/models/tagging.rb +13 -13
  536. data/test/models/task.rb +5 -5
  537. data/test/models/topic.rb +118 -118
  538. data/test/models/toy.rb +6 -6
  539. data/test/models/traffic_light.rb +4 -4
  540. data/test/models/treasure.rb +14 -14
  541. data/test/models/treaty.rb +7 -7
  542. data/test/models/tree.rb +3 -3
  543. data/test/models/tuning_peg.rb +4 -4
  544. data/test/models/tyre.rb +11 -11
  545. data/test/models/user.rb +14 -14
  546. data/test/models/uuid_child.rb +3 -3
  547. data/test/models/uuid_item.rb +6 -6
  548. data/test/models/uuid_parent.rb +3 -3
  549. data/test/models/vegetables.rb +24 -24
  550. data/test/models/vehicle.rb +6 -6
  551. data/test/models/vertex.rb +9 -9
  552. data/test/models/warehouse_thing.rb +5 -5
  553. data/test/models/wheel.rb +3 -3
  554. data/test/models/without_table.rb +3 -3
  555. data/test/models/zine.rb +3 -3
  556. data/test/schema/i5/ibm_db_specific_schema.rb +137 -0
  557. data/test/schema/ids/ibm_db_specific_schema.rb +140 -0
  558. data/test/schema/luw/ibm_db_specific_schema.rb +137 -0
  559. data/test/schema/mysql2_specific_schema.rb +68 -68
  560. data/test/schema/oracle_specific_schema.rb +40 -40
  561. data/test/schema/postgresql_specific_schema.rb +114 -114
  562. data/test/schema/schema.rb +1057 -1057
  563. data/test/schema/schema.rb.original +1057 -1057
  564. data/test/schema/sqlite_specific_schema.rb +18 -18
  565. data/test/schema/zOS/ibm_db_specific_schema.rb +208 -0
  566. data/test/support/config.rb +43 -43
  567. data/test/support/connection.rb +23 -23
  568. data/test/support/connection_helper.rb +14 -14
  569. data/test/support/ddl_helper.rb +8 -8
  570. data/test/support/schema_dumping_helper.rb +20 -20
  571. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -22
  572. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -182
  573. metadata +30 -14
  574. data/lib/mswin32/rb2x/i386/ibm_db.so +0 -0
  575. data/test/fixtures/author_addresses.original +0 -11
  576. data/test/fixtures/authors.original +0 -17
@@ -1,1294 +1,1294 @@
1
- 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'
20
-
21
- class FinderTest < ActiveRecord::TestCase
22
- fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :author_addresses, :customers, :categories, :categorizations, :cars
23
-
24
- def test_find_by_id_with_hash
25
- assert_raises(ActiveRecord::StatementInvalid) do
26
- Post.find_by_id(:limit => 1)
27
- end
28
- end
29
-
30
- 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)
33
- end
34
- end
35
-
36
- def test_find
37
- assert_equal(topics(:first).title, Topic.find(1).title)
38
- end
39
-
40
- def test_find_with_proc_parameter_and_block
41
- exception = assert_raises(RuntimeError) do
42
- Topic.all.find(-> { raise "should happen" }) { |e| e.title == "non-existing-title" }
43
- end
44
- assert_equal "should happen", exception.message
45
-
46
- assert_nothing_raised do
47
- Topic.all.find(-> { raise "should not happen" }) { |e| e.title == topics(:first).title }
48
- end
49
- end
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
-
122
- def test_find_passing_active_record_object_is_deprecated
123
- assert_deprecated do
124
- Topic.find(Topic.last)
125
- end
126
- end
127
-
128
- def test_symbols_table_ref
129
- gc_disabled = GC.disable
130
- Post.where("author_id" => nil) # warm up
131
- x = Symbol.all_symbols.count
132
- Post.where("title" => {"xxxqqqq" => "bar"})
133
- assert_equal x, Symbol.all_symbols.count
134
- ensure
135
- GC.enable if gc_disabled == false
136
- end
137
-
138
- # find should handle strings that come from URLs
139
- # (example: Category.find(params[:id]))
140
- def test_find_with_string
141
- assert_equal(Topic.find(1).title,Topic.find("1").title)
142
- end
143
-
144
- def test_exists
145
- assert_equal true, Topic.exists?(1)
146
- assert_equal true, Topic.exists?("1")
147
- assert_equal true, Topic.exists?(title: "The First Topic")
148
- assert_equal true, Topic.exists?(heading: "The First Topic")
149
- assert_equal true, Topic.exists?(:author_name => "Mary", :approved => true)
150
- assert_equal true, Topic.exists?(["parent_id = ?", 1])
151
- assert_equal true, Topic.exists?(id: [1, 9999])
152
-
153
- assert_equal false, Topic.exists?(45)
154
- assert_equal false, Topic.exists?(Topic.new.id)
155
-
156
- assert_raise(NoMethodError) { Topic.exists?([1,2]) }
157
- end
158
-
159
- 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')
163
-
164
- assert_equal true, relation.exists?(title: ['Post'])
165
- assert_equal true, relation.exists?(['title LIKE ?', 'Post%'])
166
- assert_equal true, relation.exists?
167
- assert_equal true, relation.exists?(post.id)
168
- assert_equal true, relation.exists?(post.id.to_s)
169
-
170
- assert_equal false, relation.exists?(false)
171
- end
172
-
173
- def test_exists_passing_active_record_object_is_deprecated
174
- assert_deprecated do
175
- Topic.exists?(Topic.new)
176
- end
177
- end
178
-
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
183
- end
184
- assert_equal false, Topic.exists?("foo")
185
- end
186
-
187
- 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
190
- Topic.exists?
191
- end
192
- end
193
-
194
- def test_exists_returns_true_with_one_record_and_no_args
195
- assert_equal true, Topic.exists?
196
- end
197
-
198
- def test_exists_returns_false_with_false_arg
199
- assert_equal false, Topic.exists?(false)
200
- end
201
-
202
- # exists? should handle nil for id's that come from URLs and always return false
203
- # (example: Topic.exists?(params[:id])) where params[:id] is nil
204
- def test_exists_with_nil_arg
205
- assert_equal false, Topic.exists?(nil)
206
- assert_equal true, Topic.exists?
207
-
208
- assert_equal false, Topic.first.replies.exists?(nil)
209
- assert_equal true, Topic.first.replies.exists?
210
- end
211
-
212
- # ensures +exists?+ runs valid SQL by excluding order value
213
- def test_exists_with_order
214
- assert_equal true, Topic.order(:id).distinct.exists?
215
- end
216
-
217
- 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?
221
- end
222
-
223
- def test_exists_with_distinct_association_includes_and_limit
224
- puts "finder_test.test_exists_with_distinct_association_includes_and_limit"
225
- 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?
228
- end
229
-
230
- def test_exists_with_distinct_association_includes_limit_and_order
231
- puts "finder_test.test_exists_with_distinct_association_includes_limit_and_order"
232
- 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?
235
- end
236
-
237
- def test_exists_with_empty_table_and_no_args_given
238
- Topic.delete_all
239
- assert_equal false, Topic.exists?
240
- end
241
-
242
- def test_exists_with_aggregate_having_three_mappings
243
- existing_address = customers(:david).address
244
- assert_equal true, Customer.exists?(:address => existing_address)
245
- end
246
-
247
- def test_exists_with_aggregate_having_three_mappings_with_one_difference
248
- 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))
255
- end
256
-
257
- def test_exists_does_not_instantiate_records
258
- assert_not_called(Developer, :instantiate) do
259
- Developer.exists?
260
- end
261
- end
262
-
263
- def test_find_by_array_of_one_id
264
- assert_kind_of(Array, Topic.find([ 1 ]))
265
- assert_equal(1, Topic.find([ 1 ]).length)
266
- end
267
-
268
- def test_find_by_ids
269
- assert_equal 2, Topic.find(1, 2).size
270
- assert_equal topics(:second).title, Topic.find([2]).first.title
271
- end
272
-
273
- 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])
276
- assert_equal 1, entrants.size
277
- assert_equal 'Ruby Guru', entrants.first.name
278
-
279
- # Also test an edge case: If you have 11 results, and you set a
280
- # limit of 3 and offset of 9, then you should find that there
281
- # will be only 2 results, regardless of the limit.
282
- devs = Developer.all
283
- last_devs = Developer.limit(3).offset(9).find devs.map(&:id)
284
- assert_equal 2, last_devs.size
285
- assert_equal 'fixture_10', last_devs[0].name
286
- assert_equal 'Jamis', last_devs[1].name
287
- end
288
-
289
- unless current_adapter?(:IBM_DBAdapter)
290
- def test_find_with_large_number
291
- assert_raises(ActiveRecord::RecordNotFound) { Topic.find('9999999999999999999999999999999') }
292
- end
293
-
294
- def test_find_by_with_large_number
295
- assert_nil Topic.find_by(id: '9999999999999999999999999999999')
296
- end
297
-
298
- def test_find_by_id_with_large_number
299
- assert_nil Topic.find_by_id('9999999999999999999999999999999')
300
- end
301
-
302
- def test_find_on_relation_with_large_number
303
- assert_nil Topic.where('1=1').find_by(id: 9999999999999999999999999999999)
304
- end
305
-
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
311
- end
312
-
313
- def test_find_an_empty_array
314
- assert_equal [], Topic.find([])
315
- end
316
-
317
- def test_find_doesnt_have_implicit_ordering
318
- assert_sql(/^((?!ORDER).)*$/) { Topic.find(1) }
319
- end
320
-
321
- def test_find_by_ids_missing_one
322
- assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1, 2, 45) }
323
- end
324
-
325
- def test_find_with_group_and_sanitized_having_method
326
- developers = Developer.group(:salary).having("sum(salary) > ?", 10000).select('salary').to_a
327
- assert_equal 3, developers.size
328
- assert_equal 3, developers.map(&:salary).uniq.size
329
- assert developers.all? { |developer| developer.salary > 10000 }
330
- end
331
-
332
- def test_find_with_entire_select_statement
333
- topics = Topic.find_by_sql "SELECT * FROM topics WHERE author_name = 'Mary'"
334
-
335
- assert_equal(1, topics.size)
336
- assert_equal(topics(:second).title, topics.first.title)
337
- end
338
-
339
- def test_find_with_prepared_select_statement
340
- topics = Topic.find_by_sql ["SELECT * FROM topics WHERE author_name = ?", "Mary"]
341
-
342
- assert_equal(1, topics.size)
343
- assert_equal(topics(:second).title, topics.first.title)
344
- end
345
-
346
- def test_find_by_sql_with_sti_on_joined_table
347
- accounts = Account.find_by_sql("SELECT * FROM accounts INNER JOIN companies ON companies.id = accounts.firm_id")
348
- assert_equal [Account], accounts.collect(&:class).uniq
349
- end
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
-
362
- def test_take
363
- assert_equal topics(:first), Topic.take
364
- end
365
-
366
- def test_take_failing
367
- assert_nil Topic.where("title = 'This title does not exist'").take
368
- end
369
-
370
- def test_take_bang_present
371
- assert_nothing_raised do
372
- assert_equal topics(:second), Topic.where("title = 'The Second Topic of the day'").take!
373
- end
374
- end
375
-
376
- def test_take_bang_missing
377
- assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
378
- Topic.where("title = 'This title does not exist'").take!
379
- end
380
- end
381
-
382
- def test_first
383
- assert_equal topics(:second).title, Topic.where("title = 'The Second Topic of the day'").first.title
384
- end
385
-
386
- def test_first_failing
387
- assert_nil Topic.where("title = 'The Second Topic of the day!'").first
388
- end
389
-
390
- def test_first_bang_present
391
- assert_nothing_raised do
392
- assert_equal topics(:second), Topic.where("title = 'The Second Topic of the day'").first!
393
- end
394
- end
395
-
396
- def test_first_bang_missing
397
- assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
398
- Topic.where("title = 'This title does not exist'").first!
399
- end
400
- end
401
-
402
- def test_first_have_primary_key_order_by_default
403
- expected = topics(:first)
404
- expected.touch # PostgreSQL changes the default order if no order clause is used
405
- assert_equal expected, Topic.first
406
- end
407
-
408
- def test_model_class_responds_to_first_bang
409
- assert Topic.first!
410
- Topic.delete_all
411
- assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
412
- Topic.first!
413
- end
414
- end
415
-
416
- def test_second
417
- puts "finder_test.test_second"
418
- assert_equal topics(:second).title, Topic.second.title
419
- end
420
-
421
- def test_second_with_offset
422
- puts "finder_test.test_second_with_offset"
423
- assert_equal topics(:fifth), Topic.offset(3).second
424
- end
425
-
426
- def test_second_have_primary_key_order_by_default
427
- puts "finder_test.test_second_have_primary_key_order_by_default"
428
- expected = topics(:second)
429
- expected.touch # PostgreSQL changes the default order if no order clause is used
430
- assert_equal expected, Topic.second
431
- end
432
-
433
- def test_model_class_responds_to_second_bang
434
- assert Topic.second!
435
- Topic.delete_all
436
- assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
437
- Topic.second!
438
- end
439
- end
440
-
441
- def test_third
442
- puts "finder_test.test_third"
443
- assert_equal topics(:third).title, Topic.third.title
444
- end
445
-
446
- def test_third_with_offset
447
- puts "finder_test.test_third_with_offset"
448
- assert_equal topics(:fifth), Topic.offset(2).third
449
- end
450
-
451
- def test_third_have_primary_key_order_by_default
452
- puts "finder_test.test_third_have_primary_key_order_by_default"
453
- expected = topics(:third)
454
- expected.touch # PostgreSQL changes the default order if no order clause is used
455
- assert_equal expected, Topic.third
456
- end
457
-
458
- def test_model_class_responds_to_third_bang
459
- assert Topic.third!
460
- Topic.delete_all
461
- assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
462
- Topic.third!
463
- end
464
- end
465
-
466
- def test_fourth
467
- puts "finder_test.test_fourth"
468
- assert_equal topics(:fourth).title, Topic.fourth.title
469
- end
470
-
471
- def test_fourth_with_offset
472
- puts "finder_test.test_fourth_with_offset"
473
- assert_equal topics(:fifth), Topic.offset(1).fourth
474
- end
475
-
476
- def test_fourth_have_primary_key_order_by_default
477
- puts "finder_test.test_fourth_have_primary_key_order_by_default"
478
- expected = topics(:fourth)
479
- expected.touch # PostgreSQL changes the default order if no order clause is used
480
- assert_equal expected, Topic.fourth
481
- end
482
-
483
- def test_model_class_responds_to_fourth_bang
484
- assert Topic.fourth!
485
- Topic.delete_all
486
- assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
487
- Topic.fourth!
488
- end
489
- end
490
-
491
- def test_fifth
492
- assert_equal topics(:fifth).title, Topic.fifth.title
493
- end
494
-
495
- def test_fifth_with_offset
496
- puts "finder_test.test_fifth_with_offset"
497
- assert_equal topics(:fifth), Topic.offset(0).fifth
498
- end
499
-
500
- def test_fifth_have_primary_key_order_by_default
501
- puts "finder_test.test_fifth_have_primary_key_order_by_default"
502
- expected = topics(:fifth)
503
- expected.touch # PostgreSQL changes the default order if no order clause is used
504
- assert_equal expected, Topic.fifth
505
- end
506
-
507
- def test_model_class_responds_to_fifth_bang
508
- assert Topic.fifth!
509
- Topic.delete_all
510
- assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
511
- Topic.fifth!
512
- end
513
- end
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
-
576
- def test_last_bang_present
577
- assert_nothing_raised do
578
- assert_equal topics(:second), Topic.where("title = 'The Second Topic of the day'").last!
579
- end
580
- end
581
-
582
- def test_last_bang_missing
583
- assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
584
- Topic.where("title = 'This title does not exist'").last!
585
- end
586
- end
587
-
588
- def test_model_class_responds_to_last_bang
589
- assert_equal topics(:fifth), Topic.last!
590
- assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
591
- Topic.delete_all
592
- Topic.last!
593
- end
594
- end
595
-
596
- 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
- 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 }
601
- end
602
-
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"
605
- assert_equal Topic.order("title").to_a.last(2), Topic.order("title").last(2)
606
- end
607
-
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?
618
- end
619
-
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)
646
- end
647
-
648
- def test_take_and_first_and_last_with_integer_should_return_an_array
649
- assert_kind_of Array, Topic.take(5)
650
- assert_kind_of Array, Topic.first(5)
651
- assert_kind_of Array, Topic.last(5)
652
- end
653
-
654
- def test_unexisting_record_exception_handling
655
- assert_raise(ActiveRecord::RecordNotFound) {
656
- Topic.find(1).parent
657
- }
658
-
659
- Topic.find(2).topic
660
- end
661
-
662
- def test_find_only_some_columns
663
- topic = Topic.select("author_name").find(1)
664
- assert_raise(ActiveModel::MissingAttributeError) {topic.title}
665
- assert_raise(ActiveModel::MissingAttributeError) {topic.title?}
666
- assert_nil topic.read_attribute("title")
667
- assert_equal "David", topic.author_name
668
- assert !topic.attribute_present?("title")
669
- assert !topic.attribute_present?(:title)
670
- assert topic.attribute_present?("author_name")
671
- assert_respond_to topic, "author_name"
672
- end
673
-
674
- def test_find_on_array_conditions
675
- assert Topic.where(["approved = ?", false]).find(1)
676
- assert_raise(ActiveRecord::RecordNotFound) { Topic.where(["approved = ?", true]).find(1) }
677
- end
678
-
679
- def test_find_on_hash_conditions
680
- assert Topic.where(approved: false).find(1)
681
- assert_raise(ActiveRecord::RecordNotFound) { Topic.where(approved: true).find(1) }
682
- end
683
-
684
- 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) }
687
- end
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
-
694
- def test_find_on_hash_conditions_with_hashed_table_name
695
- assert Topic.where(topics: { approved: false }).find(1)
696
- assert_raise(ActiveRecord::RecordNotFound) { Topic.where(topics: { approved: true }).find(1) }
697
- end
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
-
705
- def test_find_with_hash_conditions_on_joined_table
706
- firms = Firm.joins(:account).where(:accounts => { :credit_limit => 50 })
707
- assert_equal 1, firms.size
708
- assert_equal companies(:first_firm), firms.first
709
- end
710
-
711
- 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 })
713
- assert_equal 1, firms.size
714
- assert_equal companies(:rails_core), firms.first
715
- end
716
-
717
- def test_find_on_hash_conditions_with_explicit_table_name_and_aggregate
718
- david = customers(:david)
719
- assert Customer.where('customers.name' => david.name, :address => david.address).find(david.id)
720
- assert_raise(ActiveRecord::RecordNotFound) {
721
- Customer.where('customers.name' => david.name + "1", :address => david.address).find(david.id)
722
- }
723
- end
724
-
725
- 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
727
- end
728
-
729
- def test_find_on_hash_conditions_with_range
730
- assert_equal [1,2], Topic.where(id: 1..2).to_a.map(&:id).sort
731
- assert_raise(ActiveRecord::RecordNotFound) { Topic.where(id: 2..3).find(1) }
732
- end
733
-
734
- 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
737
- assert_raise(ActiveRecord::RecordNotFound) { Topic.where(id: 2...3).find(3) }
738
- end
739
-
740
- 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
742
- assert_equal [1], Comment.where(id: 1..1, post_id: 1..10).to_a.map(&:id).sort
743
- end
744
-
745
- 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
747
- end
748
-
749
- 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
751
- end
752
-
753
- def test_find_on_multiple_hash_conditions
754
- assert Topic.where(author_name: "David", title: "The First Topic", replies_count: 1, approved: false).find(1)
755
- assert_raise(ActiveRecord::RecordNotFound) { Topic.where(author_name: "David", title: "The First Topic", replies_count: 1, approved: true).find(1) }
756
- 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
- end
759
-
760
- def test_condition_interpolation
761
- puts "finder_test.test_condition_interpolation"
762
- assert_kind_of Firm, Company.where("name = '%s'", "37signals").first
763
- assert_nil Company.where(["name = '%s'", "37signals!"]).first
764
- assert_nil Company.where(["name = '%s'", "37signals!' OR 1=1"]).first
765
- assert_kind_of Time, Topic.where(["id = %d", 1]).first.written_on
766
- end
767
-
768
- def test_condition_array_interpolation
769
- puts "finder_test.test_condition_array_interpolation"
770
- assert_kind_of Firm, Company.where(["name = '%s'", "37signals"]).first
771
- assert_nil Company.where(["name = '%s'", "37signals!"]).first
772
- assert_nil Company.where(["name = '%s'", "37signals!' OR 1=1"]).first
773
- assert_kind_of Time, Topic.where(["id = %d", 1]).first.written_on
774
- end
775
-
776
- def test_condition_hash_interpolation
777
- assert_kind_of Firm, Company.where(name: "37signals").first
778
- assert_nil Company.where(name: "37signals!").first
779
- assert_kind_of Time, Topic.where(id: 1).first.written_on
780
- end
781
-
782
- def test_hash_condition_find_malformed
783
- assert_raise(ActiveRecord::StatementInvalid) {
784
- Company.where(id: 2, dhh: true).first
785
- }
786
- end
787
-
788
- def test_hash_condition_find_with_escaped_characters
789
- puts "finder_test.test_hash_condition_find_with_escaped_characters"
790
- Company.create("name" => "Ain't noth'n like' \#stuff")
791
- assert Company.where(name: "Ain't noth'n like' \#stuff").first
792
- end
793
-
794
- 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
799
- end
800
-
801
- def test_hash_condition_find_with_nil
802
- topic = Topic.where(last_read: nil).first
803
- assert_not_nil topic
804
- assert_nil topic.last_read
805
- end
806
-
807
- def test_hash_condition_find_with_aggregate_having_one_mapping
808
- balance = customers(:david).balance
809
- assert_kind_of Money, balance
810
- found_customer = Customer.where(:balance => balance).first
811
- assert_equal customers(:david), found_customer
812
- end
813
-
814
- def test_hash_condition_find_with_aggregate_attribute_having_same_name_as_field_and_key_value_being_aggregate
815
- gps_location = customers(:david).gps_location
816
- assert_kind_of GpsLocation, gps_location
817
- found_customer = Customer.where(:gps_location => gps_location).first
818
- assert_equal customers(:david), found_customer
819
- end
820
-
821
- def test_hash_condition_find_with_aggregate_having_one_mapping_and_key_value_being_attribute_value
822
- balance = customers(:david).balance
823
- assert_kind_of Money, balance
824
- found_customer = Customer.where(:balance => balance.amount).first
825
- assert_equal customers(:david), found_customer
826
- end
827
-
828
- def test_hash_condition_find_with_aggregate_attribute_having_same_name_as_field_and_key_value_being_attribute_value
829
- gps_location = customers(:david).gps_location
830
- assert_kind_of GpsLocation, gps_location
831
- found_customer = Customer.where(:gps_location => gps_location.gps_location).first
832
- assert_equal customers(:david), found_customer
833
- end
834
-
835
- def test_hash_condition_find_with_aggregate_having_three_mappings
836
- address = customers(:david).address
837
- assert_kind_of Address, address
838
- found_customer = Customer.where(:address => address).first
839
- assert_equal customers(:david), found_customer
840
- end
841
-
842
- def test_hash_condition_find_with_one_condition_being_aggregate_and_another_not
843
- address = customers(:david).address
844
- assert_kind_of Address, address
845
- found_customer = Customer.where(:address => address, :name => customers(:david).name).first
846
- assert_equal customers(:david), found_customer
847
- end
848
-
849
- def test_condition_utc_time_interpolation_with_default_timezone_local
850
- with_env_tz 'America/New_York' do
851
- with_timezone_config default: :local do
852
- topic = Topic.first
853
- assert_equal topic, Topic.where(['written_on = ?', topic.written_on.getutc]).first
854
- end
855
- end
856
- end
857
-
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"
860
- with_env_tz 'America/New_York' do
861
- with_timezone_config default: :local do
862
- topic = Topic.first
863
- assert_equal topic, Topic.where(written_on: topic.written_on.getutc).first
864
- end
865
- end
866
- end
867
-
868
- 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
871
- with_timezone_config default: :utc do
872
- topic = Topic.first
873
- assert_equal topic, Topic.where(['written_on = ?', topic.written_on.getlocal]).first
874
- end
875
- end
876
- end
877
-
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"
880
- with_env_tz 'America/New_York' do
881
- with_timezone_config default: :utc do
882
- topic = Topic.first
883
- assert_equal topic, Topic.where(written_on: topic.written_on.getlocal).first
884
- end
885
- end
886
- end
887
-
888
- def test_bind_variables
889
- assert_kind_of Firm, Company.where(["name = ?", "37signals"]).first
890
- assert_nil Company.where(["name = ?", "37signals!"]).first
891
- assert_nil Company.where(["name = ?", "37signals!' OR 1=1"]).first
892
- assert_kind_of Time, Topic.where(["id = ?", 1]).first.written_on
893
- assert_raise(ActiveRecord::PreparedStatementInvalid) {
894
- Company.where(["id=? AND name = ?", 2]).first
895
- }
896
- assert_raise(ActiveRecord::PreparedStatementInvalid) {
897
- Company.where(["id=?", 2, 3, 4]).first
898
- }
899
- end
900
-
901
- 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
905
- end
906
-
907
- 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
911
- end
912
-
913
- def test_named_bind_variables
914
- puts "finder_test.test_named_bind_variables"
915
- assert_kind_of Firm, Company.where(["name = :name", { name: "37signals" }]).first
916
- assert_nil Company.where(["name = :name", { name: "37signals!" }]).first
917
- assert_nil Company.where(["name = :name", { name: "37signals!' OR 1=1" }]).first
918
- assert_kind_of Time, Topic.where(["id = :id", { id: 1 }]).first.written_on
919
- end
920
-
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
- def test_count_by_sql
927
- assert_equal(0, Entrant.count_by_sql("SELECT COUNT(*) FROM entrants WHERE id > 3"))
928
- assert_equal(1, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 2]))
929
- assert_equal(2, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 1]))
930
- end
931
-
932
- def test_find_by_one_attribute
933
- assert_equal topics(:first), Topic.find_by_title("The First Topic")
934
- assert_nil Topic.find_by_title("The First Topic!")
935
- end
936
-
937
- def test_find_by_one_attribute_bang
938
- assert_equal topics(:first), Topic.find_by_title!("The First Topic")
939
- assert_raises_with_message(ActiveRecord::RecordNotFound, "Couldn't find Topic") do
940
- Topic.find_by_title!("The First Topic!")
941
- end
942
- end
943
-
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"
946
- dog_alias = 'Dog'
947
- dog = Dog.create(alias: dog_alias)
948
-
949
- assert_equal dog, Dog.find_by_alias(dog_alias)
950
- end
951
-
952
- def test_find_by_one_attribute_that_is_an_alias
953
- assert_equal topics(:first), Topic.find_by_heading("The First Topic")
954
- assert_nil Topic.find_by_heading("The First Topic!")
955
- end
956
-
957
- def test_find_by_one_attribute_bang_with_blank_defined
958
- puts "finder_test.test_find_by_one_attribute_bang_with_blank_defined"
959
- blank_topic = BlankTopic.create(title: "The Blank One")
960
- assert_equal blank_topic, BlankTopic.find_by_title!("The Blank One")
961
- end
962
-
963
- 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)
965
- end
966
-
967
- def test_find_by_one_attribute_that_is_an_aggregate
968
- address = customers(:david).address
969
- assert_kind_of Address, address
970
- found_customer = Customer.find_by_address(address)
971
- assert_equal customers(:david), found_customer
972
- end
973
-
974
- def test_find_by_one_attribute_that_is_an_aggregate_with_one_attribute_difference
975
- address = customers(:david).address
976
- assert_kind_of Address, address
977
- missing_address = Address.new(address.street, address.city, address.country + "1")
978
- assert_nil Customer.find_by_address(missing_address)
979
- missing_address = Address.new(address.street, address.city + "1", address.country)
980
- assert_nil Customer.find_by_address(missing_address)
981
- missing_address = Address.new(address.street + "1", address.city, address.country)
982
- assert_nil Customer.find_by_address(missing_address)
983
- end
984
-
985
- def test_find_by_two_attributes_that_are_both_aggregates
986
- balance = customers(:david).balance
987
- address = customers(:david).address
988
- assert_kind_of Money, balance
989
- assert_kind_of Address, address
990
- found_customer = Customer.find_by_balance_and_address(balance, address)
991
- assert_equal customers(:david), found_customer
992
- end
993
-
994
- def test_find_by_two_attributes_with_one_being_an_aggregate
995
- balance = customers(:david).balance
996
- assert_kind_of Money, balance
997
- found_customer = Customer.find_by_balance_and_name(balance, customers(:david).name)
998
- assert_equal customers(:david), found_customer
999
- end
1000
-
1001
- def test_dynamic_finder_on_one_attribute_with_conditions_returns_same_results_after_caching
1002
- # 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
1006
- end
1007
-
1008
- 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)
1010
- end
1011
-
1012
- def test_find_by_one_missing_attribute
1013
- assert_raise(NoMethodError) { Topic.find_by_undertitle("The First Topic!") }
1014
- end
1015
-
1016
- def test_find_by_invalid_method_syntax
1017
- assert_raise(NoMethodError) { Topic.fail_to_find_by_title("The First Topic") }
1018
- assert_raise(NoMethodError) { Topic.find_by_title?("The First Topic") }
1019
- assert_raise(NoMethodError) { Topic.fail_to_find_or_create_by_title("Nonexistent Title") }
1020
- assert_raise(NoMethodError) { Topic.find_or_create_by_title?("Nonexistent Title") }
1021
- end
1022
-
1023
- def test_find_by_two_attributes
1024
- assert_equal topics(:first), Topic.find_by_title_and_author_name("The First Topic", "David")
1025
- assert_nil Topic.find_by_title_and_author_name("The First Topic", "Mary")
1026
- end
1027
-
1028
- def test_find_by_two_attributes_but_passing_only_one
1029
- assert_raise(ArgumentError) { Topic.find_by_title_and_author_name("The First Topic") }
1030
- end
1031
-
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
- def test_find_by_nil_attribute
1043
- topic = Topic.find_by_last_read nil
1044
- assert_not_nil topic
1045
- assert_nil topic.last_read
1046
- end
1047
-
1048
- def test_find_by_nil_and_not_nil_attributes
1049
- topic = Topic.find_by_last_read_and_author_name nil, "Mary"
1050
- assert_equal "Mary", topic.author_name
1051
- end
1052
-
1053
- def test_find_with_bad_sql
1054
- assert_raise(ActiveRecord::StatementInvalid) { Topic.find_by_sql "select 1 from badtable" }
1055
- end
1056
-
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
- def test_joins_dont_clobber_id
1068
- first = Firm.
1069
- joins('INNER JOIN companies clients ON clients.firm_id = companies.id').
1070
- where('companies.id = 1').first
1071
- assert_equal 1, first.id
1072
- end
1073
-
1074
- def test_joins_with_string_array
1075
- person_with_reader_and_post = Post.
1076
- joins(["INNER JOIN categorizations ON categorizations.post_id = posts.id",
1077
- "INNER JOIN categories ON categories.id = categorizations.category_id AND categories.type = 'SpecialCategory'"
1078
- ])
1079
- assert_equal 1, person_with_reader_and_post.size
1080
- end
1081
-
1082
- def test_find_by_id_with_conditions_with_or
1083
- assert_nothing_raised do
1084
- Post.where("posts.id <= 3 OR posts.#{QUOTED_TYPE} = 'Post'").find([1,2,3])
1085
- end
1086
- end
1087
-
1088
- 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')
1091
- assert_equal [], Post.where(id: nil)
1092
- end
1093
-
1094
- def test_find_by_empty_ids
1095
- assert_equal [], Post.find([])
1096
- end
1097
-
1098
- def test_find_by_empty_in_condition
1099
- assert_equal [], Post.where('id in (?)', [])
1100
- end
1101
-
1102
- 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')
1107
- end
1108
-
1109
- def test_select_value
1110
- assert_equal "37signals", Company.connection.select_value("SELECT name FROM companies WHERE id = 1")
1111
- assert_nil Company.connection.select_value("SELECT name FROM companies WHERE id = -1")
1112
- # make sure we didn't break count...
1113
- assert_equal 0, Company.count_by_sql("SELECT COUNT(*) FROM companies WHERE name = 'Halliburton'")
1114
- assert_equal 1, Company.count_by_sql("SELECT COUNT(*) FROM companies WHERE name = '37signals'")
1115
- end
1116
-
1117
- 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")
1120
- end
1121
-
1122
- def test_select_rows
1123
- assert_equal(
1124
- [["1", "1", nil, "37signals"],
1125
- ["2", "1", "2", "Summit"],
1126
- ["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?}})
1128
- 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?}}
1130
- end
1131
-
1132
- 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
- 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
1137
-
1138
- assert_equal 3, Post.includes(author: :author_address, authors: :author_address).
1139
- where.not(author_addresses_authors: { id: nil }).
1140
- order('author_addresses_authors.id DESC').limit(3).to_a.size
1141
- end
1142
-
1143
- def test_find_with_nil_inside_set_passed_for_one_attribute
1144
- client_of = Company.
1145
- where(client_of: [2, 1, nil],
1146
- name: ['37signals', 'Summit', 'Microsoft']).
1147
- order('client_of DESC').
1148
- map(&:client_of)
1149
-
1150
- assert client_of.include?(nil)
1151
- assert_equal [2, 1].sort, client_of.compact.sort
1152
- end
1153
-
1154
- def test_find_with_nil_inside_set_passed_for_attribute
1155
- client_of = Company.
1156
- where(client_of: [nil]).
1157
- order('client_of DESC').
1158
- map(&:client_of)
1159
-
1160
- assert_equal [], client_of.compact
1161
- end
1162
-
1163
- def test_with_limiting_with_custom_select
1164
- puts "finder_test.test_with_limiting_with_custom_select"
1165
- posts = Post.references(:authors).merge(
1166
- :includes => :author, :select => 'posts.*, authors.id as "author_id"',
1167
- :limit => 3, :order => 'posts.id'
1168
- ).to_a
1169
- assert_equal 3, posts.size
1170
- assert_equal [0, 1, 1], posts.map(&:author_id).sort
1171
- end
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
-
1183
- def test_find_one_message_with_custom_primary_key
1184
- table_with_custom_primary_key do |model|
1185
- model.primary_key = :name
1186
- e = assert_raises(ActiveRecord::RecordNotFound) do
1187
- model.find 'Hello World!'
1188
- end
1189
- assert_equal %Q{Couldn't find MercedesCar with 'name'=Hello World!}, e.message
1190
- end
1191
- end
1192
-
1193
- def test_find_some_message_with_custom_primary_key
1194
- table_with_custom_primary_key do |model|
1195
- model.primary_key = :name
1196
- e = assert_raises(ActiveRecord::RecordNotFound) do
1197
- model.find 'Hello', 'World!'
1198
- end
1199
- assert_equal %Q{Couldn't find all MercedesCars with 'name': (Hello, World!) (found 0 results, but was looking for 2)}, e.message
1200
- end
1201
- end
1202
-
1203
- def test_find_without_primary_key
1204
- assert_raises(ActiveRecord::UnknownPrimaryKey) do
1205
- Matey.find(1)
1206
- end
1207
- end
1208
-
1209
- def test_finder_with_offset_string
1210
- assert_nothing_raised { Topic.offset("3").to_a }
1211
- end
1212
-
1213
- test "find_by with hash conditions returns the first matching record" do
1214
- assert_equal posts(:eager_other), Post.find_by(id: posts(:eager_other).id)
1215
- end
1216
-
1217
- test "find_by with non-hash conditions returns the first matching record" do
1218
- assert_equal posts(:eager_other), Post.find_by("id = #{posts(:eager_other).id}")
1219
- end
1220
-
1221
- 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)
1223
- end
1224
-
1225
- test "find_by returns nil if the record is missing" do
1226
- assert_equal nil, Post.find_by("1 = 0")
1227
- end
1228
-
1229
- test "find_by with associations" do
1230
- assert_equal authors(:david), Post.find_by(author: authors(:david)).author
1231
- assert_equal authors(:mary) , Post.find_by(author: authors(:mary) ).author
1232
- end
1233
-
1234
- test "find_by doesn't have implicit ordering" do
1235
- assert_sql(/^((?!ORDER).)*$/) { Post.find_by(id: posts(:eager_other).id) }
1236
- end
1237
-
1238
- test "find_by! with hash conditions returns the first matching record" do
1239
- assert_equal posts(:eager_other), Post.find_by!(id: posts(:eager_other).id)
1240
- end
1241
-
1242
- test "find_by! with non-hash conditions returns the first matching record" do
1243
- assert_equal posts(:eager_other), Post.find_by!("id = #{posts(:eager_other).id}")
1244
- end
1245
-
1246
- 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)
1248
- end
1249
-
1250
- test "find_by! doesn't have implicit ordering" do
1251
- assert_sql(/^((?!ORDER).)*$/) { Post.find_by!(id: posts(:eager_other).id) }
1252
- end
1253
-
1254
- test "find_by! raises RecordNotFound if the record is missing" do
1255
- assert_raises(ActiveRecord::RecordNotFound) do
1256
- Post.find_by!("1 = 0")
1257
- end
1258
- end
1259
-
1260
- test "find on a scope does not perform statement caching" do
1261
- honda = cars(:honda)
1262
- zyke = cars(:zyke)
1263
- tyre = honda.tyres.create!
1264
- tyre2 = zyke.tyres.create!
1265
-
1266
- assert_equal tyre, honda.tyres.custom_find(tyre.id)
1267
- assert_equal tyre2, zyke.tyres.custom_find(tyre2.id)
1268
- end
1269
-
1270
- test "find_by on a scope does not perform statement caching" do
1271
- honda = cars(:honda)
1272
- zyke = cars(:zyke)
1273
- tyre = honda.tyres.create!
1274
- tyre2 = zyke.tyres.create!
1275
-
1276
- assert_equal tyre, honda.tyres.custom_find_by(id: tyre.id)
1277
- assert_equal tyre2, zyke.tyres.custom_find_by(id: tyre2.id)
1278
- end
1279
-
1280
- protected
1281
- def table_with_custom_primary_key
1282
- yield(Class.new(Toy) do
1283
- def self.name
1284
- 'MercedesCar'
1285
- end
1286
- end)
1287
- end
1288
-
1289
- def assert_raises_with_message(exception_class, message, &block)
1290
- err = assert_raises(exception_class) { block.call }
1291
- assert_match message, err.message
1292
- end
1293
-
1294
- end
1
+ 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'
20
+
21
+ class FinderTest < ActiveRecord::TestCase
22
+ fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :author_addresses, :customers, :categories, :categorizations, :cars
23
+
24
+ def test_find_by_id_with_hash
25
+ assert_raises(ActiveRecord::StatementInvalid) do
26
+ Post.find_by_id(:limit => 1)
27
+ end
28
+ end
29
+
30
+ 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)
33
+ end
34
+ end
35
+
36
+ def test_find
37
+ assert_equal(topics(:first).title, Topic.find(1).title)
38
+ end
39
+
40
+ def test_find_with_proc_parameter_and_block
41
+ exception = assert_raises(RuntimeError) do
42
+ Topic.all.find(-> { raise "should happen" }) { |e| e.title == "non-existing-title" }
43
+ end
44
+ assert_equal "should happen", exception.message
45
+
46
+ assert_nothing_raised do
47
+ Topic.all.find(-> { raise "should not happen" }) { |e| e.title == topics(:first).title }
48
+ end
49
+ end
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
+
122
+ def test_find_passing_active_record_object_is_deprecated
123
+ assert_deprecated do
124
+ Topic.find(Topic.last)
125
+ end
126
+ end
127
+
128
+ def test_symbols_table_ref
129
+ gc_disabled = GC.disable
130
+ Post.where("author_id" => nil) # warm up
131
+ x = Symbol.all_symbols.count
132
+ Post.where("title" => {"xxxqqqq" => "bar"})
133
+ assert_equal x, Symbol.all_symbols.count
134
+ ensure
135
+ GC.enable if gc_disabled == false
136
+ end
137
+
138
+ # find should handle strings that come from URLs
139
+ # (example: Category.find(params[:id]))
140
+ def test_find_with_string
141
+ assert_equal(Topic.find(1).title,Topic.find("1").title)
142
+ end
143
+
144
+ def test_exists
145
+ assert_equal true, Topic.exists?(1)
146
+ assert_equal true, Topic.exists?("1")
147
+ assert_equal true, Topic.exists?(title: "The First Topic")
148
+ assert_equal true, Topic.exists?(heading: "The First Topic")
149
+ assert_equal true, Topic.exists?(:author_name => "Mary", :approved => true)
150
+ assert_equal true, Topic.exists?(["parent_id = ?", 1])
151
+ assert_equal true, Topic.exists?(id: [1, 9999])
152
+
153
+ assert_equal false, Topic.exists?(45)
154
+ assert_equal false, Topic.exists?(Topic.new.id)
155
+
156
+ assert_raise(NoMethodError) { Topic.exists?([1,2]) }
157
+ end
158
+
159
+ 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')
163
+
164
+ assert_equal true, relation.exists?(title: ['Post'])
165
+ assert_equal true, relation.exists?(['title LIKE ?', 'Post%'])
166
+ assert_equal true, relation.exists?
167
+ assert_equal true, relation.exists?(post.id)
168
+ assert_equal true, relation.exists?(post.id.to_s)
169
+
170
+ assert_equal false, relation.exists?(false)
171
+ end
172
+
173
+ def test_exists_passing_active_record_object_is_deprecated
174
+ assert_deprecated do
175
+ Topic.exists?(Topic.new)
176
+ end
177
+ end
178
+
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
183
+ end
184
+ assert_equal false, Topic.exists?("foo")
185
+ end
186
+
187
+ 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
190
+ Topic.exists?
191
+ end
192
+ end
193
+
194
+ def test_exists_returns_true_with_one_record_and_no_args
195
+ assert_equal true, Topic.exists?
196
+ end
197
+
198
+ def test_exists_returns_false_with_false_arg
199
+ assert_equal false, Topic.exists?(false)
200
+ end
201
+
202
+ # exists? should handle nil for id's that come from URLs and always return false
203
+ # (example: Topic.exists?(params[:id])) where params[:id] is nil
204
+ def test_exists_with_nil_arg
205
+ assert_equal false, Topic.exists?(nil)
206
+ assert_equal true, Topic.exists?
207
+
208
+ assert_equal false, Topic.first.replies.exists?(nil)
209
+ assert_equal true, Topic.first.replies.exists?
210
+ end
211
+
212
+ # ensures +exists?+ runs valid SQL by excluding order value
213
+ def test_exists_with_order
214
+ assert_equal true, Topic.order(:id).distinct.exists?
215
+ end
216
+
217
+ 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?
221
+ end
222
+
223
+ def test_exists_with_distinct_association_includes_and_limit
224
+ puts "finder_test.test_exists_with_distinct_association_includes_and_limit"
225
+ 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?
228
+ end
229
+
230
+ def test_exists_with_distinct_association_includes_limit_and_order
231
+ puts "finder_test.test_exists_with_distinct_association_includes_limit_and_order"
232
+ 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?
235
+ end
236
+
237
+ def test_exists_with_empty_table_and_no_args_given
238
+ Topic.delete_all
239
+ assert_equal false, Topic.exists?
240
+ end
241
+
242
+ def test_exists_with_aggregate_having_three_mappings
243
+ existing_address = customers(:david).address
244
+ assert_equal true, Customer.exists?(:address => existing_address)
245
+ end
246
+
247
+ def test_exists_with_aggregate_having_three_mappings_with_one_difference
248
+ 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))
255
+ end
256
+
257
+ def test_exists_does_not_instantiate_records
258
+ assert_not_called(Developer, :instantiate) do
259
+ Developer.exists?
260
+ end
261
+ end
262
+
263
+ def test_find_by_array_of_one_id
264
+ assert_kind_of(Array, Topic.find([ 1 ]))
265
+ assert_equal(1, Topic.find([ 1 ]).length)
266
+ end
267
+
268
+ def test_find_by_ids
269
+ assert_equal 2, Topic.find(1, 2).size
270
+ assert_equal topics(:second).title, Topic.find([2]).first.title
271
+ end
272
+
273
+ 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])
276
+ assert_equal 1, entrants.size
277
+ assert_equal 'Ruby Guru', entrants.first.name
278
+
279
+ # Also test an edge case: If you have 11 results, and you set a
280
+ # limit of 3 and offset of 9, then you should find that there
281
+ # will be only 2 results, regardless of the limit.
282
+ devs = Developer.all
283
+ last_devs = Developer.limit(3).offset(9).find devs.map(&:id)
284
+ assert_equal 2, last_devs.size
285
+ assert_equal 'fixture_10', last_devs[0].name
286
+ assert_equal 'Jamis', last_devs[1].name
287
+ end
288
+
289
+ unless current_adapter?(:IBM_DBAdapter)
290
+ def test_find_with_large_number
291
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find('9999999999999999999999999999999') }
292
+ end
293
+
294
+ def test_find_by_with_large_number
295
+ assert_nil Topic.find_by(id: '9999999999999999999999999999999')
296
+ end
297
+
298
+ def test_find_by_id_with_large_number
299
+ assert_nil Topic.find_by_id('9999999999999999999999999999999')
300
+ end
301
+
302
+ def test_find_on_relation_with_large_number
303
+ assert_nil Topic.where('1=1').find_by(id: 9999999999999999999999999999999)
304
+ end
305
+
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
311
+ end
312
+
313
+ def test_find_an_empty_array
314
+ assert_equal [], Topic.find([])
315
+ end
316
+
317
+ def test_find_doesnt_have_implicit_ordering
318
+ assert_sql(/^((?!ORDER).)*$/) { Topic.find(1) }
319
+ end
320
+
321
+ def test_find_by_ids_missing_one
322
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1, 2, 45) }
323
+ end
324
+
325
+ def test_find_with_group_and_sanitized_having_method
326
+ developers = Developer.group(:salary).having("sum(salary) > ?", 10000).select('salary').to_a
327
+ assert_equal 3, developers.size
328
+ assert_equal 3, developers.map(&:salary).uniq.size
329
+ assert developers.all? { |developer| developer.salary > 10000 }
330
+ end
331
+
332
+ def test_find_with_entire_select_statement
333
+ topics = Topic.find_by_sql "SELECT * FROM topics WHERE author_name = 'Mary'"
334
+
335
+ assert_equal(1, topics.size)
336
+ assert_equal(topics(:second).title, topics.first.title)
337
+ end
338
+
339
+ def test_find_with_prepared_select_statement
340
+ topics = Topic.find_by_sql ["SELECT * FROM topics WHERE author_name = ?", "Mary"]
341
+
342
+ assert_equal(1, topics.size)
343
+ assert_equal(topics(:second).title, topics.first.title)
344
+ end
345
+
346
+ def test_find_by_sql_with_sti_on_joined_table
347
+ accounts = Account.find_by_sql("SELECT * FROM accounts INNER JOIN companies ON companies.id = accounts.firm_id")
348
+ assert_equal [Account], accounts.collect(&:class).uniq
349
+ end
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
+
362
+ def test_take
363
+ assert_equal topics(:first), Topic.take
364
+ end
365
+
366
+ def test_take_failing
367
+ assert_nil Topic.where("title = 'This title does not exist'").take
368
+ end
369
+
370
+ def test_take_bang_present
371
+ assert_nothing_raised do
372
+ assert_equal topics(:second), Topic.where("title = 'The Second Topic of the day'").take!
373
+ end
374
+ end
375
+
376
+ def test_take_bang_missing
377
+ assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
378
+ Topic.where("title = 'This title does not exist'").take!
379
+ end
380
+ end
381
+
382
+ def test_first
383
+ assert_equal topics(:second).title, Topic.where("title = 'The Second Topic of the day'").first.title
384
+ end
385
+
386
+ def test_first_failing
387
+ assert_nil Topic.where("title = 'The Second Topic of the day!'").first
388
+ end
389
+
390
+ def test_first_bang_present
391
+ assert_nothing_raised do
392
+ assert_equal topics(:second), Topic.where("title = 'The Second Topic of the day'").first!
393
+ end
394
+ end
395
+
396
+ def test_first_bang_missing
397
+ assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
398
+ Topic.where("title = 'This title does not exist'").first!
399
+ end
400
+ end
401
+
402
+ def test_first_have_primary_key_order_by_default
403
+ expected = topics(:first)
404
+ expected.touch # PostgreSQL changes the default order if no order clause is used
405
+ assert_equal expected, Topic.first
406
+ end
407
+
408
+ def test_model_class_responds_to_first_bang
409
+ assert Topic.first!
410
+ Topic.delete_all
411
+ assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
412
+ Topic.first!
413
+ end
414
+ end
415
+
416
+ def test_second
417
+ puts "finder_test.test_second"
418
+ assert_equal topics(:second).title, Topic.second.title
419
+ end
420
+
421
+ def test_second_with_offset
422
+ puts "finder_test.test_second_with_offset"
423
+ assert_equal topics(:fifth), Topic.offset(3).second
424
+ end
425
+
426
+ def test_second_have_primary_key_order_by_default
427
+ puts "finder_test.test_second_have_primary_key_order_by_default"
428
+ expected = topics(:second)
429
+ expected.touch # PostgreSQL changes the default order if no order clause is used
430
+ assert_equal expected, Topic.second
431
+ end
432
+
433
+ def test_model_class_responds_to_second_bang
434
+ assert Topic.second!
435
+ Topic.delete_all
436
+ assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
437
+ Topic.second!
438
+ end
439
+ end
440
+
441
+ def test_third
442
+ puts "finder_test.test_third"
443
+ assert_equal topics(:third).title, Topic.third.title
444
+ end
445
+
446
+ def test_third_with_offset
447
+ puts "finder_test.test_third_with_offset"
448
+ assert_equal topics(:fifth), Topic.offset(2).third
449
+ end
450
+
451
+ def test_third_have_primary_key_order_by_default
452
+ puts "finder_test.test_third_have_primary_key_order_by_default"
453
+ expected = topics(:third)
454
+ expected.touch # PostgreSQL changes the default order if no order clause is used
455
+ assert_equal expected, Topic.third
456
+ end
457
+
458
+ def test_model_class_responds_to_third_bang
459
+ assert Topic.third!
460
+ Topic.delete_all
461
+ assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
462
+ Topic.third!
463
+ end
464
+ end
465
+
466
+ def test_fourth
467
+ puts "finder_test.test_fourth"
468
+ assert_equal topics(:fourth).title, Topic.fourth.title
469
+ end
470
+
471
+ def test_fourth_with_offset
472
+ puts "finder_test.test_fourth_with_offset"
473
+ assert_equal topics(:fifth), Topic.offset(1).fourth
474
+ end
475
+
476
+ def test_fourth_have_primary_key_order_by_default
477
+ puts "finder_test.test_fourth_have_primary_key_order_by_default"
478
+ expected = topics(:fourth)
479
+ expected.touch # PostgreSQL changes the default order if no order clause is used
480
+ assert_equal expected, Topic.fourth
481
+ end
482
+
483
+ def test_model_class_responds_to_fourth_bang
484
+ assert Topic.fourth!
485
+ Topic.delete_all
486
+ assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
487
+ Topic.fourth!
488
+ end
489
+ end
490
+
491
+ def test_fifth
492
+ assert_equal topics(:fifth).title, Topic.fifth.title
493
+ end
494
+
495
+ def test_fifth_with_offset
496
+ puts "finder_test.test_fifth_with_offset"
497
+ assert_equal topics(:fifth), Topic.offset(0).fifth
498
+ end
499
+
500
+ def test_fifth_have_primary_key_order_by_default
501
+ puts "finder_test.test_fifth_have_primary_key_order_by_default"
502
+ expected = topics(:fifth)
503
+ expected.touch # PostgreSQL changes the default order if no order clause is used
504
+ assert_equal expected, Topic.fifth
505
+ end
506
+
507
+ def test_model_class_responds_to_fifth_bang
508
+ assert Topic.fifth!
509
+ Topic.delete_all
510
+ assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
511
+ Topic.fifth!
512
+ end
513
+ end
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
+
576
+ def test_last_bang_present
577
+ assert_nothing_raised do
578
+ assert_equal topics(:second), Topic.where("title = 'The Second Topic of the day'").last!
579
+ end
580
+ end
581
+
582
+ def test_last_bang_missing
583
+ assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
584
+ Topic.where("title = 'This title does not exist'").last!
585
+ end
586
+ end
587
+
588
+ def test_model_class_responds_to_last_bang
589
+ assert_equal topics(:fifth), Topic.last!
590
+ assert_raises_with_message ActiveRecord::RecordNotFound, "Couldn't find Topic" do
591
+ Topic.delete_all
592
+ Topic.last!
593
+ end
594
+ end
595
+
596
+ 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
+ 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 }
601
+ end
602
+
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"
605
+ assert_equal Topic.order("title").to_a.last(2), Topic.order("title").last(2)
606
+ end
607
+
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?
618
+ end
619
+
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)
646
+ end
647
+
648
+ def test_take_and_first_and_last_with_integer_should_return_an_array
649
+ assert_kind_of Array, Topic.take(5)
650
+ assert_kind_of Array, Topic.first(5)
651
+ assert_kind_of Array, Topic.last(5)
652
+ end
653
+
654
+ def test_unexisting_record_exception_handling
655
+ assert_raise(ActiveRecord::RecordNotFound) {
656
+ Topic.find(1).parent
657
+ }
658
+
659
+ Topic.find(2).topic
660
+ end
661
+
662
+ def test_find_only_some_columns
663
+ topic = Topic.select("author_name").find(1)
664
+ assert_raise(ActiveModel::MissingAttributeError) {topic.title}
665
+ assert_raise(ActiveModel::MissingAttributeError) {topic.title?}
666
+ assert_nil topic.read_attribute("title")
667
+ assert_equal "David", topic.author_name
668
+ assert !topic.attribute_present?("title")
669
+ assert !topic.attribute_present?(:title)
670
+ assert topic.attribute_present?("author_name")
671
+ assert_respond_to topic, "author_name"
672
+ end
673
+
674
+ def test_find_on_array_conditions
675
+ assert Topic.where(["approved = ?", false]).find(1)
676
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.where(["approved = ?", true]).find(1) }
677
+ end
678
+
679
+ def test_find_on_hash_conditions
680
+ assert Topic.where(approved: false).find(1)
681
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.where(approved: true).find(1) }
682
+ end
683
+
684
+ 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) }
687
+ end
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
+
694
+ def test_find_on_hash_conditions_with_hashed_table_name
695
+ assert Topic.where(topics: { approved: false }).find(1)
696
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.where(topics: { approved: true }).find(1) }
697
+ end
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
+
705
+ def test_find_with_hash_conditions_on_joined_table
706
+ firms = Firm.joins(:account).where(:accounts => { :credit_limit => 50 })
707
+ assert_equal 1, firms.size
708
+ assert_equal companies(:first_firm), firms.first
709
+ end
710
+
711
+ 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 })
713
+ assert_equal 1, firms.size
714
+ assert_equal companies(:rails_core), firms.first
715
+ end
716
+
717
+ def test_find_on_hash_conditions_with_explicit_table_name_and_aggregate
718
+ david = customers(:david)
719
+ assert Customer.where('customers.name' => david.name, :address => david.address).find(david.id)
720
+ assert_raise(ActiveRecord::RecordNotFound) {
721
+ Customer.where('customers.name' => david.name + "1", :address => david.address).find(david.id)
722
+ }
723
+ end
724
+
725
+ 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
727
+ end
728
+
729
+ def test_find_on_hash_conditions_with_range
730
+ assert_equal [1,2], Topic.where(id: 1..2).to_a.map(&:id).sort
731
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.where(id: 2..3).find(1) }
732
+ end
733
+
734
+ 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
737
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.where(id: 2...3).find(3) }
738
+ end
739
+
740
+ 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
742
+ assert_equal [1], Comment.where(id: 1..1, post_id: 1..10).to_a.map(&:id).sort
743
+ end
744
+
745
+ 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
747
+ end
748
+
749
+ 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
751
+ end
752
+
753
+ def test_find_on_multiple_hash_conditions
754
+ assert Topic.where(author_name: "David", title: "The First Topic", replies_count: 1, approved: false).find(1)
755
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.where(author_name: "David", title: "The First Topic", replies_count: 1, approved: true).find(1) }
756
+ 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
+ end
759
+
760
+ def test_condition_interpolation
761
+ puts "finder_test.test_condition_interpolation"
762
+ assert_kind_of Firm, Company.where("name = '%s'", "37signals").first
763
+ assert_nil Company.where(["name = '%s'", "37signals!"]).first
764
+ assert_nil Company.where(["name = '%s'", "37signals!' OR 1=1"]).first
765
+ assert_kind_of Time, Topic.where(["id = %d", 1]).first.written_on
766
+ end
767
+
768
+ def test_condition_array_interpolation
769
+ puts "finder_test.test_condition_array_interpolation"
770
+ assert_kind_of Firm, Company.where(["name = '%s'", "37signals"]).first
771
+ assert_nil Company.where(["name = '%s'", "37signals!"]).first
772
+ assert_nil Company.where(["name = '%s'", "37signals!' OR 1=1"]).first
773
+ assert_kind_of Time, Topic.where(["id = %d", 1]).first.written_on
774
+ end
775
+
776
+ def test_condition_hash_interpolation
777
+ assert_kind_of Firm, Company.where(name: "37signals").first
778
+ assert_nil Company.where(name: "37signals!").first
779
+ assert_kind_of Time, Topic.where(id: 1).first.written_on
780
+ end
781
+
782
+ def test_hash_condition_find_malformed
783
+ assert_raise(ActiveRecord::StatementInvalid) {
784
+ Company.where(id: 2, dhh: true).first
785
+ }
786
+ end
787
+
788
+ def test_hash_condition_find_with_escaped_characters
789
+ puts "finder_test.test_hash_condition_find_with_escaped_characters"
790
+ Company.create("name" => "Ain't noth'n like' \#stuff")
791
+ assert Company.where(name: "Ain't noth'n like' \#stuff").first
792
+ end
793
+
794
+ 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
799
+ end
800
+
801
+ def test_hash_condition_find_with_nil
802
+ topic = Topic.where(last_read: nil).first
803
+ assert_not_nil topic
804
+ assert_nil topic.last_read
805
+ end
806
+
807
+ def test_hash_condition_find_with_aggregate_having_one_mapping
808
+ balance = customers(:david).balance
809
+ assert_kind_of Money, balance
810
+ found_customer = Customer.where(:balance => balance).first
811
+ assert_equal customers(:david), found_customer
812
+ end
813
+
814
+ def test_hash_condition_find_with_aggregate_attribute_having_same_name_as_field_and_key_value_being_aggregate
815
+ gps_location = customers(:david).gps_location
816
+ assert_kind_of GpsLocation, gps_location
817
+ found_customer = Customer.where(:gps_location => gps_location).first
818
+ assert_equal customers(:david), found_customer
819
+ end
820
+
821
+ def test_hash_condition_find_with_aggregate_having_one_mapping_and_key_value_being_attribute_value
822
+ balance = customers(:david).balance
823
+ assert_kind_of Money, balance
824
+ found_customer = Customer.where(:balance => balance.amount).first
825
+ assert_equal customers(:david), found_customer
826
+ end
827
+
828
+ def test_hash_condition_find_with_aggregate_attribute_having_same_name_as_field_and_key_value_being_attribute_value
829
+ gps_location = customers(:david).gps_location
830
+ assert_kind_of GpsLocation, gps_location
831
+ found_customer = Customer.where(:gps_location => gps_location.gps_location).first
832
+ assert_equal customers(:david), found_customer
833
+ end
834
+
835
+ def test_hash_condition_find_with_aggregate_having_three_mappings
836
+ address = customers(:david).address
837
+ assert_kind_of Address, address
838
+ found_customer = Customer.where(:address => address).first
839
+ assert_equal customers(:david), found_customer
840
+ end
841
+
842
+ def test_hash_condition_find_with_one_condition_being_aggregate_and_another_not
843
+ address = customers(:david).address
844
+ assert_kind_of Address, address
845
+ found_customer = Customer.where(:address => address, :name => customers(:david).name).first
846
+ assert_equal customers(:david), found_customer
847
+ end
848
+
849
+ def test_condition_utc_time_interpolation_with_default_timezone_local
850
+ with_env_tz 'America/New_York' do
851
+ with_timezone_config default: :local do
852
+ topic = Topic.first
853
+ assert_equal topic, Topic.where(['written_on = ?', topic.written_on.getutc]).first
854
+ end
855
+ end
856
+ end
857
+
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"
860
+ with_env_tz 'America/New_York' do
861
+ with_timezone_config default: :local do
862
+ topic = Topic.first
863
+ assert_equal topic, Topic.where(written_on: topic.written_on.getutc).first
864
+ end
865
+ end
866
+ end
867
+
868
+ 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
871
+ with_timezone_config default: :utc do
872
+ topic = Topic.first
873
+ assert_equal topic, Topic.where(['written_on = ?', topic.written_on.getlocal]).first
874
+ end
875
+ end
876
+ end
877
+
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"
880
+ with_env_tz 'America/New_York' do
881
+ with_timezone_config default: :utc do
882
+ topic = Topic.first
883
+ assert_equal topic, Topic.where(written_on: topic.written_on.getlocal).first
884
+ end
885
+ end
886
+ end
887
+
888
+ def test_bind_variables
889
+ assert_kind_of Firm, Company.where(["name = ?", "37signals"]).first
890
+ assert_nil Company.where(["name = ?", "37signals!"]).first
891
+ assert_nil Company.where(["name = ?", "37signals!' OR 1=1"]).first
892
+ assert_kind_of Time, Topic.where(["id = ?", 1]).first.written_on
893
+ assert_raise(ActiveRecord::PreparedStatementInvalid) {
894
+ Company.where(["id=? AND name = ?", 2]).first
895
+ }
896
+ assert_raise(ActiveRecord::PreparedStatementInvalid) {
897
+ Company.where(["id=?", 2, 3, 4]).first
898
+ }
899
+ end
900
+
901
+ 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
905
+ end
906
+
907
+ 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
911
+ end
912
+
913
+ def test_named_bind_variables
914
+ puts "finder_test.test_named_bind_variables"
915
+ assert_kind_of Firm, Company.where(["name = :name", { name: "37signals" }]).first
916
+ assert_nil Company.where(["name = :name", { name: "37signals!" }]).first
917
+ assert_nil Company.where(["name = :name", { name: "37signals!' OR 1=1" }]).first
918
+ assert_kind_of Time, Topic.where(["id = :id", { id: 1 }]).first.written_on
919
+ end
920
+
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
+ def test_count_by_sql
927
+ assert_equal(0, Entrant.count_by_sql("SELECT COUNT(*) FROM entrants WHERE id > 3"))
928
+ assert_equal(1, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 2]))
929
+ assert_equal(2, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 1]))
930
+ end
931
+
932
+ def test_find_by_one_attribute
933
+ assert_equal topics(:first), Topic.find_by_title("The First Topic")
934
+ assert_nil Topic.find_by_title("The First Topic!")
935
+ end
936
+
937
+ def test_find_by_one_attribute_bang
938
+ assert_equal topics(:first), Topic.find_by_title!("The First Topic")
939
+ assert_raises_with_message(ActiveRecord::RecordNotFound, "Couldn't find Topic") do
940
+ Topic.find_by_title!("The First Topic!")
941
+ end
942
+ end
943
+
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"
946
+ dog_alias = 'Dog'
947
+ dog = Dog.create(alias: dog_alias)
948
+
949
+ assert_equal dog, Dog.find_by_alias(dog_alias)
950
+ end
951
+
952
+ def test_find_by_one_attribute_that_is_an_alias
953
+ assert_equal topics(:first), Topic.find_by_heading("The First Topic")
954
+ assert_nil Topic.find_by_heading("The First Topic!")
955
+ end
956
+
957
+ def test_find_by_one_attribute_bang_with_blank_defined
958
+ puts "finder_test.test_find_by_one_attribute_bang_with_blank_defined"
959
+ blank_topic = BlankTopic.create(title: "The Blank One")
960
+ assert_equal blank_topic, BlankTopic.find_by_title!("The Blank One")
961
+ end
962
+
963
+ 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)
965
+ end
966
+
967
+ def test_find_by_one_attribute_that_is_an_aggregate
968
+ address = customers(:david).address
969
+ assert_kind_of Address, address
970
+ found_customer = Customer.find_by_address(address)
971
+ assert_equal customers(:david), found_customer
972
+ end
973
+
974
+ def test_find_by_one_attribute_that_is_an_aggregate_with_one_attribute_difference
975
+ address = customers(:david).address
976
+ assert_kind_of Address, address
977
+ missing_address = Address.new(address.street, address.city, address.country + "1")
978
+ assert_nil Customer.find_by_address(missing_address)
979
+ missing_address = Address.new(address.street, address.city + "1", address.country)
980
+ assert_nil Customer.find_by_address(missing_address)
981
+ missing_address = Address.new(address.street + "1", address.city, address.country)
982
+ assert_nil Customer.find_by_address(missing_address)
983
+ end
984
+
985
+ def test_find_by_two_attributes_that_are_both_aggregates
986
+ balance = customers(:david).balance
987
+ address = customers(:david).address
988
+ assert_kind_of Money, balance
989
+ assert_kind_of Address, address
990
+ found_customer = Customer.find_by_balance_and_address(balance, address)
991
+ assert_equal customers(:david), found_customer
992
+ end
993
+
994
+ def test_find_by_two_attributes_with_one_being_an_aggregate
995
+ balance = customers(:david).balance
996
+ assert_kind_of Money, balance
997
+ found_customer = Customer.find_by_balance_and_name(balance, customers(:david).name)
998
+ assert_equal customers(:david), found_customer
999
+ end
1000
+
1001
+ def test_dynamic_finder_on_one_attribute_with_conditions_returns_same_results_after_caching
1002
+ # 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
1006
+ end
1007
+
1008
+ 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)
1010
+ end
1011
+
1012
+ def test_find_by_one_missing_attribute
1013
+ assert_raise(NoMethodError) { Topic.find_by_undertitle("The First Topic!") }
1014
+ end
1015
+
1016
+ def test_find_by_invalid_method_syntax
1017
+ assert_raise(NoMethodError) { Topic.fail_to_find_by_title("The First Topic") }
1018
+ assert_raise(NoMethodError) { Topic.find_by_title?("The First Topic") }
1019
+ assert_raise(NoMethodError) { Topic.fail_to_find_or_create_by_title("Nonexistent Title") }
1020
+ assert_raise(NoMethodError) { Topic.find_or_create_by_title?("Nonexistent Title") }
1021
+ end
1022
+
1023
+ def test_find_by_two_attributes
1024
+ assert_equal topics(:first), Topic.find_by_title_and_author_name("The First Topic", "David")
1025
+ assert_nil Topic.find_by_title_and_author_name("The First Topic", "Mary")
1026
+ end
1027
+
1028
+ def test_find_by_two_attributes_but_passing_only_one
1029
+ assert_raise(ArgumentError) { Topic.find_by_title_and_author_name("The First Topic") }
1030
+ end
1031
+
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
+ def test_find_by_nil_attribute
1043
+ topic = Topic.find_by_last_read nil
1044
+ assert_not_nil topic
1045
+ assert_nil topic.last_read
1046
+ end
1047
+
1048
+ def test_find_by_nil_and_not_nil_attributes
1049
+ topic = Topic.find_by_last_read_and_author_name nil, "Mary"
1050
+ assert_equal "Mary", topic.author_name
1051
+ end
1052
+
1053
+ def test_find_with_bad_sql
1054
+ assert_raise(ActiveRecord::StatementInvalid) { Topic.find_by_sql "select 1 from badtable" }
1055
+ end
1056
+
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
+ def test_joins_dont_clobber_id
1068
+ first = Firm.
1069
+ joins('INNER JOIN companies clients ON clients.firm_id = companies.id').
1070
+ where('companies.id = 1').first
1071
+ assert_equal 1, first.id
1072
+ end
1073
+
1074
+ def test_joins_with_string_array
1075
+ person_with_reader_and_post = Post.
1076
+ joins(["INNER JOIN categorizations ON categorizations.post_id = posts.id",
1077
+ "INNER JOIN categories ON categories.id = categorizations.category_id AND categories.type = 'SpecialCategory'"
1078
+ ])
1079
+ assert_equal 1, person_with_reader_and_post.size
1080
+ end
1081
+
1082
+ def test_find_by_id_with_conditions_with_or
1083
+ assert_nothing_raised do
1084
+ Post.where("posts.id <= 3 OR posts.#{QUOTED_TYPE} = 'Post'").find([1,2,3])
1085
+ end
1086
+ end
1087
+
1088
+ 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')
1091
+ assert_equal [], Post.where(id: nil)
1092
+ end
1093
+
1094
+ def test_find_by_empty_ids
1095
+ assert_equal [], Post.find([])
1096
+ end
1097
+
1098
+ def test_find_by_empty_in_condition
1099
+ assert_equal [], Post.where('id in (?)', [])
1100
+ end
1101
+
1102
+ 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')
1107
+ end
1108
+
1109
+ def test_select_value
1110
+ assert_equal "37signals", Company.connection.select_value("SELECT name FROM companies WHERE id = 1")
1111
+ assert_nil Company.connection.select_value("SELECT name FROM companies WHERE id = -1")
1112
+ # make sure we didn't break count...
1113
+ assert_equal 0, Company.count_by_sql("SELECT COUNT(*) FROM companies WHERE name = 'Halliburton'")
1114
+ assert_equal 1, Company.count_by_sql("SELECT COUNT(*) FROM companies WHERE name = '37signals'")
1115
+ end
1116
+
1117
+ 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")
1120
+ end
1121
+
1122
+ def test_select_rows
1123
+ assert_equal(
1124
+ [["1", "1", nil, "37signals"],
1125
+ ["2", "1", "2", "Summit"],
1126
+ ["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?}})
1128
+ 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?}}
1130
+ end
1131
+
1132
+ 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
+ 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
1137
+
1138
+ assert_equal 3, Post.includes(author: :author_address, authors: :author_address).
1139
+ where.not(author_addresses_authors: { id: nil }).
1140
+ order('author_addresses_authors.id DESC').limit(3).to_a.size
1141
+ end
1142
+
1143
+ def test_find_with_nil_inside_set_passed_for_one_attribute
1144
+ client_of = Company.
1145
+ where(client_of: [2, 1, nil],
1146
+ name: ['37signals', 'Summit', 'Microsoft']).
1147
+ order('client_of DESC').
1148
+ map(&:client_of)
1149
+
1150
+ assert client_of.include?(nil)
1151
+ assert_equal [2, 1].sort, client_of.compact.sort
1152
+ end
1153
+
1154
+ def test_find_with_nil_inside_set_passed_for_attribute
1155
+ client_of = Company.
1156
+ where(client_of: [nil]).
1157
+ order('client_of DESC').
1158
+ map(&:client_of)
1159
+
1160
+ assert_equal [], client_of.compact
1161
+ end
1162
+
1163
+ def test_with_limiting_with_custom_select
1164
+ puts "finder_test.test_with_limiting_with_custom_select"
1165
+ posts = Post.references(:authors).merge(
1166
+ :includes => :author, :select => 'posts.*, authors.id as "author_id"',
1167
+ :limit => 3, :order => 'posts.id'
1168
+ ).to_a
1169
+ assert_equal 3, posts.size
1170
+ assert_equal [0, 1, 1], posts.map(&:author_id).sort
1171
+ end
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
+
1183
+ def test_find_one_message_with_custom_primary_key
1184
+ table_with_custom_primary_key do |model|
1185
+ model.primary_key = :name
1186
+ e = assert_raises(ActiveRecord::RecordNotFound) do
1187
+ model.find 'Hello World!'
1188
+ end
1189
+ assert_equal %Q{Couldn't find MercedesCar with 'name'=Hello World!}, e.message
1190
+ end
1191
+ end
1192
+
1193
+ def test_find_some_message_with_custom_primary_key
1194
+ table_with_custom_primary_key do |model|
1195
+ model.primary_key = :name
1196
+ e = assert_raises(ActiveRecord::RecordNotFound) do
1197
+ model.find 'Hello', 'World!'
1198
+ end
1199
+ assert_equal %Q{Couldn't find all MercedesCars with 'name': (Hello, World!) (found 0 results, but was looking for 2)}, e.message
1200
+ end
1201
+ end
1202
+
1203
+ def test_find_without_primary_key
1204
+ assert_raises(ActiveRecord::UnknownPrimaryKey) do
1205
+ Matey.find(1)
1206
+ end
1207
+ end
1208
+
1209
+ def test_finder_with_offset_string
1210
+ assert_nothing_raised { Topic.offset("3").to_a }
1211
+ end
1212
+
1213
+ test "find_by with hash conditions returns the first matching record" do
1214
+ assert_equal posts(:eager_other), Post.find_by(id: posts(:eager_other).id)
1215
+ end
1216
+
1217
+ test "find_by with non-hash conditions returns the first matching record" do
1218
+ assert_equal posts(:eager_other), Post.find_by("id = #{posts(:eager_other).id}")
1219
+ end
1220
+
1221
+ 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)
1223
+ end
1224
+
1225
+ test "find_by returns nil if the record is missing" do
1226
+ assert_equal nil, Post.find_by("1 = 0")
1227
+ end
1228
+
1229
+ test "find_by with associations" do
1230
+ assert_equal authors(:david), Post.find_by(author: authors(:david)).author
1231
+ assert_equal authors(:mary) , Post.find_by(author: authors(:mary) ).author
1232
+ end
1233
+
1234
+ test "find_by doesn't have implicit ordering" do
1235
+ assert_sql(/^((?!ORDER).)*$/) { Post.find_by(id: posts(:eager_other).id) }
1236
+ end
1237
+
1238
+ test "find_by! with hash conditions returns the first matching record" do
1239
+ assert_equal posts(:eager_other), Post.find_by!(id: posts(:eager_other).id)
1240
+ end
1241
+
1242
+ test "find_by! with non-hash conditions returns the first matching record" do
1243
+ assert_equal posts(:eager_other), Post.find_by!("id = #{posts(:eager_other).id}")
1244
+ end
1245
+
1246
+ 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)
1248
+ end
1249
+
1250
+ test "find_by! doesn't have implicit ordering" do
1251
+ assert_sql(/^((?!ORDER).)*$/) { Post.find_by!(id: posts(:eager_other).id) }
1252
+ end
1253
+
1254
+ test "find_by! raises RecordNotFound if the record is missing" do
1255
+ assert_raises(ActiveRecord::RecordNotFound) do
1256
+ Post.find_by!("1 = 0")
1257
+ end
1258
+ end
1259
+
1260
+ test "find on a scope does not perform statement caching" do
1261
+ honda = cars(:honda)
1262
+ zyke = cars(:zyke)
1263
+ tyre = honda.tyres.create!
1264
+ tyre2 = zyke.tyres.create!
1265
+
1266
+ assert_equal tyre, honda.tyres.custom_find(tyre.id)
1267
+ assert_equal tyre2, zyke.tyres.custom_find(tyre2.id)
1268
+ end
1269
+
1270
+ test "find_by on a scope does not perform statement caching" do
1271
+ honda = cars(:honda)
1272
+ zyke = cars(:zyke)
1273
+ tyre = honda.tyres.create!
1274
+ tyre2 = zyke.tyres.create!
1275
+
1276
+ assert_equal tyre, honda.tyres.custom_find_by(id: tyre.id)
1277
+ assert_equal tyre2, zyke.tyres.custom_find_by(id: tyre2.id)
1278
+ end
1279
+
1280
+ protected
1281
+ def table_with_custom_primary_key
1282
+ yield(Class.new(Toy) do
1283
+ def self.name
1284
+ 'MercedesCar'
1285
+ end
1286
+ end)
1287
+ end
1288
+
1289
+ def assert_raises_with_message(exception_class, message, &block)
1290
+ err = assert_raises(exception_class) { block.call }
1291
+ assert_match message, err.message
1292
+ end
1293
+
1294
+ end