shoulda-matchers 2.8.0 → 3.0.0.rc1

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.
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)