Change `validate_uniqueness_of_matcher` to give non-null columns default values
Previously, if a model had an attribute that mapped to a non-nullable database column that was not under test the matcher would fail with an SQL error like: examples.column may not be NULL #... With this change the matcher attempts to provide a default value for all non-nullable, non-primary attributes. This should avoid the above error in simple cases.
This commit is contained in:
parent
5b44edf8b3
commit
561ac3e2f0
3
NEWS.md
3
NEWS.md
|
@ -22,6 +22,9 @@
|
||||||
* You cannot test that your attribute allows nil (`.in_array([nil])`) if
|
* You cannot test that your attribute allows nil (`.in_array([nil])`) if
|
||||||
the column does not allow null values.
|
the column does not allow null values.
|
||||||
|
|
||||||
|
* Change `validate_uniqueness_of(...)` so that it provides default values for
|
||||||
|
non-nullable attributes.
|
||||||
|
|
||||||
# v 2.5.0
|
# v 2.5.0
|
||||||
|
|
||||||
* Fix Rails/Test::Unit integration to ensure that the test case classes we are
|
* Fix Rails/Test::Unit integration to ensure that the test case classes we are
|
||||||
|
|
|
@ -115,6 +115,11 @@ module Shoulda # :nodoc:
|
||||||
|
|
||||||
@subject.class.new.tap do |instance|
|
@subject.class.new.tap do |instance|
|
||||||
instance.__send__("#{@attribute}=", value)
|
instance.__send__("#{@attribute}=", value)
|
||||||
|
|
||||||
|
other_non_nullable_columns.each do |non_nullable_column|
|
||||||
|
instance.__send__("#{non_nullable_column.name}=", correct_type_for_column(non_nullable_column))
|
||||||
|
end
|
||||||
|
|
||||||
if has_secure_password?
|
if has_secure_password?
|
||||||
instance.password = 'password'
|
instance.password = 'password'
|
||||||
instance.password_confirmation = 'password'
|
instance.password_confirmation = 'password'
|
||||||
|
@ -193,7 +198,7 @@ module Shoulda # :nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
def correct_type_for_column(column)
|
def correct_type_for_column(column)
|
||||||
if column.type == :string
|
if column.type == :string || column.type == :binary
|
||||||
'0'
|
'0'
|
||||||
elsif column.type == :datetime
|
elsif column.type == :datetime
|
||||||
DateTime.now
|
DateTime.now
|
||||||
|
@ -215,6 +220,12 @@ module Shoulda # :nodoc:
|
||||||
end
|
end
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def other_non_nullable_columns
|
||||||
|
@subject.class.columns.select do |column|
|
||||||
|
column.name != @attribute && !column.null && !column.primary
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -341,6 +341,42 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "a model with non-nullable attribute" do
|
||||||
|
context "of type" do
|
||||||
|
[:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |type|
|
||||||
|
context type do
|
||||||
|
it "does not raise an error" do
|
||||||
|
model = define_model_with_non_nullable(type)
|
||||||
|
expect { expect(model).to matcher }.not_to raise_error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "that is a primary key" do
|
||||||
|
it "does not cause duplicate entry errors by re-using default values for primary keys" do
|
||||||
|
create_table :examples, id: false do |t|
|
||||||
|
t.string :attr
|
||||||
|
t.integer :non_nullable, primary: true
|
||||||
|
end
|
||||||
|
model_class = define_model(:example, attr: :string) do
|
||||||
|
validates_uniqueness_of :attr
|
||||||
|
end
|
||||||
|
model_1 = model_class.new
|
||||||
|
model_2 = model_class.new
|
||||||
|
expect(model_1).to matcher
|
||||||
|
expect { expect(model_2).to matcher }.not_to raise_error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def define_model_with_non_nullable(type)
|
||||||
|
define_model(:example, attr: :string, non_nullable: { type: type, options: { null: false } }) do
|
||||||
|
attr_accessible :attr, :non_nullable
|
||||||
|
validates_uniqueness_of :attr
|
||||||
|
end.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def case_sensitive_validation_with_existing_value(attr_type)
|
def case_sensitive_validation_with_existing_value(attr_type)
|
||||||
model = define_model(:example, attr: attr_type) do
|
model = define_model(:example, attr: attr_type) do
|
||||||
attr_accessible :attr
|
attr_accessible :attr
|
||||||
|
|
Loading…
Reference in New Issue