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,44 +1,44 @@
1
- require "cases/helper"
2
-
3
- # Without using prepared statements, it makes no sense to test
4
- # BLOB data with DB2, because the length of a statement
5
- # is limited to 32KB.
6
- unless current_adapter?(:DB2Adapter)
7
- require 'models/binary'
8
-
9
- class BinaryTest < ActiveRecord::TestCase
10
- FIXTURES = %w(flowers.jpg example.log test.txt)
11
-
12
- def test_mixed_encoding
13
- str = "\x80"
14
- str.force_encoding('ASCII-8BIT')
15
-
16
- binary = Binary.new :name => 'いただきます!', :data => str
17
- binary.save!
18
- binary.reload
19
- assert_equal str, binary.data
20
-
21
- name = binary.name
22
-
23
- assert_equal 'いただきます!', name
24
- end
25
-
26
- def test_load_save
27
- Binary.delete_all
28
-
29
- FIXTURES.each do |filename|
30
- data = File.read(ASSETS_ROOT + "/#{filename}")
31
- data.force_encoding('ASCII-8BIT')
32
- data.freeze
33
-
34
- bin = Binary.new(:data => data)
35
- assert_equal data, bin.data, 'Newly assigned data differs from original'
36
-
37
- bin.save!
38
- assert_equal data, bin.data, 'Data differs from original after save'
39
-
40
- assert_equal data, bin.reload.data, 'Reloaded data differs from original'
41
- end
42
- end
43
- end
44
- end
1
+ require "cases/helper"
2
+
3
+ # Without using prepared statements, it makes no sense to test
4
+ # BLOB data with DB2, because the length of a statement
5
+ # is limited to 32KB.
6
+ unless current_adapter?(:DB2Adapter)
7
+ require 'models/binary'
8
+
9
+ class BinaryTest < ActiveRecord::TestCase
10
+ FIXTURES = %w(flowers.jpg example.log test.txt)
11
+
12
+ def test_mixed_encoding
13
+ str = "\x80"
14
+ str.force_encoding('ASCII-8BIT')
15
+
16
+ binary = Binary.new :name => 'いただきます!', :data => str
17
+ binary.save!
18
+ binary.reload
19
+ assert_equal str, binary.data
20
+
21
+ name = binary.name
22
+
23
+ assert_equal 'いただきます!', name
24
+ end
25
+
26
+ def test_load_save
27
+ Binary.delete_all
28
+
29
+ FIXTURES.each do |filename|
30
+ data = File.read(ASSETS_ROOT + "/#{filename}")
31
+ data.force_encoding('ASCII-8BIT')
32
+ data.freeze
33
+
34
+ bin = Binary.new(:data => data)
35
+ assert_equal data, bin.data, 'Newly assigned data differs from original'
36
+
37
+ bin.save!
38
+ assert_equal data, bin.data, 'Data differs from original after save'
39
+
40
+ assert_equal data, bin.reload.data, 'Reloaded data differs from original'
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,110 +1,110 @@
1
- require 'cases/helper'
2
- require 'models/topic'
3
- require 'models/author'
4
- require 'models/post'
5
-
6
- if ActiveRecord::Base.connection.supports_statement_cache? &&
7
- ActiveRecord::Base.connection.prepared_statements
8
- module ActiveRecord
9
- class BindParameterTest < ActiveRecord::TestCase
10
- fixtures :topics, :authors, :posts
11
-
12
- class LogListener
13
- attr_accessor :calls
14
-
15
- def initialize
16
- @calls = []
17
- end
18
-
19
- def call(*args)
20
- calls << args
21
- end
22
- end
23
-
24
- def setup
25
- super
26
- puts "BindParameterTest - setup"
27
- @connection = ActiveRecord::Base.connection
28
- @subscriber = LogListener.new
29
- @pk = Topic.columns_hash[Topic.primary_key]
30
- @subscription = ActiveSupport::Notifications.subscribe("sql.active_record", @subscriber)
31
- end
32
-
33
- def teardown
34
- puts "BindParameterTest - teardown"
35
- ActiveSupport::Notifications.unsubscribe(@subscription)
36
- end
37
-
38
- def test_bind_from_join_in_subquery
39
- puts "BindParameterTest - test_bind_from_join_in_subquery"
40
- subquery = Author.joins(:thinking_posts).where(name: 'David')
41
- scope = Author.from(subquery, 'authors').where(id: 1)
42
- assert_equal 1, scope.count
43
- end
44
-
45
- def test_binds_are_logged
46
- puts "BindParameterTest - test_binds_are_logged"
47
- sub = Arel::Nodes::BindParam.new
48
- binds = [Relation::QueryAttribute.new("id", 1, Type::Value.new)]
49
- sql = "select * from topics where id = #{sub.to_sql}"
50
-
51
- @connection.exec_query(sql, 'SQL', binds)
52
-
53
- message = @subscriber.calls.find { |args| args[4][:sql] == sql }
54
- assert_equal binds, message[4][:binds]
55
- end
56
-
57
- def test_find_one_uses_binds
58
- puts "BindParameterTest - test_find_one_uses_binds"
59
- Topic.find(1)
60
- message = @subscriber.calls.find { |args| args[4][:binds].any? { |attr| attr.value == 1 } }
61
- assert message, 'expected a message with binds'
62
- end
63
-
64
- def test_logs_binds_after_type_cast
65
- puts "BindParameterTest - test_logs_binds_after_type_cast"
66
- binds = [Relation::QueryAttribute.new("id", "10", Type::Integer.new)]
67
- assert_logs_binds(binds)
68
- end
69
-
70
- def test_logs_legacy_binds_after_type_cast
71
- puts "BindParameterTest - test_logs_legacy_binds_after_type_cast"
72
- binds = [[@pk, "10"]]
73
- assert_logs_binds(binds)
74
- end
75
-
76
- private
77
- def assert_logs_binds(binds)
78
- payload = {
79
- name: "SQL",
80
- sql: "select * from topics where id = ?",
81
- binds: binds,
82
- type_casted_binds: @connection.type_casted_binds(binds)
83
- }
84
-
85
- event = ActiveSupport::Notifications::Event.new(
86
- "foo",
87
- Time.now,
88
- Time.now,
89
- 123,
90
- payload)
91
-
92
- logger = Class.new(ActiveRecord::LogSubscriber) {
93
- attr_reader :debugs
94
-
95
- def initialize
96
- super
97
- @debugs = []
98
- end
99
-
100
- def debug(str)
101
- @debugs << str
102
- end
103
- }.new
104
-
105
- logger.sql(event)
106
- assert_match([[@pk.name, 10]].inspect, logger.debugs.first)
107
- end
108
- end
109
- end
110
- end
1
+ require 'cases/helper'
2
+ require 'models/topic'
3
+ require 'models/author'
4
+ require 'models/post'
5
+
6
+ if ActiveRecord::Base.connection.supports_statement_cache? &&
7
+ ActiveRecord::Base.connection.prepared_statements
8
+ module ActiveRecord
9
+ class BindParameterTest < ActiveRecord::TestCase
10
+ fixtures :topics, :authors, :posts
11
+
12
+ class LogListener
13
+ attr_accessor :calls
14
+
15
+ def initialize
16
+ @calls = []
17
+ end
18
+
19
+ def call(*args)
20
+ calls << args
21
+ end
22
+ end
23
+
24
+ def setup
25
+ super
26
+ puts "BindParameterTest - setup"
27
+ @connection = ActiveRecord::Base.connection
28
+ @subscriber = LogListener.new
29
+ @pk = Topic.columns_hash[Topic.primary_key]
30
+ @subscription = ActiveSupport::Notifications.subscribe("sql.active_record", @subscriber)
31
+ end
32
+
33
+ def teardown
34
+ puts "BindParameterTest - teardown"
35
+ ActiveSupport::Notifications.unsubscribe(@subscription)
36
+ end
37
+
38
+ def test_bind_from_join_in_subquery
39
+ puts "BindParameterTest - test_bind_from_join_in_subquery"
40
+ subquery = Author.joins(:thinking_posts).where(name: 'David')
41
+ scope = Author.from(subquery, 'authors').where(id: 1)
42
+ assert_equal 1, scope.count
43
+ end
44
+
45
+ def test_binds_are_logged
46
+ puts "BindParameterTest - test_binds_are_logged"
47
+ sub = Arel::Nodes::BindParam.new
48
+ binds = [Relation::QueryAttribute.new("id", 1, Type::Value.new)]
49
+ sql = "select * from topics where id = #{sub.to_sql}"
50
+
51
+ @connection.exec_query(sql, 'SQL', binds)
52
+
53
+ message = @subscriber.calls.find { |args| args[4][:sql] == sql }
54
+ assert_equal binds, message[4][:binds]
55
+ end
56
+
57
+ def test_find_one_uses_binds
58
+ puts "BindParameterTest - test_find_one_uses_binds"
59
+ Topic.find(1)
60
+ message = @subscriber.calls.find { |args| args[4][:binds].any? { |attr| attr.value == 1 } }
61
+ assert message, 'expected a message with binds'
62
+ end
63
+
64
+ def test_logs_binds_after_type_cast
65
+ puts "BindParameterTest - test_logs_binds_after_type_cast"
66
+ binds = [Relation::QueryAttribute.new("id", "10", Type::Integer.new)]
67
+ assert_logs_binds(binds)
68
+ end
69
+
70
+ def test_logs_legacy_binds_after_type_cast
71
+ puts "BindParameterTest - test_logs_legacy_binds_after_type_cast"
72
+ binds = [[@pk, "10"]]
73
+ assert_logs_binds(binds)
74
+ end
75
+
76
+ private
77
+ def assert_logs_binds(binds)
78
+ payload = {
79
+ name: "SQL",
80
+ sql: "select * from topics where id = ?",
81
+ binds: binds,
82
+ type_casted_binds: @connection.type_casted_binds(binds)
83
+ }
84
+
85
+ event = ActiveSupport::Notifications::Event.new(
86
+ "foo",
87
+ Time.now,
88
+ Time.now,
89
+ 123,
90
+ payload)
91
+
92
+ logger = Class.new(ActiveRecord::LogSubscriber) {
93
+ attr_reader :debugs
94
+
95
+ def initialize
96
+ super
97
+ @debugs = []
98
+ end
99
+
100
+ def debug(str)
101
+ @debugs << str
102
+ end
103
+ }.new
104
+
105
+ logger.sql(event)
106
+ assert_match([[@pk.name, 10]].inspect, logger.debugs.first)
107
+ end
108
+ end
109
+ end
110
+ end
@@ -1,25 +1,26 @@
1
- require "cases/helper"
2
-
3
- module ActiveRecord
4
- class CacheKeyTest < ActiveRecord::TestCase
5
- self.use_transactional_tests = false
6
-
7
- class CacheMe < ActiveRecord::Base; end
8
-
9
- setup do
10
- @connection = ActiveRecord::Base.connection
11
- @connection.create_table(:cache_mes) { |t| t.timestamps }
12
- end
13
-
14
- teardown do
15
- @connection.drop_table :cache_mes, if_exists: true
16
- end
17
-
18
- test "test_cache_key_format_is_not_too_precise" do
19
- record = CacheMe.create
20
- key = record.cache_key
21
-
22
- assert_equal key, record.reload.cache_key
23
- end
24
- end
25
- end
1
+ require "cases/helper"
2
+
3
+ module ActiveRecord
4
+ class CacheKeyTest < ActiveRecord::TestCase
5
+ self.use_transactional_tests = false
6
+
7
+ class CacheMe < ActiveRecord::Base; end
8
+
9
+ setup do
10
+ @connection = ActiveRecord::Base.connection
11
+ @connection.create_table(:cache_mes) { |t| t.timestamps }
12
+ end
13
+
14
+ teardown do
15
+ @connection.drop_table :cache_mes
16
+ #, if_exists: true
17
+ end
18
+
19
+ test "test_cache_key_format_is_not_too_precise" do
20
+ record = CacheMe.create
21
+ key = record.cache_key
22
+
23
+ assert_equal key, record.reload.cache_key
24
+ end
25
+ end
26
+ end
@@ -1,798 +1,798 @@
1
- require "cases/helper"
2
- require "models/book"
3
- require 'models/club'
4
- require 'models/company'
5
- require "models/contract"
6
- require 'models/edge'
7
- require 'models/organization'
8
- require 'models/possession'
9
- require 'models/topic'
10
- require 'models/reply'
11
- require 'models/minivan'
12
- require 'models/speedometer'
13
- require 'models/ship_part'
14
- require 'models/treasure'
15
- require 'models/developer'
16
- require 'models/comment'
17
- require 'models/rating'
18
- require 'models/post'
19
-
20
- class NumericData < ActiveRecord::Base
21
- self.table_name = 'numeric_data'
22
-
23
- attribute :world_population, :integer
24
- attribute :my_house_population, :integer
25
- attribute :atoms_in_universe, :integer
26
- end
27
-
28
- class CalculationsTest < ActiveRecord::TestCase
29
- fixtures :companies, :accounts, :topics, :speedometers, :minivans, :books
30
-
31
- def test_should_sum_field
32
- assert_equal 318, Account.sum(:credit_limit)
33
- end
34
-
35
- def test_should_sum_arel_attribute
36
- assert_equal 318, Account.sum(Account.arel_table[:credit_limit])
37
- end
38
-
39
- def test_should_average_field
40
- value = Account.average(:credit_limit)
41
- assert_equal 53.0, value
42
- end
43
-
44
- def test_should_average_arel_attribute
45
- value = Account.average(Account.arel_table[:credit_limit])
46
- assert_equal 53.0, value
47
- end
48
-
49
- def test_should_resolve_aliased_attributes
50
- assert_equal 318, Account.sum(:available_credit)
51
- end
52
-
53
- def test_should_return_decimal_average_of_integer_field
54
- value = Account.average(:id)
55
- assert_equal 3.5, value
56
- end
57
-
58
- def test_should_return_integer_average_if_db_returns_such
59
- ShipPart.delete_all
60
- ShipPart.create!(:id => 3, :name => 'foo')
61
- value = ShipPart.average(:id)
62
- assert_equal 3, value
63
- end
64
-
65
- def test_should_return_nil_as_average
66
- assert_nil NumericData.average(:bank_balance)
67
- end
68
-
69
- def test_should_get_maximum_of_field
70
- assert_equal 60, Account.maximum(:credit_limit)
71
- end
72
-
73
- def test_should_get_maximum_of_arel_attribute
74
- assert_equal 60, Account.maximum(Account.arel_table[:credit_limit])
75
- end
76
-
77
- def test_should_get_maximum_of_field_with_include
78
- assert_equal 55, Account.where("companies.name != 'Summit'").references(:companies).includes(:firm).maximum(:credit_limit)
79
- end
80
-
81
- def test_should_get_maximum_of_arel_attribute_with_include
82
- assert_equal 55, Account.where("companies.name != 'Summit'").references(:companies).includes(:firm).maximum(Account.arel_table[:credit_limit])
83
- end
84
-
85
- def test_should_get_minimum_of_field
86
- assert_equal 50, Account.minimum(:credit_limit)
87
- end
88
-
89
- def test_should_get_minimum_of_arel_attribute
90
- assert_equal 50, Account.minimum(Account.arel_table[:credit_limit])
91
- end
92
-
93
- def test_should_group_by_field
94
- c = Account.group(:firm_id).sum(:credit_limit)
95
- [1,6,2].each do |firm_id|
96
- assert c.keys.include?(firm_id), "Group #{c.inspect} does not contain firm_id #{firm_id}"
97
- end
98
- end
99
-
100
- def test_should_group_by_arel_attribute
101
- c = Account.group(Account.arel_table[:firm_id]).sum(:credit_limit)
102
- [1,6,2].each do |firm_id|
103
- assert c.keys.include?(firm_id), "Group #{c.inspect} does not contain firm_id #{firm_id}"
104
- end
105
- end
106
-
107
- def test_should_group_by_multiple_fields
108
- c = Account.group('firm_id', :credit_limit).count(:all)
109
- [ [nil, 50], [1, 50], [6, 50], [6, 55], [9, 53], [2, 60] ].each { |firm_and_limit| assert c.keys.include?(firm_and_limit) }
110
- end
111
-
112
- def test_should_group_by_multiple_fields_having_functions
113
- c = Topic.group(:author_name, 'COALESCE(type, title)').count(:all)
114
- assert_equal 1, c[["Carl", "The Third Topic of the day"]]
115
- assert_equal 1, c[["Mary", "Reply"]]
116
- assert_equal 1, c[["David", "The First Topic"]]
117
- assert_equal 1, c[["Carl", "Reply"]]
118
- end
119
-
120
- def test_should_group_by_summed_field
121
- c = Account.group(:firm_id).sum(:credit_limit)
122
- assert_equal 50, c[1]
123
- assert_equal 105, c[6]
124
- assert_equal 60, c[2]
125
- end
126
-
127
- def test_should_generate_valid_sql_with_joins_and_group
128
- assert_nothing_raised do
129
- AuditLog.joins(:developer).group(:id).count
130
- end
131
- end
132
-
133
- def test_should_calculate_against_given_relation
134
- developer = Developer.create!(name: "developer")
135
- developer.audit_logs.create!(message: "first log")
136
- developer.audit_logs.create!(message: "second log")
137
-
138
- c = developer.audit_logs.joins(:developer).group(:id).count
139
-
140
- assert_equal developer.audit_logs.count, c.size
141
- developer.audit_logs.each do |log|
142
- assert_equal 1, c[log.id]
143
- end
144
- end
145
-
146
- def test_should_order_by_grouped_field
147
- c = Account.group(:firm_id).order("firm_id").sum(:credit_limit)
148
- assert_equal [1, 2, 6, 9], c.keys.compact
149
- end
150
-
151
- def test_should_order_by_calculation
152
- c = Account.group(:firm_id).order("sum_credit_limit desc, firm_id").sum(:credit_limit)
153
- assert_equal [105, 60, 53, 50, 50], c.keys.collect { |k| c[k] }
154
- assert_equal [6, 2, 9, 1], c.keys.compact
155
- end
156
-
157
- def test_should_limit_calculation
158
- c = Account.where("firm_id IS NOT NULL").group(:firm_id).order("firm_id").limit(2).sum(:credit_limit)
159
- assert_equal [1, 2], c.keys.compact
160
- end
161
-
162
- def test_should_limit_calculation_with_offset
163
- c = Account.where("firm_id IS NOT NULL").group(:firm_id).order("firm_id").
164
- limit(2).offset(1).sum(:credit_limit)
165
- assert_equal [2, 6], c.keys.compact
166
- end
167
-
168
- def test_limit_should_apply_before_count
169
- accounts = Account.limit(3).where('firm_id IS NOT NULL')
170
-
171
- assert_equal 3, accounts.count(:firm_id)
172
- assert_equal 3, accounts.select(:firm_id).count
173
- end
174
-
175
- def test_limit_should_apply_before_count_arel_attribute
176
- accounts = Account.limit(3).where('firm_id IS NOT NULL')
177
-
178
- firm_id_attribute = Account.arel_table[:firm_id]
179
- assert_equal 3, accounts.count(firm_id_attribute)
180
- assert_equal 3, accounts.select(firm_id_attribute).count
181
- end
182
-
183
- def test_count_should_shortcut_with_limit_zero
184
- accounts = Account.limit(0)
185
-
186
- assert_no_queries { assert_equal 0, accounts.count }
187
- end
188
-
189
- def test_limit_is_kept
190
- return if current_adapter?(:OracleAdapter)
191
-
192
- queries = assert_sql { Account.limit(1).count }
193
- assert_equal 1, queries.length
194
- assert_match(/LIMIT/, queries.first)
195
- end
196
-
197
- def test_offset_is_kept
198
- return if current_adapter?(:OracleAdapter)
199
-
200
- queries = assert_sql { Account.offset(1).count }
201
- assert_equal 1, queries.length
202
- assert_match(/OFFSET/, queries.first)
203
- end
204
-
205
- def test_limit_with_offset_is_kept
206
- return if current_adapter?(:OracleAdapter)
207
-
208
- queries = assert_sql { Account.limit(1).offset(1).count }
209
- assert_equal 1, queries.length
210
- assert_match(/LIMIT/, queries.first)
211
- assert_match(/OFFSET/, queries.first)
212
- end
213
-
214
- def test_no_limit_no_offset
215
- queries = assert_sql { Account.count }
216
- assert_equal 1, queries.length
217
- assert_no_match(/LIMIT/, queries.first)
218
- assert_no_match(/OFFSET/, queries.first)
219
- end
220
-
221
- def test_count_on_invalid_columns_raises
222
- e = assert_raises(ActiveRecord::StatementInvalid) {
223
- Account.select("credit_limit, firm_name").count
224
- }
225
-
226
- assert_match %r{accounts}i, e.message
227
- assert_match "credit_limit, firm_name", e.message
228
- end
229
-
230
- def test_should_group_by_summed_field_having_condition
231
- c = Account.group(:firm_id).having('sum(credit_limit) > 50').sum(:credit_limit)
232
- assert_nil c[1]
233
- assert_equal 105, c[6]
234
- assert_equal 60, c[2]
235
- end
236
-
237
- def test_should_group_by_summed_field_having_condition_from_select
238
- skip unless current_adapter?(:Mysql2Adapter, :SQLite3Adapter)
239
- c = Account.select("MIN(credit_limit) AS min_credit_limit").group(:firm_id).having("min_credit_limit > 50").sum(:credit_limit)
240
- assert_nil c[1]
241
- assert_equal 60, c[2]
242
- assert_equal 53, c[9]
243
- end
244
-
245
- def test_should_group_by_summed_association
246
- c = Account.group(:firm).sum(:credit_limit)
247
- assert_equal 50, c[companies(:first_firm)]
248
- assert_equal 105, c[companies(:rails_core)]
249
- assert_equal 60, c[companies(:first_client)]
250
- end
251
-
252
- def test_should_sum_field_with_conditions
253
- assert_equal 105, Account.where('firm_id = 6').sum(:credit_limit)
254
- end
255
-
256
- def test_should_return_zero_if_sum_conditions_return_nothing
257
- assert_equal 0, Account.where('1 = 2').sum(:credit_limit)
258
- assert_equal 0, companies(:rails_core).companies.where('1 = 2').sum(:id)
259
- end
260
-
261
- def test_sum_should_return_valid_values_for_decimals
262
- NumericData.create(:bank_balance => 19.83)
263
- assert_equal 19.83, NumericData.sum(:bank_balance)
264
- end
265
-
266
- def test_should_return_type_casted_values_with_group_and_expression
267
- assert_equal 0.5, Account.group(:firm_name).sum('0.01 * credit_limit')['37signals']
268
- end
269
-
270
- def test_should_group_by_summed_field_with_conditions
271
- c = Account.where('firm_id > 1').group(:firm_id).sum(:credit_limit)
272
- assert_nil c[1]
273
- assert_equal 105, c[6]
274
- assert_equal 60, c[2]
275
- end
276
-
277
- def test_should_group_by_summed_field_with_conditions_and_having
278
- c = Account.where('firm_id > 1').group(:firm_id).
279
- having('sum(credit_limit) > 60').sum(:credit_limit)
280
- assert_nil c[1]
281
- assert_equal 105, c[6]
282
- assert_nil c[2]
283
- end
284
-
285
- def test_should_group_by_fields_with_table_alias
286
- c = Account.group('accounts.firm_id').sum(:credit_limit)
287
- assert_equal 50, c[1]
288
- assert_equal 105, c[6]
289
- assert_equal 60, c[2]
290
- end
291
-
292
- def test_should_calculate_with_invalid_field
293
- assert_equal 6, Account.calculate(:count, '*')
294
- assert_equal 6, Account.calculate(:count, :all)
295
- end
296
-
297
- def test_should_calculate_grouped_with_invalid_field
298
- c = Account.group('accounts.firm_id').count(:all)
299
- assert_equal 1, c[1]
300
- assert_equal 2, c[6]
301
- assert_equal 1, c[2]
302
- end
303
-
304
- def test_should_calculate_grouped_association_with_invalid_field
305
- c = Account.group(:firm).count(:all)
306
- assert_equal 1, c[companies(:first_firm)]
307
- assert_equal 2, c[companies(:rails_core)]
308
- assert_equal 1, c[companies(:first_client)]
309
- end
310
-
311
- def test_should_group_by_association_with_non_numeric_foreign_key
312
- Speedometer.create! id: 'ABC'
313
- Minivan.create! id: 'OMG', speedometer_id: 'ABC'
314
-
315
- c = Minivan.group(:speedometer).count(:all)
316
- first_key = c.keys.first
317
- assert_equal Speedometer, first_key.class
318
- assert_equal 1, c[first_key]
319
- end
320
-
321
- def test_should_calculate_grouped_association_with_foreign_key_option
322
- Account.belongs_to :another_firm, :class_name => 'Firm', :foreign_key => 'firm_id'
323
- c = Account.group(:another_firm).count(:all)
324
- assert_equal 1, c[companies(:first_firm)]
325
- assert_equal 2, c[companies(:rails_core)]
326
- assert_equal 1, c[companies(:first_client)]
327
- end
328
-
329
- def test_should_calculate_grouped_by_function
330
- c = Company.group("UPPER(#{QUOTED_TYPE})").count(:all)
331
- assert_equal 2, c[nil]
332
- assert_equal 1, c['DEPENDENTFIRM']
333
- assert_equal 5, c['CLIENT']
334
- assert_equal 2, c['FIRM']
335
- end
336
-
337
- def test_should_calculate_grouped_by_function_with_table_alias
338
- c = Company.group("UPPER(companies.#{QUOTED_TYPE})").count(:all)
339
- assert_equal 2, c[nil]
340
- assert_equal 1, c['DEPENDENTFIRM']
341
- assert_equal 5, c['CLIENT']
342
- assert_equal 2, c['FIRM']
343
- end
344
-
345
- def test_should_not_overshadow_enumerable_sum
346
- assert_equal 6, [1, 2, 3].sum(&:abs)
347
- end
348
-
349
- def test_should_sum_scoped_field
350
- assert_equal 15, companies(:rails_core).companies.sum(:id)
351
- end
352
-
353
- def test_should_sum_scoped_field_with_from
354
- assert_equal Club.count, Organization.clubs.count
355
- end
356
-
357
- def test_should_sum_scoped_field_with_conditions
358
- assert_equal 8, companies(:rails_core).companies.where('id > 7').sum(:id)
359
- end
360
-
361
- def test_should_group_by_scoped_field
362
- c = companies(:rails_core).companies.group(:name).sum(:id)
363
- assert_equal 7, c['Leetsoft']
364
- assert_equal 8, c['Jadedpixel']
365
- end
366
-
367
- def test_should_group_by_summed_field_through_association_and_having
368
- c = companies(:rails_core).companies.group(:name).having('sum(id) > 7').sum(:id)
369
- assert_nil c['Leetsoft']
370
- assert_equal 8, c['Jadedpixel']
371
- end
372
-
373
- def test_should_count_selected_field_with_include
374
- assert_equal 6, Account.includes(:firm).distinct.count
375
- assert_equal 4, Account.includes(:firm).distinct.select(:credit_limit).count
376
- end
377
-
378
- def test_should_not_perform_joined_include_by_default
379
- assert_equal Account.count, Account.includes(:firm).count
380
- queries = assert_sql { Account.includes(:firm).count }
381
- assert_no_match(/join/i, queries.last)
382
- end
383
-
384
- def test_should_perform_joined_include_when_referencing_included_tables
385
- joined_count = Account.includes(:firm).where(:companies => {:name => '37signals'}).count
386
- assert_equal 1, joined_count
387
- end
388
-
389
- def test_should_count_scoped_select
390
- Account.update_all("credit_limit = NULL")
391
- assert_equal 0, Account.select("credit_limit").count
392
- end
393
-
394
- def test_should_count_scoped_select_with_options
395
- Account.update_all("credit_limit = NULL")
396
- Account.last.update_columns('credit_limit' => 49)
397
- Account.first.update_columns('credit_limit' => 51)
398
-
399
- assert_equal 1, Account.select("credit_limit").where('credit_limit >= 50').count
400
- end
401
-
402
- def test_should_count_manual_select_with_include
403
- assert_equal 6, Account.select("DISTINCT accounts.id").includes(:firm).count
404
- end
405
-
406
- def test_count_selected_arel_attribute
407
- assert_equal 5, Account.select(Account.arel_table[:firm_id]).count
408
- assert_equal 4, Account.distinct.select(Account.arel_table[:firm_id]).count
409
- end
410
-
411
- def test_count_with_column_parameter
412
- assert_equal 5, Account.count(:firm_id)
413
- end
414
-
415
- def test_count_with_arel_attribute
416
- assert_equal 5, Account.count(Account.arel_table[:firm_id])
417
- end
418
-
419
- def test_count_with_arel_star
420
- assert_equal 6, Account.count(Arel.star)
421
- end
422
-
423
- def test_count_with_distinct
424
- assert_equal 4, Account.select(:credit_limit).distinct.count
425
-
426
- assert_deprecated do
427
- assert_equal 4, Account.select(:credit_limit).uniq.count
428
- end
429
- end
430
-
431
- def test_count_with_aliased_attribute
432
- assert_equal 6, Account.count(:available_credit)
433
- end
434
-
435
- def test_count_with_column_and_options_parameter
436
- assert_equal 2, Account.where("credit_limit = 50 AND firm_id IS NOT NULL").count(:firm_id)
437
- end
438
-
439
- def test_should_count_field_in_joined_table
440
- assert_equal 5, Account.joins(:firm).count('companies.id')
441
- assert_equal 4, Account.joins(:firm).distinct.count('companies.id')
442
- end
443
-
444
- def test_count_arel_attribute_in_joined_table_with
445
- assert_equal 5, Account.joins(:firm).count(Company.arel_table[:id])
446
- assert_equal 4, Account.joins(:firm).distinct.count(Company.arel_table[:id])
447
- end
448
-
449
- def test_count_selected_arel_attribute_in_joined_table
450
- assert_equal 5, Account.joins(:firm).select(Company.arel_table[:id]).count
451
- assert_equal 4, Account.joins(:firm).distinct.select(Company.arel_table[:id]).count
452
- end
453
-
454
- def test_should_count_field_in_joined_table_with_group_by
455
- c = Account.group('accounts.firm_id').joins(:firm).count('companies.id')
456
-
457
- [1,6,2,9].each { |firm_id| assert c.keys.include?(firm_id) }
458
- end
459
-
460
- def test_should_count_field_of_root_table_with_conflicting_group_by_column
461
- assert_equal({ 1 => 1 }, Firm.joins(:accounts).group(:firm_id).count)
462
- assert_equal({ 1 => 1 }, Firm.joins(:accounts).group('accounts.firm_id').count)
463
- end
464
-
465
- def test_count_with_no_parameters_isnt_deprecated
466
- assert_not_deprecated { Account.count }
467
- end
468
-
469
- def test_count_with_too_many_parameters_raises
470
- assert_raise(ArgumentError) { Account.count(1, 2, 3) }
471
- end
472
-
473
- def test_count_with_order
474
- assert_equal 6, Account.order(:credit_limit).count
475
- end
476
-
477
- def test_count_with_reverse_order
478
- assert_equal 6, Account.order(:credit_limit).reverse_order.count
479
- end
480
-
481
- def test_count_with_where_and_order
482
- assert_equal 1, Account.where(firm_name: '37signals').count
483
- assert_equal 1, Account.where(firm_name: '37signals').order(:firm_name).count
484
- assert_equal 1, Account.where(firm_name: '37signals').order(:firm_name).reverse_order.count
485
- end
486
-
487
- def test_should_sum_expression
488
- # Oracle adapter returns floating point value 636.0 after SUM
489
- if current_adapter?(:OracleAdapter)
490
- assert_equal 636, Account.sum("2 * credit_limit")
491
- else
492
- assert_equal 636, Account.sum("2 * credit_limit").to_i
493
- end
494
- end
495
-
496
- def test_sum_expression_returns_zero_when_no_records_to_sum
497
- assert_equal 0, Account.where('1 = 2').sum("2 * credit_limit")
498
- end
499
-
500
- def test_count_with_from_option
501
- assert_equal Company.count(:all), Company.from('companies').count(:all)
502
- assert_equal Account.where("credit_limit = 50").count(:all),
503
- Account.from('accounts').where("credit_limit = 50").count(:all)
504
- assert_equal Company.where(:type => "Firm").count(:type),
505
- Company.where(:type => "Firm").from('companies').count(:type)
506
- end
507
-
508
- def test_sum_with_from_option
509
- assert_equal Account.sum(:credit_limit), Account.from('accounts').sum(:credit_limit)
510
- assert_equal Account.where("credit_limit > 50").sum(:credit_limit),
511
- Account.where("credit_limit > 50").from('accounts').sum(:credit_limit)
512
- end
513
-
514
- def test_average_with_from_option
515
- assert_equal Account.average(:credit_limit), Account.from('accounts').average(:credit_limit)
516
- assert_equal Account.where("credit_limit > 50").average(:credit_limit),
517
- Account.where("credit_limit > 50").from('accounts').average(:credit_limit)
518
- end
519
-
520
- def test_minimum_with_from_option
521
- assert_equal Account.minimum(:credit_limit), Account.from('accounts').minimum(:credit_limit)
522
- assert_equal Account.where("credit_limit > 50").minimum(:credit_limit),
523
- Account.where("credit_limit > 50").from('accounts').minimum(:credit_limit)
524
- end
525
-
526
- def test_maximum_with_from_option
527
- assert_equal Account.maximum(:credit_limit), Account.from('accounts').maximum(:credit_limit)
528
- assert_equal Account.where("credit_limit > 50").maximum(:credit_limit),
529
- Account.where("credit_limit > 50").from('accounts').maximum(:credit_limit)
530
- end
531
-
532
- def test_maximum_with_not_auto_table_name_prefix_if_column_included
533
- Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
534
-
535
- assert_equal 7, Company.includes(:contracts).maximum(:developer_id)
536
- end
537
-
538
- def test_minimum_with_not_auto_table_name_prefix_if_column_included
539
- Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
540
-
541
- assert_equal 7, Company.includes(:contracts).minimum(:developer_id)
542
- end
543
-
544
- def test_sum_with_not_auto_table_name_prefix_if_column_included
545
- Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
546
-
547
- assert_equal 7, Company.includes(:contracts).sum(:developer_id)
548
- end
549
-
550
- if current_adapter?(:Mysql2Adapter)
551
- def test_from_option_with_specified_index
552
- assert_equal Edge.count(:all), Edge.from('edges USE INDEX(unique_edge_index)').count(:all)
553
- assert_equal Edge.where('sink_id < 5').count(:all),
554
- Edge.from('edges USE INDEX(unique_edge_index)').where('sink_id < 5').count(:all)
555
- end
556
- end
557
-
558
- def test_from_option_with_table_different_than_class
559
- assert_equal Account.count(:all), Company.from('accounts').count(:all)
560
- end
561
-
562
- def test_distinct_is_honored_when_used_with_count_operation_after_group
563
- # Count the number of authors for approved topics
564
- approved_topics_count = Topic.group(:approved).count(:author_name)[true]
565
- assert_equal approved_topics_count, 4
566
- # Count the number of distinct authors for approved Topics
567
- distinct_authors_for_approved_count = Topic.group(:approved).distinct.count(:author_name)[true]
568
- assert_equal distinct_authors_for_approved_count, 3
569
- end
570
-
571
- def test_pluck
572
- assert_equal [1,2,3,4,5], Topic.order(:id).pluck(:id)
573
- end
574
-
575
- def test_pluck_without_column_names
576
- assert_equal [[1, "Firm", 1, nil, "37signals", nil, 1, nil, ""]],
577
- Company.order(:id).limit(1).pluck
578
- end
579
-
580
- def test_pluck_type_cast
581
- topic = topics(:first)
582
- relation = Topic.where(:id => topic.id)
583
- assert_equal [ topic.approved ], relation.pluck(:approved)
584
- assert_equal [ topic.last_read ], relation.pluck(:last_read)
585
- assert_equal [ topic.written_on ], relation.pluck(:written_on)
586
- end
587
-
588
- def test_pluck_and_distinct
589
- assert_equal [50, 53, 55, 60], Account.order(:credit_limit).distinct.pluck(:credit_limit)
590
- end
591
-
592
- def test_pluck_in_relation
593
- company = Company.first
594
- contract = company.contracts.create!
595
- assert_equal [contract.id], company.contracts.pluck(:id)
596
- end
597
-
598
- def test_pluck_on_aliased_attribute
599
- assert_equal 'The First Topic', Topic.order(:id).pluck(:heading).first
600
- end
601
-
602
- def test_pluck_with_serialization
603
- t = Topic.create!(:content => { :foo => :bar })
604
- assert_equal [{:foo => :bar}], Topic.where(:id => t.id).pluck(:content)
605
- end
606
-
607
- def test_pluck_with_qualified_column_name
608
- assert_equal [1,2,3,4,5], Topic.order(:id).pluck("topics.id")
609
- end
610
-
611
- def test_pluck_auto_table_name_prefix
612
- c = Company.create!(:name => "test", :contracts => [Contract.new])
613
- assert_equal [c.id], Company.joins(:contracts).pluck(:id)
614
- end
615
-
616
- def test_pluck_if_table_included
617
- c = Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
618
- assert_equal [c.id], Company.includes(:contracts).where("contracts.id" => c.contracts.first).pluck(:id)
619
- end
620
-
621
- def test_pluck_not_auto_table_name_prefix_if_column_joined
622
- Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
623
- assert_equal [7], Company.joins(:contracts).pluck(:developer_id)
624
- end
625
-
626
- def test_pluck_with_selection_clause
627
- assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT credit_limit').sort
628
- assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT accounts.credit_limit').sort
629
- assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT(credit_limit)').sort
630
-
631
- # MySQL returns "SUM(DISTINCT(credit_limit))" as the column name unless
632
- # an alias is provided. Without the alias, the column cannot be found
633
- # and properly typecast.
634
- assert_equal [50 + 53 + 55 + 60], Account.pluck('SUM(DISTINCT(credit_limit)) as credit_limit')
635
- end
636
-
637
- def test_plucks_with_ids
638
- assert_equal Company.all.map(&:id).sort, Company.ids.sort
639
- end
640
-
641
- def test_pluck_with_includes_limit_and_empty_result
642
- assert_equal [], Topic.includes(:replies).limit(0).pluck(:id)
643
- assert_equal [], Topic.includes(:replies).limit(1).where('0 = 1').pluck(:id)
644
- end
645
-
646
- def test_pluck_not_auto_table_name_prefix_if_column_included
647
- Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
648
- ids = Company.includes(:contracts).pluck(:developer_id)
649
- assert_equal Company.count, ids.length
650
- assert_equal [7], ids.compact
651
- end
652
-
653
- def test_pluck_multiple_columns
654
- assert_equal [
655
- [1, "The First Topic"], [2, "The Second Topic of the day"],
656
- [3, "The Third Topic of the day"], [4, "The Fourth Topic of the day"],
657
- [5, "The Fifth Topic of the day"]
658
- ], Topic.order(:id).pluck(:id, :title)
659
- assert_equal [
660
- [1, "The First Topic", "David"], [2, "The Second Topic of the day", "Mary"],
661
- [3, "The Third Topic of the day", "Carl"], [4, "The Fourth Topic of the day", "Carl"],
662
- [5, "The Fifth Topic of the day", "Jason"]
663
- ], Topic.order(:id).pluck(:id, :title, :author_name)
664
- end
665
-
666
- def test_pluck_with_multiple_columns_and_selection_clause
667
- assert_equal [[1, 50], [2, 50], [3, 50], [4, 60], [5, 55], [6, 53]],
668
- Account.pluck('id, credit_limit')
669
- end
670
-
671
- def test_pluck_with_multiple_columns_and_includes
672
- Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
673
- companies_and_developers = Company.order('companies.id').includes(:contracts).pluck(:name, :developer_id)
674
-
675
- assert_equal Company.count, companies_and_developers.length
676
- assert_equal ["37signals", nil], companies_and_developers.first
677
- assert_equal ["test", 7], companies_and_developers.last
678
- end
679
-
680
- def test_pluck_with_reserved_words
681
- Possession.create!(:where => "Over There")
682
-
683
- assert_equal ["Over There"], Possession.pluck(:where)
684
- end
685
-
686
- def test_pluck_replaces_select_clause
687
- taks_relation = Topic.select(:approved, :id).order(:id)
688
- assert_equal [1,2,3,4,5], taks_relation.pluck(:id)
689
- assert_equal [false, true, true, true, true], taks_relation.pluck(:approved)
690
- end
691
-
692
- def test_pluck_columns_with_same_name
693
- expected = [["The First Topic", "The Second Topic of the day"], ["The Third Topic of the day", "The Fourth Topic of the day"]]
694
- actual = Topic.joins(:replies)
695
- .pluck('topics.title', 'replies_topics.title')
696
- assert_equal expected, actual
697
- end
698
-
699
- def test_calculation_with_polymorphic_relation
700
- part = ShipPart.create!(name: "has trinket")
701
- part.trinkets.create!
702
-
703
- assert_equal part.id, ShipPart.joins(:trinkets).sum(:id)
704
- end
705
-
706
- def test_pluck_joined_with_polymorphic_relation
707
- part = ShipPart.create!(name: "has trinket")
708
- part.trinkets.create!
709
-
710
- assert_equal [part.id], ShipPart.joins(:trinkets).pluck(:id)
711
- end
712
-
713
- def test_pluck_loaded_relation
714
- companies = Company.order(:id).limit(3).load
715
- assert_no_queries do
716
- assert_equal ['37signals', 'Summit', 'Microsoft'], companies.pluck(:name)
717
- end
718
- end
719
-
720
- def test_pluck_loaded_relation_multiple_columns
721
- companies = Company.order(:id).limit(3).load
722
- assert_no_queries do
723
- assert_equal [[1, '37signals'], [2, 'Summit'], [3, 'Microsoft']], companies.pluck(:id, :name)
724
- end
725
- end
726
-
727
- def test_pluck_loaded_relation_sql_fragment
728
- companies = Company.order(:name).limit(3).load
729
- assert_queries 1 do
730
- assert_equal ['37signals', 'Apex', 'Ex Nihilo'], companies.pluck('DISTINCT name')
731
- end
732
- end
733
-
734
- def test_grouped_calculation_with_polymorphic_relation
735
- part = ShipPart.create!(name: "has trinket")
736
- part.trinkets.create!
737
-
738
- assert_equal({ "has trinket" => part.id }, ShipPart.joins(:trinkets).group("ship_parts.name").sum(:id))
739
- end
740
-
741
- def test_calculation_grouped_by_association_doesnt_error_when_no_records_have_association
742
- Client.update_all(client_of: nil)
743
- assert_equal({ nil => Client.count }, Client.group(:firm).count)
744
- end
745
-
746
- def test_should_reference_correct_aliases_while_joining_tables_of_has_many_through_association
747
- assert_nothing_raised do
748
- developer = Developer.create!(name: 'developer')
749
- developer.ratings.includes(comment: :post).where(posts: { id: 1 }).count
750
- end
751
- end
752
-
753
- def test_sum_uses_enumerable_version_when_block_is_given
754
- block_called = false
755
- relation = Client.all.load
756
-
757
- assert_no_queries do
758
- assert_equal 0, relation.sum { block_called = true; 0 }
759
- end
760
- assert block_called
761
- end
762
-
763
- def test_having_with_strong_parameters
764
- protected_params = Class.new do
765
- attr_reader :permitted
766
- alias :permitted? :permitted
767
-
768
- def initialize(parameters)
769
- @parameters = parameters
770
- @permitted = false
771
- end
772
-
773
- def to_h
774
- @parameters
775
- end
776
-
777
- def permit!
778
- @permitted = true
779
- self
780
- end
781
- end
782
-
783
- params = protected_params.new(credit_limit: '50')
784
-
785
- assert_raises(ActiveModel::ForbiddenAttributesError) do
786
- Account.group(:id).having(params)
787
- end
788
-
789
- result = Account.group(:id).having(params.permit!)
790
- assert_equal 50, result[0].credit_limit
791
- assert_equal 50, result[1].credit_limit
792
- assert_equal 50, result[2].credit_limit
793
- end
794
-
795
- def test_group_by_attribute_with_custom_type
796
- assert_equal({ "proposed" => 2, "published" => 2 }, Book.group(:status).count)
797
- end
798
- end
1
+ require "cases/helper"
2
+ require "models/book"
3
+ require 'models/club'
4
+ require 'models/company'
5
+ require "models/contract"
6
+ require 'models/edge'
7
+ require 'models/organization'
8
+ require 'models/possession'
9
+ require 'models/topic'
10
+ require 'models/reply'
11
+ require 'models/minivan'
12
+ require 'models/speedometer'
13
+ require 'models/ship_part'
14
+ require 'models/treasure'
15
+ require 'models/developer'
16
+ require 'models/comment'
17
+ require 'models/rating'
18
+ require 'models/post'
19
+
20
+ class NumericData < ActiveRecord::Base
21
+ self.table_name = 'numeric_data'
22
+
23
+ attribute :world_population, :integer
24
+ attribute :my_house_population, :integer
25
+ attribute :atoms_in_universe, :integer
26
+ end
27
+
28
+ class CalculationsTest < ActiveRecord::TestCase
29
+ fixtures :companies, :accounts, :topics, :speedometers, :minivans, :books
30
+
31
+ def test_should_sum_field
32
+ assert_equal 318, Account.sum(:credit_limit)
33
+ end
34
+
35
+ def test_should_sum_arel_attribute
36
+ assert_equal 318, Account.sum(Account.arel_table[:credit_limit])
37
+ end
38
+
39
+ def test_should_average_field
40
+ value = Account.average(:credit_limit)
41
+ assert_equal 53.0, value
42
+ end
43
+
44
+ def test_should_average_arel_attribute
45
+ value = Account.average(Account.arel_table[:credit_limit])
46
+ assert_equal 53.0, value
47
+ end
48
+
49
+ def test_should_resolve_aliased_attributes
50
+ assert_equal 318, Account.sum(:available_credit)
51
+ end
52
+
53
+ def test_should_return_decimal_average_of_integer_field
54
+ value = Account.average(:id)
55
+ assert_equal 3.5, value
56
+ end
57
+
58
+ def test_should_return_integer_average_if_db_returns_such
59
+ ShipPart.delete_all
60
+ ShipPart.create!(:id => 3, :name => 'foo')
61
+ value = ShipPart.average(:id)
62
+ assert_equal 3, value
63
+ end
64
+
65
+ def test_should_return_nil_as_average
66
+ assert_nil NumericData.average(:bank_balance)
67
+ end
68
+
69
+ def test_should_get_maximum_of_field
70
+ assert_equal 60, Account.maximum(:credit_limit)
71
+ end
72
+
73
+ def test_should_get_maximum_of_arel_attribute
74
+ assert_equal 60, Account.maximum(Account.arel_table[:credit_limit])
75
+ end
76
+
77
+ def test_should_get_maximum_of_field_with_include
78
+ assert_equal 55, Account.where("companies.name != 'Summit'").references(:companies).includes(:firm).maximum(:credit_limit)
79
+ end
80
+
81
+ def test_should_get_maximum_of_arel_attribute_with_include
82
+ assert_equal 55, Account.where("companies.name != 'Summit'").references(:companies).includes(:firm).maximum(Account.arel_table[:credit_limit])
83
+ end
84
+
85
+ def test_should_get_minimum_of_field
86
+ assert_equal 50, Account.minimum(:credit_limit)
87
+ end
88
+
89
+ def test_should_get_minimum_of_arel_attribute
90
+ assert_equal 50, Account.minimum(Account.arel_table[:credit_limit])
91
+ end
92
+
93
+ def test_should_group_by_field
94
+ c = Account.group(:firm_id).sum(:credit_limit)
95
+ [1,6,2].each do |firm_id|
96
+ assert c.keys.include?(firm_id), "Group #{c.inspect} does not contain firm_id #{firm_id}"
97
+ end
98
+ end
99
+
100
+ def test_should_group_by_arel_attribute
101
+ c = Account.group(Account.arel_table[:firm_id]).sum(:credit_limit)
102
+ [1,6,2].each do |firm_id|
103
+ assert c.keys.include?(firm_id), "Group #{c.inspect} does not contain firm_id #{firm_id}"
104
+ end
105
+ end
106
+
107
+ def test_should_group_by_multiple_fields
108
+ c = Account.group('firm_id', :credit_limit).count(:all)
109
+ [ [nil, 50], [1, 50], [6, 50], [6, 55], [9, 53], [2, 60] ].each { |firm_and_limit| assert c.keys.include?(firm_and_limit) }
110
+ end
111
+
112
+ def test_should_group_by_multiple_fields_having_functions
113
+ c = Topic.group(:author_name, 'COALESCE(type, title)').count(:all)
114
+ assert_equal 1, c[["Carl", "The Third Topic of the day"]]
115
+ assert_equal 1, c[["Mary", "Reply"]]
116
+ assert_equal 1, c[["David", "The First Topic"]]
117
+ assert_equal 1, c[["Carl", "Reply"]]
118
+ end
119
+
120
+ def test_should_group_by_summed_field
121
+ c = Account.group(:firm_id).sum(:credit_limit)
122
+ assert_equal 50, c[1]
123
+ assert_equal 105, c[6]
124
+ assert_equal 60, c[2]
125
+ end
126
+
127
+ def test_should_generate_valid_sql_with_joins_and_group
128
+ assert_nothing_raised do
129
+ AuditLog.joins(:developer).group(:id).count
130
+ end
131
+ end
132
+
133
+ def test_should_calculate_against_given_relation
134
+ developer = Developer.create!(name: "developer")
135
+ developer.audit_logs.create!(message: "first log")
136
+ developer.audit_logs.create!(message: "second log")
137
+
138
+ c = developer.audit_logs.joins(:developer).group(:id).count
139
+
140
+ assert_equal developer.audit_logs.count, c.size
141
+ developer.audit_logs.each do |log|
142
+ assert_equal 1, c[log.id]
143
+ end
144
+ end
145
+
146
+ def test_should_order_by_grouped_field
147
+ c = Account.group(:firm_id).order("firm_id").sum(:credit_limit)
148
+ assert_equal [1, 2, 6, 9], c.keys.compact
149
+ end
150
+
151
+ def test_should_order_by_calculation
152
+ c = Account.group(:firm_id).order("sum_credit_limit desc, firm_id").sum(:credit_limit)
153
+ assert_equal [105, 60, 53, 50, 50], c.keys.collect { |k| c[k] }
154
+ assert_equal [6, 2, 9, 1], c.keys.compact
155
+ end
156
+
157
+ def test_should_limit_calculation
158
+ c = Account.where("firm_id IS NOT NULL").group(:firm_id).order("firm_id").limit(2).sum(:credit_limit)
159
+ assert_equal [1, 2], c.keys.compact
160
+ end
161
+
162
+ def test_should_limit_calculation_with_offset
163
+ c = Account.where("firm_id IS NOT NULL").group(:firm_id).order("firm_id").
164
+ limit(2).offset(1).sum(:credit_limit)
165
+ assert_equal [2, 6], c.keys.compact
166
+ end
167
+
168
+ def test_limit_should_apply_before_count
169
+ accounts = Account.limit(3).where('firm_id IS NOT NULL')
170
+
171
+ assert_equal 3, accounts.count(:firm_id)
172
+ assert_equal 3, accounts.select(:firm_id).count
173
+ end
174
+
175
+ def test_limit_should_apply_before_count_arel_attribute
176
+ accounts = Account.limit(3).where('firm_id IS NOT NULL')
177
+
178
+ firm_id_attribute = Account.arel_table[:firm_id]
179
+ assert_equal 3, accounts.count(firm_id_attribute)
180
+ assert_equal 3, accounts.select(firm_id_attribute).count
181
+ end
182
+
183
+ def test_count_should_shortcut_with_limit_zero
184
+ accounts = Account.limit(0)
185
+
186
+ assert_no_queries { assert_equal 0, accounts.count }
187
+ end
188
+
189
+ def test_limit_is_kept
190
+ return if current_adapter?(:OracleAdapter)
191
+
192
+ queries = assert_sql { Account.limit(1).count }
193
+ assert_equal 1, queries.length
194
+ assert_match(/LIMIT/, queries.first)
195
+ end
196
+
197
+ def test_offset_is_kept
198
+ return if current_adapter?(:OracleAdapter)
199
+
200
+ queries = assert_sql { Account.offset(1).count }
201
+ assert_equal 1, queries.length
202
+ assert_match(/OFFSET/, queries.first)
203
+ end
204
+
205
+ def test_limit_with_offset_is_kept
206
+ return if current_adapter?(:OracleAdapter)
207
+
208
+ queries = assert_sql { Account.limit(1).offset(1).count }
209
+ assert_equal 1, queries.length
210
+ assert_match(/LIMIT/, queries.first)
211
+ assert_match(/OFFSET/, queries.first)
212
+ end
213
+
214
+ def test_no_limit_no_offset
215
+ queries = assert_sql { Account.count }
216
+ assert_equal 1, queries.length
217
+ assert_no_match(/LIMIT/, queries.first)
218
+ assert_no_match(/OFFSET/, queries.first)
219
+ end
220
+
221
+ def test_count_on_invalid_columns_raises
222
+ e = assert_raises(ActiveRecord::StatementInvalid) {
223
+ Account.select("credit_limit, firm_name").count
224
+ }
225
+
226
+ assert_match %r{accounts}i, e.message
227
+ assert_match "credit_limit, firm_name", e.message
228
+ end
229
+
230
+ def test_should_group_by_summed_field_having_condition
231
+ c = Account.group(:firm_id).having('sum(credit_limit) > 50').sum(:credit_limit)
232
+ assert_nil c[1]
233
+ assert_equal 105, c[6]
234
+ assert_equal 60, c[2]
235
+ end
236
+
237
+ def test_should_group_by_summed_field_having_condition_from_select
238
+ skip unless current_adapter?(:Mysql2Adapter, :SQLite3Adapter)
239
+ c = Account.select("MIN(credit_limit) AS min_credit_limit").group(:firm_id).having("min_credit_limit > 50").sum(:credit_limit)
240
+ assert_nil c[1]
241
+ assert_equal 60, c[2]
242
+ assert_equal 53, c[9]
243
+ end
244
+
245
+ def test_should_group_by_summed_association
246
+ c = Account.group(:firm).sum(:credit_limit)
247
+ assert_equal 50, c[companies(:first_firm)]
248
+ assert_equal 105, c[companies(:rails_core)]
249
+ assert_equal 60, c[companies(:first_client)]
250
+ end
251
+
252
+ def test_should_sum_field_with_conditions
253
+ assert_equal 105, Account.where('firm_id = 6').sum(:credit_limit)
254
+ end
255
+
256
+ def test_should_return_zero_if_sum_conditions_return_nothing
257
+ assert_equal 0, Account.where('1 = 2').sum(:credit_limit)
258
+ assert_equal 0, companies(:rails_core).companies.where('1 = 2').sum(:id)
259
+ end
260
+
261
+ def test_sum_should_return_valid_values_for_decimals
262
+ NumericData.create(:bank_balance => 19.83)
263
+ assert_equal 19.83, NumericData.sum(:bank_balance)
264
+ end
265
+
266
+ def test_should_return_type_casted_values_with_group_and_expression
267
+ assert_equal 0.5, Account.group(:firm_name).sum('0.01 * credit_limit')['37signals']
268
+ end
269
+
270
+ def test_should_group_by_summed_field_with_conditions
271
+ c = Account.where('firm_id > 1').group(:firm_id).sum(:credit_limit)
272
+ assert_nil c[1]
273
+ assert_equal 105, c[6]
274
+ assert_equal 60, c[2]
275
+ end
276
+
277
+ def test_should_group_by_summed_field_with_conditions_and_having
278
+ c = Account.where('firm_id > 1').group(:firm_id).
279
+ having('sum(credit_limit) > 60').sum(:credit_limit)
280
+ assert_nil c[1]
281
+ assert_equal 105, c[6]
282
+ assert_nil c[2]
283
+ end
284
+
285
+ def test_should_group_by_fields_with_table_alias
286
+ c = Account.group('accounts.firm_id').sum(:credit_limit)
287
+ assert_equal 50, c[1]
288
+ assert_equal 105, c[6]
289
+ assert_equal 60, c[2]
290
+ end
291
+
292
+ def test_should_calculate_with_invalid_field
293
+ assert_equal 6, Account.calculate(:count, '*')
294
+ assert_equal 6, Account.calculate(:count, :all)
295
+ end
296
+
297
+ def test_should_calculate_grouped_with_invalid_field
298
+ c = Account.group('accounts.firm_id').count(:all)
299
+ assert_equal 1, c[1]
300
+ assert_equal 2, c[6]
301
+ assert_equal 1, c[2]
302
+ end
303
+
304
+ def test_should_calculate_grouped_association_with_invalid_field
305
+ c = Account.group(:firm).count(:all)
306
+ assert_equal 1, c[companies(:first_firm)]
307
+ assert_equal 2, c[companies(:rails_core)]
308
+ assert_equal 1, c[companies(:first_client)]
309
+ end
310
+
311
+ def test_should_group_by_association_with_non_numeric_foreign_key
312
+ Speedometer.create! id: 'ABC'
313
+ Minivan.create! id: 'OMG', speedometer_id: 'ABC'
314
+
315
+ c = Minivan.group(:speedometer).count(:all)
316
+ first_key = c.keys.first
317
+ assert_equal Speedometer, first_key.class
318
+ assert_equal 1, c[first_key]
319
+ end
320
+
321
+ def test_should_calculate_grouped_association_with_foreign_key_option
322
+ Account.belongs_to :another_firm, :class_name => 'Firm', :foreign_key => 'firm_id'
323
+ c = Account.group(:another_firm).count(:all)
324
+ assert_equal 1, c[companies(:first_firm)]
325
+ assert_equal 2, c[companies(:rails_core)]
326
+ assert_equal 1, c[companies(:first_client)]
327
+ end
328
+
329
+ def test_should_calculate_grouped_by_function
330
+ c = Company.group("UPPER(#{QUOTED_TYPE})").count(:all)
331
+ assert_equal 2, c[nil]
332
+ assert_equal 1, c['DEPENDENTFIRM']
333
+ assert_equal 5, c['CLIENT']
334
+ assert_equal 2, c['FIRM']
335
+ end
336
+
337
+ def test_should_calculate_grouped_by_function_with_table_alias
338
+ c = Company.group("UPPER(companies.#{QUOTED_TYPE})").count(:all)
339
+ assert_equal 2, c[nil]
340
+ assert_equal 1, c['DEPENDENTFIRM']
341
+ assert_equal 5, c['CLIENT']
342
+ assert_equal 2, c['FIRM']
343
+ end
344
+
345
+ def test_should_not_overshadow_enumerable_sum
346
+ assert_equal 6, [1, 2, 3].sum(&:abs)
347
+ end
348
+
349
+ def test_should_sum_scoped_field
350
+ assert_equal 15, companies(:rails_core).companies.sum(:id)
351
+ end
352
+
353
+ def test_should_sum_scoped_field_with_from
354
+ assert_equal Club.count, Organization.clubs.count
355
+ end
356
+
357
+ def test_should_sum_scoped_field_with_conditions
358
+ assert_equal 8, companies(:rails_core).companies.where('id > 7').sum(:id)
359
+ end
360
+
361
+ def test_should_group_by_scoped_field
362
+ c = companies(:rails_core).companies.group(:name).sum(:id)
363
+ assert_equal 7, c['Leetsoft']
364
+ assert_equal 8, c['Jadedpixel']
365
+ end
366
+
367
+ def test_should_group_by_summed_field_through_association_and_having
368
+ c = companies(:rails_core).companies.group(:name).having('sum(id) > 7').sum(:id)
369
+ assert_nil c['Leetsoft']
370
+ assert_equal 8, c['Jadedpixel']
371
+ end
372
+
373
+ def test_should_count_selected_field_with_include
374
+ assert_equal 6, Account.includes(:firm).distinct.count
375
+ assert_equal 4, Account.includes(:firm).distinct.select(:credit_limit).count
376
+ end
377
+
378
+ def test_should_not_perform_joined_include_by_default
379
+ assert_equal Account.count, Account.includes(:firm).count
380
+ queries = assert_sql { Account.includes(:firm).count }
381
+ assert_no_match(/join/i, queries.last)
382
+ end
383
+
384
+ def test_should_perform_joined_include_when_referencing_included_tables
385
+ joined_count = Account.includes(:firm).where(:companies => {:name => '37signals'}).count
386
+ assert_equal 1, joined_count
387
+ end
388
+
389
+ def test_should_count_scoped_select
390
+ Account.update_all("credit_limit = NULL")
391
+ assert_equal 0, Account.select("credit_limit").count
392
+ end
393
+
394
+ def test_should_count_scoped_select_with_options
395
+ Account.update_all("credit_limit = NULL")
396
+ Account.last.update_columns('credit_limit' => 49)
397
+ Account.first.update_columns('credit_limit' => 51)
398
+
399
+ assert_equal 1, Account.select("credit_limit").where('credit_limit >= 50').count
400
+ end
401
+
402
+ def test_should_count_manual_select_with_include
403
+ assert_equal 6, Account.select("DISTINCT accounts.id").includes(:firm).count
404
+ end
405
+
406
+ def test_count_selected_arel_attribute
407
+ assert_equal 5, Account.select(Account.arel_table[:firm_id]).count
408
+ assert_equal 4, Account.distinct.select(Account.arel_table[:firm_id]).count
409
+ end
410
+
411
+ def test_count_with_column_parameter
412
+ assert_equal 5, Account.count(:firm_id)
413
+ end
414
+
415
+ def test_count_with_arel_attribute
416
+ assert_equal 5, Account.count(Account.arel_table[:firm_id])
417
+ end
418
+
419
+ def test_count_with_arel_star
420
+ assert_equal 6, Account.count(Arel.star)
421
+ end
422
+
423
+ def test_count_with_distinct
424
+ assert_equal 4, Account.select(:credit_limit).distinct.count
425
+
426
+ assert_deprecated do
427
+ assert_equal 4, Account.select(:credit_limit).uniq.count
428
+ end
429
+ end
430
+
431
+ def test_count_with_aliased_attribute
432
+ assert_equal 6, Account.count(:available_credit)
433
+ end
434
+
435
+ def test_count_with_column_and_options_parameter
436
+ assert_equal 2, Account.where("credit_limit = 50 AND firm_id IS NOT NULL").count(:firm_id)
437
+ end
438
+
439
+ def test_should_count_field_in_joined_table
440
+ assert_equal 5, Account.joins(:firm).count('companies.id')
441
+ assert_equal 4, Account.joins(:firm).distinct.count('companies.id')
442
+ end
443
+
444
+ def test_count_arel_attribute_in_joined_table_with
445
+ assert_equal 5, Account.joins(:firm).count(Company.arel_table[:id])
446
+ assert_equal 4, Account.joins(:firm).distinct.count(Company.arel_table[:id])
447
+ end
448
+
449
+ def test_count_selected_arel_attribute_in_joined_table
450
+ assert_equal 5, Account.joins(:firm).select(Company.arel_table[:id]).count
451
+ assert_equal 4, Account.joins(:firm).distinct.select(Company.arel_table[:id]).count
452
+ end
453
+
454
+ def test_should_count_field_in_joined_table_with_group_by
455
+ c = Account.group('accounts.firm_id').joins(:firm).count('companies.id')
456
+
457
+ [1,6,2,9].each { |firm_id| assert c.keys.include?(firm_id) }
458
+ end
459
+
460
+ def test_should_count_field_of_root_table_with_conflicting_group_by_column
461
+ assert_equal({ 1 => 1 }, Firm.joins(:accounts).group(:firm_id).count)
462
+ assert_equal({ 1 => 1 }, Firm.joins(:accounts).group('accounts.firm_id').count)
463
+ end
464
+
465
+ def test_count_with_no_parameters_isnt_deprecated
466
+ assert_not_deprecated { Account.count }
467
+ end
468
+
469
+ def test_count_with_too_many_parameters_raises
470
+ assert_raise(ArgumentError) { Account.count(1, 2, 3) }
471
+ end
472
+
473
+ def test_count_with_order
474
+ assert_equal 6, Account.order(:credit_limit).count
475
+ end
476
+
477
+ def test_count_with_reverse_order
478
+ assert_equal 6, Account.order(:credit_limit).reverse_order.count
479
+ end
480
+
481
+ def test_count_with_where_and_order
482
+ assert_equal 1, Account.where(firm_name: '37signals').count
483
+ assert_equal 1, Account.where(firm_name: '37signals').order(:firm_name).count
484
+ assert_equal 1, Account.where(firm_name: '37signals').order(:firm_name).reverse_order.count
485
+ end
486
+
487
+ def test_should_sum_expression
488
+ # Oracle adapter returns floating point value 636.0 after SUM
489
+ if current_adapter?(:OracleAdapter)
490
+ assert_equal 636, Account.sum("2 * credit_limit")
491
+ else
492
+ assert_equal 636, Account.sum("2 * credit_limit").to_i
493
+ end
494
+ end
495
+
496
+ def test_sum_expression_returns_zero_when_no_records_to_sum
497
+ assert_equal 0, Account.where('1 = 2').sum("2 * credit_limit")
498
+ end
499
+
500
+ def test_count_with_from_option
501
+ assert_equal Company.count(:all), Company.from('companies').count(:all)
502
+ assert_equal Account.where("credit_limit = 50").count(:all),
503
+ Account.from('accounts').where("credit_limit = 50").count(:all)
504
+ assert_equal Company.where(:type => "Firm").count(:type),
505
+ Company.where(:type => "Firm").from('companies').count(:type)
506
+ end
507
+
508
+ def test_sum_with_from_option
509
+ assert_equal Account.sum(:credit_limit), Account.from('accounts').sum(:credit_limit)
510
+ assert_equal Account.where("credit_limit > 50").sum(:credit_limit),
511
+ Account.where("credit_limit > 50").from('accounts').sum(:credit_limit)
512
+ end
513
+
514
+ def test_average_with_from_option
515
+ assert_equal Account.average(:credit_limit), Account.from('accounts').average(:credit_limit)
516
+ assert_equal Account.where("credit_limit > 50").average(:credit_limit),
517
+ Account.where("credit_limit > 50").from('accounts').average(:credit_limit)
518
+ end
519
+
520
+ def test_minimum_with_from_option
521
+ assert_equal Account.minimum(:credit_limit), Account.from('accounts').minimum(:credit_limit)
522
+ assert_equal Account.where("credit_limit > 50").minimum(:credit_limit),
523
+ Account.where("credit_limit > 50").from('accounts').minimum(:credit_limit)
524
+ end
525
+
526
+ def test_maximum_with_from_option
527
+ assert_equal Account.maximum(:credit_limit), Account.from('accounts').maximum(:credit_limit)
528
+ assert_equal Account.where("credit_limit > 50").maximum(:credit_limit),
529
+ Account.where("credit_limit > 50").from('accounts').maximum(:credit_limit)
530
+ end
531
+
532
+ def test_maximum_with_not_auto_table_name_prefix_if_column_included
533
+ Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
534
+
535
+ assert_equal 7, Company.includes(:contracts).maximum(:developer_id)
536
+ end
537
+
538
+ def test_minimum_with_not_auto_table_name_prefix_if_column_included
539
+ Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
540
+
541
+ assert_equal 7, Company.includes(:contracts).minimum(:developer_id)
542
+ end
543
+
544
+ def test_sum_with_not_auto_table_name_prefix_if_column_included
545
+ Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
546
+
547
+ assert_equal 7, Company.includes(:contracts).sum(:developer_id)
548
+ end
549
+
550
+ if current_adapter?(:Mysql2Adapter)
551
+ def test_from_option_with_specified_index
552
+ assert_equal Edge.count(:all), Edge.from('edges USE INDEX(unique_edge_index)').count(:all)
553
+ assert_equal Edge.where('sink_id < 5').count(:all),
554
+ Edge.from('edges USE INDEX(unique_edge_index)').where('sink_id < 5').count(:all)
555
+ end
556
+ end
557
+
558
+ def test_from_option_with_table_different_than_class
559
+ assert_equal Account.count(:all), Company.from('accounts').count(:all)
560
+ end
561
+
562
+ def test_distinct_is_honored_when_used_with_count_operation_after_group
563
+ # Count the number of authors for approved topics
564
+ approved_topics_count = Topic.group(:approved).count(:author_name)[true]
565
+ assert_equal approved_topics_count, 4
566
+ # Count the number of distinct authors for approved Topics
567
+ distinct_authors_for_approved_count = Topic.group(:approved).distinct.count(:author_name)[true]
568
+ assert_equal distinct_authors_for_approved_count, 3
569
+ end
570
+
571
+ def test_pluck
572
+ assert_equal [1,2,3,4,5], Topic.order(:id).pluck(:id)
573
+ end
574
+
575
+ def test_pluck_without_column_names
576
+ assert_equal [[1, "Firm", 1, nil, "37signals", nil, 1, nil, ""]],
577
+ Company.order(:id).limit(1).pluck
578
+ end
579
+
580
+ def test_pluck_type_cast
581
+ topic = topics(:first)
582
+ relation = Topic.where(:id => topic.id)
583
+ assert_equal [ topic.approved ], relation.pluck(:approved)
584
+ assert_equal [ topic.last_read ], relation.pluck(:last_read)
585
+ assert_equal [ topic.written_on ], relation.pluck(:written_on)
586
+ end
587
+
588
+ def test_pluck_and_distinct
589
+ assert_equal [50, 53, 55, 60], Account.order(:credit_limit).distinct.pluck(:credit_limit)
590
+ end
591
+
592
+ def test_pluck_in_relation
593
+ company = Company.first
594
+ contract = company.contracts.create!
595
+ assert_equal [contract.id], company.contracts.pluck(:id)
596
+ end
597
+
598
+ def test_pluck_on_aliased_attribute
599
+ assert_equal 'The First Topic', Topic.order(:id).pluck(:heading).first
600
+ end
601
+
602
+ def test_pluck_with_serialization
603
+ t = Topic.create!(:content => { :foo => :bar })
604
+ assert_equal [{:foo => :bar}], Topic.where(:id => t.id).pluck(:content)
605
+ end
606
+
607
+ def test_pluck_with_qualified_column_name
608
+ assert_equal [1,2,3,4,5], Topic.order(:id).pluck("topics.id")
609
+ end
610
+
611
+ def test_pluck_auto_table_name_prefix
612
+ c = Company.create!(:name => "test", :contracts => [Contract.new])
613
+ assert_equal [c.id], Company.joins(:contracts).pluck(:id)
614
+ end
615
+
616
+ def test_pluck_if_table_included
617
+ c = Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
618
+ assert_equal [c.id], Company.includes(:contracts).where("contracts.id" => c.contracts.first).pluck(:id)
619
+ end
620
+
621
+ def test_pluck_not_auto_table_name_prefix_if_column_joined
622
+ Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
623
+ assert_equal [7], Company.joins(:contracts).pluck(:developer_id)
624
+ end
625
+
626
+ def test_pluck_with_selection_clause
627
+ assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT credit_limit').sort
628
+ assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT accounts.credit_limit').sort
629
+ assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT(credit_limit)').sort
630
+
631
+ # MySQL returns "SUM(DISTINCT(credit_limit))" as the column name unless
632
+ # an alias is provided. Without the alias, the column cannot be found
633
+ # and properly typecast.
634
+ assert_equal [50 + 53 + 55 + 60], Account.pluck('SUM(DISTINCT(credit_limit)) as credit_limit')
635
+ end
636
+
637
+ def test_plucks_with_ids
638
+ assert_equal Company.all.map(&:id).sort, Company.ids.sort
639
+ end
640
+
641
+ def test_pluck_with_includes_limit_and_empty_result
642
+ assert_equal [], Topic.includes(:replies).limit(0).pluck(:id)
643
+ assert_equal [], Topic.includes(:replies).limit(1).where('0 = 1').pluck(:id)
644
+ end
645
+
646
+ def test_pluck_not_auto_table_name_prefix_if_column_included
647
+ Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
648
+ ids = Company.includes(:contracts).pluck(:developer_id)
649
+ assert_equal Company.count, ids.length
650
+ assert_equal [7], ids.compact
651
+ end
652
+
653
+ def test_pluck_multiple_columns
654
+ assert_equal [
655
+ [1, "The First Topic"], [2, "The Second Topic of the day"],
656
+ [3, "The Third Topic of the day"], [4, "The Fourth Topic of the day"],
657
+ [5, "The Fifth Topic of the day"]
658
+ ], Topic.order(:id).pluck(:id, :title)
659
+ assert_equal [
660
+ [1, "The First Topic", "David"], [2, "The Second Topic of the day", "Mary"],
661
+ [3, "The Third Topic of the day", "Carl"], [4, "The Fourth Topic of the day", "Carl"],
662
+ [5, "The Fifth Topic of the day", "Jason"]
663
+ ], Topic.order(:id).pluck(:id, :title, :author_name)
664
+ end
665
+
666
+ def test_pluck_with_multiple_columns_and_selection_clause
667
+ assert_equal [[1, 50], [2, 50], [3, 50], [4, 60], [5, 55], [6, 53]],
668
+ Account.pluck('id, credit_limit')
669
+ end
670
+
671
+ def test_pluck_with_multiple_columns_and_includes
672
+ Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)])
673
+ companies_and_developers = Company.order('companies.id').includes(:contracts).pluck(:name, :developer_id)
674
+
675
+ assert_equal Company.count, companies_and_developers.length
676
+ assert_equal ["37signals", nil], companies_and_developers.first
677
+ assert_equal ["test", 7], companies_and_developers.last
678
+ end
679
+
680
+ def test_pluck_with_reserved_words
681
+ Possession.create!(:where => "Over There")
682
+
683
+ assert_equal ["Over There"], Possession.pluck(:where)
684
+ end
685
+
686
+ def test_pluck_replaces_select_clause
687
+ taks_relation = Topic.select(:approved, :id).order(:id)
688
+ assert_equal [1,2,3,4,5], taks_relation.pluck(:id)
689
+ assert_equal [false, true, true, true, true], taks_relation.pluck(:approved)
690
+ end
691
+
692
+ def test_pluck_columns_with_same_name
693
+ expected = [["The First Topic", "The Second Topic of the day"], ["The Third Topic of the day", "The Fourth Topic of the day"]]
694
+ actual = Topic.joins(:replies)
695
+ .pluck('topics.title', 'replies_topics.title')
696
+ assert_equal expected, actual
697
+ end
698
+
699
+ def test_calculation_with_polymorphic_relation
700
+ part = ShipPart.create!(name: "has trinket")
701
+ part.trinkets.create!
702
+
703
+ assert_equal part.id, ShipPart.joins(:trinkets).sum(:id)
704
+ end
705
+
706
+ def test_pluck_joined_with_polymorphic_relation
707
+ part = ShipPart.create!(name: "has trinket")
708
+ part.trinkets.create!
709
+
710
+ assert_equal [part.id], ShipPart.joins(:trinkets).pluck(:id)
711
+ end
712
+
713
+ def test_pluck_loaded_relation
714
+ companies = Company.order(:id).limit(3).load
715
+ assert_no_queries do
716
+ assert_equal ['37signals', 'Summit', 'Microsoft'], companies.pluck(:name)
717
+ end
718
+ end
719
+
720
+ def test_pluck_loaded_relation_multiple_columns
721
+ companies = Company.order(:id).limit(3).load
722
+ assert_no_queries do
723
+ assert_equal [[1, '37signals'], [2, 'Summit'], [3, 'Microsoft']], companies.pluck(:id, :name)
724
+ end
725
+ end
726
+
727
+ def test_pluck_loaded_relation_sql_fragment
728
+ companies = Company.order(:name).limit(3).load
729
+ assert_queries 1 do
730
+ assert_equal ['37signals', 'Apex', 'Ex Nihilo'], companies.pluck('DISTINCT name')
731
+ end
732
+ end
733
+
734
+ def test_grouped_calculation_with_polymorphic_relation
735
+ part = ShipPart.create!(name: "has trinket")
736
+ part.trinkets.create!
737
+
738
+ assert_equal({ "has trinket" => part.id }, ShipPart.joins(:trinkets).group("ship_parts.name").sum(:id))
739
+ end
740
+
741
+ def test_calculation_grouped_by_association_doesnt_error_when_no_records_have_association
742
+ Client.update_all(client_of: nil)
743
+ assert_equal({ nil => Client.count }, Client.group(:firm).count)
744
+ end
745
+
746
+ def test_should_reference_correct_aliases_while_joining_tables_of_has_many_through_association
747
+ assert_nothing_raised do
748
+ developer = Developer.create!(name: 'developer')
749
+ developer.ratings.includes(comment: :post).where(posts: { id: 1 }).count
750
+ end
751
+ end
752
+
753
+ def test_sum_uses_enumerable_version_when_block_is_given
754
+ block_called = false
755
+ relation = Client.all.load
756
+
757
+ assert_no_queries do
758
+ assert_equal 0, relation.sum { block_called = true; 0 }
759
+ end
760
+ assert block_called
761
+ end
762
+
763
+ def test_having_with_strong_parameters
764
+ protected_params = Class.new do
765
+ attr_reader :permitted
766
+ alias :permitted? :permitted
767
+
768
+ def initialize(parameters)
769
+ @parameters = parameters
770
+ @permitted = false
771
+ end
772
+
773
+ def to_h
774
+ @parameters
775
+ end
776
+
777
+ def permit!
778
+ @permitted = true
779
+ self
780
+ end
781
+ end
782
+
783
+ params = protected_params.new(credit_limit: '50')
784
+
785
+ assert_raises(ActiveModel::ForbiddenAttributesError) do
786
+ Account.group(:id).having(params)
787
+ end
788
+
789
+ result = Account.group(:id).having(params.permit!)
790
+ assert_equal 50, result[0].credit_limit
791
+ assert_equal 50, result[1].credit_limit
792
+ assert_equal 50, result[2].credit_limit
793
+ end
794
+
795
+ def test_group_by_attribute_with_custom_type
796
+ assert_equal({ "proposed" => 2, "published" => 2 }, Book.group(:status).count)
797
+ end
798
+ end