shoulda-matchers 2.8.0 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/.hound_config/ruby.yml +7 -0
  3. data/.travis.yml +11 -54
  4. data/Appraisals +45 -100
  5. data/CONTRIBUTING.md +51 -7
  6. data/Gemfile +7 -19
  7. data/Gemfile.lock +60 -134
  8. data/Guardfile +5 -0
  9. data/NEWS.md +203 -0
  10. data/README.md +95 -50
  11. data/Rakefile +1 -0
  12. data/doc_config/yard/templates/default/layout/html/setup.rb +1 -1
  13. data/gemfiles/4.0.0.gemfile +10 -7
  14. data/gemfiles/4.0.0.gemfile.lock +103 -79
  15. data/gemfiles/4.0.1.gemfile +10 -7
  16. data/gemfiles/4.0.1.gemfile.lock +109 -83
  17. data/gemfiles/4.1.gemfile +10 -7
  18. data/gemfiles/4.1.gemfile.lock +109 -85
  19. data/gemfiles/4.2.gemfile +10 -9
  20. data/gemfiles/4.2.gemfile.lock +86 -78
  21. data/lib/shoulda/matchers.rb +13 -18
  22. data/lib/shoulda/matchers/action_controller.rb +4 -1
  23. data/lib/shoulda/matchers/action_controller/flash_store.rb +95 -0
  24. data/lib/shoulda/matchers/action_controller/{strong_parameters_matcher.rb → permit_matcher.rb} +147 -30
  25. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +1 -1
  26. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +1 -1
  27. data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +1 -1
  28. data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +1 -1
  29. data/lib/shoulda/matchers/action_controller/route_matcher.rb +5 -1
  30. data/lib/shoulda/matchers/action_controller/route_params.rb +15 -6
  31. data/lib/shoulda/matchers/action_controller/session_store.rb +34 -0
  32. data/lib/shoulda/matchers/action_controller/set_flash_matcher.rb +30 -136
  33. data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +28 -109
  34. data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +103 -0
  35. data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +1 -12
  36. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +79 -10
  37. data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +10 -0
  38. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +21 -0
  39. data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +24 -0
  40. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +22 -5
  41. data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +29 -10
  42. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +27 -10
  43. data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +27 -12
  44. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +56 -20
  45. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +3 -11
  46. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +65 -0
  47. data/lib/shoulda/matchers/active_record/association_matcher.rb +40 -6
  48. data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +21 -7
  49. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +11 -40
  50. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +1 -1
  51. data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +2 -6
  52. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +137 -22
  53. data/lib/shoulda/matchers/configuration.rb +20 -0
  54. data/lib/shoulda/matchers/doublespeak.rb +11 -1
  55. data/lib/shoulda/matchers/doublespeak/double.rb +29 -11
  56. data/lib/shoulda/matchers/doublespeak/double_collection.rb +4 -3
  57. data/lib/shoulda/matchers/doublespeak/method_call.rb +35 -0
  58. data/lib/shoulda/matchers/doublespeak/object_double.rb +7 -2
  59. data/lib/shoulda/matchers/doublespeak/proxy_implementation.rb +4 -3
  60. data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +3 -3
  61. data/lib/shoulda/matchers/doublespeak/world.rb +21 -1
  62. data/lib/shoulda/matchers/integrations.rb +43 -0
  63. data/lib/shoulda/matchers/integrations/configuration.rb +68 -0
  64. data/lib/shoulda/matchers/integrations/configuration_error.rb +9 -0
  65. data/lib/shoulda/matchers/integrations/inclusion.rb +20 -0
  66. data/lib/shoulda/matchers/integrations/libraries.rb +15 -0
  67. data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +31 -0
  68. data/lib/shoulda/matchers/integrations/libraries/active_model.rb +26 -0
  69. data/lib/shoulda/matchers/integrations/libraries/active_record.rb +26 -0
  70. data/lib/shoulda/matchers/integrations/libraries/missing_library.rb +19 -0
  71. data/lib/shoulda/matchers/integrations/libraries/rails.rb +30 -0
  72. data/lib/shoulda/matchers/integrations/rails.rb +12 -0
  73. data/lib/shoulda/matchers/integrations/registry.rb +28 -0
  74. data/lib/shoulda/matchers/integrations/test_frameworks.rb +16 -0
  75. data/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +37 -0
  76. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +36 -0
  77. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +37 -0
  78. data/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +40 -0
  79. data/lib/shoulda/matchers/integrations/test_frameworks/rspec.rb +29 -0
  80. data/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +36 -0
  81. data/lib/shoulda/matchers/rails_shim.rb +0 -40
  82. data/lib/shoulda/matchers/version.rb +1 -1
  83. data/script/SUPPORTED_VERSIONS +1 -1
  84. data/script/update_gems_in_all_appraisals +14 -0
  85. data/shoulda-matchers.gemspec +2 -2
  86. data/spec/acceptance/active_model_integration_spec.rb +4 -1
  87. data/spec/acceptance/independent_matchers_spec.rb +6 -6
  88. data/spec/acceptance/multiple_libraries_integration_spec.rb +52 -0
  89. data/spec/acceptance/rails_integration_spec.rb +15 -5
  90. data/spec/acceptance_spec_helper.rb +8 -0
  91. data/spec/doublespeak_spec_helper.rb +14 -0
  92. data/spec/support/acceptance/adds_shoulda_matchers_to_project.rb +110 -0
  93. data/spec/support/acceptance/helpers.rb +2 -0
  94. data/spec/support/acceptance/helpers/base_helpers.rb +6 -1
  95. data/spec/support/acceptance/helpers/command_helpers.rb +6 -2
  96. data/spec/support/acceptance/helpers/minitest_helpers.rb +0 -8
  97. data/spec/support/acceptance/helpers/n_unit_helpers.rb +25 -0
  98. data/spec/support/acceptance/helpers/rspec_helpers.rb +2 -0
  99. data/spec/support/acceptance/helpers/step_helpers.rb +13 -19
  100. data/spec/support/acceptance/matchers/have_output.rb +1 -1
  101. data/spec/support/tests/bundle.rb +1 -1
  102. data/spec/support/tests/command_runner.rb +25 -13
  103. data/spec/support/tests/current_bundle.rb +47 -0
  104. data/spec/support/tests/database.rb +28 -0
  105. data/spec/support/tests/database_adapters/postgresql.rb +25 -0
  106. data/spec/support/tests/database_adapters/sqlite3.rb +26 -0
  107. data/spec/support/tests/database_configuration.rb +33 -0
  108. data/spec/support/tests/database_configuration_registry.rb +28 -0
  109. data/spec/support/tests/filesystem.rb +25 -2
  110. data/spec/support/unit/helpers/active_record_versions.rb +12 -0
  111. data/spec/support/unit/helpers/class_builder.rb +6 -2
  112. data/spec/support/unit/helpers/column_type_helpers.rb +26 -0
  113. data/spec/support/unit/helpers/controller_builder.rb +0 -28
  114. data/spec/support/unit/helpers/database_helpers.rb +18 -0
  115. data/spec/support/unit/helpers/model_builder.rb +38 -6
  116. data/spec/support/unit/helpers/rails_versions.rb +2 -2
  117. data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +9 -8
  118. data/spec/support/unit/matchers/fail_with_message_matcher.rb +1 -1
  119. data/spec/support/unit/rails_application.rb +29 -13
  120. data/spec/support/unit/record_validating_confirmation_builder.rb +1 -2
  121. data/spec/support/unit/shared_examples/set_session_or_flash.rb +355 -0
  122. data/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb +433 -0
  123. data/spec/unit/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +1 -5
  124. data/spec/unit/shoulda/matchers/action_controller/route_matcher_spec.rb +37 -0
  125. data/spec/unit/shoulda/matchers/action_controller/set_flash_matcher_spec.rb +23 -147
  126. data/spec/unit/shoulda/matchers/action_controller/set_session_matcher_spec.rb +8 -285
  127. data/spec/unit/shoulda/matchers/action_controller/set_session_or_flash_matcher_spec.rb +562 -0
  128. data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +81 -14
  129. data/spec/unit/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +16 -8
  130. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +101 -9
  131. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +39 -1
  132. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +39 -1
  133. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +39 -0
  134. data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +0 -17
  135. data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +0 -17
  136. data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +0 -17
  137. data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +838 -271
  138. data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +0 -19
  139. data/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +93 -0
  140. data/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +3 -3
  141. data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +25 -0
  142. data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +905 -0
  143. data/spec/unit/shoulda/matchers/doublespeak/double_collection_spec.rb +17 -11
  144. data/spec/unit/shoulda/matchers/doublespeak/double_implementation_registry_spec.rb +1 -1
  145. data/spec/unit/shoulda/matchers/doublespeak/double_spec.rb +144 -43
  146. data/spec/unit/shoulda/matchers/doublespeak/object_double_spec.rb +1 -1
  147. data/spec/unit/shoulda/matchers/doublespeak/proxy_implementation_spec.rb +36 -11
  148. data/spec/unit/shoulda/matchers/doublespeak/stub_implementation_spec.rb +29 -16
  149. data/spec/unit/shoulda/matchers/doublespeak/world_spec.rb +8 -5
  150. data/spec/unit/shoulda/matchers/doublespeak_spec.rb +1 -1
  151. data/spec/unit_spec_helper.rb +15 -14
  152. data/spec/warnings_spy.rb +1 -1
  153. metadata +68 -29
  154. data/docs.watchr +0 -5
  155. data/gemfiles/3.0.gemfile +0 -26
  156. data/gemfiles/3.0.gemfile.lock +0 -173
  157. data/gemfiles/3.1.gemfile +0 -32
  158. data/gemfiles/3.1.gemfile.lock +0 -212
  159. data/gemfiles/3.1_1.9.2.gemfile +0 -32
  160. data/gemfiles/3.1_1.9.2.gemfile.lock +0 -212
  161. data/gemfiles/3.2.gemfile +0 -33
  162. data/gemfiles/3.2.gemfile.lock +0 -212
  163. data/gemfiles/3.2_1.9.2.gemfile +0 -31
  164. data/gemfiles/3.2_1.9.2.gemfile.lock +0 -207
  165. data/lib/shoulda/matchers/assertion_error.rb +0 -27
  166. data/lib/shoulda/matchers/doublespeak/structs.rb +0 -10
  167. data/lib/shoulda/matchers/integrations/nunit_test_case_detection.rb +0 -39
  168. data/lib/shoulda/matchers/integrations/rspec.rb +0 -19
  169. data/lib/shoulda/matchers/integrations/test_unit.rb +0 -34
  170. data/spec/unit/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +0 -331
  171. data/spec/unit/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +0 -564
@@ -0,0 +1,103 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActionController
4
+ # @private
5
+ class SetSessionOrFlashMatcher
6
+ def initialize(store)
7
+ @store = store
8
+ end
9
+
10
+ def in_context(context)
11
+ @context = context
12
+ self
13
+ end
14
+
15
+ def [](key)
16
+ @key = key
17
+ self
18
+ end
19
+
20
+ def to(expected_value = nil, &block)
21
+ if block
22
+ unless context_set?
23
+ message = "When specifying a value as a block, a context must be specified beforehand, e.g., #{store.name}.in_context(context).to { ... }"
24
+ raise ArgumentError, message
25
+ end
26
+
27
+ @expected_value = context.instance_eval(&block)
28
+ else
29
+ @expected_value = expected_value
30
+ end
31
+
32
+ self
33
+ end
34
+
35
+ def description
36
+ "should #{expectation_description}"
37
+ end
38
+
39
+ def matches?(controller)
40
+ @controller = store.controller = controller
41
+ !store.empty? && key_matches? && expected_value_matches?
42
+ end
43
+
44
+ def failure_message
45
+ "Expected #{controller.class} to #{expectation_description}, but it did not"
46
+ end
47
+ alias_method :failure_message_for_should, :failure_message
48
+
49
+ def failure_message_when_negated
50
+ "Expected #{controller.class} not to #{expectation_description}, but it did"
51
+ end
52
+ alias_method :failure_message_for_should_not,
53
+ :failure_message_when_negated
54
+
55
+ protected
56
+
57
+ attr_reader :store, :context, :key, :expected_value, :controller
58
+
59
+ private
60
+
61
+ def context_set?
62
+ defined?(@context)
63
+ end
64
+
65
+ def key_set?
66
+ defined?(@key)
67
+ end
68
+
69
+ def expected_value_set?
70
+ defined?(@expected_value)
71
+ end
72
+
73
+ def key_matches?
74
+ !key_set? || store.has_key?(key)
75
+ end
76
+
77
+ def expected_value_matches?
78
+ !expected_value_set? || store.has_value?(expected_value)
79
+ end
80
+
81
+ def expectation_description
82
+ string = 'set'
83
+
84
+ if key_set?
85
+ string << " #{store.name}[#{key.inspect}]"
86
+ else
87
+ string << " any key in #{store.name}"
88
+ end
89
+
90
+ if expected_value_set?
91
+ if expected_value.is_a?(Regexp)
92
+ string << " to a value matching #{expected_value.inspect}"
93
+ else
94
+ string << " to #{expected_value.inspect}"
95
+ end
96
+ end
97
+
98
+ string
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -84,9 +84,6 @@ module Shoulda
84
84
  end
85
85
 
86
86
  def as(role)
87
- if active_model_less_than_3_1?
88
- raise 'You can specify role only in Rails 3.1 or greater'
89
- end
90
87
  @options[:role] = role
91
88
  self
92
89
  end
@@ -153,20 +150,12 @@ module Shoulda
153
150
  end
154
151
 
155
152
  def authorizer
156
- if active_model_less_than_3_1?
157
- @subject.class.active_authorizer
158
- else
159
- @subject.class.active_authorizer[role]
160
- end
153
+ @subject.class.active_authorizer[role]
161
154
  end
162
155
 
163
156
  def class_name
164
157
  @subject.class.name
165
158
  end
166
-
167
- def active_model_less_than_3_1?
168
- ::ActiveModel::VERSION::STRING.to_f < 3.1
169
- end
170
159
  end
171
160
  end
172
161
  end
@@ -118,9 +118,36 @@ module Shoulda
118
118
  # with_message('State must be open or closed')
119
119
  # end
120
120
  #
121
+ # Use `with_message` with a regexp to perform a partial match:
122
+ #
123
+ # class UserProfile
124
+ # include ActiveModel::Model
125
+ # attr_accessor :state
126
+ #
127
+ # validates_format_of :state,
128
+ # with: /^(open|closed)$/,
129
+ # message: 'State must be open or closed'
130
+ # end
131
+ #
132
+ # # RSpec
133
+ # describe UserProfile do
134
+ # it do
135
+ # should allow_value('open', 'closed').
136
+ # for(:state).
137
+ # with_message(/open or closed/)
138
+ # end
139
+ # end
140
+ #
141
+ # # Test::Unit
142
+ # class UserProfileTest < ActiveSupport::TestCase
143
+ # should allow_value('open', 'closed').
144
+ # for(:state).
145
+ # with_message(/open or closed/)
146
+ # end
147
+ #
121
148
  # Use `with_message` with the `:against` option if the attribute the
122
149
  # validation message is stored under is different from the attribute
123
- # being validated.
150
+ # being validated:
124
151
  #
125
152
  # class UserProfile
126
153
  # include ActiveModel::Model
@@ -167,9 +194,28 @@ module Shoulda
167
194
  AllowValueMatcher.new(*values)
168
195
  end
169
196
  end
197
+ alias_method :allow_values, :allow_value
170
198
 
171
199
  # @private
172
200
  class AllowValueMatcher
201
+ # @private
202
+ class CouldNotSetAttributeError < Shoulda::Matchers::Error
203
+ def self.create(model, attribute, expected_value, actual_value)
204
+ super(
205
+ model: model,
206
+ attribute: attribute,
207
+ expected_value: expected_value,
208
+ actual_value: actual_value
209
+ )
210
+ end
211
+
212
+ attr_accessor :model, :attribute, :expected_value, :actual_value
213
+
214
+ def message
215
+ "Expected #{model.class} to be able to set #{attribute} to #{expected_value.inspect}, but got #{actual_value.inspect} instead."
216
+ end
217
+ end
218
+
173
219
  include Helpers
174
220
 
175
221
  attr_accessor :attribute_with_message
@@ -215,14 +261,12 @@ module Shoulda
215
261
 
216
262
  def matches?(instance)
217
263
  self.instance = instance
218
- validator.record = instance
264
+ values_to_match.all? { |value| value_matches?(value) }
265
+ end
219
266
 
220
- values_to_match.none? do |value|
221
- validator.reset
222
- self.value = value
223
- set_attribute(value)
224
- errors_match? || any_range_error_occurred?
225
- end
267
+ def does_not_match?(instance)
268
+ self.instance = instance
269
+ values_to_match.all? { |value| !value_matches?(value) }
226
270
  end
227
271
 
228
272
  def failure_message
@@ -241,15 +285,26 @@ module Shoulda
241
285
 
242
286
  protected
243
287
 
244
- attr_reader :attribute_to_check_message_against
245
- attr_accessor :values_to_match, :instance, :attribute_to_set, :value,
288
+ attr_reader :instance, :attribute_to_check_message_against
289
+ attr_accessor :values_to_match, :attribute_to_set, :value,
246
290
  :matched_error, :after_setting_value_callback, :validator
247
291
 
292
+ def instance=(instance)
293
+ @instance = instance
294
+ validator.record = instance
295
+ end
296
+
248
297
  def attribute_to_check_message_against=(attribute)
249
298
  @attribute_to_check_message_against = attribute
250
299
  validator.attribute = attribute
251
300
  end
252
301
 
302
+ def value_matches?(value)
303
+ self.value = value
304
+ set_attribute(value)
305
+ !(errors_match? || any_range_error_occurred?)
306
+ end
307
+
253
308
  def set_attribute(value)
254
309
  set_attribute_ignoring_range_errors(value)
255
310
  after_setting_value_callback.call
@@ -257,6 +312,7 @@ module Shoulda
257
312
 
258
313
  def set_attribute_ignoring_range_errors(value)
259
314
  instance.__send__("#{attribute_to_set}=", value)
315
+ ensure_that_attribute_has_been_changed_to_or_from_nil!(value)
260
316
  rescue RangeError => exception
261
317
  # Have to reset the attribute so that we don't get a RangeError the
262
318
  # next time we attempt to write the attribute (ActiveRecord seems to
@@ -269,6 +325,19 @@ module Shoulda
269
325
  instance.send(:raw_write_attribute, attribute_to_set, nil)
270
326
  end
271
327
 
328
+ def ensure_that_attribute_has_been_changed_to_or_from_nil!(expected_value)
329
+ actual_value = instance.__send__(attribute_to_set)
330
+
331
+ if expected_value.nil? != actual_value.nil?
332
+ raise CouldNotSetAttributeError.create(
333
+ instance.class,
334
+ attribute_to_set,
335
+ expected_value,
336
+ actual_value
337
+ )
338
+ end
339
+ end
340
+
272
341
  def errors_match?
273
342
  has_messages? && errors_for_attribute_match?
274
343
  end
@@ -17,6 +17,16 @@ module Shoulda
17
17
  self
18
18
  end
19
19
 
20
+ def strict
21
+ @disallow_value_matcher.strict
22
+ self
23
+ end
24
+
25
+ def on(context)
26
+ @disallow_value_matcher.on(context)
27
+ self
28
+ end
29
+
20
30
  def allowed_type
21
31
  raise NotImplementedError
22
32
  end
@@ -23,6 +23,27 @@ module Shoulda
23
23
  #
24
24
  # #### Qualifiers
25
25
  #
26
+ # ##### on
27
+ #
28
+ # Use `on` if your validation applies only under a certain context.
29
+ #
30
+ # class Artillery
31
+ # include ActiveModel::Model
32
+ # attr_accessor :arms
33
+ #
34
+ # validates_absence_of :arms, on: :create
35
+ # end
36
+ #
37
+ # # RSpec
38
+ # describe Artillery do
39
+ # it { should validate_absence_of(:arms).on(:create) }
40
+ # end
41
+ #
42
+ # # Test::Unit
43
+ # class ArtilleryTest < ActiveSupport::TestCase
44
+ # should validate_absence_of(:arms).on(:create)
45
+ # end
46
+ #
26
47
  # ##### with_message
27
48
  #
28
49
  # Use `with_message` if you are using a custom validation message.
@@ -23,6 +23,30 @@ module Shoulda
23
23
  #
24
24
  # #### Qualifiers
25
25
  #
26
+ # ##### on
27
+ #
28
+ # Use `on` if your validation applies only under a certain context.
29
+ #
30
+ # class Registration
31
+ # include ActiveModel::Model
32
+ # attr_accessor :terms_of_service
33
+ #
34
+ # validates_acceptance_of :terms_of_service, on: :create
35
+ # end
36
+ #
37
+ # # RSpec
38
+ # describe Registration do
39
+ # it do
40
+ # should validate_acceptance_of(:terms_of_service).
41
+ # on(:create)
42
+ # end
43
+ # end
44
+ #
45
+ # # Test::Unit
46
+ # class RegistrationTest < ActiveSupport::TestCase
47
+ # should validate_acceptance_of(:terms_of_service).on(:create)
48
+ # end
49
+ #
26
50
  # ##### with_message
27
51
  #
28
52
  # Use `with_message` if you are using a custom validation message.
@@ -23,6 +23,27 @@ module Shoulda
23
23
  #
24
24
  # #### Qualifiers
25
25
  #
26
+ # ##### on
27
+ #
28
+ # Use `on` if your validation applies only under a certain context.
29
+ #
30
+ # class User
31
+ # include ActiveModel::Model
32
+ # attr_accessor :password
33
+ #
34
+ # validates_confirmation_of :password, on: :create
35
+ # end
36
+ #
37
+ # # RSpec
38
+ # describe User do
39
+ # it { should validate_confirmation_of(:password).on(:create) }
40
+ # end
41
+ #
42
+ # # Test::Unit
43
+ # class UserTest < ActiveSupport::TestCase
44
+ # should validate_confirmation_of(:password).on(:create)
45
+ # end
46
+ #
26
47
  # ##### with_message
27
48
  #
28
49
  # Use `with_message` if you are using a custom validation message.
@@ -109,7 +130,7 @@ module Shoulda
109
130
 
110
131
  def qualify_matcher(matcher)
111
132
  matcher.with_message(@message,
112
- against: error_attribute,
133
+ against: confirmation_attribute,
113
134
  values: { attribute: attribute }
114
135
  )
115
136
  end
@@ -120,10 +141,6 @@ module Shoulda
120
141
  @subject.__send__(setter, val)
121
142
  end
122
143
  end
123
-
124
- def error_attribute
125
- RailsShim.validates_confirmation_of_error_attribute(self)
126
- end
127
144
  end
128
145
  end
129
146
  end
@@ -54,6 +54,35 @@ module Shoulda
54
54
  #
55
55
  # #### Qualifiers
56
56
  #
57
+ # ##### on
58
+ #
59
+ # Use `on` if your validation applies only under a certain context.
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
+ # on: :create
68
+ # end
69
+ #
70
+ # # RSpec
71
+ # describe Game do
72
+ # it do
73
+ # should validate_exclusion_of(:weapon).
74
+ # in_array(['pistol', 'paintball gun', 'stick']).
75
+ # on(:create)
76
+ # end
77
+ # end
78
+ #
79
+ # # Test::Unit
80
+ # class GameTest < ActiveSupport::TestCase
81
+ # should validate_exclusion_of(:weapon).
82
+ # in_array(['pistol', 'paintball gun', 'stick']).
83
+ # on(:create)
84
+ # end
85
+ #
57
86
  # ##### with_message
58
87
  #
59
88
  # Use `with_message` if you are using a custom validation message.
@@ -89,16 +118,6 @@ module Shoulda
89
118
  ValidateExclusionOfMatcher.new(attr)
90
119
  end
91
120
 
92
- # @deprecated Use {#validate_exclusion_of} instead.
93
- # @return [ValidateExclusionOfMatcher]
94
- def ensure_exclusion_of(attr)
95
- Shoulda::Matchers.warn_about_deprecated_method(
96
- :ensure_exclusion_of,
97
- :validate_exclusion_of
98
- )
99
- validate_exclusion_of(attr)
100
- end
101
-
102
121
  # @private
103
122
  class ValidateExclusionOfMatcher < ValidationMatcher
104
123
  def initialize(attribute)