shoulda-matchers 1.4.2 → 1.5.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 (135) hide show
  1. data/.travis.yml +11 -3
  2. data/Appraisals +3 -3
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +69 -70
  5. data/MIT-LICENSE +1 -1
  6. data/NEWS.md +22 -4
  7. data/README.md +3 -1
  8. data/Rakefile +9 -5
  9. data/features/step_definitions/rails_steps.rb +7 -7
  10. data/features/support/env.rb +1 -1
  11. data/gemfiles/3.0.gemfile +1 -1
  12. data/gemfiles/3.0.gemfile.lock +25 -22
  13. data/gemfiles/3.1.gemfile +1 -1
  14. data/gemfiles/3.1.gemfile.lock +27 -24
  15. data/gemfiles/3.2.gemfile +1 -1
  16. data/gemfiles/3.2.gemfile.lock +56 -52
  17. data/lib/shoulda/matchers/action_controller.rb +3 -2
  18. data/lib/shoulda/matchers/action_controller/assign_to_matcher.rb +10 -8
  19. data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +2 -4
  20. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +3 -4
  21. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +3 -4
  22. data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +6 -6
  23. data/lib/shoulda/matchers/action_controller/respond_with_content_type_matcher.rb +5 -2
  24. data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +2 -2
  25. data/lib/shoulda/matchers/action_controller/route_matcher.rb +12 -12
  26. data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +3 -4
  27. data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +10 -11
  28. data/lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb +121 -0
  29. data/lib/shoulda/matchers/action_mailer/have_sent_email_matcher.rb +7 -4
  30. data/lib/shoulda/matchers/active_model.rb +1 -1
  31. data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +8 -8
  32. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +5 -4
  33. data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +3 -3
  34. data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +2 -2
  35. data/lib/shoulda/matchers/active_model/exception_message_finder.rb +0 -1
  36. data/lib/shoulda/matchers/active_model/helpers.rb +16 -7
  37. data/lib/shoulda/matchers/active_model/only_integer_matcher.rb +3 -3
  38. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +8 -6
  39. data/lib/shoulda/matchers/active_model/validate_format_of_matcher.rb +19 -10
  40. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +4 -4
  41. data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +19 -21
  42. data/lib/shoulda/matchers/active_model/validation_matcher.rb +7 -7
  43. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +1 -1
  44. data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +5 -5
  45. data/lib/shoulda/matchers/active_record/association_matcher.rb +3 -3
  46. data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +11 -7
  47. data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +2 -2
  48. data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +5 -5
  49. data/lib/shoulda/matchers/active_record/query_the_database_matcher.rb +5 -2
  50. data/lib/shoulda/matchers/active_record/serialize_matcher.rb +3 -3
  51. data/lib/shoulda/matchers/assertion_error.rb +4 -1
  52. data/lib/shoulda/matchers/independent/delegate_matcher.rb +17 -7
  53. data/lib/shoulda/matchers/integrations/rspec.rb +19 -33
  54. data/lib/shoulda/matchers/version.rb +1 -1
  55. data/shoulda-matchers.gemspec +6 -4
  56. data/spec/shoulda/matchers/action_controller/assign_to_matcher_spec.rb +66 -0
  57. data/spec/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +22 -0
  58. data/spec/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +42 -0
  59. data/spec/shoulda/matchers/action_controller/render_template_matcher_spec.rb +78 -0
  60. data/spec/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +58 -0
  61. data/spec/shoulda/matchers/action_controller/respond_with_content_type_matcher_spec.rb +31 -0
  62. data/spec/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +31 -0
  63. data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +65 -0
  64. data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +51 -0
  65. data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +153 -0
  66. data/spec/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +142 -0
  67. data/spec/shoulda/matchers/action_mailer/have_sent_email_spec.rb +324 -0
  68. data/spec/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +111 -0
  69. data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +124 -0
  70. data/spec/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +43 -0
  71. data/spec/shoulda/matchers/active_model/ensure_exclusion_of_matcher_spec.rb +74 -0
  72. data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +171 -0
  73. data/spec/shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb +113 -0
  74. data/spec/shoulda/{active_model → matchers/active_model}/exception_message_finder_spec.rb +2 -2
  75. data/spec/shoulda/matchers/active_model/helpers_spec.rb +158 -0
  76. data/spec/shoulda/matchers/active_model/only_integer_matcher_spec.rb +52 -0
  77. data/spec/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +41 -0
  78. data/spec/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +41 -0
  79. data/spec/shoulda/matchers/active_model/validate_format_of_matcher_spec.rb +75 -0
  80. data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +73 -0
  81. data/spec/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +127 -0
  82. data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +175 -0
  83. data/spec/shoulda/{active_model → matchers/active_model}/validation_message_finder_spec.rb +0 -1
  84. data/spec/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +106 -0
  85. data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +534 -0
  86. data/spec/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +111 -0
  87. data/spec/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +78 -0
  88. data/spec/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +41 -0
  89. data/spec/shoulda/{active_record → matchers/active_record}/query_the_database_matcher_spec.rb +10 -10
  90. data/spec/shoulda/matchers/active_record/serialize_matcher_spec.rb +86 -0
  91. data/spec/shoulda/{independent → matchers/independent}/delegate_matcher_spec.rb +55 -34
  92. data/spec/spec_helper.rb +1 -2
  93. data/spec/support/active_model_versions.rb +4 -0
  94. data/spec/support/activemodel_helpers.rb +19 -0
  95. data/spec/support/controller_builder.rb +38 -12
  96. data/spec/support/model_builder.rb +8 -2
  97. metadata +106 -98
  98. data/spec/fixtures/addresses.yml +0 -3
  99. data/spec/fixtures/friendships.yml +0 -0
  100. data/spec/fixtures/posts.yml +0 -5
  101. data/spec/fixtures/products.yml +0 -0
  102. data/spec/fixtures/taggings.yml +0 -0
  103. data/spec/fixtures/tags.yml +0 -9
  104. data/spec/fixtures/users.yml +0 -6
  105. data/spec/shoulda/action_controller/assign_to_matcher_spec.rb +0 -63
  106. data/spec/shoulda/action_controller/filter_param_matcher_spec.rb +0 -20
  107. data/spec/shoulda/action_controller/redirect_to_matcher_spec.rb +0 -40
  108. data/spec/shoulda/action_controller/render_template_matcher_spec.rb +0 -69
  109. data/spec/shoulda/action_controller/render_with_layout_matcher_spec.rb +0 -55
  110. data/spec/shoulda/action_controller/respond_with_content_type_matcher_spec.rb +0 -28
  111. data/spec/shoulda/action_controller/respond_with_matcher_spec.rb +0 -83
  112. data/spec/shoulda/action_controller/route_matcher_spec.rb +0 -65
  113. data/spec/shoulda/action_controller/set_session_matcher_spec.rb +0 -46
  114. data/spec/shoulda/action_controller/set_the_flash_matcher_spec.rb +0 -130
  115. data/spec/shoulda/action_mailer/have_sent_email_spec.rb +0 -333
  116. data/spec/shoulda/active_model/allow_mass_assignment_of_matcher_spec.rb +0 -115
  117. data/spec/shoulda/active_model/allow_value_matcher_spec.rb +0 -131
  118. data/spec/shoulda/active_model/disallow_value_matcher_spec.rb +0 -65
  119. data/spec/shoulda/active_model/ensure_exclusion_of_matcher_spec.rb +0 -79
  120. data/spec/shoulda/active_model/ensure_inclusion_of_matcher_spec.rb +0 -181
  121. data/spec/shoulda/active_model/ensure_length_of_matcher_spec.rb +0 -138
  122. data/spec/shoulda/active_model/helpers_spec.rb +0 -129
  123. data/spec/shoulda/active_model/only_integer_matcher_spec.rb +0 -69
  124. data/spec/shoulda/active_model/validate_acceptance_of_matcher_spec.rb +0 -43
  125. data/spec/shoulda/active_model/validate_confirmation_of_matcher_spec.rb +0 -48
  126. data/spec/shoulda/active_model/validate_format_of_matcher_spec.rb +0 -79
  127. data/spec/shoulda/active_model/validate_numericality_of_matcher_spec.rb +0 -112
  128. data/spec/shoulda/active_model/validate_presence_of_matcher_spec.rb +0 -135
  129. data/spec/shoulda/active_model/validate_uniqueness_of_matcher_spec.rb +0 -154
  130. data/spec/shoulda/active_record/accept_nested_attributes_for_matcher_spec.rb +0 -84
  131. data/spec/shoulda/active_record/association_matcher_spec.rb +0 -642
  132. data/spec/shoulda/active_record/have_db_column_matcher_spec.rb +0 -185
  133. data/spec/shoulda/active_record/have_db_index_matcher_spec.rb +0 -105
  134. data/spec/shoulda/active_record/have_readonly_attributes_matcher_spec.rb +0 -46
  135. data/spec/shoulda/active_record/serialize_matcher_spec.rb +0 -81
@@ -30,7 +30,7 @@ module Shoulda
30
30
  # %w(abcd 1234).each do |value|
31
31
  # it { should_not allow_value(value).for(:phone_number) }
32
32
  # end
33
- # it { should allow_value("(123) 456-7890").for(:phone_number) }
33
+ # it { should allow_value('(123) 456-7890').for(:phone_number) }
34
34
  # it { should_not allow_mass_assignment_of(:password) }
35
35
  # it { should allow_value('Activated', 'Pending').for(:status).strict }
36
36
  # it { should_not allow_value('Amazing').for(:status).strict }
@@ -16,7 +16,7 @@ module Shoulda # :nodoc:
16
16
  end
17
17
 
18
18
  class AllowMassAssignmentOfMatcher # :nodoc:
19
- attr_reader :failure_message, :negative_failure_message
19
+ attr_reader :failure_message_for_should, :failure_message_for_should_not
20
20
 
21
21
  def initialize(attribute)
22
22
  @attribute = attribute.to_s
@@ -25,7 +25,7 @@ module Shoulda # :nodoc:
25
25
 
26
26
  def as(role)
27
27
  if active_model_less_than_3_1?
28
- raise "You can specify role only in Rails 3.1 or greater"
28
+ raise 'You can specify role only in Rails 3.1 or greater'
29
29
  end
30
30
  @options[:role] = role
31
31
  self
@@ -35,12 +35,12 @@ module Shoulda # :nodoc:
35
35
  @subject = subject
36
36
  if attr_mass_assignable?
37
37
  if whitelisting?
38
- @negative_failure_message = "#{@attribute} was made accessible"
38
+ @failure_message_for_should_not = "#{@attribute} was made accessible"
39
39
  else
40
40
  if protected_attributes.empty?
41
- @negative_failure_message = "no attributes were protected"
41
+ @failure_message_for_should_not = 'no attributes were protected'
42
42
  else
43
- @negative_failure_message = "#{class_name} is protecting " <<
43
+ @failure_message_for_should_not = "#{class_name} is protecting " <<
44
44
  "#{protected_attributes.to_a.to_sentence}, " <<
45
45
  "but not #{@attribute}."
46
46
  end
@@ -48,16 +48,16 @@ module Shoulda # :nodoc:
48
48
  true
49
49
  else
50
50
  if whitelisting?
51
- @failure_message = "Expected #{@attribute} to be accessible"
51
+ @failure_message_for_should = "Expected #{@attribute} to be accessible"
52
52
  else
53
- @failure_message = "Did not expect #{@attribute} to be protected"
53
+ @failure_message_for_should = "Did not expect #{@attribute} to be protected"
54
54
  end
55
55
  false
56
56
  end
57
57
  end
58
58
 
59
59
  def description
60
- [base_description, role_description].compact.join(" ")
60
+ [base_description, role_description].compact.join(' ')
61
61
  end
62
62
 
63
63
  private
@@ -17,11 +17,11 @@ module Shoulda # :nodoc:
17
17
  #
18
18
  # Example:
19
19
  # it { should_not allow_value('bad').for(:isbn) }
20
- # it { should allow_value("isbn 1 2345 6789 0").for(:isbn) }
20
+ # it { should allow_value('isbn 1 2345 6789 0').for(:isbn) }
21
21
  #
22
22
  def allow_value(*values)
23
23
  if values.empty?
24
- raise ArgumentError, "need at least one argument"
24
+ raise ArgumentError, 'need at least one argument'
25
25
  else
26
26
  AllowValueMatcher.new(*values)
27
27
  end
@@ -60,11 +60,11 @@ module Shoulda # :nodoc:
60
60
  end
61
61
  end
62
62
 
63
- def failure_message
63
+ def failure_message_for_should
64
64
  "Did not expect #{expectation}, got error: #{@matched_error}"
65
65
  end
66
66
 
67
- def negative_failure_message
67
+ def failure_message_for_should_not
68
68
  "Expected #{expectation}, got #{error_description}"
69
69
  end
70
70
 
@@ -145,6 +145,7 @@ module Shoulda # :nodoc:
145
145
  default_error_message(
146
146
  @options[:expected_message],
147
147
  :model_name => model_name,
148
+ :instance => @instance,
148
149
  :attribute => @attribute
149
150
  )
150
151
  end
@@ -20,12 +20,12 @@ module Shoulda # :nodoc:
20
20
  self
21
21
  end
22
22
 
23
- def failure_message
24
- @allow_matcher.negative_failure_message
23
+ def failure_message_for_should
24
+ @allow_matcher.failure_message_for_should_not
25
25
  end
26
26
 
27
27
  def allowed_types
28
- ""
28
+ ''
29
29
  end
30
30
  end
31
31
  end
@@ -22,7 +22,7 @@ module Shoulda # :nodoc:
22
22
  end
23
23
 
24
24
  class EnsureInclusionOfMatcher < ValidationMatcher # :nodoc:
25
- ARBITRARY_OUTSIDE_STRING = "shouldamatchersteststring"
25
+ ARBITRARY_OUTSIDE_STRING = 'shouldamatchersteststring'
26
26
 
27
27
  def initialize(attribute)
28
28
  super(attribute)
@@ -88,7 +88,7 @@ module Shoulda # :nodoc:
88
88
  if allows_all_values_in_array? && allows_blank_value? && allows_nil_value? && disallows_value_outside_of_array?
89
89
  true
90
90
  else
91
- @failure_message = "#{@array} doesn't match array in validation"
91
+ @failure_message_for_should = "#{@array} doesn't match array in validation"
92
92
  false
93
93
  end
94
94
  end
@@ -1,7 +1,6 @@
1
1
  module Shoulda
2
2
  module Matchers
3
3
  module ActiveModel
4
-
5
4
  # Finds message information from exceptions thrown by #valid?
6
5
  class ExceptionMessageFinder
7
6
  def initialize(instance, attribute)
@@ -11,21 +11,30 @@ module Shoulda # :nodoc:
11
11
 
12
12
  # Helper method that determines the default error message used by Active
13
13
  # Record. Works for both existing Rails 2.1 and Rails 2.2 with the newly
14
- # introduced I18n module used for localization.
14
+ # introduced I18n module used for localization. Use with Rails 3.0 and
15
+ # up will delegate to ActiveModel::Errors.generate_error if a model
16
+ # instance is given.
15
17
  #
16
18
  # default_error_message(:blank)
17
19
  # default_error_message(:too_short, :count => 5)
18
20
  # default_error_message(:too_long, :count => 60)
19
21
  # default_error_message(:blank, :model_name => 'user', :attribute => 'name')
22
+ # default_error_message(:blank, :instance => #<Model>, :attribute => 'name')
20
23
  def default_error_message(key, options = {})
21
24
  model_name = options.delete(:model_name)
22
25
  attribute = options.delete(:attribute)
23
- default_translation = [ :"activerecord.errors.models.#{model_name}.#{key}",
24
- :"activerecord.errors.messages.#{key}",
25
- :"errors.attributes.#{attribute}.#{key}",
26
- :"errors.messages.#{key}" ]
27
- I18n.translate(:"activerecord.errors.models.#{model_name}.attributes.#{attribute}.#{key}",
28
- { :default => default_translation }.merge(options))
26
+ instance = options.delete(:instance)
27
+
28
+ if instance && instance.errors.respond_to?(:generate_message)
29
+ instance.errors.generate_message(attribute.to_sym, key, {})
30
+ else
31
+ default_translation = [ :"activerecord.errors.models.#{model_name}.#{key}",
32
+ :"activerecord.errors.messages.#{key}",
33
+ :"errors.attributes.#{attribute}.#{key}",
34
+ :"errors.messages.#{key}" ]
35
+ I18n.translate(:"activerecord.errors.models.#{model_name}.attributes.#{attribute}.#{key}",
36
+ { :default => default_translation }.merge(options))
37
+ end
29
38
  end
30
39
  end
31
40
  end
@@ -21,11 +21,11 @@ module Shoulda # :nodoc:
21
21
  end
22
22
 
23
23
  def allowed_types
24
- "integer"
24
+ 'integer'
25
25
  end
26
26
 
27
- def failure_message
28
- @disallow_value_matcher.failure_message
27
+ def failure_message_for_should
28
+ @disallow_value_matcher.failure_message_for_should
29
29
  end
30
30
  end
31
31
  end
@@ -39,23 +39,25 @@ module Shoulda # :nodoc:
39
39
  private
40
40
 
41
41
  def disallows_different_value
42
- set_confirmation("some value")
43
- matches = disallows_value_of("different value", @message)
42
+ set_confirmation('some value')
43
+ disallows_value_of('different value', @message)
44
44
  end
45
45
 
46
46
  def allows_same_value
47
- set_confirmation("same value")
48
- allows_value_of("same value", @message)
47
+ set_confirmation('same value')
48
+ allows_value_of('same value', @message)
49
49
  end
50
50
 
51
51
  def allows_missing_confirmation
52
52
  set_confirmation(nil)
53
- allows_value_of("any value", @message)
53
+ allows_value_of('any value', @message)
54
54
  end
55
55
 
56
56
  def set_confirmation(val)
57
57
  setter = :"#{@confirmation}="
58
- @subject.send(setter, val) if @subject.respond_to?(setter)
58
+ if @subject.respond_to?(setter)
59
+ @subject.send(setter, val)
60
+ end
59
61
  end
60
62
  end
61
63
  end
@@ -1,7 +1,8 @@
1
+ require 'active_support/deprecation'
2
+
1
3
  module Shoulda # :nodoc:
2
4
  module Matchers
3
5
  module ActiveModel # :nodoc:
4
-
5
6
  # Ensures that the model is not valid if the given attribute is not
6
7
  # formatted correctly.
7
8
  #
@@ -27,8 +28,8 @@ module Shoulda # :nodoc:
27
28
  end
28
29
 
29
30
  class ValidateFormatOfMatcher < ValidationMatcher # :nodoc:
30
-
31
31
  def initialize(attribute)
32
+ ActiveSupport::Deprecation.warn 'The validate_format_of matcher is deprecated and will be removed in 2.0'
32
33
  super
33
34
  @options = {}
34
35
  end
@@ -44,20 +45,28 @@ module Shoulda # :nodoc:
44
45
  end
45
46
 
46
47
  def with_message(message)
47
- @expected_message = message if message
48
+ if message
49
+ @expected_message = message
50
+ end
48
51
  self
49
52
  end
50
53
 
51
54
  def with(value)
52
- raise "You may not call both with and not_with" if @value_to_fail
53
- @value_to_pass = value
54
- self
55
+ if @value_to_fail
56
+ raise 'You may not call both with and not_with'
57
+ else
58
+ @value_to_pass = value
59
+ self
60
+ end
55
61
  end
56
62
 
57
63
  def not_with(value)
58
- raise "You may not call both with and not_with" if @value_to_pass
59
- @value_to_fail = value
60
- self
64
+ if @value_to_pass
65
+ raise 'You may not call both with and not_with'
66
+ else
67
+ @value_to_fail = value
68
+ self
69
+ end
61
70
  end
62
71
 
63
72
  def matches?(subject)
@@ -72,7 +81,7 @@ module Shoulda # :nodoc:
72
81
  end
73
82
 
74
83
  def description
75
- "#{@attribute} have a valid format"
84
+ "have a valid format for #{@attribute}"
76
85
  end
77
86
 
78
87
  private
@@ -48,7 +48,7 @@ module Shoulda # :nodoc:
48
48
  "only allow #{allowed_types} values for #{@attribute}"
49
49
  end
50
50
 
51
- def failure_message
51
+ def failure_message_for_should
52
52
  submatcher_failure_messages.last
53
53
  end
54
54
 
@@ -71,7 +71,7 @@ module Shoulda # :nodoc:
71
71
  end
72
72
 
73
73
  def submatcher_failure_messages
74
- failing_submatchers.map(&:failure_message)
74
+ failing_submatchers.map(&:failure_message_for_should)
75
75
  end
76
76
 
77
77
  def failing_submatchers
@@ -79,8 +79,8 @@ module Shoulda # :nodoc:
79
79
  end
80
80
 
81
81
  def allowed_types
82
- allowed = ["numeric"] + submatcher_allowed_types
83
- allowed.join(", ")
82
+ allowed = ['numeric'] + submatcher_allowed_types
83
+ allowed.join(', ')
84
84
  end
85
85
 
86
86
  def submatcher_allowed_types
@@ -1,17 +1,15 @@
1
1
  module Shoulda # :nodoc:
2
2
  module Matchers
3
3
  module ActiveModel # :nodoc:
4
-
5
4
  # Ensures that the model is invalid if the given attribute is not unique.
5
+ # It uses the first existing record or creates a new one if no record
6
+ # exists in the database. It simply uses `:validate => false` to get
7
+ # around validations, so it will probably fail if there are `NOT NULL`
8
+ # constraints. In that case, you must create a record before calling
9
+ # `validate_uniqueness_of`.
6
10
  #
7
- # Internally, this uses values from existing records to test validations,
8
- # so this will always fail if you have not saved at least one record for
9
- # the model being tested, like so:
10
- #
11
- # describe User do
12
- # before(:each) { User.create!(:email => 'address@example.com') }
13
- # it { should validate_uniqueness_of(:email) }
14
- # end
11
+ # Example:
12
+ # it { should validate_uniqueness_of(:email) }
15
13
  #
16
14
  # Options:
17
15
  #
@@ -57,14 +55,6 @@ module Shoulda # :nodoc:
57
55
  self
58
56
  end
59
57
 
60
- def description
61
- result = "require "
62
- result << "case sensitive " unless @options[:case_insensitive]
63
- result << "unique value for #{@attribute}"
64
- result << " scoped to #{@options[:scopes].join(', ')}" if @options[:scopes].present?
65
- result
66
- end
67
-
68
58
  def matches?(subject)
69
59
  @subject = subject.class.new
70
60
  @expected_message ||= :taken
@@ -73,6 +63,14 @@ module Shoulda # :nodoc:
73
63
  validate_after_scope_change?
74
64
  end
75
65
 
66
+ def description
67
+ result = 'require '
68
+ result << 'case sensitive ' unless @options[:case_insensitive]
69
+ result << "unique value for #{@attribute}"
70
+ result << " scoped to #{@options[:scopes].join(', ')}" if @options[:scopes].present?
71
+ result
72
+ end
73
+
76
74
  private
77
75
 
78
76
  def existing
@@ -85,7 +83,7 @@ module Shoulda # :nodoc:
85
83
 
86
84
  def create_instance_in_database
87
85
  @subject.class.new.tap do |instance|
88
- instance.send("#{@attribute}=", "arbitrary_string")
86
+ instance.send("#{@attribute}=", 'arbitrary_string')
89
87
  instance.save(:validate => false)
90
88
  end
91
89
  end
@@ -98,7 +96,7 @@ module Shoulda # :nodoc:
98
96
  @subject.send(setter, existing.send(scope))
99
97
  true
100
98
  else
101
- @failure_message = "#{class_name} doesn't seem to have a #{scope} attribute."
99
+ @failure_message_for_should = "#{class_name} doesn't seem to have a #{scope} attribute."
102
100
  false
103
101
  end
104
102
  end
@@ -135,11 +133,11 @@ module Shoulda # :nodoc:
135
133
  if allows_value_of(existing_value, @expected_message)
136
134
  @subject.send("#{scope}=", previous_value)
137
135
 
138
- @negative_failure_message <<
136
+ @failure_message_for_should_not <<
139
137
  " (with different value of #{scope})"
140
138
  true
141
139
  else
142
- @failure_message << " (with different value of #{scope})"
140
+ @failure_message_for_should << " (with different value of #{scope})"
143
141
  false
144
142
  end
145
143
  end
@@ -2,7 +2,7 @@ module Shoulda # :nodoc:
2
2
  module Matchers
3
3
  module ActiveModel # :nodoc:
4
4
  class ValidationMatcher # :nodoc:
5
- attr_reader :failure_message
5
+ attr_reader :failure_message_for_should
6
6
 
7
7
  def initialize(attribute)
8
8
  @attribute = attribute
@@ -14,8 +14,8 @@ module Shoulda # :nodoc:
14
14
  self
15
15
  end
16
16
 
17
- def negative_failure_message
18
- @negative_failure_message || @failure_message
17
+ def failure_message_for_should_not
18
+ @failure_message_for_should_not || @failure_message_for_should
19
19
  end
20
20
 
21
21
  def matches?(subject)
@@ -29,10 +29,10 @@ module Shoulda # :nodoc:
29
29
  allow = allow_value_matcher(value, message)
30
30
 
31
31
  if allow.matches?(@subject)
32
- @negative_failure_message = allow.failure_message
32
+ @failure_message_for_should_not = allow.failure_message_for_should
33
33
  true
34
34
  else
35
- @failure_message = allow.negative_failure_message
35
+ @failure_message_for_should = allow.failure_message_for_should_not
36
36
  false
37
37
  end
38
38
  end
@@ -41,10 +41,10 @@ module Shoulda # :nodoc:
41
41
  disallow = allow_value_matcher(value, message)
42
42
 
43
43
  if disallow.matches?(@subject)
44
- @failure_message = disallow.negative_failure_message
44
+ @failure_message_for_should = disallow.failure_message_for_should_not
45
45
  false
46
46
  else
47
- @negative_failure_message = disallow.failure_message
47
+ @failure_message_for_should_not = disallow.failure_message_for_should
48
48
  true
49
49
  end
50
50
  end