diff --git a/lib/shoulda/matchers/active_record.rb b/lib/shoulda/matchers/active_record.rb index 9c38cc89..67eaaf59 100644 --- a/lib/shoulda/matchers/active_record.rb +++ b/lib/shoulda/matchers/active_record.rb @@ -2,7 +2,7 @@ require 'shoulda/matchers/active_record/association_matcher' require 'shoulda/matchers/active_record/have_db_column_matcher' require 'shoulda/matchers/active_record/have_db_index_matcher' require 'shoulda/matchers/active_record/have_readonly_attribute_matcher' - +require 'shoulda/matchers/active_record/serialize_matcher' module Shoulda module Matchers diff --git a/lib/shoulda/matchers/active_record/serialize_matcher.rb b/lib/shoulda/matchers/active_record/serialize_matcher.rb new file mode 100644 index 00000000..ccb4aa43 --- /dev/null +++ b/lib/shoulda/matchers/active_record/serialize_matcher.rb @@ -0,0 +1,89 @@ +module Shoulda # :nodoc: + module Matchers + module ActiveRecord # :nodoc: + + # Ensure that the field becomes serialized. + # + # Options: + # * :as - tests that the association makes use of the class_name option. + # + # Example: + # it { should serialize(:details) } + # it { should serialize(:details).as(Hash) } + # + def serialize(name) + SerializeMatcher.new(name) + end + + class SerializeMatcher # :nodoc: + def initialize(name) + @name = name.to_s + end + + def as(type) + @type = type + self + end + + def matches?(subject) + @subject = subject + serialization_valid? && type_valid? + end + + def failure_message + "Expected #{expectation} (#{@missing})" + end + + def negative_failure_message + "Did not expect #{expectation}" + end + + def description + description = "serialize :#{@name}" + description += " class_name => #{@type}" if @type + description + end + + protected + + def model_class + @subject.class + end + + def serialization_valid? + if model_class.serialized_attributes.keys.include?(@name) + true + else + @missing = "no serialized attribute called :#{@name}" + false + end + end + + def type_valid? + if @type + klass = model_class.serialized_attributes[@name] + + if klass == @type + true + else + if klass.object_class == @type + true + else + @missing = ":#{@name} should be a type of #{@type}" + false + end + end + else + true + end + end + + def expectation + expectation = "#{model_class.name} to serialize the attribute called :#{@name}" + expectation += " with a type of #{@type}" if @type + expectation + end + end + end + end +end \ No newline at end of file diff --git a/spec/shoulda/active_record/serialize_matcher_spec.rb b/spec/shoulda/active_record/serialize_matcher_spec.rb new file mode 100644 index 00000000..905b8df4 --- /dev/null +++ b/spec/shoulda/active_record/serialize_matcher_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' + +describe Shoulda::Matchers::ActiveRecord::SerializeMatcher do + context "an attribute that should be serialized" do + before do + define_model :example, :attr => :string do + serialize :attr + end + @model = Example.new + end + + it "should be serialized" do + @model.should serialize(:attr) + end + end + + context "an attribute that should be serialized with a type of Hash" do + before do + define_model :example, :attr => :string do + serialize :attr, Hash + end + @model = Example.new + end + + it "should be serialized" do + @model.should serialize(:attr).as(Hash) + end + end + + context "an attribute that should be serialized with a type of Array" do + before do + define_model :example, :attr => :string, :attr2 => :string do + serialize :attr, Array + serialize :attr2, Array + end + @model = Example.new + end + + it "should be serialized" do + @model.should serialize(:attr).as(Array) + end + end + + context "an attribute that should be serialized but isn't" do + before do + define_model :example, :attr => :string + @model = Example.new + end + + it "should assign a failure message" do + matcher = serialize(:attr) + matcher.matches?(@model).should == false + matcher.failure_message.should_not be_nil + end + + it "should assign a failure message with 'as'" do + matcher = serialize(:attr).as(Hash) + matcher.matches?(@model).should == false + matcher.failure_message.should_not be_nil + end + end +end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2e318b1f..114500e7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,6 @@ # Create Rails environment based on the version given from Appraisal TESTAPP_ROOT = File.join(File.dirname(__FILE__), '..', 'tmp', 'aruba', 'testapp') +puts TESTAPP_ROOT FileUtils.rm_rf(TESTAPP_ROOT) if File.exists?(TESTAPP_ROOT) `rails new #{TESTAPP_ROOT}`