ibm_db 5.6.1 β†’ 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (592) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Makefile +13 -9
  3. data/ext/extconf.rb +176 -110
  4. data/ext/ibm_db.c +60 -0
  5. data/ext/ibm_db.o +0 -0
  6. data/ext/ibm_db.so +0 -0
  7. data/ext/mkmf.log +6 -6
  8. data/ext/ruby_ibm_db_cli.c +14 -10
  9. data/ext/ruby_ibm_db_cli.h +4 -0
  10. data/ext/ruby_ibm_db_cli.o +0 -0
  11. data/lib/IBM_DB.rb +2 -2
  12. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1254 -277
  13. data/test/active_record/connection_adapters/fake_legacy_adapter.rb +17 -0
  14. data/test/active_record/connection_adapters/fake_misleading_legacy_adapter.rb +8 -0
  15. data/test/activejob/destroy_association_async_job_test.rb +62 -0
  16. data/test/activejob/destroy_association_async_test.rb +147 -11
  17. data/test/activejob/job_runtime_test.rb +41 -0
  18. data/test/activejob/unloadable_base_job.rb +3 -0
  19. data/test/cases/active_record_schema_test.rb +196 -0
  20. data/test/cases/active_record_test.rb +21 -0
  21. data/test/cases/adapter_prevent_writes_test.rb +26 -202
  22. data/test/cases/adapter_test.rb +592 -82
  23. data/test/cases/adapters/abstract_mysql_adapter/active_schema_test.rb +210 -0
  24. data/test/cases/adapters/abstract_mysql_adapter/adapter_prevent_writes_test.rb +111 -0
  25. data/test/cases/adapters/abstract_mysql_adapter/auto_increment_test.rb +48 -0
  26. data/test/cases/adapters/abstract_mysql_adapter/bind_parameter_test.rb +91 -0
  27. data/test/cases/adapters/abstract_mysql_adapter/case_sensitivity_test.rb +65 -0
  28. data/test/cases/adapters/abstract_mysql_adapter/charset_collation_test.rb +85 -0
  29. data/test/cases/adapters/abstract_mysql_adapter/connection_test.rb +267 -0
  30. data/test/cases/adapters/abstract_mysql_adapter/count_deleted_rows_with_lock_test.rb +29 -0
  31. data/test/cases/adapters/abstract_mysql_adapter/json_test.rb +24 -0
  32. data/test/cases/adapters/abstract_mysql_adapter/mysql_boolean_test.rb +102 -0
  33. data/test/cases/adapters/abstract_mysql_adapter/mysql_enum_test.rb +47 -0
  34. data/test/cases/adapters/abstract_mysql_adapter/mysql_explain_test.rb +71 -0
  35. data/test/cases/adapters/abstract_mysql_adapter/nested_deadlock_test.rb +191 -0
  36. data/test/cases/adapters/abstract_mysql_adapter/optimizer_hints_test.rb +69 -0
  37. data/test/cases/adapters/abstract_mysql_adapter/quoting_test.rb +49 -0
  38. data/test/cases/adapters/abstract_mysql_adapter/schema_migrations_test.rb +68 -0
  39. data/test/cases/adapters/abstract_mysql_adapter/schema_test.rb +130 -0
  40. data/test/cases/adapters/abstract_mysql_adapter/set_test.rb +32 -0
  41. data/test/cases/adapters/abstract_mysql_adapter/sp_test.rb +39 -0
  42. data/test/cases/adapters/abstract_mysql_adapter/sql_types_test.rb +16 -0
  43. data/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb +125 -0
  44. data/test/cases/adapters/abstract_mysql_adapter/transaction_test.rb +204 -0
  45. data/test/cases/adapters/abstract_mysql_adapter/unsigned_type_test.rb +77 -0
  46. data/test/cases/adapters/abstract_mysql_adapter/virtual_column_test.rb +69 -0
  47. data/test/cases/adapters/abstract_mysql_adapter/warnings_test.rb +109 -0
  48. data/test/cases/adapters/mysql2/check_constraint_quoting_test.rb +35 -0
  49. data/test/cases/adapters/mysql2/dbconsole_test.rb +87 -0
  50. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +136 -10
  51. data/test/cases/adapters/mysql2/mysql2_rake_test.rb +433 -0
  52. data/test/cases/adapters/postgresql/active_schema_test.rb +8 -4
  53. data/test/cases/adapters/postgresql/array_test.rb +6 -6
  54. data/test/cases/adapters/postgresql/bind_parameter_test.rb +52 -0
  55. data/test/cases/adapters/postgresql/bit_string_test.rb +2 -2
  56. data/test/cases/adapters/postgresql/bytea_test.rb +3 -3
  57. data/test/cases/adapters/postgresql/case_insensitive_test.rb +1 -1
  58. data/test/cases/adapters/postgresql/change_schema_test.rb +32 -1
  59. data/test/cases/adapters/postgresql/cidr_test.rb +17 -0
  60. data/test/cases/adapters/postgresql/citext_test.rb +7 -1
  61. data/test/cases/adapters/postgresql/collation_test.rb +1 -1
  62. data/test/cases/adapters/postgresql/composite_test.rb +1 -1
  63. data/test/cases/adapters/postgresql/connection_test.rb +43 -36
  64. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +3 -2
  65. data/test/cases/adapters/postgresql/datatype_test.rb +9 -4
  66. data/test/cases/adapters/postgresql/date_test.rb +2 -2
  67. data/test/cases/adapters/postgresql/dbconsole_test.rb +109 -0
  68. data/test/cases/adapters/postgresql/deferred_constraints_test.rb +55 -0
  69. data/test/cases/adapters/postgresql/domain_test.rb +1 -1
  70. data/test/cases/adapters/postgresql/enum_test.rb +208 -8
  71. data/test/cases/adapters/postgresql/explain_test.rb +25 -6
  72. data/test/cases/adapters/postgresql/extension_migration_test.rb +51 -9
  73. data/test/cases/adapters/postgresql/foreign_table_test.rb +3 -3
  74. data/test/cases/adapters/postgresql/full_text_test.rb +1 -1
  75. data/test/cases/adapters/postgresql/geometric_test.rb +13 -6
  76. data/test/cases/adapters/postgresql/hstore_test.rb +22 -32
  77. data/test/cases/adapters/postgresql/infinity_test.rb +13 -2
  78. data/test/cases/adapters/postgresql/integer_test.rb +1 -1
  79. data/test/cases/adapters/postgresql/interval_test.rb +9 -17
  80. data/test/cases/adapters/postgresql/invertible_migration_test.rb +139 -0
  81. data/test/cases/adapters/postgresql/json_test.rb +5 -0
  82. data/test/cases/adapters/postgresql/ltree_test.rb +1 -1
  83. data/test/cases/adapters/postgresql/money_test.rb +17 -9
  84. data/test/cases/adapters/postgresql/network_test.rb +13 -1
  85. data/test/cases/adapters/postgresql/numbers_test.rb +18 -2
  86. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +9 -9
  87. data/test/cases/adapters/postgresql/partitions_test.rb +5 -2
  88. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +7 -110
  89. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +403 -20
  90. data/test/cases/adapters/postgresql/postgresql_rake_test.rb +637 -0
  91. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +1 -1
  92. data/test/cases/adapters/postgresql/quoting_test.rb +60 -1
  93. data/test/cases/adapters/postgresql/range_test.rb +185 -21
  94. data/test/cases/adapters/postgresql/referential_integrity_test.rb +29 -5
  95. data/test/cases/adapters/postgresql/rename_table_test.rb +35 -8
  96. data/test/cases/adapters/postgresql/schema_authorization_test.rb +2 -2
  97. data/test/cases/adapters/postgresql/schema_test.rb +270 -20
  98. data/test/cases/adapters/postgresql/serial_test.rb +5 -5
  99. data/test/cases/adapters/postgresql/statement_pool_test.rb +6 -2
  100. data/test/cases/adapters/postgresql/timestamp_test.rb +122 -5
  101. data/test/cases/adapters/postgresql/transaction_nested_test.rb +130 -6
  102. data/test/cases/adapters/postgresql/transaction_test.rb +37 -11
  103. data/test/cases/adapters/postgresql/type_lookup_test.rb +1 -1
  104. data/test/cases/adapters/postgresql/uuid_test.rb +77 -9
  105. data/test/cases/adapters/postgresql/virtual_column_test.rb +114 -0
  106. data/test/cases/adapters/postgresql/xml_test.rb +1 -1
  107. data/test/cases/adapters/sqlite3/bind_parameter_test.rb +52 -0
  108. data/test/cases/adapters/sqlite3/collation_test.rb +1 -1
  109. data/test/cases/adapters/sqlite3/copy_table_test.rb +28 -7
  110. data/test/cases/adapters/sqlite3/dbconsole_test.rb +81 -0
  111. data/test/cases/adapters/sqlite3/explain_test.rb +3 -3
  112. data/test/cases/adapters/sqlite3/quoting_test.rb +34 -3
  113. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +9 -102
  114. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +727 -72
  115. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +6 -3
  116. data/test/cases/adapters/sqlite3/sqlite_rake_test.rb +264 -0
  117. data/test/cases/adapters/sqlite3/statement_pool_test.rb +1 -1
  118. data/test/cases/adapters/sqlite3/transaction_test.rb +6 -3
  119. data/test/cases/adapters/sqlite3/virtual_column_test.rb +138 -0
  120. data/test/cases/adapters/sqlite3/virtual_table_test.rb +51 -0
  121. data/test/cases/adapters/trilogy/dbconsole_test.rb +76 -0
  122. data/test/cases/adapters/trilogy/trilogy_adapter_test.rb +473 -0
  123. data/test/cases/adapters/trilogy/trilogy_rake_test.rb +433 -0
  124. data/test/cases/aggregations_test.rb +16 -0
  125. data/test/cases/annotate_test.rb +14 -12
  126. data/test/cases/arel/attributes/attribute_test.rb +86 -47
  127. data/test/cases/arel/collectors/bind_test.rb +1 -1
  128. data/test/cases/arel/collectors/composite_test.rb +11 -1
  129. data/test/cases/arel/collectors/sql_string_test.rb +1 -1
  130. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +1 -1
  131. data/test/cases/arel/delete_manager_test.rb +0 -6
  132. data/test/cases/arel/factory_methods_test.rb +45 -0
  133. data/test/cases/arel/insert_manager_test.rb +1 -7
  134. data/test/cases/arel/nodes/as_test.rb +12 -0
  135. data/test/cases/arel/nodes/ascending_test.rb +1 -1
  136. data/test/cases/arel/nodes/bin_test.rb +1 -1
  137. data/test/cases/arel/nodes/bound_sql_literal_test.rb +31 -0
  138. data/test/cases/arel/nodes/cte_test.rb +46 -0
  139. data/test/cases/arel/nodes/descending_test.rb +1 -1
  140. data/test/cases/arel/nodes/equality_test.rb +3 -3
  141. data/test/cases/arel/nodes/filter_test.rb +37 -0
  142. data/test/cases/arel/nodes/fragments_test.rb +38 -0
  143. data/test/cases/arel/nodes/homogeneous_in_test.rb +52 -0
  144. data/test/cases/arel/nodes/infix_operation_test.rb +1 -1
  145. data/test/cases/arel/nodes/node_test.rb +1 -1
  146. data/test/cases/arel/nodes/or_test.rb +2 -2
  147. data/test/cases/arel/nodes/sql_literal_test.rb +18 -1
  148. data/test/cases/arel/nodes/table_alias_test.rb +12 -0
  149. data/test/cases/arel/nodes/unary_operation_test.rb +1 -1
  150. data/test/cases/arel/nodes/update_statement_test.rb +4 -0
  151. data/test/cases/arel/nodes_test.rb +3 -2
  152. data/test/cases/arel/select_manager_test.rb +12 -12
  153. data/test/cases/arel/support/fake_record.rb +22 -17
  154. data/test/cases/arel/table_test.rb +15 -25
  155. data/test/cases/arel/update_manager_test.rb +51 -6
  156. data/test/cases/arel/visitors/dispatch_contamination_test.rb +1 -1
  157. data/test/cases/arel/visitors/dot_test.rb +177 -2
  158. data/test/cases/arel/visitors/mysql_test.rb +49 -1
  159. data/test/cases/arel/visitors/postgres_test.rb +1 -31
  160. data/test/cases/arel/visitors/sqlite_test.rb +1 -1
  161. data/test/cases/arel/visitors/to_sql_test.rb +330 -20
  162. data/test/cases/assertions/query_assertions_test.rb +136 -0
  163. data/test/cases/associations/belongs_to_associations_test.rb +502 -41
  164. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +1 -1
  165. data/test/cases/associations/cascaded_eager_loading_test.rb +26 -15
  166. data/test/cases/associations/eager_load_nested_include_test.rb +1 -1
  167. data/test/cases/associations/eager_singularization_test.rb +1 -1
  168. data/test/cases/associations/eager_test.rb +255 -93
  169. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +25 -53
  170. data/test/cases/associations/has_many_associations_test.rb +282 -72
  171. data/test/cases/associations/has_many_through_associations_test.rb +172 -45
  172. data/test/cases/associations/has_many_through_disable_joins_associations_test.rb +197 -0
  173. data/test/cases/associations/has_one_associations_test.rb +160 -29
  174. data/test/cases/associations/has_one_through_associations_test.rb +64 -15
  175. data/test/cases/associations/has_one_through_disable_joins_associations_test.rb +82 -0
  176. data/test/cases/associations/inner_join_association_test.rb +36 -6
  177. data/test/cases/associations/inverse_associations_test.rb +177 -40
  178. data/test/cases/associations/join_model_test.rb +17 -12
  179. data/test/cases/associations/left_outer_join_association_test.rb +14 -3
  180. data/test/cases/associations/nested_error_test.rb +116 -0
  181. data/test/cases/associations/nested_through_associations_test.rb +54 -19
  182. data/test/cases/associations/required_test.rb +1 -1
  183. data/test/cases/associations_test.rb +1278 -21
  184. data/test/cases/asynchronous_queries_test.rb +310 -0
  185. data/test/cases/attribute_methods/read_test.rb +6 -0
  186. data/test/cases/attribute_methods/time_zone_converter_test.rb +21 -0
  187. data/test/cases/attribute_methods_test.rb +565 -46
  188. data/test/cases/attributes_test.rb +42 -1
  189. data/test/cases/autosave_association_test.rb +645 -92
  190. data/test/cases/base_prevent_writes_test.rb +28 -159
  191. data/test/cases/base_test.rb +434 -209
  192. data/test/cases/batches_test.rb +441 -57
  193. data/test/cases/binary_test.rb +31 -0
  194. data/test/cases/bind_parameter_test.rb +107 -16
  195. data/test/cases/cache_key_test.rb +7 -7
  196. data/test/cases/calculations_test.rb +541 -110
  197. data/test/cases/callbacks_test.rb +0 -1
  198. data/test/cases/clone_test.rb +5 -4
  199. data/test/cases/coders/yaml_column_test.rb +97 -2
  200. data/test/cases/collection_cache_key_test.rb +24 -16
  201. data/test/cases/column_alias_test.rb +2 -8
  202. data/test/cases/column_definition_test.rb +12 -3
  203. data/test/cases/comment_test.rb +23 -26
  204. data/test/cases/connection_adapters/adapter_leasing_test.rb +9 -9
  205. data/test/cases/connection_adapters/connection_handler_test.rb +145 -99
  206. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +79 -55
  207. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +17 -20
  208. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +146 -55
  209. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +136 -23
  210. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +96 -27
  211. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -5
  212. data/test/cases/connection_adapters/registration_test.rb +98 -0
  213. data/test/cases/connection_adapters/schema_cache_test.rb +288 -135
  214. data/test/cases/connection_adapters/standalone_connection_test.rb +38 -0
  215. data/test/cases/connection_adapters/statement_pool_test.rb +29 -0
  216. data/test/cases/connection_adapters/type_lookup_test.rb +12 -24
  217. data/test/cases/connection_handling_test.rb +210 -0
  218. data/test/cases/connection_management_test.rb +44 -7
  219. data/test/cases/connection_pool_test.rb +466 -99
  220. data/test/cases/core_test.rb +167 -9
  221. data/test/cases/counter_cache_test.rb +129 -2
  222. data/test/cases/custom_locking_test.rb +3 -3
  223. data/test/cases/database_configurations/hash_config_test.rb +149 -13
  224. data/test/cases/database_configurations/resolver_test.rb +14 -10
  225. data/test/cases/database_configurations/url_config_test.rb +53 -0
  226. data/test/cases/database_configurations_test.rb +86 -43
  227. data/test/cases/database_selector_test.rb +30 -8
  228. data/test/cases/database_statements_test.rb +10 -14
  229. data/test/cases/date_time_precision_test.rb +141 -11
  230. data/test/cases/date_time_test.rb +19 -1
  231. data/test/cases/defaults_test.rb +107 -41
  232. data/test/cases/delegated_type_test.rb +69 -9
  233. data/test/cases/dirty_test.rb +82 -25
  234. data/test/cases/disconnected_test.rb +10 -9
  235. data/test/cases/dup_test.rb +26 -6
  236. data/test/cases/encryption/cipher/aes256_gcm_test.rb +50 -0
  237. data/test/cases/encryption/cipher_test.rb +65 -0
  238. data/test/cases/encryption/concurrency_test.rb +27 -0
  239. data/test/cases/encryption/config_test.rb +21 -0
  240. data/test/cases/encryption/configurable_test.rb +93 -0
  241. data/test/cases/encryption/contexts_test.rb +105 -0
  242. data/test/cases/encryption/derived_secret_key_provider_test.rb +31 -0
  243. data/test/cases/encryption/deterministic_key_provider_test.rb +11 -0
  244. data/test/cases/encryption/encryptable_record_api_test.rb +175 -0
  245. data/test/cases/encryption/encryptable_record_message_pack_serialized_test.rb +42 -0
  246. data/test/cases/encryption/encryptable_record_test.rb +470 -0
  247. data/test/cases/encryption/encrypted_fixtures_test.rb +22 -0
  248. data/test/cases/encryption/encrypting_only_encryptor_test.rb +20 -0
  249. data/test/cases/encryption/encryption_schemes_test.rb +240 -0
  250. data/test/cases/encryption/encryptor_test.rb +113 -0
  251. data/test/cases/encryption/envelope_encryption_key_provider_test.rb +49 -0
  252. data/test/cases/encryption/extended_deterministic_queries_test.rb +81 -0
  253. data/test/cases/encryption/helper.rb +152 -0
  254. data/test/cases/encryption/key_generator_test.rb +55 -0
  255. data/test/cases/encryption/key_provider_test.rb +57 -0
  256. data/test/cases/encryption/key_test.rb +17 -0
  257. data/test/cases/encryption/message_pack_message_serializer_test.rb +70 -0
  258. data/test/cases/encryption/message_serializer_test.rb +82 -0
  259. data/test/cases/encryption/message_test.rb +43 -0
  260. data/test/cases/encryption/null_encryptor_test.rb +21 -0
  261. data/test/cases/encryption/properties_test.rb +69 -0
  262. data/test/cases/encryption/read_only_null_encryptor_test.rb +19 -0
  263. data/test/cases/encryption/scheme_test.rb +58 -0
  264. data/test/cases/encryption/unencrypted_attributes_test.rb +27 -0
  265. data/test/cases/encryption/uniqueness_validations_test.rb +65 -0
  266. data/test/cases/enum_test.rb +374 -72
  267. data/test/cases/errors_test.rb +7 -4
  268. data/test/cases/excluding_test.rb +116 -0
  269. data/test/cases/explain_subscriber_test.rb +6 -1
  270. data/test/cases/explain_test.rb +119 -10
  271. data/test/cases/filter_attributes_test.rb +7 -14
  272. data/test/cases/finder_respond_to_test.rb +3 -3
  273. data/test/cases/finder_test.rb +357 -72
  274. data/test/cases/fixture_set/file_test.rb +9 -0
  275. data/test/cases/fixtures_test.rb +426 -190
  276. data/test/cases/helper.rb +66 -192
  277. data/test/cases/hot_compatibility_test.rb +10 -10
  278. data/test/cases/inheritance_test.rb +51 -61
  279. data/test/cases/inherited_test.rb +40 -0
  280. data/test/cases/insert_all_test.rb +419 -9
  281. data/test/cases/instrumentation_test.rb +202 -30
  282. data/test/cases/integration_test.rb +25 -7
  283. data/test/cases/invalid_connection_test.rb +5 -5
  284. data/test/cases/invertible_migration_test.rb +108 -24
  285. data/test/cases/json_attribute_test.rb +1 -0
  286. data/test/cases/json_serialization_test.rb +5 -5
  287. data/test/cases/json_shared_test_cases.rb +5 -9
  288. data/test/cases/locking_test.rb +67 -31
  289. data/test/cases/log_subscriber_test.rb +17 -15
  290. data/test/cases/marshal_serialization_test.rb +78 -5
  291. data/test/cases/message_pack_test.rb +91 -0
  292. data/test/cases/migration/change_schema_test.rb +77 -46
  293. data/test/cases/migration/change_table_test.rb +129 -114
  294. data/test/cases/migration/check_constraint_test.rb +192 -10
  295. data/test/cases/migration/column_attributes_test.rb +4 -9
  296. data/test/cases/migration/column_positioning_test.rb +2 -2
  297. data/test/cases/migration/columns_test.rb +118 -4
  298. data/test/cases/migration/command_recorder_test.rb +181 -14
  299. data/test/cases/migration/compatibility_test.rb +883 -196
  300. data/test/cases/migration/create_join_table_test.rb +8 -1
  301. data/test/cases/migration/exclusion_constraint_test.rb +192 -0
  302. data/test/cases/migration/foreign_key_test.rb +356 -14
  303. data/test/cases/migration/helper.rb +4 -1
  304. data/test/cases/migration/index_test.rb +67 -2
  305. data/test/cases/migration/invalid_options_test.rb +129 -0
  306. data/test/cases/migration/logger_test.rb +7 -4
  307. data/test/cases/migration/pending_migrations_test.rb +103 -60
  308. data/test/cases/migration/references_foreign_key_test.rb +73 -4
  309. data/test/cases/migration/references_index_test.rb +25 -27
  310. data/test/cases/migration/references_statements_test.rb +27 -3
  311. data/test/cases/migration/rename_table_test.rb +39 -54
  312. data/test/cases/migration/schema_definitions_test.rb +109 -0
  313. data/test/cases/migration/unique_constraint_test.rb +248 -0
  314. data/test/cases/migration_test.rb +677 -220
  315. data/test/cases/migrator_test.rb +102 -75
  316. data/test/cases/multi_db_migrator_test.rb +55 -34
  317. data/test/cases/multiparameter_attributes_test.rb +26 -29
  318. data/test/cases/multiple_db_test.rb +42 -19
  319. data/test/cases/nested_attributes_test.rb +124 -6
  320. data/test/cases/nested_attributes_with_callbacks_test.rb +2 -2
  321. data/test/cases/normalized_attribute_test.rb +117 -0
  322. data/test/cases/null_relation_test.rb +35 -2
  323. data/test/cases/persistence/reload_association_cache_test.rb +20 -0
  324. data/test/cases/persistence_test.rb +629 -22
  325. data/test/cases/pooled_connections_test.rb +57 -56
  326. data/test/cases/prepared_statement_status_test.rb +8 -3
  327. data/test/cases/primary_class_test.rb +134 -0
  328. data/test/cases/primary_keys_test.rb +171 -55
  329. data/test/cases/query_cache_test.rb +558 -263
  330. data/test/cases/query_logs_test.rb +293 -0
  331. data/test/cases/quoting_test.rb +39 -72
  332. data/test/cases/readonly_test.rb +50 -12
  333. data/test/cases/reaper_test.rb +22 -6
  334. data/test/cases/reflection_test.rb +207 -9
  335. data/test/cases/relation/and_test.rb +43 -0
  336. data/test/cases/relation/delegation_test.rb +32 -5
  337. data/test/cases/relation/delete_all_test.rb +27 -6
  338. data/test/cases/relation/field_ordered_values_test.rb +128 -0
  339. data/test/cases/relation/load_async_test.rb +650 -0
  340. data/test/cases/relation/merging_test.rb +80 -109
  341. data/test/cases/relation/mutation_test.rb +12 -7
  342. data/test/cases/relation/or_test.rb +11 -8
  343. data/test/cases/relation/order_test.rb +90 -0
  344. data/test/cases/relation/predicate_builder_test.rb +21 -6
  345. data/test/cases/relation/select_test.rb +162 -3
  346. data/test/cases/relation/structural_compatibility_test.rb +38 -0
  347. data/test/cases/relation/update_all_test.rb +81 -27
  348. data/test/cases/relation/where_chain_test.rb +190 -3
  349. data/test/cases/relation/where_clause_test.rb +43 -1
  350. data/test/cases/relation/where_test.rb +95 -7
  351. data/test/cases/relation/with_test.rb +165 -0
  352. data/test/cases/relation_test.rb +42 -37
  353. data/test/cases/relations_test.rb +436 -138
  354. data/test/cases/reload_models_test.rb +18 -14
  355. data/test/cases/reserved_word_test.rb +2 -1
  356. data/test/cases/result_test.rb +14 -22
  357. data/test/cases/sanitize_test.rb +89 -27
  358. data/test/cases/schema_dumper_test.rb +535 -62
  359. data/test/cases/scoping/default_scoping_test.rb +219 -35
  360. data/test/cases/scoping/named_scoping_test.rb +25 -46
  361. data/test/cases/scoping/relation_scoping_test.rb +112 -4
  362. data/test/cases/secure_password_test.rb +108 -0
  363. data/test/cases/secure_token_test.rb +72 -0
  364. data/test/cases/serialization_test.rb +1 -1
  365. data/test/cases/serialized_attribute_test.rb +305 -60
  366. data/test/cases/shard_keys_test.rb +125 -0
  367. data/test/cases/shard_selector_test.rb +45 -0
  368. data/test/cases/signed_id_test.rb +57 -5
  369. data/test/cases/statement_cache_test.rb +31 -30
  370. data/test/cases/statement_invalid_test.rb +8 -4
  371. data/test/cases/store_test.rb +73 -9
  372. data/test/cases/strict_loading_test.rb +327 -13
  373. data/test/cases/table_metadata_test.rb +16 -0
  374. data/test/cases/tasks/database_tasks_test.rb +517 -244
  375. data/test/cases/test_case.rb +254 -60
  376. data/test/cases/test_case_test.rb +69 -0
  377. data/test/cases/test_databases_test.rb +7 -3
  378. data/test/cases/test_fixtures_test.rb +19 -40
  379. data/test/cases/time_precision_test.rb +17 -5
  380. data/test/cases/timestamp_test.rb +124 -16
  381. data/test/cases/token_for_test.rb +165 -0
  382. data/test/cases/touch_later_test.rb +43 -1
  383. data/test/cases/transaction_callbacks_test.rb +325 -8
  384. data/test/cases/transaction_instrumentation_test.rb +453 -0
  385. data/test/cases/transaction_isolation_test.rb +12 -8
  386. data/test/cases/transactions_test.rb +629 -112
  387. data/test/cases/type/date_time_test.rb +7 -1
  388. data/test/cases/type/time_test.rb +9 -0
  389. data/test/cases/type/type_map_test.rb +108 -73
  390. data/test/cases/type/unsigned_integer_test.rb +12 -0
  391. data/test/cases/type_caster/connection_test.rb +19 -0
  392. data/test/cases/type_test.rb +1 -1
  393. data/test/cases/unconnected_test.rb +7 -7
  394. data/test/cases/unsafe_raw_sql_test.rb +39 -8
  395. data/test/cases/validations/absence_validation_test.rb +1 -1
  396. data/test/cases/validations/association_validation_test.rb +25 -3
  397. data/test/cases/validations/numericality_validation_test.rb +3 -9
  398. data/test/cases/validations/presence_validation_test.rb +1 -1
  399. data/test/cases/validations/uniqueness_validation_test.rb +280 -40
  400. data/test/cases/validations_test.rb +2 -2
  401. data/test/cases/view_test.rb +33 -22
  402. data/test/cases/yaml_serialization_test.rb +23 -17
  403. data/test/config.example.yml +58 -56
  404. data/test/config.rb +1 -0
  405. data/test/fixtures/1_need_quoting.yml +2 -0
  406. data/test/fixtures/accounts.yml +5 -0
  407. data/test/fixtures/aircrafts.yml +7 -0
  408. data/test/fixtures/book_identifiers.yml +11 -0
  409. data/test/fixtures/books.yml +5 -4
  410. data/test/fixtures/cake_designers.yml +5 -0
  411. data/test/fixtures/cars.yml +6 -0
  412. data/test/fixtures/chefs.yml +5 -0
  413. data/test/fixtures/clothing_items.yml +23 -0
  414. data/test/fixtures/clubs.yml +1 -1
  415. data/test/fixtures/comments.yml +2 -1
  416. data/test/fixtures/cpk_authors.yml +8 -0
  417. data/test/fixtures/cpk_books.yml +21 -0
  418. data/test/fixtures/cpk_order_agreements.yml +13 -0
  419. data/test/fixtures/cpk_order_tags.yml +15 -0
  420. data/test/fixtures/cpk_orders.yml +11 -0
  421. data/test/fixtures/cpk_posts.yml +12 -0
  422. data/test/fixtures/cpk_reviews.yml +13 -0
  423. data/test/fixtures/cpk_tags.yml +11 -0
  424. data/test/fixtures/drink_designers.yml +5 -0
  425. data/test/fixtures/encrypted_book_that_ignores_cases.yml +4 -0
  426. data/test/fixtures/encrypted_books.yml +4 -0
  427. data/test/fixtures/fk_object_to_point_to.yml +2 -0
  428. data/test/fixtures/memberships.yml +15 -15
  429. data/test/fixtures/paragraphs.yml +5 -0
  430. data/test/fixtures/parrots.yml +4 -0
  431. data/test/fixtures/people.yml +2 -0
  432. data/test/fixtures/pirates.yml +2 -2
  433. data/test/fixtures/primary_key_error/primary_key_error.yml +6 -0
  434. data/test/fixtures/references.yml +3 -3
  435. data/test/fixtures/sharded_blog_posts.yml +14 -0
  436. data/test/fixtures/sharded_blog_posts_tags.yml +27 -0
  437. data/test/fixtures/sharded_blogs.yml +8 -0
  438. data/test/fixtures/sharded_comments.yml +22 -0
  439. data/test/fixtures/sharded_tags.yml +34 -0
  440. data/test/fixtures/sponsors.yml +2 -2
  441. data/test/fixtures/topics.yml +1 -0
  442. data/test/fixtures/treasures.yml +4 -0
  443. data/test/fixtures/virtual_columns.yml +5 -0
  444. data/test/fixtures/warehouse_things.yml +1 -1
  445. data/test/migrations/old_and_new_versions/20210716122844_add_people_description.rb +5 -0
  446. data/test/migrations/old_and_new_versions/20210716123013_add_people_number_of_legs.rb +5 -0
  447. data/test/migrations/old_and_new_versions/230_add_people_hobby.rb +5 -0
  448. data/test/migrations/old_and_new_versions/231_add_people_last_name.rb +5 -0
  449. data/test/migrations/scope/1_unscoped.rb +7 -0
  450. data/test/migrations/scope/2_mysql_only.mysql.rb +7 -0
  451. data/test/models/admin/user.rb +2 -0
  452. data/test/models/admin/user_json.rb +48 -0
  453. data/test/models/attachment.rb +7 -0
  454. data/test/models/author.rb +70 -3
  455. data/test/models/author_encrypted.rb +16 -0
  456. data/test/models/bird.rb +1 -1
  457. data/test/models/book.rb +18 -11
  458. data/test/models/book_destroy_async.rb +1 -1
  459. data/test/models/book_encrypted.rb +106 -0
  460. data/test/models/book_identifier.rb +5 -0
  461. data/test/models/branch.rb +11 -0
  462. data/test/models/bulb.rb +1 -1
  463. data/test/models/car.rb +8 -1
  464. data/test/models/cat.rb +1 -1
  465. data/test/models/category.rb +3 -1
  466. data/test/models/chat_message.rb +8 -0
  467. data/test/models/chef.rb +52 -0
  468. data/test/models/clothing_item.rb +12 -0
  469. data/test/models/club.rb +4 -1
  470. data/test/models/comment.rb +7 -4
  471. data/test/models/comment_overlapping_counter_cache.rb +15 -0
  472. data/test/models/company.rb +16 -2
  473. data/test/models/computer.rb +1 -0
  474. data/test/models/contact.rb +3 -3
  475. data/test/models/contract.rb +5 -1
  476. data/test/models/cpk/author.rb +9 -0
  477. data/test/models/cpk/book.rb +55 -0
  478. data/test/models/cpk/book_destroy_async.rb +9 -0
  479. data/test/models/cpk/car.rb +9 -0
  480. data/test/models/cpk/car_review.rb +9 -0
  481. data/test/models/cpk/chapter.rb +16 -0
  482. data/test/models/cpk/chapter_destroy_async.rb +10 -0
  483. data/test/models/cpk/comment.rb +9 -0
  484. data/test/models/cpk/order.rb +55 -0
  485. data/test/models/cpk/order_agreement.rb +10 -0
  486. data/test/models/cpk/order_tag.rb +10 -0
  487. data/test/models/cpk/post.rb +10 -0
  488. data/test/models/cpk/posts_tag.rb +10 -0
  489. data/test/models/cpk/review.rb +9 -0
  490. data/test/models/cpk/tag.rb +10 -0
  491. data/test/models/cpk.rb +15 -0
  492. data/test/models/customer.rb +3 -1
  493. data/test/models/destroy_async_parent.rb +1 -1
  494. data/test/models/developer.rb +44 -3
  495. data/test/models/discount.rb +4 -0
  496. data/test/models/drink_designer.rb +1 -0
  497. data/test/models/editor.rb +8 -0
  498. data/test/models/editorship.rb +6 -0
  499. data/test/models/entry.rb +5 -0
  500. data/test/models/essay.rb +6 -1
  501. data/test/models/essay_destroy_async.rb +1 -0
  502. data/test/models/eye.rb +87 -21
  503. data/test/models/face.rb +1 -1
  504. data/test/models/friendship.rb +3 -0
  505. data/test/models/hardback.rb +7 -0
  506. data/test/models/hotel.rb +2 -0
  507. data/test/models/human.rb +2 -2
  508. data/test/models/invoice.rb +2 -1
  509. data/test/models/invokes_an_undefined_method.rb +5 -0
  510. data/test/models/line_item.rb +6 -0
  511. data/test/models/member.rb +9 -4
  512. data/test/models/membership.rb +2 -2
  513. data/test/models/message.rb +2 -1
  514. data/test/models/need_quoting.rb +5 -0
  515. data/test/models/paragraph.rb +5 -0
  516. data/test/models/parrot.rb +6 -3
  517. data/test/models/person.rb +7 -4
  518. data/test/models/pirate.rb +4 -1
  519. data/test/models/pk_autopopulated_by_a_trigger_record.rb +5 -0
  520. data/test/models/post.rb +65 -2
  521. data/test/models/post_encrypted.rb +15 -0
  522. data/test/models/post_with_prefetched_pk.rb +15 -0
  523. data/test/models/project.rb +1 -0
  524. data/test/models/publication.rb +16 -0
  525. data/test/models/raises_argument_error.rb +5 -0
  526. data/test/models/raises_no_method_error.rb +5 -0
  527. data/test/models/recipient.rb +5 -0
  528. data/test/models/reference.rb +1 -1
  529. data/test/models/reply.rb +1 -1
  530. data/test/models/room.rb +3 -0
  531. data/test/models/sharded/blog.rb +12 -0
  532. data/test/models/sharded/blog_post.rb +17 -0
  533. data/test/models/sharded/blog_post_destroy_async.rb +14 -0
  534. data/test/models/sharded/blog_post_tag.rb +11 -0
  535. data/test/models/sharded/blog_post_with_revision.rb +11 -0
  536. data/test/models/sharded/comment.rb +12 -0
  537. data/test/models/sharded/comment_destroy_async.rb +12 -0
  538. data/test/models/sharded/tag.rb +11 -0
  539. data/test/models/sharded.rb +8 -0
  540. data/test/models/ship.rb +1 -1
  541. data/test/models/shipping_line.rb +11 -0
  542. data/test/models/subscriber.rb +1 -0
  543. data/test/models/subscription.rb +3 -1
  544. data/test/models/too_long_table_name.rb +5 -0
  545. data/test/models/topic.rb +3 -1
  546. data/test/models/traffic_light.rb +2 -2
  547. data/test/models/traffic_light_encrypted.rb +21 -0
  548. data/test/models/translation.rb +9 -0
  549. data/test/models/treasure.rb +1 -1
  550. data/test/models/tyre.rb +1 -1
  551. data/test/models/user.rb +16 -0
  552. data/test/models/user_with_invalid_relation.rb +28 -0
  553. data/test/models/uuid_comment.rb +5 -0
  554. data/test/models/uuid_entry.rb +5 -0
  555. data/test/models/uuid_message.rb +5 -0
  556. data/test/models/zine.rb +2 -1
  557. data/test/schema/mysql2_specific_schema.rb +26 -12
  558. data/test/schema/postgresql_specific_schema.rb +121 -13
  559. data/test/schema/schema.rb +361 -103
  560. data/test/schema/sqlite_specific_schema.rb +17 -6
  561. data/test/schema/trilogy_specific_schema.rb +96 -0
  562. data/test/support/adapter_helper.rb +104 -0
  563. data/test/support/async_helper.rb +15 -0
  564. data/test/support/config.rb +1 -1
  565. data/test/support/connection.rb +14 -2
  566. data/test/support/ddl_helper.rb +1 -1
  567. data/test/support/fake_adapter.rb +42 -0
  568. data/test/support/load_schema_helper.rb +22 -0
  569. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic.dump +0 -0
  570. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic_associations.dump +0 -0
  571. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic.dump +0 -0
  572. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic_associations.dump +0 -0
  573. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic.dump +0 -0
  574. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic_associations.dump +0 -0
  575. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic.dump +0 -0
  576. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic_associations.dump +0 -0
  577. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic.dump +0 -0
  578. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic_associations.dump +0 -0
  579. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic.dump +0 -0
  580. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic_associations.dump +0 -0
  581. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic.dump +0 -0
  582. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic_associations.dump +0 -0
  583. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic.dump +0 -0
  584. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic_associations.dump +0 -0
  585. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic.dump +0 -0
  586. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic_associations.dump +0 -0
  587. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic.dump +0 -0
  588. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic_associations.dump +0 -0
  589. data/test/support/schema_dumping_helper.rb +15 -9
  590. data/test/support/tools.rb +37 -0
  591. data/test/support/yaml_compatibility_fixtures/rails_4_1_no_symbol.yml +22 -0
  592. metadata +247 -15
@@ -12,6 +12,44 @@ class EnumTest < ActiveRecord::TestCase
12
12
  @book = books(:awdr)
13
13
  end
14
14
 
15
+ test "type.cast" do
16
+ type = Book.type_for_attribute(:status)
17
+
18
+ assert_equal "proposed", type.cast(0)
19
+ assert_equal "written", type.cast(1)
20
+ assert_equal "published", type.cast(2)
21
+
22
+ assert_equal "proposed", type.cast(:proposed)
23
+ assert_equal "written", type.cast(:written)
24
+ assert_equal "published", type.cast(:published)
25
+
26
+ assert_equal "proposed", type.cast("proposed")
27
+ assert_equal "written", type.cast("written")
28
+ assert_equal "published", type.cast("published")
29
+
30
+ assert_equal :unknown, type.cast(:unknown)
31
+ assert_equal "unknown", type.cast("unknown")
32
+ end
33
+
34
+ test "type.serialize" do
35
+ type = Book.type_for_attribute(:status)
36
+
37
+ assert_equal 0, type.serialize(0)
38
+ assert_equal 1, type.serialize(1)
39
+ assert_equal 2, type.serialize(2)
40
+
41
+ assert_equal 0, type.serialize(:proposed)
42
+ assert_equal 1, type.serialize(:written)
43
+ assert_equal 2, type.serialize(:published)
44
+
45
+ assert_equal 0, type.serialize("proposed")
46
+ assert_equal 1, type.serialize("written")
47
+ assert_equal 2, type.serialize("published")
48
+
49
+ assert_nil type.serialize(:unknown)
50
+ assert_nil type.serialize("unknown")
51
+ end
52
+
15
53
  test "query state by predicate" do
16
54
  assert_predicate @book, :published?
17
55
  assert_not_predicate @book, :written?
@@ -32,6 +70,7 @@ class EnumTest < ActiveRecord::TestCase
32
70
  assert_equal "visible", @book.author_visibility
33
71
  assert_equal "visible", @book.illustrator_visibility
34
72
  assert_equal "medium", @book.difficulty
73
+ assert_equal "soft", @book.cover
35
74
  end
36
75
 
37
76
  test "find via scope" do
@@ -70,6 +109,7 @@ class EnumTest < ActiveRecord::TestCase
70
109
  assert_not_equal @book, Book.where(status: [written, written]).first
71
110
  assert_not_equal @book, Book.where.not(status: published).first
72
111
  assert_equal @book, Book.where.not(status: written).first
112
+ assert_equal @book, Book.where(cover: Book.covers[:soft]).first
73
113
  end
74
114
 
75
115
  test "find via where with symbols" do
@@ -80,6 +120,9 @@ class EnumTest < ActiveRecord::TestCase
80
120
  assert_not_equal @book, Book.where.not(status: :published).first
81
121
  assert_equal @book, Book.where.not(status: :written).first
82
122
  assert_equal books(:ddd), Book.where(last_read: :forgotten).first
123
+ assert_nil Book.where(status: :prohibited).first
124
+ assert_equal @book, Book.where(cover: :soft).first
125
+ assert_equal @book, Book.where.not(cover: :hard).first
83
126
  end
84
127
 
85
128
  test "find via where with strings" do
@@ -90,11 +133,31 @@ class EnumTest < ActiveRecord::TestCase
90
133
  assert_not_equal @book, Book.where.not(status: "published").first
91
134
  assert_equal @book, Book.where.not(status: "written").first
92
135
  assert_equal books(:ddd), Book.where(last_read: "forgotten").first
136
+ assert_nil Book.where(status: "prohibited").first
137
+ end
138
+
139
+ test "find via where with large number" do
140
+ assert_equal @book, Book.where(status: [2, 9223372036854775808]).first
141
+ assert_equal @book, Book.where(status: ["2", "9223372036854775808"]).first
142
+ assert_equal @book, Book.where(status: 2..9223372036854775808).first
143
+ assert_equal @book, Book.where(status: "2".."9223372036854775808").first
144
+ end
145
+
146
+ test "find via where should be type casted" do
147
+ book = Book.enabled.create!
148
+ assert_predicate book, :enabled?
149
+
150
+ enabled = Book.boolean_statuses[:enabled].to_s
151
+ assert_equal book, Book.where(boolean_status: enabled).last
152
+ assert_equal @book, Book.where(cover: "soft").first
153
+ assert_equal @book, Book.where.not(cover: "hard").first
93
154
  end
94
155
 
95
156
  test "build from scope" do
96
157
  assert_predicate Book.written.build, :written?
97
158
  assert_not_predicate Book.written.build, :proposed?
159
+ assert_predicate PublishedBook.hard.build, :hard?
160
+ assert_not_predicate PublishedBook.hard.build, :soft?
98
161
  end
99
162
 
100
163
  test "build from where" do
@@ -113,11 +176,15 @@ class EnumTest < ActiveRecord::TestCase
113
176
  assert_predicate @book, :in_english?
114
177
  @book.author_visibility_visible!
115
178
  assert_predicate @book, :author_visibility_visible?
179
+ @book.hard!
180
+ assert_predicate @book, :hard?
116
181
  end
117
182
 
118
183
  test "update by setter" do
119
184
  @book.update! status: :written
120
185
  assert_predicate @book, :written?
186
+ @book.update! cover: :hard
187
+ assert_predicate @book, :hard?
121
188
  end
122
189
 
123
190
  test "enum methods are overwritable" do
@@ -128,11 +195,15 @@ class EnumTest < ActiveRecord::TestCase
128
195
  test "direct assignment" do
129
196
  @book.status = :written
130
197
  assert_predicate @book, :written?
198
+ @book.cover = :hard
199
+ assert_predicate @book, :hard?
131
200
  end
132
201
 
133
202
  test "assign string value" do
134
203
  @book.status = "written"
135
204
  assert_predicate @book, :written?
205
+ @book.cover = "hard"
206
+ assert_predicate @book, :hard?
136
207
  end
137
208
 
138
209
  test "enum changed attributes" do
@@ -242,6 +313,44 @@ class EnumTest < ActiveRecord::TestCase
242
313
  assert_equal "'unknown' is not a valid status", e.message
243
314
  end
244
315
 
316
+ test "validation with 'validate: true' option" do
317
+ klass = Class.new(ActiveRecord::Base) do
318
+ def self.name; "Book"; end
319
+ enum :status, [:proposed, :written], validate: true
320
+ end
321
+
322
+ valid_book = klass.new(status: "proposed")
323
+ assert_predicate valid_book, :valid?
324
+
325
+ valid_book = klass.new(status: "written")
326
+ assert_predicate valid_book, :valid?
327
+
328
+ invalid_book = klass.new(status: nil)
329
+ assert_not_predicate invalid_book, :valid?
330
+
331
+ invalid_book = klass.new(status: "unknown")
332
+ assert_not_predicate invalid_book, :valid?
333
+ end
334
+
335
+ test "validation with 'validate: hash' option" do
336
+ klass = Class.new(ActiveRecord::Base) do
337
+ def self.name; "Book"; end
338
+ enum :status, [:proposed, :written], validate: { allow_nil: true }
339
+ end
340
+
341
+ valid_book = klass.new(status: "proposed")
342
+ assert_predicate valid_book, :valid?
343
+
344
+ valid_book = klass.new(status: "written")
345
+ assert_predicate valid_book, :valid?
346
+
347
+ valid_book = klass.new(status: nil)
348
+ assert_predicate valid_book, :valid?
349
+
350
+ invalid_book = klass.new(status: "unknown")
351
+ assert_not_predicate invalid_book, :valid?
352
+ end
353
+
245
354
  test "NULL values from database should be casted to nil" do
246
355
  Book.where(id: @book.id).update_all("status = NULL")
247
356
  assert_nil @book.reload.status
@@ -295,6 +404,7 @@ class EnumTest < ActiveRecord::TestCase
295
404
  end
296
405
 
297
406
  test "creating new objects with enum scopes" do
407
+ skip "IBM_DB/DB2: composite UNIQUE index on (author_id, name) treats multiple all-NULL rows as duplicates (SQL0803N); creating several Books without author/name fails" if current_adapter?(:IBM_DBAdapter)
298
408
  assert_predicate Book.written.create, :written?
299
409
  assert_predicate Book.read.create, :read?
300
410
  assert_predicate Book.in_spanish.create, :in_spanish?
@@ -321,39 +431,83 @@ class EnumTest < ActiveRecord::TestCase
321
431
  assert_equal "published", @book.status
322
432
  end
323
433
 
434
+ test "attributes_for_database" do
435
+ assert_equal 2, @book.attributes_for_database["status"]
436
+
437
+ @book.status = "published"
438
+
439
+ assert_equal 2, @book.attributes_for_database["status"]
440
+ end
441
+
324
442
  test "invalid definition values raise an ArgumentError" do
325
443
  e = assert_raises(ArgumentError) do
326
444
  Class.new(ActiveRecord::Base) do
327
445
  self.table_name = "books"
328
- enum status: [proposed: 1, written: 2, published: 3]
446
+ enum :status
447
+ end
448
+ end
449
+
450
+ assert_match(/must not be empty\.$/, e.message)
451
+
452
+ e = assert_raises(ArgumentError) do
453
+ Class.new(ActiveRecord::Base) do
454
+ self.table_name = "books"
455
+ enum(:status, {}, **{})
456
+ end
457
+ end
458
+
459
+ assert_match(/must not be empty\.$/, e.message)
460
+
461
+ e = assert_raises(ArgumentError) do
462
+ Class.new(ActiveRecord::Base) do
463
+ self.table_name = "books"
464
+ enum :status, []
465
+ end
466
+ end
467
+
468
+ assert_match(/must not be empty\.$/, e.message)
469
+
470
+ e = assert_raises(ArgumentError) do
471
+ Class.new(ActiveRecord::Base) do
472
+ self.table_name = "books"
473
+ enum :status, [proposed: 1, written: 2, published: 3]
474
+ end
475
+ end
476
+
477
+ assert_match(/must only contain symbols or strings\.$/, e.message)
478
+
479
+ e = assert_raises(ArgumentError) do
480
+ Class.new(ActiveRecord::Base) do
481
+ self.table_name = "books"
482
+ enum :status, { "" => 1, "active" => 2 }
329
483
  end
330
484
  end
331
485
 
332
- assert_match(/must be either a hash, an array of symbols, or an array of strings./, e.message)
486
+ assert_match(/must not contain a blank name\.$/, e.message)
333
487
 
334
488
  e = assert_raises(ArgumentError) do
335
489
  Class.new(ActiveRecord::Base) do
336
490
  self.table_name = "books"
337
- enum status: { "" => 1, "active" => 2 }
491
+ enum :status, ["active", ""]
338
492
  end
339
493
  end
340
494
 
341
- assert_match(/Enum label name must not be blank/, e.message)
495
+ assert_match(/must not contain a blank name\.$/, e.message)
342
496
 
343
497
  e = assert_raises(ArgumentError) do
344
498
  Class.new(ActiveRecord::Base) do
345
499
  self.table_name = "books"
346
- enum status: ["active", ""]
500
+ enum :status, Object.new
347
501
  end
348
502
  end
349
503
 
350
- assert_match(/Enum label name must not be blank/, e.message)
504
+ assert_match(/must be either a non-empty hash or an array\.$/, e.message)
351
505
  end
352
506
 
353
507
  test "reserved enum names" do
354
508
  klass = Class.new(ActiveRecord::Base) do
355
509
  self.table_name = "books"
356
- enum status: [:proposed, :written, :published]
510
+ enum :status, [:proposed, :written, :published]
357
511
  end
358
512
 
359
513
  conflicts = [
@@ -364,16 +518,16 @@ class EnumTest < ActiveRecord::TestCase
364
518
 
365
519
  conflicts.each_with_index do |name, i|
366
520
  e = assert_raises(ArgumentError) do
367
- klass.class_eval { enum name => ["value_#{i}"] }
521
+ klass.class_eval { enum name, ["value_#{i}"] }
368
522
  end
369
- assert_match(/You tried to define an enum named \"#{name}\" on the model/, e.message)
523
+ assert_match(/You tried to define an enum named "#{name}" on the model/, e.message)
370
524
  end
371
525
  end
372
526
 
373
527
  test "reserved enum values" do
374
528
  klass = Class.new(ActiveRecord::Base) do
375
529
  self.table_name = "books"
376
- enum status: [:proposed, :written, :published]
530
+ enum :status, [:proposed, :written, :published]
377
531
  end
378
532
 
379
533
  conflicts = [
@@ -382,17 +536,28 @@ class EnumTest < ActiveRecord::TestCase
382
536
  :save, # generates #save!, which conflicts with an AR method
383
537
  :proposed, # same value as an existing enum
384
538
  :public, :private, :protected, # some important methods on Module and Class
385
- :name, :parent, :superclass
539
+ :name, :superclass,
540
+ :id # conflicts with AR querying
386
541
  ]
387
542
 
388
543
  conflicts.each_with_index do |value, i|
389
544
  e = assert_raises(ArgumentError, "enum value `#{value}` should not be allowed") do
390
- klass.class_eval { enum "status_#{i}" => [value] }
545
+ klass.class_eval { enum "status_#{i}", [value] }
391
546
  end
392
547
  assert_match(/You tried to define an enum named .* on the model/, e.message)
393
548
  end
394
549
  end
395
550
 
551
+ test "can use id as a value with a prefix or suffix" do
552
+ assert_nothing_raised do
553
+ Class.new(ActiveRecord::Base) do
554
+ self.table_name = "books"
555
+ enum :status_1, [:id], prefix: true
556
+ enum :status_2, [:id], suffix: true
557
+ end
558
+ end
559
+ end
560
+
396
561
  test "reserved enum values for relation" do
397
562
  relation_method_samples = [
398
563
  :records,
@@ -404,7 +569,7 @@ class EnumTest < ActiveRecord::TestCase
404
569
  e = assert_raises(ArgumentError, "enum value `#{value}` should not be allowed") do
405
570
  Class.new(ActiveRecord::Base) do
406
571
  self.table_name = "books"
407
- enum category: [:other, value]
572
+ enum :category, [:other, value]
408
573
  end
409
574
  end
410
575
  assert_match(/You tried to define an enum named .* on the model/, e.message)
@@ -421,7 +586,7 @@ class EnumTest < ActiveRecord::TestCase
421
586
  "do publish work..."
422
587
  end
423
588
 
424
- enum status: [:proposed, :written, :published]
589
+ enum :status, [:proposed, :written, :published]
425
590
 
426
591
  def written!
427
592
  super
@@ -434,7 +599,7 @@ class EnumTest < ActiveRecord::TestCase
434
599
  test "validate uniqueness" do
435
600
  klass = Class.new(ActiveRecord::Base) do
436
601
  def self.name; "Book"; end
437
- enum status: [:proposed, :written]
602
+ enum :status, [:proposed, :written]
438
603
  validates_uniqueness_of :status
439
604
  end
440
605
  klass.delete_all
@@ -448,10 +613,9 @@ class EnumTest < ActiveRecord::TestCase
448
613
  test "validate inclusion of value in array" do
449
614
  klass = Class.new(ActiveRecord::Base) do
450
615
  def self.name; "Book"; end
451
- enum status: [:proposed, :written]
616
+ enum :status, [:proposed, :written]
452
617
  validates_inclusion_of :status, in: ["written"]
453
618
  end
454
- klass.delete_all
455
619
  invalid_book = klass.new(status: "proposed")
456
620
  assert_not_predicate invalid_book, :valid?
457
621
  valid_book = klass.new(status: "written")
@@ -459,14 +623,15 @@ class EnumTest < ActiveRecord::TestCase
459
623
  end
460
624
 
461
625
  test "enums are distinct per class" do
626
+ skip "IBM_DB/DB2: composite UNIQUE index on (author_id, name) treats multiple all-NULL rows as duplicates (SQL0803N); creating several Books without author/name fails" if current_adapter?(:IBM_DBAdapter)
462
627
  klass1 = Class.new(ActiveRecord::Base) do
463
628
  self.table_name = "books"
464
- enum status: [:proposed, :written]
629
+ enum :status, [:proposed, :written]
465
630
  end
466
631
 
467
632
  klass2 = Class.new(ActiveRecord::Base) do
468
633
  self.table_name = "books"
469
- enum status: [:drafted, :uploaded]
634
+ enum :status, [:drafted, :uploaded]
470
635
  end
471
636
 
472
637
  book1 = klass1.proposed.create!
@@ -479,10 +644,11 @@ class EnumTest < ActiveRecord::TestCase
479
644
  end
480
645
 
481
646
  test "enums are inheritable" do
647
+ skip "IBM_DB/DB2: composite UNIQUE index on (author_id, name) treats multiple all-NULL rows as duplicates (SQL0803N); creating several Books without author/name fails" if current_adapter?(:IBM_DBAdapter)
482
648
  subklass1 = Class.new(Book)
483
649
 
484
650
  subklass2 = Class.new(Book) do
485
- enum status: [:drafted, :uploaded]
651
+ enum :status, [:drafted, :uploaded]
486
652
  end
487
653
 
488
654
  book1 = subklass1.proposed.create!
@@ -508,29 +674,13 @@ class EnumTest < ActiveRecord::TestCase
508
674
  assert_match(/can't modify frozen/, e.message)
509
675
  end
510
676
 
511
- test "declare multiple enums at a time" do
677
+ test "declare multiple enums with prefix: true" do
512
678
  klass = Class.new(ActiveRecord::Base) do
513
679
  self.table_name = "books"
514
- enum status: [:proposed, :written, :published],
515
- nullable_status: [:single, :married]
516
- end
517
680
 
518
- book1 = klass.proposed.create!
519
- assert_predicate book1, :proposed?
520
-
521
- book2 = klass.single.create!
522
- assert_predicate book2, :single?
523
- end
524
-
525
- test "declare multiple enums with { _prefix: true }" do
526
- klass = Class.new(ActiveRecord::Base) do
527
- self.table_name = "books"
681
+ enum(:status, [:value_1], prefix: true)
528
682
 
529
- enum(
530
- status: [:value_1],
531
- last_read: [:value_1],
532
- _prefix: true
533
- )
683
+ enum(:last_read, [:value_1], prefix: true)
534
684
  end
535
685
 
536
686
  instance = klass.new
@@ -538,15 +688,13 @@ class EnumTest < ActiveRecord::TestCase
538
688
  assert_respond_to instance, :last_read_value_1?
539
689
  end
540
690
 
541
- test "declare multiple enums with { _suffix: true }" do
691
+ test "declare multiple enums with suffix: true" do
542
692
  klass = Class.new(ActiveRecord::Base) do
543
693
  self.table_name = "books"
544
694
 
545
- enum(
546
- status: [:value_1],
547
- last_read: [:value_1],
548
- _suffix: true
549
- )
695
+ enum(:status, [:value_1], suffix: true)
696
+
697
+ enum(:last_read, [:value_1], suffix: true)
550
698
  end
551
699
 
552
700
  instance = klass.new
@@ -558,7 +706,7 @@ class EnumTest < ActiveRecord::TestCase
558
706
  klass = Class.new(ActiveRecord::Base) do
559
707
  self.table_name = "books"
560
708
  alias_attribute :aliased_status, :status
561
- enum aliased_status: [:proposed, :written, :published]
709
+ enum :aliased_status, [:proposed, :written, :published]
562
710
  end
563
711
 
564
712
  book = klass.proposed.create!
@@ -622,8 +770,8 @@ class EnumTest < ActiveRecord::TestCase
622
770
 
623
771
  test "uses default status when no status is provided in fixtures" do
624
772
  book = books(:tlg)
625
- assert book.proposed?, "expected fixture to default to proposed status"
626
- assert book.in_english?, "expected fixture to default to english language"
773
+ assert_predicate book, :proposed?, "expected fixture to default to proposed status"
774
+ assert_predicate book, :in_english?, "expected fixture to default to english language"
627
775
  end
628
776
 
629
777
  test "uses default value from database on initialization" do
@@ -644,34 +792,137 @@ class EnumTest < ActiveRecord::TestCase
644
792
  klass = Class.new(ActiveRecord::Base) do
645
793
  self.table_name = "books"
646
794
  attribute :status, default: 2
647
- enum status: [:proposed, :written, :published]
795
+ enum :status, [:proposed, :written, :published]
648
796
  end
649
797
 
650
798
  assert_equal "published", klass.new.status
651
799
  end
652
800
 
653
- test "overloaded default" do
801
+ test "overloaded default by :default" do
654
802
  klass = Class.new(ActiveRecord::Base) do
655
803
  self.table_name = "books"
656
- enum status: [:proposed, :written, :published], _default: :published
804
+ enum :status, [:proposed, :written, :published], default: :published
657
805
  end
658
806
 
659
807
  assert_equal "published", klass.new.status
660
808
  end
661
809
 
662
- test "scopes can be disabled" do
810
+ test ":_default is invalid in the new API" do
811
+ error = assert_raises(ArgumentError) do
812
+ Class.new(ActiveRecord::Base) do
813
+ self.table_name = "books"
814
+ enum :status, [:proposed, :written, :published], _default: :published
815
+ end
816
+ end
817
+
818
+ assert_match(/invalid option\(s\): :_default/, error.message)
819
+ end
820
+
821
+ test ":_prefix is invalid in the new API" do
822
+ error = assert_raises(ArgumentError) do
823
+ Class.new(ActiveRecord::Base) do
824
+ self.table_name = "books"
825
+ enum :status, [:proposed, :written, :published], _prefix: true
826
+ end
827
+ end
828
+
829
+ assert_match(/invalid option\(s\): :_prefix/, error.message)
830
+ end
831
+
832
+ test ":_suffix is invalid in the new API" do
833
+ error = assert_raises(ArgumentError) do
834
+ Class.new(ActiveRecord::Base) do
835
+ self.table_name = "books"
836
+ enum :status, [:proposed, :written, :published], _suffix: true
837
+ end
838
+ end
839
+
840
+ assert_match(/invalid option\(s\): :_suffix/, error.message)
841
+ end
842
+
843
+ test ":_scopes is invalid in the new API" do
844
+ error = assert_raises(ArgumentError) do
845
+ Class.new(ActiveRecord::Base) do
846
+ self.table_name = "books"
847
+ enum :status, [:proposed, :written, :published], _scopes: false
848
+ end
849
+ end
850
+
851
+ assert_match(/invalid option\(s\): :_scopes/, error.message)
852
+ end
853
+
854
+ test ":_instance_methods is invalid in the new API" do
855
+ error = assert_raises(ArgumentError) do
856
+ Class.new(ActiveRecord::Base) do
857
+ self.table_name = "books"
858
+ enum :status, [:proposed, :written, :published], _instance_methods: false
859
+ end
860
+ end
861
+
862
+ assert_match(/invalid option\(s\): :_instance_methods/, error.message)
863
+ end
864
+
865
+ test "scopes can be disabled by :scopes" do
663
866
  klass = Class.new(ActiveRecord::Base) do
664
867
  self.table_name = "books"
665
- enum status: [:proposed, :written], _scopes: false
868
+ enum :status, [:proposed, :written], scopes: false
666
869
  end
667
870
 
668
871
  assert_raises(NoMethodError) { klass.proposed }
669
872
  end
670
873
 
874
+ test "query state by predicate with :prefix" do
875
+ klass = Class.new(ActiveRecord::Base) do
876
+ self.table_name = "books"
877
+ enum :status, { proposed: 0, written: 1 }, prefix: true
878
+ enum :last_read, { unread: 0, reading: 1, read: 2 }, prefix: :being
879
+ end
880
+
881
+ book = klass.new
882
+ assert_respond_to book, :status_proposed?
883
+ assert_respond_to book, :being_unread?
884
+ end
885
+
886
+ test "query state by predicate with :suffix" do
887
+ klass = Class.new(ActiveRecord::Base) do
888
+ self.table_name = "books"
889
+ enum :cover, { hard: 0, soft: 1 }, suffix: true
890
+ enum :difficulty, { easy: 0, medium: 1, hard: 2 }, suffix: :to_read
891
+ end
892
+
893
+ book = klass.new
894
+ assert_respond_to book, :hard_cover?
895
+ assert_respond_to book, :easy_to_read?
896
+ end
897
+
898
+ test "enum labels as keyword arguments" do
899
+ klass = Class.new(ActiveRecord::Base) do
900
+ self.table_name = "books"
901
+ enum :status, active: 0, archived: 1
902
+ end
903
+
904
+ book = klass.new
905
+ assert_predicate book, :active?
906
+ assert_not_predicate book, :archived?
907
+ end
908
+
909
+ test "option names can be used as label" do
910
+ klass = Class.new(ActiveRecord::Base) do
911
+ self.table_name = "books"
912
+ enum :status, default: 0, scopes: 1, prefix: 2, suffix: 3
913
+ end
914
+
915
+ book = klass.new
916
+ assert_predicate book, :default?
917
+ assert_not_predicate book, :scopes?
918
+ assert_not_predicate book, :prefix?
919
+ assert_not_predicate book, :suffix?
920
+ end
921
+
671
922
  test "scopes are named like methods" do
672
923
  klass = Class.new(ActiveRecord::Base) do
673
924
  self.table_name = "cats"
674
- enum breed: { "American Bobtail" => 0, "Balinese-Javanese" => 1 }
925
+ enum :breed, { "American Bobtail" => 0, "Balinese-Javanese" => 1 }
675
926
  end
676
927
 
677
928
  assert_respond_to klass, :American_Bobtail
@@ -679,9 +930,13 @@ class EnumTest < ActiveRecord::TestCase
679
930
  end
680
931
 
681
932
  test "capital characters for enum names" do
933
+ # IBM_DB/DB2 normalizes identifiers to UPPERCASE; the adapter downcases column
934
+ # names on read-back, so the column is returned as 'extendedwarranty'.
935
+ # Declare the enum with the lowercase name so AR can find the column.
936
+ warranty_attr = current_adapter?(:IBM_DBAdapter) ? :extendedwarranty : :extendedWarranty
682
937
  klass = Class.new(ActiveRecord::Base) do
683
938
  self.table_name = "computers"
684
- enum extendedWarranty: [:extendedSilver, :extendedGold]
939
+ enum warranty_attr, [:extendedSilver, :extendedGold]
685
940
  end
686
941
 
687
942
  computer = klass.extendedSilver.build
@@ -692,7 +947,7 @@ class EnumTest < ActiveRecord::TestCase
692
947
  test "unicode characters for enum names" do
693
948
  klass = Class.new(ActiveRecord::Base) do
694
949
  self.table_name = "books"
695
- enum language: [:πŸ‡ΊπŸ‡Έ, :πŸ‡ͺπŸ‡Έ, :πŸ‡«πŸ‡·]
950
+ enum :language, [:πŸ‡ΊπŸ‡Έ, :πŸ‡ͺπŸ‡Έ, :πŸ‡«πŸ‡·]
696
951
  end
697
952
 
698
953
  book = klass.πŸ‡ΊπŸ‡Έ.build
@@ -703,7 +958,7 @@ class EnumTest < ActiveRecord::TestCase
703
958
  test "mangling collision for enum names" do
704
959
  klass = Class.new(ActiveRecord::Base) do
705
960
  self.table_name = "computers"
706
- enum timezone: [:"Etc/GMT+1", :"Etc/GMT-1"]
961
+ enum :timezone, [:"Etc/GMT+1", :"Etc/GMT-1"]
707
962
  end
708
963
 
709
964
  computer = klass.public_send(:"Etc/GMT+1").build
@@ -716,7 +971,7 @@ class EnumTest < ActiveRecord::TestCase
716
971
  written = Struct.new(:to_s).new("written")
717
972
  klass = Class.new(ActiveRecord::Base) do
718
973
  self.table_name = "books"
719
- enum status: { proposed => 0, written => 1 }
974
+ enum :status, { proposed => 0, written => 1 }
720
975
  end
721
976
 
722
977
  book = klass.create!(status: 0)
@@ -725,6 +980,31 @@ class EnumTest < ActiveRecord::TestCase
725
980
  assert_not_predicate book, :written?
726
981
  end
727
982
 
983
+ test "serializable? with large number label" do
984
+ skip "IBM_DB/DB2: composite UNIQUE index on (author_id, name) treats multiple all-NULL rows as duplicates (SQL0803N); creating several Books without author/name fails" if current_adapter?(:IBM_DBAdapter)
985
+ klass = Class.new(ActiveRecord::Base) do
986
+ self.table_name = "books"
987
+ enum :status, ["9223372036854775808", "-9223372036854775809"]
988
+ end
989
+
990
+ type = klass.type_for_attribute(:status)
991
+
992
+ assert type.serializable?("9223372036854775808")
993
+ assert type.serializable?("-9223372036854775809")
994
+
995
+ assert_not type.serializable?(9223372036854775808)
996
+ assert_not type.serializable?(-9223372036854775809)
997
+
998
+ book1 = klass.create!(status: "9223372036854775808")
999
+ book2 = klass.create!(status: "-9223372036854775809")
1000
+
1001
+ assert_equal 0, book1.status_for_database
1002
+ assert_equal 1, book2.status_for_database
1003
+
1004
+ assert_equal book1, klass.where(status: "9223372036854775808").last
1005
+ assert_equal book2, klass.where(status: "-9223372036854775809").last
1006
+ end
1007
+
728
1008
  test "enum logs a warning if auto-generated negative scopes would clash with other enum names" do
729
1009
  old_logger = ActiveRecord::Base.logger
730
1010
  logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
@@ -735,20 +1015,16 @@ class EnumTest < ActiveRecord::TestCase
735
1015
  " This has caused a conflict with auto generated negative scopes."\
736
1016
  " Avoid using enum elements starting with 'not' where the positive form is also an element."
737
1017
 
738
- # this message comes from ActiveRecord::Scoping::Named, but it's worth noting that both occur in this case
739
- expected_message_2 = "Creating scope :not_sent. Overwriting existing method Book.not_sent."
740
-
741
1018
  Class.new(ActiveRecord::Base) do
742
1019
  def self.name
743
1020
  "Book"
744
1021
  end
745
1022
  silence_warnings do
746
- enum status: [:sent, :not_sent]
1023
+ enum :status, [:sent, :not_sent]
747
1024
  end
748
1025
  end
749
1026
 
750
1027
  assert_includes(logger.logged(:warn), expected_message_1)
751
- assert_includes(logger.logged(:warn), expected_message_2)
752
1028
  ensure
753
1029
  ActiveRecord::Base.logger = old_logger
754
1030
  end
@@ -763,20 +1039,16 @@ class EnumTest < ActiveRecord::TestCase
763
1039
  " This has caused a conflict with auto generated negative scopes."\
764
1040
  " Avoid using enum elements starting with 'not' where the positive form is also an element."
765
1041
 
766
- # this message comes from ActiveRecord::Scoping::Named, but it's worth noting that both occur in this case
767
- expected_message_2 = "Creating scope :not_sent. Overwriting existing method Book.not_sent."
768
-
769
1042
  Class.new(ActiveRecord::Base) do
770
1043
  def self.name
771
1044
  "Book"
772
1045
  end
773
1046
  silence_warnings do
774
- enum status: [:not_sent, :sent]
1047
+ enum :status, [:not_sent, :sent]
775
1048
  end
776
1049
  end
777
1050
 
778
1051
  assert_includes(logger.logged(:warn), expected_message_1)
779
- assert_includes(logger.logged(:warn), expected_message_2)
780
1052
  ensure
781
1053
  ActiveRecord::Base.logger = old_logger
782
1054
  end
@@ -791,9 +1063,7 @@ class EnumTest < ActiveRecord::TestCase
791
1063
  def self.name
792
1064
  "Book"
793
1065
  end
794
- silence_warnings do
795
- enum status: [:not_sent]
796
- end
1066
+ enum :status, [:not_sent]
797
1067
  end
798
1068
 
799
1069
  assert_empty(logger.logged(:warn))
@@ -812,7 +1082,7 @@ class EnumTest < ActiveRecord::TestCase
812
1082
  "Book"
813
1083
  end
814
1084
  silence_warnings do
815
- enum status: [:not_sent, :sent], _scopes: false
1085
+ enum :status, [:not_sent, :sent], scopes: false
816
1086
  end
817
1087
  end
818
1088
 
@@ -820,4 +1090,36 @@ class EnumTest < ActiveRecord::TestCase
820
1090
  ensure
821
1091
  ActiveRecord::Base.logger = old_logger
822
1092
  end
1093
+
1094
+ test "raises for attributes with undeclared type" do
1095
+ klass = Class.new(Book) do
1096
+ def self.name; "Book"; end
1097
+ enum :typeless_genre, [:adventure, :comic]
1098
+ end
1099
+
1100
+ error = assert_raises(RuntimeError) do
1101
+ klass.type_for_attribute(:typeless_genre)
1102
+ end
1103
+ assert_match "Undeclared attribute type for enum 'typeless_genre' in Book", error.message
1104
+ end
1105
+
1106
+ test "supports attributes declared with a explicit type" do
1107
+ klass = Class.new(Book) do
1108
+ attribute :my_genre, :integer
1109
+ enum :my_genre, [:adventure, :comic]
1110
+ end
1111
+
1112
+ assert_equal :integer, klass.type_for_attribute(:my_genre).type
1113
+ end
1114
+
1115
+ test "default methods can be disabled by :instance_methods" do
1116
+ klass = Class.new(ActiveRecord::Base) do
1117
+ self.table_name = "books"
1118
+ enum :status, [:proposed, :written], instance_methods: false
1119
+ end
1120
+
1121
+ instance = klass.new
1122
+ assert_raises(NoMethodError) { instance.proposed? }
1123
+ assert_raises(NoMethodError) { instance.proposed! }
1124
+ end
823
1125
  end