Module: Shoulda::Matchers::ActiveModel
Instance Method Summary (collapse)
-
- (AllowMassAssignmentOfMatcher) allow_mass_assignment_of(value)
The
allow_mass_assignment_of
matcher tests usage of Rails 3'sattr_accessible
andattr_protected
macros, asserting that an attribute in your model is contained in either the whitelist or blacklist and thus can or cannot be set via mass assignment. -
- (AllowValueMatcher) allow_value(*values)
(also: #allow_values)
The
allow_value
matcher is used to test that an attribute of a model can or cannot be set to a particular value or values. -
- (HaveSecurePasswordMatcher) have_secure_password
The
have_secure_password
matcher tests usage of thehas_secure_password
macro. -
- (ValidateAbsenceOfMatcher) validate_absence_of(attr)
The
validate_absence_of
matcher tests the usage of thevalidates_absence_of
validation. -
- (ValidateAcceptanceOfMatcher) validate_acceptance_of(attr)
The
validate_acceptance_of
matcher tests usage of thevalidates_acceptance_of
validation. -
- (ValidateConfirmationOfMatcher) validate_confirmation_of(attr)
The
validate_confirmation_of
matcher tests usage of thevalidates_confirmation_of
validation. -
- (ValidateExclusionOfMatcher) validate_exclusion_of(attr)
The
validate_exclusion_of
matcher tests usage of thevalidates_exclusion_of
validation, asserting that an attribute cannot take a blacklist of values, and inversely, can take values outside of this list. -
- (ValidateInclusionOfMatcher) validate_inclusion_of(attr)
The
validate_inclusion_of
matcher tests usage of thevalidates_inclusion_of
validation, asserting that an attribute can take a whitelist of values and cannot take values outside of this list. -
- (ValidateLengthOfMatcher) validate_length_of(attr)
The
validate_length_of
matcher tests usage of thevalidates_length_of
matcher. -
- (ValidateNumericalityOfMatcher) validate_numericality_of(attr)
The
validate_numericality_of
matcher tests usage of thevalidates_numericality_of
validation. -
- (ValidatePresenceOfMatcher) validate_presence_of(attr)
The
validate_presence_of
matcher tests usage of thevalidates_presence_of
validation.
Instance Method Details
- (AllowMassAssignmentOfMatcher) allow_mass_assignment_of(value)
The allow_mass_assignment_of
matcher tests usage of Rails 3's
attr_accessible
and attr_protected
macros, asserting that an
attribute in your model is contained in either the whitelist or
blacklist and thus can or cannot be set via mass assignment.
class Post
include ActiveModel::Model
include ActiveModel::MassAssignmentSecurity
attr_accessor :title
attr_accessible :title
end
class User
include ActiveModel::Model
include ActiveModel::MassAssignmentSecurity
attr_accessor :encrypted_password
attr_protected :encrypted_password
end
# RSpec
describe Post do
it { should allow_mass_assignment_of(:title) }
end
describe User do
it { should_not allow_mass_assignment_of(:encrypted_password) }
end
# Test::Unit
class PostTest < ActiveSupport::TestCase
should allow_mass_assignment_of(:title)
end
class UserTest < ActiveSupport::TestCase
should_not allow_mass_assignment_of(:encrypted_password)
end
Optional qualifiers
as
Use as
if your mass-assignment rules apply only under a certain role
(Rails >= 3.1 only).
class Post
include ActiveModel::Model
include ActiveModel::MassAssignmentSecurity
attr_accessor :title
attr_accessible :title, as: :admin
end
# RSpec
describe Post do
it { should allow_mass_assignment_of(:title).as(:admin) }
end
# Test::Unit
class PostTest < ActiveSupport::TestCase
should allow_mass_assignment_of(:title).as(:admin)
end
70 71 72 |
# File 'lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb', line 70 def allow_mass_assignment_of(value) AllowMassAssignmentOfMatcher.new(value) end |
- (AllowValueMatcher) allow_value(*values) Also known as: allow_values
The allow_value
matcher is used to test that an attribute of a model
can or cannot be set to a particular value or values. It is most
commonly used in conjunction with the validates_format_of
validation.
should
In the positive form, allow_value
asserts that an attribute can be
set to one or more values, succeeding if none of the values cause the
record to be invalid:
class UserProfile
include ActiveModel::Model
attr_accessor :website_url
validates_format_of :website_url, with: URI.regexp
end
# RSpec
describe UserProfile do
it do
should allow_value('http://foo.com', 'http://bar.com/baz').
for(:website_url)
end
end
# Test::Unit
class UserProfileTest < ActiveSupport::TestCase
should allow_value('http://foo.com', 'http://bar.com/baz').
for(:website_url)
end
should_not
In the negative form, allow_value
asserts that an attribute cannot be
set to one or more values, succeeding if the first value causes the
record to be invalid.
This can be surprising so in this case if you need to check that all of the values are invalid, use separate assertions:
class UserProfile
include ActiveModel::Model
attr_accessor :website_url
validates_format_of :website_url, with: URI.regexp
end
describe UserProfile do
# One assertion: 'buz' and 'bar' will not be tested
it { should_not allow_value('fiz', 'buz', 'bar').for(:website_url) }
# Three assertions, all tested separately
it { should_not allow_value('fiz').for(:website_url) }
it { should_not allow_value('buz').for(:website_url) }
it { should_not allow_value('bar').for(:website_url) }
end
Qualifiers
on
Use on
if your validation applies only under a certain context.
class UserProfile
include ActiveModel::Model
attr_accessor :birthday_as_string
validates_format_of :birthday_as_string,
with: /^(\d+)-(\d+)-(\d+)$/,
on: :create
end
# RSpec
describe UserProfile do
it do
should allow_value('2013-01-01').
for(:birthday_as_string).
on(:create)
end
end
# Test::Unit
class UserProfileTest < ActiveSupport::TestCase
should allow_value('2013-01-01').
for(:birthday_as_string).
on(:create)
end
with_message
Use with_message
if you are using a custom validation message.
class UserProfile
include ActiveModel::Model
attr_accessor :state
validates_format_of :state,
with: /^(open|closed)$/,
message: 'State must be open or closed'
end
# RSpec
describe UserProfile do
it do
should allow_value('open', 'closed').
for(:state).
with_message('State must be open or closed')
end
end
# Test::Unit
class UserProfileTest < ActiveSupport::TestCase
should allow_value('open', 'closed').
for(:state).
with_message('State must be open or closed')
end
Use with_message
with a regexp to perform a partial match:
class UserProfile
include ActiveModel::Model
attr_accessor :state
validates_format_of :state,
with: /^(open|closed)$/,
message: 'State must be open or closed'
end
# RSpec
describe UserProfile do
it do
should allow_value('open', 'closed').
for(:state).
with_message(/open or closed/)
end
end
# Test::Unit
class UserProfileTest < ActiveSupport::TestCase
should allow_value('open', 'closed').
for(:state).
with_message(/open or closed/)
end
Use with_message
with the :against
option if the attribute the
validation message is stored under is different from the attribute
being validated:
class UserProfile
include ActiveModel::Model
attr_accessor :sports_team
validate :sports_team_must_be_valid
private
def sports_team_must_be_valid
if sports_team !~ /^(Broncos|Titans)$/i
self.errors.add :chosen_sports_team,
'Must be either a Broncos fan or a Titans fan'
end
end
end
# RSpec
describe UserProfile do
it do
should allow_value('Broncos', 'Titans').
for(:sports_team).
with_message('Must be either a Broncos or Titans fan',
against: :chosen_sports_team
)
end
end
# Test::Unit
class UserProfileTest < ActiveSupport::TestCase
should allow_value('Broncos', 'Titans').
for(:sports_team).
with_message('Must be either a Broncos or Titans fan',
against: :chosen_sports_team
)
end
190 191 192 193 194 195 196 |
# File 'lib/shoulda/matchers/active_model/allow_value_matcher.rb', line 190 def allow_value(*values) if values.empty? raise ArgumentError, 'need at least one argument' else AllowValueMatcher.new(*values) end end |
- (HaveSecurePasswordMatcher) have_secure_password
The have_secure_password
matcher tests usage of the
has_secure_password
macro.
Example
class User
include ActiveModel::Model
include ActiveModel::SecurePassword
attr_accessor :password
has_secure_password
end
# RSpec
describe User do
it { should have_secure_password }
end
# Test::Unit
class UserTest < ActiveSupport::TestCase
should have_secure_password
end
29 30 31 |
# File 'lib/shoulda/matchers/active_model/have_secure_password_matcher.rb', line 29 def have_secure_password HaveSecurePasswordMatcher.new end |
- (ValidateAbsenceOfMatcher) validate_absence_of(attr)
The validate_absence_of
matcher tests the usage of the
validates_absence_of
validation.
class Artillery
include ActiveModel::Model
attr_accessor :arms
validates_absence_of :arms
end
# RSpec
describe Artillery do
it { should validate_absence_of(:arms) }
end
# Test::Unit
class ArtilleryTest < ActiveSupport::TestCase
should validate_absence_of(:arms)
end
Qualifiers
on
Use on
if your validation applies only under a certain context.
class Artillery
include ActiveModel::Model
attr_accessor :arms
validates_absence_of :arms, on: :create
end
# RSpec
describe Artillery do
it { should validate_absence_of(:arms).on(:create) }
end
# Test::Unit
class ArtilleryTest < ActiveSupport::TestCase
should validate_absence_of(:arms).on(:create)
end
with_message
Use with_message
if you are using a custom validation message.
class Artillery
include ActiveModel::Model
attr_accessor :arms
validates_absence_of :arms,
message: "We're fresh outta arms here, soldier!"
end
# RSpec
describe Artillery do
it do
should validate_absence_of(:arms).
with_message("We're fresh outta arms here, soldier!")
end
end
# Test::Unit
class ArtilleryTest < ActiveSupport::TestCase
should validate_absence_of(:arms).
with_message("We're fresh outta arms here, soldier!")
end
75 76 77 |
# File 'lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb', line 75 def validate_absence_of(attr) ValidateAbsenceOfMatcher.new(attr) end |
- (ValidateAcceptanceOfMatcher) validate_acceptance_of(attr)
The validate_acceptance_of
matcher tests usage of the
validates_acceptance_of
validation.
class Registration
include ActiveModel::Model
attr_accessor :eula
validates_acceptance_of :eula
end
# RSpec
describe Registration do
it { should validate_acceptance_of(:eula) }
end
# Test::Unit
class RegistrationTest < ActiveSupport::TestCase
should validate_acceptance_of(:eula)
end
Qualifiers
on
Use on
if your validation applies only under a certain context.
class Registration
include ActiveModel::Model
attr_accessor :terms_of_service
validates_acceptance_of :terms_of_service, on: :create
end
# RSpec
describe Registration do
it do
should validate_acceptance_of(:terms_of_service).
on(:create)
end
end
# Test::Unit
class RegistrationTest < ActiveSupport::TestCase
should validate_acceptance_of(:terms_of_service).on(:create)
end
with_message
Use with_message
if you are using a custom validation message.
class Registration
include ActiveModel::Model
attr_accessor :terms_of_service
validates_acceptance_of :terms_of_service,
message: 'You must accept the terms of service'
end
# RSpec
describe Registration do
it do
should validate_acceptance_of(:terms_of_service).
with_message('You must accept the terms of service')
end
end
# Test::Unit
class RegistrationTest < ActiveSupport::TestCase
should validate_acceptance_of(:terms_of_service).
with_message('You must accept the terms of service')
end
78 79 80 |
# File 'lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb', line 78 def validate_acceptance_of(attr) ValidateAcceptanceOfMatcher.new(attr) end |
- (ValidateConfirmationOfMatcher) validate_confirmation_of(attr)
The validate_confirmation_of
matcher tests usage of the
validates_confirmation_of
validation.
class User
include ActiveModel::Model
attr_accessor :email
validates_confirmation_of :email
end
# RSpec
describe User do
it { should validate_confirmation_of(:email) }
end
# Test::Unit
class UserTest < ActiveSupport::TestCase
should validate_confirmation_of(:email)
end
Qualifiers
on
Use on
if your validation applies only under a certain context.
class User
include ActiveModel::Model
attr_accessor :password
validates_confirmation_of :password, on: :create
end
# RSpec
describe User do
it { should validate_confirmation_of(:password).on(:create) }
end
# Test::Unit
class UserTest < ActiveSupport::TestCase
should validate_confirmation_of(:password).on(:create)
end
with_message
Use with_message
if you are using a custom validation message.
class User
include ActiveModel::Model
attr_accessor :password
validates_confirmation_of :password,
message: 'Please re-enter your password'
end
# RSpec
describe User do
it do
should validate_confirmation_of(:password).
with_message('Please re-enter your password')
end
end
# Test::Unit
class UserTest < ActiveSupport::TestCase
should validate_confirmation_of(:password).
with_message('Please re-enter your password')
end
75 76 77 |
# File 'lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb', line 75 def validate_confirmation_of(attr) ValidateConfirmationOfMatcher.new(attr) end |
- (ValidateExclusionOfMatcher) validate_exclusion_of(attr)
The validate_exclusion_of
matcher tests usage of the
validates_exclusion_of
validation, asserting that an attribute cannot
take a blacklist of values, and inversely, can take values outside of
this list.
If your blacklist is an array of values, use in_array
:
class Game
include ActiveModel::Model
attr_accessor :supported_os
validates_exclusion_of :supported_os, in: ['Mac', 'Linux']
end
# RSpec
describe Game do
it do
should validate_exclusion_of(:supported_os).
in_array(['Mac', 'Linux'])
end
end
# Test::Unit
class GameTest < ActiveSupport::TestCase
should validate_exclusion_of(:supported_os).
in_array(['Mac', 'Linux'])
end
If your blacklist is a range of values, use in_range
:
class Game
include ActiveModel::Model
attr_accessor :supported_os
validates_exclusion_of :supported_os, in: ['Mac', 'Linux']
end
# RSpec
describe Game do
it do
should validate_exclusion_of(:floors_with_enemies).
in_range(5..8)
end
end
# Test::Unit
class GameTest < ActiveSupport::TestCase
should validate_exclusion_of(:floors_with_enemies).
in_range(5..8)
end
Qualifiers
on
Use on
if your validation applies only under a certain context.
class Game
include ActiveModel::Model
attr_accessor :weapon
validates_exclusion_of :weapon,
in: ['pistol', 'paintball gun', 'stick'],
on: :create
end
# RSpec
describe Game do
it do
should validate_exclusion_of(:weapon).
in_array(['pistol', 'paintball gun', 'stick']).
on(:create)
end
end
# Test::Unit
class GameTest < ActiveSupport::TestCase
should validate_exclusion_of(:weapon).
in_array(['pistol', 'paintball gun', 'stick']).
on(:create)
end
with_message
Use with_message
if you are using a custom validation message.
class Game
include ActiveModel::Model
attr_accessor :weapon
validates_exclusion_of :weapon,
in: ['pistol', 'paintball gun', 'stick'],
message: 'You chose a puny weapon'
end
# RSpec
describe Game do
it do
should validate_exclusion_of(:weapon).
in_array(['pistol', 'paintball gun', 'stick']).
with_message('You chose a puny weapon')
end
end
# Test::Unit
class GameTest < ActiveSupport::TestCase
should validate_exclusion_of(:weapon).
in_array(['pistol', 'paintball gun', 'stick']).
with_message('You chose a puny weapon')
end
117 118 119 |
# File 'lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb', line 117 def validate_exclusion_of(attr) ValidateExclusionOfMatcher.new(attr) end |
- (ValidateInclusionOfMatcher) validate_inclusion_of(attr)
The validate_inclusion_of
matcher tests usage of the
validates_inclusion_of
validation, asserting that an attribute can
take a whitelist of values and cannot take values outside of this list.
If your whitelist is an array of values, use in_array
:
class Issue
include ActiveModel::Model
attr_accessor :state
validates_inclusion_of :state, in: %w(open resolved unresolved)
end
# RSpec
describe Issue do
it do
should validate_inclusion_of(:state).
in_array(%w(open resolved unresolved))
end
end
# Test::Unit
class IssueTest < ActiveSupport::TestCase
should validate_inclusion_of(:state).
in_array(%w(open resolved unresolved))
end
If your whitelist is a range of values, use in_range
:
class Issue
include ActiveModel::Model
attr_accessor :priority
validates_inclusion_of :priority, in: 1..5
end
# RSpec
describe Issue do
it { should validate_inclusion_of(:state).in_range(1..5) }
end
# Test::Unit
class IssueTest < ActiveSupport::TestCase
should validate_inclusion_of(:state).in_range(1..5)
end
Caveats
We discourage using validate_inclusion_of
with boolean columns. In
fact, there is never a case where a boolean column will be anything but
true, false, or nil, as ActiveRecord will type-cast an incoming value to
one of these three values. That means there isn't any way we can refute
this logic in a test. Hence, this will produce a warning:
it { should validate_inclusion_of(:imported).in_array([true, false]) }
The only case where validate_inclusion_of
could be appropriate is
for ensuring that a boolean column accepts nil, but we recommend
using allow_value
instead, like this:
it { should allow_value(nil).for(:imported) }
Qualifiers
Use on
if your validation applies only under a certain context.
class Issue
include ActiveModel::Model
attr_accessor :severity
validates_inclusion_of :severity,
in: %w(low medium high),
on: :create
end
# RSpec
describe Issue do
it do
should validate_inclusion_of(:severity).
in_array(%w(low medium high)).
on(:create)
end
end
# Test::Unit
class IssueTest < ActiveSupport::TestCase
should validate_inclusion_of(:severity).
in_array(%w(low medium high)).
on(:create)
end
with_message
Use with_message
if you are using a custom validation message.
class Issue
include ActiveModel::Model
attr_accessor :severity
validates_inclusion_of :severity,
in: %w(low medium high),
message: 'Severity must be low, medium, or high'
end
# RSpec
describe Issue do
it do
should validate_inclusion_of(:severity).
in_array(%w(low medium high)).
with_message('Severity must be low, medium, or high')
end
end
# Test::Unit
class IssueTest < ActiveSupport::TestCase
should validate_inclusion_of(:severity).
in_array(%w(low medium high)).
with_message('Severity must be low, medium, or high')
end
with_low_message
Use with_low_message
if you have a custom validation message for when
a given value is too low.
class Person
include ActiveModel::Model
attr_accessor :age
validate :age_must_be_valid
private
def age_must_be_valid
if age < 65
self.errors.add :age, 'You do not receive any benefits'
end
end
end
# RSpec
describe Person do
it do
should validate_inclusion_of(:age).
in_range(0..65).
with_low_message('You do not receive any benefits')
end
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_inclusion_of(:age).
in_range(0..65).
with_low_message('You do not receive any benefits')
end
with_high_message
Use with_high_message
if you have a custom validation message for
when a given value is too high.
class Person
include ActiveModel::Model
attr_accessor :age
validate :age_must_be_valid
private
def age_must_be_valid
if age > 21
self.errors.add :age, "You're too old for this stuff"
end
end
end
# RSpec
describe Person do
it do
should validate_inclusion_of(:age).
in_range(0..21).
with_high_message("You're too old for this stuff")
end
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_inclusion_of(:age).
in_range(0..21).
with_high_message("You're too old for this stuff")
end
allow_nil
Use allow_nil
to assert that the attribute allows nil.
class Issue
include ActiveModel::Model
attr_accessor :state
validates_presence_of :state
validates_inclusion_of :state,
in: %w(open resolved unresolved),
allow_nil: true
end
# RSpec
describe Issue do
it do
should validate_inclusion_of(:state).
in_array(%w(open resolved unresolved)).
allow_nil
end
end
# Test::Unit
class IssueTest < ActiveSupport::TestCase
should validate_inclusion_of(:state).
in_array(%w(open resolved unresolved)).
allow_nil
end
allow_blank
Use allow_blank
to assert that the attribute allows blank.
class Issue
include ActiveModel::Model
attr_accessor :state
validates_presence_of :state
validates_inclusion_of :state,
in: %w(open resolved unresolved),
allow_blank: true
end
# RSpec
describe Issue do
it do
should validate_inclusion_of(:state).
in_array(%w(open resolved unresolved)).
allow_blank
end
end
# Test::Unit
class IssueTest < ActiveSupport::TestCase
should validate_inclusion_of(:state).
in_array(%w(open resolved unresolved)).
allow_blank
end
260 261 262 |
# File 'lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb', line 260 def validate_inclusion_of(attr) ValidateInclusionOfMatcher.new(attr) end |
- (ValidateLengthOfMatcher) validate_length_of(attr)
The validate_length_of
matcher tests usage of the
validates_length_of
matcher. Note that this matcher is intended to be
used against string columns and not integer columns.
Qualifiers
Use on
if your validation applies only under a certain context.
class User
include ActiveModel::Model
attr_accessor :password
validates_length_of :password, minimum: 10, on: :create
end
# RSpec
describe User do
it do
should validate_length_of(:password).
is_at_least(10).
on(:create)
end
end
# Test::Unit
class UserTest < ActiveSupport::TestCase
should validate_length_of(:password).
is_at_least(10).
on(:create)
end
is_at_least
Use is_at_least
to test usage of the :minimum
option. This asserts
that the attribute can take a string which is equal to or longer than
the given length and cannot take a string which is shorter.
class User
include ActiveModel::Model
attr_accessor :bio
validates_length_of :bio, minimum: 15
end
# RSpec
describe User do
it { should validate_length_of(:bio).is_at_least(15) }
end
# Test::Unit
class UserTest < ActiveSupport::TestCase
should validate_length_of(:bio).is_at_least(15)
end
is_at_most
Use is_at_most
to test usage of the :maximum
option. This asserts
that the attribute can take a string which is equal to or shorter than
the given length and cannot take a string which is longer.
class User
include ActiveModel::Model
attr_accessor :status_update
validates_length_of :status_update, maximum: 140
end
# RSpec
describe User do
it { should validate_length_of(:status_update).is_at_most(140) }
end
# Test::Unit
class UserTest < ActiveSupport::TestCase
should validate_length_of(:status_update).is_at_most(140)
end
is_equal_to
Use is_equal_to
to test usage of the :is
option. This asserts that
the attribute can take a string which is exactly equal to the given
length and cannot take a string which is shorter or longer.
class User
include ActiveModel::Model
attr_accessor :favorite_superhero
validates_length_of :favorite_superhero, is: 6
end
# RSpec
describe User do
it { should validate_length_of(:favorite_superhero).is_equal_to(6) }
end
# Test::Unit
class UserTest < ActiveSupport::TestCase
should validate_length_of(:favorite_superhero).is_equal_to(6)
end
is_at_least + is_at_most
Use is_at_least
and is_at_most
together to test usage of the :in
option.
class User
include ActiveModel::Model
attr_accessor :password
validates_length_of :password, in: 5..30
end
# RSpec
describe User do
it do
should validate_length_of(:password).
is_at_least(5).is_at_most(30)
end
end
# Test::Unit
class UserTest < ActiveSupport::TestCase
should validate_length_of(:password).
is_at_least(5).is_at_most(30)
end
with_message
Use with_message
if you are using a custom validation message.
class User
include ActiveModel::Model
attr_accessor :password
validates_length_of :password,
minimum: 10,
message: "Password isn't long enough"
end
# RSpec
describe User do
it do
should validate_length_of(:password).
is_at_least(10).
with_message("Password isn't long enough")
end
end
# Test::Unit
class UserTest < ActiveSupport::TestCase
should validate_length_of(:password).
is_at_least(10).
with_message("Password isn't long enough")
end
with_short_message
Use with_short_message
if you are using a custom "too short" message.
class User
include ActiveModel::Model
attr_accessor :secret_key
validates_length_of :secret_key,
in: 15..100,
too_short: 'Secret key must be more than 15 characters'
end
# RSpec
describe User do
it do
should validate_length_of(:secret_key).
is_at_least(15).
with_short_message('Secret key must be more than 15 characters')
end
end
# Test::Unit
class UserTest < ActiveSupport::TestCase
should validate_length_of(:secret_key).
is_at_least(15).
with_short_message('Secret key must be more than 15 characters')
end
with_long_message
Use with_long_message
if you are using a custom "too long" message.
class User
include ActiveModel::Model
attr_accessor :secret_key
validates_length_of :secret_key,
in: 15..100,
too_long: 'Secret key must be less than 100 characters'
end
# RSpec
describe User do
it do
should validate_length_of(:secret_key).
is_at_most(100).
with_long_message('Secret key must be less than 100 characters')
end
end
# Test::Unit
class UserTest < ActiveSupport::TestCase
should validate_length_of(:secret_key).
is_at_most(100).
with_long_message('Secret key must be less than 100 characters')
end
221 222 223 |
# File 'lib/shoulda/matchers/active_model/validate_length_of_matcher.rb', line 221 def validate_length_of(attr) ValidateLengthOfMatcher.new(attr) end |
- (ValidateNumericalityOfMatcher) validate_numericality_of(attr)
The validate_numericality_of
matcher tests usage of the
validates_numericality_of
validation.
class Person
include ActiveModel::Model
attr_accessor :gpa
validates_numericality_of :gpa
end
# RSpec
describe Person do
it { should validate_numericality_of(:gpa) }
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_numericality_of(:gpa)
end
Qualifiers
on
Use on
if your validation applies only under a certain context.
class Person
include ActiveModel::Model
attr_accessor :number_of_dependents
validates_numericality_of :number_of_dependents, on: :create
end
# RSpec
describe Person do
it do
should validate_numericality_of(:number_of_dependents).
on(:create)
end
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_numericality_of(:number_of_dependents).on(:create)
end
only_integer
Use only_integer
to test usage of the :only_integer
option. This
asserts that your attribute only allows integer numbers and disallows
non-integer ones.
class Person
include ActiveModel::Model
attr_accessor :age
validates_numericality_of :age, only_integer: true
end
# RSpec
describe Person do
it { should validate_numericality_of(:age).only_integer }
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_numericality_of(:age).only_integer
end
is_less_than
Use is_less_than
to test usage of the the :less_than
option. This
asserts that the attribute can take a number which is less than the
given value and cannot take a number which is greater than or equal to
it.
class Person
include ActiveModel::Model
attr_accessor :number_of_cars
validates_numericality_of :number_of_cars, less_than: 2
end
# RSpec
describe Person do
it do
should validate_numericality_of(:number_of_cars).
is_less_than(2)
end
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_numericality_of(:number_of_cars).
is_less_than(2)
end
is_less_than_or_equal_to
Use is_less_than_or_equal_to
to test usage of the
:less_than_or_equal_to
option. This asserts that the attribute can
take a number which is less than or equal to the given value and cannot
take a number which is greater than it.
class Person
include ActiveModel::Model
attr_accessor :birth_year
validates_numericality_of :birth_year, less_than_or_equal_to: 1987
end
# RSpec
describe Person do
it do
should validate_numericality_of(:birth_year).
is_less_than_or_equal_to(1987)
end
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_numericality_of(:birth_year).
is_less_than_or_equal_to(1987)
end
is_equal_to
Use is_equal_to
to test usage of the :equal_to
option. This asserts
that the attribute can take a number which is equal to the given value
and cannot take a number which is not equal.
class Person
include ActiveModel::Model
attr_accessor :weight
validates_numericality_of :weight, equal_to: 150
end
# RSpec
describe Person do
it { should validate_numericality_of(:weight).is_equal_to(150) }
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_numericality_of(:weight).is_equal_to(150)
end
is_greater_than_or_equal_to
Use is_greater_than_or_equal_to
to test usage of the
:greater_than_or_equal_to
option. This asserts that the attribute can
take a number which is greater than or equal to the given value and
cannot take a number which is less than it.
class Person
include ActiveModel::Model
attr_accessor :height
validates_numericality_of :height, greater_than_or_equal_to: 55
end
# RSpec
describe Person do
it do
should validate_numericality_of(:height).
is_greater_than_or_equal_to(55)
end
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_numericality_of(:height).
is_greater_than_or_equal_to(55)
end
is_greater_than
Use is_greater_than
to test usage of tthe :greater_than
option.
This asserts that the attribute can take a number which is greater than
the given value and cannot take a number less than or equal to it.
class Person
include ActiveModel::Model
attr_accessor :legal_age
validates_numericality_of :legal_age, greater_than: 21
end
# RSpec
describe Person do
it do
should validate_numericality_of(:legal_age).
is_greater_than(21)
end
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_numericality_of(:legal_age).
is_greater_than(21)
end
even
Use even
to test usage of the :even
option. This asserts that the
attribute can take odd numbers and cannot take even ones.
class Person
include ActiveModel::Model
attr_accessor :birth_month
validates_numericality_of :birth_month, even: true
end
# RSpec
describe Person do
it { should validate_numericality_of(:birth_month).even }
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_numericality_of(:birth_month).even
end
odd
Use odd
to test usage of the :odd
option. This asserts that the
attribute can take a number which is odd and cannot take a number which
is even.
class Person
include ActiveModel::Model
attr_accessor :birth_day
validates_numericality_of :birth_day, odd: true
end
# RSpec
describe Person do
it { should validate_numericality_of(:birth_day).odd }
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_numericality_of(:birth_day).odd
end
with_message
Use with_message
if you are using a custom validation message.
class Person
include ActiveModel::Model
attr_accessor :number_of_dependents
validates_numericality_of :number_of_dependents,
message: 'Number of dependents must be a number'
end
# RSpec
describe Person do
it do
should validate_numericality_of(:number_of_dependents).
with_message('Number of dependents must be a number')
end
end
# Test::Unit
class PersonTest < ActiveSupport::TestCase
should validate_numericality_of(:number_of_dependents).
with_message('Number of dependents must be a number')
end
allow_nil
Use allow_nil
to assert that the attribute allows nil.
class Age
include ActiveModel::Model
attr_accessor :age
validates_numericality_of :age, allow_nil: true
end
# RSpec
describe Post do
it { should validate_numericality_of(:age).allow_nil }
end
# Test::Unit
class PostTest < ActiveSupport::TestCase
should validate_numericality_of(:age).allow_nil
end
301 302 303 |
# File 'lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb', line 301 def validate_numericality_of(attr) ValidateNumericalityOfMatcher.new(attr) end |
- (ValidatePresenceOfMatcher) validate_presence_of(attr)
The validate_presence_of
matcher tests usage of the
validates_presence_of
validation.
class Robot
include ActiveModel::Model
attr_accessor :arms
validates_presence_of :arms
end
# RSpec
describe Robot do
it { should validate_presence_of(:arms) }
end
# Test::Unit
class RobotTest < ActiveSupport::TestCase
should validate_presence_of(:arms)
end
Caveats
Under Rails 4 and greater, if your model has_secure_password
and you
are validating presence of the password using a record whose password
has already been set prior to calling the matcher, you will be
instructed to use a record whose password is empty instead.
For example, given this scenario:
class User < ActiveRecord::Base
has_secure_password validations: false
validates_presence_of :password
end
describe User do
subject { User.new(password: '123456') }
it { should validate_presence_of(:password) }
end
the above test will raise an error like this:
The validation failed because your User model declares
`has_secure_password`, and `validate_presence_of` was called on a
user which has `password` already set to a value. Please use a user
with an empty `password` instead.
This happens because has_secure_password
itself overrides your model
so that it is impossible to set password
to nil. This means that it is
impossible to test that setting password
to nil places your model in
an invalid state (which in turn means that the validation itself is
unnecessary).
Qualifiers
on
Use on
if your validation applies only under a certain context.
class Robot
include ActiveModel::Model
attr_accessor :arms
validates_presence_of :arms, on: :create
end
# RSpec
describe Robot do
it { should validate_presence_of(:arms).on(:create) }
end
# Test::Unit
class RobotTest < ActiveSupport::TestCase
should validate_presence_of(:arms).on(:create)
end
with_message
Use with_message
if you are using a custom validation message.
class Robot
include ActiveModel::Model
attr_accessor :legs
validates_presence_of :legs, message: 'Robot has no legs'
end
# RSpec
describe Robot do
it do
should validate_presence_of(:legs).
with_message('Robot has no legs')
end
end
# Test::Unit
class RobotTest < ActiveSupport::TestCase
should validate_presence_of(:legs).
with_message('Robot has no legs')
end
108 109 110 |
# File 'lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb', line 108 def validate_presence_of(attr) ValidatePresenceOfMatcher.new(attr) end |