From 1b5fc27cf8df2ab9e74259c1f853ae6fc8711e08 Mon Sep 17 00:00:00 2001 From: Blake Thomson Date: Sun, 23 Oct 2011 16:41:37 +0300 Subject: [PATCH] Add validates_confirmation_of matcher --- lib/shoulda/matchers/active_model.rb | 1 + .../validate_confirmation_of_matcher.rb | 63 +++++++++++++++++++ .../validate_confirmation_of_matcher_spec.rb | 48 ++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb create mode 100644 spec/shoulda/active_model/validate_confirmation_of_matcher_spec.rb diff --git a/lib/shoulda/matchers/active_model.rb b/lib/shoulda/matchers/active_model.rb index e77a633c..e304e444 100644 --- a/lib/shoulda/matchers/active_model.rb +++ b/lib/shoulda/matchers/active_model.rb @@ -8,6 +8,7 @@ require 'shoulda/matchers/active_model/validate_presence_of_matcher' require 'shoulda/matchers/active_model/validate_format_of_matcher' require 'shoulda/matchers/active_model/validate_uniqueness_of_matcher' require 'shoulda/matchers/active_model/validate_acceptance_of_matcher' +require 'shoulda/matchers/active_model/validate_confirmation_of_matcher' require 'shoulda/matchers/active_model/validate_numericality_of_matcher' require 'shoulda/matchers/active_model/allow_mass_assignment_of_matcher' diff --git a/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb b/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb new file mode 100644 index 00000000..3717f0c1 --- /dev/null +++ b/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb @@ -0,0 +1,63 @@ +module Shoulda # :nodoc: + module Matchers + module ActiveModel # :nodoc: + # Ensures that the model's attribute matches confirmation + # + # Example: + # it { should validate_confirmation_of(:password) } + # + def validate_confirmation_of(attr) + ValidateConfirmationOfMatcher.new(attr) + end + + class ValidateConfirmationOfMatcher < ValidationMatcher # :nodoc: + include Helpers + + def initialize(attribute) + @attribute = attribute + @confirmation = "#{attribute}_confirmation" + end + + def with_message(message) + @message = message if message + self + end + + def description + "require #{@base_attribute} to match #{@attribute}" + end + + def matches?(subject) + super(subject) + @message ||= :confirmation + + disallows_different_value && + allows_same_value && + allows_missing_confirmation + end + + private + + def disallows_different_value + set_confirmation("some value") + matches = disallows_value_of("different value", @message) + end + + def allows_same_value + set_confirmation("same value") + allows_value_of("same value", @message) + end + + def allows_missing_confirmation + set_confirmation(nil) + allows_value_of("any value", @message) + end + + def set_confirmation(val) + setter = :"#{@confirmation}=" + @subject.send(setter, val) if @subject.respond_to?(setter) + end + end + end + end +end diff --git a/spec/shoulda/active_model/validate_confirmation_of_matcher_spec.rb b/spec/shoulda/active_model/validate_confirmation_of_matcher_spec.rb new file mode 100644 index 00000000..29bd8a2c --- /dev/null +++ b/spec/shoulda/active_model/validate_confirmation_of_matcher_spec.rb @@ -0,0 +1,48 @@ +require 'spec_helper' + +describe Shoulda::Matchers::ActiveModel::ValidateConfirmationOfMatcher do + + context "an attribute which needs confirmation" do + before do + define_model(:example, :attr => :string) do + validates_confirmation_of :attr + end + @model = Example.new + end + + it "should require confirmation of that attribute" do + @model.should validate_confirmation_of(:attr) + end + + it "should not override the default message with a blank" do + @model.should validate_confirmation_of(:attr).with_message(nil) + end + end + + context "an attribute which must be confirmed with a custom message" do + before do + define_model :example, :attr => :string do + validates_confirmation_of :attr, :message => 'custom' + end + @model = Example.new + end + + it "should require confirmation of that attribute with that message" do + @model.should validate_confirmation_of(:attr).with_message(/custom/) + end + + it "should not require confirmation of that attribute with another message" do + @model.should_not validate_confirmation_of(:attr) + end + end + + context "an attribute which doesn't need confirmation" do + before do + @model = define_model(:example, :attr => :string).new + end + + it "should not require confirmation of that attribute" do + @model.should_not validate_confirmation_of(:attr) + end + end +end