Permalink
Browse files

Added documentation for several matchers

  • Loading branch information...
1 parent a159fc5 commit 4ff07bceb43de87f6a972427a478a96c12af6d16 @jferris jferris committed Jan 24, 2009
View
23 lib/shoulda/active_record/matchers/allow_value_matcher.rb
@@ -1,8 +1,23 @@
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
- module Matchers # :nodoc:
+ module Matchers
+
+ # Ensures that the attribute can be set to the given value.
+ #
+ # Options:
+ # * <tt>with_message</tt> - value the test expects to find in
+ # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
+ # translation for :invalid.
+ #
+ # Example:
+ # it { should_not allow_value('bad').for(:isbn) }
+ # it { should allow_value("isbn 1 2345 6789 0").for(:isbn) }
+ #
+ def allow_value(value)
+ AllowValueMatcher.new(value)
+ end
- class AllowValueMatcher
+ class AllowValueMatcher # :nodoc:
include Helpers
def initialize(value)
@@ -82,10 +97,6 @@ def error_description
end
end
- def allow_value(value)
- AllowValueMatcher.new(value)
- end
-
end
end
end
View
4 lib/shoulda/active_record/matchers/association_matcher.rb
@@ -1,8 +1,8 @@
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
- module Matchers # :nodoc:
+ module Matchers
- class AssociationMatcher
+ class AssociationMatcher # :nodoc:
def initialize(macro, name)
@macro = macro
@name = name
View
97 lib/shoulda/active_record/matchers/database_matcher.rb
@@ -0,0 +1,97 @@
+module Shoulda # :nodoc:
+ module ActiveRecord # :nodoc:
+ module Matchers
+
+ class DatabaseMatcher # :nodoc:
+ def initialize(macro, column)
+ @macro = macro
+ @column = column
+ end
+
+ def column_type(column_type)
+ @column_type = column_type
+ self
+ end
+
+ def precision(precision)
+ @precision = precision
+ self
+ end
+
+ def matches?(subject)
+ @subject = subject
+ column_exists? && correct_column_type? && correct_precision?
+ end
+
+ def failure_message
+ "Expected #{expectation}"
+ end
+
+ def negative_failure_message
+ "Did not expect #{expectation}"
+ end
+
+ def description
+ "#{macro_description} #{@column}"
+ end
+
+ protected
+
+ def column_exists?
+ if model_class.column_names.include?(@column.to_s)
+ true
+ else
+ @missing = "#{model_class} does not have a db column named #{@column}."
+ false
+ end
+ end
+
+ def correct_column_type?
+ return true unless @column_type
+ if matched_column.type.to_s == @column_type.to_s
+ true
+ else
+ @missing = "#{model_class} has a db column named #{@column} " <<
+ "of type #{matched_column.type}, not #{@column_type}."
+ false
+ end
+ end
+
+ def correct_precision?
+ return true unless @precision
+ if matched_column.precision.to_s == @precision.to_s
+ true
+ else
+ @missing = "#{model_class} has a db column named #{@column} " <<
+ "of precision #{matched_column.precision}, " <<
+ "not #{@precision}."
+ false
+ end
+ end
+
+ def matched_column
+ model_class.columns.detect { |each| each.name == @column.to_s }
+ end
+
+ def model_class
+ @subject.class
+ end
+
+ def expectation
+ "#{model_class.name} to have a db column named #{@column}"
+ end
+
+ def macro_description
+ case @macro.to_s
+ when 'has_db_column' then 'has db column'
+ end
+ end
+ end
+
+ def has_db_column(column)
+ DatabaseMatcher.new(:has_db_column, column)
+ end
+
+ end
+ end
+end
View
26 lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb
@@ -1,8 +1,26 @@
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
- module Matchers # :nodoc:
+ module Matchers
+
+ # Ensure that the attribute's value is in the range specified
+ #
+ # Options:
+ # * <tt>in_range</tt> - the range of allowed values for this attribute
+ # * <tt>with_low_message</tt> - value the test expects to find in
+ # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
+ # translation for :inclusion.
+ # * <tt>with_high_message</tt> - value the test expects to find in
+ # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
+ # translation for :inclusion.
+ #
+ # Example:
+ # it { should ensure_inclusion_of(:age).in_range(0..100) }
+ #
+ def ensure_inclusion_of(attr)
+ EnsureInclusionOfMatcher.new(attr)
+ end
- class EnsureInclusionOfMatcher < ValidationMatcher
+ class EnsureInclusionOfMatcher < ValidationMatcher # :nodoc:
def in_range(range)
@range = range
@@ -64,10 +82,6 @@ def allows_maximum_value
end
end
- def ensure_inclusion_of(attr)
- EnsureInclusionOfMatcher.new(attr)
- end
-
end
end
end
View
39 lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb
@@ -1,8 +1,39 @@
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
- module Matchers # :nodoc:
+ module Matchers
+
+ # Ensures that the length of the attribute is validated.
+ #
+ # Options:
+ # * <tt>is_at_least</tt> - minimum length of this attribute
+ # * <tt>is_at_most</tt> - maximum length of this attribute
+ # * <tt>is_equal_to</tt> - exact requred length of this attribute
+ # * <tt>with_short_message</tt> - value the test expects to find in
+ # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
+ # translation for :too_short.
+ # * <tt>with_long_message</tt> - value the test expects to find in
+ # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
+ # translation for :too_long.
+ # * <tt>with_message</tt> - value the test expects to find in
+ # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
+ # translation for :wrong_length. Used in conjunction with
+ # <tt>is_equal_to</tt>.
+ #
+ # Examples:
+ # it { should ensure_length_of(:password).
+ # is_at_least(6).
+ # is_at_most(20) }
+ # it { should ensure_length_of(:name).
+ # is_at_least(3).
+ # with_short_message(/not long enough/) }
+ # it { should ensure_length_of(:ssn).
+ # is_equal_to(9).
+ # with_message(/is invalid/) }
+ def ensure_length_of(attr)
+ EnsureLengthOfMatcher.new(attr)
+ end
- class EnsureLengthOfMatcher < ValidationMatcher
+ class EnsureLengthOfMatcher < ValidationMatcher # :nodoc:
include Helpers
def is_at_least(length)
@@ -105,10 +136,6 @@ def string_of_length(length)
end
end
- def ensure_length_of(attr)
- EnsureLengthOfMatcher.new(attr)
- end
-
end
end
end
View
4 lib/shoulda/active_record/matchers/have_named_scope_matcher.rb
@@ -1,8 +1,8 @@
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
- module Matchers # :nodoc:
+ module Matchers
- class HaveNamedScopeMatcher
+ class HaveNamedScopeMatcher # :nodoc:
def initialize(scope_call)
@scope_call = scope_call.to_s
View
17 lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb
@@ -1,8 +1,17 @@
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
- module Matchers # :nodoc:
+ module Matchers
- class HaveReadonlyAttributeMatcher
+ # Ensures that the attribute cannot be changed once the record has been
+ # created.
+ #
+ # it { should have_readonly_attributes(:password) }
+ #
+ def have_readonly_attribute(value)
+ HaveReadonlyAttributeMatcher.new(value)
+ end
+
+ class HaveReadonlyAttributeMatcher # :nodoc:
def initialize(attribute)
@attribute = attribute.to_s
@@ -45,10 +54,6 @@ def class_name
end
- def have_readonly_attribute(value)
- HaveReadonlyAttributeMatcher.new(value)
- end
-
end
end
end
View
4 lib/shoulda/active_record/matchers/only_allow_numeric_values_matcher.rb
@@ -1,8 +1,8 @@
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
- module Matchers # :nodoc:
+ module Matchers
- class OnlyAllowNumericValuesMatcher < ValidationMatcher
+ class OnlyAllowNumericValuesMatcher < ValidationMatcher # :nodoc:
def with_message(message)
@expected_message = message if message
View
16 lib/shoulda/active_record/matchers/protect_attribute_matcher.rb
@@ -1,8 +1,16 @@
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
- module Matchers # :nodoc:
+ module Matchers
- class ProtectAttributeMatcher
+ # Ensures that the attribute cannot be set on mass update.
+ #
+ # it { should protect_attribute(:password) }
+ #
+ def protect_attribute(value)
+ ProtectAttributeMatcher.new(value)
+ end
+
+ class ProtectAttributeMatcher # :nodoc:
def initialize(attribute)
@attribute = attribute.to_s
@@ -69,10 +77,6 @@ def class_name
end
- def protect_attribute(value)
- ProtectAttributeMatcher.new(value)
- end
-
end
end
end
View
4 lib/shoulda/active_record/matchers/require_acceptance_of_matcher.rb
@@ -1,8 +1,8 @@
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
- module Matchers # :nodoc:
+ module Matchers
- class RequireAcceptanceOfMatcher < ValidationMatcher
+ class RequireAcceptanceOfMatcher < ValidationMatcher # :nodoc:
def with_message(message)
@expected_message = message if message
View
25 lib/shoulda/active_record/matchers/require_attribute_matcher.rb
@@ -1,8 +1,25 @@
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
- module Matchers # :nodoc:
+ module Matchers
+
+ # Ensures that the model is not valid if the given attribute is not
+ # present.
+ #
+ # Options:
+ # * <tt>with_message</tt> - value the test expects to find in
+ # <tt>errors.on(:attribute)</tt>. <tt>Regexp</tt> or <tt>String</tt>.
+ # Defaults to the translation for <tt>:blank</tt>.
+ #
+ # Examples:
+ # it { should require_attribute(:name) }
+ # it { should require_attribute(:name).with_message(/is not optional/) }
+ #
+ def require_attribute(attr)
+ RequireAttributeMatcher.
+ new(attr)
+ end
- class RequireAttributeMatcher < ValidationMatcher
+ class RequireAttributeMatcher < ValidationMatcher # :nodoc:
def with_message(message)
@expected_message = message if message
@@ -38,10 +55,6 @@ def collection?
end
end
- def require_attribute(attr)
- RequireAttributeMatcher.
- new(attr)
- end
end
end
end
View
40 lib/shoulda/active_record/matchers/require_unique_attribute_matcher.rb
@@ -1,8 +1,40 @@
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
- module Matchers # :nodoc:
+ module Matchers
+
+ # Ensures that the model is invalid if the given attribute is not unique.
+ #
+ # Internally, this uses values from existing records to test validations,
+ # so this will always fail if you have not saved at least one record for
+ # the model being tested, like so:
+ #
+ # describe User do
+ # before(:each) { User.create!(:email => 'address@example.com') }
+ # it { should require_unique_attribute(:email) }
+ # end
+ #
+ # Options:
+ #
+ # * <tt>with_message</tt> - value the test expects to find in
+ # <tt>errors.on(:attribute)</tt>. <tt>Regexp</tt> or <tt>String</tt>.
+ # Defaults to the translation for <tt>:taken</tt>.
+ # * <tt>scoped_to</tt> - field(s) to scope the uniqueness to.
+ # * <tt>case_insensitive</tt> - ensures that the validation does not
+ # check case. Off by default. Ignored by non-text attributes.
+ #
+ # Examples:
+ # it { should require_unique_attribute(:keyword) }
+ # it { should require_unique_attribute(:keyword).with_message(/dup/) }
+ # it { should require_unique_attribute(:email).scoped_to(:name) }
+ # it { should require_unique_attribute(:email).
+ # scoped_to(:first_name, :last_name) }
+ # it { should require_unique_attribute(:keyword).case_insensitive }
+ #
+ def require_unique_attribute(attr)
+ RequireUniqueAttributeMatcher.new(attr)
+ end
- class RequireUniqueAttributeMatcher < ValidationMatcher
+ class RequireUniqueAttributeMatcher < ValidationMatcher # :nodoc:
include Helpers
def initialize(attribute)
@@ -111,10 +143,6 @@ def existing_value
end
end
- def require_unique_attribute(attr)
- RequireUniqueAttributeMatcher.new(attr)
- end
-
end
end
end
View
4 lib/shoulda/active_record/matchers/validation_matcher.rb
@@ -1,8 +1,8 @@
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
- module Matchers # :nodoc:
+ module Matchers
- class ValidationMatcher
+ class ValidationMatcher # :nodoc:
attr_reader :failure_message

0 comments on commit 4ff07bc

Please sign in to comment.