thoughtbot--shoulda-matchers/lib/shoulda/matchers/active_record/serialize_matcher.rb

113 lines
2.9 KiB
Ruby
Raw Normal View History

module Shoulda # :nodoc:
module Matchers
module ActiveRecord # :nodoc:
# Ensure that the field becomes serialized.
#
# Options:
2011-11-15 22:30:25 +00:00
# * <tt>:as</tt> - tests that the serialized attribute makes use of the class_name option.
#
# Example:
# it { should serialize(:details) }
# it { should serialize(:details).as(Hash) }
2012-12-20 05:04:27 +00:00
# it { should serialize(:details).as_instance_of(ExampleSerializer) }
#
def serialize(name)
SerializeMatcher.new(name)
end
class SerializeMatcher # :nodoc:
def initialize(name)
@name = name.to_s
@options = {}
end
def as(type)
@options[:type] = type
self
end
2012-03-30 15:22:31 +00:00
def as_instance_of(type)
@options[:instance_type] = type
self
end
def matches?(subject)
@subject = subject
serialization_valid? && type_valid?
end
def failure_message_for_should
"Expected #{expectation} (#{@missing})"
end
def failure_message_for_should_not
"Did not expect #{expectation}"
end
def description
description = "serialize :#{@name}"
description += " class_name => #{@options[:type]}" if @options.key?(:type)
description
end
protected
def serialization_valid?
if model_class.serialized_attributes.keys.include?(@name)
true
else
@missing = "no serialized attribute called :#{@name}"
false
end
end
def class_valid?
if @options[:type]
2012-03-16 17:16:48 +00:00
klass = model_class.serialized_attributes[@name]
if klass == @options[:type]
true
else
if klass.respond_to?(:object_class) && klass.object_class == @options[:type]
2012-03-16 17:16:48 +00:00
true
else
@missing = ":#{@name} should be a type of #{@options[:type]}"
2012-03-16 17:16:48 +00:00
false
end
end
2012-03-16 17:16:48 +00:00
else
true
end
end
2012-03-30 15:22:31 +00:00
def model_class
@subject.class
end
def instance_class_valid?
if @options.key?(:instance_type)
if model_class.serialized_attributes[@name].class == @options[:instance_type]
2012-03-16 17:16:48 +00:00
true
else
@missing = ":#{@name} should be an instance of #{@options[:type]}"
2012-03-16 17:16:48 +00:00
false
end
else
2012-03-16 17:16:48 +00:00
true
end
end
def type_valid?
class_valid? && instance_class_valid?
end
def expectation
expectation = "#{model_class.name} to serialize the attribute called :#{@name}"
expectation += " with a type of #{@options[:type]}" if @options[:type]
expectation += " with an instance of #{@options[:instance_type]}" if @options[:instance_type]
expectation
end
end
end
end
2012-03-30 15:22:31 +00:00
end