shoulda-matchers 2.6.1 → 2.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +9 -0
- data/.yardopts +8 -0
- data/Appraisals +82 -33
- data/Gemfile +18 -2
- data/Gemfile.lock +13 -1
- data/NEWS.md +27 -2
- data/README.md +83 -1329
- data/Rakefile +118 -1
- data/cucumber.yml +1 -0
- data/doc_config/gh-pages/index.html.erb +9 -0
- data/doc_config/yard/setup.rb +22 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/bootstrap.css +5967 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/full_list.css +12 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/global.css +45 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/solarized.css +69 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/style.css +283 -0
- data/doc_config/yard/templates/default/fulldoc/html/full_list.erb +32 -0
- data/doc_config/yard/templates/default/fulldoc/html/full_list_class.erb +1 -0
- data/doc_config/yard/templates/default/fulldoc/html/full_list_method.erb +8 -0
- data/doc_config/yard/templates/default/fulldoc/html/js/app.js +298 -0
- data/doc_config/yard/templates/default/fulldoc/html/js/full_list.js +1 -0
- data/doc_config/yard/templates/default/fulldoc/html/js/jquery.stickyheaders.js +289 -0
- data/doc_config/yard/templates/default/fulldoc/html/js/underscore.min.js +6 -0
- data/doc_config/yard/templates/default/fulldoc/html/setup.rb +8 -0
- data/doc_config/yard/templates/default/layout/html/breadcrumb.erb +14 -0
- data/doc_config/yard/templates/default/layout/html/fonts.erb +1 -0
- data/doc_config/yard/templates/default/layout/html/layout.erb +23 -0
- data/doc_config/yard/templates/default/layout/html/search.erb +13 -0
- data/doc_config/yard/templates/default/layout/html/setup.rb +40 -0
- data/doc_config/yard/templates/default/method_details/html/source.erb +10 -0
- data/doc_config/yard/templates/default/module/html/box_info.erb +31 -0
- data/docs.watchr +5 -0
- data/features/rails_integration.feature +32 -0
- data/features/step_definitions/rails_steps.rb +55 -9
- data/features/support/env.rb +1 -0
- data/gemfiles/3.0.gemfile +13 -1
- data/gemfiles/3.0.gemfile.lock +13 -1
- data/gemfiles/3.1.gemfile +17 -2
- data/gemfiles/3.1.gemfile.lock +31 -2
- data/gemfiles/3.1_1.9.2.gemfile +33 -0
- data/gemfiles/3.1_1.9.2.gemfile.lock +203 -0
- data/gemfiles/3.2.gemfile +18 -2
- data/gemfiles/3.2.gemfile.lock +32 -2
- data/gemfiles/3.2_1.9.2.gemfile +32 -0
- data/gemfiles/3.2_1.9.2.gemfile.lock +200 -0
- data/gemfiles/4.0.0.gemfile +20 -1
- data/gemfiles/4.0.0.gemfile.lock +46 -2
- data/gemfiles/4.0.1.gemfile +20 -1
- data/gemfiles/4.0.1.gemfile.lock +46 -2
- data/gemfiles/4.1.gemfile +21 -2
- data/gemfiles/4.1.gemfile.lock +47 -4
- data/lib/shoulda/matchers/action_controller.rb +0 -20
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +119 -28
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +22 -6
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +43 -10
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +40 -13
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +63 -11
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +34 -1
- data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +84 -15
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +84 -28
- data/lib/shoulda/matchers/action_controller/route_params.rb +4 -3
- data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +76 -13
- data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +147 -13
- data/lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb +148 -2
- data/lib/shoulda/matchers/active_model.rb +0 -25
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +66 -9
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +161 -19
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +5 -5
- data/lib/shoulda/matchers/active_model/ensure_exclusion_of_matcher.rb +92 -13
- data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +218 -16
- data/lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb +198 -32
- data/lib/shoulda/matchers/active_model/errors.rb +5 -2
- data/lib/shoulda/matchers/active_model/exception_message_finder.rb +1 -1
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +29 -8
- data/lib/shoulda/matchers/active_model/helpers.rb +20 -8
- data/lib/shoulda/matchers/active_model/numericality_matchers.rb +9 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +4 -6
- data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +3 -2
- data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +52 -14
- data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +51 -13
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +53 -7
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +275 -19
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +84 -14
- data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +170 -41
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +20 -15
- data/lib/shoulda/matchers/active_model/validation_message_finder.rb +1 -2
- data/lib/shoulda/matchers/active_record.rb +1 -12
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +89 -15
- data/lib/shoulda/matchers/active_record/association_matcher.rb +726 -70
- data/lib/shoulda/matchers/active_record/association_matchers.rb +9 -0
- data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +2 -1
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +4 -3
- data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +4 -5
- data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +79 -15
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +64 -15
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +21 -7
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +85 -10
- data/lib/shoulda/matchers/assertion_error.rb +7 -1
- data/lib/shoulda/matchers/doublespeak.rb +2 -1
- data/lib/shoulda/matchers/doublespeak/double.rb +3 -1
- data/lib/shoulda/matchers/doublespeak/double_collection.rb +2 -1
- data/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +1 -0
- data/lib/shoulda/matchers/doublespeak/object_double.rb +2 -1
- data/lib/shoulda/matchers/doublespeak/proxy_implementation.rb +2 -1
- data/lib/shoulda/matchers/doublespeak/structs.rb +2 -0
- data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +2 -1
- data/lib/shoulda/matchers/doublespeak/world.rb +3 -4
- data/lib/shoulda/matchers/error.rb +1 -0
- data/lib/shoulda/matchers/independent/delegate_matcher.rb +108 -20
- data/lib/shoulda/matchers/independent/delegate_matcher/stubbed_target.rb +4 -3
- data/lib/shoulda/matchers/integrations/nunit_test_case_detection.rb +3 -0
- data/lib/shoulda/matchers/rails_shim.rb +3 -2
- data/lib/shoulda/matchers/version.rb +2 -1
- data/lib/shoulda/matchers/warn.rb +1 -0
- data/script/SUPPORTED_VERSIONS +1 -0
- data/script/install_gems_in_all_appraisals +14 -0
- data/script/run_all_tests +14 -0
- data/shoulda-matchers.gemspec +0 -10
- data/spec/report_warnings.rb +7 -0
- data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +1 -1
- data/spec/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +9 -0
- data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +0 -36
- data/spec/shoulda/matchers/active_model/validation_message_finder_spec.rb +2 -2
- data/spec/shoulda/matchers/doublespeak/double_spec.rb +1 -1
- data/spec/shoulda/matchers/doublespeak/world_spec.rb +11 -29
- data/spec/shoulda/matchers/doublespeak_spec.rb +3 -3
- data/spec/spec_helper.rb +17 -0
- data/spec/support/class_builder.rb +4 -0
- data/spec/support/test_application.rb +1 -1
- data/spec/warnings_spy.rb +64 -0
- data/spec/warnings_spy/filesystem.rb +45 -0
- data/spec/warnings_spy/partitioner.rb +29 -0
- data/spec/warnings_spy/reader.rb +64 -0
- data/spec/warnings_spy/reporter.rb +87 -0
- metadata +49 -134
@@ -1,8 +1,10 @@
|
|
1
|
-
module Shoulda
|
1
|
+
module Shoulda
|
2
2
|
module Matchers
|
3
|
-
module ActiveModel
|
3
|
+
module ActiveModel
|
4
|
+
# @private
|
4
5
|
class CouldNotDetermineValueOutsideOfArray < RuntimeError; end
|
5
6
|
|
7
|
+
# @private
|
6
8
|
class NonNullableBooleanError < Shoulda::Matchers::Error
|
7
9
|
def self.create(attribute)
|
8
10
|
super(attribute: attribute)
|
@@ -19,6 +21,7 @@ Hence, this test will fail and there is no way to make it pass.
|
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
24
|
+
# @private
|
22
25
|
class CouldNotSetPasswordError < Shoulda::Matchers::Error
|
23
26
|
def self.create(model)
|
24
27
|
super(model: model)
|
@@ -1,16 +1,37 @@
|
|
1
|
-
module Shoulda
|
1
|
+
module Shoulda
|
2
2
|
module Matchers
|
3
|
-
module ActiveModel
|
4
|
-
|
5
|
-
#
|
3
|
+
module ActiveModel
|
4
|
+
# The `have_secure_password` matcher tests usage of the
|
5
|
+
# `has_secure_password` macro.
|
6
|
+
#
|
7
|
+
# #### Example
|
8
|
+
#
|
9
|
+
# class User
|
10
|
+
# include ActiveModel::Model
|
11
|
+
# include ActiveModel::SecurePassword
|
12
|
+
# attr_accessor :password
|
13
|
+
#
|
14
|
+
# has_secure_password
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # RSpec
|
18
|
+
# describe User do
|
19
|
+
# it { should have_secure_password }
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # Test::Unit
|
23
|
+
# class UserTest < ActiveSupport::TestCase
|
24
|
+
# should have_secure_password
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# @return [HaveSecurePasswordMatcher]
|
6
28
|
#
|
7
|
-
# Example:
|
8
|
-
# it { should have_secure_password }
|
9
29
|
def have_secure_password
|
10
30
|
HaveSecurePasswordMatcher.new
|
11
31
|
end
|
12
32
|
|
13
|
-
|
33
|
+
# @private
|
34
|
+
class HaveSecurePasswordMatcher
|
14
35
|
attr_reader :failure_message
|
15
36
|
|
16
37
|
alias failure_message_for_should failure_message
|
@@ -47,7 +68,7 @@ module Shoulda # :nodoc:
|
|
47
68
|
failure.nil?
|
48
69
|
end
|
49
70
|
|
50
|
-
|
71
|
+
protected
|
51
72
|
|
52
73
|
attr_reader :subject
|
53
74
|
|
@@ -1,14 +1,26 @@
|
|
1
|
-
module Shoulda
|
1
|
+
module Shoulda
|
2
2
|
module Matchers
|
3
|
-
module ActiveModel
|
3
|
+
module ActiveModel
|
4
|
+
# @private
|
4
5
|
module Helpers
|
5
|
-
def pretty_error_messages(obj)
|
6
|
-
obj.errors.map do |attribute,
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
def pretty_error_messages(obj)
|
7
|
+
obj.errors.map do |attribute, message|
|
8
|
+
full_message = message.dup
|
9
|
+
parenthetical_parts = []
|
10
|
+
|
11
|
+
unless attribute.to_sym == :base
|
12
|
+
parenthetical_parts << "attribute: #{attribute.to_s.inspect}"
|
13
|
+
|
14
|
+
if obj.respond_to?(attribute)
|
15
|
+
parenthetical_parts << "value: #{obj.__send__(attribute).inspect}"
|
16
|
+
end
|
10
17
|
end
|
11
|
-
|
18
|
+
|
19
|
+
if parenthetical_parts.any?
|
20
|
+
full_message << " (#{parenthetical_parts.join(', ')})"
|
21
|
+
end
|
22
|
+
|
23
|
+
full_message
|
12
24
|
end
|
13
25
|
end
|
14
26
|
|
@@ -1,11 +1,8 @@
|
|
1
|
-
module Shoulda
|
1
|
+
module Shoulda
|
2
2
|
module Matchers
|
3
|
-
module ActiveModel
|
3
|
+
module ActiveModel
|
4
4
|
module NumericalityMatchers
|
5
|
-
#
|
6
|
-
# it { should validate_numericality_of(:attr).
|
7
|
-
# is_greater_than(6).
|
8
|
-
# less_than(20)...(and so on) }
|
5
|
+
# @private
|
9
6
|
class ComparisonMatcher < ValidationMatcher
|
10
7
|
ERROR_MESSAGES = {
|
11
8
|
:> => :greater_than,
|
@@ -24,6 +21,7 @@ module Shoulda # :nodoc:
|
|
24
21
|
@operator = operator
|
25
22
|
@message = ERROR_MESSAGES[operator]
|
26
23
|
@comparison_combos = comparison_combos
|
24
|
+
@strict = false
|
27
25
|
end
|
28
26
|
|
29
27
|
def for(attribute)
|
@@ -1,8 +1,9 @@
|
|
1
|
-
module Shoulda
|
1
|
+
module Shoulda
|
2
2
|
module Matchers
|
3
|
-
module ActiveModel
|
3
|
+
module ActiveModel
|
4
4
|
module NumericalityMatchers
|
5
|
-
|
5
|
+
# @private
|
6
|
+
class EvenNumberMatcher < NumericTypeMatcher
|
6
7
|
NON_EVEN_NUMBER_VALUE = 1
|
7
8
|
|
8
9
|
def initialize(attribute, options = {})
|
@@ -1,8 +1,9 @@
|
|
1
|
-
module Shoulda
|
1
|
+
module Shoulda
|
2
2
|
module Matchers
|
3
|
-
module ActiveModel
|
3
|
+
module ActiveModel
|
4
4
|
module NumericalityMatchers
|
5
|
-
|
5
|
+
# @private
|
6
|
+
class OddNumberMatcher < NumericTypeMatcher
|
6
7
|
NON_ODD_NUMBER_VALUE = 2
|
7
8
|
|
8
9
|
def initialize(attribute, options = {})
|
@@ -1,8 +1,9 @@
|
|
1
|
-
module Shoulda
|
1
|
+
module Shoulda
|
2
2
|
module Matchers
|
3
|
-
module ActiveModel
|
3
|
+
module ActiveModel
|
4
4
|
module NumericalityMatchers
|
5
|
-
|
5
|
+
# @private
|
6
|
+
class OnlyIntegerMatcher < NumericTypeMatcher
|
6
7
|
NON_INTEGER_VALUE = 0.1
|
7
8
|
def initialize(attribute)
|
8
9
|
@attribute = attribute
|
@@ -1,24 +1,62 @@
|
|
1
|
-
module Shoulda
|
1
|
+
module Shoulda
|
2
2
|
module Matchers
|
3
|
-
module ActiveModel
|
4
|
-
|
5
|
-
#
|
3
|
+
module ActiveModel
|
4
|
+
# The `validate_absence_of` matcher tests the usage of the
|
5
|
+
# `validates_absence_of` validation.
|
6
|
+
#
|
7
|
+
# class Artillery
|
8
|
+
# include ActiveModel::Model
|
9
|
+
# attr_accessor :arms
|
10
|
+
#
|
11
|
+
# validates_absence_of :arms
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# # RSpec
|
15
|
+
# describe Artillery do
|
16
|
+
# it { should validate_absence_of(:arms) }
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# # Test::Unit
|
20
|
+
# class ArtilleryTest < ActiveSupport::TestCase
|
21
|
+
# should validate_absence_of(:arms)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# #### Qualifiers
|
25
|
+
#
|
26
|
+
# ##### with_message
|
6
27
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
28
|
+
# Use `with_message` if you are using a custom validation message.
|
29
|
+
#
|
30
|
+
# class Artillery
|
31
|
+
# include ActiveModel::Model
|
32
|
+
# attr_accessor :arms
|
33
|
+
#
|
34
|
+
# validates_absence_of :arms,
|
35
|
+
# message: "We're fresh outta arms here, soldier!"
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # RSpec
|
39
|
+
# describe Artillery do
|
40
|
+
# it do
|
41
|
+
# should validate_absence_of(:arms).
|
42
|
+
# with_message("We're fresh outta arms here, soldier!")
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# # Test::Unit
|
47
|
+
# class ArtilleryTest < ActiveSupport::TestCase
|
48
|
+
# should validate_absence_of(:arms).
|
49
|
+
# with_message("We're fresh outta arms here, soldier!")
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# @return [ValidateAbsenceOfMatcher}
|
11
53
|
#
|
12
|
-
# Examples:
|
13
|
-
# it { should validate_absence_of(:name) }
|
14
|
-
# it { should validate_absence_of(:name).
|
15
|
-
# with_message(/may not be set/) }
|
16
54
|
def validate_absence_of(attr)
|
17
55
|
ValidateAbsenceOfMatcher.new(attr)
|
18
56
|
end
|
19
57
|
|
20
|
-
|
21
|
-
|
58
|
+
# @private
|
59
|
+
class ValidateAbsenceOfMatcher < ValidationMatcher
|
22
60
|
def with_message(message)
|
23
61
|
@expected_message = message
|
24
62
|
self
|
@@ -1,24 +1,62 @@
|
|
1
|
-
module Shoulda
|
1
|
+
module Shoulda
|
2
2
|
module Matchers
|
3
|
-
module ActiveModel
|
4
|
-
|
5
|
-
#
|
6
|
-
#
|
3
|
+
module ActiveModel
|
4
|
+
# The `validate_acceptance_of` matcher tests usage of the
|
5
|
+
# `validates_acceptance_of` validation.
|
6
|
+
#
|
7
|
+
# class Registration
|
8
|
+
# include ActiveModel::Model
|
9
|
+
# attr_accessor :eula
|
10
|
+
#
|
11
|
+
# validates_acceptance_of :eula
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# # RSpec
|
15
|
+
# describe Registration do
|
16
|
+
# it { should validate_acceptance_of(:eula) }
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# # Test::Unit
|
20
|
+
# class RegistrationTest < ActiveSupport::TestCase
|
21
|
+
# should validate_acceptance_of(:eula)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# #### Qualifiers
|
7
25
|
#
|
8
|
-
#
|
9
|
-
# * <tt>with_message</tt> - value the test expects to find in
|
10
|
-
# <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
|
11
|
-
# translation for <tt>:accepted</tt>.
|
26
|
+
# ##### with_message
|
12
27
|
#
|
13
|
-
#
|
14
|
-
#
|
28
|
+
# Use `with_message` if you are using a custom validation message.
|
29
|
+
#
|
30
|
+
# class Registration
|
31
|
+
# include ActiveModel::Model
|
32
|
+
# attr_accessor :terms_of_service
|
33
|
+
#
|
34
|
+
# validates_acceptance_of :terms_of_service,
|
35
|
+
# message: 'You must accept the terms of service'
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # RSpec
|
39
|
+
# describe Registration do
|
40
|
+
# it do
|
41
|
+
# should validate_acceptance_of(:terms_of_service).
|
42
|
+
# with_message('You must accept the terms of service')
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# # Test::Unit
|
47
|
+
# class RegistrationTest < ActiveSupport::TestCase
|
48
|
+
# should validate_acceptance_of(:terms_of_service).
|
49
|
+
# with_message('You must accept the terms of service')
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# @return [ValidateAcceptanceOfMatcher]
|
15
53
|
#
|
16
54
|
def validate_acceptance_of(attr)
|
17
55
|
ValidateAcceptanceOfMatcher.new(attr)
|
18
56
|
end
|
19
57
|
|
20
|
-
|
21
|
-
|
58
|
+
# @private
|
59
|
+
class ValidateAcceptanceOfMatcher < ValidationMatcher
|
22
60
|
def with_message(message)
|
23
61
|
if message
|
24
62
|
@expected_message = message
|
@@ -1,22 +1,68 @@
|
|
1
|
-
module Shoulda
|
1
|
+
module Shoulda
|
2
2
|
module Matchers
|
3
|
-
module ActiveModel
|
4
|
-
#
|
3
|
+
module ActiveModel
|
4
|
+
# The `validate_confirmation_of` matcher tests usage of the
|
5
|
+
# `validates_confirmation_of` validation.
|
5
6
|
#
|
6
|
-
#
|
7
|
-
#
|
7
|
+
# class User
|
8
|
+
# include ActiveModel::Model
|
9
|
+
# attr_accessor :email
|
10
|
+
#
|
11
|
+
# validates_confirmation_of :email
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# # RSpec
|
15
|
+
# describe User do
|
16
|
+
# it { should validate_confirmation_of(:email) }
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# # Test::Unit
|
20
|
+
# class UserTest < ActiveSupport::TestCase
|
21
|
+
# should validate_confirmation_of(:email)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# #### Qualifiers
|
25
|
+
#
|
26
|
+
# ##### with_message
|
27
|
+
#
|
28
|
+
# Use `with_message` if you are using a custom validation message.
|
29
|
+
#
|
30
|
+
# class User
|
31
|
+
# include ActiveModel::Model
|
32
|
+
# attr_accessor :password
|
33
|
+
#
|
34
|
+
# validates_confirmation_of :password,
|
35
|
+
# message: 'Please re-enter your password'
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # RSpec
|
39
|
+
# describe User do
|
40
|
+
# it do
|
41
|
+
# should validate_confirmation_of(:password).
|
42
|
+
# with_message('Please re-enter your password')
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# # Test::Unit
|
47
|
+
# class UserTest < ActiveSupport::TestCase
|
48
|
+
# should validate_confirmation_of(:password).
|
49
|
+
# with_message('Please re-enter your password')
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# @return [ValidateConfirmationOfMatcher]
|
8
53
|
#
|
9
54
|
def validate_confirmation_of(attr)
|
10
55
|
ValidateConfirmationOfMatcher.new(attr)
|
11
56
|
end
|
12
57
|
|
13
|
-
|
58
|
+
# @private
|
59
|
+
class ValidateConfirmationOfMatcher < ValidationMatcher
|
14
60
|
include Helpers
|
15
61
|
|
16
62
|
attr_reader :attribute, :confirmation_attribute
|
17
63
|
|
18
64
|
def initialize(attribute)
|
19
|
-
|
65
|
+
super(attribute)
|
20
66
|
@confirmation_attribute = "#{attribute}_confirmation"
|
21
67
|
end
|
22
68
|
|
@@ -1,28 +1,284 @@
|
|
1
|
-
module Shoulda
|
1
|
+
module Shoulda
|
2
2
|
module Matchers
|
3
|
-
module ActiveModel
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
3
|
+
module ActiveModel
|
4
|
+
# The `validate_numericality_of` matcher tests usage of the
|
5
|
+
# `validates_numericality_of` validation.
|
6
|
+
#
|
7
|
+
# class Person
|
8
|
+
# include ActiveModel::Model
|
9
|
+
# attr_accessor :gpa
|
10
|
+
#
|
11
|
+
# validates_numericality_of :gpa
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# # RSpec
|
15
|
+
# describe Person do
|
16
|
+
# it { should validate_numericality_of(:gpa) }
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# # Test::Unit
|
20
|
+
# class PersonTest < ActiveSupport::TestCase
|
21
|
+
# should validate_numericality_of(:gpa)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# #### Qualifiers
|
25
|
+
#
|
26
|
+
# ##### only_integer
|
27
|
+
#
|
28
|
+
# Use `only_integer` to test usage of the `:only_integer` option. This
|
29
|
+
# asserts that your attribute only allows integer numbers and disallows
|
30
|
+
# non-integer ones.
|
31
|
+
#
|
32
|
+
# class Person
|
33
|
+
# include ActiveModel::Model
|
34
|
+
# attr_accessor :age
|
35
|
+
#
|
36
|
+
# validates_numericality_of :age, only_integer: true
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# # RSpec
|
40
|
+
# describe Person do
|
41
|
+
# it { should validate_numericality_of(:age).only_integer }
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# # Test::Unit
|
45
|
+
# class PersonTest < ActiveSupport::TestCase
|
46
|
+
# should validate_numericality_of(:age).only_integer
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# ##### is_less_than
|
50
|
+
#
|
51
|
+
# Use `is_less_than` to test usage of the the `:less_than` option. This
|
52
|
+
# asserts that the attribute can take a number which is less than the
|
53
|
+
# given value and cannot take a number which is greater than or equal to
|
54
|
+
# it.
|
55
|
+
#
|
56
|
+
# class Person
|
57
|
+
# include ActiveModel::Model
|
58
|
+
# attr_accessor :number_of_cars
|
59
|
+
#
|
60
|
+
# validates_numericality_of :number_of_cars, less_than: 2
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# # RSpec
|
64
|
+
# describe Person do
|
65
|
+
# it do
|
66
|
+
# should validate_numericality_of(:number_of_cars).
|
67
|
+
# is_less_than(2)
|
68
|
+
# end
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# # Test::Unit
|
72
|
+
# class PersonTest < ActiveSupport::TestCase
|
73
|
+
# should validate_numericality_of(:number_of_cars).
|
74
|
+
# is_less_than(2)
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# ##### is_less_than_or_equal_to
|
78
|
+
#
|
79
|
+
# Use `is_less_than_or_equal_to` to test usage of the
|
80
|
+
# `:less_than_or_equal_to` option. This asserts that the attribute can
|
81
|
+
# take a number which is less than or equal to the given value and cannot
|
82
|
+
# take a number which is greater than it.
|
83
|
+
#
|
84
|
+
# class Person
|
85
|
+
# include ActiveModel::Model
|
86
|
+
# attr_accessor :birth_year
|
87
|
+
#
|
88
|
+
# validates_numericality_of :birth_year, less_than_or_equal_to: 1987
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# # RSpec
|
92
|
+
# describe Person do
|
93
|
+
# it do
|
94
|
+
# should validate_numericality_of(:birth_year).
|
95
|
+
# is_less_than_or_equal_to(1987)
|
96
|
+
# end
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
# # Test::Unit
|
100
|
+
# class PersonTest < ActiveSupport::TestCase
|
101
|
+
# should validate_numericality_of(:birth_year).
|
102
|
+
# is_less_than_or_equal_to(1987)
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
# ##### is_equal_to
|
106
|
+
#
|
107
|
+
# Use `is_equal_to` to test usage of the `:equal_to` option. This asserts
|
108
|
+
# that the attribute can take a number which is equal to the given value
|
109
|
+
# and cannot take a number which is not equal.
|
110
|
+
#
|
111
|
+
# class Person
|
112
|
+
# include ActiveModel::Model
|
113
|
+
# attr_accessor :weight
|
114
|
+
#
|
115
|
+
# validates_numericality_of :weight, equal_to: 150
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
# # RSpec
|
119
|
+
# describe Person do
|
120
|
+
# it { should validate_numericality_of(:weight).is_equal_to(150) }
|
121
|
+
# end
|
122
|
+
#
|
123
|
+
# # Test::Unit
|
124
|
+
# class PersonTest < ActiveSupport::TestCase
|
125
|
+
# should validate_numericality_of(:weight).is_equal_to(150)
|
126
|
+
# end
|
127
|
+
#
|
128
|
+
# ##### is_greater_than_or_equal_to
|
129
|
+
#
|
130
|
+
# Use `is_greater_than_or_equal_to` to test usage of the
|
131
|
+
# `:greater_than_or_equal_to` option. This asserts that the attribute can
|
132
|
+
# take a number which is greater than or equal to the given value and
|
133
|
+
# cannot take a number which is less than it.
|
134
|
+
#
|
135
|
+
# class Person
|
136
|
+
# include ActiveModel::Model
|
137
|
+
# attr_accessor :height
|
138
|
+
#
|
139
|
+
# validates_numericality_of :height, greater_than_or_equal_to: 55
|
140
|
+
# end
|
141
|
+
#
|
142
|
+
# # RSpec
|
143
|
+
# describe Person do
|
144
|
+
# it do
|
145
|
+
# should validate_numericality_of(:height).
|
146
|
+
# is_greater_than_or_equal_to(55)
|
147
|
+
# end
|
148
|
+
# end
|
149
|
+
#
|
150
|
+
# # Test::Unit
|
151
|
+
# class PersonTest < ActiveSupport::TestCase
|
152
|
+
# should validate_numericality_of(:height).
|
153
|
+
# is_greater_than_or_equal_to(55)
|
154
|
+
# end
|
155
|
+
#
|
156
|
+
# ##### is_greater_than
|
157
|
+
#
|
158
|
+
# Use `is_greater_than` to test usage of tthe `:greater_than` option.
|
159
|
+
# This asserts that the attribute can take a number which is greater than
|
160
|
+
# the given value and cannot take a number less than or equal to it.
|
161
|
+
#
|
162
|
+
# class Person
|
163
|
+
# include ActiveModel::Model
|
164
|
+
# attr_accessor :legal_age
|
165
|
+
#
|
166
|
+
# validates_numericality_of :legal_age, greater_than: 21
|
167
|
+
# end
|
168
|
+
#
|
169
|
+
# # RSpec
|
170
|
+
# describe Person do
|
171
|
+
# it do
|
172
|
+
# should validate_numericality_of(:legal_age).
|
173
|
+
# is_greater_than(21)
|
174
|
+
# end
|
175
|
+
# end
|
176
|
+
#
|
177
|
+
# # Test::Unit
|
178
|
+
# class PersonTest < ActiveSupport::TestCase
|
179
|
+
# should validate_numericality_of(:legal_age).
|
180
|
+
# is_greater_than(21)
|
181
|
+
# end
|
182
|
+
#
|
183
|
+
# ##### even
|
184
|
+
#
|
185
|
+
# Use `even` to test usage of the `:even` option. This asserts that the
|
186
|
+
# attribute can take odd numbers and cannot take even ones.
|
187
|
+
#
|
188
|
+
# class Person
|
189
|
+
# include ActiveModel::Model
|
190
|
+
# attr_accessor :birth_month
|
191
|
+
#
|
192
|
+
# validates_numericality_of :birth_month, even: true
|
193
|
+
# end
|
194
|
+
#
|
195
|
+
# # RSpec
|
196
|
+
# describe Person do
|
197
|
+
# it { should validate_numericality_of(:birth_month).even }
|
198
|
+
# end
|
199
|
+
#
|
200
|
+
# # Test::Unit
|
201
|
+
# class PersonTest < ActiveSupport::TestCase
|
202
|
+
# should validate_numericality_of(:birth_month).even
|
203
|
+
# end
|
204
|
+
#
|
205
|
+
# ##### odd
|
206
|
+
#
|
207
|
+
# Use `odd` to test usage of the `:odd` option. This asserts that the
|
208
|
+
# attribute can take a number which is odd and cannot take a number which
|
209
|
+
# is even.
|
210
|
+
#
|
211
|
+
# class Person
|
212
|
+
# include ActiveModel::Model
|
213
|
+
# attr_accessor :birth_day
|
214
|
+
#
|
215
|
+
# validates_numericality_of :birth_day, odd: true
|
216
|
+
# end
|
217
|
+
#
|
218
|
+
# # RSpec
|
219
|
+
# describe Person do
|
220
|
+
# it { should validate_numericality_of(:birth_day).odd }
|
221
|
+
# end
|
222
|
+
#
|
223
|
+
# # Test::Unit
|
224
|
+
# class PersonTest < ActiveSupport::TestCase
|
225
|
+
# should validate_numericality_of(:birth_day).odd
|
226
|
+
# end
|
227
|
+
#
|
228
|
+
# ##### with_message
|
229
|
+
#
|
230
|
+
# Use `with_message` if you are using a custom validation message.
|
231
|
+
#
|
232
|
+
# class Person
|
233
|
+
# include ActiveModel::Model
|
234
|
+
# attr_accessor :number_of_dependents
|
235
|
+
#
|
236
|
+
# validates_numericality_of :number_of_dependents,
|
237
|
+
# message: 'Number of dependents must be a number'
|
238
|
+
# end
|
239
|
+
#
|
240
|
+
# # RSpec
|
241
|
+
# describe Person do
|
242
|
+
# it do
|
243
|
+
# should validate_numericality_of(:number_of_dependents).
|
244
|
+
# with_message('Number of dependents must be a number')
|
245
|
+
# end
|
246
|
+
# end
|
247
|
+
#
|
248
|
+
# # Test::Unit
|
249
|
+
# class PersonTest < ActiveSupport::TestCase
|
250
|
+
# should validate_numericality_of(:number_of_dependents).
|
251
|
+
# with_message('Number of dependents must be a number')
|
252
|
+
# end
|
253
|
+
#
|
254
|
+
# ##### allow_nil
|
255
|
+
#
|
256
|
+
# Use `allow_nil` to assert that the attribute allows nil.
|
257
|
+
#
|
258
|
+
# class Age
|
259
|
+
# include ActiveModel::Model
|
260
|
+
# attr_accessor :age
|
261
|
+
#
|
262
|
+
# validates_numericality_of :age, allow_nil: true
|
263
|
+
# end
|
264
|
+
#
|
265
|
+
# # RSpec
|
266
|
+
# describe Post do
|
267
|
+
# it { should validate_numericality_of(:age).allow_nil }
|
268
|
+
# end
|
269
|
+
#
|
270
|
+
# # Test::Unit
|
271
|
+
# class PostTest < ActiveSupport::TestCase
|
272
|
+
# should validate_numericality_of(:age).allow_nil
|
273
|
+
# end
|
274
|
+
#
|
275
|
+
# @return [ValidateNumericalityOfMatcher]
|
21
276
|
#
|
22
277
|
def validate_numericality_of(attr)
|
23
278
|
ValidateNumericalityOfMatcher.new(attr)
|
24
279
|
end
|
25
280
|
|
281
|
+
# @private
|
26
282
|
class ValidateNumericalityOfMatcher
|
27
283
|
NUMERIC_NAME = 'numbers'
|
28
284
|
NON_NUMERIC_VALUE = 'abcd'
|