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.
- checksums.yaml +4 -4
- data/ext/Makefile +13 -9
- data/ext/extconf.rb +176 -110
- data/ext/ibm_db.c +60 -0
- data/ext/ibm_db.o +0 -0
- data/ext/ibm_db.so +0 -0
- data/ext/mkmf.log +6 -6
- data/ext/ruby_ibm_db_cli.c +14 -10
- data/ext/ruby_ibm_db_cli.h +4 -0
- data/ext/ruby_ibm_db_cli.o +0 -0
- data/lib/IBM_DB.rb +2 -2
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1254 -277
- data/test/active_record/connection_adapters/fake_legacy_adapter.rb +17 -0
- data/test/active_record/connection_adapters/fake_misleading_legacy_adapter.rb +8 -0
- data/test/activejob/destroy_association_async_job_test.rb +62 -0
- data/test/activejob/destroy_association_async_test.rb +147 -11
- data/test/activejob/job_runtime_test.rb +41 -0
- data/test/activejob/unloadable_base_job.rb +3 -0
- data/test/cases/active_record_schema_test.rb +196 -0
- data/test/cases/active_record_test.rb +21 -0
- data/test/cases/adapter_prevent_writes_test.rb +26 -202
- data/test/cases/adapter_test.rb +592 -82
- data/test/cases/adapters/abstract_mysql_adapter/active_schema_test.rb +210 -0
- data/test/cases/adapters/abstract_mysql_adapter/adapter_prevent_writes_test.rb +111 -0
- data/test/cases/adapters/abstract_mysql_adapter/auto_increment_test.rb +48 -0
- data/test/cases/adapters/abstract_mysql_adapter/bind_parameter_test.rb +91 -0
- data/test/cases/adapters/abstract_mysql_adapter/case_sensitivity_test.rb +65 -0
- data/test/cases/adapters/abstract_mysql_adapter/charset_collation_test.rb +85 -0
- data/test/cases/adapters/abstract_mysql_adapter/connection_test.rb +267 -0
- data/test/cases/adapters/abstract_mysql_adapter/count_deleted_rows_with_lock_test.rb +29 -0
- data/test/cases/adapters/abstract_mysql_adapter/json_test.rb +24 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_boolean_test.rb +102 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_enum_test.rb +47 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_explain_test.rb +71 -0
- data/test/cases/adapters/abstract_mysql_adapter/nested_deadlock_test.rb +191 -0
- data/test/cases/adapters/abstract_mysql_adapter/optimizer_hints_test.rb +69 -0
- data/test/cases/adapters/abstract_mysql_adapter/quoting_test.rb +49 -0
- data/test/cases/adapters/abstract_mysql_adapter/schema_migrations_test.rb +68 -0
- data/test/cases/adapters/abstract_mysql_adapter/schema_test.rb +130 -0
- data/test/cases/adapters/abstract_mysql_adapter/set_test.rb +32 -0
- data/test/cases/adapters/abstract_mysql_adapter/sp_test.rb +39 -0
- data/test/cases/adapters/abstract_mysql_adapter/sql_types_test.rb +16 -0
- data/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb +125 -0
- data/test/cases/adapters/abstract_mysql_adapter/transaction_test.rb +204 -0
- data/test/cases/adapters/abstract_mysql_adapter/unsigned_type_test.rb +77 -0
- data/test/cases/adapters/abstract_mysql_adapter/virtual_column_test.rb +69 -0
- data/test/cases/adapters/abstract_mysql_adapter/warnings_test.rb +109 -0
- data/test/cases/adapters/mysql2/check_constraint_quoting_test.rb +35 -0
- data/test/cases/adapters/mysql2/dbconsole_test.rb +87 -0
- data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +136 -10
- data/test/cases/adapters/mysql2/mysql2_rake_test.rb +433 -0
- data/test/cases/adapters/postgresql/active_schema_test.rb +8 -4
- data/test/cases/adapters/postgresql/array_test.rb +6 -6
- data/test/cases/adapters/postgresql/bind_parameter_test.rb +52 -0
- data/test/cases/adapters/postgresql/bit_string_test.rb +2 -2
- data/test/cases/adapters/postgresql/bytea_test.rb +3 -3
- data/test/cases/adapters/postgresql/case_insensitive_test.rb +1 -1
- data/test/cases/adapters/postgresql/change_schema_test.rb +32 -1
- data/test/cases/adapters/postgresql/cidr_test.rb +17 -0
- data/test/cases/adapters/postgresql/citext_test.rb +7 -1
- data/test/cases/adapters/postgresql/collation_test.rb +1 -1
- data/test/cases/adapters/postgresql/composite_test.rb +1 -1
- data/test/cases/adapters/postgresql/connection_test.rb +43 -36
- data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +3 -2
- data/test/cases/adapters/postgresql/datatype_test.rb +9 -4
- data/test/cases/adapters/postgresql/date_test.rb +2 -2
- data/test/cases/adapters/postgresql/dbconsole_test.rb +109 -0
- data/test/cases/adapters/postgresql/deferred_constraints_test.rb +55 -0
- data/test/cases/adapters/postgresql/domain_test.rb +1 -1
- data/test/cases/adapters/postgresql/enum_test.rb +208 -8
- data/test/cases/adapters/postgresql/explain_test.rb +25 -6
- data/test/cases/adapters/postgresql/extension_migration_test.rb +51 -9
- data/test/cases/adapters/postgresql/foreign_table_test.rb +3 -3
- data/test/cases/adapters/postgresql/full_text_test.rb +1 -1
- data/test/cases/adapters/postgresql/geometric_test.rb +13 -6
- data/test/cases/adapters/postgresql/hstore_test.rb +22 -32
- data/test/cases/adapters/postgresql/infinity_test.rb +13 -2
- data/test/cases/adapters/postgresql/integer_test.rb +1 -1
- data/test/cases/adapters/postgresql/interval_test.rb +9 -17
- data/test/cases/adapters/postgresql/invertible_migration_test.rb +139 -0
- data/test/cases/adapters/postgresql/json_test.rb +5 -0
- data/test/cases/adapters/postgresql/ltree_test.rb +1 -1
- data/test/cases/adapters/postgresql/money_test.rb +17 -9
- data/test/cases/adapters/postgresql/network_test.rb +13 -1
- data/test/cases/adapters/postgresql/numbers_test.rb +18 -2
- data/test/cases/adapters/postgresql/optimizer_hints_test.rb +9 -9
- data/test/cases/adapters/postgresql/partitions_test.rb +5 -2
- data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +7 -110
- data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +403 -20
- data/test/cases/adapters/postgresql/postgresql_rake_test.rb +637 -0
- data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +1 -1
- data/test/cases/adapters/postgresql/quoting_test.rb +60 -1
- data/test/cases/adapters/postgresql/range_test.rb +185 -21
- data/test/cases/adapters/postgresql/referential_integrity_test.rb +29 -5
- data/test/cases/adapters/postgresql/rename_table_test.rb +35 -8
- data/test/cases/adapters/postgresql/schema_authorization_test.rb +2 -2
- data/test/cases/adapters/postgresql/schema_test.rb +270 -20
- data/test/cases/adapters/postgresql/serial_test.rb +5 -5
- data/test/cases/adapters/postgresql/statement_pool_test.rb +6 -2
- data/test/cases/adapters/postgresql/timestamp_test.rb +122 -5
- data/test/cases/adapters/postgresql/transaction_nested_test.rb +130 -6
- data/test/cases/adapters/postgresql/transaction_test.rb +37 -11
- data/test/cases/adapters/postgresql/type_lookup_test.rb +1 -1
- data/test/cases/adapters/postgresql/uuid_test.rb +77 -9
- data/test/cases/adapters/postgresql/virtual_column_test.rb +114 -0
- data/test/cases/adapters/postgresql/xml_test.rb +1 -1
- data/test/cases/adapters/sqlite3/bind_parameter_test.rb +52 -0
- data/test/cases/adapters/sqlite3/collation_test.rb +1 -1
- data/test/cases/adapters/sqlite3/copy_table_test.rb +28 -7
- data/test/cases/adapters/sqlite3/dbconsole_test.rb +81 -0
- data/test/cases/adapters/sqlite3/explain_test.rb +3 -3
- data/test/cases/adapters/sqlite3/quoting_test.rb +34 -3
- data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +9 -102
- data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +727 -72
- data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +6 -3
- data/test/cases/adapters/sqlite3/sqlite_rake_test.rb +264 -0
- data/test/cases/adapters/sqlite3/statement_pool_test.rb +1 -1
- data/test/cases/adapters/sqlite3/transaction_test.rb +6 -3
- data/test/cases/adapters/sqlite3/virtual_column_test.rb +138 -0
- data/test/cases/adapters/sqlite3/virtual_table_test.rb +51 -0
- data/test/cases/adapters/trilogy/dbconsole_test.rb +76 -0
- data/test/cases/adapters/trilogy/trilogy_adapter_test.rb +473 -0
- data/test/cases/adapters/trilogy/trilogy_rake_test.rb +433 -0
- data/test/cases/aggregations_test.rb +16 -0
- data/test/cases/annotate_test.rb +14 -12
- data/test/cases/arel/attributes/attribute_test.rb +86 -47
- data/test/cases/arel/collectors/bind_test.rb +1 -1
- data/test/cases/arel/collectors/composite_test.rb +11 -1
- data/test/cases/arel/collectors/sql_string_test.rb +1 -1
- data/test/cases/arel/collectors/substitute_bind_collector_test.rb +1 -1
- data/test/cases/arel/delete_manager_test.rb +0 -6
- data/test/cases/arel/factory_methods_test.rb +45 -0
- data/test/cases/arel/insert_manager_test.rb +1 -7
- data/test/cases/arel/nodes/as_test.rb +12 -0
- data/test/cases/arel/nodes/ascending_test.rb +1 -1
- data/test/cases/arel/nodes/bin_test.rb +1 -1
- data/test/cases/arel/nodes/bound_sql_literal_test.rb +31 -0
- data/test/cases/arel/nodes/cte_test.rb +46 -0
- data/test/cases/arel/nodes/descending_test.rb +1 -1
- data/test/cases/arel/nodes/equality_test.rb +3 -3
- data/test/cases/arel/nodes/filter_test.rb +37 -0
- data/test/cases/arel/nodes/fragments_test.rb +38 -0
- data/test/cases/arel/nodes/homogeneous_in_test.rb +52 -0
- data/test/cases/arel/nodes/infix_operation_test.rb +1 -1
- data/test/cases/arel/nodes/node_test.rb +1 -1
- data/test/cases/arel/nodes/or_test.rb +2 -2
- data/test/cases/arel/nodes/sql_literal_test.rb +18 -1
- data/test/cases/arel/nodes/table_alias_test.rb +12 -0
- data/test/cases/arel/nodes/unary_operation_test.rb +1 -1
- data/test/cases/arel/nodes/update_statement_test.rb +4 -0
- data/test/cases/arel/nodes_test.rb +3 -2
- data/test/cases/arel/select_manager_test.rb +12 -12
- data/test/cases/arel/support/fake_record.rb +22 -17
- data/test/cases/arel/table_test.rb +15 -25
- data/test/cases/arel/update_manager_test.rb +51 -6
- data/test/cases/arel/visitors/dispatch_contamination_test.rb +1 -1
- data/test/cases/arel/visitors/dot_test.rb +177 -2
- data/test/cases/arel/visitors/mysql_test.rb +49 -1
- data/test/cases/arel/visitors/postgres_test.rb +1 -31
- data/test/cases/arel/visitors/sqlite_test.rb +1 -1
- data/test/cases/arel/visitors/to_sql_test.rb +330 -20
- data/test/cases/assertions/query_assertions_test.rb +136 -0
- data/test/cases/associations/belongs_to_associations_test.rb +502 -41
- data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +1 -1
- data/test/cases/associations/cascaded_eager_loading_test.rb +26 -15
- data/test/cases/associations/eager_load_nested_include_test.rb +1 -1
- data/test/cases/associations/eager_singularization_test.rb +1 -1
- data/test/cases/associations/eager_test.rb +255 -93
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +25 -53
- data/test/cases/associations/has_many_associations_test.rb +282 -72
- data/test/cases/associations/has_many_through_associations_test.rb +172 -45
- data/test/cases/associations/has_many_through_disable_joins_associations_test.rb +197 -0
- data/test/cases/associations/has_one_associations_test.rb +160 -29
- data/test/cases/associations/has_one_through_associations_test.rb +64 -15
- data/test/cases/associations/has_one_through_disable_joins_associations_test.rb +82 -0
- data/test/cases/associations/inner_join_association_test.rb +36 -6
- data/test/cases/associations/inverse_associations_test.rb +177 -40
- data/test/cases/associations/join_model_test.rb +17 -12
- data/test/cases/associations/left_outer_join_association_test.rb +14 -3
- data/test/cases/associations/nested_error_test.rb +116 -0
- data/test/cases/associations/nested_through_associations_test.rb +54 -19
- data/test/cases/associations/required_test.rb +1 -1
- data/test/cases/associations_test.rb +1278 -21
- data/test/cases/asynchronous_queries_test.rb +310 -0
- data/test/cases/attribute_methods/read_test.rb +6 -0
- data/test/cases/attribute_methods/time_zone_converter_test.rb +21 -0
- data/test/cases/attribute_methods_test.rb +565 -46
- data/test/cases/attributes_test.rb +42 -1
- data/test/cases/autosave_association_test.rb +645 -92
- data/test/cases/base_prevent_writes_test.rb +28 -159
- data/test/cases/base_test.rb +434 -209
- data/test/cases/batches_test.rb +441 -57
- data/test/cases/binary_test.rb +31 -0
- data/test/cases/bind_parameter_test.rb +107 -16
- data/test/cases/cache_key_test.rb +7 -7
- data/test/cases/calculations_test.rb +541 -110
- data/test/cases/callbacks_test.rb +0 -1
- data/test/cases/clone_test.rb +5 -4
- data/test/cases/coders/yaml_column_test.rb +97 -2
- data/test/cases/collection_cache_key_test.rb +24 -16
- data/test/cases/column_alias_test.rb +2 -8
- data/test/cases/column_definition_test.rb +12 -3
- data/test/cases/comment_test.rb +23 -26
- data/test/cases/connection_adapters/adapter_leasing_test.rb +9 -9
- data/test/cases/connection_adapters/connection_handler_test.rb +145 -99
- data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +79 -55
- data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +17 -20
- data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +146 -55
- data/test/cases/connection_adapters/connection_swapping_nested_test.rb +136 -23
- data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +96 -27
- data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -5
- data/test/cases/connection_adapters/registration_test.rb +98 -0
- data/test/cases/connection_adapters/schema_cache_test.rb +288 -135
- data/test/cases/connection_adapters/standalone_connection_test.rb +38 -0
- data/test/cases/connection_adapters/statement_pool_test.rb +29 -0
- data/test/cases/connection_adapters/type_lookup_test.rb +12 -24
- data/test/cases/connection_handling_test.rb +210 -0
- data/test/cases/connection_management_test.rb +44 -7
- data/test/cases/connection_pool_test.rb +466 -99
- data/test/cases/core_test.rb +167 -9
- data/test/cases/counter_cache_test.rb +129 -2
- data/test/cases/custom_locking_test.rb +3 -3
- data/test/cases/database_configurations/hash_config_test.rb +149 -13
- data/test/cases/database_configurations/resolver_test.rb +14 -10
- data/test/cases/database_configurations/url_config_test.rb +53 -0
- data/test/cases/database_configurations_test.rb +86 -43
- data/test/cases/database_selector_test.rb +30 -8
- data/test/cases/database_statements_test.rb +10 -14
- data/test/cases/date_time_precision_test.rb +141 -11
- data/test/cases/date_time_test.rb +19 -1
- data/test/cases/defaults_test.rb +107 -41
- data/test/cases/delegated_type_test.rb +69 -9
- data/test/cases/dirty_test.rb +82 -25
- data/test/cases/disconnected_test.rb +10 -9
- data/test/cases/dup_test.rb +26 -6
- data/test/cases/encryption/cipher/aes256_gcm_test.rb +50 -0
- data/test/cases/encryption/cipher_test.rb +65 -0
- data/test/cases/encryption/concurrency_test.rb +27 -0
- data/test/cases/encryption/config_test.rb +21 -0
- data/test/cases/encryption/configurable_test.rb +93 -0
- data/test/cases/encryption/contexts_test.rb +105 -0
- data/test/cases/encryption/derived_secret_key_provider_test.rb +31 -0
- data/test/cases/encryption/deterministic_key_provider_test.rb +11 -0
- data/test/cases/encryption/encryptable_record_api_test.rb +175 -0
- data/test/cases/encryption/encryptable_record_message_pack_serialized_test.rb +42 -0
- data/test/cases/encryption/encryptable_record_test.rb +470 -0
- data/test/cases/encryption/encrypted_fixtures_test.rb +22 -0
- data/test/cases/encryption/encrypting_only_encryptor_test.rb +20 -0
- data/test/cases/encryption/encryption_schemes_test.rb +240 -0
- data/test/cases/encryption/encryptor_test.rb +113 -0
- data/test/cases/encryption/envelope_encryption_key_provider_test.rb +49 -0
- data/test/cases/encryption/extended_deterministic_queries_test.rb +81 -0
- data/test/cases/encryption/helper.rb +152 -0
- data/test/cases/encryption/key_generator_test.rb +55 -0
- data/test/cases/encryption/key_provider_test.rb +57 -0
- data/test/cases/encryption/key_test.rb +17 -0
- data/test/cases/encryption/message_pack_message_serializer_test.rb +70 -0
- data/test/cases/encryption/message_serializer_test.rb +82 -0
- data/test/cases/encryption/message_test.rb +43 -0
- data/test/cases/encryption/null_encryptor_test.rb +21 -0
- data/test/cases/encryption/properties_test.rb +69 -0
- data/test/cases/encryption/read_only_null_encryptor_test.rb +19 -0
- data/test/cases/encryption/scheme_test.rb +58 -0
- data/test/cases/encryption/unencrypted_attributes_test.rb +27 -0
- data/test/cases/encryption/uniqueness_validations_test.rb +65 -0
- data/test/cases/enum_test.rb +374 -72
- data/test/cases/errors_test.rb +7 -4
- data/test/cases/excluding_test.rb +116 -0
- data/test/cases/explain_subscriber_test.rb +6 -1
- data/test/cases/explain_test.rb +119 -10
- data/test/cases/filter_attributes_test.rb +7 -14
- data/test/cases/finder_respond_to_test.rb +3 -3
- data/test/cases/finder_test.rb +357 -72
- data/test/cases/fixture_set/file_test.rb +9 -0
- data/test/cases/fixtures_test.rb +426 -190
- data/test/cases/helper.rb +66 -192
- data/test/cases/hot_compatibility_test.rb +10 -10
- data/test/cases/inheritance_test.rb +51 -61
- data/test/cases/inherited_test.rb +40 -0
- data/test/cases/insert_all_test.rb +419 -9
- data/test/cases/instrumentation_test.rb +202 -30
- data/test/cases/integration_test.rb +25 -7
- data/test/cases/invalid_connection_test.rb +5 -5
- data/test/cases/invertible_migration_test.rb +108 -24
- data/test/cases/json_attribute_test.rb +1 -0
- data/test/cases/json_serialization_test.rb +5 -5
- data/test/cases/json_shared_test_cases.rb +5 -9
- data/test/cases/locking_test.rb +67 -31
- data/test/cases/log_subscriber_test.rb +17 -15
- data/test/cases/marshal_serialization_test.rb +78 -5
- data/test/cases/message_pack_test.rb +91 -0
- data/test/cases/migration/change_schema_test.rb +77 -46
- data/test/cases/migration/change_table_test.rb +129 -114
- data/test/cases/migration/check_constraint_test.rb +192 -10
- data/test/cases/migration/column_attributes_test.rb +4 -9
- data/test/cases/migration/column_positioning_test.rb +2 -2
- data/test/cases/migration/columns_test.rb +118 -4
- data/test/cases/migration/command_recorder_test.rb +181 -14
- data/test/cases/migration/compatibility_test.rb +883 -196
- data/test/cases/migration/create_join_table_test.rb +8 -1
- data/test/cases/migration/exclusion_constraint_test.rb +192 -0
- data/test/cases/migration/foreign_key_test.rb +356 -14
- data/test/cases/migration/helper.rb +4 -1
- data/test/cases/migration/index_test.rb +67 -2
- data/test/cases/migration/invalid_options_test.rb +129 -0
- data/test/cases/migration/logger_test.rb +7 -4
- data/test/cases/migration/pending_migrations_test.rb +103 -60
- data/test/cases/migration/references_foreign_key_test.rb +73 -4
- data/test/cases/migration/references_index_test.rb +25 -27
- data/test/cases/migration/references_statements_test.rb +27 -3
- data/test/cases/migration/rename_table_test.rb +39 -54
- data/test/cases/migration/schema_definitions_test.rb +109 -0
- data/test/cases/migration/unique_constraint_test.rb +248 -0
- data/test/cases/migration_test.rb +677 -220
- data/test/cases/migrator_test.rb +102 -75
- data/test/cases/multi_db_migrator_test.rb +55 -34
- data/test/cases/multiparameter_attributes_test.rb +26 -29
- data/test/cases/multiple_db_test.rb +42 -19
- data/test/cases/nested_attributes_test.rb +124 -6
- data/test/cases/nested_attributes_with_callbacks_test.rb +2 -2
- data/test/cases/normalized_attribute_test.rb +117 -0
- data/test/cases/null_relation_test.rb +35 -2
- data/test/cases/persistence/reload_association_cache_test.rb +20 -0
- data/test/cases/persistence_test.rb +629 -22
- data/test/cases/pooled_connections_test.rb +57 -56
- data/test/cases/prepared_statement_status_test.rb +8 -3
- data/test/cases/primary_class_test.rb +134 -0
- data/test/cases/primary_keys_test.rb +171 -55
- data/test/cases/query_cache_test.rb +558 -263
- data/test/cases/query_logs_test.rb +293 -0
- data/test/cases/quoting_test.rb +39 -72
- data/test/cases/readonly_test.rb +50 -12
- data/test/cases/reaper_test.rb +22 -6
- data/test/cases/reflection_test.rb +207 -9
- data/test/cases/relation/and_test.rb +43 -0
- data/test/cases/relation/delegation_test.rb +32 -5
- data/test/cases/relation/delete_all_test.rb +27 -6
- data/test/cases/relation/field_ordered_values_test.rb +128 -0
- data/test/cases/relation/load_async_test.rb +650 -0
- data/test/cases/relation/merging_test.rb +80 -109
- data/test/cases/relation/mutation_test.rb +12 -7
- data/test/cases/relation/or_test.rb +11 -8
- data/test/cases/relation/order_test.rb +90 -0
- data/test/cases/relation/predicate_builder_test.rb +21 -6
- data/test/cases/relation/select_test.rb +162 -3
- data/test/cases/relation/structural_compatibility_test.rb +38 -0
- data/test/cases/relation/update_all_test.rb +81 -27
- data/test/cases/relation/where_chain_test.rb +190 -3
- data/test/cases/relation/where_clause_test.rb +43 -1
- data/test/cases/relation/where_test.rb +95 -7
- data/test/cases/relation/with_test.rb +165 -0
- data/test/cases/relation_test.rb +42 -37
- data/test/cases/relations_test.rb +436 -138
- data/test/cases/reload_models_test.rb +18 -14
- data/test/cases/reserved_word_test.rb +2 -1
- data/test/cases/result_test.rb +14 -22
- data/test/cases/sanitize_test.rb +89 -27
- data/test/cases/schema_dumper_test.rb +535 -62
- data/test/cases/scoping/default_scoping_test.rb +219 -35
- data/test/cases/scoping/named_scoping_test.rb +25 -46
- data/test/cases/scoping/relation_scoping_test.rb +112 -4
- data/test/cases/secure_password_test.rb +108 -0
- data/test/cases/secure_token_test.rb +72 -0
- data/test/cases/serialization_test.rb +1 -1
- data/test/cases/serialized_attribute_test.rb +305 -60
- data/test/cases/shard_keys_test.rb +125 -0
- data/test/cases/shard_selector_test.rb +45 -0
- data/test/cases/signed_id_test.rb +57 -5
- data/test/cases/statement_cache_test.rb +31 -30
- data/test/cases/statement_invalid_test.rb +8 -4
- data/test/cases/store_test.rb +73 -9
- data/test/cases/strict_loading_test.rb +327 -13
- data/test/cases/table_metadata_test.rb +16 -0
- data/test/cases/tasks/database_tasks_test.rb +517 -244
- data/test/cases/test_case.rb +254 -60
- data/test/cases/test_case_test.rb +69 -0
- data/test/cases/test_databases_test.rb +7 -3
- data/test/cases/test_fixtures_test.rb +19 -40
- data/test/cases/time_precision_test.rb +17 -5
- data/test/cases/timestamp_test.rb +124 -16
- data/test/cases/token_for_test.rb +165 -0
- data/test/cases/touch_later_test.rb +43 -1
- data/test/cases/transaction_callbacks_test.rb +325 -8
- data/test/cases/transaction_instrumentation_test.rb +453 -0
- data/test/cases/transaction_isolation_test.rb +12 -8
- data/test/cases/transactions_test.rb +629 -112
- data/test/cases/type/date_time_test.rb +7 -1
- data/test/cases/type/time_test.rb +9 -0
- data/test/cases/type/type_map_test.rb +108 -73
- data/test/cases/type/unsigned_integer_test.rb +12 -0
- data/test/cases/type_caster/connection_test.rb +19 -0
- data/test/cases/type_test.rb +1 -1
- data/test/cases/unconnected_test.rb +7 -7
- data/test/cases/unsafe_raw_sql_test.rb +39 -8
- data/test/cases/validations/absence_validation_test.rb +1 -1
- data/test/cases/validations/association_validation_test.rb +25 -3
- data/test/cases/validations/numericality_validation_test.rb +3 -9
- data/test/cases/validations/presence_validation_test.rb +1 -1
- data/test/cases/validations/uniqueness_validation_test.rb +280 -40
- data/test/cases/validations_test.rb +2 -2
- data/test/cases/view_test.rb +33 -22
- data/test/cases/yaml_serialization_test.rb +23 -17
- data/test/config.example.yml +58 -56
- data/test/config.rb +1 -0
- data/test/fixtures/1_need_quoting.yml +2 -0
- data/test/fixtures/accounts.yml +5 -0
- data/test/fixtures/aircrafts.yml +7 -0
- data/test/fixtures/book_identifiers.yml +11 -0
- data/test/fixtures/books.yml +5 -4
- data/test/fixtures/cake_designers.yml +5 -0
- data/test/fixtures/cars.yml +6 -0
- data/test/fixtures/chefs.yml +5 -0
- data/test/fixtures/clothing_items.yml +23 -0
- data/test/fixtures/clubs.yml +1 -1
- data/test/fixtures/comments.yml +2 -1
- data/test/fixtures/cpk_authors.yml +8 -0
- data/test/fixtures/cpk_books.yml +21 -0
- data/test/fixtures/cpk_order_agreements.yml +13 -0
- data/test/fixtures/cpk_order_tags.yml +15 -0
- data/test/fixtures/cpk_orders.yml +11 -0
- data/test/fixtures/cpk_posts.yml +12 -0
- data/test/fixtures/cpk_reviews.yml +13 -0
- data/test/fixtures/cpk_tags.yml +11 -0
- data/test/fixtures/drink_designers.yml +5 -0
- data/test/fixtures/encrypted_book_that_ignores_cases.yml +4 -0
- data/test/fixtures/encrypted_books.yml +4 -0
- data/test/fixtures/fk_object_to_point_to.yml +2 -0
- data/test/fixtures/memberships.yml +15 -15
- data/test/fixtures/paragraphs.yml +5 -0
- data/test/fixtures/parrots.yml +4 -0
- data/test/fixtures/people.yml +2 -0
- data/test/fixtures/pirates.yml +2 -2
- data/test/fixtures/primary_key_error/primary_key_error.yml +6 -0
- data/test/fixtures/references.yml +3 -3
- data/test/fixtures/sharded_blog_posts.yml +14 -0
- data/test/fixtures/sharded_blog_posts_tags.yml +27 -0
- data/test/fixtures/sharded_blogs.yml +8 -0
- data/test/fixtures/sharded_comments.yml +22 -0
- data/test/fixtures/sharded_tags.yml +34 -0
- data/test/fixtures/sponsors.yml +2 -2
- data/test/fixtures/topics.yml +1 -0
- data/test/fixtures/treasures.yml +4 -0
- data/test/fixtures/virtual_columns.yml +5 -0
- data/test/fixtures/warehouse_things.yml +1 -1
- data/test/migrations/old_and_new_versions/20210716122844_add_people_description.rb +5 -0
- data/test/migrations/old_and_new_versions/20210716123013_add_people_number_of_legs.rb +5 -0
- data/test/migrations/old_and_new_versions/230_add_people_hobby.rb +5 -0
- data/test/migrations/old_and_new_versions/231_add_people_last_name.rb +5 -0
- data/test/migrations/scope/1_unscoped.rb +7 -0
- data/test/migrations/scope/2_mysql_only.mysql.rb +7 -0
- data/test/models/admin/user.rb +2 -0
- data/test/models/admin/user_json.rb +48 -0
- data/test/models/attachment.rb +7 -0
- data/test/models/author.rb +70 -3
- data/test/models/author_encrypted.rb +16 -0
- data/test/models/bird.rb +1 -1
- data/test/models/book.rb +18 -11
- data/test/models/book_destroy_async.rb +1 -1
- data/test/models/book_encrypted.rb +106 -0
- data/test/models/book_identifier.rb +5 -0
- data/test/models/branch.rb +11 -0
- data/test/models/bulb.rb +1 -1
- data/test/models/car.rb +8 -1
- data/test/models/cat.rb +1 -1
- data/test/models/category.rb +3 -1
- data/test/models/chat_message.rb +8 -0
- data/test/models/chef.rb +52 -0
- data/test/models/clothing_item.rb +12 -0
- data/test/models/club.rb +4 -1
- data/test/models/comment.rb +7 -4
- data/test/models/comment_overlapping_counter_cache.rb +15 -0
- data/test/models/company.rb +16 -2
- data/test/models/computer.rb +1 -0
- data/test/models/contact.rb +3 -3
- data/test/models/contract.rb +5 -1
- data/test/models/cpk/author.rb +9 -0
- data/test/models/cpk/book.rb +55 -0
- data/test/models/cpk/book_destroy_async.rb +9 -0
- data/test/models/cpk/car.rb +9 -0
- data/test/models/cpk/car_review.rb +9 -0
- data/test/models/cpk/chapter.rb +16 -0
- data/test/models/cpk/chapter_destroy_async.rb +10 -0
- data/test/models/cpk/comment.rb +9 -0
- data/test/models/cpk/order.rb +55 -0
- data/test/models/cpk/order_agreement.rb +10 -0
- data/test/models/cpk/order_tag.rb +10 -0
- data/test/models/cpk/post.rb +10 -0
- data/test/models/cpk/posts_tag.rb +10 -0
- data/test/models/cpk/review.rb +9 -0
- data/test/models/cpk/tag.rb +10 -0
- data/test/models/cpk.rb +15 -0
- data/test/models/customer.rb +3 -1
- data/test/models/destroy_async_parent.rb +1 -1
- data/test/models/developer.rb +44 -3
- data/test/models/discount.rb +4 -0
- data/test/models/drink_designer.rb +1 -0
- data/test/models/editor.rb +8 -0
- data/test/models/editorship.rb +6 -0
- data/test/models/entry.rb +5 -0
- data/test/models/essay.rb +6 -1
- data/test/models/essay_destroy_async.rb +1 -0
- data/test/models/eye.rb +87 -21
- data/test/models/face.rb +1 -1
- data/test/models/friendship.rb +3 -0
- data/test/models/hardback.rb +7 -0
- data/test/models/hotel.rb +2 -0
- data/test/models/human.rb +2 -2
- data/test/models/invoice.rb +2 -1
- data/test/models/invokes_an_undefined_method.rb +5 -0
- data/test/models/line_item.rb +6 -0
- data/test/models/member.rb +9 -4
- data/test/models/membership.rb +2 -2
- data/test/models/message.rb +2 -1
- data/test/models/need_quoting.rb +5 -0
- data/test/models/paragraph.rb +5 -0
- data/test/models/parrot.rb +6 -3
- data/test/models/person.rb +7 -4
- data/test/models/pirate.rb +4 -1
- data/test/models/pk_autopopulated_by_a_trigger_record.rb +5 -0
- data/test/models/post.rb +65 -2
- data/test/models/post_encrypted.rb +15 -0
- data/test/models/post_with_prefetched_pk.rb +15 -0
- data/test/models/project.rb +1 -0
- data/test/models/publication.rb +16 -0
- data/test/models/raises_argument_error.rb +5 -0
- data/test/models/raises_no_method_error.rb +5 -0
- data/test/models/recipient.rb +5 -0
- data/test/models/reference.rb +1 -1
- data/test/models/reply.rb +1 -1
- data/test/models/room.rb +3 -0
- data/test/models/sharded/blog.rb +12 -0
- data/test/models/sharded/blog_post.rb +17 -0
- data/test/models/sharded/blog_post_destroy_async.rb +14 -0
- data/test/models/sharded/blog_post_tag.rb +11 -0
- data/test/models/sharded/blog_post_with_revision.rb +11 -0
- data/test/models/sharded/comment.rb +12 -0
- data/test/models/sharded/comment_destroy_async.rb +12 -0
- data/test/models/sharded/tag.rb +11 -0
- data/test/models/sharded.rb +8 -0
- data/test/models/ship.rb +1 -1
- data/test/models/shipping_line.rb +11 -0
- data/test/models/subscriber.rb +1 -0
- data/test/models/subscription.rb +3 -1
- data/test/models/too_long_table_name.rb +5 -0
- data/test/models/topic.rb +3 -1
- data/test/models/traffic_light.rb +2 -2
- data/test/models/traffic_light_encrypted.rb +21 -0
- data/test/models/translation.rb +9 -0
- data/test/models/treasure.rb +1 -1
- data/test/models/tyre.rb +1 -1
- data/test/models/user.rb +16 -0
- data/test/models/user_with_invalid_relation.rb +28 -0
- data/test/models/uuid_comment.rb +5 -0
- data/test/models/uuid_entry.rb +5 -0
- data/test/models/uuid_message.rb +5 -0
- data/test/models/zine.rb +2 -1
- data/test/schema/mysql2_specific_schema.rb +26 -12
- data/test/schema/postgresql_specific_schema.rb +121 -13
- data/test/schema/schema.rb +361 -103
- data/test/schema/sqlite_specific_schema.rb +17 -6
- data/test/schema/trilogy_specific_schema.rb +96 -0
- data/test/support/adapter_helper.rb +104 -0
- data/test/support/async_helper.rb +15 -0
- data/test/support/config.rb +1 -1
- data/test/support/connection.rb +14 -2
- data/test/support/ddl_helper.rb +1 -1
- data/test/support/fake_adapter.rb +42 -0
- data/test/support/load_schema_helper.rb +22 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic_associations.dump +0 -0
- data/test/support/schema_dumping_helper.rb +15 -9
- data/test/support/tools.rb +37 -0
- data/test/support/yaml_compatibility_fixtures/rails_4_1_no_symbol.yml +22 -0
- metadata +247 -15
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "cases/helper"
|
|
4
|
+
require "models/auto_id"
|
|
4
5
|
require "models/aircraft"
|
|
6
|
+
require "models/dashboard"
|
|
7
|
+
require "models/clothing_item"
|
|
5
8
|
require "models/post"
|
|
6
9
|
require "models/comment"
|
|
7
10
|
require "models/author"
|
|
@@ -15,13 +18,103 @@ require "models/project"
|
|
|
15
18
|
require "models/minimalistic"
|
|
16
19
|
require "models/parrot"
|
|
17
20
|
require "models/minivan"
|
|
21
|
+
require "models/car"
|
|
18
22
|
require "models/person"
|
|
19
23
|
require "models/ship"
|
|
20
24
|
require "models/admin"
|
|
21
25
|
require "models/admin/user"
|
|
26
|
+
require "models/cpk"
|
|
27
|
+
require "models/chat_message"
|
|
28
|
+
require "models/default"
|
|
29
|
+
require "models/post_with_prefetched_pk"
|
|
30
|
+
require "models/pk_autopopulated_by_a_trigger_record"
|
|
22
31
|
|
|
23
32
|
class PersistenceTest < ActiveRecord::TestCase
|
|
24
|
-
fixtures :topics, :companies, :developers, :accounts, :minimalistics, :authors, :author_addresses,
|
|
33
|
+
fixtures :topics, :companies, :developers, :accounts, :minimalistics, :authors, :author_addresses,
|
|
34
|
+
:posts, :minivans, :clothing_items, :cpk_books, :people, :cars
|
|
35
|
+
|
|
36
|
+
def test_populates_non_primary_key_autoincremented_column
|
|
37
|
+
topic = TitlePrimaryKeyTopic.create!(title: "title pk topic")
|
|
38
|
+
|
|
39
|
+
assert_not_nil topic.attributes["id"]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_populates_autoincremented_id_pk_regardless_of_its_position_in_columns_list
|
|
43
|
+
auto_populated_column_names = AutoId.columns.select(&:auto_populated?).map(&:name)
|
|
44
|
+
|
|
45
|
+
# It's important we test a scenario where tables has more than one auto populated column
|
|
46
|
+
# and the first column is not the primary key. Otherwise it will be a regular test not asserting this special case.
|
|
47
|
+
assert auto_populated_column_names.size > 1
|
|
48
|
+
assert_not_equal AutoId.primary_key, auto_populated_column_names.first
|
|
49
|
+
|
|
50
|
+
record = AutoId.create!
|
|
51
|
+
last_id = AutoId.last.id
|
|
52
|
+
|
|
53
|
+
assert_not_nil last_id
|
|
54
|
+
assert last_id > 0
|
|
55
|
+
assert_equal last_id, record.id
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_populates_non_primary_key_autoincremented_column_for_a_cpk_model
|
|
59
|
+
order = Cpk::Order.create(shop_id: 111_222)
|
|
60
|
+
|
|
61
|
+
_shop_id, order_id = order.id
|
|
62
|
+
|
|
63
|
+
assert_not_nil order_id
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if current_adapter?(:PostgreSQLAdapter)
|
|
67
|
+
def test_fills_auto_populated_columns_on_creation
|
|
68
|
+
record = Default.create
|
|
69
|
+
assert_not_nil record.id
|
|
70
|
+
assert_equal "Ruby on Rails", record.ruby_on_rails
|
|
71
|
+
|
|
72
|
+
if supports_virtual_columns?
|
|
73
|
+
assert_not_nil record.virtual_stored_number
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
assert_not_nil record.random_number
|
|
77
|
+
assert_not_nil record.modified_date
|
|
78
|
+
assert_not_nil record.modified_date_function
|
|
79
|
+
assert_not_nil record.modified_time
|
|
80
|
+
assert_not_nil record.modified_time_without_precision
|
|
81
|
+
assert_not_nil record.modified_time_function
|
|
82
|
+
|
|
83
|
+
assert_equal "A", record.binary_default_function
|
|
84
|
+
|
|
85
|
+
if supports_identity_columns?
|
|
86
|
+
klass = Class.new(ActiveRecord::Base) do
|
|
87
|
+
self.table_name = "postgresql_identity_table"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
record = klass.create!
|
|
91
|
+
assert_not_nil record.id
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
elsif current_adapter?(:SQLite3Adapter)
|
|
95
|
+
def test_fills_auto_populated_columns_on_creation
|
|
96
|
+
record = Default.create
|
|
97
|
+
assert_not_nil record.id
|
|
98
|
+
assert_equal "Ruby on Rails", record.ruby_on_rails
|
|
99
|
+
|
|
100
|
+
assert_not_nil record.random_number
|
|
101
|
+
assert_not_nil record.modified_date
|
|
102
|
+
assert_not_nil record.modified_date_function
|
|
103
|
+
assert_not_nil record.modified_time
|
|
104
|
+
assert_not_nil record.modified_time_without_precision
|
|
105
|
+
assert_not_nil record.modified_time_function
|
|
106
|
+
end
|
|
107
|
+
elsif current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
|
|
108
|
+
def test_fills_auto_populated_columns_on_creation
|
|
109
|
+
record = Default.create
|
|
110
|
+
assert_not_nil record.id
|
|
111
|
+
assert_not_nil record.char1
|
|
112
|
+
|
|
113
|
+
if supports_default_expression? && supports_insert_returning?
|
|
114
|
+
assert_not_nil record.uuid
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
25
118
|
|
|
26
119
|
def test_update_many
|
|
27
120
|
topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" } }
|
|
@@ -53,6 +146,29 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
53
146
|
assert_not_equal "2 updated", Topic.find(2).content
|
|
54
147
|
end
|
|
55
148
|
|
|
149
|
+
def test_update_many_with_active_record_base_object
|
|
150
|
+
error = assert_raises(ArgumentError) do
|
|
151
|
+
Topic.update(Topic.first, "content" => "1 updated")
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
assert_equal "You are passing an instance of ActiveRecord::Base to `update`. " \
|
|
155
|
+
"Please pass the id of the object by calling `.id`.", error.message
|
|
156
|
+
|
|
157
|
+
assert_not_equal "1 updated", Topic.first.content
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def test_update_many_with_array_of_active_record_base_objects
|
|
161
|
+
error = assert_raise(ArgumentError) do
|
|
162
|
+
Topic.update(Topic.first(2), content: "updated")
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
assert_equal "You are passing an array of ActiveRecord::Base instances to `update`. " \
|
|
166
|
+
"Please pass the ids of the objects by calling `pluck(:id)` or `map(&:id)`.", error.message
|
|
167
|
+
|
|
168
|
+
assert_not_equal "updated", Topic.first.content
|
|
169
|
+
assert_not_equal "updated", Topic.second.content
|
|
170
|
+
end
|
|
171
|
+
|
|
56
172
|
def test_class_level_update_without_ids
|
|
57
173
|
topics = Topic.all
|
|
58
174
|
assert_equal 5, topics.length
|
|
@@ -78,6 +194,94 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
78
194
|
assert_not_equal "2 updated", Topic.find(2).content
|
|
79
195
|
end
|
|
80
196
|
|
|
197
|
+
def test_returns_object_even_if_validations_failed
|
|
198
|
+
assert_equal Developer.all.to_a, Developer.update(salary: 1_000_000)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def test_update_many!
|
|
202
|
+
topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" } }
|
|
203
|
+
updated = Topic.update!(topic_data.keys, topic_data.values)
|
|
204
|
+
|
|
205
|
+
assert_equal [1, 2], updated.map(&:id)
|
|
206
|
+
assert_equal "1 updated", Topic.find(1).content
|
|
207
|
+
assert_equal "2 updated", Topic.find(2).content
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def test_update_many_with_duplicated_ids!
|
|
211
|
+
updated = Topic.update!([1, 1, 2], [
|
|
212
|
+
{ "content" => "1 duplicated" }, { "content" => "1 updated" }, { "content" => "2 updated" }
|
|
213
|
+
])
|
|
214
|
+
|
|
215
|
+
assert_equal [1, 1, 2], updated.map(&:id)
|
|
216
|
+
assert_equal "1 updated", Topic.find(1).content
|
|
217
|
+
assert_equal "2 updated", Topic.find(2).content
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def test_update_many_with_invalid_id!
|
|
221
|
+
topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" }, 99999 => {} }
|
|
222
|
+
|
|
223
|
+
assert_raise(ActiveRecord::RecordNotFound) do
|
|
224
|
+
Topic.update!(topic_data.keys, topic_data.values)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
assert_not_equal "1 updated", Topic.find(1).content
|
|
228
|
+
assert_not_equal "2 updated", Topic.find(2).content
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def test_update_many_with_active_record_base_object!
|
|
232
|
+
error = assert_raises(ArgumentError) do
|
|
233
|
+
Topic.update!(Topic.first, "content" => "1 updated")
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
assert_equal "You are passing an instance of ActiveRecord::Base to `update!`. " \
|
|
237
|
+
"Please pass the id of the object by calling `.id`.", error.message
|
|
238
|
+
|
|
239
|
+
assert_not_equal "1 updated", Topic.first.content
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def test_update_many_with_array_of_active_record_base_objects!
|
|
243
|
+
error = assert_raise(ArgumentError) do
|
|
244
|
+
Topic.update!(Topic.first(2), content: "updated")
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
assert_equal "You are passing an array of ActiveRecord::Base instances to `update!`. " \
|
|
248
|
+
"Please pass the ids of the objects by calling `pluck(:id)` or `map(&:id)`.", error.message
|
|
249
|
+
|
|
250
|
+
assert_not_equal "updated", Topic.first.content
|
|
251
|
+
assert_not_equal "updated", Topic.second.content
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def test_class_level_update_without_ids!
|
|
255
|
+
topics = Topic.all
|
|
256
|
+
assert_equal 5, topics.length
|
|
257
|
+
topics.each do |topic|
|
|
258
|
+
assert_not_equal "updated", topic.content
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
updated = Topic.update!(content: "updated")
|
|
262
|
+
assert_equal 5, updated.length
|
|
263
|
+
updated.each do |topic|
|
|
264
|
+
assert_equal "updated", topic.content
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def test_class_level_update_is_affected_by_scoping!
|
|
269
|
+
topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" } }
|
|
270
|
+
|
|
271
|
+
assert_raise(ActiveRecord::RecordNotFound) do
|
|
272
|
+
Topic.where("1=0").scoping { Topic.update!(topic_data.keys, topic_data.values) }
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
assert_not_equal "1 updated", Topic.find(1).content
|
|
276
|
+
assert_not_equal "2 updated", Topic.find(2).content
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def test_raises_error_when_validations_failed
|
|
280
|
+
assert_raises(ActiveRecord::RecordInvalid) do
|
|
281
|
+
Developer.update!(salary: 1_000_000)
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
81
285
|
def test_delete_all
|
|
82
286
|
assert Topic.count > 0
|
|
83
287
|
|
|
@@ -177,6 +381,40 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
177
381
|
assert_equal clients, Client.find([2, 3])
|
|
178
382
|
end
|
|
179
383
|
|
|
384
|
+
def test_destroy_with_single_composite_primary_key
|
|
385
|
+
book = cpk_books(:cpk_great_author_first_book)
|
|
386
|
+
|
|
387
|
+
assert_difference("Cpk::Book.count", -1) do
|
|
388
|
+
destroyed = Cpk::Book.destroy(book.id)
|
|
389
|
+
assert_equal destroyed, book
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
def test_destroy_with_multiple_composite_primary_keys
|
|
394
|
+
books = [
|
|
395
|
+
cpk_books(:cpk_great_author_first_book),
|
|
396
|
+
cpk_books(:cpk_great_author_second_book),
|
|
397
|
+
]
|
|
398
|
+
|
|
399
|
+
assert_difference("Cpk::Book.count", -2) do
|
|
400
|
+
destroyed = Cpk::Book.destroy(books.map(&:id))
|
|
401
|
+
assert_equal books.sort, destroyed.sort
|
|
402
|
+
assert destroyed.all?(&:frozen?), "destroyed clients should be frozen"
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def test_destroy_with_invalid_ids_for_a_model_that_expects_composite_keys
|
|
407
|
+
books = [
|
|
408
|
+
cpk_books(:cpk_great_author_first_book),
|
|
409
|
+
cpk_books(:cpk_great_author_second_book),
|
|
410
|
+
]
|
|
411
|
+
|
|
412
|
+
assert_raise(ActiveRecord::RecordNotFound) do
|
|
413
|
+
ids = books.map { |book| book.id.first }
|
|
414
|
+
Cpk::Book.destroy(ids)
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
|
|
180
418
|
def test_becomes
|
|
181
419
|
assert_kind_of Reply, topics(:first).becomes(Reply)
|
|
182
420
|
assert_equal "The First Topic", topics(:first).becomes(Reply).title
|
|
@@ -194,7 +432,7 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
194
432
|
assert_not_predicate company, :valid?
|
|
195
433
|
original_errors = company.errors
|
|
196
434
|
client = company.becomes(Client)
|
|
197
|
-
assert_equal
|
|
435
|
+
assert_equal original_errors.attribute_names, client.errors.attribute_names
|
|
198
436
|
end
|
|
199
437
|
|
|
200
438
|
def test_becomes_errors_base
|
|
@@ -208,7 +446,7 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
208
446
|
admin.errors.add :token, :invalid
|
|
209
447
|
child = admin.becomes(child_class)
|
|
210
448
|
|
|
211
|
-
assert_equal [:token],
|
|
449
|
+
assert_equal [:token], child.errors.attribute_names
|
|
212
450
|
assert_nothing_raised do
|
|
213
451
|
child.errors.add :foo, :invalid
|
|
214
452
|
end
|
|
@@ -239,6 +477,47 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
239
477
|
assert_equal %w{name}, client.changed
|
|
240
478
|
end
|
|
241
479
|
|
|
480
|
+
def test_becomes_preserve_record_status
|
|
481
|
+
skip if current_adapter?(:IBM_DBAdapter)
|
|
482
|
+
|
|
483
|
+
company = Company.new(name: "37signals")
|
|
484
|
+
client = company.becomes(Client)
|
|
485
|
+
assert_predicate client, :new_record?
|
|
486
|
+
|
|
487
|
+
company.save
|
|
488
|
+
client = company.becomes(Client)
|
|
489
|
+
assert_predicate client, :persisted?
|
|
490
|
+
assert_predicate client, :previously_new_record?
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
def test_becomes_preserve_mark_for_destruction
|
|
494
|
+
skip if current_adapter?(:IBM_DBAdapter)
|
|
495
|
+
|
|
496
|
+
topic = topics(:first)
|
|
497
|
+
topic.mark_for_destruction
|
|
498
|
+
assert_predicate topic, :marked_for_destruction?
|
|
499
|
+
|
|
500
|
+
reply = topic.becomes(Reply)
|
|
501
|
+
assert_predicate reply, :marked_for_destruction?
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
def test_becomes_initializes_missing_attributes
|
|
505
|
+
company = Company.new(name: "GrowingCompany")
|
|
506
|
+
|
|
507
|
+
client = company.becomes(LargeClient)
|
|
508
|
+
|
|
509
|
+
assert_equal 50, client.extra_size
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
def test_becomes_keeps_extra_attributes
|
|
513
|
+
client = LargeClient.new(name: "ShrinkingCompany")
|
|
514
|
+
|
|
515
|
+
company = client.becomes(Company)
|
|
516
|
+
|
|
517
|
+
assert_equal 50, company.extra_size
|
|
518
|
+
assert_equal 50, client.extra_size
|
|
519
|
+
end
|
|
520
|
+
|
|
242
521
|
def test_delete_many
|
|
243
522
|
original_count = Topic.count
|
|
244
523
|
Topic.delete(deleting = [1, 2])
|
|
@@ -296,12 +575,81 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
296
575
|
assert_equal("New Topic", topic_reloaded.title)
|
|
297
576
|
end
|
|
298
577
|
|
|
299
|
-
def
|
|
578
|
+
def test_create_prefetched_pk
|
|
579
|
+
post = PostWithPrefetchedPk.create!(title: "New Message", body: "New Body")
|
|
580
|
+
assert_equal 123456, post.id
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
def test_create_model_with_uuid_pk_populates_id
|
|
584
|
+
message = ChatMessage.create(content: "New Message")
|
|
585
|
+
assert_not_nil message.id
|
|
586
|
+
|
|
587
|
+
message_reloaded = ChatMessage.find(message.id)
|
|
588
|
+
assert_equal "New Message", message_reloaded.content
|
|
589
|
+
end if current_adapter?(:PostgreSQLAdapter)
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
def test_create_model_with_custom_named_uuid_pk_populates_id
|
|
593
|
+
message = ChatMessageCustomPk.create(content: "New Message")
|
|
594
|
+
assert_not_nil message.message_id
|
|
595
|
+
|
|
596
|
+
message_reloaded = ChatMessageCustomPk.find(message.message_id)
|
|
597
|
+
assert_equal "New Message", message_reloaded.content
|
|
598
|
+
end if current_adapter?(:PostgreSQLAdapter)
|
|
599
|
+
|
|
600
|
+
def test_build
|
|
601
|
+
topic = Topic.build(title: "New Topic")
|
|
602
|
+
assert_equal "New Topic", topic.title
|
|
603
|
+
assert_not_predicate topic, :persisted?
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
def test_build_many
|
|
607
|
+
topics = Topic.build([{ title: "first" }, { title: "second" }])
|
|
608
|
+
assert_equal ["first", "second"], topics.map(&:title)
|
|
609
|
+
topics.each { |topic| assert_not_predicate topic, :persisted? }
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
def test_build_through_factory_with_block
|
|
613
|
+
topic = Topic.build("title" => "New Topic") do |t|
|
|
614
|
+
t.author_name = "David"
|
|
615
|
+
end
|
|
616
|
+
assert_equal("New Topic", topic.title)
|
|
617
|
+
assert_equal("David", topic.author_name)
|
|
618
|
+
assert_not_predicate topic, :persisted?
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
def test_build_many_through_factory_with_block
|
|
622
|
+
topics = Topic.build([{ "title" => "first" }, { "title" => "second" }]) do |t|
|
|
623
|
+
t.author_name = "David"
|
|
624
|
+
end
|
|
625
|
+
assert_equal 2, topics.size
|
|
626
|
+
topics.each { |topic| assert_not_predicate topic, :persisted? }
|
|
627
|
+
topic1, topic2 = topics
|
|
628
|
+
assert_equal "first", topic1.title
|
|
629
|
+
assert_equal "David", topic1.author_name
|
|
630
|
+
assert_equal "second", topic2.title
|
|
631
|
+
assert_equal "David", topic2.author_name
|
|
632
|
+
end
|
|
633
|
+
|
|
634
|
+
def test_save_valid_record
|
|
300
635
|
topic = Topic.new(title: "New Topic")
|
|
301
636
|
assert topic.save!
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
def test_save_invalid_record
|
|
640
|
+
reply = WrongReply.new(title: "New reply")
|
|
641
|
+
error = assert_raise(ActiveRecord::RecordInvalid) { reply.save! }
|
|
642
|
+
|
|
643
|
+
assert_equal "Validation failed: Content Empty", error.message
|
|
644
|
+
end
|
|
645
|
+
|
|
646
|
+
def test_save_destroyed_object
|
|
647
|
+
topic = Topic.create!(title: "New Topic")
|
|
648
|
+
topic.destroy!
|
|
649
|
+
|
|
650
|
+
error = assert_raise(ActiveRecord::RecordNotSaved) { topic.save! }
|
|
302
651
|
|
|
303
|
-
|
|
304
|
-
assert_raise(ActiveRecord::RecordInvalid) { reply.save! }
|
|
652
|
+
assert_equal "Failed to save the record", error.message
|
|
305
653
|
end
|
|
306
654
|
|
|
307
655
|
def test_save_null_string_attributes
|
|
@@ -440,7 +788,7 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
440
788
|
|
|
441
789
|
def test_becomes_default_sti_subclass
|
|
442
790
|
original_type = Topic.columns_hash["type"].default
|
|
443
|
-
ActiveRecord::Base.
|
|
791
|
+
ActiveRecord::Base.lease_connection.change_column_default :topics, :type, "Reply"
|
|
444
792
|
Topic.reset_column_information
|
|
445
793
|
|
|
446
794
|
reply = topics(:second)
|
|
@@ -450,7 +798,7 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
450
798
|
assert_instance_of Topic, topic
|
|
451
799
|
|
|
452
800
|
ensure
|
|
453
|
-
ActiveRecord::Base.
|
|
801
|
+
ActiveRecord::Base.lease_connection.change_column_default :topics, :type, original_type
|
|
454
802
|
Topic.reset_column_information
|
|
455
803
|
end
|
|
456
804
|
|
|
@@ -470,6 +818,51 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
470
818
|
assert_equal("David", topic_reloaded.author_name)
|
|
471
819
|
end
|
|
472
820
|
|
|
821
|
+
def test_update_attribute_after_update
|
|
822
|
+
klass = Class.new(Topic) do
|
|
823
|
+
def self.name; "Topic"; end
|
|
824
|
+
after_update :update_author, if: :saved_change_to_title?
|
|
825
|
+
def update_author
|
|
826
|
+
update_attribute("author_name", "David")
|
|
827
|
+
end
|
|
828
|
+
end
|
|
829
|
+
topic = klass.create(title: "New Topic")
|
|
830
|
+
topic.update(title: "Another Topic")
|
|
831
|
+
|
|
832
|
+
topic_reloaded = Topic.find(topic.id)
|
|
833
|
+
assert_equal("Another Topic", topic_reloaded.title)
|
|
834
|
+
assert_equal("David", topic_reloaded.author_name)
|
|
835
|
+
end
|
|
836
|
+
|
|
837
|
+
def test_update_attribute_in_before_validation_respects_callback_chain
|
|
838
|
+
klass = Class.new(Topic) do
|
|
839
|
+
def self.name; "Topic"; end
|
|
840
|
+
|
|
841
|
+
before_validation :set_author_name
|
|
842
|
+
after_create :track_create
|
|
843
|
+
after_update :call_once, if: :saved_change_to_author_name?
|
|
844
|
+
|
|
845
|
+
attr_reader :counter
|
|
846
|
+
|
|
847
|
+
def set_author_name
|
|
848
|
+
update_attribute :author_name, "David"
|
|
849
|
+
end
|
|
850
|
+
|
|
851
|
+
def track_create
|
|
852
|
+
call_once if saved_change_to_author_name?
|
|
853
|
+
end
|
|
854
|
+
|
|
855
|
+
def call_once
|
|
856
|
+
@counter ||= 0
|
|
857
|
+
@counter += 1
|
|
858
|
+
end
|
|
859
|
+
end
|
|
860
|
+
|
|
861
|
+
comment = klass.create(title: "New Topic", author_name: "Not David")
|
|
862
|
+
|
|
863
|
+
assert_equal 1, comment.counter
|
|
864
|
+
end
|
|
865
|
+
|
|
473
866
|
def test_update_attribute_does_not_run_sql_if_attribute_is_not_changed
|
|
474
867
|
topic = Topic.create(title: "Another New Topic")
|
|
475
868
|
assert_no_queries do
|
|
@@ -487,7 +880,7 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
487
880
|
def test_delete
|
|
488
881
|
topic = Topic.find(1)
|
|
489
882
|
assert_equal topic, topic.delete, "topic.delete did not return self"
|
|
490
|
-
|
|
883
|
+
assert_predicate topic, :frozen?, "topic not frozen after delete"
|
|
491
884
|
assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
|
|
492
885
|
end
|
|
493
886
|
|
|
@@ -506,17 +899,25 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
506
899
|
def test_destroy
|
|
507
900
|
topic = Topic.find(1)
|
|
508
901
|
assert_equal topic, topic.destroy, "topic.destroy did not return self"
|
|
509
|
-
|
|
902
|
+
assert_predicate topic, :frozen?, "topic not frozen after destroy"
|
|
510
903
|
assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
|
|
511
904
|
end
|
|
512
905
|
|
|
513
906
|
def test_destroy!
|
|
514
907
|
topic = Topic.find(1)
|
|
515
908
|
assert_equal topic, topic.destroy!, "topic.destroy! did not return self"
|
|
516
|
-
|
|
909
|
+
assert_predicate topic, :frozen?, "topic not frozen after destroy!"
|
|
517
910
|
assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
|
|
518
911
|
end
|
|
519
912
|
|
|
913
|
+
def test_destroy_for_a_failed_to_destroy_cpk_record
|
|
914
|
+
book = cpk_books(:cpk_great_author_first_book)
|
|
915
|
+
book.fail_destroy = true
|
|
916
|
+
assert_raises(ActiveRecord::RecordNotDestroyed, match: /Failed to destroy Cpk::Book with \["author_id", "id"\]=/) do
|
|
917
|
+
book.destroy!
|
|
918
|
+
end
|
|
919
|
+
end
|
|
920
|
+
|
|
520
921
|
def test_find_raises_record_not_found_exception
|
|
521
922
|
assert_raise(ActiveRecord::RecordNotFound) { Topic.find(99999) }
|
|
522
923
|
end
|
|
@@ -551,6 +952,16 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
551
952
|
assert_nil Topic.find(2).last_read
|
|
552
953
|
end
|
|
553
954
|
|
|
955
|
+
def test_update_all_with_custom_sql_as_value
|
|
956
|
+
person = people(:michael)
|
|
957
|
+
person.update!(cars_count: 0)
|
|
958
|
+
|
|
959
|
+
Person.update_all(cars_count: Arel.sql(<<~SQL))
|
|
960
|
+
select count(*) from cars where cars.person_id = people.id
|
|
961
|
+
SQL
|
|
962
|
+
assert_equal 1, person.reload.cars_count
|
|
963
|
+
end
|
|
964
|
+
|
|
554
965
|
def test_delete_new_record
|
|
555
966
|
client = Client.new(name: "37signals")
|
|
556
967
|
client.delete
|
|
@@ -644,6 +1055,69 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
644
1055
|
assert_not_equal prev_month, developer.updated_at
|
|
645
1056
|
end
|
|
646
1057
|
|
|
1058
|
+
def test_update_attribute!
|
|
1059
|
+
assert_not_predicate Topic.find(1), :approved?
|
|
1060
|
+
Topic.find(1).update_attribute!("approved", true)
|
|
1061
|
+
assert_predicate Topic.find(1), :approved?
|
|
1062
|
+
|
|
1063
|
+
Topic.find(1).update_attribute!(:approved, false)
|
|
1064
|
+
assert_not_predicate Topic.find(1), :approved?
|
|
1065
|
+
|
|
1066
|
+
Topic.find(1).update_attribute!(:change_approved_before_save, true)
|
|
1067
|
+
assert_predicate Topic.find(1), :approved?
|
|
1068
|
+
end
|
|
1069
|
+
|
|
1070
|
+
def test_update_attribute_for_readonly_attribute!
|
|
1071
|
+
minivan = Minivan.find("m1")
|
|
1072
|
+
assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_attribute!(:color, "black") }
|
|
1073
|
+
end
|
|
1074
|
+
|
|
1075
|
+
def test_update_attribute_with_one_updated!
|
|
1076
|
+
t = Topic.first
|
|
1077
|
+
t.update_attribute!(:title, "super_title")
|
|
1078
|
+
assert_equal "super_title", t.title
|
|
1079
|
+
assert_not t.changed?, "topic should not have changed"
|
|
1080
|
+
assert_not t.title_changed?, "title should not have changed"
|
|
1081
|
+
assert_nil t.title_change, "title change should be nil"
|
|
1082
|
+
|
|
1083
|
+
t.reload
|
|
1084
|
+
assert_equal "super_title", t.title
|
|
1085
|
+
end
|
|
1086
|
+
|
|
1087
|
+
def test_update_attribute_for_updated_at_on!
|
|
1088
|
+
developer = Developer.find(1)
|
|
1089
|
+
prev_month = Time.now.prev_month.change(usec: 0)
|
|
1090
|
+
|
|
1091
|
+
developer.update_attribute!(:updated_at, prev_month)
|
|
1092
|
+
assert_equal prev_month, developer.updated_at
|
|
1093
|
+
|
|
1094
|
+
developer.update_attribute!(:salary, 80001)
|
|
1095
|
+
assert_not_equal prev_month, developer.updated_at
|
|
1096
|
+
|
|
1097
|
+
developer.reload
|
|
1098
|
+
assert_not_equal prev_month, developer.updated_at
|
|
1099
|
+
end
|
|
1100
|
+
|
|
1101
|
+
def test_update_attribute_for_aborted_callback!
|
|
1102
|
+
klass = Class.new(Topic) do
|
|
1103
|
+
def self.name; "Topic"; end
|
|
1104
|
+
|
|
1105
|
+
before_update :throw_abort
|
|
1106
|
+
|
|
1107
|
+
def throw_abort
|
|
1108
|
+
throw(:abort)
|
|
1109
|
+
end
|
|
1110
|
+
end
|
|
1111
|
+
|
|
1112
|
+
t = klass.create(title: "New Topic", author_name: "Not David")
|
|
1113
|
+
|
|
1114
|
+
assert_raises(ActiveRecord::RecordNotSaved) { t.update_attribute!(:title, "super_title") }
|
|
1115
|
+
|
|
1116
|
+
t_reloaded = Topic.find(t.id)
|
|
1117
|
+
|
|
1118
|
+
assert_equal "New Topic", t_reloaded.title
|
|
1119
|
+
end
|
|
1120
|
+
|
|
647
1121
|
def test_update_column
|
|
648
1122
|
topic = Topic.find(1)
|
|
649
1123
|
topic.update_column("approved", true)
|
|
@@ -722,8 +1196,8 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
722
1196
|
t.update_column(:title, "super_title")
|
|
723
1197
|
assert_equal "John", t.author_name
|
|
724
1198
|
assert_equal "super_title", t.title
|
|
725
|
-
|
|
726
|
-
|
|
1199
|
+
assert_predicate t, :changed?, "topic should have changed"
|
|
1200
|
+
assert_predicate t, :author_name_changed?, "author_name should have changed"
|
|
727
1201
|
|
|
728
1202
|
t.reload
|
|
729
1203
|
assert_equal author_name, t.author_name
|
|
@@ -821,8 +1295,8 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
821
1295
|
t.update_columns(title: "super_title")
|
|
822
1296
|
assert_equal "John", t.author_name
|
|
823
1297
|
assert_equal "super_title", t.title
|
|
824
|
-
|
|
825
|
-
|
|
1298
|
+
assert_predicate t, :changed?, "topic should have changed"
|
|
1299
|
+
assert_predicate t, :author_name_changed?, "author_name should have changed"
|
|
826
1300
|
|
|
827
1301
|
t.reload
|
|
828
1302
|
assert_equal author_name, t.author_name
|
|
@@ -969,6 +1443,17 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
969
1443
|
assert_nothing_raised { Reply.find(should_not_be_destroyed_reply.id) }
|
|
970
1444
|
end
|
|
971
1445
|
|
|
1446
|
+
def test_class_level_delete_with_invalid_ids
|
|
1447
|
+
assert_no_queries do
|
|
1448
|
+
assert_equal 0, Topic.delete(nil)
|
|
1449
|
+
assert_equal 0, Topic.delete([])
|
|
1450
|
+
end
|
|
1451
|
+
|
|
1452
|
+
assert_difference -> { Topic.count }, -1 do
|
|
1453
|
+
assert_equal 1, Topic.delete(topics(:first).id)
|
|
1454
|
+
end
|
|
1455
|
+
end
|
|
1456
|
+
|
|
972
1457
|
def test_class_level_delete_is_affected_by_scoping
|
|
973
1458
|
should_not_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
|
|
974
1459
|
Topic.find(1).replies << should_not_be_destroyed_reply
|
|
@@ -1032,9 +1517,9 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
1032
1517
|
end
|
|
1033
1518
|
|
|
1034
1519
|
def test_reload_via_querycache
|
|
1035
|
-
ActiveRecord::Base.
|
|
1036
|
-
ActiveRecord::Base.
|
|
1037
|
-
assert ActiveRecord::Base.
|
|
1520
|
+
ActiveRecord::Base.lease_connection.enable_query_cache!
|
|
1521
|
+
ActiveRecord::Base.lease_connection.clear_query_cache
|
|
1522
|
+
assert ActiveRecord::Base.lease_connection.query_cache_enabled, "cache should be on"
|
|
1038
1523
|
parrot = Parrot.create(name: "Shane")
|
|
1039
1524
|
|
|
1040
1525
|
# populate the cache with the SELECT result
|
|
@@ -1042,7 +1527,7 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
1042
1527
|
assert_equal parrot.id, found_parrot.id
|
|
1043
1528
|
|
|
1044
1529
|
# Manually update the 'name' attribute in the DB directly
|
|
1045
|
-
assert_equal 1, ActiveRecord::Base.
|
|
1530
|
+
assert_equal 1, ActiveRecord::Base.lease_connection.query_cache.size
|
|
1046
1531
|
ActiveRecord::Base.uncached do
|
|
1047
1532
|
found_parrot.name = "Mary"
|
|
1048
1533
|
found_parrot.save
|
|
@@ -1055,7 +1540,7 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
1055
1540
|
found_parrot = Parrot.find(parrot.id)
|
|
1056
1541
|
assert_equal "Mary", found_parrot.name
|
|
1057
1542
|
ensure
|
|
1058
|
-
ActiveRecord::Base.
|
|
1543
|
+
ActiveRecord::Base.lease_connection.disable_query_cache!
|
|
1059
1544
|
end
|
|
1060
1545
|
|
|
1061
1546
|
def test_save_touch_false
|
|
@@ -1077,7 +1562,7 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
1077
1562
|
child_class = Class.new(Topic)
|
|
1078
1563
|
child_class.new # force schema to load
|
|
1079
1564
|
|
|
1080
|
-
ActiveRecord::Base.
|
|
1565
|
+
ActiveRecord::Base.lease_connection.add_column(:topics, :foo, :string)
|
|
1081
1566
|
Topic.reset_column_information
|
|
1082
1567
|
|
|
1083
1568
|
# this should redefine attribute methods
|
|
@@ -1087,7 +1572,129 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
1087
1572
|
assert child_class.instance_methods.include?(:foo_changed?)
|
|
1088
1573
|
assert_equal "bar", child_class.new(foo: :bar).foo
|
|
1089
1574
|
ensure
|
|
1090
|
-
ActiveRecord::Base.
|
|
1575
|
+
ActiveRecord::Base.lease_connection.remove_column(:topics, :foo)
|
|
1091
1576
|
Topic.reset_column_information
|
|
1092
1577
|
end
|
|
1578
|
+
|
|
1579
|
+
def test_update_uses_query_constraints_config
|
|
1580
|
+
clothing_item = clothing_items(:green_t_shirt)
|
|
1581
|
+
sql = capture_sql { clothing_item.update(description: "Lovely green t-shirt") }.second
|
|
1582
|
+
assert_match(/WHERE .*clothing_type/, sql)
|
|
1583
|
+
assert_match(/WHERE .*color/, sql)
|
|
1584
|
+
end
|
|
1585
|
+
|
|
1586
|
+
def test_save_uses_query_constraints_config
|
|
1587
|
+
clothing_item = clothing_items(:green_t_shirt)
|
|
1588
|
+
clothing_item.description = "Lovely green t-shirt"
|
|
1589
|
+
sql = capture_sql { clothing_item.save }.second
|
|
1590
|
+
assert_match(/WHERE .*clothing_type/, sql)
|
|
1591
|
+
assert_match(/WHERE .*color/, sql)
|
|
1592
|
+
end
|
|
1593
|
+
|
|
1594
|
+
def test_reload_uses_query_constraints_config
|
|
1595
|
+
clothing_item = clothing_items(:green_t_shirt)
|
|
1596
|
+
sql = capture_sql { clothing_item.reload }.first
|
|
1597
|
+
assert_match(/WHERE .*clothing_type/, sql)
|
|
1598
|
+
assert_match(/WHERE .*color/, sql)
|
|
1599
|
+
end
|
|
1600
|
+
|
|
1601
|
+
def test_destroy_uses_query_constraints_config
|
|
1602
|
+
clothing_item = clothing_items(:green_t_shirt)
|
|
1603
|
+
sql = capture_sql { clothing_item.destroy }.second
|
|
1604
|
+
assert_match(/WHERE .*clothing_type/, sql)
|
|
1605
|
+
assert_match(/WHERE .*color/, sql)
|
|
1606
|
+
end
|
|
1607
|
+
|
|
1608
|
+
def test_delete_uses_query_constraints_config
|
|
1609
|
+
clothing_item = clothing_items(:green_t_shirt)
|
|
1610
|
+
sql = capture_sql { clothing_item.delete }.first
|
|
1611
|
+
assert_match(/WHERE .*clothing_type/, sql)
|
|
1612
|
+
assert_match(/WHERE .*color/, sql)
|
|
1613
|
+
end
|
|
1614
|
+
|
|
1615
|
+
def test_update_attribute_uses_query_constraints_config
|
|
1616
|
+
clothing_item = clothing_items(:green_t_shirt)
|
|
1617
|
+
sql = capture_sql { clothing_item.update_attribute(:description, "Lovely green t-shirt") }.second
|
|
1618
|
+
assert_match(/WHERE .*clothing_type/, sql)
|
|
1619
|
+
assert_match(/WHERE .*color/, sql)
|
|
1620
|
+
end
|
|
1621
|
+
|
|
1622
|
+
def test_it_is_possible_to_update_parts_of_the_query_constraints_config
|
|
1623
|
+
clothing_item = clothing_items(:green_t_shirt)
|
|
1624
|
+
clothing_item.color = "blue"
|
|
1625
|
+
clothing_item.description = "Now it's a blue t-shirt"
|
|
1626
|
+
sql = capture_sql { clothing_item.save }.second
|
|
1627
|
+
assert_match(/WHERE .*clothing_type/, sql)
|
|
1628
|
+
assert_match(/WHERE .*color/, sql)
|
|
1629
|
+
|
|
1630
|
+
assert_equal("blue", ClothingItem.find_by(id: clothing_item.id).color)
|
|
1631
|
+
end
|
|
1632
|
+
|
|
1633
|
+
def test_model_with_no_auto_populated_fields_still_returns_primary_key_after_insert
|
|
1634
|
+
record = PkAutopopulatedByATriggerRecord.create
|
|
1635
|
+
|
|
1636
|
+
assert_not_nil record.id
|
|
1637
|
+
assert record.id > 0
|
|
1638
|
+
end if supports_insert_returning? && !current_adapter?(:SQLite3Adapter)
|
|
1639
|
+
end
|
|
1640
|
+
|
|
1641
|
+
class QueryConstraintsTest < ActiveRecord::TestCase
|
|
1642
|
+
fixtures :clothing_items, :dashboards, :topics, :posts
|
|
1643
|
+
|
|
1644
|
+
def test_primary_key_stays_the_same
|
|
1645
|
+
assert_equal("id", ClothingItem.primary_key)
|
|
1646
|
+
end
|
|
1647
|
+
|
|
1648
|
+
def test_query_constraints_list_is_nil_if_primary_key_is_nil
|
|
1649
|
+
klass = Class.new(ActiveRecord::Base) do
|
|
1650
|
+
self.table_name = "developers_projects"
|
|
1651
|
+
end
|
|
1652
|
+
|
|
1653
|
+
assert_nil klass.primary_key
|
|
1654
|
+
assert_nil klass.query_constraints_list
|
|
1655
|
+
end
|
|
1656
|
+
|
|
1657
|
+
def test_query_constraints_list_is_nil_for_non_cpk_model
|
|
1658
|
+
assert_nil Post.query_constraints_list
|
|
1659
|
+
assert_nil Dashboard.query_constraints_list
|
|
1660
|
+
end
|
|
1661
|
+
|
|
1662
|
+
def test_query_constraints_list_equals_to_composite_primary_key
|
|
1663
|
+
assert_equal(["shop_id", "id"], Cpk::Order.query_constraints_list)
|
|
1664
|
+
assert_equal(["author_id", "id"], Cpk::Book.query_constraints_list)
|
|
1665
|
+
end
|
|
1666
|
+
|
|
1667
|
+
def test_child_keeps_parents_query_constraints
|
|
1668
|
+
clothing_item = clothing_items(:green_t_shirt)
|
|
1669
|
+
assert_uses_query_constraints_on_reload(clothing_item, ["clothing_type", "color"])
|
|
1670
|
+
|
|
1671
|
+
used_clothing_item = clothing_items(:used_blue_jeans)
|
|
1672
|
+
assert_uses_query_constraints_on_reload(used_clothing_item, ["clothing_type", "color"])
|
|
1673
|
+
end
|
|
1674
|
+
|
|
1675
|
+
def test_child_keeps_parents_query_contraints_derived_from_composite_pk
|
|
1676
|
+
assert_equal(["author_id", "id"], Cpk::BestSeller.query_constraints_list)
|
|
1677
|
+
end
|
|
1678
|
+
|
|
1679
|
+
def assert_uses_query_constraints_on_reload(object, columns)
|
|
1680
|
+
flunk("columns argument must not be empty") if columns.blank?
|
|
1681
|
+
|
|
1682
|
+
sql = capture_sql { object.reload }.first
|
|
1683
|
+
Array(columns).each do |column|
|
|
1684
|
+
assert_match(/WHERE .*#{column}/, sql)
|
|
1685
|
+
end
|
|
1686
|
+
end
|
|
1687
|
+
|
|
1688
|
+
def test_query_constraints_raises_an_error_when_no_columns_provided
|
|
1689
|
+
assert_raises(ArgumentError) do
|
|
1690
|
+
Class.new(ActiveRecord::Base) do
|
|
1691
|
+
self.table_name = "topics"
|
|
1692
|
+
query_constraints
|
|
1693
|
+
end
|
|
1694
|
+
end
|
|
1695
|
+
end
|
|
1696
|
+
|
|
1697
|
+
def test_child_class_with_query_constraints_overrides_parents
|
|
1698
|
+
assert_equal(["clothing_type", "color", "size"], ClothingItem::Sized.query_constraints_list)
|
|
1699
|
+
end
|
|
1093
1700
|
end
|