Skip to content

Commit

Permalink
Fix AR matcher tests for Rails 4.2
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmire committed Dec 25, 2014
1 parent 7dfbc5e commit 547d8b7
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 13 deletions.
34 changes: 30 additions & 4 deletions lib/shoulda/matchers/active_record/have_db_column_matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,11 @@ def correct_limit?
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
Expand Down Expand Up @@ -227,7 +227,7 @@ def correct_scale?
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} "
Expand All @@ -241,7 +241,10 @@ def correct_primary?
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
Expand All @@ -252,9 +255,32 @@ def actual_scale
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
Expand Down
22 changes: 19 additions & 3 deletions lib/shoulda/matchers/active_record/serialize_matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def description
protected

def serialization_valid?
if model_class.serialized_attributes.keys.include?(@name)
if attribute_is_serialized?
true
else
@missing = "no serialized attribute called :#{@name}"
Expand All @@ -140,7 +140,7 @@ def serialization_valid?

def class_valid?
if @options[:type]
klass = model_class.serialized_attributes[@name]
klass = serialization_coder
if klass == @options[:type]
true
else
Expand All @@ -162,7 +162,7 @@ def model_class

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]}"
Expand All @@ -183,6 +183,22 @@ def expectation
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
Expand Down
23 changes: 23 additions & 0 deletions lib/shoulda/matchers/rails_shim.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,29 @@ def self.verb_for_update
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
Expand Down
8 changes: 3 additions & 5 deletions spec/support/unit/helpers/model_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,12 @@ def define_model(name, columns = {}, &block)
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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def unserialized_model
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
Expand Down

0 comments on commit 547d8b7

Please sign in to comment.