From 577d83a53d3f935e39b38d06ccfbd984331843ad Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Sat, 20 Jan 2018 15:07:30 +0900 Subject: More exercise `ActiveModel::Dirty` tests --- activemodel/test/cases/dirty_test.rb | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'activemodel') diff --git a/activemodel/test/cases/dirty_test.rb b/activemodel/test/cases/dirty_test.rb index dfe041ff50..8c183ec516 100644 --- a/activemodel/test/cases/dirty_test.rb +++ b/activemodel/test/cases/dirty_test.rb @@ -5,12 +5,13 @@ require "cases/helper" class DirtyTest < ActiveModel::TestCase class DirtyModel include ActiveModel::Dirty - define_attribute_methods :name, :color, :size + define_attribute_methods :name, :color, :size, :status def initialize @name = nil @color = nil @size = nil + @status = "initialized" end def name @@ -40,6 +41,15 @@ class DirtyTest < ActiveModel::TestCase @size = val end + def status + @status + end + + def status=(val) + status_will_change! unless val == @status + @status = val + end + def save changes_applied end @@ -135,15 +145,20 @@ class DirtyTest < ActiveModel::TestCase test "saving should preserve previous changes" do @model.name = "Jericho Cane" + @model.status = "waiting" @model.save assert_equal [nil, "Jericho Cane"], @model.previous_changes["name"] + assert_equal ["initialized", "waiting"], @model.previous_changes["status"] end test "setting new attributes should not affect previous changes" do @model.name = "Jericho Cane" + @model.status = "waiting" @model.save @model.name = "DudeFella ManGuy" + @model.status = "finished" assert_equal [nil, "Jericho Cane"], @model.name_previous_change + assert_equal ["initialized", "waiting"], @model.previous_changes["status"] end test "saving should preserve model's previous changed status" do @@ -155,20 +170,26 @@ class DirtyTest < ActiveModel::TestCase test "previous value is preserved when changed after save" do assert_equal({}, @model.changed_attributes) @model.name = "Paul" - assert_equal({ "name" => nil }, @model.changed_attributes) + @model.status = "waiting" + assert_equal({ "name" => nil, "status" => "initialized" }, @model.changed_attributes) @model.save @model.name = "John" - assert_equal({ "name" => "Paul" }, @model.changed_attributes) + @model.status = "finished" + assert_equal({ "name" => "Paul", "status" => "waiting" }, @model.changed_attributes) end test "changing the same attribute multiple times retains the correct original value" do @model.name = "Otto" + @model.status = "waiting" @model.save @model.name = "DudeFella ManGuy" @model.name = "Mr. Manfredgensonton" + @model.status = "processing" + @model.status = "finished" assert_equal ["Otto", "Mr. Manfredgensonton"], @model.name_change + assert_equal ["waiting", "finished"], @model.status_change assert_equal @model.name_was, "Otto" end -- cgit v1.2.3 From a19e91f0fab13cca61acdb1f33e27be2323b9786 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Mon, 22 Jan 2018 10:46:36 +0900 Subject: PERF: Recover `changes_applied` performance (#31698) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #30985 caused `object.save` performance regression since calling `changes` in `changes_applied` is very slow. We don't need to call the expensive method in `changes_applied` as long as `@attributes` is tracked by mutation tracker. https://gist.github.com/kamipo/1a9f4f3891803b914fc72ede98268aa2 Before: ``` Warming up -------------------------------------- create_string_columns 73.000 i/100ms Calculating ------------------------------------- create_string_columns 722.256 (± 5.8%) i/s - 3.650k in 5.073031s ``` After: ``` Warming up -------------------------------------- create_string_columns 96.000 i/100ms Calculating ------------------------------------- create_string_columns 950.224 (± 7.7%) i/s - 4.800k in 5.084837s ``` --- .../lib/active_model/attribute_mutation_tracker.rb | 7 +- activemodel/lib/active_model/dirty.rb | 106 ++++++++------------- 2 files changed, 43 insertions(+), 70 deletions(-) (limited to 'activemodel') diff --git a/activemodel/lib/active_model/attribute_mutation_tracker.rb b/activemodel/lib/active_model/attribute_mutation_tracker.rb index c67e1b809a..f55613ecd5 100644 --- a/activemodel/lib/active_model/attribute_mutation_tracker.rb +++ b/activemodel/lib/active_model/attribute_mutation_tracker.rb @@ -35,6 +35,10 @@ module ActiveModel end end + def changed_attribute_names + attr_names.select { |attr| changed?(attr) } + end + def any_changes? attr_names.any? { |attr| changed?(attr) } end @@ -109,8 +113,5 @@ module ActiveModel def original_value(*) end - - def force_change(*) - end end end diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb index d2ebd18107..0044fde6c5 100644 --- a/activemodel/lib/active_model/dirty.rb +++ b/activemodel/lib/active_model/dirty.rb @@ -3,6 +3,7 @@ require "active_support/hash_with_indifferent_access" require "active_support/core_ext/object/duplicable" require "active_model/attribute_mutation_tracker" +require "active_model/attribute_set" module ActiveModel # == Active \Model \Dirty @@ -142,9 +143,8 @@ module ActiveModel end def changes_applied # :nodoc: - @previously_changed = changes + _prepare_changes @mutations_before_last_save = mutations_from_database - @attributes_changed_by_setter = ActiveSupport::HashWithIndifferentAccess.new forget_attribute_assignments @mutations_from_database = nil end @@ -155,7 +155,7 @@ module ActiveModel # person.name = 'bob' # person.changed? # => true def changed? - changed_attributes.present? + mutations_from_database.any_changes? end # Returns an array with the name of the attributes with unsaved changes. @@ -164,24 +164,24 @@ module ActiveModel # person.name = 'bob' # person.changed # => ["name"] def changed - changed_attributes.keys + mutations_from_database.changed_attribute_names end # Handles *_changed? for +method_missing+. def attribute_changed?(attr, from: OPTION_NOT_GIVEN, to: OPTION_NOT_GIVEN) # :nodoc: - !!changes_include?(attr) && + !!mutations_from_database.changed?(attr) && (to == OPTION_NOT_GIVEN || to == _read_attribute(attr)) && - (from == OPTION_NOT_GIVEN || from == changed_attributes[attr]) + (from == OPTION_NOT_GIVEN || from == attribute_was(attr)) end # Handles *_was for +method_missing+. def attribute_was(attr) # :nodoc: - attribute_changed?(attr) ? changed_attributes[attr] : _read_attribute(attr) + mutations_from_database.original_value(attr) end # Handles *_previously_changed? for +method_missing+. def attribute_previously_changed?(attr) #:nodoc: - previous_changes_include?(attr) + mutations_before_last_save.changed?(attr) end # Restore all previous data of the provided attributes. @@ -191,15 +191,12 @@ module ActiveModel # Clears all dirty data: current changes and previous changes. def clear_changes_information - @previously_changed = ActiveSupport::HashWithIndifferentAccess.new @mutations_before_last_save = nil - @attributes_changed_by_setter = ActiveSupport::HashWithIndifferentAccess.new forget_attribute_assignments @mutations_from_database = nil end def clear_attribute_changes(attr_names) - attributes_changed_by_setter.except!(*attr_names) attr_names.each do |attr_name| clear_attribute_change(attr_name) end @@ -212,13 +209,7 @@ module ActiveModel # person.name = 'robert' # person.changed_attributes # => {"name" => "bob"} def changed_attributes - # This should only be set by methods which will call changed_attributes - # multiple times when it is known that the computed value cannot change. - if defined?(@cached_changed_attributes) - @cached_changed_attributes - else - attributes_changed_by_setter.reverse_merge(mutations_from_database.changed_values).freeze - end + mutations_from_database.changed_values.freeze end # Returns a hash of changed attributes indicating their original @@ -228,9 +219,8 @@ module ActiveModel # person.name = 'bob' # person.changes # => { "name" => ["bill", "bob"] } def changes - cache_changed_attributes do - ActiveSupport::HashWithIndifferentAccess[changed.map { |attr| [attr, attribute_change(attr)] }] - end + _prepare_changes + mutations_from_database.changes end # Returns a hash of attributes that were changed before the model was saved. @@ -240,8 +230,7 @@ module ActiveModel # person.save # person.previous_changes # => {"name" => ["bob", "robert"]} def previous_changes - @previously_changed ||= ActiveSupport::HashWithIndifferentAccess.new - @previously_changed.merge(mutations_before_last_save.changes) + mutations_before_last_save.changes end def attribute_changed_in_place?(attr_name) # :nodoc: @@ -257,11 +246,17 @@ module ActiveModel unless defined?(@mutations_from_database) @mutations_from_database = nil end - @mutations_from_database ||= if defined?(@attributes) - ActiveModel::AttributeMutationTracker.new(@attributes) - else - NullMutationTracker.instance + + unless defined?(@attributes) + @_pseudo_attributes = true + @attributes = AttributeSet.new( + Hash.new { |h, attr| + h[attr] = Attribute.with_cast_value(attr, _clone_attribute(attr), Type.default_value) + } + ) end + + @mutations_from_database ||= ActiveModel::AttributeMutationTracker.new(@attributes) end def forget_attribute_assignments @@ -272,68 +267,45 @@ module ActiveModel @mutations_before_last_save ||= ActiveModel::NullMutationTracker.instance end - def cache_changed_attributes - @cached_changed_attributes = changed_attributes - yield - ensure - clear_changed_attributes_cache - end - - def clear_changed_attributes_cache - remove_instance_variable(:@cached_changed_attributes) if defined?(@cached_changed_attributes) - end - - # Returns +true+ if attr_name is changed, +false+ otherwise. - def changes_include?(attr_name) - attributes_changed_by_setter.include?(attr_name) || mutations_from_database.changed?(attr_name) - end - alias attribute_changed_by_setter? changes_include? - - # Returns +true+ if attr_name were changed before the model was saved, - # +false+ otherwise. - def previous_changes_include?(attr_name) - previous_changes.include?(attr_name) - end - # Handles *_change for +method_missing+. def attribute_change(attr) - [changed_attributes[attr], _read_attribute(attr)] if attribute_changed?(attr) + [attribute_was(attr), _read_attribute(attr)] if attribute_changed?(attr) end # Handles *_previous_change for +method_missing+. def attribute_previous_change(attr) - previous_changes[attr] if attribute_previously_changed?(attr) + mutations_before_last_save.change_to_attribute(attr) end # Handles *_will_change! for +method_missing+. def attribute_will_change!(attr) - unless attribute_changed?(attr) - begin - value = _read_attribute(attr) - value = value.duplicable? ? value.clone : value - rescue TypeError, NoMethodError - end - - set_attribute_was(attr, value) + attr = attr.to_s + mutations_from_database.force_change(attr).tap do + @attributes[attr] if defined?(@_pseudo_attributes) end - mutations_from_database.force_change(attr) end # Handles restore_*! for +method_missing+. def restore_attribute!(attr) if attribute_changed?(attr) - __send__("#{attr}=", changed_attributes[attr]) + __send__("#{attr}=", attribute_was(attr)) clear_attribute_changes([attr]) end end - def attributes_changed_by_setter - @attributes_changed_by_setter ||= ActiveSupport::HashWithIndifferentAccess.new + def _prepare_changes + if defined?(@_pseudo_attributes) + changed.each do |attr| + @attributes.write_from_user(attr, _read_attribute(attr)) + end + end end - # Force an attribute to have a particular "before" value - def set_attribute_was(attr, old_value) - attributes_changed_by_setter[attr] = old_value + def _clone_attribute(attr) + value = _read_attribute(attr) + value.duplicable? ? value.clone : value + rescue TypeError, NoMethodError + value end end end -- cgit v1.2.3 From 00de46acf52868d4e0d9fdee58c823c599a275a1 Mon Sep 17 00:00:00 2001 From: Daniel Colson Date: Sun, 21 Jan 2018 22:06:59 -0500 Subject: Use singular define_attribute_method `define_attribute_methods` splats the arguments, then calls out to `define_attribute_method` for each. When defining a singule attribute, using the singular version of the method saves us an array and an extra method call. --- activemodel/lib/active_model/attributes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activemodel') diff --git a/activemodel/lib/active_model/attributes.rb b/activemodel/lib/active_model/attributes.rb index 28dd24b3cd..046ae67ad7 100644 --- a/activemodel/lib/active_model/attributes.rb +++ b/activemodel/lib/active_model/attributes.rb @@ -23,7 +23,7 @@ module ActiveModel end self.attribute_types = attribute_types.merge(name => type) define_default_attribute(name, options.fetch(:default, NO_DEFAULT_PROVIDED), type) - define_attribute_methods(name) + define_attribute_method(name) end private -- cgit v1.2.3 From 0af36c62a5710e023402e37b019ad9982e69de4b Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Tue, 23 Jan 2018 14:08:46 -0700 Subject: Allow attributes with a proc default to be marshalled We don't implement much custom marshalling logic for these objects, but the proc default case needs to be handled separately. Unfortunately there's no way to just say "do what you would have done but with this value for one ivar", so we have to manually implement `marshal_load` as well. The test case is a little bit funky, but I'd really like an equality test in there, and there's no easy way to add one now that this is out of AR (since the `attributes` method isn't here) Fixes #31216 --- activemodel/CHANGELOG.md | 7 +++++++ .../attribute/user_provided_default.rb | 22 ++++++++++++++++++++++ activemodel/test/cases/attributes_test.rb | 9 +++++++++ 3 files changed, 38 insertions(+) (limited to 'activemodel') diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index b67a803b9d..86353674d9 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -1,7 +1,14 @@ +* Models using the attributes API with a proc default can now be marshalled. + + Fixes #31216. + + *Sean Griffin* + * Fix to working before/after validation callbacks on multiple contexts. *Yoshiyuki Hirano* + ## Rails 5.2.0.beta2 (November 28, 2017) ## * No changes. diff --git a/activemodel/lib/active_model/attribute/user_provided_default.rb b/activemodel/lib/active_model/attribute/user_provided_default.rb index f274b687d4..a5dc6188d2 100644 --- a/activemodel/lib/active_model/attribute/user_provided_default.rb +++ b/activemodel/lib/active_model/attribute/user_provided_default.rb @@ -22,6 +22,28 @@ module ActiveModel self.class.new(name, user_provided_value, type, original_attribute) end + def marshal_dump + result = [ + name, + value_before_type_cast, + type, + original_attribute, + ] + result << value if defined?(@value) + result + end + + def marshal_load(values) + name, user_provided_value, type, original_attribute, value = values + @name = name + @user_provided_value = user_provided_value + @type = type + @original_attribute = original_attribute + if values.length == 5 + @value = value + end + end + protected attr_reader :user_provided_value diff --git a/activemodel/test/cases/attributes_test.rb b/activemodel/test/cases/attributes_test.rb index e43bf15335..7c1d813ce0 100644 --- a/activemodel/test/cases/attributes_test.rb +++ b/activemodel/test/cases/attributes_test.rb @@ -64,5 +64,14 @@ module ActiveModel assert_equal "4.4", data.integer_field end + + test "attributes with proc defaults can be marshalled" do + data = ModelForAttributesTest.new + attributes = data.instance_variable_get(:@attributes) + round_tripped = Marshal.load(Marshal.dump(data)) + new_attributes = round_tripped.instance_variable_get(:@attributes) + + assert_equal attributes, new_attributes + end end end -- cgit v1.2.3 From 0d50cae996c51630361e8514e1f168b0c48957e1 Mon Sep 17 00:00:00 2001 From: Daniel Colson Date: Wed, 24 Jan 2018 21:14:10 -0500 Subject: Use respond_to test helpers --- activemodel/lib/active_model/lint.rb | 24 ++++++++++++------------ activemodel/test/cases/attribute_methods_test.rb | 4 ++-- activemodel/test/cases/callbacks_test.rb | 12 ++++++------ activemodel/test/cases/errors_test.rb | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) (limited to 'activemodel') diff --git a/activemodel/lib/active_model/lint.rb b/activemodel/lib/active_model/lint.rb index 34d9ac6c96..b7ceabb59a 100644 --- a/activemodel/lib/active_model/lint.rb +++ b/activemodel/lib/active_model/lint.rb @@ -29,7 +29,7 @@ module ActiveModel # to_key returns an Enumerable of all (primary) key attributes # of the model, and is used to a generate unique DOM id for the object. def test_to_key - assert model.respond_to?(:to_key), "The model should respond to to_key" + assert_respond_to model, :to_key def model.persisted?() false end assert model.to_key.nil?, "to_key should return nil when `persisted?` returns false" end @@ -44,7 +44,7 @@ module ActiveModel # tests for this behavior in lint because it doesn't make sense to force # any of the possible implementation strategies on the implementer. def test_to_param - assert model.respond_to?(:to_param), "The model should respond to to_param" + assert_respond_to model, :to_param def model.to_key() [1] end def model.persisted?() false end assert model.to_param.nil?, "to_param should return nil when `persisted?` returns false" @@ -56,7 +56,7 @@ module ActiveModel # to_partial_path is used for looking up partials. For example, # a BlogPost model might return "blog_posts/blog_post". def test_to_partial_path - assert model.respond_to?(:to_partial_path), "The model should respond to to_partial_path" + assert_respond_to model, :to_partial_path assert_kind_of String, model.to_partial_path end @@ -68,7 +68,7 @@ module ActiveModel # will route to the create action. If it is persisted, a form for the # object will route to the update action. def test_persisted? - assert model.respond_to?(:persisted?), "The model should respond to persisted?" + assert_respond_to model, :persisted? assert_boolean model.persisted?, "persisted?" end @@ -79,14 +79,14 @@ module ActiveModel # # Check ActiveModel::Naming for more information. def test_model_naming - assert model.class.respond_to?(:model_name), "The model class should respond to model_name" + assert_respond_to model.class, :model_name model_name = model.class.model_name - assert model_name.respond_to?(:to_str) - assert model_name.human.respond_to?(:to_str) - assert model_name.singular.respond_to?(:to_str) - assert model_name.plural.respond_to?(:to_str) + assert_respond_to model_name, :to_str + assert_respond_to model_name.human, :to_str + assert_respond_to model_name.singular, :to_str + assert_respond_to model_name.plural, :to_str - assert model.respond_to?(:model_name), "The model instance should respond to model_name" + assert_respond_to model, :model_name assert_equal model.model_name, model.class.model_name end @@ -100,13 +100,13 @@ module ActiveModel # If localization is used, the strings should be localized for the current # locale. If no error is present, the method should return an empty array. def test_errors_aref - assert model.respond_to?(:errors), "The model should respond to errors" + assert_respond_to model, :errors assert model.errors[:hello].is_a?(Array), "errors#[] should return an Array" end private def model - assert @model.respond_to?(:to_model), "The object should respond to to_model" + assert_respond_to @model, :to_model @model.to_model end diff --git a/activemodel/test/cases/attribute_methods_test.rb b/activemodel/test/cases/attribute_methods_test.rb index d2837ec894..0cfc6f4b6b 100644 --- a/activemodel/test/cases/attribute_methods_test.rb +++ b/activemodel/test/cases/attribute_methods_test.rb @@ -220,7 +220,7 @@ class AttributeMethodsTest < ActiveModel::TestCase ModelWithAttributes.define_attribute_methods(:foo) ModelWithAttributes.undefine_attribute_methods - assert !ModelWithAttributes.new.respond_to?(:foo) + assert_not_respond_to ModelWithAttributes.new, :foo assert_raises(NoMethodError) { ModelWithAttributes.new.foo } end @@ -255,7 +255,7 @@ class AttributeMethodsTest < ActiveModel::TestCase m = ModelWithAttributes2.new m.attributes = { "private_method" => "<3", "protected_method" => "O_o" } - assert !m.respond_to?(:private_method) + assert_not_respond_to m, :private_method assert m.respond_to?(:private_method, true) c = ClassWithProtected.new diff --git a/activemodel/test/cases/callbacks_test.rb b/activemodel/test/cases/callbacks_test.rb index a5d29d0f22..1ec12d8222 100644 --- a/activemodel/test/cases/callbacks_test.rb +++ b/activemodel/test/cases/callbacks_test.rb @@ -85,21 +85,21 @@ class CallbacksTest < ActiveModel::TestCase end test "only selects which types of callbacks should be created" do - assert !ModelCallbacks.respond_to?(:before_initialize) - assert !ModelCallbacks.respond_to?(:around_initialize) + assert_not_respond_to ModelCallbacks, :before_initialize + assert_not_respond_to ModelCallbacks, :around_initialize assert_respond_to ModelCallbacks, :after_initialize end test "only selects which types of callbacks should be created from an array list" do assert_respond_to ModelCallbacks, :before_multiple assert_respond_to ModelCallbacks, :around_multiple - assert !ModelCallbacks.respond_to?(:after_multiple) + assert_not_respond_to ModelCallbacks, :after_multiple end test "no callbacks should be created" do - assert !ModelCallbacks.respond_to?(:before_empty) - assert !ModelCallbacks.respond_to?(:around_empty) - assert !ModelCallbacks.respond_to?(:after_empty) + assert_not_respond_to ModelCallbacks, :before_empty + assert_not_respond_to ModelCallbacks, :around_empty + assert_not_respond_to ModelCallbacks, :after_empty end class Violin diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb index d5c282b620..16ace62f26 100644 --- a/activemodel/test/cases/errors_test.rb +++ b/activemodel/test/cases/errors_test.rb @@ -320,7 +320,7 @@ class ErrorsTest < ActiveModel::TestCase test "generate_message works without i18n_scope" do person = Person.new - assert !Person.respond_to?(:i18n_scope) + assert_not_respond_to Person, :i18n_scope assert_nothing_raised { person.errors.generate_message(:name, :blank) } -- cgit v1.2.3 From 211adb47e76b358ea15a3f756431c042ab231c23 Mon Sep 17 00:00:00 2001 From: Daniel Colson Date: Wed, 24 Jan 2018 22:04:11 -0500 Subject: Change refute to assert_not --- activemodel/test/cases/attribute_test.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'activemodel') diff --git a/activemodel/test/cases/attribute_test.rb b/activemodel/test/cases/attribute_test.rb index 14d86cef97..47ca495a01 100644 --- a/activemodel/test/cases/attribute_test.rb +++ b/activemodel/test/cases/attribute_test.rb @@ -187,7 +187,7 @@ module ActiveModel test "an attribute is not changed if it hasn't been assigned or mutated" do attribute = Attribute.from_database(:foo, 1, Type::Value.new) - refute attribute.changed? + assert_not attribute.changed? end test "an attribute is changed if it's been assigned a new value" do @@ -201,7 +201,7 @@ module ActiveModel attribute = Attribute.from_database(:foo, 1, Type::Value.new) unchanged = attribute.with_value_from_user(1) - refute unchanged.changed? + assert_not unchanged.changed? end test "an attribute can not be mutated if it has not been read, @@ -226,7 +226,7 @@ module ActiveModel forgotten = changed.forgetting_assignment assert changed.changed? # sanity check - refute forgotten.changed? + assert_not forgotten.changed? end test "with_value_from_user validates the value" do -- cgit v1.2.3 From 94333a4c31bd10c1f358c538a167e6a4589bae2d Mon Sep 17 00:00:00 2001 From: Daniel Colson Date: Thu, 25 Jan 2018 18:14:09 -0500 Subject: Use assert_predicate and assert_not_predicate --- activemodel/test/cases/attribute_set_test.rb | 10 +- activemodel/test/cases/attribute_test.rb | 18 +- activemodel/test/cases/attributes_dirty_test.rb | 38 ++-- activemodel/test/cases/dirty_test.rb | 40 ++--- activemodel/test/cases/errors_test.rb | 8 +- activemodel/test/cases/type/boolean_test.rb | 4 +- .../cases/validations/absence_validation_test.rb | 18 +- .../validations/acceptance_validation_test.rb | 26 +-- .../validations/conditional_validation_test.rb | 42 ++--- .../validations/confirmation_validation_test.rb | 28 +-- .../cases/validations/exclusion_validation_test.rb | 36 ++-- .../cases/validations/format_validation_test.rb | 34 ++-- .../cases/validations/inclusion_validation_test.rb | 88 ++++----- .../cases/validations/length_validation_test.rb | 196 ++++++++++----------- .../validations/numericality_validation_test.rb | 10 +- .../cases/validations/presence_validation_test.rb | 20 +-- .../test/cases/validations/validates_test.rb | 22 +-- .../test/cases/validations/with_validation_test.rb | 28 +-- activemodel/test/cases/validations_test.rb | 56 +++--- 19 files changed, 361 insertions(+), 361 deletions(-) (limited to 'activemodel') diff --git a/activemodel/test/cases/attribute_set_test.rb b/activemodel/test/cases/attribute_set_test.rb index 6e522d6c80..9f7498fa65 100644 --- a/activemodel/test/cases/attribute_set_test.rb +++ b/activemodel/test/cases/attribute_set_test.rb @@ -74,8 +74,8 @@ module ActiveModel clone.freeze - assert clone.frozen? - assert_not attributes.frozen? + assert_predicate clone, :frozen? + assert_not_predicate attributes, :frozen? end test "to_hash returns a hash of the type cast values" do @@ -105,8 +105,8 @@ module ActiveModel test "known columns are built with uninitialized attributes" do attributes = attributes_with_uninitialized_key - assert attributes[:foo].initialized? - assert_not attributes[:bar].initialized? + assert_predicate attributes[:foo], :initialized? + assert_not_predicate attributes[:bar], :initialized? end test "uninitialized attributes are not included in the attributes hash" do @@ -169,7 +169,7 @@ module ActiveModel assert attributes.key?(:foo) assert_equal [:foo], attributes.keys - assert attributes[:foo].initialized? + assert_predicate attributes[:foo], :initialized? end class MyType diff --git a/activemodel/test/cases/attribute_test.rb b/activemodel/test/cases/attribute_test.rb index 47ca495a01..ea2b0efd11 100644 --- a/activemodel/test/cases/attribute_test.rb +++ b/activemodel/test/cases/attribute_test.rb @@ -175,33 +175,33 @@ module ActiveModel test "an attribute has not been read by default" do attribute = Attribute.from_database(:foo, 1, Type::Value.new) - assert_not attribute.has_been_read? + assert_not_predicate attribute, :has_been_read? end test "an attribute has been read when its value is calculated" do attribute = Attribute.from_database(:foo, 1, Type::Value.new) attribute.value - assert attribute.has_been_read? + assert_predicate attribute, :has_been_read? end test "an attribute is not changed if it hasn't been assigned or mutated" do attribute = Attribute.from_database(:foo, 1, Type::Value.new) - assert_not attribute.changed? + assert_not_predicate attribute, :changed? end test "an attribute is changed if it's been assigned a new value" do attribute = Attribute.from_database(:foo, 1, Type::Value.new) changed = attribute.with_value_from_user(2) - assert changed.changed? + assert_predicate changed, :changed? end test "an attribute is not changed if it's assigned the same value" do attribute = Attribute.from_database(:foo, 1, Type::Value.new) unchanged = attribute.with_value_from_user(1) - assert_not unchanged.changed? + assert_not_predicate unchanged, :changed? end test "an attribute can not be mutated if it has not been read, @@ -209,15 +209,15 @@ module ActiveModel type_which_raises_from_all_methods = Object.new attribute = Attribute.from_database(:foo, "bar", type_which_raises_from_all_methods) - assert_not attribute.changed_in_place? + assert_not_predicate attribute, :changed_in_place? end test "an attribute is changed if it has been mutated" do attribute = Attribute.from_database(:foo, "bar", Type::String.new) attribute.value << "!" - assert attribute.changed_in_place? - assert attribute.changed? + assert_predicate attribute, :changed_in_place? + assert_predicate attribute, :changed? end test "an attribute can forget its changes" do @@ -226,7 +226,7 @@ module ActiveModel forgotten = changed.forgetting_assignment assert changed.changed? # sanity check - assert_not forgotten.changed? + assert_not_predicate forgotten, :changed? end test "with_value_from_user validates the value" do diff --git a/activemodel/test/cases/attributes_dirty_test.rb b/activemodel/test/cases/attributes_dirty_test.rb index 83a86371e0..c991176389 100644 --- a/activemodel/test/cases/attributes_dirty_test.rb +++ b/activemodel/test/cases/attributes_dirty_test.rb @@ -25,11 +25,11 @@ class AttributesDirtyTest < ActiveModel::TestCase end test "setting attribute will result in change" do - assert !@model.changed? - assert !@model.name_changed? + assert_not_predicate @model, :changed? + assert_not_predicate @model, :name_changed? @model.name = "Ringo" - assert @model.changed? - assert @model.name_changed? + assert_predicate @model, :changed? + assert_predicate @model, :name_changed? end test "list of changed attribute keys" do @@ -71,35 +71,35 @@ class AttributesDirtyTest < ActiveModel::TestCase test "attribute mutation" do @model.name = "Yam" @model.save - assert !@model.name_changed? + assert_not_predicate @model, :name_changed? @model.name.replace("Hadad") - assert @model.name_changed? + assert_predicate @model, :name_changed? end test "resetting attribute" do @model.name = "Bob" @model.restore_name! assert_nil @model.name - assert !@model.name_changed? + assert_not_predicate @model, :name_changed? end test "setting color to same value should not result in change being recorded" do @model.color = "red" - assert @model.color_changed? + assert_predicate @model, :color_changed? @model.save - assert !@model.color_changed? - assert !@model.changed? + assert_not_predicate @model, :color_changed? + assert_not_predicate @model, :changed? @model.color = "red" - assert !@model.color_changed? - assert !@model.changed? + assert_not_predicate @model, :color_changed? + assert_not_predicate @model, :changed? end test "saving should reset model's changed status" do @model.name = "Alf" - assert @model.changed? + assert_predicate @model, :changed? @model.save - assert !@model.changed? - assert !@model.name_changed? + assert_not_predicate @model, :changed? + assert_not_predicate @model, :name_changed? end test "saving should preserve previous changes" do @@ -118,7 +118,7 @@ class AttributesDirtyTest < ActiveModel::TestCase test "saving should preserve model's previous changed status" do @model.name = "Jericho Cane" @model.save - assert @model.name_previously_changed? + assert_predicate @model, :name_previously_changed? end test "previous value is preserved when changed after save" do @@ -143,7 +143,7 @@ class AttributesDirtyTest < ActiveModel::TestCase test "using attribute_will_change! with a symbol" do @model.size = 1 - assert @model.size_changed? + assert_predicate @model, :size_changed? end test "reload should reset all changes" do @@ -170,7 +170,7 @@ class AttributesDirtyTest < ActiveModel::TestCase @model.restore_attributes - assert_not @model.changed? + assert_not_predicate @model, :changed? assert_equal "Dmitry", @model.name assert_equal "Red", @model.color end @@ -184,7 +184,7 @@ class AttributesDirtyTest < ActiveModel::TestCase @model.restore_attributes(["name"]) - assert @model.changed? + assert_predicate @model, :changed? assert_equal "Dmitry", @model.name assert_equal "White", @model.color end diff --git a/activemodel/test/cases/dirty_test.rb b/activemodel/test/cases/dirty_test.rb index 8c183ec516..f769eb0da1 100644 --- a/activemodel/test/cases/dirty_test.rb +++ b/activemodel/test/cases/dirty_test.rb @@ -64,11 +64,11 @@ class DirtyTest < ActiveModel::TestCase end test "setting attribute will result in change" do - assert !@model.changed? - assert !@model.name_changed? + assert_not_predicate @model, :changed? + assert_not_predicate @model, :name_changed? @model.name = "Ringo" - assert @model.changed? - assert @model.name_changed? + assert_predicate @model, :changed? + assert_predicate @model, :name_changed? end test "list of changed attribute keys" do @@ -109,38 +109,38 @@ class DirtyTest < ActiveModel::TestCase test "attribute mutation" do @model.instance_variable_set("@name", "Yam".dup) - assert !@model.name_changed? + assert_not_predicate @model, :name_changed? @model.name.replace("Hadad") - assert !@model.name_changed? + assert_not_predicate @model, :name_changed? @model.name_will_change! @model.name.replace("Baal") - assert @model.name_changed? + assert_predicate @model, :name_changed? end test "resetting attribute" do @model.name = "Bob" @model.restore_name! assert_nil @model.name - assert !@model.name_changed? + assert_not_predicate @model, :name_changed? end test "setting color to same value should not result in change being recorded" do @model.color = "red" - assert @model.color_changed? + assert_predicate @model, :color_changed? @model.save - assert !@model.color_changed? - assert !@model.changed? + assert_not_predicate @model, :color_changed? + assert_not_predicate @model, :changed? @model.color = "red" - assert !@model.color_changed? - assert !@model.changed? + assert_not_predicate @model, :color_changed? + assert_not_predicate @model, :changed? end test "saving should reset model's changed status" do @model.name = "Alf" - assert @model.changed? + assert_predicate @model, :changed? @model.save - assert !@model.changed? - assert !@model.name_changed? + assert_not_predicate @model, :changed? + assert_not_predicate @model, :name_changed? end test "saving should preserve previous changes" do @@ -164,7 +164,7 @@ class DirtyTest < ActiveModel::TestCase test "saving should preserve model's previous changed status" do @model.name = "Jericho Cane" @model.save - assert @model.name_previously_changed? + assert_predicate @model, :name_previously_changed? end test "previous value is preserved when changed after save" do @@ -195,7 +195,7 @@ class DirtyTest < ActiveModel::TestCase test "using attribute_will_change! with a symbol" do @model.size = 1 - assert @model.size_changed? + assert_predicate @model, :size_changed? end test "reload should reset all changes" do @@ -222,7 +222,7 @@ class DirtyTest < ActiveModel::TestCase @model.restore_attributes - assert_not @model.changed? + assert_not_predicate @model, :changed? assert_equal "Dmitry", @model.name assert_equal "Red", @model.color end @@ -236,7 +236,7 @@ class DirtyTest < ActiveModel::TestCase @model.restore_attributes(["name"]) - assert @model.changed? + assert_predicate @model, :changed? assert_equal "Dmitry", @model.name assert_equal "White", @model.color end diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb index 16ace62f26..7d155170d3 100644 --- a/activemodel/test/cases/errors_test.rb +++ b/activemodel/test/cases/errors_test.rb @@ -83,7 +83,7 @@ class ErrorsTest < ActiveModel::TestCase assert_equal 1, person.errors.count person.errors.clear - assert person.errors.empty? + assert_predicate person.errors, :empty? end test "error access is indifferent" do @@ -128,8 +128,8 @@ class ErrorsTest < ActiveModel::TestCase test "detecting whether there are errors with empty?, blank?, include?" do person = Person.new person.errors[:foo] - assert person.errors.empty? - assert person.errors.blank? + assert_predicate person.errors, :empty? + assert_predicate person.errors, :blank? assert_not_includes person.errors, :foo end @@ -371,7 +371,7 @@ class ErrorsTest < ActiveModel::TestCase assert_equal 1, person.errors.details.count person.errors.clear - assert person.errors.details.empty? + assert_predicate person.errors.details, :empty? end test "copy errors" do diff --git a/activemodel/test/cases/type/boolean_test.rb b/activemodel/test/cases/type/boolean_test.rb index 2d33579595..2de0f53640 100644 --- a/activemodel/test/cases/type/boolean_test.rb +++ b/activemodel/test/cases/type/boolean_test.rb @@ -7,8 +7,8 @@ module ActiveModel class BooleanTest < ActiveModel::TestCase def test_type_cast_boolean type = Type::Boolean.new - assert type.cast("").nil? - assert type.cast(nil).nil? + assert_predicate type.cast(""), :nil? + assert_predicate type.cast(nil), :nil? assert type.cast(true) assert type.cast(1) diff --git a/activemodel/test/cases/validations/absence_validation_test.rb b/activemodel/test/cases/validations/absence_validation_test.rb index 801577474a..8bc4f4723a 100644 --- a/activemodel/test/cases/validations/absence_validation_test.rb +++ b/activemodel/test/cases/validations/absence_validation_test.rb @@ -17,16 +17,16 @@ class AbsenceValidationTest < ActiveModel::TestCase t = Topic.new t.title = "foo" t.content = "bar" - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["must be blank"], t.errors[:title] assert_equal ["must be blank"], t.errors[:content] t.title = "" t.content = "something" - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["must be blank"], t.errors[:content] assert_equal [], t.errors[:title] t.content = "" - assert t.valid? + assert_predicate t, :valid? end def test_validates_absence_of_with_array_arguments @@ -34,7 +34,7 @@ class AbsenceValidationTest < ActiveModel::TestCase t = Topic.new t.title = "foo" t.content = "bar" - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["must be blank"], t.errors[:title] assert_equal ["must be blank"], t.errors[:content] end @@ -43,7 +43,7 @@ class AbsenceValidationTest < ActiveModel::TestCase Person.validates_absence_of :karma, message: "This string contains 'single' and \"double\" quotes" p = Person.new p.karma = "good" - assert p.invalid? + assert_predicate p, :invalid? assert_equal "This string contains 'single' and \"double\" quotes", p.errors[:karma].last end @@ -51,19 +51,19 @@ class AbsenceValidationTest < ActiveModel::TestCase Person.validates_absence_of :karma p = Person.new p.karma = "good" - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["must be blank"], p.errors[:karma] p.karma = nil - assert p.valid? + assert_predicate p, :valid? end def test_validates_absence_of_for_ruby_class_with_custom_reader CustomReader.validates_absence_of :karma p = CustomReader.new p[:karma] = "excellent" - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["must be blank"], p.errors[:karma] p[:karma] = "" - assert p.valid? + assert_predicate p, :valid? end end diff --git a/activemodel/test/cases/validations/acceptance_validation_test.rb b/activemodel/test/cases/validations/acceptance_validation_test.rb index c5f54b1868..7662f996ae 100644 --- a/activemodel/test/cases/validations/acceptance_validation_test.rb +++ b/activemodel/test/cases/validations/acceptance_validation_test.rb @@ -15,54 +15,54 @@ class AcceptanceValidationTest < ActiveModel::TestCase Topic.validates_acceptance_of(:terms_of_service) t = Topic.new("title" => "We should not be confirmed") - assert t.valid? + assert_predicate t, :valid? end def test_terms_of_service_agreement Topic.validates_acceptance_of(:terms_of_service) t = Topic.new("title" => "We should be confirmed", "terms_of_service" => "") - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["must be accepted"], t.errors[:terms_of_service] t.terms_of_service = "1" - assert t.valid? + assert_predicate t, :valid? end def test_eula Topic.validates_acceptance_of(:eula, message: "must be abided") t = Topic.new("title" => "We should be confirmed", "eula" => "") - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["must be abided"], t.errors[:eula] t.eula = "1" - assert t.valid? + assert_predicate t, :valid? end def test_terms_of_service_agreement_with_accept_value Topic.validates_acceptance_of(:terms_of_service, accept: "I agree.") t = Topic.new("title" => "We should be confirmed", "terms_of_service" => "") - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["must be accepted"], t.errors[:terms_of_service] t.terms_of_service = "I agree." - assert t.valid? + assert_predicate t, :valid? end def test_terms_of_service_agreement_with_multiple_accept_values Topic.validates_acceptance_of(:terms_of_service, accept: [1, "I concur."]) t = Topic.new("title" => "We should be confirmed", "terms_of_service" => "") - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["must be accepted"], t.errors[:terms_of_service] t.terms_of_service = 1 - assert t.valid? + assert_predicate t, :valid? t.terms_of_service = "I concur." - assert t.valid? + assert_predicate t, :valid? end def test_validates_acceptance_of_for_ruby_class @@ -71,11 +71,11 @@ class AcceptanceValidationTest < ActiveModel::TestCase p = Person.new p.karma = "" - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["must be accepted"], p.errors[:karma] p.karma = "1" - assert p.valid? + assert_predicate p, :valid? ensure Person.clear_validators! end @@ -83,6 +83,6 @@ class AcceptanceValidationTest < ActiveModel::TestCase def test_validates_acceptance_of_true Topic.validates_acceptance_of(:terms_of_service) - assert Topic.new(terms_of_service: true).valid? + assert_predicate Topic.new(terms_of_service: true), :valid? end end diff --git a/activemodel/test/cases/validations/conditional_validation_test.rb b/activemodel/test/cases/validations/conditional_validation_test.rb index caea8b65ef..1704db9a48 100644 --- a/activemodel/test/cases/validations/conditional_validation_test.rb +++ b/activemodel/test/cases/validations/conditional_validation_test.rb @@ -13,24 +13,24 @@ class ConditionalValidationTest < ActiveModel::TestCase # When the method returns true Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: :condition_is_true) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["hoo 5"], t.errors["title"] end def test_if_validation_using_array_of_true_methods Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: [:condition_is_true, :condition_is_true]) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["hoo 5"], t.errors["title"] end def test_unless_validation_using_array_of_false_methods Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: [:condition_is_false, :condition_is_false]) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["hoo 5"], t.errors["title"] end @@ -38,21 +38,21 @@ class ConditionalValidationTest < ActiveModel::TestCase # When the method returns true Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: :condition_is_true) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? assert_empty t.errors[:title] end def test_if_validation_using_array_of_true_and_false_methods Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: [:condition_is_true, :condition_is_false]) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? assert_empty t.errors[:title] end def test_unless_validation_using_array_of_true_and_felse_methods Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: [:condition_is_true, :condition_is_false]) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? assert_empty t.errors[:title] end @@ -60,7 +60,7 @@ class ConditionalValidationTest < ActiveModel::TestCase # When the method returns false Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: :condition_is_false) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? assert_empty t.errors[:title] end @@ -68,8 +68,8 @@ class ConditionalValidationTest < ActiveModel::TestCase # When the method returns false Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: :condition_is_false) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["hoo 5"], t.errors["title"] end @@ -78,8 +78,8 @@ class ConditionalValidationTest < ActiveModel::TestCase Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: Proc.new { |r| r.content.size > 4 }) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["hoo 5"], t.errors["title"] end @@ -88,7 +88,7 @@ class ConditionalValidationTest < ActiveModel::TestCase Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: Proc.new { |r| r.content.size > 4 }) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? assert_empty t.errors[:title] end @@ -97,7 +97,7 @@ class ConditionalValidationTest < ActiveModel::TestCase Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: Proc.new { |r| r.title != "uhohuhoh" }) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? assert_empty t.errors[:title] end @@ -106,23 +106,23 @@ class ConditionalValidationTest < ActiveModel::TestCase Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: Proc.new { |r| r.title != "uhohuhoh" }) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["hoo 5"], t.errors["title"] end def test_validation_using_conbining_if_true_and_unless_true_conditions Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: :condition_is_true, unless: :condition_is_true) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? assert_empty t.errors[:title] end def test_validation_using_conbining_if_true_and_unless_false_conditions Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: :condition_is_true, unless: :condition_is_false) t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["hoo 5"], t.errors["title"] end end diff --git a/activemodel/test/cases/validations/confirmation_validation_test.rb b/activemodel/test/cases/validations/confirmation_validation_test.rb index 8b2c65289b..8603a8ac5c 100644 --- a/activemodel/test/cases/validations/confirmation_validation_test.rb +++ b/activemodel/test/cases/validations/confirmation_validation_test.rb @@ -14,40 +14,40 @@ class ConfirmationValidationTest < ActiveModel::TestCase Topic.validates_confirmation_of(:title) t = Topic.new(author_name: "Plutarch") - assert t.valid? + assert_predicate t, :valid? t.title_confirmation = "Parallel Lives" - assert t.invalid? + assert_predicate t, :invalid? t.title_confirmation = nil t.title = "Parallel Lives" - assert t.valid? + assert_predicate t, :valid? t.title_confirmation = "Parallel Lives" - assert t.valid? + assert_predicate t, :valid? end def test_title_confirmation Topic.validates_confirmation_of(:title) t = Topic.new("title" => "We should be confirmed", "title_confirmation" => "") - assert t.invalid? + assert_predicate t, :invalid? t.title_confirmation = "We should be confirmed" - assert t.valid? + assert_predicate t, :valid? end def test_validates_confirmation_of_with_boolean_attribute Topic.validates_confirmation_of(:approved) t = Topic.new(approved: true, approved_confirmation: nil) - assert t.valid? + assert_predicate t, :valid? t.approved_confirmation = false - assert t.invalid? + assert_predicate t, :invalid? t.approved_confirmation = true - assert t.valid? + assert_predicate t, :valid? end def test_validates_confirmation_of_for_ruby_class @@ -55,12 +55,12 @@ class ConfirmationValidationTest < ActiveModel::TestCase p = Person.new p.karma_confirmation = "None" - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["doesn't match Karma"], p.errors[:karma_confirmation] p.karma = "None" - assert p.valid? + assert_predicate p, :valid? ensure Person.clear_validators! end @@ -77,7 +77,7 @@ class ConfirmationValidationTest < ActiveModel::TestCase Topic.validates_confirmation_of(:title) t = Topic.new("title" => "We should be confirmed", "title_confirmation" => "") - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["doesn't match Test Title"], t.errors[:title_confirmation] ensure I18n.load_path.replace @old_load_path @@ -122,13 +122,13 @@ class ConfirmationValidationTest < ActiveModel::TestCase Topic.validates_confirmation_of(:title, case_sensitive: true) t = Topic.new(title: "title", title_confirmation: "Title") - assert t.invalid? + assert_predicate t, :invalid? end def test_title_confirmation_with_case_sensitive_option_false Topic.validates_confirmation_of(:title, case_sensitive: false) t = Topic.new(title: "title", title_confirmation: "Title") - assert t.valid? + assert_predicate t, :valid? end end diff --git a/activemodel/test/cases/validations/exclusion_validation_test.rb b/activemodel/test/cases/validations/exclusion_validation_test.rb index 68d611e904..50bd47065c 100644 --- a/activemodel/test/cases/validations/exclusion_validation_test.rb +++ b/activemodel/test/cases/validations/exclusion_validation_test.rb @@ -14,8 +14,8 @@ class ExclusionValidationTest < ActiveModel::TestCase def test_validates_exclusion_of Topic.validates_exclusion_of(:title, in: %w( abe monkey )) - assert Topic.new("title" => "something", "content" => "abc").valid? - assert Topic.new("title" => "monkey", "content" => "abc").invalid? + assert_predicate Topic.new("title" => "something", "content" => "abc"), :valid? + assert_predicate Topic.new("title" => "monkey", "content" => "abc"), :invalid? end def test_validates_exclusion_of_with_formatted_message @@ -24,8 +24,8 @@ class ExclusionValidationTest < ActiveModel::TestCase assert Topic.new("title" => "something", "content" => "abc") t = Topic.new("title" => "monkey") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["option monkey is restricted"], t.errors[:title] end @@ -35,8 +35,8 @@ class ExclusionValidationTest < ActiveModel::TestCase assert Topic.new("title" => "something", "content" => "abc") t = Topic.new("title" => "monkey") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? end def test_validates_exclusion_of_for_ruby_class @@ -44,12 +44,12 @@ class ExclusionValidationTest < ActiveModel::TestCase p = Person.new p.karma = "abe" - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["is reserved"], p.errors[:karma] p.karma = "Lifo" - assert p.valid? + assert_predicate p, :valid? ensure Person.clear_validators! end @@ -60,26 +60,26 @@ class ExclusionValidationTest < ActiveModel::TestCase t = Topic.new t.title = "elephant" t.author_name = "sikachu" - assert t.invalid? + assert_predicate t, :invalid? t.title = "wasabi" - assert t.valid? + assert_predicate t, :valid? end def test_validates_exclusion_of_with_range Topic.validates_exclusion_of :content, in: ("a".."g") - assert Topic.new(content: "g").invalid? - assert Topic.new(content: "h").valid? + assert_predicate Topic.new(content: "g"), :invalid? + assert_predicate Topic.new(content: "h"), :valid? end def test_validates_exclusion_of_with_time_range Topic.validates_exclusion_of :created_at, in: 6.days.ago..2.days.ago - assert Topic.new(created_at: 5.days.ago).invalid? - assert Topic.new(created_at: 3.days.ago).invalid? - assert Topic.new(created_at: 7.days.ago).valid? - assert Topic.new(created_at: 1.day.ago).valid? + assert_predicate Topic.new(created_at: 5.days.ago), :invalid? + assert_predicate Topic.new(created_at: 3.days.ago), :invalid? + assert_predicate Topic.new(created_at: 7.days.ago), :valid? + assert_predicate Topic.new(created_at: 1.day.ago), :valid? end def test_validates_inclusion_of_with_symbol @@ -92,7 +92,7 @@ class ExclusionValidationTest < ActiveModel::TestCase %w(abe) end - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["is reserved"], p.errors[:karma] p = Person.new @@ -102,7 +102,7 @@ class ExclusionValidationTest < ActiveModel::TestCase %w() end - assert p.valid? + assert_predicate p, :valid? ensure Person.clear_validators! end diff --git a/activemodel/test/cases/validations/format_validation_test.rb b/activemodel/test/cases/validations/format_validation_test.rb index b0de80a6fc..e9430cc7c4 100644 --- a/activemodel/test/cases/validations/format_validation_test.rb +++ b/activemodel/test/cases/validations/format_validation_test.rb @@ -16,22 +16,22 @@ class FormatValidationTest < ActiveModel::TestCase t = Topic.new("title" => "i'm incorrect", "content" => "Validation macros rule!") assert t.invalid?, "Shouldn't be valid" assert_equal ["is bad data"], t.errors[:title] - assert t.errors[:content].empty? + assert_predicate t.errors[:content], :empty? t.title = "Validation macros rule!" - assert t.valid? - assert t.errors[:title].empty? + assert_predicate t, :valid? + assert_predicate t.errors[:title], :empty? assert_raise(ArgumentError) { Topic.validates_format_of(:title, :content) } end def test_validate_format_with_allow_blank Topic.validates_format_of(:title, with: /\AValidation\smacros \w+!\z/, allow_blank: true) - assert Topic.new("title" => "Shouldn't be valid").invalid? - assert Topic.new("title" => "").valid? - assert Topic.new("title" => nil).valid? - assert Topic.new("title" => "Validation macros rule!").valid? + assert_predicate Topic.new("title" => "Shouldn't be valid"), :invalid? + assert_predicate Topic.new("title" => ""), :valid? + assert_predicate Topic.new("title" => nil), :valid? + assert_predicate Topic.new("title" => "Validation macros rule!"), :valid? end # testing ticket #3142 @@ -42,7 +42,7 @@ class FormatValidationTest < ActiveModel::TestCase assert t.invalid?, "Shouldn't be valid" assert_equal ["is bad data"], t.errors[:title] - assert t.errors[:content].empty? + assert_predicate t.errors[:content], :empty? t.title = "-11" assert t.invalid?, "Shouldn't be valid" @@ -58,14 +58,14 @@ class FormatValidationTest < ActiveModel::TestCase t.title = "1" - assert t.valid? - assert t.errors[:title].empty? + assert_predicate t, :valid? + assert_predicate t.errors[:title], :empty? end def test_validate_format_with_formatted_message Topic.validates_format_of(:title, with: /\AValid Title\z/, message: "can't be %{value}") t = Topic.new(title: "Invalid title") - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["can't be Invalid title"], t.errors[:title] end @@ -114,10 +114,10 @@ class FormatValidationTest < ActiveModel::TestCase t = Topic.new t.title = "digit" t.content = "Pixies" - assert t.invalid? + assert_predicate t, :invalid? t.content = "1234" - assert t.valid? + assert_predicate t, :valid? end def test_validates_format_of_without_lambda @@ -126,10 +126,10 @@ class FormatValidationTest < ActiveModel::TestCase t = Topic.new t.title = "characters" t.content = "1234" - assert t.invalid? + assert_predicate t, :invalid? t.content = "Pixies" - assert t.valid? + assert_predicate t, :valid? end def test_validates_format_of_for_ruby_class @@ -137,12 +137,12 @@ class FormatValidationTest < ActiveModel::TestCase p = Person.new p.karma = "Pixies" - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["is invalid"], p.errors[:karma] p.karma = "1234" - assert p.valid? + assert_predicate p, :valid? ensure Person.clear_validators! end diff --git a/activemodel/test/cases/validations/inclusion_validation_test.rb b/activemodel/test/cases/validations/inclusion_validation_test.rb index 94df0649a9..daad76759f 100644 --- a/activemodel/test/cases/validations/inclusion_validation_test.rb +++ b/activemodel/test/cases/validations/inclusion_validation_test.rb @@ -13,61 +13,61 @@ class InclusionValidationTest < ActiveModel::TestCase def test_validates_inclusion_of_range Topic.validates_inclusion_of(:title, in: "aaa".."bbb") - assert Topic.new("title" => "bbc", "content" => "abc").invalid? - assert Topic.new("title" => "aa", "content" => "abc").invalid? - assert Topic.new("title" => "aaab", "content" => "abc").invalid? - assert Topic.new("title" => "aaa", "content" => "abc").valid? - assert Topic.new("title" => "abc", "content" => "abc").valid? - assert Topic.new("title" => "bbb", "content" => "abc").valid? + assert_predicate Topic.new("title" => "bbc", "content" => "abc"), :invalid? + assert_predicate Topic.new("title" => "aa", "content" => "abc"), :invalid? + assert_predicate Topic.new("title" => "aaab", "content" => "abc"), :invalid? + assert_predicate Topic.new("title" => "aaa", "content" => "abc"), :valid? + assert_predicate Topic.new("title" => "abc", "content" => "abc"), :valid? + assert_predicate Topic.new("title" => "bbb", "content" => "abc"), :valid? end def test_validates_inclusion_of_time_range range_begin = 1.year.ago range_end = Time.now Topic.validates_inclusion_of(:created_at, in: range_begin..range_end) - assert Topic.new(title: "aaa", created_at: 2.years.ago).invalid? - assert Topic.new(title: "aaa", created_at: 3.months.ago).valid? - assert Topic.new(title: "aaa", created_at: 37.weeks.from_now).invalid? - assert Topic.new(title: "aaa", created_at: range_begin).valid? - assert Topic.new(title: "aaa", created_at: range_end).valid? + assert_predicate Topic.new(title: "aaa", created_at: 2.years.ago), :invalid? + assert_predicate Topic.new(title: "aaa", created_at: 3.months.ago), :valid? + assert_predicate Topic.new(title: "aaa", created_at: 37.weeks.from_now), :invalid? + assert_predicate Topic.new(title: "aaa", created_at: range_begin), :valid? + assert_predicate Topic.new(title: "aaa", created_at: range_end), :valid? end def test_validates_inclusion_of_date_range range_begin = 1.year.until(Date.today) range_end = Date.today Topic.validates_inclusion_of(:created_at, in: range_begin..range_end) - assert Topic.new(title: "aaa", created_at: 2.years.until(Date.today)).invalid? - assert Topic.new(title: "aaa", created_at: 3.months.until(Date.today)).valid? - assert Topic.new(title: "aaa", created_at: 37.weeks.since(Date.today)).invalid? - assert Topic.new(title: "aaa", created_at: 1.year.until(Date.today)).valid? - assert Topic.new(title: "aaa", created_at: Date.today).valid? - assert Topic.new(title: "aaa", created_at: range_begin).valid? - assert Topic.new(title: "aaa", created_at: range_end).valid? + assert_predicate Topic.new(title: "aaa", created_at: 2.years.until(Date.today)), :invalid? + assert_predicate Topic.new(title: "aaa", created_at: 3.months.until(Date.today)), :valid? + assert_predicate Topic.new(title: "aaa", created_at: 37.weeks.since(Date.today)), :invalid? + assert_predicate Topic.new(title: "aaa", created_at: 1.year.until(Date.today)), :valid? + assert_predicate Topic.new(title: "aaa", created_at: Date.today), :valid? + assert_predicate Topic.new(title: "aaa", created_at: range_begin), :valid? + assert_predicate Topic.new(title: "aaa", created_at: range_end), :valid? end def test_validates_inclusion_of_date_time_range range_begin = 1.year.until(DateTime.current) range_end = DateTime.current Topic.validates_inclusion_of(:created_at, in: range_begin..range_end) - assert Topic.new(title: "aaa", created_at: 2.years.until(DateTime.current)).invalid? - assert Topic.new(title: "aaa", created_at: 3.months.until(DateTime.current)).valid? - assert Topic.new(title: "aaa", created_at: 37.weeks.since(DateTime.current)).invalid? - assert Topic.new(title: "aaa", created_at: range_begin).valid? - assert Topic.new(title: "aaa", created_at: range_end).valid? + assert_predicate Topic.new(title: "aaa", created_at: 2.years.until(DateTime.current)), :invalid? + assert_predicate Topic.new(title: "aaa", created_at: 3.months.until(DateTime.current)), :valid? + assert_predicate Topic.new(title: "aaa", created_at: 37.weeks.since(DateTime.current)), :invalid? + assert_predicate Topic.new(title: "aaa", created_at: range_begin), :valid? + assert_predicate Topic.new(title: "aaa", created_at: range_end), :valid? end def test_validates_inclusion_of Topic.validates_inclusion_of(:title, in: %w( a b c d e f g )) - assert Topic.new("title" => "a!", "content" => "abc").invalid? - assert Topic.new("title" => "a b", "content" => "abc").invalid? - assert Topic.new("title" => nil, "content" => "def").invalid? + assert_predicate Topic.new("title" => "a!", "content" => "abc"), :invalid? + assert_predicate Topic.new("title" => "a b", "content" => "abc"), :invalid? + assert_predicate Topic.new("title" => nil, "content" => "def"), :invalid? t = Topic.new("title" => "a", "content" => "I know you are but what am I?") - assert t.valid? + assert_predicate t, :valid? t.title = "uhoh" - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["is not included in the list"], t.errors[:title] assert_raise(ArgumentError) { Topic.validates_inclusion_of(:title, in: nil) } @@ -81,30 +81,30 @@ class InclusionValidationTest < ActiveModel::TestCase def test_validates_inclusion_of_with_allow_nil Topic.validates_inclusion_of(:title, in: %w( a b c d e f g ), allow_nil: true) - assert Topic.new("title" => "a!", "content" => "abc").invalid? - assert Topic.new("title" => "", "content" => "abc").invalid? - assert Topic.new("title" => nil, "content" => "abc").valid? + assert_predicate Topic.new("title" => "a!", "content" => "abc"), :invalid? + assert_predicate Topic.new("title" => "", "content" => "abc"), :invalid? + assert_predicate Topic.new("title" => nil, "content" => "abc"), :valid? end def test_validates_inclusion_of_with_formatted_message Topic.validates_inclusion_of(:title, in: %w( a b c d e f g ), message: "option %{value} is not in the list") - assert Topic.new("title" => "a", "content" => "abc").valid? + assert_predicate Topic.new("title" => "a", "content" => "abc"), :valid? t = Topic.new("title" => "uhoh", "content" => "abc") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["option uhoh is not in the list"], t.errors[:title] end def test_validates_inclusion_of_with_within_option Topic.validates_inclusion_of(:title, within: %w( a b c d e f g )) - assert Topic.new("title" => "a", "content" => "abc").valid? + assert_predicate Topic.new("title" => "a", "content" => "abc"), :valid? t = Topic.new("title" => "uhoh", "content" => "abc") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? end def test_validates_inclusion_of_for_ruby_class @@ -112,12 +112,12 @@ class InclusionValidationTest < ActiveModel::TestCase p = Person.new p.karma = "Lifo" - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["is not included in the list"], p.errors[:karma] p.karma = "monkey" - assert p.valid? + assert_predicate p, :valid? ensure Person.clear_validators! end @@ -128,10 +128,10 @@ class InclusionValidationTest < ActiveModel::TestCase t = Topic.new t.title = "wasabi" t.author_name = "sikachu" - assert t.invalid? + assert_predicate t, :invalid? t.title = "elephant" - assert t.valid? + assert_predicate t, :valid? end def test_validates_inclusion_of_with_symbol @@ -144,7 +144,7 @@ class InclusionValidationTest < ActiveModel::TestCase %w() end - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["is not included in the list"], p.errors[:karma] p = Person.new @@ -154,7 +154,7 @@ class InclusionValidationTest < ActiveModel::TestCase %w(Lifo) end - assert p.valid? + assert_predicate p, :valid? ensure Person.clear_validators! end diff --git a/activemodel/test/cases/validations/length_validation_test.rb b/activemodel/test/cases/validations/length_validation_test.rb index 42f76f3e3c..774a2cde74 100644 --- a/activemodel/test/cases/validations/length_validation_test.rb +++ b/activemodel/test/cases/validations/length_validation_test.rb @@ -13,153 +13,153 @@ class LengthValidationTest < ActiveModel::TestCase def test_validates_length_of_with_allow_nil Topic.validates_length_of(:title, is: 5, allow_nil: true) - assert Topic.new("title" => "ab").invalid? - assert Topic.new("title" => "").invalid? - assert Topic.new("title" => nil).valid? - assert Topic.new("title" => "abcde").valid? + assert_predicate Topic.new("title" => "ab"), :invalid? + assert_predicate Topic.new("title" => ""), :invalid? + assert_predicate Topic.new("title" => nil), :valid? + assert_predicate Topic.new("title" => "abcde"), :valid? end def test_validates_length_of_with_allow_blank Topic.validates_length_of(:title, is: 5, allow_blank: true) - assert Topic.new("title" => "ab").invalid? - assert Topic.new("title" => "").valid? - assert Topic.new("title" => nil).valid? - assert Topic.new("title" => "abcde").valid? + assert_predicate Topic.new("title" => "ab"), :invalid? + assert_predicate Topic.new("title" => ""), :valid? + assert_predicate Topic.new("title" => nil), :valid? + assert_predicate Topic.new("title" => "abcde"), :valid? end def test_validates_length_of_using_minimum Topic.validates_length_of :title, minimum: 5 t = Topic.new("title" => "valid", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? t.title = "not" - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["is too short (minimum is 5 characters)"], t.errors[:title] t.title = "" - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["is too short (minimum is 5 characters)"], t.errors[:title] t.title = nil - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["is too short (minimum is 5 characters)"], t.errors["title"] end def test_validates_length_of_using_maximum_should_allow_nil Topic.validates_length_of :title, maximum: 10 t = Topic.new - assert t.valid? + assert_predicate t, :valid? end def test_optionally_validates_length_of_using_minimum Topic.validates_length_of :title, minimum: 5, allow_nil: true t = Topic.new("title" => "valid", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? t.title = nil - assert t.valid? + assert_predicate t, :valid? end def test_validates_length_of_using_maximum Topic.validates_length_of :title, maximum: 5 t = Topic.new("title" => "valid", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? t.title = "notvalid" - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["is too long (maximum is 5 characters)"], t.errors[:title] t.title = "" - assert t.valid? + assert_predicate t, :valid? end def test_optionally_validates_length_of_using_maximum Topic.validates_length_of :title, maximum: 5, allow_nil: true t = Topic.new("title" => "valid", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? t.title = nil - assert t.valid? + assert_predicate t, :valid? end def test_validates_length_of_using_within Topic.validates_length_of(:title, :content, within: 3..5) t = Topic.new("title" => "a!", "content" => "I'm ooooooooh so very long") - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["is too short (minimum is 3 characters)"], t.errors[:title] assert_equal ["is too long (maximum is 5 characters)"], t.errors[:content] t.title = nil t.content = nil - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["is too short (minimum is 3 characters)"], t.errors[:title] assert_equal ["is too short (minimum is 3 characters)"], t.errors[:content] t.title = "abe" t.content = "mad" - assert t.valid? + assert_predicate t, :valid? end def test_validates_length_of_using_within_with_exclusive_range Topic.validates_length_of(:title, within: 4...10) t = Topic.new("title" => "9 chars!!") - assert t.valid? + assert_predicate t, :valid? t.title = "Now I'm 10" - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["is too long (maximum is 9 characters)"], t.errors[:title] t.title = "Four" - assert t.valid? + assert_predicate t, :valid? end def test_optionally_validates_length_of_using_within Topic.validates_length_of :title, :content, within: 3..5, allow_nil: true t = Topic.new("title" => "abc", "content" => "abcd") - assert t.valid? + assert_predicate t, :valid? t.title = nil - assert t.valid? + assert_predicate t, :valid? end def test_validates_length_of_using_is Topic.validates_length_of :title, is: 5 t = Topic.new("title" => "valid", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? t.title = "notvalid" - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["is the wrong length (should be 5 characters)"], t.errors[:title] t.title = "" - assert t.invalid? + assert_predicate t, :invalid? t.title = nil - assert t.invalid? + assert_predicate t, :invalid? end def test_optionally_validates_length_of_using_is Topic.validates_length_of :title, is: 5, allow_nil: true t = Topic.new("title" => "valid", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? t.title = nil - assert t.valid? + assert_predicate t, :valid? end def test_validates_length_of_using_bignum @@ -187,45 +187,45 @@ class LengthValidationTest < ActiveModel::TestCase def test_validates_length_of_custom_errors_for_minimum_with_message Topic.validates_length_of(:title, minimum: 5, message: "boo %{count}") t = Topic.new("title" => "uhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["boo 5"], t.errors[:title] end def test_validates_length_of_custom_errors_for_minimum_with_too_short Topic.validates_length_of(:title, minimum: 5, too_short: "hoo %{count}") t = Topic.new("title" => "uhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["hoo 5"], t.errors[:title] end def test_validates_length_of_custom_errors_for_maximum_with_message Topic.validates_length_of(:title, maximum: 5, message: "boo %{count}") t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["boo 5"], t.errors[:title] end def test_validates_length_of_custom_errors_for_in Topic.validates_length_of(:title, in: 10..20, message: "hoo %{count}") t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["hoo 10"], t.errors["title"] t = Topic.new("title" => "uhohuhohuhohuhohuhohuhohuhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["hoo 20"], t.errors["title"] end def test_validates_length_of_custom_errors_for_maximum_with_too_long Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}") t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["hoo 5"], t.errors["title"] end @@ -233,29 +233,29 @@ class LengthValidationTest < ActiveModel::TestCase Topic.validates_length_of :title, minimum: 3, maximum: 5, too_short: "too short", too_long: "too long" t = Topic.new(title: "a") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["too short"], t.errors["title"] t = Topic.new(title: "aaaaaa") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["too long"], t.errors["title"] end def test_validates_length_of_custom_errors_for_is_with_message Topic.validates_length_of(:title, is: 5, message: "boo %{count}") t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["boo 5"], t.errors["title"] end def test_validates_length_of_custom_errors_for_is_with_wrong_length Topic.validates_length_of(:title, is: 5, wrong_length: "hoo %{count}") t = Topic.new("title" => "uhohuhoh", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["hoo 5"], t.errors["title"] end @@ -263,11 +263,11 @@ class LengthValidationTest < ActiveModel::TestCase Topic.validates_length_of :title, minimum: 5 t = Topic.new("title" => "一二三四五", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? t.title = "一二三四" - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["is too short (minimum is 5 characters)"], t.errors["title"] end @@ -275,11 +275,11 @@ class LengthValidationTest < ActiveModel::TestCase Topic.validates_length_of :title, maximum: 5 t = Topic.new("title" => "一二三四五", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? t.title = "一二34五六" - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["is too long (maximum is 5 characters)"], t.errors["title"] end @@ -287,12 +287,12 @@ class LengthValidationTest < ActiveModel::TestCase Topic.validates_length_of(:title, :content, within: 3..5) t = Topic.new("title" => "一二", "content" => "12三四五六七") - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["is too short (minimum is 3 characters)"], t.errors[:title] assert_equal ["is too long (maximum is 5 characters)"], t.errors[:content] t.title = "一二三" t.content = "12三" - assert t.valid? + assert_predicate t, :valid? end def test_optionally_validates_length_of_using_within_utf8 @@ -312,11 +312,11 @@ class LengthValidationTest < ActiveModel::TestCase Topic.validates_length_of :title, is: 5 t = Topic.new("title" => "一二345", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? t.title = "一二345六" - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["is the wrong length (should be 5 characters)"], t.errors["title"] end @@ -324,11 +324,11 @@ class LengthValidationTest < ActiveModel::TestCase Topic.validates_length_of(:approved, is: 4) t = Topic.new("title" => "uhohuhoh", "content" => "whatever", approved: 1) - assert t.invalid? - assert t.errors[:approved].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:approved], :any? t = Topic.new("title" => "uhohuhoh", "content" => "whatever", approved: 1234) - assert t.valid? + assert_predicate t, :valid? end def test_validates_length_of_for_ruby_class @@ -336,12 +336,12 @@ class LengthValidationTest < ActiveModel::TestCase p = Person.new p.karma = "Pix" - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["is too short (minimum is 5 characters)"], p.errors[:karma] p.karma = "The Smiths" - assert p.valid? + assert_predicate p, :valid? ensure Person.clear_validators! end @@ -350,80 +350,80 @@ class LengthValidationTest < ActiveModel::TestCase Topic.validates_length_of(:title, within: 5..Float::INFINITY) t = Topic.new("title" => "1234") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? t.title = "12345" - assert t.valid? + assert_predicate t, :valid? Topic.validates_length_of(:author_name, maximum: Float::INFINITY) - assert t.valid? + assert_predicate t, :valid? t.author_name = "A very long author name that should still be valid." * 100 - assert t.valid? + assert_predicate t, :valid? end def test_validates_length_of_using_maximum_should_not_allow_nil_when_nil_not_allowed Topic.validates_length_of :title, maximum: 10, allow_nil: false t = Topic.new - assert t.invalid? + assert_predicate t, :invalid? end def test_validates_length_of_using_maximum_should_not_allow_nil_and_empty_string_when_blank_not_allowed Topic.validates_length_of :title, maximum: 10, allow_blank: false t = Topic.new - assert t.invalid? + assert_predicate t, :invalid? t.title = "" - assert t.invalid? + assert_predicate t, :invalid? end def test_validates_length_of_using_both_minimum_and_maximum_should_not_allow_nil Topic.validates_length_of :title, minimum: 5, maximum: 10 t = Topic.new - assert t.invalid? + assert_predicate t, :invalid? end def test_validates_length_of_using_minimum_0_should_not_allow_nil Topic.validates_length_of :title, minimum: 0 t = Topic.new - assert t.invalid? + assert_predicate t, :invalid? t.title = "" - assert t.valid? + assert_predicate t, :valid? end def test_validates_length_of_using_is_0_should_not_allow_nil Topic.validates_length_of :title, is: 0 t = Topic.new - assert t.invalid? + assert_predicate t, :invalid? t.title = "" - assert t.valid? + assert_predicate t, :valid? end def test_validates_with_diff_in_option Topic.validates_length_of(:title, is: 5) Topic.validates_length_of(:title, is: 5, if: Proc.new { false }) - assert Topic.new("title" => "david").valid? - assert Topic.new("title" => "david2").invalid? + assert_predicate Topic.new("title" => "david"), :valid? + assert_predicate Topic.new("title" => "david2"), :invalid? end def test_validates_length_of_using_proc_as_maximum Topic.validates_length_of :title, maximum: ->(model) { 5 } t = Topic.new("title" => "valid", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? t.title = "notvalid" - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["is too long (maximum is 5 characters)"], t.errors[:title] t.title = "" - assert t.valid? + assert_predicate t, :valid? end def test_validates_length_of_using_proc_as_maximum_with_model_method @@ -431,14 +431,14 @@ class LengthValidationTest < ActiveModel::TestCase Topic.validates_length_of :title, maximum: Proc.new(&:max_title_length) t = Topic.new("title" => "valid", "content" => "whatever") - assert t.valid? + assert_predicate t, :valid? t.title = "notvalid" - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["is too long (maximum is 5 characters)"], t.errors[:title] t.title = "" - assert t.valid? + assert_predicate t, :valid? end end diff --git a/activemodel/test/cases/validations/numericality_validation_test.rb b/activemodel/test/cases/validations/numericality_validation_test.rb index 5413255e6b..01b78ae72e 100644 --- a/activemodel/test/cases/validations/numericality_validation_test.rb +++ b/activemodel/test/cases/validations/numericality_validation_test.rb @@ -237,13 +237,13 @@ class NumericalityValidationTest < ActiveModel::TestCase Topic.validates_numericality_of :approved, less_than: 4, message: "smaller than %{count}" topic = Topic.new("title" => "numeric test", "approved" => 10) - assert !topic.valid? + assert_not_predicate topic, :valid? assert_equal ["smaller than 4"], topic.errors[:approved] Topic.validates_numericality_of :approved, greater_than: 4, message: "greater than %{count}" topic = Topic.new("title" => "numeric test", "approved" => 1) - assert !topic.valid? + assert_not_predicate topic, :valid? assert_equal ["greater than 4"], topic.errors[:approved] end @@ -252,12 +252,12 @@ class NumericalityValidationTest < ActiveModel::TestCase p = Person.new p.karma = "Pix" - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["is not a number"], p.errors[:karma] p.karma = "1234" - assert p.valid? + assert_predicate p, :valid? ensure Person.clear_validators! end @@ -268,7 +268,7 @@ class NumericalityValidationTest < ActiveModel::TestCase topic = Topic.new topic.approved = (base + 1).to_s - assert topic.invalid? + assert_predicate topic, :invalid? end def test_validates_numericality_with_invalid_args diff --git a/activemodel/test/cases/validations/presence_validation_test.rb b/activemodel/test/cases/validations/presence_validation_test.rb index 22c2f0af87..c3eca41070 100644 --- a/activemodel/test/cases/validations/presence_validation_test.rb +++ b/activemodel/test/cases/validations/presence_validation_test.rb @@ -17,25 +17,25 @@ class PresenceValidationTest < ActiveModel::TestCase Topic.validates_presence_of(:title, :content) t = Topic.new - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["can't be blank"], t.errors[:title] assert_equal ["can't be blank"], t.errors[:content] t.title = "something" t.content = " " - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["can't be blank"], t.errors[:content] t.content = "like stuff" - assert t.valid? + assert_predicate t, :valid? end def test_accepts_array_arguments Topic.validates_presence_of %w(title content) t = Topic.new - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["can't be blank"], t.errors[:title] assert_equal ["can't be blank"], t.errors[:content] end @@ -43,7 +43,7 @@ class PresenceValidationTest < ActiveModel::TestCase def test_validates_acceptance_of_with_custom_error_using_quotes Person.validates_presence_of :karma, message: "This string contains 'single' and \"double\" quotes" p = Person.new - assert p.invalid? + assert_predicate p, :invalid? assert_equal "This string contains 'single' and \"double\" quotes", p.errors[:karma].last end @@ -51,24 +51,24 @@ class PresenceValidationTest < ActiveModel::TestCase Person.validates_presence_of :karma p = Person.new - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["can't be blank"], p.errors[:karma] p.karma = "Cold" - assert p.valid? + assert_predicate p, :valid? end def test_validates_presence_of_for_ruby_class_with_custom_reader CustomReader.validates_presence_of :karma p = CustomReader.new - assert p.invalid? + assert_predicate p, :invalid? assert_equal ["can't be blank"], p.errors[:karma] p[:karma] = "Cold" - assert p.valid? + assert_predicate p, :valid? end def test_validates_presence_of_with_allow_nil_option @@ -78,7 +78,7 @@ class PresenceValidationTest < ActiveModel::TestCase assert t.valid?, t.errors.full_messages t.title = "" - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["can't be blank"], t.errors[:title] t.title = " " diff --git a/activemodel/test/cases/validations/validates_test.rb b/activemodel/test/cases/validations/validates_test.rb index 7f32f5dc74..80c347703a 100644 --- a/activemodel/test/cases/validations/validates_test.rb +++ b/activemodel/test/cases/validations/validates_test.rb @@ -37,7 +37,7 @@ class ValidatesTest < ActiveModel::TestCase person = Person.new person.title = 123 - assert person.valid? + assert_predicate person, :valid? end def test_validates_with_built_in_validation_and_options @@ -71,7 +71,7 @@ class ValidatesTest < ActiveModel::TestCase def test_validates_with_if_as_shared_conditions Person.validates :karma, presence: true, email: true, if: :condition_is_false person = Person.new - assert person.valid? + assert_predicate person, :valid? end def test_validates_with_unless_as_local_conditions @@ -84,40 +84,40 @@ class ValidatesTest < ActiveModel::TestCase def test_validates_with_unless_shared_conditions Person.validates :karma, presence: true, email: true, unless: :condition_is_true person = Person.new - assert person.valid? + assert_predicate person, :valid? end def test_validates_with_allow_nil_shared_conditions Person.validates :karma, length: { minimum: 20 }, email: true, allow_nil: true person = Person.new - assert person.valid? + assert_predicate person, :valid? end def test_validates_with_regexp Person.validates :karma, format: /positive|negative/ person = Person.new - assert person.invalid? + assert_predicate person, :invalid? assert_equal ["is invalid"], person.errors[:karma] person.karma = "positive" - assert person.valid? + assert_predicate person, :valid? end def test_validates_with_array Person.validates :gender, inclusion: %w(m f) person = Person.new - assert person.invalid? + assert_predicate person, :invalid? assert_equal ["is not included in the list"], person.errors[:gender] person.gender = "m" - assert person.valid? + assert_predicate person, :valid? end def test_validates_with_range Person.validates :karma, length: 6..20 person = Person.new - assert person.invalid? + assert_predicate person, :invalid? assert_equal ["is too short (minimum is 6 characters)"], person.errors[:karma] person.karma = "something" - assert person.valid? + assert_predicate person, :valid? end def test_validates_with_validator_class_and_options @@ -159,7 +159,7 @@ class ValidatesTest < ActiveModel::TestCase topic = Topic.new topic.title = "What's happening" topic.title_confirmation = "Not this" - assert !topic.valid? + assert_not_predicate topic, :valid? assert_equal ["Y U NO CONFIRM"], topic.errors[:title_confirmation] end end diff --git a/activemodel/test/cases/validations/with_validation_test.rb b/activemodel/test/cases/validations/with_validation_test.rb index 13ef5e6a31..b0ebb267f0 100644 --- a/activemodel/test/cases/validations/with_validation_test.rb +++ b/activemodel/test/cases/validations/with_validation_test.rb @@ -65,7 +65,7 @@ class ValidatesWithTest < ActiveModel::TestCase test "with multiple classes" do Topic.validates_with(ValidatorThatAddsErrors, OtherValidatorThatAddsErrors) topic = Topic.new - assert topic.invalid? + assert_predicate topic, :invalid? assert_includes topic.errors[:base], ERROR_MESSAGE assert_includes topic.errors[:base], OTHER_ERROR_MESSAGE end @@ -79,21 +79,21 @@ class ValidatesWithTest < ActiveModel::TestCase validator.expect(:is_a?, false, [String]) Topic.validates_with(validator, if: :condition_is_true, foo: :bar) - assert topic.valid? + assert_predicate topic, :valid? validator.verify end test "validates_with with options" do Topic.validates_with(ValidatorThatValidatesOptions, field: :first_name) topic = Topic.new - assert topic.invalid? + assert_predicate topic, :invalid? assert_includes topic.errors[:base], ERROR_MESSAGE end test "validates_with each validator" do Topic.validates_with(ValidatorPerEachAttribute, attributes: [:title, :content]) topic = Topic.new title: "Title", content: "Content" - assert topic.invalid? + assert_predicate topic, :invalid? assert_equal ["Value is Title"], topic.errors[:title] assert_equal ["Value is Content"], topic.errors[:content] end @@ -113,28 +113,28 @@ class ValidatesWithTest < ActiveModel::TestCase test "each validator skip nil values if :allow_nil is set to true" do Topic.validates_with(ValidatorPerEachAttribute, attributes: [:title, :content], allow_nil: true) topic = Topic.new content: "" - assert topic.invalid? - assert topic.errors[:title].empty? + assert_predicate topic, :invalid? + assert_predicate topic.errors[:title], :empty? assert_equal ["Value is "], topic.errors[:content] end test "each validator skip blank values if :allow_blank is set to true" do Topic.validates_with(ValidatorPerEachAttribute, attributes: [:title, :content], allow_blank: true) topic = Topic.new content: "" - assert topic.valid? - assert topic.errors[:title].empty? - assert topic.errors[:content].empty? + assert_predicate topic, :valid? + assert_predicate topic.errors[:title], :empty? + assert_predicate topic.errors[:content], :empty? end test "validates_with can validate with an instance method" do Topic.validates :title, with: :my_validation topic = Topic.new title: "foo" - assert topic.valid? - assert topic.errors[:title].empty? + assert_predicate topic, :valid? + assert_predicate topic.errors[:title], :empty? topic = Topic.new - assert !topic.valid? + assert_not_predicate topic, :valid? assert_equal ["is missing"], topic.errors[:title] end @@ -142,8 +142,8 @@ class ValidatesWithTest < ActiveModel::TestCase Topic.validates :title, :content, with: :my_validation_with_arg topic = Topic.new title: "foo" - assert !topic.valid? - assert topic.errors[:title].empty? + assert_not_predicate topic, :valid? + assert_predicate topic.errors[:title], :empty? assert_equal ["is missing"], topic.errors[:content] end end diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb index ab8c41bbd0..1cf1122618 100644 --- a/activemodel/test/cases/validations_test.rb +++ b/activemodel/test/cases/validations_test.rb @@ -30,7 +30,7 @@ class ValidationsTest < ActiveModel::TestCase def test_single_attr_validation_and_error_msg r = Reply.new r.title = "There's no content!" - assert r.invalid? + assert_predicate r, :invalid? assert r.errors[:content].any?, "A reply without content should mark that attribute as invalid" assert_equal ["is Empty"], r.errors["content"], "A reply without content should contain an error" assert_equal 1, r.errors.count @@ -38,7 +38,7 @@ class ValidationsTest < ActiveModel::TestCase def test_double_attr_validation_and_error_msg r = Reply.new - assert r.invalid? + assert_predicate r, :invalid? assert r.errors[:title].any?, "A reply without title should mark that attribute as invalid" assert_equal ["is Empty"], r.errors["title"], "A reply without title should contain an error" @@ -111,8 +111,8 @@ class ValidationsTest < ActiveModel::TestCase def test_errors_empty_after_errors_on_check t = Topic.new - assert t.errors[:id].empty? - assert t.errors.empty? + assert_predicate t.errors[:id], :empty? + assert_predicate t.errors, :empty? end def test_validates_each @@ -122,7 +122,7 @@ class ValidationsTest < ActiveModel::TestCase hits += 1 end t = Topic.new("title" => "valid", "content" => "whatever") - assert t.invalid? + assert_predicate t, :invalid? assert_equal 4, hits assert_equal %w(gotcha gotcha), t.errors[:title] assert_equal %w(gotcha gotcha), t.errors[:content] @@ -135,7 +135,7 @@ class ValidationsTest < ActiveModel::TestCase hits += 1 end t = CustomReader.new("title" => "valid", "content" => "whatever") - assert t.invalid? + assert_predicate t, :invalid? assert_equal 4, hits assert_equal %w(gotcha gotcha), t.errors[:title] assert_equal %w(gotcha gotcha), t.errors[:content] @@ -146,16 +146,16 @@ class ValidationsTest < ActiveModel::TestCase def test_validate_block Topic.validate { errors.add("title", "will never be valid") } t = Topic.new("title" => "Title", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["will never be valid"], t.errors["title"] end def test_validate_block_with_params Topic.validate { |topic| topic.errors.add("title", "will never be valid") } t = Topic.new("title" => "Title", "content" => "whatever") - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? assert_equal ["will never be valid"], t.errors["title"] end @@ -214,7 +214,7 @@ class ValidationsTest < ActiveModel::TestCase def test_errors_conversions Topic.validates_presence_of %w(title content) t = Topic.new - assert t.invalid? + assert_predicate t, :invalid? xml = t.errors.to_xml assert_match %r{}, xml @@ -232,14 +232,14 @@ class ValidationsTest < ActiveModel::TestCase Topic.validates_length_of :title, minimum: 2 t = Topic.new("title" => "") - assert t.invalid? + assert_predicate t, :invalid? assert_equal "can't be blank", t.errors["title"].first Topic.validates_presence_of :title, :author_name Topic.validate { errors.add("author_email_address", "will never be valid") } Topic.validates_length_of :title, :content, minimum: 2 t = Topic.new title: "" - assert t.invalid? + assert_predicate t, :invalid? assert_equal :title, key = t.errors.keys[0] assert_equal "can't be blank", t.errors[key][0] @@ -258,8 +258,8 @@ class ValidationsTest < ActiveModel::TestCase t = Topic.new(title: "") # If block should not fire - assert t.valid? - assert t.author_name.nil? + assert_predicate t, :valid? + assert_predicate t.author_name, :nil? # If block should fire assert t.invalid?(:update) @@ -270,18 +270,18 @@ class ValidationsTest < ActiveModel::TestCase Topic.validates_presence_of :title t = Topic.new - assert t.invalid? - assert t.errors[:title].any? + assert_predicate t, :invalid? + assert_predicate t.errors[:title], :any? t.title = "Things are going to change" - assert !t.invalid? + assert_not_predicate t, :invalid? end def test_validation_with_message_as_proc Topic.validates_presence_of(:title, message: proc { "no blanks here".upcase }) t = Topic.new - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["NO BLANKS HERE"], t.errors[:title] end @@ -331,13 +331,13 @@ class ValidationsTest < ActiveModel::TestCase Topic.validates :content, length: { minimum: 10 } topic = Topic.new - assert topic.invalid? + assert_predicate topic, :invalid? assert_equal 3, topic.errors.size topic.title = "Some Title" topic.author_name = "Some Author" topic.content = "Some Content Whose Length is more than 10." - assert topic.valid? + assert_predicate topic, :valid? end def test_validate @@ -381,7 +381,7 @@ class ValidationsTest < ActiveModel::TestCase def test_strict_validation_not_fails Topic.validates :title, strict: true, presence: true - assert Topic.new(title: "hello").valid? + assert_predicate Topic.new(title: "hello"), :valid? end def test_strict_validation_particular_validator @@ -414,7 +414,7 @@ class ValidationsTest < ActiveModel::TestCase def test_validates_with_false_hash_value Topic.validates :title, presence: false - assert Topic.new.valid? + assert_predicate Topic.new, :valid? end def test_strict_validation_error_message @@ -439,19 +439,19 @@ class ValidationsTest < ActiveModel::TestCase duped = topic.dup duped.title = nil - assert duped.invalid? + assert_predicate duped, :invalid? topic.title = nil duped.title = "Mathematics" - assert topic.invalid? - assert duped.valid? + assert_predicate topic, :invalid? + assert_predicate duped, :valid? end def test_validation_with_message_as_proc_that_takes_a_record_as_a_parameter Topic.validates_presence_of(:title, message: proc { |record| "You have failed me for the last time, #{record.author_name}." }) t = Topic.new(author_name: "Admiral") - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["You have failed me for the last time, Admiral."], t.errors[:title] end @@ -459,7 +459,7 @@ class ValidationsTest < ActiveModel::TestCase Topic.validates_presence_of(:title, message: proc { |record, data| "#{data[:attribute]} is missing. You have failed me for the last time, #{record.author_name}." }) t = Topic.new(author_name: "Admiral") - assert t.invalid? + assert_predicate t, :invalid? assert_equal ["Title is missing. You have failed me for the last time, Admiral."], t.errors[:title] end end -- cgit v1.2.3 From 82c39e1a0b5114e2d89a80883a41090567a83196 Mon Sep 17 00:00:00 2001 From: Daniel Colson Date: Thu, 25 Jan 2018 18:16:57 -0500 Subject: Use assert_empty and assert_not_empty --- activemodel/test/cases/errors_test.rb | 6 +++--- activemodel/test/cases/validations/format_validation_test.rb | 8 ++++---- activemodel/test/cases/validations/with_validation_test.rb | 10 +++++----- activemodel/test/cases/validations_test.rb | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) (limited to 'activemodel') diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb index 7d155170d3..fe351f922d 100644 --- a/activemodel/test/cases/errors_test.rb +++ b/activemodel/test/cases/errors_test.rb @@ -83,7 +83,7 @@ class ErrorsTest < ActiveModel::TestCase assert_equal 1, person.errors.count person.errors.clear - assert_predicate person.errors, :empty? + assert_empty person.errors end test "error access is indifferent" do @@ -128,7 +128,7 @@ class ErrorsTest < ActiveModel::TestCase test "detecting whether there are errors with empty?, blank?, include?" do person = Person.new person.errors[:foo] - assert_predicate person.errors, :empty? + assert_empty person.errors assert_predicate person.errors, :blank? assert_not_includes person.errors, :foo end @@ -371,7 +371,7 @@ class ErrorsTest < ActiveModel::TestCase assert_equal 1, person.errors.details.count person.errors.clear - assert_predicate person.errors.details, :empty? + assert_empty person.errors.details end test "copy errors" do diff --git a/activemodel/test/cases/validations/format_validation_test.rb b/activemodel/test/cases/validations/format_validation_test.rb index e9430cc7c4..2a7088b3e8 100644 --- a/activemodel/test/cases/validations/format_validation_test.rb +++ b/activemodel/test/cases/validations/format_validation_test.rb @@ -16,12 +16,12 @@ class FormatValidationTest < ActiveModel::TestCase t = Topic.new("title" => "i'm incorrect", "content" => "Validation macros rule!") assert t.invalid?, "Shouldn't be valid" assert_equal ["is bad data"], t.errors[:title] - assert_predicate t.errors[:content], :empty? + assert_empty t.errors[:content] t.title = "Validation macros rule!" assert_predicate t, :valid? - assert_predicate t.errors[:title], :empty? + assert_empty t.errors[:title] assert_raise(ArgumentError) { Topic.validates_format_of(:title, :content) } end @@ -42,7 +42,7 @@ class FormatValidationTest < ActiveModel::TestCase assert t.invalid?, "Shouldn't be valid" assert_equal ["is bad data"], t.errors[:title] - assert_predicate t.errors[:content], :empty? + assert_empty t.errors[:content] t.title = "-11" assert t.invalid?, "Shouldn't be valid" @@ -59,7 +59,7 @@ class FormatValidationTest < ActiveModel::TestCase t.title = "1" assert_predicate t, :valid? - assert_predicate t.errors[:title], :empty? + assert_empty t.errors[:title] end def test_validate_format_with_formatted_message diff --git a/activemodel/test/cases/validations/with_validation_test.rb b/activemodel/test/cases/validations/with_validation_test.rb index b0ebb267f0..8239792c79 100644 --- a/activemodel/test/cases/validations/with_validation_test.rb +++ b/activemodel/test/cases/validations/with_validation_test.rb @@ -114,7 +114,7 @@ class ValidatesWithTest < ActiveModel::TestCase Topic.validates_with(ValidatorPerEachAttribute, attributes: [:title, :content], allow_nil: true) topic = Topic.new content: "" assert_predicate topic, :invalid? - assert_predicate topic.errors[:title], :empty? + assert_empty topic.errors[:title] assert_equal ["Value is "], topic.errors[:content] end @@ -122,8 +122,8 @@ class ValidatesWithTest < ActiveModel::TestCase Topic.validates_with(ValidatorPerEachAttribute, attributes: [:title, :content], allow_blank: true) topic = Topic.new content: "" assert_predicate topic, :valid? - assert_predicate topic.errors[:title], :empty? - assert_predicate topic.errors[:content], :empty? + assert_empty topic.errors[:title] + assert_empty topic.errors[:content] end test "validates_with can validate with an instance method" do @@ -131,7 +131,7 @@ class ValidatesWithTest < ActiveModel::TestCase topic = Topic.new title: "foo" assert_predicate topic, :valid? - assert_predicate topic.errors[:title], :empty? + assert_empty topic.errors[:title] topic = Topic.new assert_not_predicate topic, :valid? @@ -143,7 +143,7 @@ class ValidatesWithTest < ActiveModel::TestCase topic = Topic.new title: "foo" assert_not_predicate topic, :valid? - assert_predicate topic.errors[:title], :empty? + assert_empty topic.errors[:title] assert_equal ["is missing"], topic.errors[:content] end end diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb index 1cf1122618..7776233db5 100644 --- a/activemodel/test/cases/validations_test.rb +++ b/activemodel/test/cases/validations_test.rb @@ -111,8 +111,8 @@ class ValidationsTest < ActiveModel::TestCase def test_errors_empty_after_errors_on_check t = Topic.new - assert_predicate t.errors[:id], :empty? - assert_predicate t.errors, :empty? + assert_empty t.errors[:id] + assert_empty t.errors end def test_validates_each -- cgit v1.2.3 From 393d497a53973a45dda7a0d6384f9839ce17110a Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Tue, 30 Jan 2018 10:15:01 +0900 Subject: Don't expose `attributes_with_uninitialized_key` utility method It is not a test case. --- activemodel/test/cases/attribute_set_test.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'activemodel') diff --git a/activemodel/test/cases/attribute_set_test.rb b/activemodel/test/cases/attribute_set_test.rb index 9f7498fa65..9b323dae9d 100644 --- a/activemodel/test/cases/attribute_set_test.rb +++ b/activemodel/test/cases/attribute_set_test.rb @@ -209,11 +209,6 @@ module ActiveModel assert_equal "value from user", attributes.fetch_value(:foo) end - def attributes_with_uninitialized_key - builder = AttributeSet::Builder.new(foo: Type::Integer.new, bar: Type::Float.new) - builder.build_from_database(foo: "1.1") - end - test "freezing doesn't prevent the set from materializing" do builder = AttributeSet::Builder.new(foo: Type::String.new) attributes = builder.build_from_database(foo: "1") @@ -253,5 +248,11 @@ module ActiveModel assert_equal attributes, attributes2 assert_not_equal attributes2, attributes3 end + + private + def attributes_with_uninitialized_key + builder = AttributeSet::Builder.new(foo: Type::Integer.new, bar: Type::Float.new) + builder.build_from_database(foo: "1.1") + end end end -- cgit v1.2.3 From 1c383df324fdf0b68b3f54a649eb7d2a4f55bcb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 30 Jan 2018 18:51:17 -0500 Subject: Start Rails 6.0 development!!! :tada::tada::tada: --- activemodel/CHANGELOG.md | 66 +---------------------------- activemodel/lib/active_model/gem_version.rb | 6 +-- 2 files changed, 4 insertions(+), 68 deletions(-) (limited to 'activemodel') diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index 86353674d9..13ea7d0bf3 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -1,67 +1,3 @@ -* Models using the attributes API with a proc default can now be marshalled. - Fixes #31216. - *Sean Griffin* - -* Fix to working before/after validation callbacks on multiple contexts. - - *Yoshiyuki Hirano* - - -## Rails 5.2.0.beta2 (November 28, 2017) ## - -* No changes. - - -## Rails 5.2.0.beta1 (November 27, 2017) ## - -* Execute `ConfirmationValidator` validation when `_confirmation`'s value is `false`. - - *bogdanvlviv* - -* Allow passing a Proc or Symbol to length validator options. - - *Matt Rohrer* - -* Add method `#merge!` for `ActiveModel::Errors`. - - *Jahfer Husain* - -* Fix regression in numericality validator when comparing Decimal and Float input - values with more scale than the schema. - - *Bradley Priest* - -* Fix methods `#keys`, `#values` in `ActiveModel::Errors`. - - Change `#keys` to only return the keys that don't have empty messages. - - Change `#values` to only return the not empty values. - - Example: - - # Before - person = Person.new - person.errors.keys # => [] - person.errors.values # => [] - person.errors.messages # => {} - person.errors[:name] # => [] - person.errors.messages # => {:name => []} - person.errors.keys # => [:name] - person.errors.values # => [[]] - - # After - person = Person.new - person.errors.keys # => [] - person.errors.values # => [] - person.errors.messages # => {} - person.errors[:name] # => [] - person.errors.messages # => {:name => []} - person.errors.keys # => [] - person.errors.values # => [] - - *bogdanvlviv* - - -Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/activemodel/CHANGELOG.md) for previous changes. +Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/activemodel/CHANGELOG.md) for previous changes. diff --git a/activemodel/lib/active_model/gem_version.rb b/activemodel/lib/active_model/gem_version.rb index 3c344fe854..cef5441e4a 100644 --- a/activemodel/lib/active_model/gem_version.rb +++ b/activemodel/lib/active_model/gem_version.rb @@ -7,10 +7,10 @@ module ActiveModel end module VERSION - MAJOR = 5 - MINOR = 2 + MAJOR = 6 + MINOR = 0 TINY = 0 - PRE = "beta2" + PRE = "alpha" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end -- cgit v1.2.3 From 8f2bb58ba2a74975b737f7f7655247b447b7ac08 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Fri, 2 Feb 2018 07:52:33 +0900 Subject: PERF: Recover marshaling dump/load performance (#31827) * PERF: Recover marshaling dump/load performance This performance regression which is described in #30680 was caused by f0ddf87 due to force materialized `LazyAttributeHash`. Since 95b86e5, default proc has been removed in the class, so it is no longer needed that force materialized. Avoiding force materialized will recover marshaling dump/load performance. Benchmark: https://gist.github.com/blimmer/1360ea51cd3147bae8aeb7c6d09bff17 Before: ``` it took 0.6248569069430232 seconds to unmarshal the objects Total allocated: 38681544 bytes (530060 objects) allocated memory by class ----------------------------------- 12138848 Hash 10542384 String 7920000 ActiveModel::Attribute::Uninitialized 5600000 ActiveModel::Attribute::FromDatabase 1200000 Foo 880000 ActiveModel::LazyAttributeHash 400000 ActiveModel::AttributeSet 80 Integer 72 ActiveRecord::ConnectionAdapters::SQLite3Adapter::SQLite3Integer 40 ActiveModel::Type::String 40 ActiveRecord::Type::DateTime 40 Object 40 Range allocated objects by class ----------------------------------- 250052 String 110000 ActiveModel::Attribute::Uninitialized 70001 Hash 70000 ActiveModel::Attribute::FromDatabase 10000 ActiveModel::AttributeSet 10000 ActiveModel::LazyAttributeHash 10000 Foo 2 Integer 1 ActiveModel::Type::String 1 ActiveRecord::ConnectionAdapters::SQLite3Adapter::SQLite3Integer 1 ActiveRecord::Type::DateTime 1 Object 1 Range ``` After: ``` it took 0.1660824950085953 seconds to unmarshal the objects Total allocated: 13883811 bytes (220090 objects) allocated memory by class ----------------------------------- 5743371 String 4940008 Hash 1200000 Foo 880000 ActiveModel::LazyAttributeHash 720000 Array 400000 ActiveModel::AttributeSet 80 ActiveModel::Attribute::FromDatabase 80 Integer 72 ActiveRecord::ConnectionAdapters::SQLite3Adapter::SQLite3Integer 40 ActiveModel::Type::String 40 ActiveModel::Type::Value 40 ActiveRecord::Type::DateTime 40 Object 40 Range allocated objects by class ----------------------------------- 130077 String 50004 Hash 10000 ActiveModel::AttributeSet 10000 ActiveModel::LazyAttributeHash 10000 Array 10000 Foo 2 Integer 1 ActiveModel::Attribute::FromDatabase 1 ActiveModel::Type::String 1 ActiveModel::Type::Value 1 ActiveRecord::ConnectionAdapters::SQLite3Adapter::SQLite3Integer 1 ActiveRecord::Type::DateTime 1 Object 1 Range ``` Fixes #30680. * Keep the `@delegate_hash` to avoid to lose any mutations that have been made to the record --- .../lib/active_model/attribute_set/builder.rb | 20 +++++++++++--------- activemodel/test/cases/attribute_set_test.rb | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) (limited to 'activemodel') diff --git a/activemodel/lib/active_model/attribute_set/builder.rb b/activemodel/lib/active_model/attribute_set/builder.rb index 758eb830fc..bf2d06b48a 100644 --- a/activemodel/lib/active_model/attribute_set/builder.rb +++ b/activemodel/lib/active_model/attribute_set/builder.rb @@ -22,12 +22,12 @@ module ActiveModel class LazyAttributeHash # :nodoc: delegate :transform_values, :each_key, :each_value, :fetch, :except, to: :materialize - def initialize(types, values, additional_types, default_attributes) + def initialize(types, values, additional_types, default_attributes, delegate_hash = {}) @types = types @values = values @additional_types = additional_types @materialized = false - @delegate_hash = {} + @delegate_hash = delegate_hash @default_attributes = default_attributes end @@ -76,15 +76,17 @@ module ActiveModel end def marshal_dump - materialize + [@types, @values, @additional_types, @default_attributes, @delegate_hash] end - def marshal_load(delegate_hash) - @delegate_hash = delegate_hash - @types = {} - @values = {} - @additional_types = {} - @materialized = true + def marshal_load(values) + if values.is_a?(Hash) + empty_hash = {}.freeze + initialize(empty_hash, empty_hash, empty_hash, empty_hash, values) + @materialized = true + else + initialize(*values) + end end protected diff --git a/activemodel/test/cases/attribute_set_test.rb b/activemodel/test/cases/attribute_set_test.rb index 9b323dae9d..b868dba743 100644 --- a/activemodel/test/cases/attribute_set_test.rb +++ b/activemodel/test/cases/attribute_set_test.rb @@ -217,6 +217,22 @@ module ActiveModel assert_equal({ foo: "1" }, attributes.to_hash) end + test "marshaling dump/load legacy materialized attribute hash" do + builder = AttributeSet::Builder.new(foo: Type::String.new) + attributes = builder.build_from_database(foo: "1") + + attributes.instance_variable_get(:@attributes).instance_eval do + class << self + def marshal_dump + materialize + end + end + end + + attributes = Marshal.load(Marshal.dump(attributes)) + assert_equal({ foo: "1" }, attributes.to_hash) + end + test "#accessed_attributes returns only attributes which have been read" do builder = AttributeSet::Builder.new(foo: Type::Value.new, bar: Type::Value.new) attributes = builder.build_from_database(foo: "1", bar: "2") -- cgit v1.2.3 From 0ea8e7db1a0659efe87ed2a85cb6ade69a8fddad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 16 Feb 2018 18:52:10 -0500 Subject: Remove support to Ruby 2.2 Rails 6 will only support Ruby >= 2.3. --- activemodel/activemodel.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activemodel') diff --git a/activemodel/activemodel.gemspec b/activemodel/activemodel.gemspec index a070a2898c..c5ed606b6b 100644 --- a/activemodel/activemodel.gemspec +++ b/activemodel/activemodel.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.summary = "A toolkit for building modeling frameworks (part of Rails)." s.description = "A toolkit for building modeling frameworks like Active Record. Rich support for attributes, callbacks, validations, serialization, internationalization, and testing." - s.required_ruby_version = ">= 2.2.2" + s.required_ruby_version = ">= 2.3.0" s.license = "MIT" -- cgit v1.2.3 From 89bcca59e91fa9da941de890012872e8288e77b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 16 Feb 2018 19:28:30 -0500 Subject: Remove usage of strip_heredoc in the framework in favor of <<~ Some places we can't remove because Ruby still don't have a method equivalent to strip_heredoc to be called in an already existent string. --- activemodel/test/cases/errors_test.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'activemodel') diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb index fe351f922d..cb6a8c43d5 100644 --- a/activemodel/test/cases/errors_test.rb +++ b/activemodel/test/cases/errors_test.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require "cases/helper" -require "active_support/core_ext/string/strip" require "yaml" class ErrorsTest < ActiveModel::TestCase @@ -406,7 +405,7 @@ class ErrorsTest < ActiveModel::TestCase end test "errors are backward compatible with the Rails 4.2 format" do - yaml = <<-CODE.strip_heredoc + yaml = <<~CODE --- !ruby/object:ActiveModel::Errors base: &1 !ruby/object:ErrorsTest::Person errors: !ruby/object:ActiveModel::Errors -- cgit v1.2.3 From 1e526788e6b1d3f42f4d8fdca20e588d42838c80 Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Fri, 16 Feb 2018 17:14:27 -0800 Subject: Rails 6 requires Ruby 2.3+ --- activemodel/lib/active_model/attribute_mutation_tracker.rb | 7 +------ activemodel/lib/active_model/type/integer.rb | 7 +------ activemodel/lib/active_model/type/registry.rb | 12 ++---------- activemodel/lib/active_model/validations/acceptance.rb | 7 +------ activemodel/lib/active_model/validations/clusivity.rb | 2 +- activemodel/test/cases/attribute_assignment_test.rb | 5 +---- 6 files changed, 7 insertions(+), 33 deletions(-) (limited to 'activemodel') diff --git a/activemodel/lib/active_model/attribute_mutation_tracker.rb b/activemodel/lib/active_model/attribute_mutation_tracker.rb index f55613ecd5..8e92c8807f 100644 --- a/activemodel/lib/active_model/attribute_mutation_tracker.rb +++ b/activemodel/lib/active_model/attribute_mutation_tracker.rb @@ -69,13 +69,8 @@ module ActiveModel forced_changes << attr_name.to_s end - # TODO Change this to private once we've dropped Ruby 2.2 support. - # Workaround for Ruby 2.2 "private attribute?" warning. - protected - - attr_reader :attributes, :forced_changes - private + attr_reader :attributes, :forced_changes def attr_names attributes.keys diff --git a/activemodel/lib/active_model/type/integer.rb b/activemodel/lib/active_model/type/integer.rb index fe396998a3..da74aaa3c5 100644 --- a/activemodel/lib/active_model/type/integer.rb +++ b/activemodel/lib/active_model/type/integer.rb @@ -31,13 +31,8 @@ module ActiveModel result end - # TODO Change this to private once we've dropped Ruby 2.2 support. - # Workaround for Ruby 2.2 "private attribute?" warning. - protected - - attr_reader :range - private + attr_reader :range def cast_value(value) case value diff --git a/activemodel/lib/active_model/type/registry.rb b/activemodel/lib/active_model/type/registry.rb index 7272d7b0c5..a19dc0f011 100644 --- a/activemodel/lib/active_model/type/registry.rb +++ b/activemodel/lib/active_model/type/registry.rb @@ -23,13 +23,8 @@ module ActiveModel end end - # TODO Change this to private once we've dropped Ruby 2.2 support. - # Workaround for Ruby 2.2 "private attribute?" warning. - protected - - attr_reader :registrations - private + attr_reader :registrations def registration_klass Registration @@ -59,10 +54,7 @@ module ActiveModel type_name == name end - # TODO Change this to private once we've dropped Ruby 2.2 support. - # Workaround for Ruby 2.2 "private attribute?" warning. - protected - + private attr_reader :name, :block end end diff --git a/activemodel/lib/active_model/validations/acceptance.rb b/activemodel/lib/active_model/validations/acceptance.rb index f35e4dec7f..ea3a6b52ab 100644 --- a/activemodel/lib/active_model/validations/acceptance.rb +++ b/activemodel/lib/active_model/validations/acceptance.rb @@ -58,13 +58,8 @@ module ActiveModel klass.send(:attr_writer, *attr_writers) end - # TODO Change this to private once we've dropped Ruby 2.2 support. - # Workaround for Ruby 2.2 "private attribute?" warning. - protected - - attr_reader :attributes - private + attr_reader :attributes def convert_to_reader_name(method_name) method_name.to_s.chomp("=") diff --git a/activemodel/lib/active_model/validations/clusivity.rb b/activemodel/lib/active_model/validations/clusivity.rb index 0b9b5ce6a1..bafb8e2106 100644 --- a/activemodel/lib/active_model/validations/clusivity.rb +++ b/activemodel/lib/active_model/validations/clusivity.rb @@ -32,7 +32,7 @@ module ActiveModel @delimiter ||= options[:in] || options[:within] end - # In Ruby 2.2 Range#include? on non-number-or-time-ish ranges checks all + # After Ruby 2.2, Range#include? on non-number-or-time-ish ranges checks all # possible values in the range for equality, which is slower but more accurate. # Range#cover? uses the previous logic of comparing a value with the range # endpoints, which is fast but is only accurate on Numeric, Time, Date, diff --git a/activemodel/test/cases/attribute_assignment_test.rb b/activemodel/test/cases/attribute_assignment_test.rb index 5ecf0a69c4..448f8587fd 100644 --- a/activemodel/test/cases/attribute_assignment_test.rb +++ b/activemodel/test/cases/attribute_assignment_test.rb @@ -18,10 +18,7 @@ class AttributeAssignmentTest < ActiveModel::TestCase raise ErrorFromAttributeWriter end - # TODO Change this to private once we've dropped Ruby 2.2 support. - # Workaround for Ruby 2.2 "private attribute?" warning. - protected - + private attr_writer :metadata end -- cgit v1.2.3 From d4eb0dc89ee6b476e2e10869dc282a96f956c6c7 Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Sat, 17 Feb 2018 13:02:18 -0800 Subject: Rails 6 requires Ruby 2.4.1+ Skipping over 2.4.0 to sidestep the `"symbol_from_string".to_sym.dup` bug. References #32028 --- activemodel/CHANGELOG.md | 5 +++++ activemodel/activemodel.gemspec | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'activemodel') diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index 13ea7d0bf3..b28c83e4ed 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -1,3 +1,8 @@ +## Rails 6.0.0.alpha (Unreleased) ## + +* Rails 6 requires Ruby 2.4.1 or newer. + + *Jeremy Daer* Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/activemodel/CHANGELOG.md) for previous changes. diff --git a/activemodel/activemodel.gemspec b/activemodel/activemodel.gemspec index c5ed606b6b..7be466dc4c 100644 --- a/activemodel/activemodel.gemspec +++ b/activemodel/activemodel.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.summary = "A toolkit for building modeling frameworks (part of Rails)." s.description = "A toolkit for building modeling frameworks like Active Record. Rich support for attributes, callbacks, validations, serialization, internationalization, and testing." - s.required_ruby_version = ">= 2.3.0" + s.required_ruby_version = ">= 2.4.1" s.license = "MIT" -- cgit v1.2.3 From cfbde022eedde2ae45e2dde9e3d8792933f070f4 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Tue, 20 Feb 2018 23:38:06 +0900 Subject: PostgreSQL: Allow BC dates like datetime consistently BC dates are supported by both date and datetime types. https://www.postgresql.org/docs/current/static/datatype-datetime.html Since #1097, new datetime allows year zero as 1 BC, but new date does not. It should be allowed even in new date consistently. --- activemodel/lib/active_model/type/date.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activemodel') diff --git a/activemodel/lib/active_model/type/date.rb b/activemodel/lib/active_model/type/date.rb index 8cecc16d0f..8ec5deedc4 100644 --- a/activemodel/lib/active_model/type/date.rb +++ b/activemodel/lib/active_model/type/date.rb @@ -42,7 +42,7 @@ module ActiveModel end def new_date(year, mon, mday) - if year && year != 0 + unless year.nil? || (year == 0 && mon == 0 && mday == 0) ::Date.new(year, mon, mday) rescue nil end end -- cgit v1.2.3