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.
- data/.travis.yml +11 -3
- data/Appraisals +3 -3
- data/Gemfile +1 -1
- data/Gemfile.lock +69 -70
- data/MIT-LICENSE +1 -1
- data/NEWS.md +22 -4
- data/README.md +3 -1
- data/Rakefile +9 -5
- data/features/step_definitions/rails_steps.rb +7 -7
- data/features/support/env.rb +1 -1
- data/gemfiles/3.0.gemfile +1 -1
- data/gemfiles/3.0.gemfile.lock +25 -22
- data/gemfiles/3.1.gemfile +1 -1
- data/gemfiles/3.1.gemfile.lock +27 -24
- data/gemfiles/3.2.gemfile +1 -1
- data/gemfiles/3.2.gemfile.lock +56 -52
- data/lib/shoulda/matchers/action_controller.rb +3 -2
- data/lib/shoulda/matchers/action_controller/assign_to_matcher.rb +10 -8
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +2 -4
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +3 -4
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +3 -4
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +6 -6
- data/lib/shoulda/matchers/action_controller/respond_with_content_type_matcher.rb +5 -2
- data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +2 -2
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +12 -12
- data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +3 -4
- data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +10 -11
- data/lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb +121 -0
- data/lib/shoulda/matchers/action_mailer/have_sent_email_matcher.rb +7 -4
- data/lib/shoulda/matchers/active_model.rb +1 -1
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +8 -8
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +5 -4
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_model/exception_message_finder.rb +0 -1
- data/lib/shoulda/matchers/active_model/helpers.rb +16 -7
- data/lib/shoulda/matchers/active_model/only_integer_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +8 -6
- data/lib/shoulda/matchers/active_model/validate_format_of_matcher.rb +19 -10
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +4 -4
- data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +19 -21
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +7 -7
- data/lib/shoulda/matchers/active_model/validation_message_finder.rb +1 -1
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +5 -5
- data/lib/shoulda/matchers/active_record/association_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +11 -7
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +5 -5
- data/lib/shoulda/matchers/active_record/query_the_database_matcher.rb +5 -2
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +3 -3
- data/lib/shoulda/matchers/assertion_error.rb +4 -1
- data/lib/shoulda/matchers/independent/delegate_matcher.rb +17 -7
- data/lib/shoulda/matchers/integrations/rspec.rb +19 -33
- data/lib/shoulda/matchers/version.rb +1 -1
- data/shoulda-matchers.gemspec +6 -4
- data/spec/shoulda/matchers/action_controller/assign_to_matcher_spec.rb +66 -0
- data/spec/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +22 -0
- data/spec/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +42 -0
- data/spec/shoulda/matchers/action_controller/render_template_matcher_spec.rb +78 -0
- data/spec/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +58 -0
- data/spec/shoulda/matchers/action_controller/respond_with_content_type_matcher_spec.rb +31 -0
- data/spec/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +31 -0
- data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +65 -0
- data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +51 -0
- data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +153 -0
- data/spec/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +142 -0
- data/spec/shoulda/matchers/action_mailer/have_sent_email_spec.rb +324 -0
- data/spec/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +111 -0
- data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +124 -0
- data/spec/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +43 -0
- data/spec/shoulda/matchers/active_model/ensure_exclusion_of_matcher_spec.rb +74 -0
- data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +171 -0
- data/spec/shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb +113 -0
- data/spec/shoulda/{active_model → matchers/active_model}/exception_message_finder_spec.rb +2 -2
- data/spec/shoulda/matchers/active_model/helpers_spec.rb +158 -0
- data/spec/shoulda/matchers/active_model/only_integer_matcher_spec.rb +52 -0
- data/spec/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +41 -0
- data/spec/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +41 -0
- data/spec/shoulda/matchers/active_model/validate_format_of_matcher_spec.rb +75 -0
- data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +73 -0
- data/spec/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +127 -0
- data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +175 -0
- data/spec/shoulda/{active_model → matchers/active_model}/validation_message_finder_spec.rb +0 -1
- data/spec/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +106 -0
- data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +534 -0
- data/spec/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +111 -0
- data/spec/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +78 -0
- data/spec/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +41 -0
- data/spec/shoulda/{active_record → matchers/active_record}/query_the_database_matcher_spec.rb +10 -10
- data/spec/shoulda/matchers/active_record/serialize_matcher_spec.rb +86 -0
- data/spec/shoulda/{independent → matchers/independent}/delegate_matcher_spec.rb +55 -34
- data/spec/spec_helper.rb +1 -2
- data/spec/support/active_model_versions.rb +4 -0
- data/spec/support/activemodel_helpers.rb +19 -0
- data/spec/support/controller_builder.rb +38 -12
- data/spec/support/model_builder.rb +8 -2
- metadata +106 -98
- data/spec/fixtures/addresses.yml +0 -3
- data/spec/fixtures/friendships.yml +0 -0
- data/spec/fixtures/posts.yml +0 -5
- data/spec/fixtures/products.yml +0 -0
- data/spec/fixtures/taggings.yml +0 -0
- data/spec/fixtures/tags.yml +0 -9
- data/spec/fixtures/users.yml +0 -6
- data/spec/shoulda/action_controller/assign_to_matcher_spec.rb +0 -63
- data/spec/shoulda/action_controller/filter_param_matcher_spec.rb +0 -20
- data/spec/shoulda/action_controller/redirect_to_matcher_spec.rb +0 -40
- data/spec/shoulda/action_controller/render_template_matcher_spec.rb +0 -69
- data/spec/shoulda/action_controller/render_with_layout_matcher_spec.rb +0 -55
- data/spec/shoulda/action_controller/respond_with_content_type_matcher_spec.rb +0 -28
- data/spec/shoulda/action_controller/respond_with_matcher_spec.rb +0 -83
- data/spec/shoulda/action_controller/route_matcher_spec.rb +0 -65
- data/spec/shoulda/action_controller/set_session_matcher_spec.rb +0 -46
- data/spec/shoulda/action_controller/set_the_flash_matcher_spec.rb +0 -130
- data/spec/shoulda/action_mailer/have_sent_email_spec.rb +0 -333
- data/spec/shoulda/active_model/allow_mass_assignment_of_matcher_spec.rb +0 -115
- data/spec/shoulda/active_model/allow_value_matcher_spec.rb +0 -131
- data/spec/shoulda/active_model/disallow_value_matcher_spec.rb +0 -65
- data/spec/shoulda/active_model/ensure_exclusion_of_matcher_spec.rb +0 -79
- data/spec/shoulda/active_model/ensure_inclusion_of_matcher_spec.rb +0 -181
- data/spec/shoulda/active_model/ensure_length_of_matcher_spec.rb +0 -138
- data/spec/shoulda/active_model/helpers_spec.rb +0 -129
- data/spec/shoulda/active_model/only_integer_matcher_spec.rb +0 -69
- data/spec/shoulda/active_model/validate_acceptance_of_matcher_spec.rb +0 -43
- data/spec/shoulda/active_model/validate_confirmation_of_matcher_spec.rb +0 -48
- data/spec/shoulda/active_model/validate_format_of_matcher_spec.rb +0 -79
- data/spec/shoulda/active_model/validate_numericality_of_matcher_spec.rb +0 -112
- data/spec/shoulda/active_model/validate_presence_of_matcher_spec.rb +0 -135
- data/spec/shoulda/active_model/validate_uniqueness_of_matcher_spec.rb +0 -154
- data/spec/shoulda/active_record/accept_nested_attributes_for_matcher_spec.rb +0 -84
- data/spec/shoulda/active_record/association_matcher_spec.rb +0 -642
- data/spec/shoulda/active_record/have_db_column_matcher_spec.rb +0 -185
- data/spec/shoulda/active_record/have_db_index_matcher_spec.rb +0 -105
- data/spec/shoulda/active_record/have_readonly_attributes_matcher_spec.rb +0 -46
- 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(
|
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 :
|
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
|
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
|
-
@
|
38
|
+
@failure_message_for_should_not = "#{@attribute} was made accessible"
|
39
39
|
else
|
40
40
|
if protected_attributes.empty?
|
41
|
-
@
|
41
|
+
@failure_message_for_should_not = 'no attributes were protected'
|
42
42
|
else
|
43
|
-
@
|
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
|
-
@
|
51
|
+
@failure_message_for_should = "Expected #{@attribute} to be accessible"
|
52
52
|
else
|
53
|
-
@
|
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(
|
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,
|
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
|
63
|
+
def failure_message_for_should
|
64
64
|
"Did not expect #{expectation}, got error: #{@matched_error}"
|
65
65
|
end
|
66
66
|
|
67
|
-
def
|
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
|
24
|
-
@allow_matcher.
|
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 =
|
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
|
-
@
|
91
|
+
@failure_message_for_should = "#{@array} doesn't match array in validation"
|
92
92
|
false
|
93
93
|
end
|
94
94
|
end
|
@@ -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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
24
|
+
'integer'
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
@disallow_value_matcher.
|
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(
|
43
|
-
|
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(
|
48
|
-
allows_value_of(
|
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(
|
53
|
+
allows_value_of('any value', @message)
|
54
54
|
end
|
55
55
|
|
56
56
|
def set_confirmation(val)
|
57
57
|
setter = :"#{@confirmation}="
|
58
|
-
|
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
|
-
|
48
|
+
if message
|
49
|
+
@expected_message = message
|
50
|
+
end
|
48
51
|
self
|
49
52
|
end
|
50
53
|
|
51
54
|
def with(value)
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
59
|
-
|
60
|
-
|
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
|
-
"
|
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
|
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(&:
|
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 = [
|
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
|
-
#
|
8
|
-
#
|
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}=",
|
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
|
-
@
|
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
|
-
@
|
136
|
+
@failure_message_for_should_not <<
|
139
137
|
" (with different value of #{scope})"
|
140
138
|
true
|
141
139
|
else
|
142
|
-
@
|
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 :
|
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
|
18
|
-
@
|
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
|
-
@
|
32
|
+
@failure_message_for_should_not = allow.failure_message_for_should
|
33
33
|
true
|
34
34
|
else
|
35
|
-
@
|
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
|
-
@
|
44
|
+
@failure_message_for_should = disallow.failure_message_for_should_not
|
45
45
|
false
|
46
46
|
else
|
47
|
-
@
|
47
|
+
@failure_message_for_should_not = disallow.failure_message_for_should
|
48
48
|
true
|
49
49
|
end
|
50
50
|
end
|