shoulda-matchers 3.1.3 → 4.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/.hound/ruby.yml +336 -316
  3. data/.python-version +1 -0
  4. data/.rubocop.yml +3 -1
  5. data/.travis.yml +7 -6
  6. data/Appraisals +76 -44
  7. data/CONTRIBUTING.md +137 -66
  8. data/Gemfile +5 -5
  9. data/Gemfile.lock +30 -35
  10. data/MAINTAINING.md +250 -0
  11. data/MIT-LICENSE +1 -1
  12. data/NEWS.md +176 -4
  13. data/README.md +138 -200
  14. data/Rakefile +7 -0
  15. data/bin/setup +190 -0
  16. data/doc_config/yard/templates/default/fulldoc/html/css/global.css +4 -0
  17. data/doc_config/yard/templates/default/fulldoc/html/full_list.erb +0 -6
  18. data/doc_config/yard/templates/default/fulldoc/html/js/app.js +0 -17
  19. data/doc_config/yard/templates/default/fulldoc/html/setup.rb +27 -0
  20. data/gemfiles/4.2.gemfile +21 -20
  21. data/gemfiles/4.2.gemfile.lock +143 -140
  22. data/gemfiles/5.0.gemfile +37 -0
  23. data/gemfiles/5.0.gemfile.lock +238 -0
  24. data/gemfiles/5.1.gemfile +38 -0
  25. data/gemfiles/5.1.gemfile.lock +254 -0
  26. data/gemfiles/5.2.gemfile +40 -0
  27. data/gemfiles/5.2.gemfile.lock +273 -0
  28. data/lib/shoulda/matchers/action_controller/callback_matcher.rb +18 -6
  29. data/lib/shoulda/matchers/action_controller/permit_matcher.rb +6 -1
  30. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +1 -1
  31. data/lib/shoulda/matchers/action_controller/route_matcher.rb +87 -27
  32. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +1 -0
  33. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +0 -4
  34. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +5 -0
  35. data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +5 -0
  36. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +26 -11
  37. data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +39 -4
  38. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +116 -47
  39. data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +127 -38
  40. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +55 -37
  41. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +30 -1
  42. data/lib/shoulda/matchers/active_model/validation_matcher.rb +11 -4
  43. data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +11 -6
  44. data/lib/shoulda/matchers/active_record.rb +3 -0
  45. data/lib/shoulda/matchers/active_record/association_matcher.rb +172 -22
  46. data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +1 -1
  47. data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +11 -6
  48. data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +46 -0
  49. data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +51 -0
  50. data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +268 -38
  51. data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +1 -1
  52. data/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +111 -0
  53. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +207 -79
  54. data/lib/shoulda/matchers/doublespeak/object_double.rb +5 -1
  55. data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +100 -21
  56. data/lib/shoulda/matchers/rails_shim.rb +133 -52
  57. data/lib/shoulda/matchers/routing.rb +2 -2
  58. data/lib/shoulda/matchers/util.rb +23 -1
  59. data/lib/shoulda/matchers/util/word_wrap.rb +6 -2
  60. data/lib/shoulda/matchers/version.rb +1 -1
  61. data/script/install_gems_in_all_appraisals +3 -1
  62. data/script/run_all_tests +3 -1
  63. data/script/supported_ruby_versions +7 -0
  64. data/script/update_gem_in_all_appraisals +3 -1
  65. data/script/update_gems_in_all_appraisals +3 -1
  66. data/shoulda-matchers.gemspec +3 -3
  67. data/spec/acceptance/independent_matchers_spec.rb +2 -2
  68. data/spec/acceptance/multiple_libraries_integration_spec.rb +1 -1
  69. data/spec/acceptance/rails_integration_spec.rb +2 -2
  70. data/spec/spec_helper.rb +2 -3
  71. data/spec/support/acceptance/helpers.rb +2 -0
  72. data/spec/support/acceptance/helpers/command_helpers.rb +17 -4
  73. data/spec/support/acceptance/helpers/rails_migration_helpers.rb +21 -0
  74. data/spec/support/acceptance/helpers/step_helpers.rb +1 -1
  75. data/spec/support/tests/current_bundle.rb +3 -9
  76. data/spec/support/tests/filesystem.rb +2 -2
  77. data/spec/support/unit/attribute.rb +0 -2
  78. data/spec/support/unit/capture.rb +9 -3
  79. data/spec/support/unit/helpers/action_pack_versions.rb +22 -0
  80. data/spec/support/unit/helpers/active_model_versions.rb +4 -0
  81. data/spec/support/unit/helpers/active_record_versions.rb +22 -2
  82. data/spec/support/unit/helpers/active_resource_builder.rb +2 -2
  83. data/spec/support/unit/helpers/controller_builder.rb +1 -1
  84. data/spec/support/unit/helpers/message_helpers.rb +19 -0
  85. data/spec/support/unit/helpers/rails_versions.rb +14 -0
  86. data/spec/support/unit/matchers/fail_with_message_matcher.rb +7 -5
  87. data/spec/support/unit/matchers/print_warning_including.rb +21 -13
  88. data/spec/support/unit/model_creation_strategies/active_record.rb +1 -1
  89. data/spec/support/unit/model_creators/active_record.rb +0 -1
  90. data/spec/support/unit/model_creators/basic.rb +7 -2
  91. data/spec/support/unit/rails_application.rb +25 -0
  92. data/spec/support/unit/record_validating_confirmation_builder.rb +5 -2
  93. data/spec/support/unit/validation_matcher_scenario.rb +0 -2
  94. data/spec/unit/shoulda/matchers/action_controller/callback_matcher_spec.rb +18 -18
  95. data/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb +33 -5
  96. data/spec/unit/shoulda/matchers/action_controller/render_template_matcher_spec.rb +1 -1
  97. data/spec/unit/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +80 -78
  98. data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +7 -9
  99. data/spec/unit/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +28 -4
  100. data/spec/unit/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +19 -1
  101. data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +27 -4
  102. data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +62 -5
  103. data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +52 -18
  104. data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +51 -4
  105. data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +99 -71
  106. data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +41 -15
  107. data/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +445 -15
  108. data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +615 -93
  109. data/spec/unit/shoulda/matchers/active_record/have_secure_token_matcher_spec.rb +169 -0
  110. data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +167 -97
  111. data/spec/unit/shoulda/matchers/doublespeak/world_spec.rb +2 -4
  112. data/spec/unit/shoulda/matchers/independent/delegate_method_matcher_spec.rb +152 -19
  113. data/spec/unit/shoulda/matchers/routing/route_matcher_spec.rb +258 -94
  114. data/spec/unit_spec_helper.rb +9 -1
  115. data/zeus.json +1 -1
  116. metadata +31 -16
  117. data/gemfiles/4.0.0.gemfile +0 -38
  118. data/gemfiles/4.0.0.gemfile.lock +0 -223
  119. data/gemfiles/4.0.1.gemfile +0 -38
  120. data/gemfiles/4.0.1.gemfile.lock +0 -225
  121. data/gemfiles/4.1.gemfile +0 -38
  122. data/gemfiles/4.1.gemfile.lock +0 -220
  123. data/script/SUPPORTED_VERSIONS +0 -1
@@ -216,6 +216,27 @@ module Shoulda
216
216
  # with_long_message('Secret key must be less than 100 characters')
217
217
  # end
218
218
  #
219
+ # ##### allow_nil
220
+ #
221
+ # Use `allow_nil` to assert that the attribute allows nil.
222
+ #
223
+ # class User
224
+ # include ActiveModel::Model
225
+ # attr_accessor :bio
226
+ #
227
+ # validates_length_of :bio, minimum: 15, allow_nil: true
228
+ # end
229
+ #
230
+ # # RSpec
231
+ # describe User do
232
+ # it { should validate_length_of(:bio).is_at_least(15).allow_nil }
233
+ # end
234
+ #
235
+ # # Test::Unit
236
+ # class UserTest < ActiveSupport::TestCase
237
+ # should validate_length_of(:bio).is_at_least(15).allow_nil
238
+ # end
239
+ #
219
240
  # @return [ValidateLengthOfMatcher]
220
241
  #
221
242
  def validate_length_of(attr)
@@ -281,6 +302,11 @@ module Shoulda
281
302
  self
282
303
  end
283
304
 
305
+ def allow_nil
306
+ @options[:allow_nil] = true
307
+ self
308
+ end
309
+
284
310
  def simple_description
285
311
  description = "validate that the length of :#{@attribute}"
286
312
 
@@ -302,69 +328,102 @@ module Shoulda
302
328
 
303
329
  def matches?(subject)
304
330
  super(subject)
305
- translate_messages!
306
- lower_bound_matches? && upper_bound_matches?
331
+
332
+ lower_bound_matches? &&
333
+ upper_bound_matches? &&
334
+ allow_nil_matches?
307
335
  end
308
336
 
309
- private
337
+ def does_not_match?(subject)
338
+ super(subject)
310
339
 
311
- def translate_messages!
312
- if Symbol === @short_message
313
- @short_message = default_error_message(@short_message,
314
- model_name: @subject.class.to_s.underscore,
315
- instance: @subject,
316
- attribute: @attribute,
317
- count: @options[:minimum])
318
- end
340
+ lower_bound_does_not_match? ||
341
+ upper_bound_does_not_match? ||
342
+ allow_nil_does_not_match?
343
+ end
319
344
 
320
- if Symbol === @long_message
321
- @long_message = default_error_message(@long_message,
322
- model_name: @subject.class.to_s.underscore,
323
- instance: @subject,
324
- attribute: @attribute,
325
- count: @options[:maximum])
326
- end
345
+ private
346
+
347
+ def expects_to_allow_nil?
348
+ @options[:allow_nil]
327
349
  end
328
350
 
329
351
  def lower_bound_matches?
330
352
  disallows_lower_length? && allows_minimum_length?
331
353
  end
332
354
 
355
+ def lower_bound_does_not_match?
356
+ allows_lower_length? || disallows_minimum_length?
357
+ end
358
+
333
359
  def upper_bound_matches?
334
360
  disallows_higher_length? && allows_maximum_length?
335
361
  end
336
362
 
363
+ def upper_bound_does_not_match?
364
+ allows_higher_length? || disallows_maximum_length?
365
+ end
366
+
367
+ def allows_lower_length?
368
+ @options.key?(:minimum) &&
369
+ @options[:minimum] > 0 &&
370
+ allows_length_of?(
371
+ @options[:minimum] - 1,
372
+ translated_short_message
373
+ )
374
+ end
375
+
337
376
  def disallows_lower_length?
338
- if @options.key?(:minimum)
377
+ !@options.key?(:minimum) ||
339
378
  @options[:minimum] == 0 ||
340
- disallows_length_of?(@options[:minimum] - 1, @short_message)
341
- else
342
- true
343
- end
379
+ disallows_length_of?(
380
+ @options[:minimum] - 1,
381
+ translated_short_message
382
+ )
383
+ end
384
+
385
+ def allows_higher_length?
386
+ @options.key?(:maximum) &&
387
+ allows_length_of?(
388
+ @options[:maximum] + 1,
389
+ translated_long_message
390
+ )
344
391
  end
345
392
 
346
393
  def disallows_higher_length?
347
- if @options.key?(:maximum)
348
- disallows_length_of?(@options[:maximum] + 1, @long_message)
349
- else
350
- true
351
- end
394
+ !@options.key?(:maximum) ||
395
+ disallows_length_of?(
396
+ @options[:maximum] + 1,
397
+ translated_long_message
398
+ )
352
399
  end
353
400
 
354
401
  def allows_minimum_length?
355
- if @options.key?(:minimum)
356
- allows_length_of?(@options[:minimum], @short_message)
357
- else
358
- true
359
- end
402
+ !@options.key?(:minimum) ||
403
+ allows_length_of?(@options[:minimum], translated_short_message)
404
+ end
405
+
406
+ def disallows_minimum_length?
407
+ @options.key?(:minimum) &&
408
+ disallows_length_of?(@options[:minimum], translated_short_message)
360
409
  end
361
410
 
362
411
  def allows_maximum_length?
363
- if @options.key?(:maximum)
364
- allows_length_of?(@options[:maximum], @long_message)
365
- else
366
- true
367
- end
412
+ !@options.key?(:maximum) ||
413
+ allows_length_of?(@options[:maximum], translated_long_message)
414
+ end
415
+
416
+ def disallows_maximum_length?
417
+ @options.key?(:maximum) &&
418
+ disallows_length_of?(@options[:maximum], translated_long_message)
419
+ end
420
+
421
+ def allow_nil_matches?
422
+ !expects_to_allow_nil? || allows_value_of(nil)
423
+ end
424
+
425
+ def allow_nil_does_not_match?
426
+ expects_to_allow_nil? && disallows_value_of(nil)
368
427
  end
369
428
 
370
429
  def allows_length_of?(length, message)
@@ -378,6 +437,36 @@ module Shoulda
378
437
  def string_of_length(length)
379
438
  'x' * length
380
439
  end
440
+
441
+ def translated_short_message
442
+ @_translated_short_message ||=
443
+ if @short_message.is_a?(Symbol)
444
+ default_error_message(
445
+ @short_message,
446
+ model_name: @subject.class.to_s.underscore,
447
+ instance: @subject,
448
+ attribute: @attribute,
449
+ count: @options[:minimum]
450
+ )
451
+ else
452
+ @short_message
453
+ end
454
+ end
455
+
456
+ def translated_long_message
457
+ @_translated_long_message ||=
458
+ if @long_message.is_a?(Symbol)
459
+ default_error_message(
460
+ @long_message,
461
+ model_name: @subject.class.to_s.underscore,
462
+ instance: @subject,
463
+ attribute: @attribute,
464
+ count: @options[:maximum]
465
+ )
466
+ else
467
+ @long_message
468
+ end
469
+ end
381
470
  end
382
471
  end
383
472
  end
@@ -411,13 +411,13 @@ module Shoulda
411
411
  end
412
412
 
413
413
  def matches?(subject)
414
- @subject = subject
415
- @number_of_submatchers = @submatchers.size
416
-
417
- add_disallow_value_matcher
418
- qualify_submatchers
414
+ matches_or_does_not_match?(subject)
415
+ first_submatcher_that_fails_to_match.nil?
416
+ end
419
417
 
420
- first_failing_submatcher.nil?
418
+ def does_not_match?(subject)
419
+ matches_or_does_not_match?(subject)
420
+ first_submatcher_that_fails_to_not_match.nil?
421
421
  end
422
422
 
423
423
  def simple_description
@@ -440,20 +440,14 @@ module Shoulda
440
440
  def failure_message
441
441
  overall_failure_message.dup.tap do |message|
442
442
  message << "\n"
443
- message << failure_message_for_first_failing_submatcher
443
+ message << failure_message_for_first_submatcher_that_fails_to_match
444
444
  end
445
445
  end
446
446
 
447
447
  def failure_message_when_negated
448
448
  overall_failure_message_when_negated.dup.tap do |message|
449
- if submatcher_failure_message_when_negated.present?
450
- raise "hmm, this needs to be implemented."
451
- message << "\n"
452
- message << Shoulda::Matchers.word_wrap(
453
- submatcher_failure_message_when_negated,
454
- indent: 2
455
- )
456
- end
449
+ message << "\n"
450
+ message << failure_message_for_first_submatcher_that_fails_to_not_match
457
451
  end
458
452
  end
459
453
 
@@ -464,19 +458,25 @@ module Shoulda
464
458
 
465
459
  private
466
460
 
467
- def model
468
- @subject.class
461
+ def matches_or_does_not_match?(subject)
462
+ @subject = subject
463
+ @number_of_submatchers = @submatchers.size
464
+
465
+ add_disallow_value_matcher
466
+ qualify_submatchers
469
467
  end
470
468
 
471
469
  def overall_failure_message
472
470
  Shoulda::Matchers.word_wrap(
473
- "#{model.name} did not properly #{description}."
471
+ "Expected #{model.name} to #{description}, but this could not " +
472
+ 'be proved.'
474
473
  )
475
474
  end
476
475
 
477
476
  def overall_failure_message_when_negated
478
477
  Shoulda::Matchers.word_wrap(
479
- "Expected #{model.name} not to #{description}, but it did."
478
+ "Expected #{model.name} not to #{description}, but this could not " +
479
+ 'be proved.'
480
480
  )
481
481
  end
482
482
 
@@ -566,35 +566,49 @@ module Shoulda
566
566
  end
567
567
  end
568
568
 
569
- def first_failing_submatcher
569
+ def first_submatcher_that_fails_to_match
570
570
  @_failing_submatchers ||= @submatchers.detect do |submatcher|
571
571
  !submatcher.matches?(@subject)
572
572
  end
573
573
  end
574
574
 
575
- def submatcher_failure_message
576
- first_failing_submatcher.failure_message
575
+ def first_submatcher_that_fails_to_not_match
576
+ @_failing_submatchers ||= @submatchers.detect do |submatcher|
577
+ !submatcher.does_not_match?(@subject)
578
+ end
577
579
  end
578
580
 
579
- def submatcher_failure_message_when_negated
580
- first_failing_submatcher.failure_message_when_negated
581
+ def failure_message_for_first_submatcher_that_fails_to_match
582
+ build_submatcher_failure_message_for(
583
+ first_submatcher_that_fails_to_match,
584
+ :failure_message
585
+ )
581
586
  end
582
587
 
583
- def failure_message_for_first_failing_submatcher
584
- submatcher = first_failing_submatcher
588
+ def failure_message_for_first_submatcher_that_fails_to_not_match
589
+ build_submatcher_failure_message_for(
590
+ first_submatcher_that_fails_to_not_match,
591
+ :failure_message_when_negated
592
+ )
593
+ end
585
594
 
586
- if number_of_submatchers_for_failure_message > 1
587
- submatcher_description = submatcher.simple_description.
588
- sub(/\bvalidate that\b/, 'validates').
589
- sub(/\bdisallow\b/, 'disallows').
590
- sub(/\ballow\b/, 'allows')
591
- submatcher_message =
595
+ def build_submatcher_failure_message_for(
596
+ submatcher,
597
+ failure_message_method
598
+ )
599
+ failure_message = submatcher.public_send(failure_message_method)
600
+ submatcher_description = submatcher.simple_description.
601
+ sub(/\bvalidate that\b/, 'validates').
602
+ sub(/\bdisallow\b/, 'disallows').
603
+ sub(/\ballow\b/, 'allows')
604
+ submatcher_message =
605
+ if number_of_submatchers_for_failure_message > 1
592
606
  "In checking that #{model.name} #{submatcher_description}, " +
593
- submatcher.failure_message[0].downcase +
594
- submatcher.failure_message[1..-1]
595
- else
596
- submatcher_message = submatcher.failure_message
597
- end
607
+ failure_message[0].downcase +
608
+ failure_message[1..-1]
609
+ else
610
+ failure_message
611
+ end
598
612
 
599
613
  Shoulda::Matchers.word_wrap(submatcher_message, indent: 2)
600
614
  end
@@ -616,6 +630,10 @@ module Shoulda
616
630
  arr
617
631
  end
618
632
  end
633
+
634
+ def model
635
+ @subject.class
636
+ end
619
637
  end
620
638
  end
621
639
  end
@@ -119,14 +119,27 @@ module Shoulda
119
119
  def matches?(subject)
120
120
  super(subject)
121
121
 
122
+ possibly_ignore_interference_by_writer
123
+
122
124
  if secure_password_being_validated?
123
- ignore_interference_by_writer.default_to(when: :blank?)
124
125
  disallows_and_double_checks_value_of!(blank_value, @expected_message)
125
126
  else
126
127
  disallows_original_or_typecast_value?(blank_value, @expected_message)
127
128
  end
128
129
  end
129
130
 
131
+ def does_not_match?(subject)
132
+ super(subject)
133
+
134
+ possibly_ignore_interference_by_writer
135
+
136
+ if secure_password_being_validated?
137
+ allows_and_double_checks_value_of!(blank_value, @expected_message)
138
+ else
139
+ allows_original_or_typecast_value?(blank_value, @expected_message)
140
+ end
141
+ end
142
+
130
143
  def simple_description
131
144
  "validate that :#{@attribute} cannot be empty/falsy"
132
145
  end
@@ -139,6 +152,22 @@ module Shoulda
139
152
  @attribute == :password
140
153
  end
141
154
 
155
+ def possibly_ignore_interference_by_writer
156
+ if secure_password_being_validated?
157
+ ignore_interference_by_writer.default_to(when: :blank?)
158
+ end
159
+ end
160
+
161
+ def allows_and_double_checks_value_of!(value, message)
162
+ allows_value_of(value, message)
163
+ rescue ActiveModel::AllowValueMatcher::AttributeChangedValueError
164
+ raise ActiveModel::CouldNotSetPasswordError.create(@subject.class)
165
+ end
166
+
167
+ def allows_original_or_typecast_value?(value, message)
168
+ allows_value_of(blank_value, @expected_message)
169
+ end
170
+
142
171
  def disallows_and_double_checks_value_of!(value, message)
143
172
  disallows_value_of(value, message)
144
173
  rescue ActiveModel::AllowValueMatcher::AttributeChangedValueError
@@ -51,6 +51,11 @@ module Shoulda
51
51
  false
52
52
  end
53
53
 
54
+ def does_not_match?(subject)
55
+ @subject = subject
56
+ true
57
+ end
58
+
54
59
  def failure_message
55
60
  overall_failure_message.dup.tap do |message|
56
61
  if failure_reason.present?
@@ -65,10 +70,10 @@ module Shoulda
65
70
 
66
71
  def failure_message_when_negated
67
72
  overall_failure_message_when_negated.dup.tap do |message|
68
- if failure_reason_when_negated.present?
73
+ if failure_reason.present?
69
74
  message << "\n"
70
75
  message << Shoulda::Matchers.word_wrap(
71
- failure_reason_when_negated,
76
+ failure_reason,
72
77
  indent: 2
73
78
  )
74
79
  end
@@ -115,13 +120,15 @@ module Shoulda
115
120
 
116
121
  def overall_failure_message
117
122
  Shoulda::Matchers.word_wrap(
118
- "#{model.name} did not properly #{description}."
123
+ "Expected #{model.name} to #{description}, but this could not be " +
124
+ 'proved.'
119
125
  )
120
126
  end
121
127
 
122
128
  def overall_failure_message_when_negated
123
129
  Shoulda::Matchers.word_wrap(
124
- "Expected #{model.name} not to #{description}, but it did."
130
+ "Expected #{model.name} not to #{description}, but this could " +
131
+ 'not be proved.'
125
132
  )
126
133
  end
127
134