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.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +9 -0
  4. data/.yardopts +8 -0
  5. data/Appraisals +82 -33
  6. data/Gemfile +18 -2
  7. data/Gemfile.lock +13 -1
  8. data/NEWS.md +27 -2
  9. data/README.md +83 -1329
  10. data/Rakefile +118 -1
  11. data/cucumber.yml +1 -0
  12. data/doc_config/gh-pages/index.html.erb +9 -0
  13. data/doc_config/yard/setup.rb +22 -0
  14. data/doc_config/yard/templates/default/fulldoc/html/css/bootstrap.css +5967 -0
  15. data/doc_config/yard/templates/default/fulldoc/html/css/full_list.css +12 -0
  16. data/doc_config/yard/templates/default/fulldoc/html/css/global.css +45 -0
  17. data/doc_config/yard/templates/default/fulldoc/html/css/solarized.css +69 -0
  18. data/doc_config/yard/templates/default/fulldoc/html/css/style.css +283 -0
  19. data/doc_config/yard/templates/default/fulldoc/html/full_list.erb +32 -0
  20. data/doc_config/yard/templates/default/fulldoc/html/full_list_class.erb +1 -0
  21. data/doc_config/yard/templates/default/fulldoc/html/full_list_method.erb +8 -0
  22. data/doc_config/yard/templates/default/fulldoc/html/js/app.js +298 -0
  23. data/doc_config/yard/templates/default/fulldoc/html/js/full_list.js +1 -0
  24. data/doc_config/yard/templates/default/fulldoc/html/js/jquery.stickyheaders.js +289 -0
  25. data/doc_config/yard/templates/default/fulldoc/html/js/underscore.min.js +6 -0
  26. data/doc_config/yard/templates/default/fulldoc/html/setup.rb +8 -0
  27. data/doc_config/yard/templates/default/layout/html/breadcrumb.erb +14 -0
  28. data/doc_config/yard/templates/default/layout/html/fonts.erb +1 -0
  29. data/doc_config/yard/templates/default/layout/html/layout.erb +23 -0
  30. data/doc_config/yard/templates/default/layout/html/search.erb +13 -0
  31. data/doc_config/yard/templates/default/layout/html/setup.rb +40 -0
  32. data/doc_config/yard/templates/default/method_details/html/source.erb +10 -0
  33. data/doc_config/yard/templates/default/module/html/box_info.erb +31 -0
  34. data/docs.watchr +5 -0
  35. data/features/rails_integration.feature +32 -0
  36. data/features/step_definitions/rails_steps.rb +55 -9
  37. data/features/support/env.rb +1 -0
  38. data/gemfiles/3.0.gemfile +13 -1
  39. data/gemfiles/3.0.gemfile.lock +13 -1
  40. data/gemfiles/3.1.gemfile +17 -2
  41. data/gemfiles/3.1.gemfile.lock +31 -2
  42. data/gemfiles/3.1_1.9.2.gemfile +33 -0
  43. data/gemfiles/3.1_1.9.2.gemfile.lock +203 -0
  44. data/gemfiles/3.2.gemfile +18 -2
  45. data/gemfiles/3.2.gemfile.lock +32 -2
  46. data/gemfiles/3.2_1.9.2.gemfile +32 -0
  47. data/gemfiles/3.2_1.9.2.gemfile.lock +200 -0
  48. data/gemfiles/4.0.0.gemfile +20 -1
  49. data/gemfiles/4.0.0.gemfile.lock +46 -2
  50. data/gemfiles/4.0.1.gemfile +20 -1
  51. data/gemfiles/4.0.1.gemfile.lock +46 -2
  52. data/gemfiles/4.1.gemfile +21 -2
  53. data/gemfiles/4.1.gemfile.lock +47 -4
  54. data/lib/shoulda/matchers/action_controller.rb +0 -20
  55. data/lib/shoulda/matchers/action_controller/callback_matcher.rb +119 -28
  56. data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +22 -6
  57. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +43 -10
  58. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +40 -13
  59. data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +63 -11
  60. data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +34 -1
  61. data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +84 -15
  62. data/lib/shoulda/matchers/action_controller/route_matcher.rb +84 -28
  63. data/lib/shoulda/matchers/action_controller/route_params.rb +4 -3
  64. data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +76 -13
  65. data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +147 -13
  66. data/lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb +148 -2
  67. data/lib/shoulda/matchers/active_model.rb +0 -25
  68. data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +66 -9
  69. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +161 -19
  70. data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +5 -5
  71. data/lib/shoulda/matchers/active_model/ensure_exclusion_of_matcher.rb +92 -13
  72. data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +218 -16
  73. data/lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb +198 -32
  74. data/lib/shoulda/matchers/active_model/errors.rb +5 -2
  75. data/lib/shoulda/matchers/active_model/exception_message_finder.rb +1 -1
  76. data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +29 -8
  77. data/lib/shoulda/matchers/active_model/helpers.rb +20 -8
  78. data/lib/shoulda/matchers/active_model/numericality_matchers.rb +9 -0
  79. data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +4 -6
  80. data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +4 -3
  81. data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +3 -2
  82. data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +4 -3
  83. data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +4 -3
  84. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +52 -14
  85. data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +51 -13
  86. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +53 -7
  87. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +275 -19
  88. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +84 -14
  89. data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +170 -41
  90. data/lib/shoulda/matchers/active_model/validation_matcher.rb +20 -15
  91. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +1 -2
  92. data/lib/shoulda/matchers/active_record.rb +1 -12
  93. data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +89 -15
  94. data/lib/shoulda/matchers/active_record/association_matcher.rb +726 -70
  95. data/lib/shoulda/matchers/active_record/association_matchers.rb +9 -0
  96. data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +4 -3
  97. data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +4 -3
  98. data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +4 -3
  99. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +2 -1
  100. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +4 -3
  101. data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +4 -5
  102. data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +4 -3
  103. data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +4 -3
  104. data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +4 -3
  105. data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +79 -15
  106. data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +64 -15
  107. data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +21 -7
  108. data/lib/shoulda/matchers/active_record/serialize_matcher.rb +85 -10
  109. data/lib/shoulda/matchers/assertion_error.rb +7 -1
  110. data/lib/shoulda/matchers/doublespeak.rb +2 -1
  111. data/lib/shoulda/matchers/doublespeak/double.rb +3 -1
  112. data/lib/shoulda/matchers/doublespeak/double_collection.rb +2 -1
  113. data/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +1 -0
  114. data/lib/shoulda/matchers/doublespeak/object_double.rb +2 -1
  115. data/lib/shoulda/matchers/doublespeak/proxy_implementation.rb +2 -1
  116. data/lib/shoulda/matchers/doublespeak/structs.rb +2 -0
  117. data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +2 -1
  118. data/lib/shoulda/matchers/doublespeak/world.rb +3 -4
  119. data/lib/shoulda/matchers/error.rb +1 -0
  120. data/lib/shoulda/matchers/independent/delegate_matcher.rb +108 -20
  121. data/lib/shoulda/matchers/independent/delegate_matcher/stubbed_target.rb +4 -3
  122. data/lib/shoulda/matchers/integrations/nunit_test_case_detection.rb +3 -0
  123. data/lib/shoulda/matchers/rails_shim.rb +3 -2
  124. data/lib/shoulda/matchers/version.rb +2 -1
  125. data/lib/shoulda/matchers/warn.rb +1 -0
  126. data/script/SUPPORTED_VERSIONS +1 -0
  127. data/script/install_gems_in_all_appraisals +14 -0
  128. data/script/run_all_tests +14 -0
  129. data/shoulda-matchers.gemspec +0 -10
  130. data/spec/report_warnings.rb +7 -0
  131. data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +1 -1
  132. data/spec/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +9 -0
  133. data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +0 -36
  134. data/spec/shoulda/matchers/active_model/validation_message_finder_spec.rb +2 -2
  135. data/spec/shoulda/matchers/doublespeak/double_spec.rb +1 -1
  136. data/spec/shoulda/matchers/doublespeak/world_spec.rb +11 -29
  137. data/spec/shoulda/matchers/doublespeak_spec.rb +3 -3
  138. data/spec/spec_helper.rb +17 -0
  139. data/spec/support/class_builder.rb +4 -0
  140. data/spec/support/test_application.rb +1 -1
  141. data/spec/warnings_spy.rb +64 -0
  142. data/spec/warnings_spy/filesystem.rb +45 -0
  143. data/spec/warnings_spy/partitioner.rb +29 -0
  144. data/spec/warnings_spy/reader.rb +64 -0
  145. data/spec/warnings_spy/reporter.rb +87 -0
  146. metadata +49 -134
@@ -22,33 +22,8 @@ require 'shoulda/matchers/active_model/allow_mass_assignment_of_matcher'
22
22
  require 'shoulda/matchers/active_model/errors'
23
23
  require 'shoulda/matchers/active_model/have_secure_password_matcher'
24
24
 
25
-
26
25
  module Shoulda
27
26
  module Matchers
28
- # = Matchers for your active record models
29
- #
30
- # These matchers will test most of the validations of ActiveModel::Validations.
31
- #
32
- # describe User do
33
- # it { should validate_presence_of(:name) }
34
- # it { should validate_presence_of(:phone_number) }
35
- # %w(abcd 1234).each do |value|
36
- # it { should_not allow_value(value).for(:phone_number) }
37
- # end
38
- # it { should allow_value('(123) 456-7890').for(:phone_number) }
39
- # it { should_not allow_mass_assignment_of(:password) }
40
- # it { should allow_value('Activated', 'Pending').for(:status).strict }
41
- # it { should_not allow_value('Amazing').for(:status).strict }
42
- # end
43
- #
44
- # These tests work with the following model:
45
- #
46
- # class User < ActiveRecord::Base
47
- # validates_presence_of :name
48
- # validates_presence_of :phone_number
49
- # validates_inclusion_of :status, in: %w(Activated Pending), strict: true
50
- # attr_accessible :name, :phone_number
51
- # end
52
27
  module ActiveModel
53
28
  end
54
29
  end
@@ -1,21 +1,78 @@
1
- module Shoulda # :nodoc:
1
+ module Shoulda
2
2
  module Matchers
3
- module ActiveModel # :nodoc:
4
-
5
- # Ensures that the attribute can be set on mass update.
3
+ module ActiveModel
4
+ # The `allow_mass_assignment_of` matcher tests usage of Rails 3's
5
+ # `attr_accessible` and `attr_protected` macros, asserting that an
6
+ # attribute in your model is contained in either the whitelist or
7
+ # blacklist and thus can or cannot be set via mass assignment.
8
+ #
9
+ # class Post
10
+ # include ActiveModel::Model
11
+ # include ActiveModel::MassAssignmentSecurity
12
+ # attr_accessor :title
13
+ #
14
+ # attr_accessible :title
15
+ # end
16
+ #
17
+ # class User
18
+ # include ActiveModel::Model
19
+ # include ActiveModel::MassAssignmentSecurity
20
+ # attr_accessor :encrypted_password
21
+ #
22
+ # attr_protected :encrypted_password
23
+ # end
24
+ #
25
+ # # RSpec
26
+ # describe Post do
27
+ # it { should allow_mass_assignment_of(:title) }
28
+ # end
29
+ #
30
+ # describe User do
31
+ # it { should_not allow_mass_assignment_of(:encrypted_password) }
32
+ # end
33
+ #
34
+ # # Test::Unit
35
+ # class PostTest < ActiveSupport::TestCase
36
+ # should allow_mass_assignment_of(:title)
37
+ # end
38
+ #
39
+ # class UserTest < ActiveSupport::TestCase
40
+ # should_not allow_mass_assignment_of(:encrypted_password)
41
+ # end
42
+ #
43
+ # #### Optional qualifiers
44
+ #
45
+ # ##### as
46
+ #
47
+ # Use `as` if your mass-assignment rules apply only under a certain role
48
+ # *(Rails >= 3.1 only)*.
49
+ #
50
+ # class Post
51
+ # include ActiveModel::Model
52
+ # include ActiveModel::MassAssignmentSecurity
53
+ # attr_accessor :title
54
+ #
55
+ # attr_accessible :title, as: :admin
56
+ # end
6
57
  #
7
- # it { should_not allow_mass_assignment_of(:password) }
8
- # it { should allow_mass_assignment_of(:first_name) }
58
+ # # RSpec
59
+ # describe Post do
60
+ # it { should allow_mass_assignment_of(:title).as(:admin) }
61
+ # end
9
62
  #
10
- # In Rails 3.1 you can check role as well:
63
+ # # Test::Unit
64
+ # class PostTest < ActiveSupport::TestCase
65
+ # should allow_mass_assignment_of(:title).as(:admin)
66
+ # end
11
67
  #
12
- # it { should allow_mass_assignment_of(:first_name).as(:admin) }
68
+ # @return [AllowMassAssignmentOfMatcher]
13
69
  #
14
70
  def allow_mass_assignment_of(value)
15
71
  AllowMassAssignmentOfMatcher.new(value)
16
72
  end
17
73
 
18
- class AllowMassAssignmentOfMatcher # :nodoc:
74
+ # @private
75
+ class AllowMassAssignmentOfMatcher
19
76
  attr_reader :failure_message, :failure_message_when_negated
20
77
 
21
78
  alias failure_message_for_should failure_message
@@ -1,23 +1,164 @@
1
- module Shoulda # :nodoc:
1
+ module Shoulda
2
2
  module Matchers
3
- module ActiveModel # :nodoc:
4
-
5
- # Ensures that the attribute can be set to the given value or values. If
6
- # multiple values are given the match succeeds only if all given values
7
- # are allowed. Otherwise, the matcher fails at the first bad value in the
8
- # argument list (the remaining arguments are not processed then).
3
+ module ActiveModel
4
+ # The `allow_value` matcher is used to test that an attribute of a model
5
+ # can or cannot be set to a particular value or values. It is most
6
+ # commonly used in conjunction with the `validates_format_of` validation.
7
+ #
8
+ # #### should
9
+ #
10
+ # In the positive form, `allow_value` asserts that an attribute can be
11
+ # set to one or more values, succeeding if none of the values cause the
12
+ # record to be invalid:
13
+ #
14
+ # class UserProfile
15
+ # include ActiveModel::Model
16
+ # attr_accessor :website_url
17
+ #
18
+ # validates_format_of :website_url, with: URI.regexp
19
+ # end
20
+ #
21
+ # # RSpec
22
+ # describe UserProfile do
23
+ # it do
24
+ # should allow_value('http://foo.com', 'http://bar.com/baz').
25
+ # for(:website_url)
26
+ # end
27
+ # end
28
+ #
29
+ # # Test::Unit
30
+ # class UserProfileTest < ActiveSupport::TestCase
31
+ # should allow_value('http://foo.com', 'http://bar.com/baz').
32
+ # for(:website_url)
33
+ # end
34
+ #
35
+ # #### should_not
36
+ #
37
+ # In the negative form, `allow_value` asserts that an attribute cannot be
38
+ # set to one or more values, succeeding if the *first* value causes the
39
+ # record to be invalid.
40
+ #
41
+ # **This can be surprising** so in this case if you need to check that
42
+ # *all* of the values are invalid, use separate assertions:
43
+ #
44
+ # class UserProfile
45
+ # include ActiveModel::Model
46
+ # attr_accessor :website_url
47
+ #
48
+ # validates_format_of :website_url, with: URI.regexp
49
+ # end
50
+ #
51
+ # describe UserProfile do
52
+ # # One assertion: 'buz' and 'bar' will not be tested
53
+ # it { should_not allow_value('fiz', 'buz', 'bar').for(:website_url) }
54
+ #
55
+ # # Three assertions, all tested separately
56
+ # it { should_not allow_value('fiz').for(:website_url) }
57
+ # it { should_not allow_value('buz').for(:website_url) }
58
+ # it { should_not allow_value('bar').for(:website_url) }
59
+ # end
60
+ #
61
+ # #### Qualifiers
62
+ #
63
+ # ##### on
64
+ #
65
+ # Use `on` if your validation applies only under a certain context.
66
+ #
67
+ # class UserProfile
68
+ # include ActiveModel::Model
69
+ # attr_accessor :birthday_as_string
70
+ #
71
+ # validates_format_of :birthday_as_string,
72
+ # with: /^(\d+)-(\d+)-(\d+)$/,
73
+ # on: :create
74
+ # end
75
+ #
76
+ # # RSpec
77
+ # describe UserProfile do
78
+ # it do
79
+ # should allow_value('2013-01-01').
80
+ # for(:birthday_as_string).
81
+ # on(:create)
82
+ # end
83
+ # end
84
+ #
85
+ # # Test::Unit
86
+ # class UserProfileTest < ActiveSupport::TestCase
87
+ # should allow_value('2013-01-01').
88
+ # for(:birthday_as_string).
89
+ # on(:create)
90
+ # end
91
+ #
92
+ # ##### with_message
93
+ #
94
+ # Use `with_message` if you are using a custom validation message.
95
+ #
96
+ # class UserProfile
97
+ # include ActiveModel::Model
98
+ # attr_accessor :state
99
+ #
100
+ # validates_format_of :state,
101
+ # with: /^(open|closed)$/,
102
+ # message: 'State must be open or closed'
103
+ # end
104
+ #
105
+ # # RSpec
106
+ # describe UserProfile do
107
+ # it do
108
+ # should allow_value('open', 'closed').
109
+ # for(:state).
110
+ # with_message('State must be open or closed')
111
+ # end
112
+ # end
113
+ #
114
+ # # Test::Unit
115
+ # class UserProfileTest < ActiveSupport::TestCase
116
+ # should allow_value('open', 'closed').
117
+ # for(:state).
118
+ # with_message('State must be open or closed')
119
+ # end
120
+ #
121
+ # Use `with_message` with the `:against` option if the attribute the
122
+ # validation message is stored under is different from the attribute
123
+ # being validated.
124
+ #
125
+ # class UserProfile
126
+ # include ActiveModel::Model
127
+ # attr_accessor :sports_team
128
+ #
129
+ # validate :sports_team_must_be_valid
130
+ #
131
+ # private
132
+ #
133
+ # def sports_team_must_be_valid
134
+ # if sports_team !~ /^(Broncos|Titans)$/i
135
+ # self.errors.add :chosen_sports_team,
136
+ # 'Must be either a Broncos fan or a Titans fan'
137
+ # end
138
+ # end
139
+ # end
140
+ #
141
+ # # RSpec
142
+ # describe UserProfile do
143
+ # it do
144
+ # should allow_value('Broncos', 'Titans').
145
+ # for(:sports_team).
146
+ # with_message('Must be either a Broncos or Titans fan',
147
+ # against: :chosen_sports_team
148
+ # )
149
+ # end
150
+ # end
9
151
  #
10
- # Options:
11
- # * <tt>with_message</tt> - value the test expects to find in
12
- # <tt>errors.on(:attribute)</tt>. Regexp or string. If omitted,
13
- # the test looks for any errors in <tt>errors.on(:attribute)</tt>.
14
- # * <tt>strict</tt> - expects the model to raise an exception when the
15
- # validation fails rather than adding to the errors collection. Used for
16
- # testing `validates!` and the `strict: true` validation options.
152
+ # # Test::Unit
153
+ # class UserProfileTest < ActiveSupport::TestCase
154
+ # should allow_value('Broncos', 'Titans').
155
+ # for(:sports_team).
156
+ # with_message('Must be either a Broncos or Titans fan',
157
+ # against: :chosen_sports_team
158
+ # )
159
+ # end
17
160
  #
18
- # Example:
19
- # it { should_not allow_value('bad').for(:isbn) }
20
- # it { should allow_value('isbn 1 2345 6789 0').for(:isbn) }
161
+ # @return [AllowValueMatcher]
21
162
  #
22
163
  def allow_value(*values)
23
164
  if values.empty?
@@ -27,7 +168,8 @@ module Shoulda # :nodoc:
27
168
  end
28
169
  end
29
170
 
30
- class AllowValueMatcher # :nodoc:
171
+ # @private
172
+ class AllowValueMatcher
31
173
  include Helpers
32
174
 
33
175
  attr_accessor :attribute_with_message
@@ -95,7 +237,7 @@ module Shoulda # :nodoc:
95
237
  message_finder.allow_description(allowed_values)
96
238
  end
97
239
 
98
- private
240
+ protected
99
241
 
100
242
  attr_accessor :values_to_match, :message_finder_factory,
101
243
  :instance, :attribute_to_set, :attribute_to_check_message_against,
@@ -1,13 +1,13 @@
1
1
  require 'forwardable'
2
2
 
3
- module Shoulda # :nodoc:
3
+ module Shoulda
4
4
  module Matchers
5
- module ActiveModel # :nodoc:
6
- class DisallowValueMatcher # :nodoc:
5
+ module ActiveModel
6
+ # @private
7
+ class DisallowValueMatcher
7
8
  extend Forwardable
8
9
 
9
10
  def_delegators :allow_matcher, :_after_setting_value
10
-
11
11
  def initialize(value)
12
12
  @allow_matcher = AllowValueMatcher.new(value)
13
13
  end
@@ -46,7 +46,7 @@ module Shoulda # :nodoc:
46
46
  self
47
47
  end
48
48
 
49
- private
49
+ protected
50
50
 
51
51
  attr_reader :allow_matcher
52
52
  end
@@ -1,24 +1,103 @@
1
- module Shoulda # :nodoc:
1
+ module Shoulda
2
2
  module Matchers
3
- module ActiveModel # :nodoc:
4
-
5
- # Ensure that the attribute's value is not in the range specified
3
+ module ActiveModel
4
+ # The `ensure_exclusion_of` matcher tests usage of the
5
+ # `validates_exclusion_of` validation, asserting that an attribute cannot
6
+ # take a blacklist of values, and inversely, can take values outside of
7
+ # this list.
8
+ #
9
+ # If your blacklist is an array of values, use `in_array`:
10
+ #
11
+ # class Game
12
+ # include ActiveModel::Model
13
+ # attr_accessor :supported_os
14
+ #
15
+ # validates_exclusion_of :supported_os, in: ['Mac', 'Linux']
16
+ # end
17
+ #
18
+ # # RSpec
19
+ # describe Game do
20
+ # it do
21
+ # should ensure_exclusion_of(:supported_os).
22
+ # in_array(['Mac', 'Linux'])
23
+ # end
24
+ # end
25
+ #
26
+ # # Test::Unit
27
+ # class GameTest < ActiveSupport::TestCase
28
+ # should ensure_exclusion_of(:supported_os).
29
+ # in_array(['Mac', 'Linux'])
30
+ # end
31
+ #
32
+ # If your blacklist is a range of values, use `in_rnage`:
33
+ #
34
+ # class Game
35
+ # include ActiveModel::Model
36
+ # attr_accessor :supported_os
37
+ #
38
+ # validates_exclusion_of :supported_os, in: ['Mac', 'Linux']
39
+ # end
40
+ #
41
+ # # RSpec
42
+ # describe Game do
43
+ # it do
44
+ # should ensure_exclusion_of(:floors_with_enemies).
45
+ # in_range(5..8)
46
+ # end
47
+ # end
6
48
  #
7
- # Options:
8
- # * <tt>in_array</tt> - the array of not allowed values for this attribute
9
- # * <tt>in_range</tt> - the range of not allowed values for this attribute
10
- # * <tt>with_message</tt> - value the test expects to find in
11
- # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
12
- # translation for :exclusion.
49
+ # # Test::Unit
50
+ # class GameTest < ActiveSupport::TestCase
51
+ # should ensure_exclusion_of(:floors_with_enemies).
52
+ # in_range(5..8)
53
+ # end
13
54
  #
14
- # Example:
15
- # it { should ensure_exclusion_of(:age).in_range(30..60) }
55
+ # #### Qualifiers
56
+ #
57
+ # ##### with_message
58
+ #
59
+ # Use `with_message` if you are using a custom validation message.
60
+ #
61
+ # class Game
62
+ # include ActiveModel::Model
63
+ # attr_accessor :weapon
64
+ #
65
+ # validates_exclusion_of :weapon,
66
+ # in: ['pistol', 'paintball gun', 'stick'],
67
+ # message: 'You chose a puny weapon'
68
+ # end
69
+ #
70
+ # # RSpec
71
+ # describe Game do
72
+ # it do
73
+ # should ensure_exclusion_of(:weapon).
74
+ # in_array(['pistol', 'paintball gun', 'stick']).
75
+ # with_message('You chose a puny weapon')
76
+ # end
77
+ # end
78
+ #
79
+ # # Test::Unit
80
+ # class GameTest < ActiveSupport::TestCase
81
+ # should ensure_exclusion_of(:weapon).
82
+ # in_array(['pistol', 'paintball gun', 'stick']).
83
+ # with_message('You chose a puny weapon')
84
+ # end
85
+ #
86
+ # @return [EnsureExclusionOfMatcher]
16
87
  #
17
88
  def ensure_exclusion_of(attr)
18
89
  EnsureExclusionOfMatcher.new(attr)
19
90
  end
20
91
 
21
- class EnsureExclusionOfMatcher < ValidationMatcher # :nodoc:
92
+ # @private
93
+ class EnsureExclusionOfMatcher < ValidationMatcher
94
+ def initialize(attribute)
95
+ super(attribute)
96
+ @array = nil
97
+ @range = nil
98
+ @expected_message = nil
99
+ end
100
+
22
101
  def in_array(array)
23
102
  @array = array
24
103
  self