Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add allow_values_for_matcher.

  • Loading branch information...
commit c6c1d398e88e7a38e7a79ab23ef3d389733afab5 1 parent 0a706f9
@nmerouze nmerouze authored
View
86 lib/remarkable_mongomapper/matchers/allow_values_for_matcher.rb
@@ -0,0 +1,86 @@
+module Remarkable
+ module MongoMapper
+ module Matchers
+ class AllowValuesForMatcher < Remarkable::MongoMapper::Base #:nodoc:
+ include Remarkable::Negative
+ arguments :collection => :attributes, :as => :attribute
+
+ optional :message
+ optional :in, :splat => true
+ optional :allow_nil, :allow_blank, :default => true
+
+ collection_assertions :is_valid?, :is_invalid?, :allow_nil?, :allow_blank?
+
+ default_options :message => "is invalid"
+
+ before_assert do
+ first_value = @options[:in].is_a?(Array) ? @options[:in].first : @options[:in]
+ @in_range = first_value.is_a?(Range)
+
+ @options[:in] = if @in_range
+ first_value.to_a[0,2] + first_value.to_a[-2,2]
+ else
+ [*@options[:in]].compact
+ end
+
+ @options[:in].uniq!
+ end
+
+ protected
+
+ def is_valid?
+ assert_collection :value, valid_values do |value|
+ good?(value)
+ end
+ end
+
+ def is_invalid?
+ assert_collection :value, invalid_values do |value|
+ bad?(value)
+ end
+ end
+
+ def valid_values
+ @options[:in]
+ end
+
+ def invalid_values
+ []
+ end
+
+ def interpolation_options
+ options = if @in_range
+ { :in => (@options[:in].first..@options[:in].last).inspect }
+ elsif @options[:in].is_a?(Array)
+ { :in => array_to_sentence(@options[:in], true, '[]') }
+ else
+ { :in => @options[:in].inspect }
+ end
+
+ options.merge!(:behavior => @behavior.to_s)
+ end
+
+ end
+
+ # Ensures that the attribute can be set to the given values.
+ #
+ # == Options
+ #
+ # * <tt>:allow_nil</tt> - when supplied, validates if it allows nil or not.
+ # * <tt>:allow_blank</tt> - when supplied, validates if it allows blank or not.
+ # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
+ # Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.invalid')</tt>
+ #
+ # == Examples
+ #
+ # should_allow_values_for :isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0"
+ # it { should allow_values_for(:isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0") }
+ #
+ def allow_values_for(attribute, *args, &block)
+ options = args.extract_options!
+ AllowValuesForMatcher.new(attribute, options.merge!(:in => args), &block).spec(self)
+ end
+
+ end
+ end
+end
View
22 locales/en.yml
@@ -1,6 +1,26 @@
en:
remarkable:
mongo_mapper:
+ describe:
+ each: "{{key}} is {{value}}"
+ prepend: "when "
+ connector: " and "
+ expectations:
+ allow_nil: "{{subject_name}} to {{not}}allow nil values for {{attribute}}"
+ allow_blank: "{{subject_name}} to {{not}}allow blank values for {{attribute}}"
+ optionals:
+ allow_nil:
+ positive: "allowing nil values"
+ negative: "not allowing nil values"
+ allow_blank:
+ positive: "allowing blank values"
+ negative: "not allowing blank values"
+
+ allow_values_for:
+ description: "allow {{in}} as values for {{attributes}}"
+ expectations:
+ is_valid: "{{subject_name}} to be valid when {{attribute}} is set to {{value}}"
+
association:
many: have many
belongs_to: belong to
@@ -12,7 +32,7 @@ en:
options_match: "{{subject_name}} records {{type}} {{association}} with options {{options}}, got {{actual}}"
have_key:
- description: "have key(s) {{attributes}}"
+ description: "have key(s) {{attributes}} with type {{type}}"
expectations:
has_key: "{{subject_name}} to have key named {{attribute}} with type {{type}}"
View
55 spec/matchers/allow_values_for_matcher_spec.rb
@@ -0,0 +1,55 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe 'allow_values_for' do
+ subject do
+ Site.new
+ end
+
+ describe 'messages' do
+ before(:each){ @model = subject; @matcher = allow_values_for(:title) }
+
+ it 'should contain a description' do
+ @matcher = allow_values_for(:title, "X", "Y", "Z")
+ @matcher.description.should == 'allow "X", "Y", and "Z" as values for title'
+ end
+
+ it 'should set is_valid? message' do
+ @matcher.in("A").matches?(subject)
+ @matcher.failure_message.should == 'Expected Site to be valid when title is set to "A"'
+ end
+
+ it 'should set allow_nil? message' do
+ @matcher.allow_nil.matches?(subject)
+ @matcher.failure_message.should == 'Expected Site to allow nil values for title'
+ end
+
+ it 'should set allow_blank? message' do
+ @matcher.allow_blank.matches?(subject)
+ @matcher.failure_message.should == 'Expected Site to allow blank values for title'
+ end
+ end
+
+ describe 'matchers' do
+ it { should allow_values_for(:title).in('X', 'Y', 'Z') }
+ it { should_not allow_values_for(:title).in('A') }
+
+ # it { should define_and_validate(:with => /X|Y|Z/, :message => 'valid').in('X', 'Y', 'Z').message('valid') }
+
+ # create_optional_boolean_specs(:allow_nil, self, :with => /X|Y|Z/)
+ # create_optional_boolean_specs(:allow_blank, self, :with => /X|Y|Z/)
+ end
+
+ describe 'macros' do
+ should_allow_values_for :title, 'X'
+ should_not_allow_values_for :title, 'A'
+ end
+
+ describe 'failures' do
+ it "should fail if any of the values are valid on invalid cases" do
+ lambda {
+ should_not allow_values_for :title, 'A', 'X', 'B'
+ }.should raise_error(Spec::Expectations::ExpectationNotMetError, /Did not expect Site to be valid/)
+ end
+ end
+end
+
View
4 spec/models.rb
@@ -34,7 +34,9 @@ class Rating
end
class Site
- include MongoMapper::EmbeddedDocument
+ include MongoMapper::Document
+
+ key :title, String, :format => /X|Y|Z/
end
class Webiste
Please sign in to comment.
Something went wrong with that request. Please try again.