shoulda-matchers 3.0.1 → 3.1.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.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -3
  4. data/CONTRIBUTING.md +60 -28
  5. data/Gemfile +1 -0
  6. data/Gemfile.lock +15 -12
  7. data/NEWS.md +111 -0
  8. data/README.md +94 -6
  9. data/Rakefile +10 -8
  10. data/custom_plan.rb +88 -0
  11. data/gemfiles/4.0.0.gemfile +1 -0
  12. data/gemfiles/4.0.0.gemfile.lock +21 -18
  13. data/gemfiles/4.0.1.gemfile +1 -0
  14. data/gemfiles/4.0.1.gemfile.lock +21 -18
  15. data/gemfiles/4.1.gemfile +1 -0
  16. data/gemfiles/4.1.gemfile.lock +21 -18
  17. data/gemfiles/4.2.gemfile +1 -0
  18. data/gemfiles/4.2.gemfile.lock +24 -21
  19. data/lib/shoulda/matchers/action_controller/permit_matcher.rb +6 -11
  20. data/lib/shoulda/matchers/active_model.rb +10 -1
  21. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +258 -180
  22. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +45 -0
  23. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error.rb +23 -0
  24. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +236 -0
  25. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +62 -0
  26. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +40 -0
  27. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +48 -0
  28. data/lib/shoulda/matchers/active_model/allow_value_matcher/successful_check.rb +14 -0
  29. data/lib/shoulda/matchers/active_model/allow_value_matcher/successful_setting.rb +14 -0
  30. data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +34 -14
  31. data/lib/shoulda/matchers/active_model/helpers.rb +9 -17
  32. data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +13 -6
  33. data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +13 -2
  34. data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +19 -35
  35. data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +13 -2
  36. data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +12 -2
  37. data/lib/shoulda/matchers/active_model/qualifiers.rb +12 -0
  38. data/lib/shoulda/matchers/active_model/qualifiers/ignore_interference_by_writer.rb +101 -0
  39. data/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +21 -0
  40. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +30 -32
  41. data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +5 -8
  42. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +22 -22
  43. data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +27 -16
  44. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +58 -15
  45. data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +22 -12
  46. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +165 -87
  47. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +7 -9
  48. data/lib/shoulda/matchers/active_model/validation_matcher.rb +111 -49
  49. data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +60 -0
  50. data/lib/shoulda/matchers/active_model/validator.rb +71 -52
  51. data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +19 -5
  52. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +450 -124
  53. data/lib/shoulda/matchers/util.rb +43 -0
  54. data/lib/shoulda/matchers/util/word_wrap.rb +59 -31
  55. data/lib/shoulda/matchers/version.rb +1 -1
  56. data/script/update_gem_in_all_appraisals +1 -1
  57. data/script/update_gems_in_all_appraisals +1 -1
  58. data/spec/acceptance/multiple_libraries_integration_spec.rb +5 -2
  59. data/spec/acceptance/rails_integration_spec.rb +6 -2
  60. data/spec/spec_helper.rb +1 -3
  61. data/spec/support/acceptance/helpers/step_helpers.rb +4 -1
  62. data/spec/support/tests/current_bundle.rb +21 -7
  63. data/spec/support/unit/active_record/create_table.rb +54 -0
  64. data/spec/support/unit/attribute.rb +47 -0
  65. data/spec/support/unit/capture.rb +6 -0
  66. data/spec/support/unit/change_value.rb +111 -0
  67. data/spec/support/unit/create_model_arguments/basic.rb +135 -0
  68. data/spec/support/unit/create_model_arguments/has_many.rb +15 -0
  69. data/spec/support/unit/create_model_arguments/uniqueness_matcher.rb +74 -0
  70. data/spec/support/unit/helpers/active_record_versions.rb +1 -1
  71. data/spec/support/unit/helpers/class_builder.rb +61 -47
  72. data/spec/support/unit/helpers/database_helpers.rb +5 -3
  73. data/spec/support/unit/helpers/model_builder.rb +77 -97
  74. data/spec/support/unit/helpers/validation_matcher_scenario_helpers.rb +44 -0
  75. data/spec/support/unit/load_environment.rb +12 -0
  76. data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +2 -2
  77. data/spec/support/unit/matchers/fail_with_message_matcher.rb +12 -1
  78. data/spec/support/unit/model_creation_strategies/active_model.rb +111 -0
  79. data/spec/support/unit/model_creation_strategies/active_record.rb +77 -0
  80. data/spec/support/unit/model_creators.rb +19 -0
  81. data/spec/support/unit/model_creators/active_model.rb +39 -0
  82. data/spec/support/unit/model_creators/active_record.rb +43 -0
  83. data/spec/support/unit/model_creators/active_record/has_and_belongs_to_many.rb +95 -0
  84. data/spec/support/unit/model_creators/active_record/has_many.rb +67 -0
  85. data/spec/support/unit/model_creators/active_record/uniqueness_matcher.rb +42 -0
  86. data/spec/support/unit/model_creators/basic.rb +97 -0
  87. data/spec/support/unit/rails_application.rb +1 -1
  88. data/spec/support/unit/record_validating_confirmation_builder.rb +3 -7
  89. data/spec/support/unit/shared_examples/ignoring_interference_by_writer.rb +79 -0
  90. data/spec/support/unit/validation_matcher_scenario.rb +62 -0
  91. data/spec/unit/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +4 -0
  92. data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +575 -140
  93. data/spec/unit/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +115 -15
  94. data/spec/unit/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +42 -4
  95. data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +92 -6
  96. data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +122 -10
  97. data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +306 -58
  98. data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +122 -3
  99. data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +805 -131
  100. data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +196 -29
  101. data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +82 -40
  102. data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +600 -101
  103. data/spec/unit/shoulda/matchers/util/word_wrap_spec.rb +88 -33
  104. data/spec/unit_spec_helper.rb +10 -22
  105. data/zeus.json +11 -0
  106. metadata +64 -23
  107. data/lib/shoulda/matchers/active_model/strict_validator.rb +0 -51
  108. data/spec/support/unit/shared_examples/numerical_type_submatcher.rb +0 -15
  109. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +0 -288
  110. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +0 -100
  111. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +0 -100
  112. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +0 -100
@@ -0,0 +1,21 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActiveModel
4
+ module Qualifiers
5
+ # @private
6
+ module IgnoringInterferenceByWriter
7
+ attr_reader :ignore_interference_by_writer
8
+
9
+ def initialize(*args)
10
+ @ignore_interference_by_writer = IgnoreInterferenceByWriter.new
11
+ end
12
+
13
+ def ignoring_interference_by_writer(value = :always)
14
+ @ignore_interference_by_writer.set(value)
15
+ self
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -4,21 +4,21 @@ module Shoulda
4
4
  # The `validate_absence_of` matcher tests the usage of the
5
5
  # `validates_absence_of` validation.
6
6
  #
7
- # class Artillery
7
+ # class PowerHungryCountry
8
8
  # include ActiveModel::Model
9
- # attr_accessor :arms
9
+ # attr_accessor :nuclear_weapons
10
10
  #
11
- # validates_absence_of :arms
11
+ # validates_absence_of :nuclear_weapons
12
12
  # end
13
13
  #
14
14
  # # RSpec
15
- # describe Artillery do
16
- # it { should validate_absence_of(:arms) }
15
+ # describe PowerHungryCountry do
16
+ # it { should validate_absence_of(:nuclear_weapons) }
17
17
  # end
18
18
  #
19
19
  # # Minitest (Shoulda)
20
- # class ArtilleryTest < ActiveSupport::TestCase
21
- # should validate_absence_of(:arms)
20
+ # class PowerHungryCountryTest < ActiveSupport::TestCase
21
+ # should validate_absence_of(:nuclear_weapons)
22
22
  # end
23
23
  #
24
24
  # #### Qualifiers
@@ -27,47 +27,47 @@ module Shoulda
27
27
  #
28
28
  # Use `on` if your validation applies only under a certain context.
29
29
  #
30
- # class Artillery
30
+ # class PowerHungryCountry
31
31
  # include ActiveModel::Model
32
- # attr_accessor :arms
32
+ # attr_accessor :nuclear_weapons
33
33
  #
34
- # validates_absence_of :arms, on: :create
34
+ # validates_absence_of :nuclear_weapons, on: :create
35
35
  # end
36
36
  #
37
37
  # # RSpec
38
- # describe Artillery do
39
- # it { should validate_absence_of(:arms).on(:create) }
38
+ # describe PowerHungryCountry do
39
+ # it { should validate_absence_of(:nuclear_weapons).on(:create) }
40
40
  # end
41
41
  #
42
42
  # # Minitest (Shoulda)
43
- # class ArtilleryTest < ActiveSupport::TestCase
44
- # should validate_absence_of(:arms).on(:create)
43
+ # class PowerHungryCountryTest < ActiveSupport::TestCase
44
+ # should validate_absence_of(:nuclear_weapons).on(:create)
45
45
  # end
46
46
  #
47
47
  # ##### with_message
48
48
  #
49
49
  # Use `with_message` if you are using a custom validation message.
50
50
  #
51
- # class Artillery
51
+ # class PowerHungryCountry
52
52
  # include ActiveModel::Model
53
- # attr_accessor :arms
53
+ # attr_accessor :nuclear_weapons
54
54
  #
55
- # validates_absence_of :arms,
56
- # message: "We're fresh outta arms here, soldier!"
55
+ # validates_absence_of :nuclear_weapons,
56
+ # message: "there shall be peace on Earth"
57
57
  # end
58
58
  #
59
59
  # # RSpec
60
- # describe Artillery do
60
+ # describe PowerHungryCountry do
61
61
  # it do
62
- # should validate_absence_of(:arms).
63
- # with_message("We're fresh outta arms here, soldier!")
62
+ # should validate_absence_of(:nuclear_weapons).
63
+ # with_message("there shall be peace on Earth")
64
64
  # end
65
65
  # end
66
66
  #
67
67
  # # Minitest (Shoulda)
68
- # class ArtilleryTest < ActiveSupport::TestCase
69
- # should validate_absence_of(:arms).
70
- # with_message("We're fresh outta arms here, soldier!")
68
+ # class PowerHungryCountryTest < ActiveSupport::TestCase
69
+ # should validate_absence_of(:nuclear_weapons).
70
+ # with_message("there shall be peace on Earth")
71
71
  # end
72
72
  #
73
73
  # @return [ValidateAbsenceOfMatcher}
@@ -78,20 +78,18 @@ module Shoulda
78
78
 
79
79
  # @private
80
80
  class ValidateAbsenceOfMatcher < ValidationMatcher
81
- def with_message(message)
82
- @expected_message = message
83
- self
81
+ def initialize(attribute)
82
+ super
83
+ @expected_message = :present
84
84
  end
85
85
 
86
86
  def matches?(subject)
87
87
  super(subject)
88
- @expected_message ||= :present
89
-
90
88
  disallows_value_of(value, @expected_message)
91
89
  end
92
90
 
93
- def description
94
- "require #{@attribute} to not be set"
91
+ def simple_description
92
+ "validate that :#{@attribute} is empty/falsy"
95
93
  end
96
94
 
97
95
  private
@@ -110,7 +108,7 @@ module Shoulda
110
108
  when :decimal then BigDecimal.new(1, 0)
111
109
  when :datetime, :time, :timestamp then Time.now
112
110
  when :date then Date.new
113
- when :binary then "0"
111
+ when :binary then '0'
114
112
  else 'an arbitrary value'
115
113
  end
116
114
  end
@@ -81,21 +81,18 @@ module Shoulda
81
81
 
82
82
  # @private
83
83
  class ValidateAcceptanceOfMatcher < ValidationMatcher
84
- def with_message(message)
85
- if message
86
- @expected_message = message
87
- end
88
- self
84
+ def initialize(attribute)
85
+ super
86
+ @expected_message = :accepted
89
87
  end
90
88
 
91
89
  def matches?(subject)
92
90
  super(subject)
93
- @expected_message ||= :accepted
94
91
  disallows_value_of(false, @expected_message)
95
92
  end
96
93
 
97
- def description
98
- "require #{@attribute} to be accepted"
94
+ def simple_description
95
+ %(validate that :#{@attribute} has been set to "1")
99
96
  end
100
97
  end
101
98
  end
@@ -83,22 +83,17 @@ module Shoulda
83
83
  attr_reader :attribute, :confirmation_attribute
84
84
 
85
85
  def initialize(attribute)
86
- super(attribute)
86
+ super
87
+ @expected_message = :confirmation
87
88
  @confirmation_attribute = "#{attribute}_confirmation"
88
89
  end
89
90
 
90
- def with_message(message)
91
- @message = message if message
92
- self
93
- end
94
-
95
- def description
96
- "require #{@confirmation_attribute} to match #{@attribute}"
91
+ def simple_description
92
+ "validate that :#{@confirmation_attribute} matches :#{@attribute}"
97
93
  end
98
94
 
99
95
  def matches?(subject)
100
96
  super(subject)
101
- @message ||= :confirmation
102
97
 
103
98
  disallows_different_value &&
104
99
  allows_same_value &&
@@ -108,38 +103,43 @@ module Shoulda
108
103
  private
109
104
 
110
105
  def disallows_different_value
111
- set_confirmation('some value')
112
106
  disallows_value_of('different value') do |matcher|
113
- qualify_matcher(matcher)
107
+ qualify_matcher(matcher, 'some value')
114
108
  end
115
109
  end
116
110
 
117
111
  def allows_same_value
118
- set_confirmation('same value')
119
112
  allows_value_of('same value') do |matcher|
120
- qualify_matcher(matcher)
113
+ qualify_matcher(matcher, 'same value')
121
114
  end
122
115
  end
123
116
 
124
117
  def allows_missing_confirmation
125
- set_confirmation(nil)
126
118
  allows_value_of('any value') do |matcher|
127
- qualify_matcher(matcher)
119
+ qualify_matcher(matcher, nil)
128
120
  end
129
121
  end
130
122
 
131
- def qualify_matcher(matcher)
132
- matcher.with_message(@message,
123
+ def qualify_matcher(matcher, confirmation_attribute_value)
124
+ matcher.values_to_preset = {
125
+ confirmation_attribute => confirmation_attribute_value
126
+ }
127
+ matcher.with_message(
128
+ @expected_message,
133
129
  against: confirmation_attribute,
134
130
  values: { attribute: attribute }
135
131
  )
136
132
  end
137
133
 
138
- def set_confirmation(val)
139
- setter = :"#{@confirmation_attribute}="
140
- if @subject.respond_to?(setter)
141
- @subject.__send__(setter, val)
142
- end
134
+ def set_confirmation(value)
135
+ @last_value_set_on_confirmation_attribute = value
136
+
137
+ AttributeSetter.set(
138
+ matcher_name: 'confirmation',
139
+ object: @subject,
140
+ attribute_name: confirmation_attribute,
141
+ value: value
142
+ )
143
143
  end
144
144
  end
145
145
  end
@@ -122,9 +122,9 @@ module Shoulda
122
122
  class ValidateExclusionOfMatcher < ValidationMatcher
123
123
  def initialize(attribute)
124
124
  super(attribute)
125
+ @expected_message = :exclusion
125
126
  @array = nil
126
127
  @range = nil
127
- @expected_message = nil
128
128
  end
129
129
 
130
130
  def in_array(array)
@@ -139,13 +139,21 @@ module Shoulda
139
139
  self
140
140
  end
141
141
 
142
- def with_message(message)
143
- @expected_message = message if message
144
- self
145
- end
142
+ def simple_description
143
+ if @range
144
+ "validate that :#{@attribute} lies outside the range " +
145
+ Shoulda::Matchers::Util.inspect_range(@range)
146
+ else
147
+ description = "validate that :#{@attribute}"
148
+
149
+ if @array.many?
150
+ description << " is neither #{inspected_array}"
151
+ else
152
+ description << " is not #{inspected_array}"
153
+ end
146
154
 
147
- def description
148
- "ensure exclusion of #{@attribute} in #{inspect_message}"
155
+ description
156
+ end
149
157
  end
150
158
 
151
159
  def matches?(subject)
@@ -165,28 +173,24 @@ module Shoulda
165
173
 
166
174
  def disallows_all_values_in_array?
167
175
  @array.all? do |value|
168
- disallows_value_of(value, expected_message)
176
+ disallows_value_of(value, @expected_message)
169
177
  end
170
178
  end
171
179
 
172
180
  def allows_lower_value
173
- @minimum == 0 || allows_value_of(@minimum - 1, expected_message)
181
+ @minimum == 0 || allows_value_of(@minimum - 1, @expected_message)
174
182
  end
175
183
 
176
184
  def allows_higher_value
177
- allows_value_of(@maximum + 1, expected_message)
185
+ allows_value_of(@maximum + 1, @expected_message)
178
186
  end
179
187
 
180
188
  def disallows_minimum_value
181
- disallows_value_of(@minimum, expected_message)
189
+ disallows_value_of(@minimum, @expected_message)
182
190
  end
183
191
 
184
192
  def disallows_maximum_value
185
- disallows_value_of(@maximum, expected_message)
186
- end
187
-
188
- def expected_message
189
- @expected_message || :exclusion
193
+ disallows_value_of(@maximum, @expected_message)
190
194
  end
191
195
 
192
196
  def inspect_message
@@ -196,6 +200,13 @@ module Shoulda
196
200
  @array.inspect
197
201
  end
198
202
  end
203
+
204
+ def inspected_array
205
+ Shoulda::Matchers::Util.inspect_values(@array).to_sentence(
206
+ two_words_connector: " nor ",
207
+ last_word_connector: ", nor "
208
+ )
209
+ end
199
210
  end
200
211
  end
201
212
  end
@@ -13,21 +13,22 @@ module Shoulda
13
13
  # include ActiveModel::Model
14
14
  # attr_accessor :state
15
15
  #
16
- # validates_inclusion_of :state, in: %w(open resolved unresolved)
16
+ # validates_inclusion_of :state,
17
+ # in: ['open', 'resolved', 'unresolved']
17
18
  # end
18
19
  #
19
20
  # # RSpec
20
21
  # describe Issue do
21
22
  # it do
22
23
  # should validate_inclusion_of(:state).
23
- # in_array(%w(open resolved unresolved))
24
+ # in_array(['open', 'resolved', 'unresolved'])
24
25
  # end
25
26
  # end
26
27
  #
27
28
  # # Minitest (Shoulda)
28
29
  # class IssueTest < ActiveSupport::TestCase
29
30
  # should validate_inclusion_of(:state).
30
- # in_array(%w(open resolved unresolved))
31
+ # in_array(['open', 'resolved', 'unresolved'])
31
32
  # end
32
33
  #
33
34
  # If your whitelist is a range of values, use `in_range`:
@@ -57,7 +58,10 @@ module Shoulda
57
58
  # one of these three values. That means there isn't any way we can refute
58
59
  # this logic in a test. Hence, this will produce a warning:
59
60
  #
60
- # it { should validate_inclusion_of(:imported).in_array([true, false]) }
61
+ # it do
62
+ # should validate_inclusion_of(:imported).
63
+ # in_array([true, false])
64
+ # end
61
65
  #
62
66
  # The only case where `validate_inclusion_of` *could* be appropriate is
63
67
  # for ensuring that a boolean column accepts nil, but we recommend
@@ -205,7 +209,7 @@ module Shoulda
205
209
  #
206
210
  # validates_presence_of :state
207
211
  # validates_inclusion_of :state,
208
- # in: %w(open resolved unresolved),
212
+ # in: ['open', 'resolved', 'unresolved'],
209
213
  # allow_nil: true
210
214
  # end
211
215
  #
@@ -213,7 +217,7 @@ module Shoulda
213
217
  # describe Issue do
214
218
  # it do
215
219
  # should validate_inclusion_of(:state).
216
- # in_array(%w(open resolved unresolved)).
220
+ # in_array(['open', 'resolved', 'unresolved']).
217
221
  # allow_nil
218
222
  # end
219
223
  # end
@@ -221,7 +225,7 @@ module Shoulda
221
225
  # # Minitest (Shoulda)
222
226
  # class IssueTest < ActiveSupport::TestCase
223
227
  # should validate_inclusion_of(:state).
224
- # in_array(%w(open resolved unresolved)).
228
+ # in_array(['open', 'resolved', 'unresolved']).
225
229
  # allow_nil
226
230
  # end
227
231
  #
@@ -235,7 +239,7 @@ module Shoulda
235
239
  #
236
240
  # validates_presence_of :state
237
241
  # validates_inclusion_of :state,
238
- # in: %w(open resolved unresolved),
242
+ # in: ['open', 'resolved', 'unresolved'],
239
243
  # allow_blank: true
240
244
  # end
241
245
  #
@@ -243,7 +247,7 @@ module Shoulda
243
247
  # describe Issue do
244
248
  # it do
245
249
  # should validate_inclusion_of(:state).
246
- # in_array(%w(open resolved unresolved)).
250
+ # in_array(['open', 'resolved', 'unresolved']).
247
251
  # allow_blank
248
252
  # end
249
253
  # end
@@ -251,7 +255,7 @@ module Shoulda
251
255
  # # Minitest (Shoulda)
252
256
  # class IssueTest < ActiveSupport::TestCase
253
257
  # should validate_inclusion_of(:state).
254
- # in_array(%w(open resolved unresolved)).
258
+ # in_array(['open', 'resolved', 'unresolved']).
255
259
  # allow_blank
256
260
  # end
257
261
  #
@@ -310,31 +314,61 @@ EOT
310
314
  self
311
315
  end
312
316
 
317
+ def expects_to_allow_blank?
318
+ @options[:allow_blank]
319
+ end
320
+
313
321
  def allow_nil(allow_nil = true)
314
322
  @options[:allow_nil] = allow_nil
315
323
  self
316
324
  end
317
325
 
326
+ def expects_to_allow_nil?
327
+ @options[:allow_nil]
328
+ end
329
+
318
330
  def with_message(message)
319
331
  if message
332
+ @expects_custom_validation_message = true
320
333
  @low_message = message
321
334
  @high_message = message
322
335
  end
336
+
323
337
  self
324
338
  end
325
339
 
326
340
  def with_low_message(message)
327
- @low_message = message if message
341
+ if message
342
+ @expects_custom_validation_message = true
343
+ @low_message = message
344
+ end
345
+
328
346
  self
329
347
  end
330
348
 
331
349
  def with_high_message(message)
332
- @high_message = message if message
350
+ if message
351
+ @high_message = message
352
+ end
353
+
333
354
  self
334
355
  end
335
356
 
336
- def description
337
- "ensure inclusion of #{@attribute} in #{inspect_message}"
357
+ def simple_description
358
+ if @range
359
+ "validate that :#{@attribute} lies inside the range " +
360
+ Shoulda::Matchers::Util.inspect_range(@range)
361
+ else
362
+ description = "validate that :#{@attribute}"
363
+
364
+ if @array.many?
365
+ description << " is either #{inspected_array}"
366
+ else
367
+ description << " is #{inspected_array}"
368
+ end
369
+
370
+ description
371
+ end
338
372
  end
339
373
 
340
374
  def matches?(subject)
@@ -398,7 +432,9 @@ EOT
398
432
  end
399
433
 
400
434
  def disallows_lower_value
401
- @minimum == 0 || disallows_value_of(@minimum - 1, @low_message)
435
+ @minimum.nil? ||
436
+ @minimum == 0 ||
437
+ disallows_value_of(@minimum - 1, @low_message)
402
438
  end
403
439
 
404
440
  def disallows_higher_value
@@ -518,6 +554,13 @@ EOT
518
554
  else :unknown
519
555
  end
520
556
  end
557
+
558
+ def inspected_array
559
+ Shoulda::Matchers::Util.inspect_values(@array).to_sentence(
560
+ two_words_connector: " or ",
561
+ last_word_connector: ", or "
562
+ )
563
+ end
521
564
  end
522
565
  end
523
566
  end