shoulda-matchers 4.4.1 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +22 -0
  3. data/README.md +7 -9
  4. data/lib/shoulda/matchers/action_controller/callback_matcher.rb +4 -2
  5. data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +3 -2
  6. data/lib/shoulda/matchers/action_controller/permit_matcher.rb +26 -21
  7. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +6 -8
  8. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +6 -8
  9. data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +16 -13
  10. data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +2 -1
  11. data/lib/shoulda/matchers/action_controller/route_matcher.rb +5 -6
  12. data/lib/shoulda/matchers/action_controller/route_params.rb +1 -1
  13. data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +19 -13
  14. data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +18 -16
  15. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +29 -27
  16. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +1 -1
  17. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +5 -5
  18. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +2 -2
  19. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +1 -1
  20. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +1 -1
  21. data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +1 -1
  22. data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +51 -25
  23. data/lib/shoulda/matchers/active_model/helpers.rb +1 -1
  24. data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +32 -34
  25. data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +1 -1
  26. data/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +1 -1
  27. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +9 -1
  28. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +2 -2
  29. data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +8 -7
  30. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +26 -25
  31. data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +6 -6
  32. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +39 -26
  33. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +2 -2
  34. data/lib/shoulda/matchers/active_model/validation_matcher.rb +6 -6
  35. data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +2 -4
  36. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +2 -4
  37. data/lib/shoulda/matchers/active_model/validator.rb +3 -3
  38. data/lib/shoulda/matchers/active_record.rb +26 -26
  39. data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +6 -3
  40. data/lib/shoulda/matchers/active_record/association_matcher.rb +80 -40
  41. data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +5 -2
  42. data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +4 -4
  43. data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +1 -1
  44. data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +11 -6
  45. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +2 -9
  46. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +12 -7
  47. data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +23 -5
  48. data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +3 -3
  49. data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +1 -1
  50. data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +3 -3
  51. data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +3 -2
  52. data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +7 -5
  53. data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +8 -8
  54. data/lib/shoulda/matchers/active_record/have_attached_matcher.rb +46 -8
  55. data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +39 -17
  56. data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +1 -1
  57. data/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +7 -7
  58. data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +12 -10
  59. data/lib/shoulda/matchers/active_record/have_rich_text_matcher.rb +11 -7
  60. data/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +2 -0
  61. data/lib/shoulda/matchers/active_record/serialize_matcher.rb +13 -9
  62. data/lib/shoulda/matchers/active_record/uniqueness.rb +1 -1
  63. data/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +1 -3
  64. data/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +0 -2
  65. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +78 -71
  66. data/lib/shoulda/matchers/doublespeak.rb +2 -1
  67. data/lib/shoulda/matchers/doublespeak/double.rb +1 -1
  68. data/lib/shoulda/matchers/doublespeak/double_collection.rb +3 -3
  69. data/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +8 -5
  70. data/lib/shoulda/matchers/doublespeak/object_double.rb +1 -1
  71. data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +1 -5
  72. data/lib/shoulda/matchers/doublespeak/world.rb +2 -2
  73. data/lib/shoulda/matchers/error.rb +1 -1
  74. data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +14 -13
  75. data/lib/shoulda/matchers/integrations/configuration.rb +1 -1
  76. data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +1 -1
  77. data/lib/shoulda/matchers/integrations/libraries/rails.rb +2 -2
  78. data/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +1 -1
  79. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +1 -1
  80. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +1 -1
  81. data/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +1 -1
  82. data/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +1 -1
  83. data/lib/shoulda/matchers/rails_shim.rb +5 -3
  84. data/lib/shoulda/matchers/util.rb +7 -2
  85. data/lib/shoulda/matchers/util/word_wrap.rb +7 -7
  86. data/lib/shoulda/matchers/version.rb +1 -1
  87. data/lib/shoulda/matchers/warn.rb +3 -3
  88. data/shoulda-matchers.gemspec +10 -7
  89. metadata +11 -10
@@ -26,7 +26,7 @@ module Shoulda
26
26
  attribute.to_sym,
27
27
  type,
28
28
  model_name,
29
- options
29
+ options,
30
30
  )
31
31
  end
32
32
  end
@@ -5,23 +5,42 @@ module Shoulda
5
5
  # @private
6
6
  class ComparisonMatcher < ValidationMatcher
7
7
  ERROR_MESSAGES = {
8
- :> => :greater_than,
9
- :>= => :greater_than_or_equal_to,
10
- :< => :less_than,
11
- :<= => :less_than_or_equal_to,
12
- :== => :equal_to,
13
- :!= => :other_than,
14
- }
8
+ :> => {
9
+ label: :greater_than,
10
+ assertions: [false, false, true],
11
+ },
12
+ :>= => {
13
+ label: :greater_than_or_equal_to,
14
+ assertions: [false, true, true],
15
+ },
16
+ :< => {
17
+ label: :less_than,
18
+ assertions: [true, false, false],
19
+ },
20
+ :<= => {
21
+ label: :less_than_or_equal_to,
22
+ assertions: [true, true, false],
23
+ },
24
+ :== => {
25
+ label: :equal_to,
26
+ assertions: [false, true, false],
27
+ },
28
+ :!= => {
29
+ label: :other_than,
30
+ assertions: [true, false, true],
31
+ },
32
+ }.freeze
15
33
 
16
34
  def initialize(numericality_matcher, value, operator)
17
35
  super(nil)
18
36
  unless numericality_matcher.respond_to? :diff_to_compare
19
37
  raise ArgumentError, 'numericality_matcher is invalid'
20
38
  end
39
+
21
40
  @numericality_matcher = numericality_matcher
22
41
  @value = value
23
42
  @operator = operator
24
- @message = ERROR_MESSAGES[operator]
43
+ @message = ERROR_MESSAGES[operator][:label]
25
44
  end
26
45
 
27
46
  def simple_description
@@ -94,10 +113,9 @@ module Shoulda
94
113
  end
95
114
 
96
115
  def submatchers_and_results
97
- @_submatchers_and_results ||=
98
- submatchers.map do |matcher|
99
- { matcher: matcher, matched: matcher.matches?(@subject) }
100
- end
116
+ @_submatchers_and_results ||= submatchers.map do |matcher|
117
+ { matcher: matcher, matched: matcher.matches?(@subject) }
118
+ end
101
119
  end
102
120
 
103
121
  def comparison_combos
@@ -115,20 +133,7 @@ module Shoulda
115
133
  end
116
134
 
117
135
  def assertions
118
- case @operator
119
- when :>
120
- [false, false, true]
121
- when :>=
122
- [false, true, true]
123
- when :==
124
- [false, true, false]
125
- when :<
126
- [true, false, false]
127
- when :<=
128
- [true, true, false]
129
- when :!=
130
- [true, false, true]
131
- end
136
+ ERROR_MESSAGES[@operator][:assertions]
132
137
  end
133
138
 
134
139
  def diffs_to_compare
@@ -143,14 +148,7 @@ module Shoulda
143
148
  end
144
149
 
145
150
  def comparison_expectation
146
- case @operator
147
- when :> then "greater than"
148
- when :>= then "greater than or equal to"
149
- when :== then "equal to"
150
- when :< then "less than"
151
- when :<= then "less than or equal to"
152
- when :!= then 'other than'
153
- end
151
+ ERROR_MESSAGES[@operator][:label].to_s.tr('_', ' ')
154
152
  end
155
153
  end
156
154
  end
@@ -44,7 +44,7 @@ module Shoulda
44
44
 
45
45
  attr_reader :attribute
46
46
 
47
- def wrap_disallow_value_matcher(matcher)
47
+ def wrap_disallow_value_matcher(_matcher)
48
48
  raise NotImplementedError
49
49
  end
50
50
 
@@ -6,7 +6,7 @@ module Shoulda
6
6
  module IgnoringInterferenceByWriter
7
7
  attr_reader :ignore_interference_by_writer
8
8
 
9
- def initialize(*args)
9
+ def initialize(*)
10
10
  @ignore_interference_by_writer = IgnoreInterferenceByWriter.new
11
11
  end
12
12
 
@@ -103,10 +103,12 @@ module Shoulda
103
103
  if reflection
104
104
  obj = reflection.klass.new
105
105
  if collection?
106
- [ obj ]
106
+ [obj]
107
107
  else
108
108
  obj
109
109
  end
110
+ elsif array_column?
111
+ ['an arbitary value']
110
112
  else
111
113
  case column_type
112
114
  when :integer, :float then 1
@@ -137,6 +139,12 @@ module Shoulda
137
139
  @subject.class.respond_to?(:reflect_on_association) &&
138
140
  @subject.class.reflect_on_association(@attribute)
139
141
  end
142
+
143
+ def array_column?
144
+ @subject.class.respond_to?(:columns_hash) &&
145
+ @subject.class.columns_hash[@attribute.to_s].respond_to?(:array) &&
146
+ @subject.class.columns_hash[@attribute.to_s].array
147
+ end
140
148
  end
141
149
  end
142
150
  end
@@ -148,12 +148,12 @@ module Shoulda
148
148
 
149
149
  def qualify_matcher(matcher, confirmation_attribute_value)
150
150
  matcher.values_to_preset = {
151
- confirmation_attribute => confirmation_attribute_value
151
+ confirmation_attribute => confirmation_attribute_value,
152
152
  }
153
153
  matcher.with_message(
154
154
  @expected_message,
155
155
  against: confirmation_attribute,
156
- values: { attribute: attribute }
156
+ values: { attribute: attribute },
157
157
  )
158
158
  end
159
159
  end
@@ -146,11 +146,12 @@ module Shoulda
146
146
  else
147
147
  description = "validate that :#{@attribute}"
148
148
 
149
- if @array.many?
150
- description << " is neither #{inspected_array}"
151
- else
152
- description << " is not #{inspected_array}"
153
- end
149
+ description <<
150
+ if @array.many?
151
+ " is neither #{inspected_array}"
152
+ else
153
+ " is not #{inspected_array}"
154
+ end
154
155
 
155
156
  description
156
157
  end
@@ -238,8 +239,8 @@ module Shoulda
238
239
 
239
240
  def inspected_array
240
241
  Shoulda::Matchers::Util.inspect_values(@array).to_sentence(
241
- two_words_connector: " nor ",
242
- last_word_connector: ", nor "
242
+ two_words_connector: ' nor ',
243
+ last_word_connector: ', nor ',
243
244
  )
244
245
  end
245
246
  end
@@ -268,20 +268,20 @@ module Shoulda
268
268
 
269
269
  # @private
270
270
  class ValidateInclusionOfMatcher < ValidationMatcher
271
- BLANK_VALUES = ['', ' ', "\n", "\r", "\t", "\f"]
272
- ARBITRARY_OUTSIDE_STRING = 'shoulda-matchers test string'
271
+ BLANK_VALUES = ['', ' ', "\n", "\r", "\t", "\f"].freeze
272
+ ARBITRARY_OUTSIDE_STRING = 'shoulda-matchers test string'.freeze
273
273
  ARBITRARY_OUTSIDE_INTEGER = 123456789
274
274
  ARBITRARY_OUTSIDE_DECIMAL = BigDecimal('0.123456789')
275
275
  ARBITRARY_OUTSIDE_DATE = Date.jd(9999999)
276
276
  ARBITRARY_OUTSIDE_DATETIME = DateTime.jd(9999999)
277
277
  ARBITRARY_OUTSIDE_TIME = Time.at(9999999999)
278
- BOOLEAN_ALLOWS_BOOLEAN_MESSAGE = <<EOT
278
+ BOOLEAN_ALLOWS_BOOLEAN_MESSAGE = <<EOT.freeze
279
279
  You are using `validate_inclusion_of` to assert that a boolean column allows
280
280
  boolean values and disallows non-boolean ones. Be aware that it is not possible
281
281
  to fully test this, as boolean columns will automatically convert non-boolean
282
282
  values to boolean ones. Hence, you should consider removing this test.
283
283
  EOT
284
- BOOLEAN_ALLOWS_NIL_MESSAGE = <<EOT
284
+ BOOLEAN_ALLOWS_NIL_MESSAGE = <<EOT.freeze
285
285
  You are using `validate_inclusion_of` to assert that a boolean column allows nil.
286
286
  Be aware that it is not possible to fully test this, as anything other than
287
287
  true, false or nil will be converted to false. Hence, you should consider
@@ -354,11 +354,12 @@ EOT
354
354
  else
355
355
  description = "validate that :#{@attribute}"
356
356
 
357
- if @array.many?
358
- description << " is either #{inspected_array}"
359
- else
360
- description << " is #{inspected_array}"
361
- end
357
+ description <<
358
+ if @array.many?
359
+ " is either #{inspected_array}"
360
+ else
361
+ " is #{inspected_array}"
362
+ end
362
363
 
363
364
  description
364
365
  end
@@ -545,10 +546,10 @@ EOT
545
546
  values = []
546
547
 
547
548
  values << case @array
548
- when [true] then false
549
- when [false] then true
550
- else raise CouldNotDetermineValueOutsideOfArray
551
- end
549
+ when [true] then false
550
+ when [false] then true
551
+ else raise CouldNotDetermineValueOutsideOfArray
552
+ end
552
553
 
553
554
  if attribute_allows_nil?
554
555
  values << nil
@@ -581,21 +582,21 @@ EOT
581
582
 
582
583
  def column_type_to_attribute_type(type)
583
584
  case type
584
- when :float then :integer
585
- when :timestamp then :datetime
586
- else type
585
+ when :float then :integer
586
+ when :timestamp then :datetime
587
+ else type
587
588
  end
588
589
  end
589
590
 
590
591
  def value_to_attribute_type(value)
591
592
  case value
592
- when true, false then :boolean
593
- when BigDecimal then :decimal
594
- when Integer then :integer
595
- when Date then :date
596
- when DateTime then :datetime
597
- when Time then :time
598
- else :unknown
593
+ when true, false then :boolean
594
+ when BigDecimal then :decimal
595
+ when Integer then :integer
596
+ when Date then :date
597
+ when DateTime then :datetime
598
+ when Time then :time
599
+ else :unknown
599
600
  end
600
601
  end
601
602
 
@@ -609,8 +610,8 @@ EOT
609
610
 
610
611
  def inspected_array
611
612
  Shoulda::Matchers::Util.inspect_values(@array).to_sentence(
612
- two_words_connector: " or ",
613
- last_word_connector: ", or "
613
+ two_words_connector: ' or ',
614
+ last_word_connector: ', or ',
614
615
  )
615
616
  end
616
617
  end
@@ -392,7 +392,7 @@ module Shoulda
392
392
  @options[:minimum] > 0 &&
393
393
  allows_length_of?(
394
394
  @options[:minimum] - 1,
395
- translated_short_message
395
+ translated_short_message,
396
396
  )
397
397
  end
398
398
 
@@ -402,7 +402,7 @@ module Shoulda
402
402
  (@options[:minimum] == 1 && expects_to_allow_blank?) ||
403
403
  disallows_length_of?(
404
404
  @options[:minimum] - 1,
405
- translated_short_message
405
+ translated_short_message,
406
406
  )
407
407
  end
408
408
 
@@ -410,7 +410,7 @@ module Shoulda
410
410
  @options.key?(:maximum) &&
411
411
  allows_length_of?(
412
412
  @options[:maximum] + 1,
413
- translated_long_message
413
+ translated_long_message,
414
414
  )
415
415
  end
416
416
 
@@ -418,7 +418,7 @@ module Shoulda
418
418
  !@options.key?(:maximum) ||
419
419
  disallows_length_of?(
420
420
  @options[:maximum] + 1,
421
- translated_long_message
421
+ translated_long_message,
422
422
  )
423
423
  end
424
424
 
@@ -470,7 +470,7 @@ module Shoulda
470
470
  model_name: @subject.class.to_s.underscore,
471
471
  instance: @subject,
472
472
  attribute: @attribute,
473
- count: @options[:minimum]
473
+ count: @options[:minimum],
474
474
  )
475
475
  else
476
476
  @short_message
@@ -485,7 +485,7 @@ module Shoulda
485
485
  model_name: @subject.class.to_s.underscore,
486
486
  instance: @subject,
487
487
  attribute: @attribute,
488
- count: @options[:maximum]
488
+ count: @options[:maximum],
489
489
  )
490
490
  else
491
491
  @long_message
@@ -331,8 +331,7 @@ module Shoulda
331
331
 
332
332
  # @private
333
333
  class ValidateNumericalityOfMatcher
334
- NUMERIC_NAME = 'number'
335
- NON_NUMERIC_VALUE = 'abcd'
334
+ NUMERIC_NAME = 'number'.freeze
336
335
  DEFAULT_DIFF_TO_COMPARE = 1
337
336
 
338
337
  include Qualifiers::IgnoringInterferenceByWriter
@@ -364,7 +363,7 @@ module Shoulda
364
363
 
365
364
  def only_integer
366
365
  prepare_submatcher(
367
- NumericalityMatchers::OnlyIntegerMatcher.new(self, @attribute)
366
+ NumericalityMatchers::OnlyIntegerMatcher.new(self, @attribute),
368
367
  )
369
368
  self
370
369
  end
@@ -372,9 +371,9 @@ module Shoulda
372
371
  def allow_nil
373
372
  @expects_to_allow_nil = true
374
373
  prepare_submatcher(
375
- AllowValueMatcher.new(nil)
376
- .for(@attribute)
377
- .with_message(:not_a_number)
374
+ AllowValueMatcher.new(nil).
375
+ for(@attribute).
376
+ with_message(:not_a_number),
378
377
  )
379
378
  self
380
379
  end
@@ -385,14 +384,14 @@ module Shoulda
385
384
 
386
385
  def odd
387
386
  prepare_submatcher(
388
- NumericalityMatchers::OddNumberMatcher.new(self, @attribute)
387
+ NumericalityMatchers::OddNumberMatcher.new(self, @attribute),
389
388
  )
390
389
  self
391
390
  end
392
391
 
393
392
  def even
394
393
  prepare_submatcher(
395
- NumericalityMatchers::EvenNumberMatcher.new(self, @attribute)
394
+ NumericalityMatchers::EvenNumberMatcher.new(self, @attribute),
396
395
  )
397
396
  self
398
397
  end
@@ -459,7 +458,7 @@ module Shoulda
459
458
  description << Shoulda::Matchers::Util.a_or_an(full_allowed_type)
460
459
 
461
460
  if comparison_descriptions.present?
462
- description << ' ' + comparison_descriptions
461
+ description << " #{comparison_descriptions}"
463
462
  end
464
463
 
465
464
  description
@@ -479,7 +478,8 @@ module Shoulda
479
478
  def failure_message_when_negated
480
479
  overall_failure_message_when_negated.dup.tap do |message|
481
480
  message << "\n"
482
- message << failure_message_for_first_submatcher_that_fails_to_not_match
481
+ message <<
482
+ failure_message_for_first_submatcher_that_fails_to_not_match
483
483
  end
484
484
  end
485
485
 
@@ -500,15 +500,15 @@ module Shoulda
500
500
 
501
501
  def overall_failure_message
502
502
  Shoulda::Matchers.word_wrap(
503
- "Expected #{model.name} to #{description}, but this could not " +
504
- 'be proved.'
503
+ "Expected #{model.name} to #{description}, but this could not "\
504
+ 'be proved.',
505
505
  )
506
506
  end
507
507
 
508
508
  def overall_failure_message_when_negated
509
509
  Shoulda::Matchers.word_wrap(
510
- "Expected #{model.name} not to #{description}, but this could not " +
511
- 'be proved.'
510
+ "Expected #{model.name} not to #{description}, but this could not "\
511
+ 'be proved.',
512
512
  )
513
513
  end
514
514
 
@@ -530,7 +530,7 @@ module Shoulda
530
530
 
531
531
  def add_disallow_value_matcher
532
532
  disallow_value_matcher = DisallowValueMatcher.
533
- new(NON_NUMERIC_VALUE).
533
+ new(non_numeric_value).
534
534
  for(@attribute).
535
535
  with_message(:not_a_number)
536
536
 
@@ -558,7 +558,10 @@ module Shoulda
558
558
  end
559
559
 
560
560
  if submatcher.respond_to?(:diff_to_compare)
561
- @diff_to_compare = [@diff_to_compare, submatcher.diff_to_compare].max
561
+ @diff_to_compare = [
562
+ @diff_to_compare,
563
+ submatcher.diff_to_compare,
564
+ ].max
562
565
  end
563
566
 
564
567
  @submatchers << submatcher
@@ -579,7 +582,7 @@ module Shoulda
579
582
  end
580
583
 
581
584
  submatcher.ignoring_interference_by_writer(
582
- ignore_interference_by_writer
585
+ ignore_interference_by_writer,
583
586
  )
584
587
  end
585
588
  end
@@ -600,28 +603,30 @@ module Shoulda
600
603
  end
601
604
 
602
605
  def first_submatcher_that_fails_to_match
603
- @_failing_submatchers ||= @submatchers.detect do |submatcher|
604
- !submatcher.matches?(@subject)
605
- end
606
+ @_first_submatcher_that_fails_to_match ||=
607
+ @submatchers.detect do |submatcher|
608
+ !submatcher.matches?(@subject)
609
+ end
606
610
  end
607
611
 
608
612
  def first_submatcher_that_fails_to_not_match
609
- @_failing_submatchers ||= @submatchers.detect do |submatcher|
610
- !submatcher.does_not_match?(@subject)
611
- end
613
+ @_first_submatcher_that_fails_to_not_match ||=
614
+ @submatchers.detect do |submatcher|
615
+ !submatcher.does_not_match?(@subject)
616
+ end
612
617
  end
613
618
 
614
619
  def failure_message_for_first_submatcher_that_fails_to_match
615
620
  build_submatcher_failure_message_for(
616
621
  first_submatcher_that_fails_to_match,
617
- :failure_message
622
+ :failure_message,
618
623
  )
619
624
  end
620
625
 
621
626
  def failure_message_for_first_submatcher_that_fails_to_not_match
622
627
  build_submatcher_failure_message_for(
623
628
  first_submatcher_that_fails_to_not_match,
624
- :failure_message_when_negated
629
+ :failure_message_when_negated,
625
630
  )
626
631
  end
627
632
 
@@ -652,7 +657,11 @@ module Shoulda
652
657
 
653
658
  def comparison_descriptions
654
659
  description_array = submatcher_comparison_descriptions
655
- description_array.empty? ? '' : submatcher_comparison_descriptions.join(' and ')
660
+ if description_array.empty?
661
+ ''
662
+ else
663
+ submatcher_comparison_descriptions.join(' and ')
664
+ end
656
665
  end
657
666
 
658
667
  def submatcher_comparison_descriptions
@@ -667,6 +676,10 @@ module Shoulda
667
676
  def model
668
677
  @subject.class
669
678
  end
679
+
680
+ def non_numeric_value
681
+ 'abcd'
682
+ end
670
683
  end
671
684
  end
672
685
  end