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

Sign up to get free protection for your applications and to get access to all the features.
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,1713 +1,1713 @@
1
- require "cases/helper"
2
- require 'models/post'
3
- require 'models/author'
4
- require 'models/topic'
5
- require 'models/reply'
6
- require 'models/category'
7
- require 'models/company'
8
- require 'models/customer'
9
- require 'models/developer'
10
- require 'models/computer'
11
- require 'models/project'
12
- require 'models/default'
13
- require 'models/auto_id'
14
- require 'models/boolean'
15
- require 'models/column_name'
16
- require 'models/subscriber'
17
- require 'models/keyboard'
18
- require 'models/comment'
19
- require 'models/minimalistic'
20
- require 'models/warehouse_thing'
21
- require 'models/parrot'
22
- require 'models/person'
23
- require 'models/edge'
24
- require 'models/joke'
25
- require 'models/bird'
26
- require 'models/car'
27
- require 'models/bulb'
28
- require 'rexml/document'
29
- require 'concurrent/atomic/count_down_latch'
30
-
31
- class FirstAbstractClass < ActiveRecord::Base
32
- self.abstract_class = true
33
- end
34
- class SecondAbstractClass < FirstAbstractClass
35
- self.abstract_class = true
36
- end
37
- class Photo < SecondAbstractClass; end
38
- class Category < ActiveRecord::Base; end
39
- class Categorization < ActiveRecord::Base; end
40
- class Smarts < ActiveRecord::Base; end
41
- class CreditCard < ActiveRecord::Base
42
- class PinNumber < ActiveRecord::Base
43
- class CvvCode < ActiveRecord::Base; end
44
- class SubCvvCode < CvvCode; end
45
- end
46
- class SubPinNumber < PinNumber; end
47
- class Brand < Category; end
48
- end
49
- class MasterCreditCard < ActiveRecord::Base; end
50
- class Post < ActiveRecord::Base; end
51
- class Computer < ActiveRecord::Base; end
52
- class NonExistentTable < ActiveRecord::Base; end
53
- class TestOracleDefault < ActiveRecord::Base; end
54
-
55
- class ReadonlyTitlePost < Post
56
- attr_readonly :title
57
- end
58
-
59
- class Weird < ActiveRecord::Base; end
60
-
61
- class Boolean < ActiveRecord::Base
62
- def has_fun
63
- super
64
- end
65
- end
66
-
67
- class LintTest < ActiveRecord::TestCase
68
- include ActiveModel::Lint::Tests
69
-
70
- class LintModel < ActiveRecord::Base; end
71
-
72
- def setup
73
- @model = LintModel.new
74
- end
75
- end
76
-
77
- class BasicsTest < ActiveRecord::TestCase
78
- #fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse_things', :authors, :categorizations, :categories, :posts
79
- fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse_things', :categorizations, :categories, :posts
80
-
81
- def test_column_names_are_escaped
82
- puts "In base_test test_column_names_are_escaped"
83
- conn = ActiveRecord::Base.connection
84
- classname = conn.class.name[/[^:]*$/]
85
- badchar = {
86
- 'SQLite3Adapter' => '"',
87
- 'Mysql2Adapter' => '`',
88
- 'PostgreSQLAdapter' => '"',
89
- 'OracleAdapter' => '"',
90
- 'IBM_DBAdapter' => '"',
91
- 'FbAdapter' => '"'
92
- }.fetch(classname) {
93
- raise "need a bad char for #{classname}"
94
- }
95
-
96
- quoted = conn.quote_column_name "foo#{badchar}bar"
97
- if current_adapter?(:OracleAdapter)
98
- # Oracle does not allow double quotes in table and column names at all
99
- # therefore quoting removes them
100
- assert_equal("#{badchar}foobar#{badchar}", quoted)
101
- elsif current_adapter?(:IBM_DBAdapter)
102
- assert_equal("foo#{badchar}bar", quoted)
103
- else
104
- assert_equal("#{badchar}foo#{badchar * 2}bar#{badchar}", quoted)
105
- end
106
- end
107
-
108
- def test_columns_should_obey_set_primary_key
109
- puts "In base_test test_columns_should_obey_set_primary_key"
110
- pk = Subscriber.columns_hash[Subscriber.primary_key]
111
- assert_equal 'nick', pk.name, 'nick should be primary key'
112
- end
113
-
114
- def test_primary_key_with_no_id
115
- puts "In base_test test_primary_key_with_no_id"
116
- assert_nil Edge.primary_key
117
- end
118
-
119
- unless current_adapter?(:PostgreSQLAdapter, :OracleAdapter, :SQLServerAdapter, :IBM_DBAdapter, :FbAdapter)
120
- def test_limit_with_comma
121
- puts "In base_test test_limit_with_comma"
122
- assert_deprecated do
123
- assert Topic.limit("1,2").to_a
124
- end
125
- end
126
- end
127
-
128
- def test_many_mutations
129
- puts "In base_test test_many_mutations"
130
- car = Car.new name: "<3<3<3"
131
- car.engines_count = 0
132
- 20_000.times { car.engines_count += 1 }
133
- assert car.save
134
- end
135
-
136
- def test_limit_without_comma
137
- puts "In base_test test_limit_without_comma"
138
- assert_equal 1, Topic.limit("1").to_a.length
139
- assert_equal 1, Topic.limit(1).to_a.length
140
- end
141
-
142
- def test_limit_should_take_value_from_latest_limit
143
- puts "In base_test test_limit_should_take_value_from_latest_limit"
144
- assert_equal 1, Topic.limit(2).limit(1).to_a.length
145
- end
146
-
147
- def test_invalid_limit
148
- puts "In base_test test_invalid_limit"
149
- assert_raises(ArgumentError) do
150
- Topic.limit("asdfadf").to_a
151
- end
152
- end
153
-
154
- def test_limit_should_sanitize_sql_injection_for_limit_without_commas
155
- puts "In base_test test_limit_should_sanitize_sql_injection_for_limit_without_commas"
156
- assert_raises(ArgumentError) do
157
- Topic.limit("1 select * from schema").to_a
158
- end
159
- end
160
-
161
- def test_limit_should_sanitize_sql_injection_for_limit_with_commas
162
- puts "In base_test test_limit_should_sanitize_sql_injection_for_limit_with_commas"
163
- assert_deprecated do
164
- assert_raises(ArgumentError) do
165
- Topic.limit("1, 7 procedure help()").to_a
166
- end
167
- end
168
- end
169
-
170
- def test_select_symbol
171
- puts "In base_test test_select_symbol"
172
- topic_ids = Topic.select(:id).map(&:id).sort
173
- assert_equal Topic.pluck(:id).sort, topic_ids
174
- end
175
-
176
- def test_table_exists
177
- puts "In base_test test_table_exists"
178
- assert !NonExistentTable.table_exists?
179
- assert Topic.table_exists?
180
- end
181
-
182
- def test_preserving_date_objects
183
- puts "In base_test test_preserving_date_objects"
184
- # Oracle enhanced adapter allows to define Date attributes in model class (see topic.rb)
185
- assert_kind_of(
186
- Date, Topic.find(1).last_read,
187
- "The last_read attribute should be of the Date class"
188
- )
189
- end
190
-
191
- def test_previously_changed
192
- puts "In base_test test_previously_changed"
193
- topic = Topic.first
194
- topic.title = '<3<3<3'
195
- assert_equal({}, topic.previous_changes)
196
-
197
- topic.save!
198
- expected = ["The First Topic", "<3<3<3"]
199
- assert_equal(expected, topic.previous_changes['title'])
200
- end
201
-
202
- def test_previously_changed_dup
203
- puts "In base_test test_previously_changed_dup"
204
- topic = Topic.first
205
- topic.title = '<3<3<3'
206
- topic.save!
207
-
208
- t2 = topic.dup
209
-
210
- assert_equal(topic.previous_changes, t2.previous_changes)
211
-
212
- topic.title = "lolwut"
213
- topic.save!
214
-
215
- assert_not_equal(topic.previous_changes, t2.previous_changes)
216
- end
217
-
218
- def test_preserving_time_objects
219
- puts "In base_test test_preserving_time_objects"
220
- assert_kind_of(
221
- Time, Topic.find(1).bonus_time,
222
- "The bonus_time attribute should be of the Time class"
223
- )
224
-
225
- assert_kind_of(
226
- Time, Topic.find(1).written_on,
227
- "The written_on attribute should be of the Time class"
228
- )
229
-
230
- # For adapters which support microsecond resolution.
231
- if subsecond_precision_supported?
232
- assert_equal 11, Topic.find(1).written_on.sec
233
- assert_equal 223300, Topic.find(1).written_on.usec
234
- assert_equal 9900, Topic.find(2).written_on.usec
235
- assert_equal 129346, Topic.find(3).written_on.usec
236
- end
237
- end
238
-
239
- def test_preserving_time_objects_with_local_time_conversion_to_default_timezone_utc
240
- puts "In base_test test_preserving_time_objects_with_local_time_conversion_to_default_timezone_utc"
241
- with_env_tz eastern_time_zone do
242
- with_timezone_config default: :utc do
243
- time = Time.local(2000)
244
- topic = Topic.create('written_on' => time)
245
- saved_time = Topic.find(topic.id).reload.written_on
246
- assert_equal time, saved_time
247
- assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "EST"], time.to_a
248
- assert_equal [0, 0, 5, 1, 1, 2000, 6, 1, false, "UTC"], saved_time.to_a
249
- end
250
- end
251
- end
252
-
253
- def test_preserving_time_objects_with_time_with_zone_conversion_to_default_timezone_utc
254
- puts "In base_test test_preserving_time_objects_with_time_with_zone_conversion_to_default_timezone_utc"
255
- with_env_tz eastern_time_zone do
256
- with_timezone_config default: :utc do
257
- Time.use_zone 'Central Time (US & Canada)' do
258
- time = Time.zone.local(2000)
259
- topic = Topic.create('written_on' => time)
260
- saved_time = Topic.find(topic.id).reload.written_on
261
- assert_equal time, saved_time
262
- assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "CST"], time.to_a
263
- assert_equal [0, 0, 6, 1, 1, 2000, 6, 1, false, "UTC"], saved_time.to_a
264
- end
265
- end
266
- end
267
- end
268
-
269
- def test_preserving_time_objects_with_utc_time_conversion_to_default_timezone_local
270
- puts "In base_test test_preserving_time_objects_with_utc_time_conversion_to_default_timezone_local"
271
- with_env_tz eastern_time_zone do
272
- with_timezone_config default: :local do
273
- time = Time.utc(2000)
274
- topic = Topic.create('written_on' => time)
275
- saved_time = Topic.find(topic.id).reload.written_on
276
- assert_equal time, saved_time
277
- assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"], time.to_a
278
- assert_equal [0, 0, 19, 31, 12, 1999, 5, 365, false, "EST"], saved_time.to_a
279
- end
280
- end
281
- end
282
-
283
- def test_preserving_time_objects_with_time_with_zone_conversion_to_default_timezone_local
284
- puts "In base_test test_preserving_time_objects_with_time_with_zone_conversion_to_default_timezone_local"
285
- with_env_tz eastern_time_zone do
286
- with_timezone_config default: :local do
287
- Time.use_zone 'Central Time (US & Canada)' do
288
- time = Time.zone.local(2000)
289
- topic = Topic.create('written_on' => time)
290
- saved_time = Topic.find(topic.id).reload.written_on
291
- assert_equal time, saved_time
292
- assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "CST"], time.to_a
293
- assert_equal [0, 0, 1, 1, 1, 2000, 6, 1, false, "EST"], saved_time.to_a
294
- end
295
- end
296
- end
297
- end
298
-
299
- def eastern_time_zone
300
- if Gem.win_platform?
301
- "EST5EDT"
302
- else
303
- "America/New_York"
304
- end
305
- end
306
-
307
- def test_custom_mutator
308
- puts "In base_test test_custom_mutator"
309
- topic = Topic.find(1)
310
- # This mutator is protected in the class definition
311
- topic.send(:approved=, true)
312
- assert topic.instance_variable_get("@custom_approved")
313
- end
314
-
315
- def test_initialize_with_attributes
316
- puts "In base_test test_initialize_with_attributes"
317
- topic = Topic.new({
318
- "title" => "initialized from attributes", "written_on" => "2003-12-12 23:23"
319
- })
320
-
321
- assert_equal("initialized from attributes", topic.title)
322
- end
323
-
324
- def test_initialize_with_invalid_attribute
325
- puts "In base_test test_initialize_with_invalid_attribute"
326
- Topic.new({ "title" => "test",
327
- "last_read(1i)" => "2005", "last_read(2i)" => "2", "last_read(3i)" => "31"})
328
- rescue ActiveRecord::MultiparameterAssignmentErrors => ex
329
- assert_equal(1, ex.errors.size)
330
- assert_equal("last_read", ex.errors[0].attribute)
331
- end
332
-
333
- def test_create_after_initialize_without_block
334
- puts "In base_test test_create_after_initialize_without_block"
335
- cb = CustomBulb.create(:name => 'Dude')
336
- assert_equal('Dude', cb.name)
337
- assert_equal(true, cb.frickinawesome)
338
- end
339
-
340
- def test_create_after_initialize_with_block
341
- puts "In base_test test_create_after_initialize_with_block"
342
- cb = CustomBulb.create {|c| c.name = 'Dude' }
343
- assert_equal('Dude', cb.name)
344
- assert_equal(true, cb.frickinawesome)
345
- end
346
-
347
- def test_create_after_initialize_with_array_param
348
- puts "In base_test test_create_after_initialize_with_array_param"
349
- cbs = CustomBulb.create([{ name: 'Dude' }, { name: 'Bob' }])
350
- assert_equal 'Dude', cbs[0].name
351
- assert_equal 'Bob', cbs[1].name
352
- assert cbs[0].frickinawesome
353
- assert !cbs[1].frickinawesome
354
- end
355
-
356
- def test_load
357
- puts "In base_test test_load"
358
- topics = Topic.all.merge!(:order => 'id').to_a
359
- assert_equal(5, topics.size)
360
- assert_equal(topics(:first).title, topics.first.title)
361
- end
362
-
363
- def test_load_with_condition
364
- puts "In base_test test_load_with_condition"
365
- topics = Topic.all.merge!(:where => "author_name = 'Mary'").to_a
366
-
367
- assert_equal(1, topics.size)
368
- assert_equal(topics(:second).title, topics.first.title)
369
- end
370
-
371
- GUESSED_CLASSES = [Category, Smarts, CreditCard, CreditCard::PinNumber, CreditCard::PinNumber::CvvCode, CreditCard::SubPinNumber, CreditCard::Brand, MasterCreditCard]
372
-
373
- def test_table_name_guesses
374
- puts "In base_test test_table_name_guesses"
375
- assert_equal "topics", Topic.table_name
376
-
377
- assert_equal "categories", Category.table_name
378
- assert_equal "smarts", Smarts.table_name
379
- assert_equal "credit_cards", CreditCard.table_name
380
- assert_equal "credit_card_pin_numbers", CreditCard::PinNumber.table_name
381
- assert_equal "credit_card_pin_number_cvv_codes", CreditCard::PinNumber::CvvCode.table_name
382
- assert_equal "credit_card_pin_numbers", CreditCard::SubPinNumber.table_name
383
- assert_equal "categories", CreditCard::Brand.table_name
384
- assert_equal "master_credit_cards", MasterCreditCard.table_name
385
- ensure
386
- GUESSED_CLASSES.each(&:reset_table_name)
387
- end
388
-
389
- def test_singular_table_name_guesses
390
- puts "In base_test test_singular_table_name_guesses"
391
- ActiveRecord::Base.pluralize_table_names = false
392
- GUESSED_CLASSES.each(&:reset_table_name)
393
-
394
- assert_equal "category", Category.table_name
395
- assert_equal "smarts", Smarts.table_name
396
- assert_equal "credit_card", CreditCard.table_name
397
- assert_equal "credit_card_pin_number", CreditCard::PinNumber.table_name
398
- assert_equal "credit_card_pin_number_cvv_code", CreditCard::PinNumber::CvvCode.table_name
399
- assert_equal "credit_card_pin_number", CreditCard::SubPinNumber.table_name
400
- assert_equal "category", CreditCard::Brand.table_name
401
- assert_equal "master_credit_card", MasterCreditCard.table_name
402
- ensure
403
- ActiveRecord::Base.pluralize_table_names = true
404
- GUESSED_CLASSES.each(&:reset_table_name)
405
- end
406
-
407
- def test_table_name_guesses_with_prefixes_and_suffixes
408
- puts "In base_test test_table_name_guesses_with_prefixes_and_suffixes"
409
- ActiveRecord::Base.table_name_prefix = "test_"
410
- Category.reset_table_name
411
- assert_equal "test_categories", Category.table_name
412
- ActiveRecord::Base.table_name_suffix = "_test"
413
- Category.reset_table_name
414
- assert_equal "test_categories_test", Category.table_name
415
- ActiveRecord::Base.table_name_prefix = ""
416
- Category.reset_table_name
417
- assert_equal "categories_test", Category.table_name
418
- ActiveRecord::Base.table_name_suffix = ""
419
- Category.reset_table_name
420
- assert_equal "categories", Category.table_name
421
- ensure
422
- ActiveRecord::Base.table_name_prefix = ""
423
- ActiveRecord::Base.table_name_suffix = ""
424
- GUESSED_CLASSES.each(&:reset_table_name)
425
- end
426
-
427
- def test_singular_table_name_guesses_with_prefixes_and_suffixes
428
- puts "In base_test test_singular_table_name_guesses_with_prefixes_and_suffixes"
429
- ActiveRecord::Base.pluralize_table_names = false
430
-
431
- ActiveRecord::Base.table_name_prefix = "test_"
432
- Category.reset_table_name
433
- assert_equal "test_category", Category.table_name
434
- ActiveRecord::Base.table_name_suffix = "_test"
435
- Category.reset_table_name
436
- assert_equal "test_category_test", Category.table_name
437
- ActiveRecord::Base.table_name_prefix = ""
438
- Category.reset_table_name
439
- assert_equal "category_test", Category.table_name
440
- ActiveRecord::Base.table_name_suffix = ""
441
- Category.reset_table_name
442
- assert_equal "category", Category.table_name
443
- ensure
444
- ActiveRecord::Base.pluralize_table_names = true
445
- ActiveRecord::Base.table_name_prefix = ""
446
- ActiveRecord::Base.table_name_suffix = ""
447
- GUESSED_CLASSES.each(&:reset_table_name)
448
- end
449
-
450
- def test_table_name_guesses_with_inherited_prefixes_and_suffixes
451
- puts "In base_test test_table_name_guesses_with_inherited_prefixes_and_suffixes"
452
- GUESSED_CLASSES.each(&:reset_table_name)
453
-
454
- CreditCard.table_name_prefix = "test_"
455
- CreditCard.reset_table_name
456
- Category.reset_table_name
457
- assert_equal "test_credit_cards", CreditCard.table_name
458
- assert_equal "categories", Category.table_name
459
- CreditCard.table_name_suffix = "_test"
460
- CreditCard.reset_table_name
461
- Category.reset_table_name
462
- assert_equal "test_credit_cards_test", CreditCard.table_name
463
- assert_equal "categories", Category.table_name
464
- CreditCard.table_name_prefix = ""
465
- CreditCard.reset_table_name
466
- Category.reset_table_name
467
- assert_equal "credit_cards_test", CreditCard.table_name
468
- assert_equal "categories", Category.table_name
469
- CreditCard.table_name_suffix = ""
470
- CreditCard.reset_table_name
471
- Category.reset_table_name
472
- assert_equal "credit_cards", CreditCard.table_name
473
- assert_equal "categories", Category.table_name
474
- ensure
475
- CreditCard.table_name_prefix = ""
476
- CreditCard.table_name_suffix = ""
477
- GUESSED_CLASSES.each(&:reset_table_name)
478
- end
479
-
480
- def test_singular_table_name_guesses_for_individual_table
481
- puts "In base_test test_singular_table_name_guesses_for_individual_table"
482
- Post.pluralize_table_names = false
483
- Post.reset_table_name
484
- assert_equal "post", Post.table_name
485
- assert_equal "categories", Category.table_name
486
- ensure
487
- Post.pluralize_table_names = true
488
- Post.reset_table_name
489
- end
490
-
491
- if current_adapter?(:Mysql2Adapter)
492
- puts "In base_test test_update_all_with_order_and_limit"
493
- def test_update_all_with_order_and_limit
494
- assert_equal 1, Topic.limit(1).order('id DESC').update_all(:content => 'bulk updated!')
495
- end
496
- end
497
-
498
- def test_null_fields
499
- puts "In base_test test_null_fields"
500
- assert_nil Topic.find(1).parent_id
501
- assert_nil Topic.create("title" => "Hey you").parent_id
502
- end
503
-
504
- def test_default_values
505
- puts "In base_test test_default_values"
506
- topic = Topic.new
507
- assert topic.approved?
508
- assert_nil topic.written_on
509
- assert_nil topic.bonus_time
510
- assert_nil topic.last_read
511
-
512
- topic.save
513
-
514
- topic = Topic.find(topic.id)
515
- assert topic.approved?
516
- assert_nil topic.last_read
517
-
518
- # Oracle has some funky default handling, so it requires a bit of
519
- # extra testing. See ticket #2788.
520
- if current_adapter?(:OracleAdapter)
521
- test = TestOracleDefault.new
522
- assert_equal "X", test.test_char
523
- assert_equal "hello", test.test_string
524
- assert_equal 3, test.test_int
525
- end
526
- end
527
-
528
- # Oracle does not have a TIME datatype.
529
- unless current_adapter?(:OracleAdapter,:IBM_DBAdapter)
530
- def test_utc_as_time_zone
531
- puts "In base_test test_utc_as_time_zone"
532
- with_timezone_config default: :utc do
533
- attributes = { "bonus_time" => "5:42:00AM" }
534
- topic = Topic.find(1)
535
- topic.attributes = attributes
536
- assert_equal Time.utc(2000, 1, 1, 5, 42, 0), topic.bonus_time
537
- end
538
- end
539
- end
540
-
541
- def test_utc_as_time_zone_and_new
542
- puts "In base_test test_utc_as_time_zone_and_new"
543
- with_timezone_config default: :utc do
544
- attributes = { "bonus_time(1i)"=>"2000",
545
- "bonus_time(2i)"=>"1",
546
- "bonus_time(3i)"=>"1",
547
- "bonus_time(4i)"=>"10",
548
- "bonus_time(5i)"=>"35",
549
- "bonus_time(6i)"=>"50" }
550
- topic = Topic.new(attributes)
551
- assert_equal Time.utc(2000, 1, 1, 10, 35, 50), topic.bonus_time
552
- end
553
- end
554
- end
555
-
556
- def test_default_values_on_empty_strings
557
- puts "In base_test test_default_values_on_empty_strings"
558
- topic = Topic.new
559
- topic.approved = nil
560
- topic.last_read = nil
561
-
562
- topic.save
563
-
564
- topic = Topic.find(topic.id)
565
- assert_nil topic.last_read
566
-
567
- assert_nil topic.approved
568
- end
569
-
570
- def test_equality
571
- puts "In base_test test_equality"
572
- assert_equal Topic.find(1), Topic.find(2).topic
573
- end
574
-
575
- def test_find_by_slug
576
- puts "In base_test test_find_by_slug"
577
- assert_equal Topic.find('1-meowmeow'), Topic.find(1)
578
- end
579
-
580
- def test_find_by_slug_with_array
581
- puts "In base_test test_find_by_slug_with_array"
582
- assert_equal Topic.find([1, 2]), Topic.find(['1-meowmeow', '2-hello'])
583
- assert_equal 'The Second Topic of the day', Topic.find(['2-hello', '1-meowmeow']).first.title
584
- end
585
-
586
- def test_find_by_slug_with_range
587
- puts "In base_test test_find_by_slug_with_range"
588
- assert_equal Topic.where(id: '1-meowmeow'..'2-hello'), Topic.where(id: 1..2)
589
- end
590
-
591
- def test_equality_of_new_records
592
- puts "In base_test test_equality_of_new_records"
593
- assert_not_equal Topic.new, Topic.new
594
- assert_equal false, Topic.new == Topic.new
595
- end
596
-
597
- def test_equality_of_destroyed_records
598
- puts "In base_test test_equality_of_destroyed_records"
599
- topic_1 = Topic.new(:title => 'test_1')
600
- topic_1.save
601
- topic_2 = Topic.find(topic_1.id)
602
- topic_1.destroy
603
- assert_equal topic_1, topic_2
604
- assert_equal topic_2, topic_1
605
- end
606
-
607
- def test_equality_with_blank_ids
608
- puts "In base_test test_equality_with_blank_ids"
609
- one = Subscriber.new(:id => '')
610
- two = Subscriber.new(:id => '')
611
- assert_equal one, two
612
- end
613
-
614
- def test_equality_of_relation_and_collection_proxy
615
- puts "In base_test test_equality_of_relation_and_collection_proxy"
616
- car = Car.create!
617
- car.bulbs.build
618
- car.save
619
-
620
- assert car.bulbs == Bulb.where(car_id: car.id), 'CollectionProxy should be comparable with Relation'
621
- assert Bulb.where(car_id: car.id) == car.bulbs, 'Relation should be comparable with CollectionProxy'
622
- end
623
-
624
- def test_equality_of_relation_and_array
625
- puts "In base_test test_equality_of_relation_and_array"
626
- car = Car.create!
627
- car.bulbs.build
628
- car.save
629
-
630
- assert Bulb.where(car_id: car.id) == car.bulbs.to_a, 'Relation should be comparable with Array'
631
- end
632
-
633
- def test_equality_of_relation_and_association_relation
634
- puts "In base_test test_equality_of_relation_and_association_relation"
635
- car = Car.create!
636
- car.bulbs.build
637
- car.save
638
-
639
- assert_equal Bulb.where(car_id: car.id), car.bulbs.includes(:car), 'Relation should be comparable with AssociationRelation'
640
- assert_equal car.bulbs.includes(:car), Bulb.where(car_id: car.id), 'AssociationRelation should be comparable with Relation'
641
- end
642
-
643
- def test_equality_of_collection_proxy_and_association_relation
644
- puts "In base_test test_equality_of_collection_proxy_and_association_relation"
645
- car = Car.create!
646
- car.bulbs.build
647
- car.save
648
-
649
- assert_equal car.bulbs, car.bulbs.includes(:car), 'CollectionProxy should be comparable with AssociationRelation'
650
- assert_equal car.bulbs.includes(:car), car.bulbs, 'AssociationRelation should be comparable with CollectionProxy'
651
- end
652
-
653
- def test_hashing
654
- puts "In base_test test_hashing"
655
- assert_equal [ Topic.find(1) ], [ Topic.find(2).topic ] & [ Topic.find(1) ]
656
- end
657
-
658
- def test_successful_comparison_of_like_class_records
659
- puts "In base_test test_successful_comparison_of_like_class_records"
660
- topic_1 = Topic.create!
661
- topic_2 = Topic.create!
662
-
663
- assert_equal [topic_2, topic_1].sort, [topic_1, topic_2]
664
- end
665
-
666
- def test_failed_comparison_of_unlike_class_records
667
- puts "In base_test test_failed_comparison_of_unlike_class_records"
668
- assert_raises ArgumentError do
669
- [ topics(:first), posts(:welcome) ].sort
670
- end
671
- end
672
-
673
- def test_create_without_prepared_statement
674
- puts "In base_test test_create_without_prepared_statement"
675
- topic = Topic.connection.unprepared_statement do
676
- Topic.create(:title => 'foo')
677
- end
678
-
679
- assert_equal topic, Topic.find(topic.id)
680
- end
681
-
682
- def test_destroy_without_prepared_statement
683
- puts "In base_test test_destroy_without_prepared_statement"
684
- topic = Topic.create(title: 'foo')
685
- Topic.connection.unprepared_statement do
686
- Topic.find(topic.id).destroy
687
- end
688
-
689
- assert_equal nil, Topic.find_by_id(topic.id)
690
- end
691
-
692
- def test_comparison_with_different_objects
693
- puts "In base_test test_comparison_with_different_objects"
694
- topic = Topic.create
695
- category = Category.create(:name => "comparison")
696
- assert_nil topic <=> category
697
- end
698
-
699
- def test_comparison_with_different_objects_in_array
700
- puts "In base_test test_comparison_with_different_objects_in_array"
701
- topic = Topic.create
702
- assert_raises(ArgumentError) do
703
- [1, topic].sort
704
- end
705
- end
706
-
707
- def test_readonly_attributes
708
- puts "In base_test test_readonly_attributes"
709
- assert_equal Set.new([ 'title' , 'comments_count' ]), ReadonlyTitlePost.readonly_attributes
710
-
711
- post = ReadonlyTitlePost.create(:title => "cannot change this", :body => "changeable")
712
- post.reload
713
- assert_equal "cannot change this", post.title
714
-
715
- post.update(title: "try to change", body: "changed")
716
- post.reload
717
- assert_equal "cannot change this", post.title
718
- assert_equal "changed", post.body
719
- end
720
-
721
- def test_unicode_column_name
722
- puts "In base_test test_unicode_column_name"
723
- Weird.reset_column_information
724
- weird = Weird.create(:なまえ => 'たこ焼き仮面')
725
- assert_equal 'たこ焼き仮面', weird.なまえ
726
- end
727
-
728
- unless current_adapter?(:PostgreSQLAdapter)
729
- def test_respect_internal_encoding
730
- puts "In base_test test_respect_internal_encoding"
731
- old_default_internal = Encoding.default_internal
732
- silence_warnings { Encoding.default_internal = "EUC-JP" }
733
-
734
- Weird.reset_column_information
735
-
736
- assert_equal ["EUC-JP"], Weird.columns.map {|c| c.name.encoding.name }.uniq
737
- ensure
738
- silence_warnings { Encoding.default_internal = old_default_internal }
739
- Weird.reset_column_information
740
- end
741
- end
742
-
743
- def test_non_valid_identifier_column_name
744
- puts "In base_test test_non_valid_identifier_column_name"
745
- weird = Weird.create('a$b' => 'value')
746
- weird.reload
747
- assert_equal 'value', weird.send('a$b')
748
- assert_equal 'value', weird.read_attribute('a$b')
749
-
750
- weird.update_columns('a$b' => 'value2')
751
- weird.reload
752
- assert_equal 'value2', weird.send('a$b')
753
- assert_equal 'value2', weird.read_attribute('a$b')
754
- end
755
-
756
- def test_group_weirds_by_from
757
- puts "In base_test test_group_weirds_by_from"
758
- Weird.create('a$b' => 'value', :from => 'aaron')
759
- count = Weird.group(Weird.arel_table[:from]).count
760
- assert_equal 1, count['aaron']
761
- end
762
-
763
- def test_attributes_on_dummy_time
764
- puts "In base_test test_attributes_on_dummy_time"
765
- # Oracle does not have a TIME datatype.
766
- return true if current_adapter?(:OracleAdapter)
767
-
768
- with_timezone_config default: :local do
769
- attributes = {
770
- "bonus_time" => "5:42:00AM"
771
- }
772
- topic = Topic.find(1)
773
- topic.attributes = attributes
774
- assert_equal Time.local(2000, 1, 1, 5, 42, 0), topic.bonus_time
775
- end
776
- end
777
-
778
- def test_attributes_on_dummy_time_with_invalid_time
779
- puts "In base_test test_attributes_on_dummy_time_with_invalid_time"
780
- # Oracle does not have a TIME datatype.
781
- return true if current_adapter?(:OracleAdapter)
782
-
783
- attributes = {
784
- "bonus_time" => "not a time"
785
- }
786
- topic = Topic.find(1)
787
- topic.attributes = attributes
788
- assert_nil topic.bonus_time
789
- end
790
-
791
- def test_boolean
792
- puts "In base_test test_boolean"
793
- b_nil = Boolean.create({ "value" => nil })
794
- nil_id = b_nil.id
795
- b_false = Boolean.create({ "value" => false })
796
- false_id = b_false.id
797
- b_true = Boolean.create({ "value" => true })
798
- true_id = b_true.id
799
-
800
- b_nil = Boolean.find(nil_id)
801
- assert_nil b_nil.value
802
- b_false = Boolean.find(false_id)
803
- assert !b_false.value?
804
- b_true = Boolean.find(true_id)
805
- assert b_true.value?
806
- end
807
-
808
- def test_boolean_without_questionmark
809
- puts "In base_test test_boolean_without_questionmark"
810
- b_true = Boolean.create({ "value" => true })
811
- true_id = b_true.id
812
-
813
- subclass = Class.new(Boolean).find true_id
814
- superclass = Boolean.find true_id
815
-
816
- assert_equal superclass.read_attribute(:has_fun), subclass.read_attribute(:has_fun)
817
- end
818
-
819
- def test_boolean_cast_from_string
820
- puts "In base_test test_boolean_cast_from_string"
821
- b_blank = Boolean.create({ "value" => "" })
822
- blank_id = b_blank.id
823
- b_false = Boolean.create({ "value" => "0" })
824
- false_id = b_false.id
825
- b_true = Boolean.create({ "value" => "1" })
826
- true_id = b_true.id
827
-
828
- b_blank = Boolean.find(blank_id)
829
- assert_nil b_blank.value
830
- b_false = Boolean.find(false_id)
831
- assert !b_false.value?
832
- b_true = Boolean.find(true_id)
833
- assert b_true.value?
834
- end
835
-
836
- def test_new_record_returns_boolean
837
- puts "In base_test test_new_record_returns_boolean"
838
- assert_equal false, Topic.new.persisted?
839
- assert_equal true, Topic.find(1).persisted?
840
- end
841
-
842
- def test_dup
843
- puts "In base_test test_dup"
844
- topic = Topic.find(1)
845
- duped_topic = nil
846
- assert_nothing_raised { duped_topic = topic.dup }
847
- assert_equal topic.title, duped_topic.title
848
- assert !duped_topic.persisted?
849
-
850
- # test if the attributes have been duped
851
- topic.title = "a"
852
- duped_topic.title = "b"
853
- assert_equal "a", topic.title
854
- assert_equal "b", duped_topic.title
855
-
856
- # test if the attribute values have been duped
857
- duped_topic = topic.dup
858
- duped_topic.title.replace "c"
859
- assert_equal "a", topic.title
860
-
861
- # test if attributes set as part of after_initialize are duped correctly
862
- assert_equal topic.author_email_address, duped_topic.author_email_address
863
-
864
- # test if saved clone object differs from original
865
- duped_topic.save
866
- assert duped_topic.persisted?
867
- assert_not_equal duped_topic.id, topic.id
868
-
869
- duped_topic.reload
870
- assert_equal("c", duped_topic.title)
871
- end
872
-
873
- DeveloperSalary = Struct.new(:amount)
874
- def test_dup_with_aggregate_of_same_name_as_attribute
875
- puts "In base_test test_dup_with_aggregate_of_same_name_as_attribute"
876
- developer_with_aggregate = Class.new(ActiveRecord::Base) do
877
- self.table_name = 'developers'
878
- composed_of :salary, :class_name => 'BasicsTest::DeveloperSalary', :mapping => [%w(salary amount)]
879
- end
880
-
881
- dev = developer_with_aggregate.find(1)
882
- assert_kind_of DeveloperSalary, dev.salary
883
-
884
- dup = nil
885
- assert_nothing_raised { dup = dev.dup }
886
- assert_kind_of DeveloperSalary, dup.salary
887
- assert_equal dev.salary.amount, dup.salary.amount
888
- assert !dup.persisted?
889
-
890
- # test if the attributes have been duped
891
- original_amount = dup.salary.amount
892
- dev.salary.amount = 1
893
- assert_equal original_amount, dup.salary.amount
894
-
895
- assert dup.save
896
- assert dup.persisted?
897
- assert_not_equal dup.id, dev.id
898
- end
899
-
900
- def test_dup_does_not_copy_associations
901
- puts "In base_test test_dup_does_not_copy_associations"
902
- author = authors(:david)
903
- assert_not_equal [], author.posts
904
-
905
- author_dup = author.dup
906
- assert_equal [], author_dup.posts
907
- end
908
-
909
- def test_clone_preserves_subtype
910
- puts "In base_test test_clone_preserves_subtype"
911
- clone = nil
912
- assert_nothing_raised { clone = Company.find(3).clone }
913
- assert_kind_of Client, clone
914
- end
915
-
916
- def test_clone_of_new_object_with_defaults
917
- puts "In base_test test_clone_of_new_object_with_defaults"
918
- developer = Developer.new
919
- assert !developer.name_changed?
920
- assert !developer.salary_changed?
921
-
922
- cloned_developer = developer.clone
923
- assert !cloned_developer.name_changed?
924
- assert !cloned_developer.salary_changed?
925
- end
926
-
927
- def test_clone_of_new_object_marks_attributes_as_dirty
928
- puts "In base_test test_clone_of_new_object_marks_attributes_as_dirty"
929
- developer = Developer.new :name => 'Bjorn', :salary => 100000
930
- assert developer.name_changed?
931
- assert developer.salary_changed?
932
-
933
- cloned_developer = developer.clone
934
- assert cloned_developer.name_changed?
935
- assert cloned_developer.salary_changed?
936
- end
937
-
938
- def test_clone_of_new_object_marks_as_dirty_only_changed_attributes
939
- puts "In base_test test_clone_of_new_object_marks_as_dirty_only_changed_attributes"
940
- developer = Developer.new :name => 'Bjorn'
941
- assert developer.name_changed? # obviously
942
- assert !developer.salary_changed? # attribute has non-nil default value, so treated as not changed
943
-
944
- cloned_developer = developer.clone
945
- assert cloned_developer.name_changed?
946
- assert !cloned_developer.salary_changed? # ... and cloned instance should behave same
947
- end
948
-
949
- def test_dup_of_saved_object_marks_attributes_as_dirty
950
- puts "In base_test test_dup_of_saved_object_marks_attributes_as_dirty"
951
- developer = Developer.create! :name => 'Bjorn', :salary => 100000
952
- assert !developer.name_changed?
953
- assert !developer.salary_changed?
954
-
955
- cloned_developer = developer.dup
956
- assert cloned_developer.name_changed? # both attributes differ from defaults
957
- assert cloned_developer.salary_changed?
958
- end
959
-
960
- def test_dup_of_saved_object_marks_as_dirty_only_changed_attributes
961
- puts "In base_test test_dup_of_saved_object_marks_as_dirty_only_changed_attributes"
962
- developer = Developer.create! :name => 'Bjorn'
963
- assert !developer.name_changed? # both attributes of saved object should be treated as not changed
964
- assert !developer.salary_changed?
965
-
966
- cloned_developer = developer.dup
967
- assert cloned_developer.name_changed? # ... but on cloned object should be
968
- assert !cloned_developer.salary_changed? # ... BUT salary has non-nil default which should be treated as not changed on cloned instance
969
- end
970
-
971
- def test_bignum
972
- puts "In base_test test_bignum"
973
- company = Company.find(1)
974
- company.rating = 2147483647
975
- company.save
976
- company = Company.find(1)
977
- assert_equal 2147483647, company.rating
978
- end
979
-
980
- # TODO: extend defaults tests to other databases!
981
- if current_adapter?(:PostgreSQLAdapter)
982
- def test_default
983
- puts "In base_test test_default"
984
- with_timezone_config default: :local do
985
- default = Default.new
986
-
987
- # fixed dates / times
988
- assert_equal Date.new(2004, 1, 1), default.fixed_date
989
- assert_equal Time.local(2004, 1,1,0,0,0,0), default.fixed_time
990
-
991
- # char types
992
- assert_equal 'Y', default.char1
993
- assert_equal 'a varchar field', default.char2
994
- assert_equal 'a text field', default.char3
995
- end
996
- end
997
- end
998
-
999
- class NumericData < ActiveRecord::Base
1000
- self.table_name = 'numeric_data'
1001
-
1002
- attribute :my_house_population, :integer
1003
- attribute :atoms_in_universe, :integer
1004
- end
1005
-
1006
- def test_big_decimal_conditions
1007
- puts "In base_test test_big_decimal_conditions"
1008
- m = NumericData.new(
1009
- :bank_balance => 1586.43,
1010
- :big_bank_balance => BigDecimal("1000234000567.95"),
1011
- :world_population => 6000000000,
1012
- :my_house_population => 3
1013
- )
1014
- assert m.save
1015
- assert_equal 0, NumericData.where("bank_balance > ?", 2000.0).count
1016
- end
1017
-
1018
- def test_numeric_fields
1019
- puts "In base_test test_numeric_fields"
1020
- m = NumericData.new(
1021
- :bank_balance => 1586.43,
1022
- :big_bank_balance => BigDecimal("1000234000567.95"),
1023
- :world_population => 6000000000,
1024
- :my_house_population => 3
1025
- )
1026
- assert m.save
1027
-
1028
- m1 = NumericData.find(m.id)
1029
- assert_not_nil m1
1030
-
1031
- # As with migration_test.rb, we should make world_population >= 2**62
1032
- # to cover 64-bit platforms and test it is a Bignum, but the main thing
1033
- # is that it's an Integer.
1034
- unless current_adapter?(:IBM_DBAdapter)
1035
- assert_kind_of Integer, m1.world_population
1036
- else
1037
- assert_equal 6000000000, m1.world_population
1038
-
1039
- assert_kind_of Integer, m1.my_house_population
1040
- assert_equal 3, m1.my_house_population
1041
-
1042
- assert_kind_of BigDecimal, m1.bank_balance
1043
- assert_equal BigDecimal("1586.43"), m1.bank_balance
1044
-
1045
- assert_kind_of BigDecimal, m1.big_bank_balance
1046
- assert_equal BigDecimal("1000234000567.95"), m1.big_bank_balance
1047
- end
1048
-
1049
- def test_numeric_fields_with_scale
1050
- puts "In base_test test_numeric_fields_with_scale"
1051
- m = NumericData.new(
1052
- :bank_balance => 1586.43122334,
1053
- :big_bank_balance => BigDecimal("234000567.952344"),
1054
- :world_population => 6000000000,
1055
- :my_house_population => 3
1056
- )
1057
- assert m.save
1058
-
1059
- m1 = NumericData.find(m.id)
1060
- assert_not_nil m1
1061
-
1062
- # As with migration_test.rb, we should make world_population >= 2**62
1063
- # to cover 64-bit platforms and test it is a Bignum, but the main thing
1064
- # is that it's an Integer.
1065
- assert_kind_of Integer, m1.world_population
1066
- assert_equal 6000000000, m1.world_population
1067
-
1068
- assert_kind_of Integer, m1.my_house_population
1069
- assert_equal 3, m1.my_house_population
1070
-
1071
- assert_kind_of BigDecimal, m1.bank_balance
1072
- assert_equal BigDecimal("1586.43"), m1.bank_balance
1073
-
1074
- assert_kind_of BigDecimal, m1.big_bank_balance
1075
- assert_equal BigDecimal("234000567.95"), m1.big_bank_balance
1076
- end
1077
-
1078
- def test_auto_id
1079
- puts "In base_test test_auto_id"
1080
- auto = AutoId.new
1081
- auto.save
1082
- assert(auto.id > 0)
1083
- end
1084
-
1085
- def test_sql_injection_via_find
1086
- puts "In base_test test_sql_injection_via_find"
1087
- assert_raise(ActiveRecord::RecordNotFound, ActiveRecord::StatementInvalid) do
1088
- Topic.find("123456 OR id > 0")
1089
- end
1090
- end
1091
-
1092
- def test_column_name_properly_quoted
1093
- puts "In base_test test_column_name_properly_quoted"
1094
- col_record = ColumnName.new
1095
- col_record.references = 40
1096
- assert col_record.save
1097
- col_record.references = 41
1098
- assert col_record.save
1099
- assert_not_nil c2 = ColumnName.find(col_record.id)
1100
- assert_equal(41, c2.references)
1101
- end
1102
-
1103
- def test_quoting_arrays
1104
- puts "In base_test test_quoting_arrays"
1105
- replies = Reply.all.merge!(:where => [ "id IN (?)", topics(:first).replies.collect(&:id) ]).to_a
1106
- assert_equal topics(:first).replies.size, replies.size
1107
-
1108
- replies = Reply.all.merge!(:where => [ "id IN (?)", [] ]).to_a
1109
- assert_equal 0, replies.size
1110
- end
1111
-
1112
- def test_quote
1113
- puts "In base_test test_quote"
1114
- author_name = "\\ \001 ' \n \\n \""
1115
- topic = Topic.create('author_name' => author_name)
1116
- assert_equal author_name, Topic.find(topic.id).author_name
1117
- end
1118
-
1119
- def test_toggle_attribute
1120
- puts "In base_test test_toggle_attribute"
1121
- assert !topics(:first).approved?
1122
- topics(:first).toggle!(:approved)
1123
- assert topics(:first).approved?
1124
- topic = topics(:first)
1125
- topic.toggle(:approved)
1126
- assert !topic.approved?
1127
- topic.reload
1128
- assert topic.approved?
1129
- end
1130
-
1131
- def test_reload
1132
- puts "In base_test test_reload"
1133
- t1 = Topic.find(1)
1134
- t2 = Topic.find(1)
1135
- t1.title = "something else"
1136
- t1.save
1137
- t2.reload
1138
- assert_equal t1.title, t2.title
1139
- end
1140
-
1141
- def test_reload_with_exclusive_scope
1142
- puts "In base_test test_reload_with_exclusive_scope"
1143
- dev = DeveloperCalledDavid.first
1144
- dev.update!(name: "NotDavid" )
1145
- assert_equal dev, dev.reload
1146
- end
1147
-
1148
- def test_switching_between_table_name
1149
- puts "In base_test test_switching_between_table_name"
1150
- k = Class.new(Joke)
1151
-
1152
- assert_difference("GoodJoke.count") do
1153
- k.table_name = "cold_jokes"
1154
- k.create
1155
-
1156
- k.table_name = "funny_jokes"
1157
- k.create
1158
- end
1159
- end
1160
-
1161
- def test_clear_cash_when_setting_table_name
1162
- puts "In base_test test_clear_cash_when_setting_table_name"
1163
- original_table_name = Joke.table_name
1164
-
1165
- Joke.table_name = "funny_jokes"
1166
- before_columns = Joke.columns
1167
- before_seq = Joke.sequence_name
1168
-
1169
- Joke.table_name = "cold_jokes"
1170
- after_columns = Joke.columns
1171
- after_seq = Joke.sequence_name
1172
-
1173
- assert_not_equal before_columns, after_columns
1174
- assert_not_equal before_seq, after_seq unless before_seq.nil? && after_seq.nil?
1175
- ensure
1176
- Joke.table_name = original_table_name
1177
- end
1178
-
1179
- def test_dont_clear_sequence_name_when_setting_explicitly
1180
- puts "In base_test test_dont_clear_sequence_name_when_setting_explicitly"
1181
- k = Class.new(Joke)
1182
- k.sequence_name = "black_jokes_seq"
1183
- k.table_name = "cold_jokes"
1184
- before_seq = k.sequence_name
1185
-
1186
- k.table_name = "funny_jokes"
1187
- after_seq = k.sequence_name
1188
-
1189
- assert_equal before_seq, after_seq unless before_seq.nil? && after_seq.nil?
1190
- end
1191
-
1192
- def test_dont_clear_inheritance_column_when_setting_explicitly
1193
- puts "In base_test test_dont_clear_inheritance_column_when_setting_explicitly"
1194
- k = Class.new(Joke)
1195
- k.inheritance_column = "my_type"
1196
- before_inherit = k.inheritance_column
1197
-
1198
- k.reset_column_information
1199
- after_inherit = k.inheritance_column
1200
-
1201
- assert_equal before_inherit, after_inherit unless before_inherit.blank? && after_inherit.blank?
1202
- end
1203
-
1204
- def test_set_table_name_symbol_converted_to_string
1205
- puts "In base_test test_set_table_name_symbol_converted_to_string"
1206
- k = Class.new(Joke)
1207
- k.table_name = :cold_jokes
1208
- assert_equal 'cold_jokes', k.table_name
1209
- end
1210
-
1211
- def test_quoted_table_name_after_set_table_name
1212
- puts "In base_test test_quoted_table_name_after_set_table_name"
1213
- klass = Class.new(ActiveRecord::Base)
1214
-
1215
- klass.table_name = "foo"
1216
- assert_equal "foo", klass.table_name
1217
- assert_equal klass.connection.quote_table_name("foo"), klass.quoted_table_name
1218
-
1219
- klass.table_name = "bar"
1220
- assert_equal "bar", klass.table_name
1221
- assert_equal klass.connection.quote_table_name("bar"), klass.quoted_table_name
1222
- end
1223
-
1224
- def test_set_table_name_with_inheritance
1225
- puts "In base_test test_set_table_name_with_inheritance"
1226
- k = Class.new( ActiveRecord::Base )
1227
- def k.name; "Foo"; end
1228
- def k.table_name; super + "ks"; end
1229
- assert_equal "foosks", k.table_name
1230
- end
1231
-
1232
- def test_sequence_name_with_abstract_class
1233
- puts "In base_test test_sequence_name_with_abstract_class"
1234
- ak = Class.new(ActiveRecord::Base)
1235
- ak.abstract_class = true
1236
- k = Class.new(ak)
1237
- k.table_name = "projects"
1238
- orig_name = k.sequence_name
1239
- skip "sequences not supported by db" unless orig_name
1240
- assert_equal k.reset_sequence_name, orig_name
1241
- end
1242
-
1243
- def test_count_with_join
1244
- puts "In base_test test_count_with_join"
1245
- res = Post.count_by_sql "SELECT COUNT(*) FROM posts LEFT JOIN comments ON posts.id=comments.post_id WHERE posts.#{QUOTED_TYPE} = 'Post'"
1246
-
1247
- res2 = Post.where("posts.#{QUOTED_TYPE} = 'Post'").joins("LEFT JOIN comments ON posts.id=comments.post_id").count
1248
- assert_equal res, res2
1249
-
1250
- res3 = nil
1251
- assert_nothing_raised do
1252
- res3 = Post.where("posts.#{QUOTED_TYPE} = 'Post'").joins("LEFT JOIN comments ON posts.id=comments.post_id").count
1253
- end
1254
- assert_equal res, res3
1255
-
1256
- res4 = Post.count_by_sql "SELECT COUNT(p.id) FROM posts p, comments co WHERE p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id"
1257
- res5 = nil
1258
- assert_nothing_raised do
1259
- res5 = Post.where("p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id").joins("p, comments co").select("p.id").count
1260
- end
1261
-
1262
- assert_equal res4, res5
1263
-
1264
- res6 = Post.count_by_sql "SELECT COUNT(DISTINCT p.id) FROM posts p, comments co WHERE p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id"
1265
- res7 = nil
1266
- assert_nothing_raised do
1267
- res7 = Post.where("p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id").joins("p, comments co").select("p.id").distinct.count
1268
- end
1269
- assert_equal res6, res7
1270
- end
1271
-
1272
- def test_no_limit_offset
1273
- puts "In base_test test_no_limit_offset"
1274
- assert_nothing_raised do
1275
- Developer.all.merge!(:offset => 2).to_a
1276
- end
1277
- end
1278
-
1279
- def test_find_last
1280
- puts "In base_test test_find_last"
1281
- last = Developer.last
1282
- assert_equal last, Developer.all.merge!(:order => 'id desc').first
1283
- end
1284
-
1285
- def test_last
1286
- puts "In base_test test_last"
1287
- assert_equal Developer.all.merge!(:order => 'id desc').first, Developer.last
1288
- end
1289
-
1290
- def test_all
1291
- puts "In base_test test_all"
1292
- developers = Developer.all
1293
- assert_kind_of ActiveRecord::Relation, developers
1294
- assert_equal Developer.all, developers
1295
- end
1296
-
1297
- def test_all_with_conditions
1298
- puts "In base_test test_all_with_conditions"
1299
- assert_equal Developer.all.merge!(:order => 'id desc').to_a, Developer.order('id desc').to_a
1300
- end
1301
-
1302
- def test_find_ordered_last
1303
- puts "In base_test test_find_ordered_last"
1304
- last = Developer.all.merge!(:order => 'developers.salary ASC').last
1305
- assert_equal last, Developer.all.merge!(:order => 'developers.salary ASC').to_a.last
1306
- end
1307
-
1308
- def test_find_reverse_ordered_last
1309
- puts "In base_test test_find_reverse_ordered_last"
1310
- last = Developer.all.merge!(:order => 'developers.salary DESC').last
1311
- assert_equal last, Developer.all.merge!(:order => 'developers.salary DESC').to_a.last
1312
- end
1313
-
1314
- def test_find_multiple_ordered_last
1315
- puts "In base_test test_find_multiple_ordered_last"
1316
- last = Developer.all.merge!(:order => 'developers.name, developers.salary DESC').last
1317
- assert_equal last, Developer.all.merge!(:order => 'developers.name, developers.salary DESC').to_a.last
1318
- end
1319
-
1320
- def test_find_keeps_multiple_order_values
1321
- puts "In base_test test_find_keeps_multiple_order_values"
1322
- combined = Developer.all.merge!(:order => 'developers.name, developers.salary').to_a
1323
- assert_equal combined, Developer.all.merge!(:order => ['developers.name', 'developers.salary']).to_a
1324
- end
1325
-
1326
- def test_find_keeps_multiple_group_values
1327
- puts "In base_test test_find_keeps_multiple_group_values"
1328
- combined = Developer.all.merge!(:group => 'developers.name, developers.salary, developers.id, developers.created_at, developers.updated_at, developers.created_on, developers.updated_on').to_a
1329
- assert_equal combined, Developer.all.merge!(:group => ['developers.name', 'developers.salary', 'developers.id', 'developers.created_at', 'developers.updated_at', 'developers.created_on', 'developers.updated_on']).to_a
1330
- end
1331
-
1332
- def test_find_symbol_ordered_last
1333
- puts "In base_test test_find_symbol_ordered_last"
1334
- last = Developer.all.merge!(:order => :salary).last
1335
- assert_equal last, Developer.all.merge!(:order => :salary).to_a.last
1336
- end
1337
-
1338
- def test_abstract_class_table_name
1339
- puts "In base_test test_abstract_class_table_name"
1340
- assert_nil AbstractCompany.table_name
1341
- end
1342
-
1343
- def test_find_on_abstract_base_class_doesnt_use_type_condition
1344
- puts "In base_test test_find_on_abstract_base_class_doesnt_use_type_condition"
1345
- old_class = LooseDescendant
1346
- Object.send :remove_const, :LooseDescendant
1347
-
1348
- descendant = old_class.create! :first_name => 'bob'
1349
- assert_not_nil LoosePerson.find(descendant.id), "Should have found instance of LooseDescendant when finding abstract LoosePerson: #{descendant.inspect}"
1350
- ensure
1351
- unless Object.const_defined?(:LooseDescendant)
1352
- Object.const_set :LooseDescendant, old_class
1353
- end
1354
- end
1355
-
1356
- def test_assert_queries
1357
- puts "In base_test test_assert_queries"
1358
- query = lambda { ActiveRecord::Base.connection.execute 'select count(*) from developers' }
1359
- assert_queries(2) { 2.times { query.call } }
1360
- assert_queries 1, &query
1361
- assert_no_queries { assert true }
1362
- end
1363
-
1364
- def test_benchmark_with_log_level
1365
- puts "In base_test test_benchmark_with_log_level"
1366
- original_logger = ActiveRecord::Base.logger
1367
- log = StringIO.new
1368
- ActiveRecord::Base.logger = ActiveSupport::Logger.new(log)
1369
- ActiveRecord::Base.logger.level = Logger::WARN
1370
- ActiveRecord::Base.benchmark("Debug Topic Count", :level => :debug) { Topic.count }
1371
- ActiveRecord::Base.benchmark("Warn Topic Count", :level => :warn) { Topic.count }
1372
- ActiveRecord::Base.benchmark("Error Topic Count", :level => :error) { Topic.count }
1373
- assert_no_match(/Debug Topic Count/, log.string)
1374
- assert_match(/Warn Topic Count/, log.string)
1375
- assert_match(/Error Topic Count/, log.string)
1376
- ensure
1377
- ActiveRecord::Base.logger = original_logger
1378
- end
1379
-
1380
- def test_benchmark_with_use_silence
1381
- puts "In base_test test_benchmark_with_use_silence"
1382
- original_logger = ActiveRecord::Base.logger
1383
- log = StringIO.new
1384
- ActiveRecord::Base.logger = ActiveSupport::Logger.new(log)
1385
- ActiveRecord::Base.logger.level = Logger::DEBUG
1386
- ActiveRecord::Base.benchmark("Logging", :level => :debug, :silence => false) { ActiveRecord::Base.logger.debug "Quiet" }
1387
- assert_match(/Quiet/, log.string)
1388
- ensure
1389
- ActiveRecord::Base.logger = original_logger
1390
- end
1391
-
1392
- def test_clear_cache!
1393
- puts "In base_test test_clear_cache"
1394
- # preheat cache
1395
- c1 = Post.connection.schema_cache.columns('posts')
1396
- ActiveRecord::Base.clear_cache!
1397
- c2 = Post.connection.schema_cache.columns('posts')
1398
- c1.each_with_index do |v, i|
1399
- assert_not_same v, c2[i]
1400
- end
1401
- assert_equal c1, c2
1402
- end
1403
-
1404
- def test_current_scope_is_reset
1405
- puts "In base_test test_current_scope_is_reset"
1406
- Object.const_set :UnloadablePost, Class.new(ActiveRecord::Base)
1407
- UnloadablePost.send(:current_scope=, UnloadablePost.all)
1408
-
1409
- UnloadablePost.unloadable
1410
- klass = UnloadablePost
1411
- assert_not_nil ActiveRecord::Scoping::ScopeRegistry.value_for(:current_scope, klass)
1412
- ActiveSupport::Dependencies.remove_unloadable_constants!
1413
- assert_nil ActiveRecord::Scoping::ScopeRegistry.value_for(:current_scope, klass)
1414
- ensure
1415
- Object.class_eval{ remove_const :UnloadablePost } if defined?(UnloadablePost)
1416
- end
1417
-
1418
- def test_marshal_round_trip
1419
- puts "In base_test test_marshal_round_trip"
1420
- expected = posts(:welcome)
1421
- marshalled = Marshal.dump(expected)
1422
- actual = Marshal.load(marshalled)
1423
-
1424
- assert_equal expected.attributes, actual.attributes
1425
- end
1426
-
1427
- def test_marshal_new_record_round_trip
1428
- puts "In base_test test_marshal_new_record_round_trip"
1429
- marshalled = Marshal.dump(Post.new)
1430
- post = Marshal.load(marshalled)
1431
-
1432
- assert post.new_record?, "should be a new record"
1433
- end
1434
-
1435
- def test_marshalling_with_associations
1436
- puts "In base_test test_marshalling_with_associations"
1437
- post = Post.new
1438
- post.comments.build
1439
-
1440
- marshalled = Marshal.dump(post)
1441
- post = Marshal.load(marshalled)
1442
-
1443
- assert_equal 1, post.comments.length
1444
- end
1445
-
1446
- if Process.respond_to?(:fork) && !in_memory_db?
1447
- def test_marshal_between_processes
1448
- puts "In base_test test_marshal_between_processes"
1449
- # Define a new model to ensure there are no caches
1450
- if self.class.const_defined?("Post", false)
1451
- flunk "there should be no post constant"
1452
- end
1453
-
1454
- self.class.const_set("Post", Class.new(ActiveRecord::Base) {
1455
- has_many :comments
1456
- })
1457
-
1458
- rd, wr = IO.pipe
1459
- rd.binmode
1460
- wr.binmode
1461
-
1462
- ActiveRecord::Base.connection_handler.clear_all_connections!
1463
-
1464
- fork do
1465
- rd.close
1466
- post = Post.new
1467
- post.comments.build
1468
- wr.write Marshal.dump(post)
1469
- wr.close
1470
- end
1471
-
1472
- wr.close
1473
- assert Marshal.load rd.read
1474
- rd.close
1475
- end
1476
- end
1477
-
1478
- def test_marshalling_new_record_round_trip_with_associations
1479
- puts "In base_test test_marshalling_new_record_round_trip_with_associations"
1480
- post = Post.new
1481
- post.comments.build
1482
-
1483
- post = Marshal.load(Marshal.dump(post))
1484
-
1485
- assert post.new_record?, "should be a new record"
1486
- end
1487
-
1488
- def test_attribute_names
1489
- puts "In base_test test_attribute_names"
1490
- assert_equal ["id", "type", "firm_id", "firm_name", "name", "client_of", "rating", "account_id", "description"],
1491
- Company.attribute_names
1492
- end
1493
-
1494
- def test_has_attribute
1495
- puts "In base_test test_has_attribute"
1496
- assert Company.has_attribute?('id')
1497
- assert Company.has_attribute?('type')
1498
- assert Company.has_attribute?('name')
1499
- assert_not Company.has_attribute?('lastname')
1500
- assert_not Company.has_attribute?('age')
1501
- end
1502
-
1503
- def test_has_attribute_with_symbol
1504
- puts "In base_test test_has_attribute_with_symbol"
1505
- assert Company.has_attribute?(:id)
1506
- assert_not Company.has_attribute?(:age)
1507
- end
1508
-
1509
- def test_attribute_names_on_table_not_exists
1510
- puts "In base_test test_attribute_names_on_table_not_exists"
1511
- assert_equal [], NonExistentTable.attribute_names
1512
- end
1513
-
1514
- def test_attribute_names_on_abstract_class
1515
- puts "In base_test test_attribute_names_on_abstract_class"
1516
- assert_equal [], AbstractCompany.attribute_names
1517
- end
1518
-
1519
- def test_touch_should_raise_error_on_a_new_object
1520
- puts "In base_test test_touch_should_raise_error_on_a_new_object"
1521
- company = Company.new(:rating => 1, :name => "37signals", :firm_name => "37signals")
1522
- assert_raises(ActiveRecord::ActiveRecordError) do
1523
- company.touch :updated_at
1524
- end
1525
- end
1526
-
1527
- def test_uniq_delegates_to_scoped
1528
- puts "In base_test test_uniq_delegates_to_scoped"
1529
- assert_deprecated do
1530
- assert_equal Bird.all.distinct, Bird.uniq
1531
- end
1532
- end
1533
-
1534
- def test_distinct_delegates_to_scoped
1535
- puts "In base_test test_distinct_delegates_to_scoped"
1536
- assert_equal Bird.all.distinct, Bird.distinct
1537
- end
1538
-
1539
- def test_table_name_with_2_abstract_subclasses
1540
- puts "In base_test test_table_name_with_2_abstract_subclasses"
1541
- assert_equal "photos", Photo.table_name
1542
- end
1543
-
1544
- def test_column_types_typecast
1545
- puts "In base_test test_column_types_typecast"
1546
- topic = Topic.first
1547
- assert_not_equal 't.lo', topic.author_name
1548
-
1549
- attrs = topic.attributes.dup
1550
- attrs.delete 'id'
1551
-
1552
- typecast = Class.new(ActiveRecord::Type::Value) {
1553
- def cast value
1554
- "t.lo"
1555
- end
1556
- }
1557
-
1558
- types = { 'author_name' => typecast.new }
1559
- topic = Topic.instantiate(attrs, types)
1560
-
1561
- assert_equal 't.lo', topic.author_name
1562
- end
1563
-
1564
- def test_typecasting_aliases
1565
- puts "In base_test test_typecasting_aliases"
1566
- assert_equal 10, Topic.select('10 as tenderlove').first.tenderlove
1567
- end
1568
-
1569
- def test_slice
1570
- puts "In base_test test_slice"
1571
- company = Company.new(:rating => 1, :name => "37signals", :firm_name => "37signals")
1572
- hash = company.slice(:name, :rating, "arbitrary_method")
1573
- assert_equal hash[:name], company.name
1574
- assert_equal hash['name'], company.name
1575
- assert_equal hash[:rating], company.rating
1576
- assert_equal hash['arbitrary_method'], company.arbitrary_method
1577
- assert_equal hash[:arbitrary_method], company.arbitrary_method
1578
- assert_nil hash[:firm_name]
1579
- assert_nil hash['firm_name']
1580
- end
1581
-
1582
- def test_default_values_are_deeply_dupped
1583
- puts "In base_test test_default_values_are_deeply_dupped"
1584
- company = Company.new
1585
- company.description << "foo"
1586
- assert_equal "", Company.new.description
1587
- end
1588
-
1589
- test "scoped can take a values hash" do
1590
- puts "In base_test scoped can take a values hash"
1591
- klass = Class.new(ActiveRecord::Base)
1592
- assert_equal ['foo'], klass.all.merge!(select: 'foo').select_values
1593
- end
1594
-
1595
- test "connection_handler can be overridden" do
1596
- puts "In base_test connection_handler can be overridden"
1597
- klass = Class.new(ActiveRecord::Base)
1598
- orig_handler = klass.connection_handler
1599
- new_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
1600
- thread_connection_handler = nil
1601
-
1602
- t = Thread.new do
1603
- klass.connection_handler = new_handler
1604
- thread_connection_handler = klass.connection_handler
1605
- end
1606
- t.join
1607
-
1608
- assert_equal klass.connection_handler, orig_handler
1609
- assert_equal thread_connection_handler, new_handler
1610
- end
1611
-
1612
- test "new threads get default the default connection handler" do
1613
- puts "In base_test new threads get default the default connection handler"
1614
- klass = Class.new(ActiveRecord::Base)
1615
- orig_handler = klass.connection_handler
1616
- handler = nil
1617
-
1618
- t = Thread.new do
1619
- handler = klass.connection_handler
1620
- end
1621
- t.join
1622
-
1623
- assert_equal handler, orig_handler
1624
- assert_equal klass.connection_handler, orig_handler
1625
- assert_equal klass.default_connection_handler, orig_handler
1626
- end
1627
-
1628
- test "changing a connection handler in a main thread does not poison the other threads" do
1629
- puts "In base_test changing a connection handler in a main thread does not poison the other threads"
1630
- klass = Class.new(ActiveRecord::Base)
1631
- orig_handler = klass.connection_handler
1632
- new_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
1633
- after_handler = nil
1634
- latch1 = Concurrent::CountDownLatch.new
1635
- latch2 = Concurrent::CountDownLatch.new
1636
-
1637
- t = Thread.new do
1638
- klass.connection_handler = new_handler
1639
- latch1.count_down
1640
- latch2.wait
1641
- after_handler = klass.connection_handler
1642
- end
1643
-
1644
- latch1.wait
1645
-
1646
- klass.connection_handler = orig_handler
1647
- latch2.count_down
1648
- t.join
1649
-
1650
- assert_equal after_handler, new_handler
1651
- assert_equal orig_handler, klass.connection_handler
1652
- end
1653
-
1654
- # Note: This is a performance optimization for Array#uniq and Hash#[] with
1655
- # AR::Base objects. If the future has made this irrelevant, feel free to
1656
- # delete this.
1657
- test "records without an id have unique hashes" do
1658
- puts "In base_test records without an id have unique hashes"
1659
- assert_not_equal Post.new.hash, Post.new.hash
1660
- end
1661
-
1662
- test "resetting column information doesn't remove attribute methods" do
1663
- puts "In base_test changing a connection handler in a main thread does not poison the other threads"
1664
- topic = topics(:first)
1665
-
1666
- assert_not topic.id_changed?
1667
-
1668
- Topic.reset_column_information
1669
-
1670
- assert_not topic.id_changed?
1671
- end
1672
-
1673
- test "ignored columns are not present in columns_hash" do
1674
- puts "In base_test ignored columns are not present in columns_hash"
1675
- cache_columns = Developer.connection.schema_cache.columns_hash(Developer.table_name)
1676
- assert_includes cache_columns.keys, "first_name"
1677
- assert_not_includes Developer.columns_hash.keys, "first_name"
1678
- assert_not_includes SubDeveloper.columns_hash.keys, "first_name"
1679
- assert_not_includes SymbolIgnoredDeveloper.columns_hash.keys, "first_name"
1680
- end
1681
-
1682
- test "ignored columns have no attribute methods" do
1683
- puts "In base_test ignored columns have no attribute methods"
1684
- refute Developer.new.respond_to?(:first_name)
1685
- refute Developer.new.respond_to?(:first_name=)
1686
- refute Developer.new.respond_to?(:first_name?)
1687
- refute SubDeveloper.new.respond_to?(:first_name)
1688
- refute SubDeveloper.new.respond_to?(:first_name=)
1689
- refute SubDeveloper.new.respond_to?(:first_name?)
1690
- refute SymbolIgnoredDeveloper.new.respond_to?(:first_name)
1691
- refute SymbolIgnoredDeveloper.new.respond_to?(:first_name=)
1692
- refute SymbolIgnoredDeveloper.new.respond_to?(:first_name?)
1693
- end
1694
-
1695
- test "ignored columns don't prevent explicit declaration of attribute methods" do
1696
- puts "In base_test ignored columns don't prevent explicit declaration of attribute methods"
1697
- assert Developer.new.respond_to?(:last_name)
1698
- assert Developer.new.respond_to?(:last_name=)
1699
- assert Developer.new.respond_to?(:last_name?)
1700
- assert SubDeveloper.new.respond_to?(:last_name)
1701
- assert SubDeveloper.new.respond_to?(:last_name=)
1702
- assert SubDeveloper.new.respond_to?(:last_name?)
1703
- assert SymbolIgnoredDeveloper.new.respond_to?(:last_name)
1704
- assert SymbolIgnoredDeveloper.new.respond_to?(:last_name=)
1705
- assert SymbolIgnoredDeveloper.new.respond_to?(:last_name?)
1706
- end
1707
-
1708
- test "ignored columns are stored as an array of string" do
1709
- puts "In base_test ignored columns are stored as an array of string"
1710
- assert_equal(%w(first_name last_name), Developer.ignored_columns)
1711
- assert_equal(%w(first_name last_name), SymbolIgnoredDeveloper.ignored_columns)
1712
- end
1713
- end
1
+ require "cases/helper"
2
+ require 'models/post'
3
+ require 'models/author'
4
+ require 'models/topic'
5
+ require 'models/reply'
6
+ require 'models/category'
7
+ require 'models/company'
8
+ require 'models/customer'
9
+ require 'models/developer'
10
+ require 'models/computer'
11
+ require 'models/project'
12
+ require 'models/default'
13
+ require 'models/auto_id'
14
+ require 'models/boolean'
15
+ require 'models/column_name'
16
+ require 'models/subscriber'
17
+ require 'models/keyboard'
18
+ require 'models/comment'
19
+ require 'models/minimalistic'
20
+ require 'models/warehouse_thing'
21
+ require 'models/parrot'
22
+ require 'models/person'
23
+ require 'models/edge'
24
+ require 'models/joke'
25
+ require 'models/bird'
26
+ require 'models/car'
27
+ require 'models/bulb'
28
+ require 'rexml/document'
29
+ require 'concurrent/atomic/count_down_latch'
30
+
31
+ class FirstAbstractClass < ActiveRecord::Base
32
+ self.abstract_class = true
33
+ end
34
+ class SecondAbstractClass < FirstAbstractClass
35
+ self.abstract_class = true
36
+ end
37
+ class Photo < SecondAbstractClass; end
38
+ class Category < ActiveRecord::Base; end
39
+ class Categorization < ActiveRecord::Base; end
40
+ class Smarts < ActiveRecord::Base; end
41
+ class CreditCard < ActiveRecord::Base
42
+ class PinNumber < ActiveRecord::Base
43
+ class CvvCode < ActiveRecord::Base; end
44
+ class SubCvvCode < CvvCode; end
45
+ end
46
+ class SubPinNumber < PinNumber; end
47
+ class Brand < Category; end
48
+ end
49
+ class MasterCreditCard < ActiveRecord::Base; end
50
+ class Post < ActiveRecord::Base; end
51
+ class Computer < ActiveRecord::Base; end
52
+ class NonExistentTable < ActiveRecord::Base; end
53
+ class TestOracleDefault < ActiveRecord::Base; end
54
+
55
+ class ReadonlyTitlePost < Post
56
+ attr_readonly :title
57
+ end
58
+
59
+ class Weird < ActiveRecord::Base; end
60
+
61
+ class Boolean < ActiveRecord::Base
62
+ def has_fun
63
+ super
64
+ end
65
+ end
66
+
67
+ class LintTest < ActiveRecord::TestCase
68
+ include ActiveModel::Lint::Tests
69
+
70
+ class LintModel < ActiveRecord::Base; end
71
+
72
+ def setup
73
+ @model = LintModel.new
74
+ end
75
+ end
76
+
77
+ class BasicsTest < ActiveRecord::TestCase
78
+ #fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse_things', :authors, :categorizations, :categories, :posts
79
+ fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse_things', :categorizations, :categories, :posts
80
+
81
+ def test_column_names_are_escaped
82
+ puts "In base_test test_column_names_are_escaped"
83
+ conn = ActiveRecord::Base.connection
84
+ classname = conn.class.name[/[^:]*$/]
85
+ badchar = {
86
+ 'SQLite3Adapter' => '"',
87
+ 'Mysql2Adapter' => '`',
88
+ 'PostgreSQLAdapter' => '"',
89
+ 'OracleAdapter' => '"',
90
+ 'IBM_DBAdapter' => '"',
91
+ 'FbAdapter' => '"'
92
+ }.fetch(classname) {
93
+ raise "need a bad char for #{classname}"
94
+ }
95
+
96
+ quoted = conn.quote_column_name "foo#{badchar}bar"
97
+ if current_adapter?(:OracleAdapter)
98
+ # Oracle does not allow double quotes in table and column names at all
99
+ # therefore quoting removes them
100
+ assert_equal("#{badchar}foobar#{badchar}", quoted)
101
+ elsif current_adapter?(:IBM_DBAdapter)
102
+ assert_equal("foo#{badchar}bar", quoted)
103
+ else
104
+ assert_equal("#{badchar}foo#{badchar * 2}bar#{badchar}", quoted)
105
+ end
106
+ end
107
+
108
+ def test_columns_should_obey_set_primary_key
109
+ puts "In base_test test_columns_should_obey_set_primary_key"
110
+ pk = Subscriber.columns_hash[Subscriber.primary_key]
111
+ assert_equal 'nick', pk.name, 'nick should be primary key'
112
+ end
113
+
114
+ def test_primary_key_with_no_id
115
+ puts "In base_test test_primary_key_with_no_id"
116
+ assert_nil Edge.primary_key
117
+ end
118
+
119
+ unless current_adapter?(:PostgreSQLAdapter, :OracleAdapter, :SQLServerAdapter, :IBM_DBAdapter, :FbAdapter)
120
+ def test_limit_with_comma
121
+ puts "In base_test test_limit_with_comma"
122
+ assert_deprecated do
123
+ assert Topic.limit("1,2").to_a
124
+ end
125
+ end
126
+ end
127
+
128
+ def test_many_mutations
129
+ puts "In base_test test_many_mutations"
130
+ car = Car.new name: "<3<3<3"
131
+ car.engines_count = 0
132
+ 20_000.times { car.engines_count += 1 }
133
+ assert car.save
134
+ end
135
+
136
+ def test_limit_without_comma
137
+ puts "In base_test test_limit_without_comma"
138
+ assert_equal 1, Topic.limit("1").to_a.length
139
+ assert_equal 1, Topic.limit(1).to_a.length
140
+ end
141
+
142
+ def test_limit_should_take_value_from_latest_limit
143
+ puts "In base_test test_limit_should_take_value_from_latest_limit"
144
+ assert_equal 1, Topic.limit(2).limit(1).to_a.length
145
+ end
146
+
147
+ def test_invalid_limit
148
+ puts "In base_test test_invalid_limit"
149
+ assert_raises(ArgumentError) do
150
+ Topic.limit("asdfadf").to_a
151
+ end
152
+ end
153
+
154
+ def test_limit_should_sanitize_sql_injection_for_limit_without_commas
155
+ puts "In base_test test_limit_should_sanitize_sql_injection_for_limit_without_commas"
156
+ assert_raises(ArgumentError) do
157
+ Topic.limit("1 select * from schema").to_a
158
+ end
159
+ end
160
+
161
+ def test_limit_should_sanitize_sql_injection_for_limit_with_commas
162
+ puts "In base_test test_limit_should_sanitize_sql_injection_for_limit_with_commas"
163
+ assert_deprecated do
164
+ assert_raises(ArgumentError) do
165
+ Topic.limit("1, 7 procedure help()").to_a
166
+ end
167
+ end
168
+ end
169
+
170
+ def test_select_symbol
171
+ puts "In base_test test_select_symbol"
172
+ topic_ids = Topic.select(:id).map(&:id).sort
173
+ assert_equal Topic.pluck(:id).sort, topic_ids
174
+ end
175
+
176
+ def test_table_exists
177
+ puts "In base_test test_table_exists"
178
+ assert !NonExistentTable.table_exists?
179
+ assert Topic.table_exists?
180
+ end
181
+
182
+ def test_preserving_date_objects
183
+ puts "In base_test test_preserving_date_objects"
184
+ # Oracle enhanced adapter allows to define Date attributes in model class (see topic.rb)
185
+ assert_kind_of(
186
+ Date, Topic.find(1).last_read,
187
+ "The last_read attribute should be of the Date class"
188
+ )
189
+ end
190
+
191
+ def test_previously_changed
192
+ puts "In base_test test_previously_changed"
193
+ topic = Topic.first
194
+ topic.title = '<3<3<3'
195
+ assert_equal({}, topic.previous_changes)
196
+
197
+ topic.save!
198
+ expected = ["The First Topic", "<3<3<3"]
199
+ assert_equal(expected, topic.previous_changes['title'])
200
+ end
201
+
202
+ def test_previously_changed_dup
203
+ puts "In base_test test_previously_changed_dup"
204
+ topic = Topic.first
205
+ topic.title = '<3<3<3'
206
+ topic.save!
207
+
208
+ t2 = topic.dup
209
+
210
+ assert_equal(topic.previous_changes, t2.previous_changes)
211
+
212
+ topic.title = "lolwut"
213
+ topic.save!
214
+
215
+ assert_not_equal(topic.previous_changes, t2.previous_changes)
216
+ end
217
+
218
+ def test_preserving_time_objects
219
+ puts "In base_test test_preserving_time_objects"
220
+ assert_kind_of(
221
+ Time, Topic.find(1).bonus_time,
222
+ "The bonus_time attribute should be of the Time class"
223
+ )
224
+
225
+ assert_kind_of(
226
+ Time, Topic.find(1).written_on,
227
+ "The written_on attribute should be of the Time class"
228
+ )
229
+
230
+ # For adapters which support microsecond resolution.
231
+ if subsecond_precision_supported?
232
+ assert_equal 11, Topic.find(1).written_on.sec
233
+ assert_equal 223300, Topic.find(1).written_on.usec
234
+ assert_equal 9900, Topic.find(2).written_on.usec
235
+ assert_equal 129346, Topic.find(3).written_on.usec
236
+ end
237
+ end
238
+
239
+ def test_preserving_time_objects_with_local_time_conversion_to_default_timezone_utc
240
+ puts "In base_test test_preserving_time_objects_with_local_time_conversion_to_default_timezone_utc"
241
+ with_env_tz eastern_time_zone do
242
+ with_timezone_config default: :utc do
243
+ time = Time.local(2000)
244
+ topic = Topic.create('written_on' => time)
245
+ saved_time = Topic.find(topic.id).reload.written_on
246
+ assert_equal time, saved_time
247
+ assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "EST"], time.to_a
248
+ assert_equal [0, 0, 5, 1, 1, 2000, 6, 1, false, "UTC"], saved_time.to_a
249
+ end
250
+ end
251
+ end
252
+
253
+ def test_preserving_time_objects_with_time_with_zone_conversion_to_default_timezone_utc
254
+ puts "In base_test test_preserving_time_objects_with_time_with_zone_conversion_to_default_timezone_utc"
255
+ with_env_tz eastern_time_zone do
256
+ with_timezone_config default: :utc do
257
+ Time.use_zone 'Central Time (US & Canada)' do
258
+ time = Time.zone.local(2000)
259
+ topic = Topic.create('written_on' => time)
260
+ saved_time = Topic.find(topic.id).reload.written_on
261
+ assert_equal time, saved_time
262
+ assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "CST"], time.to_a
263
+ assert_equal [0, 0, 6, 1, 1, 2000, 6, 1, false, "UTC"], saved_time.to_a
264
+ end
265
+ end
266
+ end
267
+ end
268
+
269
+ def test_preserving_time_objects_with_utc_time_conversion_to_default_timezone_local
270
+ puts "In base_test test_preserving_time_objects_with_utc_time_conversion_to_default_timezone_local"
271
+ with_env_tz eastern_time_zone do
272
+ with_timezone_config default: :local do
273
+ time = Time.utc(2000)
274
+ topic = Topic.create('written_on' => time)
275
+ saved_time = Topic.find(topic.id).reload.written_on
276
+ assert_equal time, saved_time
277
+ assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"], time.to_a
278
+ assert_equal [0, 0, 19, 31, 12, 1999, 5, 365, false, "EST"], saved_time.to_a
279
+ end
280
+ end
281
+ end
282
+
283
+ def test_preserving_time_objects_with_time_with_zone_conversion_to_default_timezone_local
284
+ puts "In base_test test_preserving_time_objects_with_time_with_zone_conversion_to_default_timezone_local"
285
+ with_env_tz eastern_time_zone do
286
+ with_timezone_config default: :local do
287
+ Time.use_zone 'Central Time (US & Canada)' do
288
+ time = Time.zone.local(2000)
289
+ topic = Topic.create('written_on' => time)
290
+ saved_time = Topic.find(topic.id).reload.written_on
291
+ assert_equal time, saved_time
292
+ assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "CST"], time.to_a
293
+ assert_equal [0, 0, 1, 1, 1, 2000, 6, 1, false, "EST"], saved_time.to_a
294
+ end
295
+ end
296
+ end
297
+ end
298
+
299
+ def eastern_time_zone
300
+ if Gem.win_platform?
301
+ "EST5EDT"
302
+ else
303
+ "America/New_York"
304
+ end
305
+ end
306
+
307
+ def test_custom_mutator
308
+ puts "In base_test test_custom_mutator"
309
+ topic = Topic.find(1)
310
+ # This mutator is protected in the class definition
311
+ topic.send(:approved=, true)
312
+ assert topic.instance_variable_get("@custom_approved")
313
+ end
314
+
315
+ def test_initialize_with_attributes
316
+ puts "In base_test test_initialize_with_attributes"
317
+ topic = Topic.new({
318
+ "title" => "initialized from attributes", "written_on" => "2003-12-12 23:23"
319
+ })
320
+
321
+ assert_equal("initialized from attributes", topic.title)
322
+ end
323
+
324
+ def test_initialize_with_invalid_attribute
325
+ puts "In base_test test_initialize_with_invalid_attribute"
326
+ Topic.new({ "title" => "test",
327
+ "last_read(1i)" => "2005", "last_read(2i)" => "2", "last_read(3i)" => "31"})
328
+ rescue ActiveRecord::MultiparameterAssignmentErrors => ex
329
+ assert_equal(1, ex.errors.size)
330
+ assert_equal("last_read", ex.errors[0].attribute)
331
+ end
332
+
333
+ def test_create_after_initialize_without_block
334
+ puts "In base_test test_create_after_initialize_without_block"
335
+ cb = CustomBulb.create(:name => 'Dude')
336
+ assert_equal('Dude', cb.name)
337
+ assert_equal(true, cb.frickinawesome)
338
+ end
339
+
340
+ def test_create_after_initialize_with_block
341
+ puts "In base_test test_create_after_initialize_with_block"
342
+ cb = CustomBulb.create {|c| c.name = 'Dude' }
343
+ assert_equal('Dude', cb.name)
344
+ assert_equal(true, cb.frickinawesome)
345
+ end
346
+
347
+ def test_create_after_initialize_with_array_param
348
+ puts "In base_test test_create_after_initialize_with_array_param"
349
+ cbs = CustomBulb.create([{ name: 'Dude' }, { name: 'Bob' }])
350
+ assert_equal 'Dude', cbs[0].name
351
+ assert_equal 'Bob', cbs[1].name
352
+ assert cbs[0].frickinawesome
353
+ assert !cbs[1].frickinawesome
354
+ end
355
+
356
+ def test_load
357
+ puts "In base_test test_load"
358
+ topics = Topic.all.merge!(:order => 'id').to_a
359
+ assert_equal(5, topics.size)
360
+ assert_equal(topics(:first).title, topics.first.title)
361
+ end
362
+
363
+ def test_load_with_condition
364
+ puts "In base_test test_load_with_condition"
365
+ topics = Topic.all.merge!(:where => "author_name = 'Mary'").to_a
366
+
367
+ assert_equal(1, topics.size)
368
+ assert_equal(topics(:second).title, topics.first.title)
369
+ end
370
+
371
+ GUESSED_CLASSES = [Category, Smarts, CreditCard, CreditCard::PinNumber, CreditCard::PinNumber::CvvCode, CreditCard::SubPinNumber, CreditCard::Brand, MasterCreditCard]
372
+
373
+ def test_table_name_guesses
374
+ puts "In base_test test_table_name_guesses"
375
+ assert_equal "topics", Topic.table_name
376
+
377
+ assert_equal "categories", Category.table_name
378
+ assert_equal "smarts", Smarts.table_name
379
+ assert_equal "credit_cards", CreditCard.table_name
380
+ assert_equal "credit_card_pin_numbers", CreditCard::PinNumber.table_name
381
+ assert_equal "credit_card_pin_number_cvv_codes", CreditCard::PinNumber::CvvCode.table_name
382
+ assert_equal "credit_card_pin_numbers", CreditCard::SubPinNumber.table_name
383
+ assert_equal "categories", CreditCard::Brand.table_name
384
+ assert_equal "master_credit_cards", MasterCreditCard.table_name
385
+ ensure
386
+ GUESSED_CLASSES.each(&:reset_table_name)
387
+ end
388
+
389
+ def test_singular_table_name_guesses
390
+ puts "In base_test test_singular_table_name_guesses"
391
+ ActiveRecord::Base.pluralize_table_names = false
392
+ GUESSED_CLASSES.each(&:reset_table_name)
393
+
394
+ assert_equal "category", Category.table_name
395
+ assert_equal "smarts", Smarts.table_name
396
+ assert_equal "credit_card", CreditCard.table_name
397
+ assert_equal "credit_card_pin_number", CreditCard::PinNumber.table_name
398
+ assert_equal "credit_card_pin_number_cvv_code", CreditCard::PinNumber::CvvCode.table_name
399
+ assert_equal "credit_card_pin_number", CreditCard::SubPinNumber.table_name
400
+ assert_equal "category", CreditCard::Brand.table_name
401
+ assert_equal "master_credit_card", MasterCreditCard.table_name
402
+ ensure
403
+ ActiveRecord::Base.pluralize_table_names = true
404
+ GUESSED_CLASSES.each(&:reset_table_name)
405
+ end
406
+
407
+ def test_table_name_guesses_with_prefixes_and_suffixes
408
+ puts "In base_test test_table_name_guesses_with_prefixes_and_suffixes"
409
+ ActiveRecord::Base.table_name_prefix = "test_"
410
+ Category.reset_table_name
411
+ assert_equal "test_categories", Category.table_name
412
+ ActiveRecord::Base.table_name_suffix = "_test"
413
+ Category.reset_table_name
414
+ assert_equal "test_categories_test", Category.table_name
415
+ ActiveRecord::Base.table_name_prefix = ""
416
+ Category.reset_table_name
417
+ assert_equal "categories_test", Category.table_name
418
+ ActiveRecord::Base.table_name_suffix = ""
419
+ Category.reset_table_name
420
+ assert_equal "categories", Category.table_name
421
+ ensure
422
+ ActiveRecord::Base.table_name_prefix = ""
423
+ ActiveRecord::Base.table_name_suffix = ""
424
+ GUESSED_CLASSES.each(&:reset_table_name)
425
+ end
426
+
427
+ def test_singular_table_name_guesses_with_prefixes_and_suffixes
428
+ puts "In base_test test_singular_table_name_guesses_with_prefixes_and_suffixes"
429
+ ActiveRecord::Base.pluralize_table_names = false
430
+
431
+ ActiveRecord::Base.table_name_prefix = "test_"
432
+ Category.reset_table_name
433
+ assert_equal "test_category", Category.table_name
434
+ ActiveRecord::Base.table_name_suffix = "_test"
435
+ Category.reset_table_name
436
+ assert_equal "test_category_test", Category.table_name
437
+ ActiveRecord::Base.table_name_prefix = ""
438
+ Category.reset_table_name
439
+ assert_equal "category_test", Category.table_name
440
+ ActiveRecord::Base.table_name_suffix = ""
441
+ Category.reset_table_name
442
+ assert_equal "category", Category.table_name
443
+ ensure
444
+ ActiveRecord::Base.pluralize_table_names = true
445
+ ActiveRecord::Base.table_name_prefix = ""
446
+ ActiveRecord::Base.table_name_suffix = ""
447
+ GUESSED_CLASSES.each(&:reset_table_name)
448
+ end
449
+
450
+ def test_table_name_guesses_with_inherited_prefixes_and_suffixes
451
+ puts "In base_test test_table_name_guesses_with_inherited_prefixes_and_suffixes"
452
+ GUESSED_CLASSES.each(&:reset_table_name)
453
+
454
+ CreditCard.table_name_prefix = "test_"
455
+ CreditCard.reset_table_name
456
+ Category.reset_table_name
457
+ assert_equal "test_credit_cards", CreditCard.table_name
458
+ assert_equal "categories", Category.table_name
459
+ CreditCard.table_name_suffix = "_test"
460
+ CreditCard.reset_table_name
461
+ Category.reset_table_name
462
+ assert_equal "test_credit_cards_test", CreditCard.table_name
463
+ assert_equal "categories", Category.table_name
464
+ CreditCard.table_name_prefix = ""
465
+ CreditCard.reset_table_name
466
+ Category.reset_table_name
467
+ assert_equal "credit_cards_test", CreditCard.table_name
468
+ assert_equal "categories", Category.table_name
469
+ CreditCard.table_name_suffix = ""
470
+ CreditCard.reset_table_name
471
+ Category.reset_table_name
472
+ assert_equal "credit_cards", CreditCard.table_name
473
+ assert_equal "categories", Category.table_name
474
+ ensure
475
+ CreditCard.table_name_prefix = ""
476
+ CreditCard.table_name_suffix = ""
477
+ GUESSED_CLASSES.each(&:reset_table_name)
478
+ end
479
+
480
+ def test_singular_table_name_guesses_for_individual_table
481
+ puts "In base_test test_singular_table_name_guesses_for_individual_table"
482
+ Post.pluralize_table_names = false
483
+ Post.reset_table_name
484
+ assert_equal "post", Post.table_name
485
+ assert_equal "categories", Category.table_name
486
+ ensure
487
+ Post.pluralize_table_names = true
488
+ Post.reset_table_name
489
+ end
490
+
491
+ if current_adapter?(:Mysql2Adapter)
492
+ puts "In base_test test_update_all_with_order_and_limit"
493
+ def test_update_all_with_order_and_limit
494
+ assert_equal 1, Topic.limit(1).order('id DESC').update_all(:content => 'bulk updated!')
495
+ end
496
+ end
497
+
498
+ def test_null_fields
499
+ puts "In base_test test_null_fields"
500
+ assert_nil Topic.find(1).parent_id
501
+ assert_nil Topic.create("title" => "Hey you").parent_id
502
+ end
503
+
504
+ def test_default_values
505
+ puts "In base_test test_default_values"
506
+ topic = Topic.new
507
+ assert topic.approved?
508
+ assert_nil topic.written_on
509
+ assert_nil topic.bonus_time
510
+ assert_nil topic.last_read
511
+
512
+ topic.save
513
+
514
+ topic = Topic.find(topic.id)
515
+ assert topic.approved?
516
+ assert_nil topic.last_read
517
+
518
+ # Oracle has some funky default handling, so it requires a bit of
519
+ # extra testing. See ticket #2788.
520
+ if current_adapter?(:OracleAdapter)
521
+ test = TestOracleDefault.new
522
+ assert_equal "X", test.test_char
523
+ assert_equal "hello", test.test_string
524
+ assert_equal 3, test.test_int
525
+ end
526
+ end
527
+
528
+ # Oracle does not have a TIME datatype.
529
+ unless current_adapter?(:OracleAdapter,:IBM_DBAdapter)
530
+ def test_utc_as_time_zone
531
+ puts "In base_test test_utc_as_time_zone"
532
+ with_timezone_config default: :utc do
533
+ attributes = { "bonus_time" => "5:42:00AM" }
534
+ topic = Topic.find(1)
535
+ topic.attributes = attributes
536
+ assert_equal Time.utc(2000, 1, 1, 5, 42, 0), topic.bonus_time
537
+ end
538
+ end
539
+ end
540
+
541
+ def test_utc_as_time_zone_and_new
542
+ puts "In base_test test_utc_as_time_zone_and_new"
543
+ with_timezone_config default: :utc do
544
+ attributes = { "bonus_time(1i)"=>"2000",
545
+ "bonus_time(2i)"=>"1",
546
+ "bonus_time(3i)"=>"1",
547
+ "bonus_time(4i)"=>"10",
548
+ "bonus_time(5i)"=>"35",
549
+ "bonus_time(6i)"=>"50" }
550
+ topic = Topic.new(attributes)
551
+ assert_equal Time.utc(2000, 1, 1, 10, 35, 50), topic.bonus_time
552
+ end
553
+ end
554
+ end
555
+
556
+ def test_default_values_on_empty_strings
557
+ puts "In base_test test_default_values_on_empty_strings"
558
+ topic = Topic.new
559
+ topic.approved = nil
560
+ topic.last_read = nil
561
+
562
+ topic.save
563
+
564
+ topic = Topic.find(topic.id)
565
+ assert_nil topic.last_read
566
+
567
+ assert_nil topic.approved
568
+ end
569
+
570
+ def test_equality
571
+ puts "In base_test test_equality"
572
+ assert_equal Topic.find(1), Topic.find(2).topic
573
+ end
574
+
575
+ def test_find_by_slug
576
+ puts "In base_test test_find_by_slug"
577
+ assert_equal Topic.find('1-meowmeow'), Topic.find(1)
578
+ end
579
+
580
+ def test_find_by_slug_with_array
581
+ puts "In base_test test_find_by_slug_with_array"
582
+ assert_equal Topic.find([1, 2]), Topic.find(['1-meowmeow', '2-hello'])
583
+ assert_equal 'The Second Topic of the day', Topic.find(['2-hello', '1-meowmeow']).first.title
584
+ end
585
+
586
+ def test_find_by_slug_with_range
587
+ puts "In base_test test_find_by_slug_with_range"
588
+ assert_equal Topic.where(id: '1-meowmeow'..'2-hello'), Topic.where(id: 1..2)
589
+ end
590
+
591
+ def test_equality_of_new_records
592
+ puts "In base_test test_equality_of_new_records"
593
+ assert_not_equal Topic.new, Topic.new
594
+ assert_equal false, Topic.new == Topic.new
595
+ end
596
+
597
+ def test_equality_of_destroyed_records
598
+ puts "In base_test test_equality_of_destroyed_records"
599
+ topic_1 = Topic.new(:title => 'test_1')
600
+ topic_1.save
601
+ topic_2 = Topic.find(topic_1.id)
602
+ topic_1.destroy
603
+ assert_equal topic_1, topic_2
604
+ assert_equal topic_2, topic_1
605
+ end
606
+
607
+ def test_equality_with_blank_ids
608
+ puts "In base_test test_equality_with_blank_ids"
609
+ one = Subscriber.new(:id => '')
610
+ two = Subscriber.new(:id => '')
611
+ assert_equal one, two
612
+ end
613
+
614
+ def test_equality_of_relation_and_collection_proxy
615
+ puts "In base_test test_equality_of_relation_and_collection_proxy"
616
+ car = Car.create!
617
+ car.bulbs.build
618
+ car.save
619
+
620
+ assert car.bulbs == Bulb.where(car_id: car.id), 'CollectionProxy should be comparable with Relation'
621
+ assert Bulb.where(car_id: car.id) == car.bulbs, 'Relation should be comparable with CollectionProxy'
622
+ end
623
+
624
+ def test_equality_of_relation_and_array
625
+ puts "In base_test test_equality_of_relation_and_array"
626
+ car = Car.create!
627
+ car.bulbs.build
628
+ car.save
629
+
630
+ assert Bulb.where(car_id: car.id) == car.bulbs.to_a, 'Relation should be comparable with Array'
631
+ end
632
+
633
+ def test_equality_of_relation_and_association_relation
634
+ puts "In base_test test_equality_of_relation_and_association_relation"
635
+ car = Car.create!
636
+ car.bulbs.build
637
+ car.save
638
+
639
+ assert_equal Bulb.where(car_id: car.id), car.bulbs.includes(:car), 'Relation should be comparable with AssociationRelation'
640
+ assert_equal car.bulbs.includes(:car), Bulb.where(car_id: car.id), 'AssociationRelation should be comparable with Relation'
641
+ end
642
+
643
+ def test_equality_of_collection_proxy_and_association_relation
644
+ puts "In base_test test_equality_of_collection_proxy_and_association_relation"
645
+ car = Car.create!
646
+ car.bulbs.build
647
+ car.save
648
+
649
+ assert_equal car.bulbs, car.bulbs.includes(:car), 'CollectionProxy should be comparable with AssociationRelation'
650
+ assert_equal car.bulbs.includes(:car), car.bulbs, 'AssociationRelation should be comparable with CollectionProxy'
651
+ end
652
+
653
+ def test_hashing
654
+ puts "In base_test test_hashing"
655
+ assert_equal [ Topic.find(1) ], [ Topic.find(2).topic ] & [ Topic.find(1) ]
656
+ end
657
+
658
+ def test_successful_comparison_of_like_class_records
659
+ puts "In base_test test_successful_comparison_of_like_class_records"
660
+ topic_1 = Topic.create!
661
+ topic_2 = Topic.create!
662
+
663
+ assert_equal [topic_2, topic_1].sort, [topic_1, topic_2]
664
+ end
665
+
666
+ def test_failed_comparison_of_unlike_class_records
667
+ puts "In base_test test_failed_comparison_of_unlike_class_records"
668
+ assert_raises ArgumentError do
669
+ [ topics(:first), posts(:welcome) ].sort
670
+ end
671
+ end
672
+
673
+ def test_create_without_prepared_statement
674
+ puts "In base_test test_create_without_prepared_statement"
675
+ topic = Topic.connection.unprepared_statement do
676
+ Topic.create(:title => 'foo')
677
+ end
678
+
679
+ assert_equal topic, Topic.find(topic.id)
680
+ end
681
+
682
+ def test_destroy_without_prepared_statement
683
+ puts "In base_test test_destroy_without_prepared_statement"
684
+ topic = Topic.create(title: 'foo')
685
+ Topic.connection.unprepared_statement do
686
+ Topic.find(topic.id).destroy
687
+ end
688
+
689
+ assert_equal nil, Topic.find_by_id(topic.id)
690
+ end
691
+
692
+ def test_comparison_with_different_objects
693
+ puts "In base_test test_comparison_with_different_objects"
694
+ topic = Topic.create
695
+ category = Category.create(:name => "comparison")
696
+ assert_nil topic <=> category
697
+ end
698
+
699
+ def test_comparison_with_different_objects_in_array
700
+ puts "In base_test test_comparison_with_different_objects_in_array"
701
+ topic = Topic.create
702
+ assert_raises(ArgumentError) do
703
+ [1, topic].sort
704
+ end
705
+ end
706
+
707
+ def test_readonly_attributes
708
+ puts "In base_test test_readonly_attributes"
709
+ assert_equal Set.new([ 'title' , 'comments_count' ]), ReadonlyTitlePost.readonly_attributes
710
+
711
+ post = ReadonlyTitlePost.create(:title => "cannot change this", :body => "changeable")
712
+ post.reload
713
+ assert_equal "cannot change this", post.title
714
+
715
+ post.update(title: "try to change", body: "changed")
716
+ post.reload
717
+ assert_equal "cannot change this", post.title
718
+ assert_equal "changed", post.body
719
+ end
720
+
721
+ def test_unicode_column_name
722
+ puts "In base_test test_unicode_column_name"
723
+ Weird.reset_column_information
724
+ weird = Weird.create(:なまえ => 'たこ焼き仮面')
725
+ assert_equal 'たこ焼き仮面', weird.なまえ
726
+ end
727
+
728
+ unless current_adapter?(:PostgreSQLAdapter)
729
+ def test_respect_internal_encoding
730
+ puts "In base_test test_respect_internal_encoding"
731
+ old_default_internal = Encoding.default_internal
732
+ silence_warnings { Encoding.default_internal = "EUC-JP" }
733
+
734
+ Weird.reset_column_information
735
+
736
+ assert_equal ["EUC-JP"], Weird.columns.map {|c| c.name.encoding.name }.uniq
737
+ ensure
738
+ silence_warnings { Encoding.default_internal = old_default_internal }
739
+ Weird.reset_column_information
740
+ end
741
+ end
742
+
743
+ def test_non_valid_identifier_column_name
744
+ puts "In base_test test_non_valid_identifier_column_name"
745
+ weird = Weird.create('a$b' => 'value')
746
+ weird.reload
747
+ assert_equal 'value', weird.send('a$b')
748
+ assert_equal 'value', weird.read_attribute('a$b')
749
+
750
+ weird.update_columns('a$b' => 'value2')
751
+ weird.reload
752
+ assert_equal 'value2', weird.send('a$b')
753
+ assert_equal 'value2', weird.read_attribute('a$b')
754
+ end
755
+
756
+ def test_group_weirds_by_from
757
+ puts "In base_test test_group_weirds_by_from"
758
+ Weird.create('a$b' => 'value', :from => 'aaron')
759
+ count = Weird.group(Weird.arel_table[:from]).count
760
+ assert_equal 1, count['aaron']
761
+ end
762
+
763
+ def test_attributes_on_dummy_time
764
+ puts "In base_test test_attributes_on_dummy_time"
765
+ # Oracle does not have a TIME datatype.
766
+ return true if current_adapter?(:OracleAdapter)
767
+
768
+ with_timezone_config default: :local do
769
+ attributes = {
770
+ "bonus_time" => "5:42:00AM"
771
+ }
772
+ topic = Topic.find(1)
773
+ topic.attributes = attributes
774
+ assert_equal Time.local(2000, 1, 1, 5, 42, 0), topic.bonus_time
775
+ end
776
+ end
777
+
778
+ def test_attributes_on_dummy_time_with_invalid_time
779
+ puts "In base_test test_attributes_on_dummy_time_with_invalid_time"
780
+ # Oracle does not have a TIME datatype.
781
+ return true if current_adapter?(:OracleAdapter)
782
+
783
+ attributes = {
784
+ "bonus_time" => "not a time"
785
+ }
786
+ topic = Topic.find(1)
787
+ topic.attributes = attributes
788
+ assert_nil topic.bonus_time
789
+ end
790
+
791
+ def test_boolean
792
+ puts "In base_test test_boolean"
793
+ b_nil = Boolean.create({ "value" => nil })
794
+ nil_id = b_nil.id
795
+ b_false = Boolean.create({ "value" => false })
796
+ false_id = b_false.id
797
+ b_true = Boolean.create({ "value" => true })
798
+ true_id = b_true.id
799
+
800
+ b_nil = Boolean.find(nil_id)
801
+ assert_nil b_nil.value
802
+ b_false = Boolean.find(false_id)
803
+ assert !b_false.value?
804
+ b_true = Boolean.find(true_id)
805
+ assert b_true.value?
806
+ end
807
+
808
+ def test_boolean_without_questionmark
809
+ puts "In base_test test_boolean_without_questionmark"
810
+ b_true = Boolean.create({ "value" => true })
811
+ true_id = b_true.id
812
+
813
+ subclass = Class.new(Boolean).find true_id
814
+ superclass = Boolean.find true_id
815
+
816
+ assert_equal superclass.read_attribute(:has_fun), subclass.read_attribute(:has_fun)
817
+ end
818
+
819
+ def test_boolean_cast_from_string
820
+ puts "In base_test test_boolean_cast_from_string"
821
+ b_blank = Boolean.create({ "value" => "" })
822
+ blank_id = b_blank.id
823
+ b_false = Boolean.create({ "value" => "0" })
824
+ false_id = b_false.id
825
+ b_true = Boolean.create({ "value" => "1" })
826
+ true_id = b_true.id
827
+
828
+ b_blank = Boolean.find(blank_id)
829
+ assert_nil b_blank.value
830
+ b_false = Boolean.find(false_id)
831
+ assert !b_false.value?
832
+ b_true = Boolean.find(true_id)
833
+ assert b_true.value?
834
+ end
835
+
836
+ def test_new_record_returns_boolean
837
+ puts "In base_test test_new_record_returns_boolean"
838
+ assert_equal false, Topic.new.persisted?
839
+ assert_equal true, Topic.find(1).persisted?
840
+ end
841
+
842
+ def test_dup
843
+ puts "In base_test test_dup"
844
+ topic = Topic.find(1)
845
+ duped_topic = nil
846
+ assert_nothing_raised { duped_topic = topic.dup }
847
+ assert_equal topic.title, duped_topic.title
848
+ assert !duped_topic.persisted?
849
+
850
+ # test if the attributes have been duped
851
+ topic.title = "a"
852
+ duped_topic.title = "b"
853
+ assert_equal "a", topic.title
854
+ assert_equal "b", duped_topic.title
855
+
856
+ # test if the attribute values have been duped
857
+ duped_topic = topic.dup
858
+ duped_topic.title.replace "c"
859
+ assert_equal "a", topic.title
860
+
861
+ # test if attributes set as part of after_initialize are duped correctly
862
+ assert_equal topic.author_email_address, duped_topic.author_email_address
863
+
864
+ # test if saved clone object differs from original
865
+ duped_topic.save
866
+ assert duped_topic.persisted?
867
+ assert_not_equal duped_topic.id, topic.id
868
+
869
+ duped_topic.reload
870
+ assert_equal("c", duped_topic.title)
871
+ end
872
+
873
+ DeveloperSalary = Struct.new(:amount)
874
+ def test_dup_with_aggregate_of_same_name_as_attribute
875
+ puts "In base_test test_dup_with_aggregate_of_same_name_as_attribute"
876
+ developer_with_aggregate = Class.new(ActiveRecord::Base) do
877
+ self.table_name = 'developers'
878
+ composed_of :salary, :class_name => 'BasicsTest::DeveloperSalary', :mapping => [%w(salary amount)]
879
+ end
880
+
881
+ dev = developer_with_aggregate.find(1)
882
+ assert_kind_of DeveloperSalary, dev.salary
883
+
884
+ dup = nil
885
+ assert_nothing_raised { dup = dev.dup }
886
+ assert_kind_of DeveloperSalary, dup.salary
887
+ assert_equal dev.salary.amount, dup.salary.amount
888
+ assert !dup.persisted?
889
+
890
+ # test if the attributes have been duped
891
+ original_amount = dup.salary.amount
892
+ dev.salary.amount = 1
893
+ assert_equal original_amount, dup.salary.amount
894
+
895
+ assert dup.save
896
+ assert dup.persisted?
897
+ assert_not_equal dup.id, dev.id
898
+ end
899
+
900
+ def test_dup_does_not_copy_associations
901
+ puts "In base_test test_dup_does_not_copy_associations"
902
+ author = authors(:david)
903
+ assert_not_equal [], author.posts
904
+
905
+ author_dup = author.dup
906
+ assert_equal [], author_dup.posts
907
+ end
908
+
909
+ def test_clone_preserves_subtype
910
+ puts "In base_test test_clone_preserves_subtype"
911
+ clone = nil
912
+ assert_nothing_raised { clone = Company.find(3).clone }
913
+ assert_kind_of Client, clone
914
+ end
915
+
916
+ def test_clone_of_new_object_with_defaults
917
+ puts "In base_test test_clone_of_new_object_with_defaults"
918
+ developer = Developer.new
919
+ assert !developer.name_changed?
920
+ assert !developer.salary_changed?
921
+
922
+ cloned_developer = developer.clone
923
+ assert !cloned_developer.name_changed?
924
+ assert !cloned_developer.salary_changed?
925
+ end
926
+
927
+ def test_clone_of_new_object_marks_attributes_as_dirty
928
+ puts "In base_test test_clone_of_new_object_marks_attributes_as_dirty"
929
+ developer = Developer.new :name => 'Bjorn', :salary => 100000
930
+ assert developer.name_changed?
931
+ assert developer.salary_changed?
932
+
933
+ cloned_developer = developer.clone
934
+ assert cloned_developer.name_changed?
935
+ assert cloned_developer.salary_changed?
936
+ end
937
+
938
+ def test_clone_of_new_object_marks_as_dirty_only_changed_attributes
939
+ puts "In base_test test_clone_of_new_object_marks_as_dirty_only_changed_attributes"
940
+ developer = Developer.new :name => 'Bjorn'
941
+ assert developer.name_changed? # obviously
942
+ assert !developer.salary_changed? # attribute has non-nil default value, so treated as not changed
943
+
944
+ cloned_developer = developer.clone
945
+ assert cloned_developer.name_changed?
946
+ assert !cloned_developer.salary_changed? # ... and cloned instance should behave same
947
+ end
948
+
949
+ def test_dup_of_saved_object_marks_attributes_as_dirty
950
+ puts "In base_test test_dup_of_saved_object_marks_attributes_as_dirty"
951
+ developer = Developer.create! :name => 'Bjorn', :salary => 100000
952
+ assert !developer.name_changed?
953
+ assert !developer.salary_changed?
954
+
955
+ cloned_developer = developer.dup
956
+ assert cloned_developer.name_changed? # both attributes differ from defaults
957
+ assert cloned_developer.salary_changed?
958
+ end
959
+
960
+ def test_dup_of_saved_object_marks_as_dirty_only_changed_attributes
961
+ puts "In base_test test_dup_of_saved_object_marks_as_dirty_only_changed_attributes"
962
+ developer = Developer.create! :name => 'Bjorn'
963
+ assert !developer.name_changed? # both attributes of saved object should be treated as not changed
964
+ assert !developer.salary_changed?
965
+
966
+ cloned_developer = developer.dup
967
+ assert cloned_developer.name_changed? # ... but on cloned object should be
968
+ assert !cloned_developer.salary_changed? # ... BUT salary has non-nil default which should be treated as not changed on cloned instance
969
+ end
970
+
971
+ def test_bignum
972
+ puts "In base_test test_bignum"
973
+ company = Company.find(1)
974
+ company.rating = 2147483647
975
+ company.save
976
+ company = Company.find(1)
977
+ assert_equal 2147483647, company.rating
978
+ end
979
+
980
+ # TODO: extend defaults tests to other databases!
981
+ if current_adapter?(:PostgreSQLAdapter)
982
+ def test_default
983
+ puts "In base_test test_default"
984
+ with_timezone_config default: :local do
985
+ default = Default.new
986
+
987
+ # fixed dates / times
988
+ assert_equal Date.new(2004, 1, 1), default.fixed_date
989
+ assert_equal Time.local(2004, 1,1,0,0,0,0), default.fixed_time
990
+
991
+ # char types
992
+ assert_equal 'Y', default.char1
993
+ assert_equal 'a varchar field', default.char2
994
+ assert_equal 'a text field', default.char3
995
+ end
996
+ end
997
+ end
998
+
999
+ class NumericData < ActiveRecord::Base
1000
+ self.table_name = 'numeric_data'
1001
+
1002
+ attribute :my_house_population, :integer
1003
+ attribute :atoms_in_universe, :integer
1004
+ end
1005
+
1006
+ def test_big_decimal_conditions
1007
+ puts "In base_test test_big_decimal_conditions"
1008
+ m = NumericData.new(
1009
+ :bank_balance => 1586.43,
1010
+ :big_bank_balance => BigDecimal("1000234000567.95"),
1011
+ :world_population => 6000000000,
1012
+ :my_house_population => 3
1013
+ )
1014
+ assert m.save
1015
+ assert_equal 0, NumericData.where("bank_balance > ?", 2000.0).count
1016
+ end
1017
+
1018
+ def test_numeric_fields
1019
+ puts "In base_test test_numeric_fields"
1020
+ m = NumericData.new(
1021
+ :bank_balance => 1586.43,
1022
+ :big_bank_balance => BigDecimal("1000234000567.95"),
1023
+ :world_population => 6000000000,
1024
+ :my_house_population => 3
1025
+ )
1026
+ assert m.save
1027
+
1028
+ m1 = NumericData.find(m.id)
1029
+ assert_not_nil m1
1030
+
1031
+ # As with migration_test.rb, we should make world_population >= 2**62
1032
+ # to cover 64-bit platforms and test it is a Bignum, but the main thing
1033
+ # is that it's an Integer.
1034
+ unless current_adapter?(:IBM_DBAdapter)
1035
+ assert_kind_of Integer, m1.world_population
1036
+ else
1037
+ assert_equal 6000000000, m1.world_population
1038
+
1039
+ assert_kind_of Integer, m1.my_house_population
1040
+ assert_equal 3, m1.my_house_population
1041
+
1042
+ assert_kind_of BigDecimal, m1.bank_balance
1043
+ assert_equal BigDecimal("1586.43"), m1.bank_balance
1044
+
1045
+ assert_kind_of BigDecimal, m1.big_bank_balance
1046
+ assert_equal BigDecimal("1000234000567.95"), m1.big_bank_balance
1047
+ end
1048
+
1049
+ def test_numeric_fields_with_scale
1050
+ puts "In base_test test_numeric_fields_with_scale"
1051
+ m = NumericData.new(
1052
+ :bank_balance => 1586.43122334,
1053
+ :big_bank_balance => BigDecimal("234000567.952344"),
1054
+ :world_population => 6000000000,
1055
+ :my_house_population => 3
1056
+ )
1057
+ assert m.save
1058
+
1059
+ m1 = NumericData.find(m.id)
1060
+ assert_not_nil m1
1061
+
1062
+ # As with migration_test.rb, we should make world_population >= 2**62
1063
+ # to cover 64-bit platforms and test it is a Bignum, but the main thing
1064
+ # is that it's an Integer.
1065
+ assert_kind_of Integer, m1.world_population
1066
+ assert_equal 6000000000, m1.world_population
1067
+
1068
+ assert_kind_of Integer, m1.my_house_population
1069
+ assert_equal 3, m1.my_house_population
1070
+
1071
+ assert_kind_of BigDecimal, m1.bank_balance
1072
+ assert_equal BigDecimal("1586.43"), m1.bank_balance
1073
+
1074
+ assert_kind_of BigDecimal, m1.big_bank_balance
1075
+ assert_equal BigDecimal("234000567.95"), m1.big_bank_balance
1076
+ end
1077
+
1078
+ def test_auto_id
1079
+ puts "In base_test test_auto_id"
1080
+ auto = AutoId.new
1081
+ auto.save
1082
+ assert(auto.id > 0)
1083
+ end
1084
+
1085
+ def test_sql_injection_via_find
1086
+ puts "In base_test test_sql_injection_via_find"
1087
+ assert_raise(ActiveRecord::RecordNotFound, ActiveRecord::StatementInvalid) do
1088
+ Topic.find("123456 OR id > 0")
1089
+ end
1090
+ end
1091
+
1092
+ def test_column_name_properly_quoted
1093
+ puts "In base_test test_column_name_properly_quoted"
1094
+ col_record = ColumnName.new
1095
+ col_record.references = 40
1096
+ assert col_record.save
1097
+ col_record.references = 41
1098
+ assert col_record.save
1099
+ assert_not_nil c2 = ColumnName.find(col_record.id)
1100
+ assert_equal(41, c2.references)
1101
+ end
1102
+
1103
+ def test_quoting_arrays
1104
+ puts "In base_test test_quoting_arrays"
1105
+ replies = Reply.all.merge!(:where => [ "id IN (?)", topics(:first).replies.collect(&:id) ]).to_a
1106
+ assert_equal topics(:first).replies.size, replies.size
1107
+
1108
+ replies = Reply.all.merge!(:where => [ "id IN (?)", [] ]).to_a
1109
+ assert_equal 0, replies.size
1110
+ end
1111
+
1112
+ def test_quote
1113
+ puts "In base_test test_quote"
1114
+ author_name = "\\ \001 ' \n \\n \""
1115
+ topic = Topic.create('author_name' => author_name)
1116
+ assert_equal author_name, Topic.find(topic.id).author_name
1117
+ end
1118
+
1119
+ def test_toggle_attribute
1120
+ puts "In base_test test_toggle_attribute"
1121
+ assert !topics(:first).approved?
1122
+ topics(:first).toggle!(:approved)
1123
+ assert topics(:first).approved?
1124
+ topic = topics(:first)
1125
+ topic.toggle(:approved)
1126
+ assert !topic.approved?
1127
+ topic.reload
1128
+ assert topic.approved?
1129
+ end
1130
+
1131
+ def test_reload
1132
+ puts "In base_test test_reload"
1133
+ t1 = Topic.find(1)
1134
+ t2 = Topic.find(1)
1135
+ t1.title = "something else"
1136
+ t1.save
1137
+ t2.reload
1138
+ assert_equal t1.title, t2.title
1139
+ end
1140
+
1141
+ def test_reload_with_exclusive_scope
1142
+ puts "In base_test test_reload_with_exclusive_scope"
1143
+ dev = DeveloperCalledDavid.first
1144
+ dev.update!(name: "NotDavid" )
1145
+ assert_equal dev, dev.reload
1146
+ end
1147
+
1148
+ def test_switching_between_table_name
1149
+ puts "In base_test test_switching_between_table_name"
1150
+ k = Class.new(Joke)
1151
+
1152
+ assert_difference("GoodJoke.count") do
1153
+ k.table_name = "cold_jokes"
1154
+ k.create
1155
+
1156
+ k.table_name = "funny_jokes"
1157
+ k.create
1158
+ end
1159
+ end
1160
+
1161
+ def test_clear_cash_when_setting_table_name
1162
+ puts "In base_test test_clear_cash_when_setting_table_name"
1163
+ original_table_name = Joke.table_name
1164
+
1165
+ Joke.table_name = "funny_jokes"
1166
+ before_columns = Joke.columns
1167
+ before_seq = Joke.sequence_name
1168
+
1169
+ Joke.table_name = "cold_jokes"
1170
+ after_columns = Joke.columns
1171
+ after_seq = Joke.sequence_name
1172
+
1173
+ assert_not_equal before_columns, after_columns
1174
+ assert_not_equal before_seq, after_seq unless before_seq.nil? && after_seq.nil?
1175
+ ensure
1176
+ Joke.table_name = original_table_name
1177
+ end
1178
+
1179
+ def test_dont_clear_sequence_name_when_setting_explicitly
1180
+ puts "In base_test test_dont_clear_sequence_name_when_setting_explicitly"
1181
+ k = Class.new(Joke)
1182
+ k.sequence_name = "black_jokes_seq"
1183
+ k.table_name = "cold_jokes"
1184
+ before_seq = k.sequence_name
1185
+
1186
+ k.table_name = "funny_jokes"
1187
+ after_seq = k.sequence_name
1188
+
1189
+ assert_equal before_seq, after_seq unless before_seq.nil? && after_seq.nil?
1190
+ end
1191
+
1192
+ def test_dont_clear_inheritance_column_when_setting_explicitly
1193
+ puts "In base_test test_dont_clear_inheritance_column_when_setting_explicitly"
1194
+ k = Class.new(Joke)
1195
+ k.inheritance_column = "my_type"
1196
+ before_inherit = k.inheritance_column
1197
+
1198
+ k.reset_column_information
1199
+ after_inherit = k.inheritance_column
1200
+
1201
+ assert_equal before_inherit, after_inherit unless before_inherit.blank? && after_inherit.blank?
1202
+ end
1203
+
1204
+ def test_set_table_name_symbol_converted_to_string
1205
+ puts "In base_test test_set_table_name_symbol_converted_to_string"
1206
+ k = Class.new(Joke)
1207
+ k.table_name = :cold_jokes
1208
+ assert_equal 'cold_jokes', k.table_name
1209
+ end
1210
+
1211
+ def test_quoted_table_name_after_set_table_name
1212
+ puts "In base_test test_quoted_table_name_after_set_table_name"
1213
+ klass = Class.new(ActiveRecord::Base)
1214
+
1215
+ klass.table_name = "foo"
1216
+ assert_equal "foo", klass.table_name
1217
+ assert_equal klass.connection.quote_table_name("foo"), klass.quoted_table_name
1218
+
1219
+ klass.table_name = "bar"
1220
+ assert_equal "bar", klass.table_name
1221
+ assert_equal klass.connection.quote_table_name("bar"), klass.quoted_table_name
1222
+ end
1223
+
1224
+ def test_set_table_name_with_inheritance
1225
+ puts "In base_test test_set_table_name_with_inheritance"
1226
+ k = Class.new( ActiveRecord::Base )
1227
+ def k.name; "Foo"; end
1228
+ def k.table_name; super + "ks"; end
1229
+ assert_equal "foosks", k.table_name
1230
+ end
1231
+
1232
+ def test_sequence_name_with_abstract_class
1233
+ puts "In base_test test_sequence_name_with_abstract_class"
1234
+ ak = Class.new(ActiveRecord::Base)
1235
+ ak.abstract_class = true
1236
+ k = Class.new(ak)
1237
+ k.table_name = "projects"
1238
+ orig_name = k.sequence_name
1239
+ skip "sequences not supported by db" unless orig_name
1240
+ assert_equal k.reset_sequence_name, orig_name
1241
+ end
1242
+
1243
+ def test_count_with_join
1244
+ puts "In base_test test_count_with_join"
1245
+ res = Post.count_by_sql "SELECT COUNT(*) FROM posts LEFT JOIN comments ON posts.id=comments.post_id WHERE posts.#{QUOTED_TYPE} = 'Post'"
1246
+
1247
+ res2 = Post.where("posts.#{QUOTED_TYPE} = 'Post'").joins("LEFT JOIN comments ON posts.id=comments.post_id").count
1248
+ assert_equal res, res2
1249
+
1250
+ res3 = nil
1251
+ assert_nothing_raised do
1252
+ res3 = Post.where("posts.#{QUOTED_TYPE} = 'Post'").joins("LEFT JOIN comments ON posts.id=comments.post_id").count
1253
+ end
1254
+ assert_equal res, res3
1255
+
1256
+ res4 = Post.count_by_sql "SELECT COUNT(p.id) FROM posts p, comments co WHERE p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id"
1257
+ res5 = nil
1258
+ assert_nothing_raised do
1259
+ res5 = Post.where("p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id").joins("p, comments co").select("p.id").count
1260
+ end
1261
+
1262
+ assert_equal res4, res5
1263
+
1264
+ res6 = Post.count_by_sql "SELECT COUNT(DISTINCT p.id) FROM posts p, comments co WHERE p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id"
1265
+ res7 = nil
1266
+ assert_nothing_raised do
1267
+ res7 = Post.where("p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id").joins("p, comments co").select("p.id").distinct.count
1268
+ end
1269
+ assert_equal res6, res7
1270
+ end
1271
+
1272
+ def test_no_limit_offset
1273
+ puts "In base_test test_no_limit_offset"
1274
+ assert_nothing_raised do
1275
+ Developer.all.merge!(:offset => 2).to_a
1276
+ end
1277
+ end
1278
+
1279
+ def test_find_last
1280
+ puts "In base_test test_find_last"
1281
+ last = Developer.last
1282
+ assert_equal last, Developer.all.merge!(:order => 'id desc').first
1283
+ end
1284
+
1285
+ def test_last
1286
+ puts "In base_test test_last"
1287
+ assert_equal Developer.all.merge!(:order => 'id desc').first, Developer.last
1288
+ end
1289
+
1290
+ def test_all
1291
+ puts "In base_test test_all"
1292
+ developers = Developer.all
1293
+ assert_kind_of ActiveRecord::Relation, developers
1294
+ assert_equal Developer.all, developers
1295
+ end
1296
+
1297
+ def test_all_with_conditions
1298
+ puts "In base_test test_all_with_conditions"
1299
+ assert_equal Developer.all.merge!(:order => 'id desc').to_a, Developer.order('id desc').to_a
1300
+ end
1301
+
1302
+ def test_find_ordered_last
1303
+ puts "In base_test test_find_ordered_last"
1304
+ last = Developer.all.merge!(:order => 'developers.salary ASC').last
1305
+ assert_equal last, Developer.all.merge!(:order => 'developers.salary ASC').to_a.last
1306
+ end
1307
+
1308
+ def test_find_reverse_ordered_last
1309
+ puts "In base_test test_find_reverse_ordered_last"
1310
+ last = Developer.all.merge!(:order => 'developers.salary DESC').last
1311
+ assert_equal last, Developer.all.merge!(:order => 'developers.salary DESC').to_a.last
1312
+ end
1313
+
1314
+ def test_find_multiple_ordered_last
1315
+ puts "In base_test test_find_multiple_ordered_last"
1316
+ last = Developer.all.merge!(:order => 'developers.name, developers.salary DESC').last
1317
+ assert_equal last, Developer.all.merge!(:order => 'developers.name, developers.salary DESC').to_a.last
1318
+ end
1319
+
1320
+ def test_find_keeps_multiple_order_values
1321
+ puts "In base_test test_find_keeps_multiple_order_values"
1322
+ combined = Developer.all.merge!(:order => 'developers.name, developers.salary').to_a
1323
+ assert_equal combined, Developer.all.merge!(:order => ['developers.name', 'developers.salary']).to_a
1324
+ end
1325
+
1326
+ def test_find_keeps_multiple_group_values
1327
+ puts "In base_test test_find_keeps_multiple_group_values"
1328
+ combined = Developer.all.merge!(:group => 'developers.name, developers.salary, developers.id, developers.created_at, developers.updated_at, developers.created_on, developers.updated_on').to_a
1329
+ assert_equal combined, Developer.all.merge!(:group => ['developers.name', 'developers.salary', 'developers.id', 'developers.created_at', 'developers.updated_at', 'developers.created_on', 'developers.updated_on']).to_a
1330
+ end
1331
+
1332
+ def test_find_symbol_ordered_last
1333
+ puts "In base_test test_find_symbol_ordered_last"
1334
+ last = Developer.all.merge!(:order => :salary).last
1335
+ assert_equal last, Developer.all.merge!(:order => :salary).to_a.last
1336
+ end
1337
+
1338
+ def test_abstract_class_table_name
1339
+ puts "In base_test test_abstract_class_table_name"
1340
+ assert_nil AbstractCompany.table_name
1341
+ end
1342
+
1343
+ def test_find_on_abstract_base_class_doesnt_use_type_condition
1344
+ puts "In base_test test_find_on_abstract_base_class_doesnt_use_type_condition"
1345
+ old_class = LooseDescendant
1346
+ Object.send :remove_const, :LooseDescendant
1347
+
1348
+ descendant = old_class.create! :first_name => 'bob'
1349
+ assert_not_nil LoosePerson.find(descendant.id), "Should have found instance of LooseDescendant when finding abstract LoosePerson: #{descendant.inspect}"
1350
+ ensure
1351
+ unless Object.const_defined?(:LooseDescendant)
1352
+ Object.const_set :LooseDescendant, old_class
1353
+ end
1354
+ end
1355
+
1356
+ def test_assert_queries
1357
+ puts "In base_test test_assert_queries"
1358
+ query = lambda { ActiveRecord::Base.connection.execute 'select count(*) from developers' }
1359
+ assert_queries(2) { 2.times { query.call } }
1360
+ assert_queries 1, &query
1361
+ assert_no_queries { assert true }
1362
+ end
1363
+
1364
+ def test_benchmark_with_log_level
1365
+ puts "In base_test test_benchmark_with_log_level"
1366
+ original_logger = ActiveRecord::Base.logger
1367
+ log = StringIO.new
1368
+ ActiveRecord::Base.logger = ActiveSupport::Logger.new(log)
1369
+ ActiveRecord::Base.logger.level = Logger::WARN
1370
+ ActiveRecord::Base.benchmark("Debug Topic Count", :level => :debug) { Topic.count }
1371
+ ActiveRecord::Base.benchmark("Warn Topic Count", :level => :warn) { Topic.count }
1372
+ ActiveRecord::Base.benchmark("Error Topic Count", :level => :error) { Topic.count }
1373
+ assert_no_match(/Debug Topic Count/, log.string)
1374
+ assert_match(/Warn Topic Count/, log.string)
1375
+ assert_match(/Error Topic Count/, log.string)
1376
+ ensure
1377
+ ActiveRecord::Base.logger = original_logger
1378
+ end
1379
+
1380
+ def test_benchmark_with_use_silence
1381
+ puts "In base_test test_benchmark_with_use_silence"
1382
+ original_logger = ActiveRecord::Base.logger
1383
+ log = StringIO.new
1384
+ ActiveRecord::Base.logger = ActiveSupport::Logger.new(log)
1385
+ ActiveRecord::Base.logger.level = Logger::DEBUG
1386
+ ActiveRecord::Base.benchmark("Logging", :level => :debug, :silence => false) { ActiveRecord::Base.logger.debug "Quiet" }
1387
+ assert_match(/Quiet/, log.string)
1388
+ ensure
1389
+ ActiveRecord::Base.logger = original_logger
1390
+ end
1391
+
1392
+ def test_clear_cache!
1393
+ puts "In base_test test_clear_cache"
1394
+ # preheat cache
1395
+ c1 = Post.connection.schema_cache.columns('posts')
1396
+ ActiveRecord::Base.clear_cache!
1397
+ c2 = Post.connection.schema_cache.columns('posts')
1398
+ c1.each_with_index do |v, i|
1399
+ assert_not_same v, c2[i]
1400
+ end
1401
+ assert_equal c1, c2
1402
+ end
1403
+
1404
+ def test_current_scope_is_reset
1405
+ puts "In base_test test_current_scope_is_reset"
1406
+ Object.const_set :UnloadablePost, Class.new(ActiveRecord::Base)
1407
+ UnloadablePost.send(:current_scope=, UnloadablePost.all)
1408
+
1409
+ UnloadablePost.unloadable
1410
+ klass = UnloadablePost
1411
+ assert_not_nil ActiveRecord::Scoping::ScopeRegistry.value_for(:current_scope, klass)
1412
+ ActiveSupport::Dependencies.remove_unloadable_constants!
1413
+ assert_nil ActiveRecord::Scoping::ScopeRegistry.value_for(:current_scope, klass)
1414
+ ensure
1415
+ Object.class_eval{ remove_const :UnloadablePost } if defined?(UnloadablePost)
1416
+ end
1417
+
1418
+ def test_marshal_round_trip
1419
+ puts "In base_test test_marshal_round_trip"
1420
+ expected = posts(:welcome)
1421
+ marshalled = Marshal.dump(expected)
1422
+ actual = Marshal.load(marshalled)
1423
+
1424
+ assert_equal expected.attributes, actual.attributes
1425
+ end
1426
+
1427
+ def test_marshal_new_record_round_trip
1428
+ puts "In base_test test_marshal_new_record_round_trip"
1429
+ marshalled = Marshal.dump(Post.new)
1430
+ post = Marshal.load(marshalled)
1431
+
1432
+ assert post.new_record?, "should be a new record"
1433
+ end
1434
+
1435
+ def test_marshalling_with_associations
1436
+ puts "In base_test test_marshalling_with_associations"
1437
+ post = Post.new
1438
+ post.comments.build
1439
+
1440
+ marshalled = Marshal.dump(post)
1441
+ post = Marshal.load(marshalled)
1442
+
1443
+ assert_equal 1, post.comments.length
1444
+ end
1445
+
1446
+ if Process.respond_to?(:fork) && !in_memory_db?
1447
+ def test_marshal_between_processes
1448
+ puts "In base_test test_marshal_between_processes"
1449
+ # Define a new model to ensure there are no caches
1450
+ if self.class.const_defined?("Post", false)
1451
+ flunk "there should be no post constant"
1452
+ end
1453
+
1454
+ self.class.const_set("Post", Class.new(ActiveRecord::Base) {
1455
+ has_many :comments
1456
+ })
1457
+
1458
+ rd, wr = IO.pipe
1459
+ rd.binmode
1460
+ wr.binmode
1461
+
1462
+ ActiveRecord::Base.connection_handler.clear_all_connections!
1463
+
1464
+ fork do
1465
+ rd.close
1466
+ post = Post.new
1467
+ post.comments.build
1468
+ wr.write Marshal.dump(post)
1469
+ wr.close
1470
+ end
1471
+
1472
+ wr.close
1473
+ assert Marshal.load rd.read
1474
+ rd.close
1475
+ end
1476
+ end
1477
+
1478
+ def test_marshalling_new_record_round_trip_with_associations
1479
+ puts "In base_test test_marshalling_new_record_round_trip_with_associations"
1480
+ post = Post.new
1481
+ post.comments.build
1482
+
1483
+ post = Marshal.load(Marshal.dump(post))
1484
+
1485
+ assert post.new_record?, "should be a new record"
1486
+ end
1487
+
1488
+ def test_attribute_names
1489
+ puts "In base_test test_attribute_names"
1490
+ assert_equal ["id", "type", "firm_id", "firm_name", "name", "client_of", "rating", "account_id", "description"],
1491
+ Company.attribute_names
1492
+ end
1493
+
1494
+ def test_has_attribute
1495
+ puts "In base_test test_has_attribute"
1496
+ assert Company.has_attribute?('id')
1497
+ assert Company.has_attribute?('type')
1498
+ assert Company.has_attribute?('name')
1499
+ assert_not Company.has_attribute?('lastname')
1500
+ assert_not Company.has_attribute?('age')
1501
+ end
1502
+
1503
+ def test_has_attribute_with_symbol
1504
+ puts "In base_test test_has_attribute_with_symbol"
1505
+ assert Company.has_attribute?(:id)
1506
+ assert_not Company.has_attribute?(:age)
1507
+ end
1508
+
1509
+ def test_attribute_names_on_table_not_exists
1510
+ puts "In base_test test_attribute_names_on_table_not_exists"
1511
+ assert_equal [], NonExistentTable.attribute_names
1512
+ end
1513
+
1514
+ def test_attribute_names_on_abstract_class
1515
+ puts "In base_test test_attribute_names_on_abstract_class"
1516
+ assert_equal [], AbstractCompany.attribute_names
1517
+ end
1518
+
1519
+ def test_touch_should_raise_error_on_a_new_object
1520
+ puts "In base_test test_touch_should_raise_error_on_a_new_object"
1521
+ company = Company.new(:rating => 1, :name => "37signals", :firm_name => "37signals")
1522
+ assert_raises(ActiveRecord::ActiveRecordError) do
1523
+ company.touch :updated_at
1524
+ end
1525
+ end
1526
+
1527
+ def test_uniq_delegates_to_scoped
1528
+ puts "In base_test test_uniq_delegates_to_scoped"
1529
+ assert_deprecated do
1530
+ assert_equal Bird.all.distinct, Bird.uniq
1531
+ end
1532
+ end
1533
+
1534
+ def test_distinct_delegates_to_scoped
1535
+ puts "In base_test test_distinct_delegates_to_scoped"
1536
+ assert_equal Bird.all.distinct, Bird.distinct
1537
+ end
1538
+
1539
+ def test_table_name_with_2_abstract_subclasses
1540
+ puts "In base_test test_table_name_with_2_abstract_subclasses"
1541
+ assert_equal "photos", Photo.table_name
1542
+ end
1543
+
1544
+ def test_column_types_typecast
1545
+ puts "In base_test test_column_types_typecast"
1546
+ topic = Topic.first
1547
+ assert_not_equal 't.lo', topic.author_name
1548
+
1549
+ attrs = topic.attributes.dup
1550
+ attrs.delete 'id'
1551
+
1552
+ typecast = Class.new(ActiveRecord::Type::Value) {
1553
+ def cast value
1554
+ "t.lo"
1555
+ end
1556
+ }
1557
+
1558
+ types = { 'author_name' => typecast.new }
1559
+ topic = Topic.instantiate(attrs, types)
1560
+
1561
+ assert_equal 't.lo', topic.author_name
1562
+ end
1563
+
1564
+ def test_typecasting_aliases
1565
+ puts "In base_test test_typecasting_aliases"
1566
+ assert_equal 10, Topic.select('10 as tenderlove').first.tenderlove
1567
+ end
1568
+
1569
+ def test_slice
1570
+ puts "In base_test test_slice"
1571
+ company = Company.new(:rating => 1, :name => "37signals", :firm_name => "37signals")
1572
+ hash = company.slice(:name, :rating, "arbitrary_method")
1573
+ assert_equal hash[:name], company.name
1574
+ assert_equal hash['name'], company.name
1575
+ assert_equal hash[:rating], company.rating
1576
+ assert_equal hash['arbitrary_method'], company.arbitrary_method
1577
+ assert_equal hash[:arbitrary_method], company.arbitrary_method
1578
+ assert_nil hash[:firm_name]
1579
+ assert_nil hash['firm_name']
1580
+ end
1581
+
1582
+ def test_default_values_are_deeply_dupped
1583
+ puts "In base_test test_default_values_are_deeply_dupped"
1584
+ company = Company.new
1585
+ company.description << "foo"
1586
+ assert_equal "", Company.new.description
1587
+ end
1588
+
1589
+ test "scoped can take a values hash" do
1590
+ puts "In base_test scoped can take a values hash"
1591
+ klass = Class.new(ActiveRecord::Base)
1592
+ assert_equal ['foo'], klass.all.merge!(select: 'foo').select_values
1593
+ end
1594
+
1595
+ test "connection_handler can be overridden" do
1596
+ puts "In base_test connection_handler can be overridden"
1597
+ klass = Class.new(ActiveRecord::Base)
1598
+ orig_handler = klass.connection_handler
1599
+ new_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
1600
+ thread_connection_handler = nil
1601
+
1602
+ t = Thread.new do
1603
+ klass.connection_handler = new_handler
1604
+ thread_connection_handler = klass.connection_handler
1605
+ end
1606
+ t.join
1607
+
1608
+ assert_equal klass.connection_handler, orig_handler
1609
+ assert_equal thread_connection_handler, new_handler
1610
+ end
1611
+
1612
+ test "new threads get default the default connection handler" do
1613
+ puts "In base_test new threads get default the default connection handler"
1614
+ klass = Class.new(ActiveRecord::Base)
1615
+ orig_handler = klass.connection_handler
1616
+ handler = nil
1617
+
1618
+ t = Thread.new do
1619
+ handler = klass.connection_handler
1620
+ end
1621
+ t.join
1622
+
1623
+ assert_equal handler, orig_handler
1624
+ assert_equal klass.connection_handler, orig_handler
1625
+ assert_equal klass.default_connection_handler, orig_handler
1626
+ end
1627
+
1628
+ test "changing a connection handler in a main thread does not poison the other threads" do
1629
+ puts "In base_test changing a connection handler in a main thread does not poison the other threads"
1630
+ klass = Class.new(ActiveRecord::Base)
1631
+ orig_handler = klass.connection_handler
1632
+ new_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
1633
+ after_handler = nil
1634
+ latch1 = Concurrent::CountDownLatch.new
1635
+ latch2 = Concurrent::CountDownLatch.new
1636
+
1637
+ t = Thread.new do
1638
+ klass.connection_handler = new_handler
1639
+ latch1.count_down
1640
+ latch2.wait
1641
+ after_handler = klass.connection_handler
1642
+ end
1643
+
1644
+ latch1.wait
1645
+
1646
+ klass.connection_handler = orig_handler
1647
+ latch2.count_down
1648
+ t.join
1649
+
1650
+ assert_equal after_handler, new_handler
1651
+ assert_equal orig_handler, klass.connection_handler
1652
+ end
1653
+
1654
+ # Note: This is a performance optimization for Array#uniq and Hash#[] with
1655
+ # AR::Base objects. If the future has made this irrelevant, feel free to
1656
+ # delete this.
1657
+ test "records without an id have unique hashes" do
1658
+ puts "In base_test records without an id have unique hashes"
1659
+ assert_not_equal Post.new.hash, Post.new.hash
1660
+ end
1661
+
1662
+ test "resetting column information doesn't remove attribute methods" do
1663
+ puts "In base_test changing a connection handler in a main thread does not poison the other threads"
1664
+ topic = topics(:first)
1665
+
1666
+ assert_not topic.id_changed?
1667
+
1668
+ Topic.reset_column_information
1669
+
1670
+ assert_not topic.id_changed?
1671
+ end
1672
+
1673
+ test "ignored columns are not present in columns_hash" do
1674
+ puts "In base_test ignored columns are not present in columns_hash"
1675
+ cache_columns = Developer.connection.schema_cache.columns_hash(Developer.table_name)
1676
+ assert_includes cache_columns.keys, "first_name"
1677
+ assert_not_includes Developer.columns_hash.keys, "first_name"
1678
+ assert_not_includes SubDeveloper.columns_hash.keys, "first_name"
1679
+ assert_not_includes SymbolIgnoredDeveloper.columns_hash.keys, "first_name"
1680
+ end
1681
+
1682
+ test "ignored columns have no attribute methods" do
1683
+ puts "In base_test ignored columns have no attribute methods"
1684
+ refute Developer.new.respond_to?(:first_name)
1685
+ refute Developer.new.respond_to?(:first_name=)
1686
+ refute Developer.new.respond_to?(:first_name?)
1687
+ refute SubDeveloper.new.respond_to?(:first_name)
1688
+ refute SubDeveloper.new.respond_to?(:first_name=)
1689
+ refute SubDeveloper.new.respond_to?(:first_name?)
1690
+ refute SymbolIgnoredDeveloper.new.respond_to?(:first_name)
1691
+ refute SymbolIgnoredDeveloper.new.respond_to?(:first_name=)
1692
+ refute SymbolIgnoredDeveloper.new.respond_to?(:first_name?)
1693
+ end
1694
+
1695
+ test "ignored columns don't prevent explicit declaration of attribute methods" do
1696
+ puts "In base_test ignored columns don't prevent explicit declaration of attribute methods"
1697
+ assert Developer.new.respond_to?(:last_name)
1698
+ assert Developer.new.respond_to?(:last_name=)
1699
+ assert Developer.new.respond_to?(:last_name?)
1700
+ assert SubDeveloper.new.respond_to?(:last_name)
1701
+ assert SubDeveloper.new.respond_to?(:last_name=)
1702
+ assert SubDeveloper.new.respond_to?(:last_name?)
1703
+ assert SymbolIgnoredDeveloper.new.respond_to?(:last_name)
1704
+ assert SymbolIgnoredDeveloper.new.respond_to?(:last_name=)
1705
+ assert SymbolIgnoredDeveloper.new.respond_to?(:last_name?)
1706
+ end
1707
+
1708
+ test "ignored columns are stored as an array of string" do
1709
+ puts "In base_test ignored columns are stored as an array of string"
1710
+ assert_equal(%w(first_name last_name), Developer.ignored_columns)
1711
+ assert_equal(%w(first_name last_name), SymbolIgnoredDeveloper.ignored_columns)
1712
+ end
1713
+ end