Module: Remarkable::ActiveRecord::Matchers

Defined in:
lib/remarkable_activerecord/matchers/have_index_matcher.rb,
lib/remarkable_activerecord/matchers/have_scope_matcher.rb,
lib/remarkable_activerecord/matchers/association_matcher.rb,
lib/remarkable_activerecord/matchers/have_column_matcher.rb,
lib/remarkable_activerecord/matchers/allow_values_for_matcher.rb,
lib/remarkable_activerecord/matchers/validate_length_of_matcher.rb,
lib/remarkable_activerecord/matchers/validate_associated_matcher.rb,
lib/remarkable_activerecord/matchers/validate_presence_of_matcher.rb,
lib/remarkable_activerecord/matchers/validate_exclusion_of_matcher.rb,
lib/remarkable_activerecord/matchers/validate_inclusion_of_matcher.rb,
lib/remarkable_activerecord/matchers/validate_acceptance_of_matcher.rb,
lib/remarkable_activerecord/matchers/validate_uniqueness_of_matcher.rb,
lib/remarkable_activerecord/matchers/allow_mass_assignment_of_matcher.rb,
lib/remarkable_activerecord/matchers/have_readonly_attributes_matcher.rb,
lib/remarkable_activerecord/matchers/validate_confirmation_of_matcher.rb,
lib/remarkable_activerecord/matchers/validate_numericality_of_matcher.rb

Defined Under Namespace

Classes: AllowMassAssignmentOfMatcher, AllowValuesForMatcher, AssociationMatcher, HaveColumnMatcher, HaveIndexMatcher, HaveReadonlyAttributesMatcher, HaveScopeMatcher, ValidateAcceptanceOfMatcher, ValidateAssociatedMatcher, ValidateConfirmationOfMatcher, ValidateExclusionOfMatcher, ValidateInclusionOfMatcher, ValidateLengthOfMatcher, ValidateNumericalityOfMatcher, ValidatePresenceOfMatcher, ValidateUniquenessOfMatcher

Instance Method Summary collapse

Instance Method Details

#allow_mass_assignment_of(*attributes) ⇒ Object

Ensures that the attribute can be set on mass update.

Examples

should_allow_mass_assignment_of :email, :name
it { should allow_mass_assignment_of(:email, :name) }


29
30
31
# File 'lib/remarkable_activerecord/matchers/allow_mass_assignment_of_matcher.rb', line 29

def allow_mass_assignment_of(*attributes)
  AllowMassAssignmentOfMatcher.new(*attributes).spec(self)
end

#allow_values_for(attribute, *args) ⇒ Object Also known as: validate_format_of

Ensures that the attribute can be set to the given values.

Note: this matcher accepts at once just one attribute to test. Note: this matcher is also aliased as “validate_format_of”.

Options

  • :allow_nil - when supplied, validates if it allows nil or not.

  • :allow_blank - when supplied, validates if it allows blank or not.

  • :message - value the test expects to find in errors.on(:attribute). Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.invalid')

Examples

should_allow_values_for :isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0"
should_not_allow_values_for :isbn, "bad 1", "bad 2"

it { should allow_values_for(:isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0") }
it { should_not allow_values_for(:isbn, "bad 1", "bad 2") }


86
87
88
89
# File 'lib/remarkable_activerecord/matchers/allow_values_for_matcher.rb', line 86

def allow_values_for(attribute, *args)
  options = args.extract_options!
  AllowValuesForMatcher.new(attribute, options.merge!(:in => args)).spec(self)
end

#belong_to(*associations) ⇒ Object

Ensure that the belongs_to relationship exists. Will also test that the subject table has the association_id column.

Options

  • :class_name - the expected associted class name.

  • :foreign_key - the expected foreign key in the subject table.

  • :dependent - the expected dependent value for the association.

  • :readonly - checks wether readonly is true or false.

  • :validate - checks wether validate is true or false.

  • :autosave - checks wether autosave is true or false.

  • :counter_cache - the expected dependent value for the association. It also checks if the column actually exists in the table.

  • :polymorphic - if the association should be polymorphic or not. When true it also checks for the association_type column in the subject table.

Examples

should_belong_to :parent, :polymorphic => true
it { should belong_to(:parent) }


152
153
154
# File 'lib/remarkable_activerecord/matchers/association_matcher.rb', line 152

def belong_to(*associations)
  AssociationMatcher.new(:belongs_to, *associations).spec(self)
end

#have_and_belong_to_many(*associations) ⇒ Object

Ensures that the has_and_belongs_to_many relationship exists, if the join table is in place and if the foreign_key column exists.

Options

  • :class_name - the expected associted class name.

  • :join_table - the expected join table name.

  • :foreign_key - the expected foreign key in the association table.

  • :uniq - checks wether uniq is true or false.

  • :readonly - checks wether readonly is true or false.

  • :validate - checks wether validate is true or false.

  • :autosave - checks wether autosave is true or false.

Examples

should_have_and_belong_to_many :posts, :cars
it{ should have_and_belong_to_many :posts, :cars }


174
175
176
# File 'lib/remarkable_activerecord/matchers/association_matcher.rb', line 174

def have_and_belong_to_many(*associations)
  AssociationMatcher.new(:has_and_belongs_to_many, *associations).spec(self)
end

#have_column(*args) ⇒ Object Also known as: have_columns, have_db_column, have_db_columns

Ensures that a column of the database actually exists.

Options

  • All options available in migrations are available:

    :type, :default, :precision, :limit, :scale, :sql_type, :primary, :null

Examples

should_have_column :name, :type => :string, :default => ''

it { should have_column(:name, :type => :string) }
it { should have_column(:name).type(:string) }


59
60
61
# File 'lib/remarkable_activerecord/matchers/have_column_matcher.rb', line 59

def have_column(*args)
  HaveColumnMatcher.new(*args).spec(self)
end

#have_index(*args) ⇒ Object Also known as: have_indices, have_db_index, have_db_indices

Ensures the database column has specified index.

Options

  • unique - when supplied, tests if the index is unique or not

Examples

it { should have_index(:ssn).unique(true) }
it { should have_index([:name, :email]).unique(true) }


48
49
50
# File 'lib/remarkable_activerecord/matchers/have_index_matcher.rb', line 48

def have_index(*args)
  HaveIndexMatcher.new(*args).spec(self)
end

#have_many(*associations) ⇒ Object

Ensures that the has_many relationship exists. Will also test that the associated table has the required columns. It works by default with polymorphic association (:as does not have to be supplied).

Options

  • :class_name - the expected associted class name.

  • :through - the expected join model which to perform the query. It also checks if the through table exists.

  • :foreign_key - the expected foreign key in the associated table. When used with :through, it will check for the foreign key in the join table.

  • :dependent - the expected dependent value for the association.

  • :uniq - checks wether uniq is true or false.

  • :readonly - checks wether readonly is true or false.

  • :validate - checks wether validate is true or false.

  • :autosave - checks wether autosave is true or false.

Examples

should_have_many :friends
should_have_many :enemies, :through => :friends
should_have_many :enemies, :dependent => :destroy

it{ should have_many(:friends) }
it{ should have_many(:enemies, :through => :friends) }
it{ should have_many(:enemies, :dependent => :destroy) }


205
206
207
# File 'lib/remarkable_activerecord/matchers/association_matcher.rb', line 205

def have_many(*associations)
  AssociationMatcher.new(:has_many, *associations).spec(self)
end

#have_one(*associations) ⇒ Object

Ensures that the has_many relationship exists. Will also test that the associated table has the required columns. It works by default with polymorphic association (:as does not have to be supplied).

Options

  • :class_name - the expected associted class name.

  • :through - the expected join model which to perform the query. It also checks if the through table exists.

  • :foreign_key - the expected foreign key in the associated table. When used with :through, it will check for the foreign key in the join table.

  • :dependent - the expected dependent value for the association.

  • :validate - checks wether validate is true or false.

  • :autosave - checks wether autosave is true or false.

Examples

should_have_one :universe
it{ should have_one(:universe) }


229
230
231
# File 'lib/remarkable_activerecord/matchers/association_matcher.rb', line 229

def have_one(*associations)
  AssociationMatcher.new(:has_one, *associations).spec(self)
end

#have_readonly_attributes(*attributes) ⇒ Object Also known as: have_readonly_attribute

Ensures that the attribute cannot be changed once the record has been created.

Examples

it { should have_readonly_attributes(:password, :admin_flag) }


23
24
25
# File 'lib/remarkable_activerecord/matchers/have_readonly_attributes_matcher.rb', line 23

def have_readonly_attributes(*attributes)
  HaveReadonlyAttributesMatcher.new(*attributes).spec(self)
end

#have_scope(*args) ⇒ Object Also known as: have_named_scope

Ensures that the model has a method named scope that returns a NamedScope object with the supplied proxy options.

Options

  • with - Options to be sent to the named scope

And all other options that the named scope would pass on to find.

Examples

it { should have_scope(:visible, :conditions => {:visible => true}) }
it { should have_scope(:visible).conditions(:visible => true) }

Passes for

named_scope :visible, :conditions => {:visible => true}

Or for

def self.visible
  scoped(:conditions => {:visible => true})
end

You can test lambdas or methods that return ActiveRecord#scoped calls:

it { should have_scope(:recent, :with => 5) }
it { should have_scope(:recent, :with => 1) }

Passes for

named_scope :recent, lambda {|c| {:limit => c}}

Or for

def self.recent(c)
  scoped(:limit => c)
end


73
74
75
# File 'lib/remarkable_activerecord/matchers/have_scope_matcher.rb', line 73

def have_scope(*args)
  HaveScopeMatcher.new(*args).spec(self)
end

#validate_acceptance_of(*attributes) ⇒ Object

Ensures that the model cannot be saved if one of the attributes listed is not accepted.

Options

  • :accept - the expected value to be accepted.

  • :allow_nil - when supplied, validates if it allows nil or not.

  • :message - value the test expects to find in errors.on(:attribute). Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.accepted')

Examples

should_validate_acceptance_of :eula, :terms
should_validate_acceptance_of :eula, :terms, :accept => true

it { should validate_acceptance_of(:eula, :terms) }
it { should validate_acceptance_of(:eula, :terms, :accept => true) }


44
45
46
# File 'lib/remarkable_activerecord/matchers/validate_acceptance_of_matcher.rb', line 44

def validate_acceptance_of(*attributes)
  ValidateAcceptanceOfMatcher.new(*attributes).spec(self)
end

#validate_associated(*args, &block) ⇒ Object

Ensures that the model is invalid if one of the associations given is invalid. It tries to build the association automatically. In has_one and belongs_to cases, it will build it like this:

@model.build_association
@project.build_manager

In has_many and has_and_belongs_to_many to cases it will build it like this:

@model.association.build
@project.tasks.build

The object returned MUST be invalid and it’s likely the case, since the associated object is empty when calling build. However, if the associated object has to be manipulated to be invalid, you will have to give :builder as option or a block to manipulate it:

should_validate_associated(:tasks) do |project|
  project.tasks.build(:captcha => 'i_am_a_bot')
end

In the case above, the associated object task is only invalid when the captcha attribute is set. So we give a block to the matcher that tell exactly how to build an invalid object.

The example above can also be written as:

should_validate_associated :tasks, :builder => proc{ |p| p.tasks.build(:captcha => 'i_am_a_bot') }

Options

  • :builder - a proc to build the association

  • :message - value the test expects to find in errors.on(:attribute). Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.invalid')

Examples

should_validate_associated :tasks
should_validate_associated(:tasks){ |p| p.tasks.build(:captcha => 'i_am_a_bot') }
should_validate_associated :tasks, :builder => proc{ |p| p.tasks.build(:captcha => 'i_am_a_bot') }

it { should validate_associated(:tasks) }
it { should validate_associated(:tasks){ |p| p.tasks.build(:captcha => 'i_am_a_bot') } }
it { should validate_associated(:tasks, :builder => proc{ |p| p.tasks.build(:captcha => 'i_am_a_bot') }) }


94
95
96
# File 'lib/remarkable_activerecord/matchers/validate_associated_matcher.rb', line 94

def validate_associated(*args, &block)
  ValidateAssociatedMatcher.new(*args, &block).spec(self)
end

#validate_confirmation_of(*attributes) ⇒ Object

Ensures that the model cannot be saved if one of the attributes is not confirmed.

Options

  • :message - value the test expects to find in errors.on(:attribute). Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.confirmation')

Examples

should_validate_confirmation_of :email, :password

it { should validate_confirmation_of(:email, :password) }


38
39
40
# File 'lib/remarkable_activerecord/matchers/validate_confirmation_of_matcher.rb', line 38

def validate_confirmation_of(*attributes)
  ValidateConfirmationOfMatcher.new(*attributes).spec(self)
end

#validate_exclusion_of(*args) ⇒ Object

Ensures that given values are not valid for the attribute. If a range is given, ensures that the attribute is not valid in the given range.

Options

  • :in - values to test exclusion.

  • :allow_nil - when supplied, validates if it allows nil or not.

  • :allow_blank - when supplied, validates if it allows blank or not.

  • :message - value the test expects to find in errors.on(:attribute). Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.exclusion')

Examples

it { should validate_exclusion_of(:username, :in => ["admin", "user"]) }
it { should validate_exclusion_of(:age, :in => 30..60) }

should_validate_exclusion_of :username, :in => ["admin", "user"]
should_validate_exclusion_of :age, :in => 30..60


41
42
43
# File 'lib/remarkable_activerecord/matchers/validate_exclusion_of_matcher.rb', line 41

def validate_exclusion_of(*args)
  ValidateExclusionOfMatcher.new(*args).spec(self)
end

#validate_inclusion_of(*args) ⇒ Object

Ensures that given values are valid for the attribute. If a range is given, ensures that the attribute is valid in the given range.

Options

  • :in - values to test inclusion.

  • :allow_nil - when supplied, validates if it allows nil or not.

  • :allow_blank - when supplied, validates if it allows blank or not.

  • :message - value the test expects to find in errors.on(:attribute). Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.inclusion')

Examples

should_validate_inclusion_of :size, :in => ["S", "M", "L", "XL"]
should_validate_inclusion_of :age, :in => 18..100

it { should validate_inclusion_of(:size, :in => ["S", "M", "L", "XL"]) }
it { should validate_inclusion_of(:age, :in => 18..100) }


41
42
43
# File 'lib/remarkable_activerecord/matchers/validate_inclusion_of_matcher.rb', line 41

def validate_inclusion_of(*args)
  ValidateInclusionOfMatcher.new(*args).spec(self)
end

#validate_length_of(*attributes) ⇒ Object

Validates the length of the given attributes. You have also to supply one of the following options: minimum, maximum, is or within.

Note: this method is also aliased as validate_size_of.

Options

  • :minimum - The minimum size of the attribute.

  • :maximum - The maximum size of the attribute.

  • :is - The exact size of the attribute.

  • :within - A range specifying the minimum and maximum size of the attribute.

  • :in - A synonym(or alias) for :within.

  • :allow_nil - when supplied, validates if it allows nil or not.

  • :allow_blank - when supplied, validates if it allows blank or not.

  • :too_short - value the test expects to find in errors.on(:attribute) when attribute is too short. Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.too_short') % range.first

  • :too_long - value the test expects to find in errors.on(:attribute) when attribute is too long. Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.too_long') % range.last

  • :wrong_length - value the test expects to find in errors.on(:attribute) when attribute is the wrong length. Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.wrong_length') % range.last

  • :message - value the test expects to find in errors.on(:attribute). Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.wrong_length') % value

Gotcha

In Rails 2.3.x, when :message is supplied, it overwrites the messages supplied in :wrong_length, :too_short and :too_long. However, in earlier versions, Rails ignores the :message option.

Examples

should_validate_length_of :password, :within => 6..20
should_validate_length_of :password, :maximum => 20
should_validate_length_of :password, :minimum => 6
should_validate_length_of :age, :is => 18

it { should validate_length_of(:password).within(6..20) }
it { should validate_length_of(:password).maximum(20) }
it { should validate_length_of(:password).minimum(6) }
it { should validate_length_of(:age).is(18) }


118
119
120
# File 'lib/remarkable_activerecord/matchers/validate_length_of_matcher.rb', line 118

def validate_length_of(*attributes)
  ValidateLengthOfMatcher.new(*attributes).spec(self)
end

#validate_numericality_of(*attributes) ⇒ Object

Ensures that the given attributes accepts only numbers.

Options

  • :only_integer - when supplied, checks if it accepts only integers or not

  • :odd - when supplied, checks if it accepts only odd values or not

  • :even - when supplied, checks if it accepts only even values or not

  • :equal_to - when supplied, checks if attributes are only valid when equal to given value

  • :less_than - when supplied, checks if attributes are only valid when less than given value

  • :greater_than - when supplied, checks if attributes are only valid when greater than given value

  • :less_than_or_equal_to - when supplied, checks if attributes are only valid when less than or equal to given value

  • :greater_than_or_equal_to - when supplied, checks if attributes are only valid when greater than or equal to given value

  • :message - value the test expects to find in errors.on(:attribute). Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.not_a_number')

Examples

should_validate_numericality_of :age, :price
should_validate_numericality_of :price, :only_integer => false, :greater_than => 10

it { should validate_numericality_of(:age).odd }
it { should validate_numericality_of(:age).even }
it { should validate_numericality_of(:age).only_integer }
it { should validate_numericality_of(:age, :odd => true) }
it { should validate_numericality_of(:age, :even => true) }


177
178
179
# File 'lib/remarkable_activerecord/matchers/validate_numericality_of_matcher.rb', line 177

def validate_numericality_of(*attributes)
  ValidateNumericalityOfMatcher.new(*attributes).spec(self)
end

#validate_presence_of(*args) ⇒ Object

Ensures that the model cannot be saved if one of the attributes listed is not present.

Options

  • :message - value the test expects to find in errors.on(:attribute). Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.blank')

Examples

should_validate_presence_of :name, :phone_number
it { should validate_presence_of(:name, :phone_number) }


24
25
26
# File 'lib/remarkable_activerecord/matchers/validate_presence_of_matcher.rb', line 24

def validate_presence_of(*args)
  ValidatePresenceOfMatcher.new(*args).spec(self)
end

#validate_uniqueness_of(*attributes) ⇒ Object

Ensures that the model cannot be saved if one of the attributes listed is not unique.

Requires an existing record in the database. If you supply :allow_nil as option, you need to have in the database a record which is not nil in the given attributes. The same is required for allow_blank option.

Options

  • :scope - field(s) to scope the uniqueness to.

  • :case_sensitive - the matcher look for an exact match.

  • :allow_nil - when supplied, validates if it allows nil or not.

  • :allow_blank - when supplied, validates if it allows blank or not.

  • :message - value the test expects to find in errors.on(:attribute). Regexp, string or symbol. Default = I18n.translate('activerecord.errors.messages.taken')

Examples

it { should validate_uniqueness_of(:keyword, :username) }
it { should validate_uniqueness_of(:name, :message => "O NOES! SOMEONE STOELED YER NAME!") }
it { should validate_uniqueness_of(:email, :scope => :name, :case_sensitive => false) }
it { should validate_uniqueness_of(:address, :scope => [:first_name, :last_name]) }


146
147
148
# File 'lib/remarkable_activerecord/matchers/validate_uniqueness_of_matcher.rb', line 146

def validate_uniqueness_of(*attributes)
  ValidateUniquenessOfMatcher.new(*attributes).spec(self)
end