mirror of
https://github.com/thoughtbot/shoulda-matchers.git
synced 2022-11-09 12:01:38 -05:00
Uniqueness: Support UUID columns that end in "f"
This commit fixes the uniqueness matcher so that when qualified with `scoped_to` and one of the scopes is a UUID column that happens to end in an "f", the matcher is able to generate a proper next value during testing and doesn't error.
This commit is contained in:
parent
74fa081ef5
commit
81034eaf3d
3 changed files with 45 additions and 13 deletions
10
NEWS.md
10
NEWS.md
|
@ -21,6 +21,16 @@
|
|||
* `set_session['key'].to(nil)` will no longer pass when the key in question
|
||||
has not been set yet.
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* So far the tests for the gem have been running against only SQLite. Now they
|
||||
run against PostgreSQL, too. As a result we were able to fix some
|
||||
Postgres-related bugs:
|
||||
|
||||
* Fix `validate_uniqueness_of` + `scoped_to` so that when one of the scope
|
||||
attributes is a UUID column that ends in an "f", the matcher is able to
|
||||
generate a proper "next" value without erroring.
|
||||
|
||||
# 2.8.0
|
||||
|
||||
### Deprecations
|
||||
|
|
|
@ -393,11 +393,14 @@ module Shoulda
|
|||
end
|
||||
|
||||
def correct_type_for_column(column)
|
||||
if column.type == :string
|
||||
column = column_for(scope)
|
||||
|
||||
case column.type
|
||||
when :string
|
||||
'0'
|
||||
elsif column.type == :datetime
|
||||
when :datetime
|
||||
DateTime.now
|
||||
elsif column.type == :uuid
|
||||
when :uuid
|
||||
SecureRandom.uuid
|
||||
else
|
||||
0
|
||||
|
@ -405,10 +408,14 @@ module Shoulda
|
|||
end
|
||||
|
||||
def next_value_for(scope, previous_value)
|
||||
if @subject.class.respond_to?(:defined_enums) && @subject.defined_enums[scope.to_s]
|
||||
column = column_for(scope)
|
||||
|
||||
if column.type == :uuid
|
||||
SecureRandom.uuid
|
||||
elsif defined_as_enum?(scope)
|
||||
available_values = available_enum_values_for(scope, previous_value)
|
||||
available_values.keys.last
|
||||
elsif scope.to_s =~ /_type$/ && model_class?(previous_value)
|
||||
elsif polymorphic_type_attribute?(scope, previous_value)
|
||||
Uniqueness::TestModels.create(previous_value).to_s
|
||||
elsif previous_value.respond_to?(:next)
|
||||
previous_value.next
|
||||
|
@ -419,16 +426,21 @@ module Shoulda
|
|||
end
|
||||
end
|
||||
|
||||
def defined_as_enum?(scope)
|
||||
@subject.class.respond_to?(:defined_enums) &&
|
||||
@subject.defined_enums[scope.to_s]
|
||||
end
|
||||
|
||||
def polymorphic_type_attribute?(scope, previous_value)
|
||||
scope.to_s =~ /_type$/ && model_class?(previous_value)
|
||||
end
|
||||
|
||||
def available_enum_values_for(scope, previous_value)
|
||||
@subject.defined_enums[scope.to_s].reject do |key, _|
|
||||
key == previous_value
|
||||
end
|
||||
end
|
||||
|
||||
def class_name
|
||||
@subject.class.name
|
||||
end
|
||||
|
||||
def existing_value
|
||||
value = existing_record.__send__(@attribute)
|
||||
if @options[:case_insensitive] && value.respond_to?(:swapcase!)
|
||||
|
@ -436,6 +448,14 @@ module Shoulda
|
|||
end
|
||||
value
|
||||
end
|
||||
|
||||
def class_name
|
||||
@subject.class.name
|
||||
end
|
||||
|
||||
def column_for(scope)
|
||||
@subject.class.columns_hash[scope.to_s]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,8 +35,8 @@ describe Shoulda::Matchers::ActiveRecord::ValidateUniquenessOfMatcher, type: :mo
|
|||
context "when more than one record exists that has the next version of the attribute's value" do
|
||||
it 'accepts' do
|
||||
value1 = dummy_value_for(value_type)
|
||||
value2 = next_version_of(value1)
|
||||
value3 = next_version_of(value2)
|
||||
value2 = next_version_of(value1, value_type)
|
||||
value3 = next_version_of(value2, value_type)
|
||||
model = define_model_validating_uniqueness(
|
||||
scopes: [ build_attribute(name: :scope) ],
|
||||
)
|
||||
|
@ -633,8 +633,10 @@ describe Shoulda::Matchers::ActiveRecord::ValidateUniquenessOfMatcher, type: :mo
|
|||
end
|
||||
end
|
||||
|
||||
def next_version_of(value)
|
||||
if value.is_a?(Time)
|
||||
def next_version_of(value, value_type)
|
||||
if value_type == :uuid
|
||||
SecureRandom.uuid
|
||||
elsif value_type == :time
|
||||
value + 1
|
||||
elsif value.respond_to?(:next)
|
||||
value.next
|
||||
|
|
Loading…
Add table
Reference in a new issue