mcmire-shoulda-matchers 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +32 -0
- data/.yardopts +7 -0
- data/Appraisals +45 -0
- data/CONTRIBUTING.md +41 -0
- data/Gemfile +31 -0
- data/Gemfile.lock +166 -0
- data/MIT-LICENSE +22 -0
- data/NEWS.md +299 -0
- data/README.md +163 -0
- data/Rakefile +116 -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 +300 -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 +8 -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/features/rails_integration.feature +113 -0
- data/features/step_definitions/rails_steps.rb +162 -0
- data/features/support/env.rb +5 -0
- data/gemfiles/3.0.gemfile +24 -0
- data/gemfiles/3.0.gemfile.lock +150 -0
- data/gemfiles/3.1.gemfile +27 -0
- data/gemfiles/3.1.gemfile.lock +173 -0
- data/gemfiles/3.2.gemfile +27 -0
- data/gemfiles/3.2.gemfile.lock +171 -0
- data/gemfiles/4.0.0.gemfile +28 -0
- data/gemfiles/4.0.0.gemfile.lock +172 -0
- data/gemfiles/4.0.1.gemfile +28 -0
- data/gemfiles/4.0.1.gemfile.lock +172 -0
- data/lib/shoulda-matchers.rb +1 -0
- data/lib/shoulda/matchers.rb +11 -0
- data/lib/shoulda/matchers/action_controller.rb +17 -0
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +64 -0
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +97 -0
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +81 -0
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +117 -0
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +114 -0
- data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +154 -0
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +116 -0
- data/lib/shoulda/matchers/action_controller/route_params.rb +48 -0
- data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +164 -0
- data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +296 -0
- data/lib/shoulda/matchers/active_model.rb +30 -0
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +167 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +314 -0
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +46 -0
- data/lib/shoulda/matchers/active_model/ensure_exclusion_of_matcher.rb +160 -0
- data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +417 -0
- data/lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb +337 -0
- data/lib/shoulda/matchers/active_model/errors.rb +10 -0
- data/lib/shoulda/matchers/active_model/exception_message_finder.rb +58 -0
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +92 -0
- data/lib/shoulda/matchers/active_model/helpers.rb +46 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers.rb +9 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +75 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +27 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +27 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +26 -0
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +112 -0
- data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +77 -0
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +121 -0
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +380 -0
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +89 -0
- data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +372 -0
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +97 -0
- data/lib/shoulda/matchers/active_model/validation_message_finder.rb +69 -0
- data/lib/shoulda/matchers/active_record.rb +22 -0
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +204 -0
- data/lib/shoulda/matchers/active_record/association_matcher.rb +901 -0
- data/lib/shoulda/matchers/active_record/association_matchers.rb +9 -0
- data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +81 -0
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +65 -0
- data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +94 -0
- data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +63 -0
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +261 -0
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +149 -0
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +72 -0
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +181 -0
- data/lib/shoulda/matchers/assertion_error.rb +19 -0
- data/lib/shoulda/matchers/error.rb +6 -0
- data/lib/shoulda/matchers/integrations/rspec.rb +20 -0
- data/lib/shoulda/matchers/integrations/test_unit.rb +30 -0
- data/lib/shoulda/matchers/rails_shim.rb +50 -0
- data/lib/shoulda/matchers/version.rb +6 -0
- data/lib/shoulda/matchers/warn.rb +8 -0
- data/shoulda-matchers.gemspec +23 -0
- data/spec/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +22 -0
- data/spec/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +42 -0
- data/spec/shoulda/matchers/action_controller/render_template_matcher_spec.rb +78 -0
- data/spec/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +63 -0
- data/spec/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +63 -0
- data/spec/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +31 -0
- data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +70 -0
- data/spec/shoulda/matchers/action_controller/route_params_spec.rb +30 -0
- data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +51 -0
- data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +153 -0
- data/spec/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +111 -0
- data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +170 -0
- data/spec/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +81 -0
- data/spec/shoulda/matchers/active_model/ensure_exclusion_of_matcher_spec.rb +95 -0
- data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +320 -0
- data/spec/shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb +166 -0
- data/spec/shoulda/matchers/active_model/exception_message_finder_spec.rb +111 -0
- data/spec/shoulda/matchers/active_model/have_secure_password_matcher_spec.rb +20 -0
- data/spec/shoulda/matchers/active_model/helpers_spec.rb +158 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +169 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +59 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +59 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +57 -0
- data/spec/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +139 -0
- data/spec/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +41 -0
- data/spec/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +47 -0
- data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +331 -0
- data/spec/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +180 -0
- data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +398 -0
- data/spec/shoulda/matchers/active_model/validation_message_finder_spec.rb +127 -0
- data/spec/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +107 -0
- data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +860 -0
- data/spec/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +247 -0
- data/spec/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +111 -0
- data/spec/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +78 -0
- data/spec/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +41 -0
- data/spec/shoulda/matchers/active_record/serialize_matcher_spec.rb +86 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/active_model_versions.rb +13 -0
- data/spec/support/active_resource_builder.rb +29 -0
- data/spec/support/activemodel_helpers.rb +19 -0
- data/spec/support/capture_helpers.rb +19 -0
- data/spec/support/class_builder.rb +42 -0
- data/spec/support/controller_builder.rb +74 -0
- data/spec/support/fail_with_message_including_matcher.rb +33 -0
- data/spec/support/fail_with_message_matcher.rb +32 -0
- data/spec/support/i18n_faker.rb +10 -0
- data/spec/support/mailer_builder.rb +10 -0
- data/spec/support/model_builder.rb +81 -0
- data/spec/support/rails_versions.rb +18 -0
- data/spec/support/shared_examples/numerical_submatcher.rb +19 -0
- data/spec/support/shared_examples/numerical_type_submatcher.rb +17 -0
- data/spec/support/test_application.rb +120 -0
- data/yard.watchr +5 -0
- metadata +281 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActiveModel
|
4
|
+
# @private
|
5
|
+
module Helpers
|
6
|
+
def pretty_error_messages(obj)
|
7
|
+
obj.errors.map do |attribute, model|
|
8
|
+
msg = "#{attribute} #{model}"
|
9
|
+
if attribute.to_sym != :base && obj.respond_to?(attribute)
|
10
|
+
msg << " (#{obj.__send__(attribute).inspect})"
|
11
|
+
end
|
12
|
+
msg
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Helper method that determines the default error message used by Active
|
17
|
+
# Record. Works for both existing Rails 2.1 and Rails 2.2 with the newly
|
18
|
+
# introduced I18n module used for localization. Use with Rails 3.0 and
|
19
|
+
# up will delegate to ActiveModel::Errors.generate_error if a model
|
20
|
+
# instance is given.
|
21
|
+
#
|
22
|
+
# default_error_message(:blank)
|
23
|
+
# default_error_message(:too_short, count: 5)
|
24
|
+
# default_error_message(:too_long, count: 60)
|
25
|
+
# default_error_message(:blank, model_name: 'user', attribute: 'name')
|
26
|
+
# default_error_message(:blank, instance: #<Model>, attribute: 'name')
|
27
|
+
def default_error_message(key, options = {})
|
28
|
+
model_name = options.delete(:model_name)
|
29
|
+
attribute = options.delete(:attribute)
|
30
|
+
instance = options.delete(:instance)
|
31
|
+
|
32
|
+
if instance && instance.errors.respond_to?(:generate_message)
|
33
|
+
instance.errors.generate_message(attribute.to_sym, key, options)
|
34
|
+
else
|
35
|
+
default_translation = [ :"activerecord.errors.models.#{model_name}.#{key}",
|
36
|
+
:"activerecord.errors.messages.#{key}",
|
37
|
+
:"errors.attributes.#{attribute}.#{key}",
|
38
|
+
:"errors.messages.#{key}" ]
|
39
|
+
I18n.translate(:"activerecord.errors.models.#{model_name}.attributes.#{attribute}.#{key}",
|
40
|
+
{ default: default_translation }.merge(options))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActiveModel
|
4
|
+
module NumericalityMatchers
|
5
|
+
# @private
|
6
|
+
class ComparisonMatcher < ValidationMatcher
|
7
|
+
def initialize(numericality_matcher, value, operator)
|
8
|
+
unless numericality_matcher.respond_to? :diff_to_compare
|
9
|
+
raise ArgumentError, 'numericality_matcher is invalid'
|
10
|
+
end
|
11
|
+
@numericality_matcher = numericality_matcher
|
12
|
+
@value = value
|
13
|
+
@operator = operator
|
14
|
+
@message = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def for(attribute)
|
18
|
+
@attribute = attribute
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def matches?(subject)
|
23
|
+
@subject = subject
|
24
|
+
all_bounds_correct?
|
25
|
+
end
|
26
|
+
|
27
|
+
def with_message(message)
|
28
|
+
@message = message
|
29
|
+
end
|
30
|
+
|
31
|
+
def comparison_description
|
32
|
+
"#{expectation} #{@value}"
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def comparison_combos
|
38
|
+
allow = :allows_value_of
|
39
|
+
disallow = :disallows_value_of
|
40
|
+
checker_types =
|
41
|
+
case @operator
|
42
|
+
when :> then [allow, disallow, disallow]
|
43
|
+
when :>= then [allow, allow, disallow]
|
44
|
+
when :== then [disallow, allow, disallow]
|
45
|
+
when :< then [disallow, disallow, allow]
|
46
|
+
when :<= then [disallow, allow, allow]
|
47
|
+
end
|
48
|
+
diffs_to_compare.zip(checker_types)
|
49
|
+
end
|
50
|
+
|
51
|
+
def diffs_to_compare
|
52
|
+
diff = @numericality_matcher.diff_to_compare
|
53
|
+
[diff, 0, -diff]
|
54
|
+
end
|
55
|
+
|
56
|
+
def expectation
|
57
|
+
case @operator
|
58
|
+
when :> then "greater than"
|
59
|
+
when :>= then "greater than or equal to"
|
60
|
+
when :== then "equal to"
|
61
|
+
when :< then "less than"
|
62
|
+
when :<= then "less than or equal to"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def all_bounds_correct?
|
67
|
+
comparison_combos.all? do |diff, checker_type|
|
68
|
+
__send__(checker_type, @value + diff, @message)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActiveModel
|
4
|
+
module NumericalityMatchers
|
5
|
+
# @private
|
6
|
+
class EvenNumberMatcher < NumericTypeMatcher
|
7
|
+
NON_EVEN_NUMBER_VALUE = 1
|
8
|
+
|
9
|
+
def initialize(attribute, options = {})
|
10
|
+
@attribute = attribute
|
11
|
+
@disallow_value_matcher = DisallowValueMatcher.new(NON_EVEN_NUMBER_VALUE).
|
12
|
+
for(@attribute).
|
13
|
+
with_message(:even)
|
14
|
+
end
|
15
|
+
|
16
|
+
def allowed_type
|
17
|
+
'even numbers'
|
18
|
+
end
|
19
|
+
|
20
|
+
def diff_to_compare
|
21
|
+
2
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActiveModel
|
4
|
+
module NumericalityMatchers
|
5
|
+
# @private
|
6
|
+
class NumericTypeMatcher
|
7
|
+
def initialize
|
8
|
+
raise NotImplementedError
|
9
|
+
end
|
10
|
+
|
11
|
+
def matches?(subject)
|
12
|
+
@disallow_value_matcher.matches?(subject)
|
13
|
+
end
|
14
|
+
|
15
|
+
def with_message(message)
|
16
|
+
@disallow_value_matcher.with_message(message)
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def allowed_type
|
21
|
+
raise NotImplementedError
|
22
|
+
end
|
23
|
+
|
24
|
+
def diff_to_compare
|
25
|
+
raise NotImplementedError
|
26
|
+
end
|
27
|
+
|
28
|
+
def failure_message
|
29
|
+
@disallow_value_matcher.failure_message
|
30
|
+
end
|
31
|
+
alias failure_message_for_should failure_message
|
32
|
+
|
33
|
+
def failure_message_when_negated
|
34
|
+
@disallow_value_matcher.failure_message_when_negated
|
35
|
+
end
|
36
|
+
alias failure_message_for_should_not failure_message_when_negated
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActiveModel
|
4
|
+
module NumericalityMatchers
|
5
|
+
# @private
|
6
|
+
class OddNumberMatcher < NumericTypeMatcher
|
7
|
+
NON_ODD_NUMBER_VALUE = 2
|
8
|
+
|
9
|
+
def initialize(attribute, options = {})
|
10
|
+
@attribute = attribute
|
11
|
+
@disallow_value_matcher = DisallowValueMatcher.new(NON_ODD_NUMBER_VALUE).
|
12
|
+
for(@attribute).
|
13
|
+
with_message(:odd)
|
14
|
+
end
|
15
|
+
|
16
|
+
def allowed_type
|
17
|
+
'odd numbers'
|
18
|
+
end
|
19
|
+
|
20
|
+
def diff_to_compare
|
21
|
+
2
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActiveModel
|
4
|
+
module NumericalityMatchers
|
5
|
+
# @private
|
6
|
+
class OnlyIntegerMatcher
|
7
|
+
NON_INTEGER_VALUE = 0.1
|
8
|
+
def initialize(attribute)
|
9
|
+
@attribute = attribute
|
10
|
+
@disallow_value_matcher = DisallowValueMatcher.new(NON_INTEGER_VALUE).
|
11
|
+
for(attribute).
|
12
|
+
with_message(:not_an_integer)
|
13
|
+
end
|
14
|
+
|
15
|
+
def allowed_type
|
16
|
+
'integers'
|
17
|
+
end
|
18
|
+
|
19
|
+
def diff_to_compare
|
20
|
+
1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
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
|
+
#
|
10
|
+
# validates_absence_of :arms
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# # RSpec
|
14
|
+
# describe Artillery do
|
15
|
+
# it { should validate_absence_of(:arms) }
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# # Test::Unit
|
19
|
+
# class ArtilleryTest < ActiveSupport::TestCase
|
20
|
+
# should validate_absence_of(:arms)
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# #### Qualifiers
|
24
|
+
#
|
25
|
+
# ##### with_message
|
26
|
+
#
|
27
|
+
# Use `with_message` if you are using a custom validation message.
|
28
|
+
#
|
29
|
+
# class Artillery
|
30
|
+
# include ActiveModel::Model
|
31
|
+
#
|
32
|
+
# validates_absence_of :arms, message: "We're fresh outta arms here, soldier!"
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# # RSpec
|
36
|
+
# describe Artillery do
|
37
|
+
# it do
|
38
|
+
# should validate_absence_of(:arms).
|
39
|
+
# with_message("We're fresh outta arms here, soldier!")
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# # Test::Unit
|
44
|
+
# class ArtilleryTest < ActiveSupport::TestCase
|
45
|
+
# should validate_absence_of(:arms).
|
46
|
+
# with_message("We're fresh outta arms here, soldier!")
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# @return [ValidateAbsenceOfMatcher}
|
50
|
+
#
|
51
|
+
def validate_absence_of(attr)
|
52
|
+
ValidateAbsenceOfMatcher.new(attr)
|
53
|
+
end
|
54
|
+
|
55
|
+
# @private
|
56
|
+
class ValidateAbsenceOfMatcher < ValidationMatcher
|
57
|
+
def with_message(message)
|
58
|
+
@expected_message = message
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
def matches?(subject)
|
63
|
+
super(subject)
|
64
|
+
@expected_message ||= :present
|
65
|
+
disallows_value_of(value, @expected_message)
|
66
|
+
end
|
67
|
+
|
68
|
+
def description
|
69
|
+
"require #{@attribute} to not be set"
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def value
|
75
|
+
if reflection
|
76
|
+
obj = reflection.klass.new
|
77
|
+
if collection?
|
78
|
+
[ obj ]
|
79
|
+
else
|
80
|
+
obj
|
81
|
+
end
|
82
|
+
elsif attribute_class == Fixnum
|
83
|
+
1
|
84
|
+
elsif !attribute_class || attribute_class == String
|
85
|
+
'an arbitrary value'
|
86
|
+
else
|
87
|
+
attribute_class.new
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def attribute_class
|
92
|
+
@subject.class.respond_to?(:columns_hash) &&
|
93
|
+
@subject.class.columns_hash[@attribute].respond_to?(:klass) &&
|
94
|
+
@subject.class.columns_hash[@attribute].klass
|
95
|
+
end
|
96
|
+
|
97
|
+
def collection?
|
98
|
+
if reflection
|
99
|
+
[:has_many, :has_and_belongs_to_many].include?(reflection.macro)
|
100
|
+
else
|
101
|
+
false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def reflection
|
106
|
+
@subject.class.respond_to?(:reflect_on_association) &&
|
107
|
+
@subject.class.reflect_on_association(@attribute)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
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
|
+
#
|
10
|
+
# validates_acceptance_of :eula
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# # RSpec
|
14
|
+
# describe Registration do
|
15
|
+
# it { should validate_acceptance_of(:eula) }
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# # Test::Unit
|
19
|
+
# class RegistrationTest < ActiveSupport::TestCase
|
20
|
+
# should validate_acceptance_of(:eula)
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# #### Qualifiers
|
24
|
+
#
|
25
|
+
# ##### with_message
|
26
|
+
#
|
27
|
+
# Use `with_message` if you are using a custom validation message.
|
28
|
+
#
|
29
|
+
# class Registration
|
30
|
+
# include ActiveModel::Model
|
31
|
+
#
|
32
|
+
# validates_acceptance_of :terms_of_service,
|
33
|
+
# message: 'You must accept the terms of service'
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# # RSpec
|
37
|
+
# describe Registration do
|
38
|
+
# it do
|
39
|
+
# should validate_acceptance_of(:terms_of_service).
|
40
|
+
# with_message('You must accept the terms of service')
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# # Test::Unit
|
45
|
+
# class RegistrationTest < ActiveSupport::TestCase
|
46
|
+
# should validate_acceptance_of(:terms_of_service).
|
47
|
+
# with_message('You must accept the terms of service')
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# @return [ValidateAcceptanceOfMatcher]
|
51
|
+
#
|
52
|
+
def validate_acceptance_of(attr)
|
53
|
+
ValidateAcceptanceOfMatcher.new(attr)
|
54
|
+
end
|
55
|
+
|
56
|
+
# @private
|
57
|
+
class ValidateAcceptanceOfMatcher < ValidationMatcher
|
58
|
+
def with_message(message)
|
59
|
+
if message
|
60
|
+
@expected_message = message
|
61
|
+
end
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
def matches?(subject)
|
66
|
+
super(subject)
|
67
|
+
@expected_message ||= :accepted
|
68
|
+
disallows_value_of(false, @expected_message)
|
69
|
+
end
|
70
|
+
|
71
|
+
def description
|
72
|
+
"require #{@attribute} to be accepted"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|