ibm_db 5.2.0-x86-mingw32 → 5.4.0-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +9 -0
- data/LICENSE +55 -18
- data/README +1 -1
- data/debug.log +1 -0
- data/ext/Makefile +28 -24
- data/ext/ibm_db.c +66 -65
- data/ext/ibm_db.o +0 -0
- data/ext/ibm_db.so +0 -0
- data/ext/mkmf.log +26 -24
- data/ext/ruby_ibm_db_cli.c +1 -0
- data/ext/ruby_ibm_db_cli.o +0 -0
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1520 -1282
- data/lib/ibm_db.so +1 -0
- data/lib/mswin32/ibm_db.rb +3 -1
- data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
- data/lib/mswin32/rb3x/i386/ruby31/ibm_db.so +0 -0
- data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
- data/test/activejob/destroy_association_async_test.rb +305 -0
- data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
- data/test/activejob/helper.rb +15 -0
- data/test/assets/schema_dump_5_1.yml +345 -0
- data/test/cases/adapter_prevent_writes_test.rb +334 -0
- data/test/cases/adapter_test.rb +432 -218
- data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
- data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
- data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
- data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
- data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
- data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
- data/test/cases/adapters/mysql2/connection_test.rb +48 -50
- data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
- data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
- data/test/cases/adapters/mysql2/enum_test.rb +32 -11
- data/test/cases/adapters/mysql2/explain_test.rb +13 -11
- data/test/cases/adapters/mysql2/json_test.rb +17 -188
- data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
- data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
- data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
- data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
- data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
- data/test/cases/adapters/mysql2/schema_test.rb +24 -22
- data/test/cases/adapters/mysql2/set_test.rb +32 -0
- data/test/cases/adapters/mysql2/sp_test.rb +10 -8
- data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
- data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
- data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
- data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
- data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
- data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
- data/test/cases/adapters/postgresql/array_test.rb +118 -63
- data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
- data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
- data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
- data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
- data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
- data/test/cases/adapters/postgresql/citext_test.rb +58 -58
- data/test/cases/adapters/postgresql/collation_test.rb +17 -15
- data/test/cases/adapters/postgresql/composite_test.rb +25 -23
- data/test/cases/adapters/postgresql/connection_test.rb +73 -85
- data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
- data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
- data/test/cases/adapters/postgresql/date_test.rb +42 -0
- data/test/cases/adapters/postgresql/domain_test.rb +9 -7
- data/test/cases/adapters/postgresql/enum_test.rb +12 -10
- data/test/cases/adapters/postgresql/explain_test.rb +10 -8
- data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
- data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
- data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
- data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
- data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
- data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
- data/test/cases/adapters/postgresql/integer_test.rb +2 -0
- data/test/cases/adapters/postgresql/interval_test.rb +99 -0
- data/test/cases/adapters/postgresql/json_test.rb +16 -201
- data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
- data/test/cases/adapters/postgresql/money_test.rb +47 -16
- data/test/cases/adapters/postgresql/network_test.rb +36 -28
- data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
- data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
- data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
- data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
- data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
- data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
- data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
- data/test/cases/adapters/postgresql/range_test.rb +406 -292
- data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
- data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
- data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
- data/test/cases/adapters/postgresql/schema_test.rb +207 -91
- data/test/cases/adapters/postgresql/serial_test.rb +9 -7
- data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
- data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
- data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
- data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
- data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
- data/test/cases/adapters/postgresql/utils_test.rb +11 -9
- data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
- data/test/cases/adapters/postgresql/xml_test.rb +10 -14
- data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
- data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
- data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
- data/test/cases/adapters/sqlite3/json_test.rb +29 -0
- data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
- data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
- data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
- data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
- data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
- data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
- data/test/cases/aggregations_test.rb +14 -12
- data/test/cases/annotate_test.rb +46 -0
- data/test/cases/ar_schema_test.rb +153 -86
- data/test/cases/arel/attributes/attribute_test.rb +1145 -0
- data/test/cases/arel/attributes/math_test.rb +83 -0
- data/test/cases/arel/attributes_test.rb +27 -0
- data/test/cases/arel/collectors/bind_test.rb +40 -0
- data/test/cases/arel/collectors/composite_test.rb +47 -0
- data/test/cases/arel/collectors/sql_string_test.rb +41 -0
- data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
- data/test/cases/arel/crud_test.rb +65 -0
- data/test/cases/arel/delete_manager_test.rb +53 -0
- data/test/cases/arel/factory_methods_test.rb +46 -0
- data/test/cases/arel/helper.rb +45 -0
- data/test/cases/arel/insert_manager_test.rb +241 -0
- data/test/cases/arel/nodes/and_test.rb +30 -0
- data/test/cases/arel/nodes/as_test.rb +36 -0
- data/test/cases/arel/nodes/ascending_test.rb +46 -0
- data/test/cases/arel/nodes/bin_test.rb +35 -0
- data/test/cases/arel/nodes/binary_test.rb +29 -0
- data/test/cases/arel/nodes/bind_param_test.rb +22 -0
- data/test/cases/arel/nodes/case_test.rb +96 -0
- data/test/cases/arel/nodes/casted_test.rb +18 -0
- data/test/cases/arel/nodes/comment_test.rb +22 -0
- data/test/cases/arel/nodes/count_test.rb +35 -0
- data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
- data/test/cases/arel/nodes/descending_test.rb +46 -0
- data/test/cases/arel/nodes/distinct_test.rb +21 -0
- data/test/cases/arel/nodes/equality_test.rb +62 -0
- data/test/cases/arel/nodes/extract_test.rb +43 -0
- data/test/cases/arel/nodes/false_test.rb +21 -0
- data/test/cases/arel/nodes/grouping_test.rb +26 -0
- data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
- data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
- data/test/cases/arel/nodes/named_function_test.rb +48 -0
- data/test/cases/arel/nodes/node_test.rb +22 -0
- data/test/cases/arel/nodes/not_test.rb +31 -0
- data/test/cases/arel/nodes/or_test.rb +36 -0
- data/test/cases/arel/nodes/over_test.rb +69 -0
- data/test/cases/arel/nodes/select_core_test.rb +79 -0
- data/test/cases/arel/nodes/select_statement_test.rb +51 -0
- data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
- data/test/cases/arel/nodes/sum_test.rb +35 -0
- data/test/cases/arel/nodes/table_alias_test.rb +29 -0
- data/test/cases/arel/nodes/true_test.rb +21 -0
- data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
- data/test/cases/arel/nodes/update_statement_test.rb +60 -0
- data/test/cases/arel/nodes/window_test.rb +81 -0
- data/test/cases/arel/nodes_test.rb +34 -0
- data/test/cases/arel/select_manager_test.rb +1238 -0
- data/test/cases/arel/support/fake_record.rb +135 -0
- data/test/cases/arel/table_test.rb +216 -0
- data/test/cases/arel/update_manager_test.rb +126 -0
- data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
- data/test/cases/arel/visitors/dot_test.rb +90 -0
- data/test/cases/arel/visitors/mysql_test.rb +157 -0
- data/test/cases/arel/visitors/postgres_test.rb +366 -0
- data/test/cases/arel/visitors/sqlite_test.rb +75 -0
- data/test/cases/arel/visitors/to_sql_test.rb +750 -0
- data/test/cases/associations/belongs_to_associations_test.rb +510 -158
- data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
- data/test/cases/associations/callbacks_test.rb +56 -38
- data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
- data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
- data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
- data/test/cases/associations/eager_singularization_test.rb +21 -21
- data/test/cases/associations/eager_test.rb +559 -415
- data/test/cases/associations/extension_test.rb +18 -12
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
- data/test/cases/associations/has_many_associations_test.rb +1038 -465
- data/test/cases/associations/has_many_through_associations_test.rb +558 -249
- data/test/cases/associations/has_one_associations_test.rb +294 -129
- data/test/cases/associations/has_one_through_associations_test.rb +121 -75
- data/test/cases/associations/inner_join_association_test.rb +114 -38
- data/test/cases/associations/inverse_associations_test.rb +606 -398
- data/test/cases/associations/join_model_test.rb +158 -148
- data/test/cases/associations/left_outer_join_association_test.rb +59 -24
- data/test/cases/associations/nested_through_associations_test.rb +166 -109
- data/test/cases/associations/required_test.rb +35 -10
- data/test/cases/associations_test.rb +241 -110
- data/test/cases/attribute_methods/read_test.rb +11 -11
- data/test/cases/attribute_methods_test.rb +413 -298
- data/test/cases/attributes_test.rb +145 -27
- data/test/cases/autosave_association_test.rb +681 -436
- data/test/cases/base_prevent_writes_test.rb +229 -0
- data/test/cases/base_test.rb +599 -542
- data/test/cases/batches_test.rb +288 -82
- data/test/cases/binary_test.rb +26 -31
- data/test/cases/bind_parameter_test.rb +194 -21
- data/test/cases/boolean_test.rb +52 -0
- data/test/cases/cache_key_test.rb +110 -5
- data/test/cases/calculations_test.rb +740 -177
- data/test/cases/callbacks_test.rb +74 -207
- data/test/cases/clone_test.rb +15 -10
- data/test/cases/coders/json_test.rb +2 -0
- data/test/cases/coders/yaml_column_test.rb +16 -13
- data/test/cases/collection_cache_key_test.rb +177 -20
- data/test/cases/column_alias_test.rb +9 -7
- data/test/cases/column_definition_test.rb +10 -68
- data/test/cases/comment_test.rb +166 -107
- data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
- data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
- data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
- data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
- data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
- data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
- data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
- data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
- data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
- data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
- data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
- data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
- data/test/cases/connection_management_test.rb +13 -11
- data/test/cases/connection_pool_test.rb +316 -83
- data/test/cases/core_test.rb +82 -58
- data/test/cases/counter_cache_test.rb +204 -50
- data/test/cases/custom_locking_test.rb +5 -3
- data/test/cases/database_configurations/hash_config_test.rb +74 -0
- data/test/cases/database_configurations/resolver_test.rb +150 -0
- data/test/cases/database_configurations_test.rb +145 -0
- data/test/cases/database_selector_test.rb +296 -0
- data/test/cases/database_statements_test.rb +18 -16
- data/test/cases/date_test.rb +8 -16
- data/test/cases/date_time_precision_test.rb +100 -78
- data/test/cases/date_time_test.rb +23 -8
- data/test/cases/defaults_test.rb +106 -71
- data/test/cases/delegated_type_test.rb +57 -0
- data/test/cases/dirty_test.rb +419 -223
- data/test/cases/disconnected_test.rb +6 -6
- data/test/cases/dup_test.rb +54 -27
- data/test/cases/enum_test.rb +461 -82
- data/test/cases/errors_test.rb +7 -7
- data/test/cases/explain_subscriber_test.rb +17 -15
- data/test/cases/explain_test.rb +11 -19
- data/test/cases/filter_attributes_test.rb +153 -0
- data/test/cases/finder_respond_to_test.rb +14 -14
- data/test/cases/finder_test.rb +669 -287
- data/test/cases/fixture_set/file_test.rb +34 -38
- data/test/cases/fixtures_test.rb +833 -176
- data/test/cases/forbidden_attributes_protection_test.rb +32 -67
- data/test/cases/habtm_destroy_order_test.rb +25 -25
- data/test/cases/helper.rb +78 -49
- data/test/cases/hot_compatibility_test.rb +33 -32
- data/test/cases/i18n_test.rb +18 -17
- data/test/cases/inheritance_test.rb +180 -115
- data/test/cases/insert_all_test.rb +489 -0
- data/test/cases/instrumentation_test.rb +101 -0
- data/test/cases/integration_test.rb +119 -31
- data/test/cases/invalid_connection_test.rb +18 -16
- data/test/cases/invertible_migration_test.rb +183 -43
- data/test/cases/json_attribute_test.rb +35 -0
- data/test/cases/json_serialization_test.rb +57 -58
- data/test/cases/json_shared_test_cases.rb +290 -0
- data/test/cases/locking_test.rb +413 -119
- data/test/cases/log_subscriber_test.rb +68 -26
- data/test/cases/marshal_serialization_test.rb +39 -0
- data/test/cases/migration/change_schema_test.rb +118 -72
- data/test/cases/migration/change_table_test.rb +138 -30
- data/test/cases/migration/check_constraint_test.rb +162 -0
- data/test/cases/migration/column_attributes_test.rb +45 -35
- data/test/cases/migration/column_positioning_test.rb +18 -6
- data/test/cases/migration/columns_test.rb +93 -77
- data/test/cases/migration/command_recorder_test.rb +121 -34
- data/test/cases/migration/compatibility_test.rb +578 -23
- data/test/cases/migration/create_join_table_test.rb +35 -25
- data/test/cases/migration/foreign_key_test.rb +503 -284
- data/test/cases/migration/helper.rb +4 -3
- data/test/cases/migration/index_test.rb +119 -70
- data/test/cases/migration/logger_test.rb +9 -6
- data/test/cases/migration/pending_migrations_test.rb +88 -34
- data/test/cases/migration/references_foreign_key_test.rb +164 -150
- data/test/cases/migration/references_index_test.rb +38 -19
- data/test/cases/migration/references_statements_test.rb +15 -14
- data/test/cases/migration/rename_table_test.rb +53 -30
- data/test/cases/migration_test.rb +637 -269
- data/test/cases/migrator_test.rb +191 -135
- data/test/cases/mixin_test.rb +7 -11
- data/test/cases/modules_test.rb +36 -34
- data/test/cases/multi_db_migrator_test.rb +223 -0
- data/test/cases/multiparameter_attributes_test.rb +60 -33
- data/test/cases/multiple_db_test.rb +16 -22
- data/test/cases/nested_attributes_test.rb +341 -320
- data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
- data/test/cases/null_relation_test.rb +84 -0
- data/test/cases/numeric_data_test.rb +93 -0
- data/test/cases/persistence_test.rb +361 -269
- data/test/cases/pooled_connections_test.rb +18 -26
- data/test/cases/prepared_statement_status_test.rb +48 -0
- data/test/cases/primary_keys_test.rb +210 -104
- data/test/cases/query_cache_test.rb +610 -141
- data/test/cases/quoting_test.rb +132 -31
- data/test/cases/readonly_test.rb +49 -48
- data/test/cases/reaper_test.rb +146 -32
- data/test/cases/reflection_test.rb +167 -156
- data/test/cases/relation/delegation_test.rb +49 -36
- data/test/cases/relation/delete_all_test.rb +117 -0
- data/test/cases/relation/merging_test.rb +319 -42
- data/test/cases/relation/mutation_test.rb +55 -93
- data/test/cases/relation/or_test.rb +129 -29
- data/test/cases/relation/predicate_builder_test.rb +21 -6
- data/test/cases/relation/record_fetch_warning_test.rb +5 -3
- data/test/cases/relation/select_test.rb +67 -0
- data/test/cases/relation/update_all_test.rb +317 -0
- data/test/cases/relation/where_chain_test.rb +68 -32
- data/test/cases/relation/where_clause_test.rb +136 -61
- data/test/cases/relation/where_test.rb +155 -48
- data/test/cases/relation_test.rb +266 -112
- data/test/cases/relations_test.rb +969 -744
- data/test/cases/reload_models_test.rb +13 -9
- data/test/cases/reserved_word_test.rb +141 -0
- data/test/cases/result_test.rb +68 -17
- data/test/cases/sanitize_test.rb +87 -71
- data/test/cases/schema_dumper_test.rb +221 -128
- data/test/cases/schema_loading_test.rb +3 -2
- data/test/cases/scoping/default_scoping_test.rb +185 -144
- data/test/cases/scoping/named_scoping_test.rb +177 -89
- data/test/cases/scoping/relation_scoping_test.rb +197 -75
- data/test/cases/secure_token_test.rb +18 -3
- data/test/cases/serialization_test.rb +30 -28
- data/test/cases/serialized_attribute_test.rb +133 -42
- data/test/cases/signed_id_test.rb +168 -0
- data/test/cases/statement_cache_test.rb +41 -24
- data/test/cases/statement_invalid_test.rb +42 -0
- data/test/cases/store_test.rb +180 -55
- data/test/cases/strict_loading_test.rb +473 -0
- data/test/cases/suppressor_test.rb +26 -12
- data/test/cases/tasks/database_tasks_test.rb +1258 -194
- data/test/cases/tasks/mysql_rake_test.rb +370 -298
- data/test/cases/tasks/postgresql_rake_test.rb +481 -251
- data/test/cases/tasks/sqlite_rake_test.rb +225 -178
- data/test/cases/test_case.rb +51 -40
- data/test/cases/test_databases_test.rb +79 -0
- data/test/cases/test_fixtures_test.rb +79 -19
- data/test/cases/time_precision_test.rb +98 -76
- data/test/cases/timestamp_test.rb +102 -99
- data/test/cases/touch_later_test.rb +12 -10
- data/test/cases/transaction_callbacks_test.rb +344 -90
- data/test/cases/transaction_isolation_test.rb +12 -12
- data/test/cases/transactions_test.rb +612 -162
- data/test/cases/type/adapter_specific_registry_test.rb +14 -2
- data/test/cases/type/date_time_test.rb +4 -2
- data/test/cases/type/integer_test.rb +4 -2
- data/test/cases/type/string_test.rb +10 -8
- data/test/cases/type/time_test.rb +28 -0
- data/test/cases/type/type_map_test.rb +29 -28
- data/test/cases/type/unsigned_integer_test.rb +19 -0
- data/test/cases/type_test.rb +2 -0
- data/test/cases/types_test.rb +3 -1
- data/test/cases/unconnected_test.rb +14 -1
- data/test/cases/unsafe_raw_sql_test.rb +274 -0
- data/test/cases/validations/absence_validation_test.rb +19 -17
- data/test/cases/validations/association_validation_test.rb +30 -28
- data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
- data/test/cases/validations/i18n_validation_test.rb +22 -21
- data/test/cases/validations/length_validation_test.rb +34 -33
- data/test/cases/validations/numericality_validation_test.rb +181 -0
- data/test/cases/validations/presence_validation_test.rb +21 -19
- data/test/cases/validations/uniqueness_validation_test.rb +156 -86
- data/test/cases/validations_repair_helper.rb +2 -0
- data/test/cases/validations_test.rb +61 -26
- data/test/cases/view_test.rb +122 -116
- data/test/cases/yaml_serialization_test.rb +79 -34
- data/test/config.example.yml +19 -19
- data/test/config.rb +3 -1
- data/test/config.yml +16 -6
- data/test/fixtures/all/namespaced/accounts.yml +2 -0
- data/test/fixtures/author_addresses.yml +1 -8
- data/test/fixtures/authors.yml +1 -7
- data/test/fixtures/binaries.yml +4 -0
- data/test/fixtures/books.yml +9 -2
- data/test/fixtures/categories_posts.yml +3 -0
- data/test/fixtures/citations.yml +5 -0
- data/test/fixtures/comments.yml +7 -0
- data/test/fixtures/companies.yml +5 -0
- data/test/fixtures/computers.yml +2 -0
- data/test/fixtures/customers.yml +10 -1
- data/test/fixtures/developers.yml +1 -1
- data/test/fixtures/essays.yml +10 -0
- data/test/fixtures/faces.yml +3 -3
- data/test/fixtures/humans.yml +5 -0
- data/test/fixtures/interests.yml +7 -7
- data/test/fixtures/memberships.yml +7 -0
- data/test/fixtures/minimalistics.yml +3 -0
- data/test/fixtures/mixed_case_monkeys.yml +2 -2
- data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
- data/test/fixtures/naked/yml/parrots.yml +1 -0
- data/test/fixtures/other_books.yml +26 -0
- data/test/fixtures/other_posts.yml +1 -0
- data/test/fixtures/parrots.yml +7 -1
- data/test/fixtures/pirates.yml +3 -0
- data/test/fixtures/posts.yml +11 -3
- data/test/fixtures/readers.yml +6 -0
- data/test/fixtures/reserved_words/values.yml +2 -2
- data/test/fixtures/sponsors.yml +3 -0
- data/test/fixtures/strict_zines.yml +2 -0
- data/test/fixtures/subscribers.yml +1 -1
- data/test/fixtures/tasks.yml +1 -1
- data/test/fixtures/warehouse-things.yml +3 -0
- data/test/migrations/10_urban/9_add_expressions.rb +2 -0
- data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
- data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
- data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
- data/test/migrations/missing/1_people_have_last_names.rb +2 -0
- data/test/migrations/missing/3_we_need_reminders.rb +2 -0
- data/test/migrations/missing/4_innocent_jointable.rb +3 -1
- data/test/migrations/rename/1_we_need_things.rb +2 -0
- data/test/migrations/rename/2_rename_things.rb +2 -0
- data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
- data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
- data/test/migrations/to_copy2/1_create_articles.rb +2 -0
- data/test/migrations/to_copy2/2_create_comments.rb +3 -1
- data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
- data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
- data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
- data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
- data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
- data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
- data/test/migrations/valid/2_we_need_reminders.rb +2 -0
- data/test/migrations/valid/3_innocent_jointable.rb +3 -1
- data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
- data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
- data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
- data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
- data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
- data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
- data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
- data/test/models/account.rb +46 -0
- data/test/models/admin/account.rb +3 -1
- data/test/models/admin/randomly_named_c1.rb +2 -0
- data/test/models/admin/user.rb +16 -8
- data/test/models/admin.rb +4 -2
- data/test/models/aircraft.rb +3 -1
- data/test/models/arunit2_model.rb +2 -0
- data/test/models/author.rb +153 -102
- data/test/models/auto_id.rb +2 -0
- data/test/models/autoloadable/extra_firm.rb +2 -0
- data/test/models/binary.rb +3 -1
- data/test/models/binary_field.rb +6 -0
- data/test/models/bird.rb +13 -1
- data/test/models/book.rb +14 -4
- data/test/models/book_destroy_async.rb +24 -0
- data/test/models/boolean.rb +5 -0
- data/test/models/bulb.rb +13 -4
- data/test/models/cake_designer.rb +2 -0
- data/test/models/car.rb +17 -10
- data/test/models/carrier.rb +2 -0
- data/test/models/cart.rb +5 -0
- data/test/models/cat.rb +2 -0
- data/test/models/categorization.rb +8 -6
- data/test/models/category.rb +28 -16
- data/test/models/chef.rb +2 -0
- data/test/models/citation.rb +5 -1
- data/test/models/club.rb +13 -10
- data/test/models/college.rb +4 -2
- data/test/models/column.rb +2 -0
- data/test/models/column_name.rb +2 -0
- data/test/models/comment.rb +32 -10
- data/test/models/company.rb +102 -106
- data/test/models/company_in_module.rb +27 -26
- data/test/models/computer.rb +3 -1
- data/test/models/contact.rb +15 -13
- data/test/models/content.rb +5 -3
- data/test/models/contract.rb +21 -3
- data/test/models/country.rb +2 -4
- data/test/models/course.rb +3 -1
- data/test/models/customer.rb +10 -8
- data/test/models/customer_carrier.rb +2 -0
- data/test/models/dashboard.rb +2 -0
- data/test/models/default.rb +2 -0
- data/test/models/department.rb +2 -0
- data/test/models/destroy_async_parent.rb +15 -0
- data/test/models/destroy_async_parent_soft_delete.rb +20 -0
- data/test/models/developer.rb +152 -85
- data/test/models/dl_keyed_belongs_to.rb +13 -0
- data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
- data/test/models/dl_keyed_has_many.rb +5 -0
- data/test/models/dl_keyed_has_many_through.rb +5 -0
- data/test/models/dl_keyed_has_one.rb +5 -0
- data/test/models/dl_keyed_join.rb +10 -0
- data/test/models/dog.rb +2 -0
- data/test/models/dog_lover.rb +2 -0
- data/test/models/doubloon.rb +3 -1
- data/test/models/drink_designer.rb +17 -0
- data/test/models/edge.rb +4 -2
- data/test/models/electron.rb +2 -0
- data/test/models/engine.rb +3 -2
- data/test/models/entrant.rb +2 -0
- data/test/models/entry.rb +5 -0
- data/test/models/essay.rb +6 -3
- data/test/models/essay_destroy_async.rb +12 -0
- data/test/models/event.rb +3 -1
- data/test/models/eye.rb +5 -3
- data/test/models/face.rb +14 -6
- data/test/models/family.rb +6 -0
- data/test/models/family_tree.rb +6 -0
- data/test/models/friendship.rb +5 -3
- data/test/models/frog.rb +8 -0
- data/test/models/guid.rb +3 -1
- data/test/models/guitar.rb +2 -0
- data/test/models/hotel.rb +5 -3
- data/test/models/human.rb +39 -0
- data/test/models/image.rb +3 -1
- data/test/models/interest.rb +14 -3
- data/test/models/invoice.rb +4 -2
- data/test/models/item.rb +3 -1
- data/test/models/job.rb +5 -3
- data/test/models/joke.rb +4 -2
- data/test/models/keyboard.rb +3 -1
- data/test/models/legacy_thing.rb +2 -0
- data/test/models/lesson.rb +2 -0
- data/test/models/line_item.rb +3 -1
- data/test/models/liquid.rb +2 -0
- data/test/models/matey.rb +3 -1
- data/test/models/measurement.rb +4 -0
- data/test/models/member.rb +23 -20
- data/test/models/member_detail.rb +3 -0
- data/test/models/member_type.rb +2 -0
- data/test/models/membership.rb +4 -1
- data/test/models/mentor.rb +3 -1
- data/test/models/message.rb +5 -0
- data/test/models/minimalistic.rb +2 -0
- data/test/models/minivan.rb +3 -2
- data/test/models/mixed_case_monkey.rb +3 -1
- data/test/models/molecule.rb +2 -0
- data/test/models/mouse.rb +6 -0
- data/test/models/movie.rb +2 -0
- data/test/models/node.rb +4 -2
- data/test/models/non_primary_key.rb +2 -0
- data/test/models/notification.rb +2 -0
- data/test/models/numeric_data.rb +12 -0
- data/test/models/order.rb +4 -2
- data/test/models/organization.rb +9 -7
- data/test/models/other_dog.rb +3 -1
- data/test/models/owner.rb +6 -4
- data/test/models/parrot.rb +12 -4
- data/test/models/person.rb +59 -54
- data/test/models/personal_legacy_thing.rb +3 -1
- data/test/models/pet.rb +4 -2
- data/test/models/pet_treasure.rb +2 -0
- data/test/models/pirate.rb +67 -43
- data/test/models/possession.rb +3 -1
- data/test/models/post.rb +184 -86
- data/test/models/price_estimate.rb +11 -1
- data/test/models/professor.rb +3 -1
- data/test/models/project.rb +14 -12
- data/test/models/publisher/article.rb +2 -0
- data/test/models/publisher/magazine.rb +2 -0
- data/test/models/publisher.rb +2 -0
- data/test/models/randomly_named_c1.rb +2 -0
- data/test/models/rating.rb +5 -1
- data/test/models/reader.rb +7 -5
- data/test/models/recipe.rb +2 -0
- data/test/models/record.rb +2 -0
- data/test/models/reference.rb +6 -3
- data/test/models/reply.rb +39 -21
- data/test/models/room.rb +6 -0
- data/test/models/section.rb +6 -0
- data/test/models/seminar.rb +6 -0
- data/test/models/session.rb +6 -0
- data/test/models/ship.rb +12 -9
- data/test/models/ship_part.rb +5 -3
- data/test/models/shop.rb +4 -2
- data/test/models/shop_account.rb +2 -0
- data/test/models/speedometer.rb +2 -0
- data/test/models/sponsor.rb +8 -5
- data/test/models/squeak.rb +6 -0
- data/test/models/strict_zine.rb +7 -0
- data/test/models/string_key_object.rb +2 -0
- data/test/models/student.rb +2 -0
- data/test/models/subscriber.rb +4 -2
- data/test/models/subscription.rb +5 -1
- data/test/models/tag.rb +6 -3
- data/test/models/tagging.rb +13 -6
- data/test/models/task.rb +2 -0
- data/test/models/topic.rb +54 -19
- data/test/models/toy.rb +4 -0
- data/test/models/traffic_light.rb +2 -0
- data/test/models/treasure.rb +5 -3
- data/test/models/treaty.rb +2 -4
- data/test/models/tree.rb +2 -0
- data/test/models/tuning_peg.rb +2 -0
- data/test/models/tyre.rb +2 -0
- data/test/models/user.rb +12 -4
- data/test/models/uuid_child.rb +2 -0
- data/test/models/uuid_item.rb +2 -0
- data/test/models/uuid_parent.rb +2 -0
- data/test/models/vegetables.rb +12 -3
- data/test/models/vertex.rb +6 -4
- data/test/models/warehouse_thing.rb +2 -0
- data/test/models/wheel.rb +3 -1
- data/test/models/without_table.rb +3 -1
- data/test/models/zine.rb +3 -1
- data/test/schema/mysql2_specific_schema.rb +49 -35
- data/test/schema/oracle_specific_schema.rb +13 -15
- data/test/schema/postgresql_specific_schema.rb +51 -40
- data/test/schema/schema.rb +334 -154
- data/test/schema/sqlite_specific_schema.rb +9 -16
- data/test/support/config.rb +26 -26
- data/test/support/connection.rb +14 -8
- data/test/support/connection_helper.rb +3 -1
- data/test/support/ddl_helper.rb +2 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
- data/test/support/schema_dumping_helper.rb +2 -0
- data/test/support/stubs/strong_parameters.rb +40 -0
- data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
- data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
- metadata +192 -14
data/test/cases/dirty_test.rb
CHANGED
@@ -1,37 +1,23 @@
|
|
1
|
-
|
2
|
-
require 'models/topic' # For booleans
|
3
|
-
require 'models/pirate' # For timestamps
|
4
|
-
require 'models/parrot'
|
5
|
-
require 'models/person' # For optimistic locking
|
6
|
-
require 'models/aircraft'
|
1
|
+
# frozen_string_literal: true
|
7
2
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
# after_save/update and the model itself
|
16
|
-
# can end up checking dirty status and acting on the results
|
17
|
-
def check_changes
|
18
|
-
if self.changed?
|
19
|
-
self.detected_changes_in_after_update = true
|
20
|
-
self.changes_detected_in_after_update = self.changes
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
class NumericData < ActiveRecord::Base
|
26
|
-
self.table_name = 'numeric_data'
|
27
|
-
end
|
3
|
+
require "cases/helper"
|
4
|
+
require "models/topic" # For booleans
|
5
|
+
require "models/pirate" # For timestamps
|
6
|
+
require "models/parrot"
|
7
|
+
require "models/person" # For optimistic locking
|
8
|
+
require "models/aircraft"
|
9
|
+
require "models/numeric_data"
|
28
10
|
|
29
11
|
class DirtyTest < ActiveRecord::TestCase
|
30
12
|
include InTimeZone
|
31
13
|
|
32
14
|
# Dummy to force column loads so query counts are clean.
|
33
15
|
def setup
|
34
|
-
Person.create :
|
16
|
+
Person.create first_name: "foo"
|
17
|
+
end
|
18
|
+
|
19
|
+
def teardown
|
20
|
+
Person.delete_by(first_name: "foo")
|
35
21
|
end
|
36
22
|
|
37
23
|
def test_attribute_changes
|
@@ -41,82 +27,82 @@ class DirtyTest < ActiveRecord::TestCase
|
|
41
27
|
assert_equal false, pirate.non_validated_parrot_id_changed?
|
42
28
|
|
43
29
|
# Change catchphrase.
|
44
|
-
pirate.catchphrase =
|
45
|
-
|
30
|
+
pirate.catchphrase = "arrr"
|
31
|
+
assert_predicate pirate, :catchphrase_changed?
|
46
32
|
assert_nil pirate.catchphrase_was
|
47
|
-
assert_equal [nil,
|
33
|
+
assert_equal [nil, "arrr"], pirate.catchphrase_change
|
48
34
|
|
49
35
|
# Saved - no changes.
|
50
36
|
pirate.save!
|
51
|
-
|
37
|
+
assert_not_predicate pirate, :catchphrase_changed?
|
52
38
|
assert_nil pirate.catchphrase_change
|
53
39
|
|
54
40
|
# Same value - no changes.
|
55
|
-
pirate.catchphrase =
|
56
|
-
|
41
|
+
pirate.catchphrase = "arrr"
|
42
|
+
assert_not_predicate pirate, :catchphrase_changed?
|
57
43
|
assert_nil pirate.catchphrase_change
|
58
44
|
end
|
59
45
|
|
60
46
|
def test_time_attributes_changes_with_time_zone
|
61
|
-
in_time_zone
|
47
|
+
in_time_zone "Paris" do
|
62
48
|
target = Class.new(ActiveRecord::Base)
|
63
|
-
target.table_name =
|
49
|
+
target.table_name = "pirates"
|
64
50
|
|
65
51
|
# New record - no changes.
|
66
52
|
pirate = target.new
|
67
|
-
|
53
|
+
assert_not_predicate pirate, :created_on_changed?
|
68
54
|
assert_nil pirate.created_on_change
|
69
55
|
|
70
56
|
# Saved - no changes.
|
71
|
-
pirate.catchphrase =
|
57
|
+
pirate.catchphrase = "arrrr, time zone!!"
|
72
58
|
pirate.save!
|
73
|
-
|
59
|
+
assert_not_predicate pirate, :created_on_changed?
|
74
60
|
assert_nil pirate.created_on_change
|
75
61
|
|
76
62
|
# Change created_on.
|
77
63
|
old_created_on = pirate.created_on
|
78
64
|
pirate.created_on = Time.now - 1.day
|
79
|
-
|
65
|
+
assert_predicate pirate, :created_on_changed?
|
80
66
|
assert_kind_of ActiveSupport::TimeWithZone, pirate.created_on_was
|
81
67
|
assert_equal old_created_on, pirate.created_on_was
|
82
68
|
pirate.created_on = old_created_on
|
83
|
-
|
69
|
+
assert_not_predicate pirate, :created_on_changed?
|
84
70
|
end
|
85
71
|
end
|
86
72
|
|
87
73
|
def test_setting_time_attributes_with_time_zone_field_to_itself_should_not_be_marked_as_a_change
|
88
|
-
in_time_zone
|
74
|
+
in_time_zone "Paris" do
|
89
75
|
target = Class.new(ActiveRecord::Base)
|
90
|
-
target.table_name =
|
76
|
+
target.table_name = "pirates"
|
91
77
|
|
92
78
|
pirate = target.create!
|
93
79
|
pirate.created_on = pirate.created_on
|
94
|
-
|
80
|
+
assert_not_predicate pirate, :created_on_changed?
|
95
81
|
end
|
96
82
|
end
|
97
83
|
|
98
84
|
def test_time_attributes_changes_without_time_zone_by_skip
|
99
|
-
in_time_zone
|
85
|
+
in_time_zone "Paris" do
|
100
86
|
target = Class.new(ActiveRecord::Base)
|
101
|
-
target.table_name =
|
87
|
+
target.table_name = "pirates"
|
102
88
|
|
103
89
|
target.skip_time_zone_conversion_for_attributes = [:created_on]
|
104
90
|
|
105
91
|
# New record - no changes.
|
106
92
|
pirate = target.new
|
107
|
-
|
93
|
+
assert_not_predicate pirate, :created_on_changed?
|
108
94
|
assert_nil pirate.created_on_change
|
109
95
|
|
110
96
|
# Saved - no changes.
|
111
|
-
pirate.catchphrase =
|
97
|
+
pirate.catchphrase = "arrrr, time zone!!"
|
112
98
|
pirate.save!
|
113
|
-
|
99
|
+
assert_not_predicate pirate, :created_on_changed?
|
114
100
|
assert_nil pirate.created_on_change
|
115
101
|
|
116
102
|
# Change created_on.
|
117
103
|
old_created_on = pirate.created_on
|
118
104
|
pirate.created_on = Time.now + 1.day
|
119
|
-
|
105
|
+
assert_predicate pirate, :created_on_changed?
|
120
106
|
# kind_of does not work because
|
121
107
|
# ActiveSupport::TimeWithZone.name == 'Time'
|
122
108
|
assert_instance_of Time, pirate.created_on_was
|
@@ -127,23 +113,23 @@ class DirtyTest < ActiveRecord::TestCase
|
|
127
113
|
def test_time_attributes_changes_without_time_zone
|
128
114
|
with_timezone_config aware_attributes: false do
|
129
115
|
target = Class.new(ActiveRecord::Base)
|
130
|
-
target.table_name =
|
116
|
+
target.table_name = "pirates"
|
131
117
|
|
132
118
|
# New record - no changes.
|
133
119
|
pirate = target.new
|
134
|
-
|
120
|
+
assert_not_predicate pirate, :created_on_changed?
|
135
121
|
assert_nil pirate.created_on_change
|
136
122
|
|
137
123
|
# Saved - no changes.
|
138
|
-
pirate.catchphrase =
|
124
|
+
pirate.catchphrase = "arrrr, time zone!!"
|
139
125
|
pirate.save!
|
140
|
-
|
126
|
+
assert_not_predicate pirate, :created_on_changed?
|
141
127
|
assert_nil pirate.created_on_change
|
142
128
|
|
143
129
|
# Change created_on.
|
144
130
|
old_created_on = pirate.created_on
|
145
131
|
pirate.created_on = Time.now + 1.day
|
146
|
-
|
132
|
+
assert_predicate pirate, :created_on_changed?
|
147
133
|
# kind_of does not work because
|
148
134
|
# ActiveSupport::TimeWithZone.name == 'Time'
|
149
135
|
assert_instance_of Time, pirate.created_on_was
|
@@ -151,28 +137,47 @@ class DirtyTest < ActiveRecord::TestCase
|
|
151
137
|
end
|
152
138
|
end
|
153
139
|
|
154
|
-
|
155
140
|
def test_aliased_attribute_changes
|
156
141
|
# the actual attribute here is name, title is an
|
157
142
|
# alias setup via alias_attribute
|
158
143
|
parrot = Parrot.new
|
159
|
-
|
144
|
+
assert_not_predicate parrot, :title_changed?
|
160
145
|
assert_nil parrot.title_change
|
161
146
|
|
162
|
-
parrot.name =
|
163
|
-
|
147
|
+
parrot.name = "Sam"
|
148
|
+
assert_predicate parrot, :title_changed?
|
164
149
|
assert_nil parrot.title_was
|
165
150
|
assert_equal parrot.name_change, parrot.title_change
|
166
151
|
end
|
167
152
|
|
168
153
|
def test_restore_attribute!
|
169
|
-
pirate = Pirate.create!(:
|
170
|
-
pirate.catchphrase =
|
154
|
+
pirate = Pirate.create!(catchphrase: "Yar!")
|
155
|
+
pirate.catchphrase = "Ahoy!"
|
156
|
+
|
157
|
+
assert_equal "Ahoy!", pirate.catchphrase
|
158
|
+
assert_equal ["Yar!", "Ahoy!"], pirate.catchphrase_change
|
171
159
|
|
172
160
|
pirate.restore_catchphrase!
|
161
|
+
|
162
|
+
assert_nil pirate.catchphrase_change
|
173
163
|
assert_equal "Yar!", pirate.catchphrase
|
174
164
|
assert_equal Hash.new, pirate.changes
|
175
|
-
|
165
|
+
assert_not_predicate pirate, :catchphrase_changed?
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_clear_attribute_change
|
169
|
+
pirate = Pirate.create!(catchphrase: "Yar!")
|
170
|
+
pirate.catchphrase = "Ahoy!"
|
171
|
+
|
172
|
+
assert_equal "Ahoy!", pirate.catchphrase
|
173
|
+
assert_equal ["Yar!", "Ahoy!"], pirate.catchphrase_change
|
174
|
+
|
175
|
+
pirate.clear_catchphrase_change
|
176
|
+
|
177
|
+
assert_nil pirate.catchphrase_change
|
178
|
+
assert_equal "Ahoy!", pirate.catchphrase
|
179
|
+
assert_equal Hash.new, pirate.changes
|
180
|
+
assert_not_predicate pirate, :catchphrase_changed?
|
176
181
|
end
|
177
182
|
|
178
183
|
def test_nullable_number_not_marked_as_changed_if_new_value_is_blank
|
@@ -180,7 +185,7 @@ class DirtyTest < ActiveRecord::TestCase
|
|
180
185
|
|
181
186
|
["", nil].each do |value|
|
182
187
|
pirate.parrot_id = value
|
183
|
-
|
188
|
+
assert_not_predicate pirate, :parrot_id_changed?
|
184
189
|
assert_nil pirate.parrot_id_change
|
185
190
|
end
|
186
191
|
end
|
@@ -190,7 +195,7 @@ class DirtyTest < ActiveRecord::TestCase
|
|
190
195
|
|
191
196
|
["", nil].each do |value|
|
192
197
|
numeric_data.bank_balance = value
|
193
|
-
|
198
|
+
assert_not_predicate numeric_data, :bank_balance_changed?
|
194
199
|
assert_nil numeric_data.bank_balance_change
|
195
200
|
end
|
196
201
|
end
|
@@ -200,15 +205,15 @@ class DirtyTest < ActiveRecord::TestCase
|
|
200
205
|
|
201
206
|
["", nil].each do |value|
|
202
207
|
numeric_data.temperature = value
|
203
|
-
|
208
|
+
assert_not_predicate numeric_data, :temperature_changed?
|
204
209
|
assert_nil numeric_data.temperature_change
|
205
210
|
end
|
206
211
|
end
|
207
212
|
|
208
213
|
def test_nullable_datetime_not_marked_as_changed_if_new_value_is_blank
|
209
|
-
in_time_zone
|
214
|
+
in_time_zone "Edinburgh" do
|
210
215
|
target = Class.new(ActiveRecord::Base)
|
211
|
-
target.table_name =
|
216
|
+
target.table_name = "topics"
|
212
217
|
|
213
218
|
topic = target.create
|
214
219
|
assert_nil topic.written_on
|
@@ -216,7 +221,7 @@ class DirtyTest < ActiveRecord::TestCase
|
|
216
221
|
["", nil].each do |value|
|
217
222
|
topic.written_on = value
|
218
223
|
assert_nil topic.written_on
|
219
|
-
|
224
|
+
assert_not_predicate topic, :written_on_changed?
|
220
225
|
end
|
221
226
|
end
|
222
227
|
end
|
@@ -224,40 +229,40 @@ class DirtyTest < ActiveRecord::TestCase
|
|
224
229
|
def test_integer_zero_to_string_zero_not_marked_as_changed
|
225
230
|
pirate = Pirate.new
|
226
231
|
pirate.parrot_id = 0
|
227
|
-
pirate.catchphrase =
|
232
|
+
pirate.catchphrase = "arrr"
|
228
233
|
assert pirate.save!
|
229
234
|
|
230
|
-
|
235
|
+
assert_not_predicate pirate, :changed?
|
231
236
|
|
232
|
-
pirate.parrot_id =
|
233
|
-
|
237
|
+
pirate.parrot_id = "0"
|
238
|
+
assert_not_predicate pirate, :changed?
|
234
239
|
end
|
235
240
|
|
236
241
|
def test_integer_zero_to_integer_zero_not_marked_as_changed
|
237
242
|
pirate = Pirate.new
|
238
243
|
pirate.parrot_id = 0
|
239
|
-
pirate.catchphrase =
|
244
|
+
pirate.catchphrase = "arrr"
|
240
245
|
assert pirate.save!
|
241
246
|
|
242
|
-
|
247
|
+
assert_not_predicate pirate, :changed?
|
243
248
|
|
244
249
|
pirate.parrot_id = 0
|
245
|
-
|
250
|
+
assert_not_predicate pirate, :changed?
|
246
251
|
end
|
247
252
|
|
248
253
|
def test_float_zero_to_string_zero_not_marked_as_changed
|
249
|
-
data = NumericData.new :
|
254
|
+
data = NumericData.new temperature: 0.0
|
250
255
|
data.save!
|
251
256
|
|
252
|
-
|
257
|
+
assert_not_predicate data, :changed?
|
253
258
|
|
254
|
-
data.temperature =
|
259
|
+
data.temperature = "0"
|
255
260
|
assert_empty data.changes
|
256
261
|
|
257
|
-
data.temperature =
|
262
|
+
data.temperature = "0.0"
|
258
263
|
assert_empty data.changes
|
259
264
|
|
260
|
-
data.temperature =
|
265
|
+
data.temperature = "0.00"
|
261
266
|
assert_empty data.changes
|
262
267
|
end
|
263
268
|
|
@@ -269,108 +274,122 @@ class DirtyTest < ActiveRecord::TestCase
|
|
269
274
|
|
270
275
|
# check the change from 1 to ''
|
271
276
|
pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties")
|
272
|
-
pirate.parrot_id =
|
273
|
-
|
277
|
+
pirate.parrot_id = ""
|
278
|
+
assert_predicate pirate, :parrot_id_changed?
|
274
279
|
assert_equal([1, nil], pirate.parrot_id_change)
|
275
280
|
pirate.save
|
276
281
|
|
277
282
|
# check the change from nil to 0
|
278
283
|
pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties")
|
279
284
|
pirate.parrot_id = 0
|
280
|
-
|
285
|
+
assert_predicate pirate, :parrot_id_changed?
|
281
286
|
assert_equal([nil, 0], pirate.parrot_id_change)
|
282
287
|
pirate.save
|
283
288
|
|
284
289
|
# check the change from 0 to ''
|
285
290
|
pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties")
|
286
|
-
pirate.parrot_id =
|
287
|
-
|
291
|
+
pirate.parrot_id = ""
|
292
|
+
assert_predicate pirate, :parrot_id_changed?
|
288
293
|
assert_equal([0, nil], pirate.parrot_id_change)
|
289
294
|
end
|
290
295
|
|
291
296
|
def test_object_should_be_changed_if_any_attribute_is_changed
|
292
297
|
pirate = Pirate.new
|
293
|
-
|
298
|
+
assert_not_predicate pirate, :changed?
|
294
299
|
assert_equal [], pirate.changed
|
295
300
|
assert_equal Hash.new, pirate.changes
|
296
301
|
|
297
|
-
pirate.catchphrase =
|
298
|
-
|
302
|
+
pirate.catchphrase = "arrr"
|
303
|
+
assert_predicate pirate, :changed?
|
299
304
|
assert_nil pirate.catchphrase_was
|
300
305
|
assert_equal %w(catchphrase), pirate.changed
|
301
|
-
assert_equal({
|
306
|
+
assert_equal({ "catchphrase" => [nil, "arrr"] }, pirate.changes)
|
302
307
|
|
303
308
|
pirate.save
|
304
|
-
|
309
|
+
assert_not_predicate pirate, :changed?
|
305
310
|
assert_equal [], pirate.changed
|
306
311
|
assert_equal Hash.new, pirate.changes
|
307
312
|
end
|
308
313
|
|
309
314
|
def test_attribute_will_change!
|
310
|
-
pirate = Pirate.create!(:
|
315
|
+
pirate = Pirate.create!(catchphrase: "arr")
|
311
316
|
|
312
|
-
|
317
|
+
assert_not_predicate pirate, :catchphrase_changed?
|
313
318
|
assert pirate.catchphrase_will_change!
|
314
|
-
|
315
|
-
assert_equal [
|
319
|
+
assert_predicate pirate, :catchphrase_changed?
|
320
|
+
assert_equal ["arr", "arr"], pirate.catchphrase_change
|
316
321
|
|
317
|
-
pirate.catchphrase <<
|
318
|
-
|
319
|
-
assert_equal [
|
322
|
+
pirate.catchphrase << " matey!"
|
323
|
+
assert_predicate pirate, :catchphrase_changed?
|
324
|
+
assert_equal ["arr", "arr matey!"], pirate.catchphrase_change
|
325
|
+
end
|
326
|
+
|
327
|
+
def test_virtual_attribute_will_change
|
328
|
+
parrot = Parrot.create!(name: "Ruby")
|
329
|
+
parrot.send(:attribute_will_change!, :cancel_save_from_callback)
|
330
|
+
assert_predicate parrot, :has_changes_to_save?
|
320
331
|
end
|
321
332
|
|
322
333
|
def test_association_assignment_changes_foreign_key
|
323
|
-
pirate = Pirate.create!(:
|
324
|
-
pirate.parrot = Parrot.create!(:
|
325
|
-
|
334
|
+
pirate = Pirate.create!(catchphrase: "jarl")
|
335
|
+
pirate.parrot = Parrot.create!(name: "Lorre")
|
336
|
+
assert_predicate pirate, :changed?
|
326
337
|
assert_equal %w(parrot_id), pirate.changed
|
327
338
|
end
|
328
339
|
|
329
340
|
def test_attribute_should_be_compared_with_type_cast
|
330
341
|
topic = Topic.new
|
331
|
-
|
332
|
-
|
342
|
+
assert_predicate topic, :approved?
|
343
|
+
assert_not_predicate topic, :approved_changed?
|
333
344
|
|
334
345
|
# Coming from web form.
|
335
|
-
params = {:
|
346
|
+
params = { topic: { approved: 1 } }
|
336
347
|
# In the controller.
|
337
348
|
topic.attributes = params[:topic]
|
338
|
-
|
339
|
-
|
349
|
+
assert_predicate topic, :approved?
|
350
|
+
assert_not_predicate topic, :approved_changed?
|
351
|
+
end
|
352
|
+
|
353
|
+
def test_string_attribute_should_compare_with_typecast_symbol_after_update
|
354
|
+
pirate = Pirate.create!(catchphrase: :foo)
|
355
|
+
pirate.update_column :catchphrase, :foo
|
356
|
+
pirate.catchphrase
|
357
|
+
assert_not_predicate pirate, :catchphrase_changed?
|
340
358
|
end
|
341
359
|
|
342
360
|
def test_partial_update
|
343
|
-
pirate = Pirate.new(:
|
361
|
+
pirate = Pirate.new(catchphrase: "foo")
|
344
362
|
old_updated_on = 1.hour.ago.beginning_of_day
|
345
363
|
|
346
364
|
with_partial_writes Pirate, false do
|
347
365
|
assert_queries(2) { 2.times { pirate.save! } }
|
348
|
-
Pirate.where(id: pirate.id).update_all(:
|
366
|
+
Pirate.where(id: pirate.id).update_all(updated_on: old_updated_on)
|
349
367
|
end
|
350
368
|
|
351
369
|
with_partial_writes Pirate, true do
|
352
|
-
|
370
|
+
assert_no_queries { 2.times { pirate.save! } }
|
353
371
|
assert_equal old_updated_on, pirate.reload.updated_on
|
354
372
|
|
355
|
-
assert_queries(1) { pirate.catchphrase =
|
373
|
+
assert_queries(1) { pirate.catchphrase = "bar"; pirate.save! }
|
356
374
|
assert_not_equal old_updated_on, pirate.reload.updated_on
|
357
375
|
end
|
358
376
|
end
|
359
377
|
|
360
378
|
def test_partial_update_with_optimistic_locking
|
361
|
-
person = Person.new(:
|
362
|
-
old_lock_version = 1
|
379
|
+
person = Person.new(first_name: "foo")
|
363
380
|
|
364
381
|
with_partial_writes Person, false do
|
365
382
|
assert_queries(2) { 2.times { person.save! } }
|
366
|
-
Person.where(id: person.id).update_all(:
|
383
|
+
Person.where(id: person.id).update_all(first_name: "baz")
|
367
384
|
end
|
368
385
|
|
386
|
+
old_lock_version = person.lock_version + 1
|
387
|
+
|
369
388
|
with_partial_writes Person, true do
|
370
|
-
|
389
|
+
assert_no_queries { 2.times { person.save! } }
|
371
390
|
assert_equal old_lock_version, person.reload.lock_version
|
372
391
|
|
373
|
-
assert_queries(1) { person.first_name =
|
392
|
+
assert_queries(1) { person.first_name = "bar"; person.save! }
|
374
393
|
assert_not_equal old_lock_version, person.reload.lock_version
|
375
394
|
end
|
376
395
|
end
|
@@ -378,7 +397,7 @@ class DirtyTest < ActiveRecord::TestCase
|
|
378
397
|
def test_changed_attributes_should_be_preserved_if_save_failure
|
379
398
|
pirate = Pirate.new
|
380
399
|
pirate.parrot_id = 1
|
381
|
-
|
400
|
+
assert_not pirate.save
|
382
401
|
check_pirate_after_save_failure(pirate)
|
383
402
|
|
384
403
|
pirate = Pirate.new
|
@@ -388,71 +407,70 @@ class DirtyTest < ActiveRecord::TestCase
|
|
388
407
|
end
|
389
408
|
|
390
409
|
def test_reload_should_clear_changed_attributes
|
391
|
-
pirate = Pirate.create!(:
|
410
|
+
pirate = Pirate.create!(catchphrase: "shiver me timbers")
|
392
411
|
pirate.catchphrase = "*hic*"
|
393
|
-
|
412
|
+
assert_predicate pirate, :changed?
|
394
413
|
pirate.reload
|
395
|
-
|
414
|
+
assert_not_predicate pirate, :changed?
|
396
415
|
end
|
397
416
|
|
398
417
|
def test_dup_objects_should_not_copy_dirty_flag_from_creator
|
399
|
-
pirate = Pirate.create!(:
|
418
|
+
pirate = Pirate.create!(catchphrase: "shiver me timbers")
|
400
419
|
pirate_dup = pirate.dup
|
401
420
|
pirate_dup.restore_catchphrase!
|
402
421
|
pirate.catchphrase = "I love Rum"
|
403
|
-
|
404
|
-
|
422
|
+
assert_predicate pirate, :catchphrase_changed?
|
423
|
+
assert_not_predicate pirate_dup, :catchphrase_changed?
|
405
424
|
end
|
406
425
|
|
407
426
|
def test_reverted_changes_are_not_dirty
|
408
427
|
phrase = "shiver me timbers"
|
409
|
-
pirate = Pirate.create!(:
|
428
|
+
pirate = Pirate.create!(catchphrase: phrase)
|
410
429
|
pirate.catchphrase = "*hic*"
|
411
|
-
|
430
|
+
assert_predicate pirate, :changed?
|
412
431
|
pirate.catchphrase = phrase
|
413
|
-
|
432
|
+
assert_not_predicate pirate, :changed?
|
414
433
|
end
|
415
434
|
|
416
435
|
def test_reverted_changes_are_not_dirty_after_multiple_changes
|
417
436
|
phrase = "shiver me timbers"
|
418
|
-
pirate = Pirate.create!(:
|
437
|
+
pirate = Pirate.create!(catchphrase: phrase)
|
419
438
|
10.times do |i|
|
420
439
|
pirate.catchphrase = "*hic*" * i
|
421
|
-
|
440
|
+
assert_predicate pirate, :changed?
|
422
441
|
end
|
423
|
-
|
442
|
+
assert_predicate pirate, :changed?
|
424
443
|
pirate.catchphrase = phrase
|
425
|
-
|
444
|
+
assert_not_predicate pirate, :changed?
|
426
445
|
end
|
427
446
|
|
428
|
-
|
429
447
|
def test_reverted_changes_are_not_dirty_going_from_nil_to_value_and_back
|
430
|
-
pirate = Pirate.create!(:
|
448
|
+
pirate = Pirate.create!(catchphrase: "Yar!")
|
431
449
|
|
432
450
|
pirate.parrot_id = 1
|
433
|
-
|
434
|
-
|
435
|
-
|
451
|
+
assert_predicate pirate, :changed?
|
452
|
+
assert_predicate pirate, :parrot_id_changed?
|
453
|
+
assert_not_predicate pirate, :catchphrase_changed?
|
436
454
|
|
437
455
|
pirate.parrot_id = nil
|
438
|
-
|
439
|
-
|
440
|
-
|
456
|
+
assert_not_predicate pirate, :changed?
|
457
|
+
assert_not_predicate pirate, :parrot_id_changed?
|
458
|
+
assert_not_predicate pirate, :catchphrase_changed?
|
441
459
|
end
|
442
460
|
|
443
461
|
def test_save_should_store_serialized_attributes_even_with_partial_writes
|
444
462
|
with_partial_writes(Topic) do
|
445
|
-
topic = Topic.create!(:
|
463
|
+
topic = Topic.create!(content: { a: "a" })
|
446
464
|
|
447
|
-
|
465
|
+
assert_not_predicate topic, :changed?
|
448
466
|
|
449
467
|
topic.content[:b] = "b"
|
450
468
|
|
451
|
-
|
469
|
+
assert_predicate topic, :changed?
|
452
470
|
|
453
471
|
topic.save!
|
454
472
|
|
455
|
-
|
473
|
+
assert_not_predicate topic, :changed?
|
456
474
|
assert_equal "b", topic.content[:b]
|
457
475
|
|
458
476
|
topic.reload
|
@@ -463,30 +481,37 @@ class DirtyTest < ActiveRecord::TestCase
|
|
463
481
|
|
464
482
|
def test_save_always_should_update_timestamps_when_serialized_attributes_are_present
|
465
483
|
with_partial_writes(Topic) do
|
466
|
-
topic = Topic.create!(:
|
484
|
+
topic = Topic.create!(content: { a: "a" })
|
467
485
|
topic.save!
|
468
486
|
|
469
487
|
updated_at = topic.updated_at
|
470
488
|
travel(1.second) do
|
471
|
-
topic.content[:hello] =
|
489
|
+
topic.content[:hello] = "world"
|
472
490
|
topic.save!
|
473
491
|
end
|
474
492
|
|
475
493
|
assert_not_equal updated_at, topic.updated_at
|
476
|
-
assert_equal
|
494
|
+
assert_equal "world", topic.content[:hello]
|
477
495
|
end
|
478
496
|
end
|
479
497
|
|
480
498
|
def test_save_should_not_save_serialized_attribute_with_partial_writes_if_not_present
|
481
499
|
with_partial_writes(Topic) do
|
482
|
-
Topic.create!(:
|
483
|
-
topic = Topic.select(
|
484
|
-
topic.update_columns author_name:
|
485
|
-
topic
|
486
|
-
assert_not_nil topic.content
|
500
|
+
topic = Topic.create!(author_name: "Bill", content: { a: "a" })
|
501
|
+
topic = Topic.select("id, author_name").find(topic.id)
|
502
|
+
topic.update_columns author_name: "John"
|
503
|
+
assert_not_nil topic.reload.content
|
487
504
|
end
|
488
505
|
end
|
489
506
|
|
507
|
+
def test_changes_to_save_should_not_mutate_array_of_hashes
|
508
|
+
topic = Topic.new(author_name: "Bill", content: [{ a: "a" }])
|
509
|
+
|
510
|
+
topic.changes_to_save
|
511
|
+
|
512
|
+
assert_equal [{ a: "a" }], topic.content
|
513
|
+
end
|
514
|
+
|
490
515
|
def test_previous_changes
|
491
516
|
# original values should be in previous_changes
|
492
517
|
pirate = Pirate.new
|
@@ -496,13 +521,14 @@ class DirtyTest < ActiveRecord::TestCase
|
|
496
521
|
pirate.save!
|
497
522
|
|
498
523
|
assert_equal 4, pirate.previous_changes.size
|
499
|
-
assert_equal [nil, "arrr"], pirate.previous_changes[
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
524
|
+
assert_equal [nil, "arrr"], pirate.previous_changes["catchphrase"]
|
525
|
+
assert_nil pirate.catchphrase_previously_was
|
526
|
+
assert_equal [nil, pirate.id], pirate.previous_changes["id"]
|
527
|
+
assert_nil pirate.previous_changes["updated_on"][0]
|
528
|
+
assert_not_nil pirate.previous_changes["updated_on"][1]
|
529
|
+
assert_nil pirate.previous_changes["created_on"][0]
|
530
|
+
assert_not_nil pirate.previous_changes["created_on"][1]
|
531
|
+
assert_not pirate.previous_changes.key?("parrot_id")
|
506
532
|
|
507
533
|
# original values should be in previous_changes
|
508
534
|
pirate = Pirate.new
|
@@ -512,11 +538,12 @@ class DirtyTest < ActiveRecord::TestCase
|
|
512
538
|
pirate.save
|
513
539
|
|
514
540
|
assert_equal 4, pirate.previous_changes.size
|
515
|
-
assert_equal [nil, "arrr"], pirate.previous_changes[
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
541
|
+
assert_equal [nil, "arrr"], pirate.previous_changes["catchphrase"]
|
542
|
+
assert_nil pirate.catchphrase_previously_was
|
543
|
+
assert_equal [nil, pirate.id], pirate.previous_changes["id"]
|
544
|
+
assert_includes pirate.previous_changes, "updated_on"
|
545
|
+
assert_includes pirate.previous_changes, "created_on"
|
546
|
+
assert_not pirate.previous_changes.key?("parrot_id")
|
520
547
|
|
521
548
|
pirate.catchphrase = "Yar!!"
|
522
549
|
pirate.reload
|
@@ -530,11 +557,12 @@ class DirtyTest < ActiveRecord::TestCase
|
|
530
557
|
pirate.save!
|
531
558
|
|
532
559
|
assert_equal 2, pirate.previous_changes.size
|
533
|
-
assert_equal ["arrr", "Me Maties!"], pirate.previous_changes[
|
534
|
-
|
535
|
-
assert_not_nil pirate.previous_changes[
|
536
|
-
|
537
|
-
|
560
|
+
assert_equal ["arrr", "Me Maties!"], pirate.previous_changes["catchphrase"]
|
561
|
+
assert_equal "arrr", pirate.catchphrase_previously_was
|
562
|
+
assert_not_nil pirate.previous_changes["updated_on"][0]
|
563
|
+
assert_not_nil pirate.previous_changes["updated_on"][1]
|
564
|
+
assert_not pirate.previous_changes.key?("parrot_id")
|
565
|
+
assert_not pirate.previous_changes.key?("created_on")
|
538
566
|
|
539
567
|
pirate = Pirate.find_by_catchphrase("Me Maties!")
|
540
568
|
|
@@ -544,11 +572,12 @@ class DirtyTest < ActiveRecord::TestCase
|
|
544
572
|
pirate.save
|
545
573
|
|
546
574
|
assert_equal 2, pirate.previous_changes.size
|
547
|
-
assert_equal ["Me Maties!", "Thar She Blows!"], pirate.previous_changes[
|
548
|
-
|
549
|
-
assert_not_nil pirate.previous_changes[
|
550
|
-
|
551
|
-
|
575
|
+
assert_equal ["Me Maties!", "Thar She Blows!"], pirate.previous_changes["catchphrase"]
|
576
|
+
assert_equal "Me Maties!", pirate.catchphrase_previously_was
|
577
|
+
assert_not_nil pirate.previous_changes["updated_on"][0]
|
578
|
+
assert_not_nil pirate.previous_changes["updated_on"][1]
|
579
|
+
assert_not pirate.previous_changes.key?("parrot_id")
|
580
|
+
assert_not pirate.previous_changes.key?("created_on")
|
552
581
|
|
553
582
|
travel(1.second)
|
554
583
|
|
@@ -556,11 +585,12 @@ class DirtyTest < ActiveRecord::TestCase
|
|
556
585
|
pirate.update(catchphrase: "Ahoy!")
|
557
586
|
|
558
587
|
assert_equal 2, pirate.previous_changes.size
|
559
|
-
assert_equal ["Thar She Blows!", "Ahoy!"], pirate.previous_changes[
|
560
|
-
|
561
|
-
assert_not_nil pirate.previous_changes[
|
562
|
-
|
563
|
-
|
588
|
+
assert_equal ["Thar She Blows!", "Ahoy!"], pirate.previous_changes["catchphrase"]
|
589
|
+
assert_equal "Thar She Blows!", pirate.catchphrase_previously_was
|
590
|
+
assert_not_nil pirate.previous_changes["updated_on"][0]
|
591
|
+
assert_not_nil pirate.previous_changes["updated_on"][1]
|
592
|
+
assert_not pirate.previous_changes.key?("parrot_id")
|
593
|
+
assert_not pirate.previous_changes.key?("created_on")
|
564
594
|
|
565
595
|
travel(1.second)
|
566
596
|
|
@@ -568,63 +598,61 @@ class DirtyTest < ActiveRecord::TestCase
|
|
568
598
|
pirate.update_attribute(:catchphrase, "Ninjas suck!")
|
569
599
|
|
570
600
|
assert_equal 2, pirate.previous_changes.size
|
571
|
-
assert_equal ["Ahoy!", "Ninjas suck!"], pirate.previous_changes[
|
572
|
-
|
573
|
-
assert_not_nil pirate.previous_changes[
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
ActiveRecord::Base.connection.create_table :testings do |t|
|
584
|
-
t.string :field
|
585
|
-
end
|
586
|
-
assert_nothing_raised do
|
587
|
-
Testings.new.attributes
|
588
|
-
end
|
589
|
-
ensure
|
590
|
-
ActiveRecord::Base.connection.drop_table :testings rescue nil
|
601
|
+
assert_equal ["Ahoy!", "Ninjas suck!"], pirate.previous_changes["catchphrase"]
|
602
|
+
assert_equal "Ahoy!", pirate.catchphrase_previously_was
|
603
|
+
assert_not_nil pirate.previous_changes["updated_on"][0]
|
604
|
+
assert_not_nil pirate.previous_changes["updated_on"][1]
|
605
|
+
assert_not pirate.previous_changes.key?("parrot_id")
|
606
|
+
assert_not pirate.previous_changes.key?("created_on")
|
607
|
+
end
|
608
|
+
|
609
|
+
class Testings < ActiveRecord::Base; end
|
610
|
+
def test_field_named_field
|
611
|
+
ActiveRecord::Base.connection.create_table :testings do |t|
|
612
|
+
t.string :field
|
591
613
|
end
|
614
|
+
assert_nothing_raised do
|
615
|
+
Testings.new.attributes
|
616
|
+
end
|
617
|
+
ensure
|
618
|
+
ActiveRecord::Base.connection.drop_table :testings rescue nil
|
619
|
+
ActiveRecord::Base.clear_cache!
|
592
620
|
end
|
593
621
|
|
594
622
|
def test_datetime_attribute_can_be_updated_with_fractional_seconds
|
595
|
-
skip "Fractional seconds are not supported" unless
|
596
|
-
in_time_zone
|
623
|
+
skip "Fractional seconds are not supported" unless supports_datetime_with_precision?
|
624
|
+
in_time_zone "Paris" do
|
597
625
|
target = Class.new(ActiveRecord::Base)
|
598
|
-
target.table_name =
|
626
|
+
target.table_name = "topics"
|
599
627
|
|
600
|
-
written_on = Time.utc(2012, 12, 1, 12, 0, 0).in_time_zone(
|
628
|
+
written_on = Time.utc(2012, 12, 1, 12, 0, 0).in_time_zone("Paris")
|
601
629
|
|
602
|
-
topic = target.create(:
|
630
|
+
topic = target.create(written_on: written_on)
|
603
631
|
topic.written_on += 0.3
|
604
632
|
|
605
|
-
assert topic.written_on_changed?,
|
633
|
+
assert topic.written_on_changed?, "Fractional second update not detected"
|
606
634
|
end
|
607
635
|
end
|
608
636
|
|
609
637
|
def test_datetime_attribute_doesnt_change_if_zone_is_modified_in_string
|
610
|
-
time_in_paris = Time.utc(2014, 1, 1, 12, 0, 0).in_time_zone(
|
611
|
-
pirate = Pirate.create!(:
|
638
|
+
time_in_paris = Time.utc(2014, 1, 1, 12, 0, 0).in_time_zone("Paris")
|
639
|
+
pirate = Pirate.create!(catchphrase: "rrrr", created_on: time_in_paris)
|
612
640
|
|
613
|
-
pirate.created_on = pirate.created_on.in_time_zone(
|
614
|
-
|
641
|
+
pirate.created_on = pirate.created_on.in_time_zone("Tokyo").to_s
|
642
|
+
assert_not_predicate pirate, :created_on_changed?
|
615
643
|
end
|
616
644
|
|
617
645
|
test "partial insert" do
|
618
646
|
with_partial_writes Person do
|
619
647
|
jon = nil
|
620
648
|
assert_sql(/first_name/i) do
|
621
|
-
jon = Person.create! first_name:
|
649
|
+
jon = Person.create! first_name: "Jon"
|
622
650
|
end
|
623
651
|
|
624
|
-
assert ActiveRecord::SQLCounter.log_all.none? { |sql| sql
|
652
|
+
assert ActiveRecord::SQLCounter.log_all.none? { |sql| sql.include?("followers_count") }
|
625
653
|
|
626
654
|
jon.reload
|
627
|
-
assert_equal
|
655
|
+
assert_equal "Jon", jon.first_name
|
628
656
|
assert_equal 0, jon.followers_count
|
629
657
|
assert_not_nil jon.id
|
630
658
|
end
|
@@ -642,7 +670,7 @@ class DirtyTest < ActiveRecord::TestCase
|
|
642
670
|
pirate = Pirate.create!(catchphrase: "arrrr")
|
643
671
|
pirate.catchphrase << " matey!"
|
644
672
|
|
645
|
-
|
673
|
+
assert_predicate pirate, :catchphrase_changed?
|
646
674
|
expected_changes = {
|
647
675
|
"catchphrase" => ["arrrr", "arrrr matey!"]
|
648
676
|
}
|
@@ -650,13 +678,13 @@ class DirtyTest < ActiveRecord::TestCase
|
|
650
678
|
assert_equal("arrrr", pirate.catchphrase_was)
|
651
679
|
assert pirate.catchphrase_changed?(from: "arrrr")
|
652
680
|
assert_not pirate.catchphrase_changed?(from: "anything else")
|
653
|
-
|
681
|
+
assert_includes pirate.changed_attributes, :catchphrase
|
654
682
|
|
655
683
|
pirate.save!
|
656
684
|
pirate.reload
|
657
685
|
|
658
686
|
assert_equal "arrrr matey!", pirate.catchphrase
|
659
|
-
|
687
|
+
assert_not_predicate pirate, :changed?
|
660
688
|
end
|
661
689
|
|
662
690
|
test "in place mutation for binary" do
|
@@ -667,19 +695,60 @@ class DirtyTest < ActiveRecord::TestCase
|
|
667
695
|
|
668
696
|
binary = klass.create!(data: "\\\\foo")
|
669
697
|
|
670
|
-
|
698
|
+
assert_not_predicate binary, :changed?
|
671
699
|
|
672
700
|
binary.data = binary.data.dup
|
673
701
|
|
674
|
-
|
702
|
+
assert_not_predicate binary, :changed?
|
675
703
|
|
676
704
|
binary = klass.last
|
677
705
|
|
678
|
-
|
706
|
+
assert_not_predicate binary, :changed?
|
679
707
|
|
680
708
|
binary.data << "bar"
|
681
709
|
|
682
|
-
|
710
|
+
assert_predicate binary, :changed?
|
711
|
+
end
|
712
|
+
|
713
|
+
test "changes is correct for subclass" do
|
714
|
+
foo = Class.new(Pirate) do
|
715
|
+
def catchphrase
|
716
|
+
super.upcase
|
717
|
+
end
|
718
|
+
end
|
719
|
+
|
720
|
+
pirate = foo.create!(catchphrase: "arrrr")
|
721
|
+
|
722
|
+
new_catchphrase = "arrrr matey!"
|
723
|
+
|
724
|
+
pirate.catchphrase = new_catchphrase
|
725
|
+
assert_predicate pirate, :catchphrase_changed?
|
726
|
+
|
727
|
+
expected_changes = {
|
728
|
+
"catchphrase" => ["arrrr", new_catchphrase]
|
729
|
+
}
|
730
|
+
|
731
|
+
assert_equal new_catchphrase.upcase, pirate.catchphrase
|
732
|
+
assert_equal expected_changes, pirate.changes
|
733
|
+
end
|
734
|
+
|
735
|
+
test "changes is correct if override attribute reader" do
|
736
|
+
pirate = Pirate.create!(catchphrase: "arrrr")
|
737
|
+
def pirate.catchphrase
|
738
|
+
super.upcase
|
739
|
+
end
|
740
|
+
|
741
|
+
new_catchphrase = "arrrr matey!"
|
742
|
+
|
743
|
+
pirate.catchphrase = new_catchphrase
|
744
|
+
assert_predicate pirate, :catchphrase_changed?
|
745
|
+
|
746
|
+
expected_changes = {
|
747
|
+
"catchphrase" => ["arrrr", new_catchphrase]
|
748
|
+
}
|
749
|
+
|
750
|
+
assert_equal new_catchphrase.upcase, pirate.catchphrase
|
751
|
+
assert_equal expected_changes, pirate.changes
|
683
752
|
end
|
684
753
|
|
685
754
|
test "attribute_changed? doesn't compute in-place changes for unrelated attributes" do
|
@@ -689,27 +758,45 @@ class DirtyTest < ActiveRecord::TestCase
|
|
689
758
|
end
|
690
759
|
end
|
691
760
|
klass = Class.new(ActiveRecord::Base) do
|
692
|
-
self.table_name =
|
761
|
+
self.table_name = "people"
|
693
762
|
attribute :foo, test_type_class.new
|
694
763
|
end
|
695
764
|
|
696
765
|
model = klass.new(first_name: "Jim")
|
697
|
-
|
766
|
+
assert_predicate model, :first_name_changed?
|
698
767
|
end
|
699
768
|
|
700
769
|
test "attribute_will_change! doesn't try to save non-persistable attributes" do
|
701
770
|
klass = Class.new(ActiveRecord::Base) do
|
702
|
-
self.table_name =
|
771
|
+
self.table_name = "people"
|
703
772
|
attribute :non_persisted_attribute, :string
|
704
773
|
end
|
705
774
|
|
706
775
|
record = klass.new(first_name: "Sean")
|
707
776
|
record.non_persisted_attribute_will_change!
|
708
777
|
|
709
|
-
|
778
|
+
assert_predicate record, :non_persisted_attribute_changed?
|
710
779
|
assert record.save
|
711
780
|
end
|
712
781
|
|
782
|
+
test "virtual attributes are not written with partial_writes off" do
|
783
|
+
with_partial_writes(ActiveRecord::Base, false) do
|
784
|
+
klass = Class.new(ActiveRecord::Base) do
|
785
|
+
self.table_name = "people"
|
786
|
+
attribute :non_persisted_attribute, :string
|
787
|
+
end
|
788
|
+
|
789
|
+
record = klass.new(first_name: "Sean")
|
790
|
+
record.non_persisted_attribute_will_change!
|
791
|
+
|
792
|
+
assert record.save
|
793
|
+
|
794
|
+
record.non_persisted_attribute_will_change!
|
795
|
+
|
796
|
+
assert record.save
|
797
|
+
end
|
798
|
+
end
|
799
|
+
|
713
800
|
test "mutating and then assigning doesn't remove the change" do
|
714
801
|
pirate = Pirate.create!(catchphrase: "arrrr")
|
715
802
|
pirate.catchphrase << " matey!"
|
@@ -736,13 +823,122 @@ class DirtyTest < ActiveRecord::TestCase
|
|
736
823
|
|
737
824
|
test "attributes assigned but not selected are dirty" do
|
738
825
|
person = Person.select(:id).first
|
739
|
-
|
826
|
+
assert_not_predicate person, :changed?
|
740
827
|
|
741
828
|
person.first_name = "Sean"
|
742
|
-
|
829
|
+
assert_predicate person, :changed?
|
743
830
|
|
744
831
|
person.first_name = nil
|
745
|
-
|
832
|
+
assert_predicate person, :changed?
|
833
|
+
end
|
834
|
+
|
835
|
+
test "attributes not selected are still missing after save" do
|
836
|
+
person = Person.select(:id).first
|
837
|
+
assert_raises(ActiveModel::MissingAttributeError) { person.first_name }
|
838
|
+
assert person.save # calls forget_attribute_assignments
|
839
|
+
assert_raises(ActiveModel::MissingAttributeError) { person.first_name }
|
840
|
+
end
|
841
|
+
|
842
|
+
test "saved_change_to_attribute? returns whether a change occurred in the last save" do
|
843
|
+
person = Person.create!(first_name: "Sean")
|
844
|
+
|
845
|
+
assert_predicate person, :saved_change_to_first_name?
|
846
|
+
assert_not_predicate person, :saved_change_to_gender?
|
847
|
+
assert person.saved_change_to_first_name?(from: nil, to: "Sean")
|
848
|
+
assert person.saved_change_to_first_name?(from: nil)
|
849
|
+
assert person.saved_change_to_first_name?(to: "Sean")
|
850
|
+
assert_not person.saved_change_to_first_name?(from: "Jim", to: "Sean")
|
851
|
+
assert_not person.saved_change_to_first_name?(from: "Jim")
|
852
|
+
assert_not person.saved_change_to_first_name?(to: "Jim")
|
853
|
+
end
|
854
|
+
|
855
|
+
test "saved_change_to_attribute returns the change that occurred in the last save" do
|
856
|
+
person = Person.create!(first_name: "Sean", gender: "M")
|
857
|
+
|
858
|
+
assert_equal [nil, "Sean"], person.saved_change_to_first_name
|
859
|
+
assert_equal [nil, "M"], person.saved_change_to_gender
|
860
|
+
|
861
|
+
person.update(first_name: "Jim")
|
862
|
+
|
863
|
+
assert_equal ["Sean", "Jim"], person.saved_change_to_first_name
|
864
|
+
assert_nil person.saved_change_to_gender
|
865
|
+
end
|
866
|
+
|
867
|
+
test "attribute_before_last_save returns the original value before saving" do
|
868
|
+
person = Person.create!(first_name: "Sean", gender: "M")
|
869
|
+
|
870
|
+
assert_nil person.first_name_before_last_save
|
871
|
+
assert_nil person.gender_before_last_save
|
872
|
+
|
873
|
+
person.first_name = "Jim"
|
874
|
+
|
875
|
+
assert_nil person.first_name_before_last_save
|
876
|
+
assert_nil person.gender_before_last_save
|
877
|
+
|
878
|
+
person.save
|
879
|
+
|
880
|
+
assert_equal "Sean", person.first_name_before_last_save
|
881
|
+
assert_equal "M", person.gender_before_last_save
|
882
|
+
end
|
883
|
+
|
884
|
+
test "saved_changes? returns whether the last call to save changed anything" do
|
885
|
+
person = Person.create!(first_name: "Sean")
|
886
|
+
|
887
|
+
assert_predicate person, :saved_changes?
|
888
|
+
|
889
|
+
person.save
|
890
|
+
|
891
|
+
assert_not_predicate person, :saved_changes?
|
892
|
+
end
|
893
|
+
|
894
|
+
test "saved_changes returns a hash of all the changes that occurred" do
|
895
|
+
person = Person.create!(first_name: "Sean", gender: "M")
|
896
|
+
|
897
|
+
assert_equal [nil, "Sean"], person.saved_changes[:first_name]
|
898
|
+
assert_equal [nil, "M"], person.saved_changes[:gender]
|
899
|
+
assert_equal %w(id first_name gender created_at updated_at).sort, person.saved_changes.keys.sort
|
900
|
+
|
901
|
+
travel(1.second) do
|
902
|
+
person.update(first_name: "Jim")
|
903
|
+
end
|
904
|
+
|
905
|
+
assert_equal ["Sean", "Jim"], person.saved_changes[:first_name]
|
906
|
+
assert_equal %w(first_name lock_version updated_at).sort, person.saved_changes.keys.sort
|
907
|
+
end
|
908
|
+
|
909
|
+
test "changed? in after callbacks returns false" do
|
910
|
+
klass = Class.new(ActiveRecord::Base) do
|
911
|
+
self.table_name = "people"
|
912
|
+
|
913
|
+
after_save do
|
914
|
+
raise "changed? should be false" if changed?
|
915
|
+
raise "has_changes_to_save? should be false" if has_changes_to_save?
|
916
|
+
raise "saved_changes? should be true" unless saved_changes?
|
917
|
+
raise "id_in_database should not be nil" if id_in_database.nil?
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
person = klass.create!(first_name: "Sean")
|
922
|
+
assert_not_predicate person, :changed?
|
923
|
+
end
|
924
|
+
|
925
|
+
test "changed? in around callbacks after yield returns false" do
|
926
|
+
klass = Class.new(ActiveRecord::Base) do
|
927
|
+
self.table_name = "people"
|
928
|
+
|
929
|
+
around_create :check_around
|
930
|
+
|
931
|
+
def check_around
|
932
|
+
yield
|
933
|
+
raise "changed? should be false" if changed?
|
934
|
+
raise "has_changes_to_save? should be false" if has_changes_to_save?
|
935
|
+
raise "saved_changes? should be true" unless saved_changes?
|
936
|
+
raise "id_in_database should not be nil" if id_in_database.nil?
|
937
|
+
end
|
938
|
+
end
|
939
|
+
|
940
|
+
person = klass.create!(first_name: "Sean")
|
941
|
+
assert_not_predicate person, :changed?
|
746
942
|
end
|
747
943
|
|
748
944
|
private
|
@@ -755,8 +951,8 @@ class DirtyTest < ActiveRecord::TestCase
|
|
755
951
|
end
|
756
952
|
|
757
953
|
def check_pirate_after_save_failure(pirate)
|
758
|
-
|
759
|
-
|
954
|
+
assert_predicate pirate, :changed?
|
955
|
+
assert_predicate pirate, :parrot_id_changed?
|
760
956
|
assert_equal %w(parrot_id), pirate.changed
|
761
957
|
assert_nil pirate.parrot_id_was
|
762
958
|
end
|