Fix AR matcher tests for Rails 4.2

This commit is contained in:
Elliot Winkler 2014-12-24 16:46:49 -05:00
parent 7dfbc5e0c2
commit 547d8b762f
5 changed files with 76 additions and 13 deletions

View File

@ -189,11 +189,11 @@ module Shoulda
def correct_default?
return true unless @options.key?(:default)
if matched_column.default.to_s == @options[:default].to_s
if matched_column.type_cast_default.to_s == @options[:default].to_s
true
else
@missing = "#{model_class} has a db column named #{@column} " <<
"of default #{matched_column.default}, " <<
"of default #{matched_column.type_cast_default}, " <<
"not #{@options[:default]}."
false
end
@ -227,7 +227,7 @@ module Shoulda
def correct_primary?
return true unless @options.key?(:primary)
if matched_column.primary == @options[:primary]
if matched_column.primary? == @options[:primary]
true
else
@missing = "#{model_class} has a db column named #{@column} "
@ -241,7 +241,10 @@ module Shoulda
end
def matched_column
model_class.columns.detect { |each| each.name == @column.to_s }
@_matched_column ||= begin
column = model_class.columns.detect { |each| each.name == @column.to_s }
DecoratedColumn.new(model_class, column)
end
end
def model_class
@ -252,9 +255,32 @@ module Shoulda
matched_column.scale
end
def actual_primary?
model_class.primary_key == matched_column.name
end
def expectation
"#{model_class.name} to #{description}"
end
class DecoratedColumn < SimpleDelegator
def initialize(model, column)
@model = model
super(column)
end
def type_cast_default
Shoulda::Matchers::RailsShim.type_cast_default_for(model, self)
end
def primary?
model.primary_key == name
end
protected
attr_reader :model
end
end
end
end

View File

@ -130,7 +130,7 @@ module Shoulda
protected
def serialization_valid?
if model_class.serialized_attributes.keys.include?(@name)
if attribute_is_serialized?
true
else
@missing = "no serialized attribute called :#{@name}"
@ -140,7 +140,7 @@ module Shoulda
def class_valid?
if @options[:type]
klass = model_class.serialized_attributes[@name]
klass = serialization_coder
if klass == @options[:type]
true
else
@ -162,7 +162,7 @@ module Shoulda
def instance_class_valid?
if @options.key?(:instance_type)
if model_class.serialized_attributes[@name].class == @options[:instance_type]
if serialization_coder.is_a?(@options[:instance_type])
true
else
@missing = ":#{@name} should be an instance of #{@options[:type]}"
@ -183,6 +183,22 @@ module Shoulda
expectation += " with an instance of #{@options[:instance_type]}" if @options[:instance_type]
expectation
end
def attribute_is_serialized?
serialized_attributes.include?(@name)
end
def serialization_coder
serialized_attributes[@name]
end
def serialized_attributes
Shoulda::Matchers::RailsShim.serialized_attributes_for(model)
end
def model
@subject.class
end
end
end
end

View File

@ -42,6 +42,29 @@ module Shoulda
end
end
def self.type_cast_default_for(model, column)
if model.respond_to?(:column_defaults)
# Rails 4.2
model.column_defaults[column.name]
else
column.default
end
end
def self.serialized_attributes_for(model)
if defined?(::ActiveRecord::Type::Serialized)
# Rails 5+
model.columns.select do |column|
column.cast_type.is_a?(::ActiveRecord::Type::Serialized)
end.inject({}) do |hash, column|
hash[column.name.to_s] = column.cast_type.coder
hash
end
else
model.serialized_attributes
end
end
def self.active_record_major_version
::ActiveRecord::VERSION::MAJOR
end

View File

@ -78,14 +78,12 @@ module UnitTests
private
def clear_column_caches
# Rails 3.1 - 4.0
if ActiveRecord::Base.connection_pool.respond_to?(:clear_cache!)
ActiveRecord::Base.connection_pool.clear_cache!
end
# Rails 4.x
if ActiveRecord::Base.connection.respond_to?(:schema_cache)
ActiveRecord::Base.connection.schema_cache.clear!
# Rails 3.1 - 4.0
elsif ActiveRecord::Base.connection_pool.respond_to?(:clear_cache!)
ActiveRecord::Base.connection_pool.clear_cache!
end
end

View File

@ -39,7 +39,7 @@ describe Shoulda::Matchers::ActiveRecord::SerializeMatcher, type: :model do
end
end
context 'an attribute that is serialized as a specific type' do
context 'an attribute that will end up being serialized as YAML' do
it 'accepts when the types match' do
expect(with_serialized_attr(Hash)).to serialize(:attr).as(Hash)
end