Always run absence matcher tests

This commit is contained in:
Elliot Winkler 2017-11-29 12:22:52 -06:00
parent 3b61f8a039
commit e5ce548600
1 changed files with 246 additions and 248 deletions

View File

@ -1,266 +1,264 @@
require 'unit_spec_helper'
describe Shoulda::Matchers::ActiveModel::ValidateAbsenceOfMatcher, type: :model do
if active_model_4_0?
def self.available_column_types
[
:string,
:text,
:integer,
:float,
:decimal,
:datetime,
:timestamp,
:time,
:date,
:binary
]
def self.available_column_types
[
:string,
:text,
:integer,
:float,
:decimal,
:datetime,
:timestamp,
:time,
:date,
:binary
]
end
context 'a model with an absence validation' do
it 'accepts' do
expect(validating_absence_of(:attr)).to validate_absence_of(:attr)
end
context 'a model with an absence validation' do
it 'accepts' do
expect(validating_absence_of(:attr)).to validate_absence_of(:attr)
end
it 'does not override the default message with a present' do
expect(validating_absence_of(:attr)).to validate_absence_of(:attr).with_message(nil)
end
available_column_types.each do |type|
context "when column is of type #{type}" do
it "accepts" do
expect(validating_absence_of(:attr, {}, type: type)).
to validate_absence_of(:attr)
end
it_supports(
'ignoring_interference_by_writer',
tests: {
accept_if_qualified_but_changing_value_does_not_interfere: {
changing_values_with: :next_value
},
}
)
define_method(:validation_matcher_scenario_args) do |*args|
super(*args).deep_merge(column_type: type)
end
end
end
def validation_matcher_scenario_args
super.deep_merge(model_creator: :active_record)
end
it 'does not override the default message with a present' do
expect(validating_absence_of(:attr)).to validate_absence_of(:attr).with_message(nil)
end
context 'a model without an absence validation' do
it 'rejects with the correct failure message' do
record = define_model(:example, attr: :string).new
message = <<-MESSAGE
Example did not properly validate that :attr is empty/falsy.
After setting :attr to "an arbitrary value", the matcher expected
the Example to be invalid, but it was valid instead.
MESSAGE
assertion = lambda do
expect(record).to validate_absence_of(:attr)
available_column_types.each do |type|
context "when column is of type #{type}" do
it "accepts" do
expect(validating_absence_of(:attr, {}, type: type)).
to validate_absence_of(:attr)
end
expect(&assertion).to fail_with_message(message)
end
end
it_supports(
'ignoring_interference_by_writer',
tests: {
accept_if_qualified_but_changing_value_does_not_interfere: {
changing_values_with: :next_value
},
}
)
context 'an ActiveModel class with an absence validation' do
it 'accepts' do
expect(active_model_validating_absence_of(:attr)).to validate_absence_of(:attr)
end
it 'does not override the default message with a blank' do
expect(active_model_validating_absence_of(:attr)).to validate_absence_of(:attr).with_message(nil)
end
it_supports(
'ignoring_interference_by_writer',
tests: {
accept_if_qualified_but_changing_value_does_not_interfere: {
changing_values_with: :upcase
},
}
)
def validation_matcher_scenario_args
super.deep_merge(model_creator: :active_model)
end
end
context 'an ActiveModel class without an absence validation' do
it 'rejects with the correct failure message' do
message = <<-MESSAGE
Example did not properly validate that :attr is empty/falsy.
After setting :attr to "an arbitrary value", the matcher expected
the Example to be invalid, but it was valid instead.
MESSAGE
assertion = lambda do
expect(active_model_with(:attr)).to validate_absence_of(:attr)
end
expect(&assertion).to fail_with_message(message)
end
end
context 'a has_many association with an absence validation' do
it 'requires the attribute to not be set' do
expect(having_many(:children, absence: true)).to validate_absence_of(:children)
end
it_supports(
'ignoring_interference_by_writer',
tests: {
accept_if_qualified_but_changing_value_does_not_interfere: {
changing_values_with: :next_value
},
}
)
def validation_matcher_scenario_args
super.deep_merge(model_creator: :"active_record/has_many")
end
end
context 'a has_many association without an absence validation' do
it 'does not require the attribute to not be set' do
expect(having_many(:children, absence: false)).
not_to validate_absence_of(:children)
end
end
context 'an absent has_and_belongs_to_many association' do
it 'accepts' do
model = having_and_belonging_to_many(:children, absence: true)
expect(model).to validate_absence_of(:children)
end
it_supports(
'ignoring_interference_by_writer',
tests: {
accept_if_qualified_but_changing_value_does_not_interfere: {
changing_values_with: :next_value
},
}
)
def validation_matcher_scenario_args
super.deep_merge(model_creator: :"active_record/habtm")
end
end
context 'a non-absent has_and_belongs_to_many association' do
it 'rejects with the correct failure message' do
model = having_and_belonging_to_many(:children, absence: false)
message = <<-MESSAGE
Parent did not properly validate that :children is empty/falsy.
After setting :children to [#<Child id: nil>], the matcher expected
the Parent to be invalid, but it was valid instead.
MESSAGE
assertion = lambda do
expect(model).to validate_absence_of(:children)
end
expect(&assertion).to fail_with_message(message)
end
end
context "an i18n translation containing %{attribute} and %{model}" do
after { I18n.backend.reload! }
it "does not raise an exception" do
stub_translation("activerecord.errors.messages.present",
"%{attribute} must be blank in a %{model}")
expect {
expect(validating_absence_of(:attr)).to validate_absence_of(:attr)
}.to_not raise_exception
end
end
context "an attribute with a context-dependent validation" do
context "without the validation context" do
it "does not match" do
expect(validating_absence_of(:attr, on: :customisable)).not_to validate_absence_of(:attr)
define_method(:validation_matcher_scenario_args) do |*args|
super(*args).deep_merge(column_type: type)
end
end
context "with the validation context" do
it "matches" do
expect(validating_absence_of(:attr, on: :customisable)).to validate_absence_of(:attr).on(:customisable)
end
end
end
def define_model_validating_absence_of(attr, validation_options = {}, given_column_options = {})
default_column_options = { type: :string, options: {} }
column_options = default_column_options.merge(given_column_options)
define_model :example, attr => column_options do |model|
model.validates_absence_of(attr, validation_options)
if block_given?
yield model
end
end
end
def validating_absence_of(attr, validation_options = {}, given_column_options = {})
model = define_model_validating_absence_of(
attr,
validation_options,
given_column_options
)
model.new
end
alias_method :build_record_validating_absence_of, :validating_absence_of
def active_model_with(attr, &block)
define_active_model_class('Example', accessors: [attr], &block).new
end
def active_model_validating_absence_of(attr)
active_model_with(attr) do
validates_absence_of attr
end
end
def having_many(plural_name, options = {})
define_model plural_name.to_s.singularize
define_model :parent do
has_many plural_name
if options[:absence]
validates_absence_of plural_name
end
end.new
end
def having_and_belonging_to_many(plural_name, options = {})
create_table 'children_parents', id: false do |t|
t.integer "#{plural_name.to_s.singularize}_id"
t.integer :parent_id
end
define_model plural_name.to_s.singularize
define_model :parent do
has_and_belongs_to_many plural_name
if options[:absence]
validates_absence_of plural_name
end
end.new
end
def validation_matcher_scenario_args
super.deep_merge(matcher_name: :validate_absence_of)
super.deep_merge(model_creator: :active_record)
end
end
context 'a model without an absence validation' do
it 'rejects with the correct failure message' do
record = define_model(:example, attr: :string).new
message = <<-MESSAGE
Example did not properly validate that :attr is empty/falsy.
After setting :attr to "an arbitrary value", the matcher expected
the Example to be invalid, but it was valid instead.
MESSAGE
assertion = lambda do
expect(record).to validate_absence_of(:attr)
end
expect(&assertion).to fail_with_message(message)
end
end
context 'an ActiveModel class with an absence validation' do
it 'accepts' do
expect(active_model_validating_absence_of(:attr)).to validate_absence_of(:attr)
end
it 'does not override the default message with a blank' do
expect(active_model_validating_absence_of(:attr)).to validate_absence_of(:attr).with_message(nil)
end
it_supports(
'ignoring_interference_by_writer',
tests: {
accept_if_qualified_but_changing_value_does_not_interfere: {
changing_values_with: :upcase
},
}
)
def validation_matcher_scenario_args
super.deep_merge(model_creator: :active_model)
end
end
context 'an ActiveModel class without an absence validation' do
it 'rejects with the correct failure message' do
message = <<-MESSAGE
Example did not properly validate that :attr is empty/falsy.
After setting :attr to "an arbitrary value", the matcher expected
the Example to be invalid, but it was valid instead.
MESSAGE
assertion = lambda do
expect(active_model_with(:attr)).to validate_absence_of(:attr)
end
expect(&assertion).to fail_with_message(message)
end
end
context 'a has_many association with an absence validation' do
it 'requires the attribute to not be set' do
expect(having_many(:children, absence: true)).to validate_absence_of(:children)
end
it_supports(
'ignoring_interference_by_writer',
tests: {
accept_if_qualified_but_changing_value_does_not_interfere: {
changing_values_with: :next_value
},
}
)
def validation_matcher_scenario_args
super.deep_merge(model_creator: :"active_record/has_many")
end
end
context 'a has_many association without an absence validation' do
it 'does not require the attribute to not be set' do
expect(having_many(:children, absence: false)).
not_to validate_absence_of(:children)
end
end
context 'an absent has_and_belongs_to_many association' do
it 'accepts' do
model = having_and_belonging_to_many(:children, absence: true)
expect(model).to validate_absence_of(:children)
end
it_supports(
'ignoring_interference_by_writer',
tests: {
accept_if_qualified_but_changing_value_does_not_interfere: {
changing_values_with: :next_value
},
}
)
def validation_matcher_scenario_args
super.deep_merge(model_creator: :"active_record/habtm")
end
end
context 'a non-absent has_and_belongs_to_many association' do
it 'rejects with the correct failure message' do
model = having_and_belonging_to_many(:children, absence: false)
message = <<-MESSAGE
Parent did not properly validate that :children is empty/falsy.
After setting :children to [#<Child id: nil>], the matcher expected
the Parent to be invalid, but it was valid instead.
MESSAGE
assertion = lambda do
expect(model).to validate_absence_of(:children)
end
expect(&assertion).to fail_with_message(message)
end
end
context "an i18n translation containing %{attribute} and %{model}" do
after { I18n.backend.reload! }
it "does not raise an exception" do
stub_translation("activerecord.errors.messages.present",
"%{attribute} must be blank in a %{model}")
expect {
expect(validating_absence_of(:attr)).to validate_absence_of(:attr)
}.to_not raise_exception
end
end
context "an attribute with a context-dependent validation" do
context "without the validation context" do
it "does not match" do
expect(validating_absence_of(:attr, on: :customisable)).not_to validate_absence_of(:attr)
end
end
context "with the validation context" do
it "matches" do
expect(validating_absence_of(:attr, on: :customisable)).to validate_absence_of(:attr).on(:customisable)
end
end
end
def define_model_validating_absence_of(attr, validation_options = {}, given_column_options = {})
default_column_options = { type: :string, options: {} }
column_options = default_column_options.merge(given_column_options)
define_model :example, attr => column_options do |model|
model.validates_absence_of(attr, validation_options)
if block_given?
yield model
end
end
end
def validating_absence_of(attr, validation_options = {}, given_column_options = {})
model = define_model_validating_absence_of(
attr,
validation_options,
given_column_options
)
model.new
end
alias_method :build_record_validating_absence_of, :validating_absence_of
def active_model_with(attr, &block)
define_active_model_class('Example', accessors: [attr], &block).new
end
def active_model_validating_absence_of(attr)
active_model_with(attr) do
validates_absence_of attr
end
end
def having_many(plural_name, options = {})
define_model plural_name.to_s.singularize
define_model :parent do
has_many plural_name
if options[:absence]
validates_absence_of plural_name
end
end.new
end
def having_and_belonging_to_many(plural_name, options = {})
create_table 'children_parents', id: false do |t|
t.integer "#{plural_name.to_s.singularize}_id"
t.integer :parent_id
end
define_model plural_name.to_s.singularize
define_model :parent do
has_and_belongs_to_many plural_name
if options[:absence]
validates_absence_of plural_name
end
end.new
end
def validation_matcher_scenario_args
super.deep_merge(matcher_name: :validate_absence_of)
end
end