shoulda-matchers 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.travis.yml +9 -15
- data/Appraisals +10 -8
- data/Gemfile.lock +1 -1
- data/NEWS.md +62 -32
- data/gemfiles/3.0.gemfile.lock +2 -2
- data/gemfiles/3.1.gemfile.lock +2 -2
- data/gemfiles/3.2.gemfile +1 -1
- data/gemfiles/3.2.gemfile.lock +3 -3
- data/lib/shoulda/matchers/active_model.rb +1 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +7 -2
- data/lib/shoulda/matchers/active_model/ensure_exclusion_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb +2 -0
- data/lib/shoulda/matchers/active_model/exception_message_finder.rb +3 -2
- data/lib/shoulda/matchers/active_model/helpers.rb +5 -2
- data/lib/shoulda/matchers/active_model/odd_even_number_matcher.rb +47 -0
- data/lib/shoulda/matchers/active_model/only_integer_matcher.rb +4 -0
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +26 -3
- data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +68 -16
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +5 -0
- data/lib/shoulda/matchers/active_model/validation_message_finder.rb +3 -2
- data/lib/shoulda/matchers/active_record/association_matcher.rb +29 -4
- data/lib/shoulda/matchers/version.rb +1 -1
- data/shoulda-matchers.gemspec +1 -0
- data/spec/shoulda/active_model/validate_uniqueness_of_matcher_spec.rb +195 -0
- data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +18 -0
- data/spec/shoulda/matchers/active_model/ensure_exclusion_of_matcher_spec.rb +21 -0
- data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +23 -0
- data/spec/shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb +46 -0
- data/spec/shoulda/matchers/active_model/odd_even_number_matcher_spec.rb +93 -0
- data/spec/shoulda/matchers/active_model/only_integer_matcher_spec.rb +4 -4
- data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +60 -0
- data/spec/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +16 -0
- data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +45 -8
- data/spec/shoulda/matchers/active_model/validation_message_finder_spec.rb +13 -0
- data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +50 -2
- data/spec/support/i18n_faker.rb +10 -0
- metadata +10 -3
@@ -56,6 +56,24 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
context "an attribute with a context-dependent validation" do
|
60
|
+
context "without the validation context" do
|
61
|
+
it "allows a bad value" do
|
62
|
+
validating_format(:with => /abc/, :on => :customisable).should allow_value("xyz").for(:attr)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "with the validation context" do
|
67
|
+
it "allows a good value" do
|
68
|
+
validating_format(:with => /abc/, :on => :customisable).should allow_value("abcde").for(:attr).on(:customisable)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "rejects a bad value" do
|
72
|
+
validating_format(:with => /abc/, :on => :customisable).should_not allow_value("xyz").for(:attr).on(:customisable)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
59
77
|
context 'an attribute with several validations' do
|
60
78
|
let(:model) do
|
61
79
|
define_model :example, :attr => :string do
|
@@ -18,6 +18,18 @@ describe Shoulda::Matchers::ActiveModel::EnsureExclusionOfMatcher do
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
context 'an attribute which must be excluded from a range with excluded end' do
|
22
|
+
it 'accepts ensuring the correct range' do
|
23
|
+
validating_exclusion(:in => 2...5).
|
24
|
+
should ensure_exclusion_of(:attr).in_range(2...5)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'rejects ensuring excluded value' do
|
28
|
+
validating_exclusion(:in => 2...5).
|
29
|
+
should_not ensure_exclusion_of(:attr).in_range(2...4)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
21
33
|
context 'an attribute with a custom validation message' do
|
22
34
|
it 'accepts ensuring the correct range' do
|
23
35
|
validating_exclusion(:in => 2..4, :message => 'not good').
|
@@ -35,6 +47,15 @@ describe Shoulda::Matchers::ActiveModel::EnsureExclusionOfMatcher do
|
|
35
47
|
|
36
48
|
model.should ensure_exclusion_of(:attr).in_range(2..5).
|
37
49
|
with_message(/should be out of this range/)
|
50
|
+
|
51
|
+
model = custom_validation do
|
52
|
+
if attr >= 2 && attr <= 4
|
53
|
+
errors.add(:attr, 'should be out of this range')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
model.should ensure_exclusion_of(:attr).in_range(2...5).
|
58
|
+
with_message(/should be out of this range/)
|
38
59
|
end
|
39
60
|
end
|
40
61
|
|
@@ -56,6 +56,18 @@ describe Shoulda::Matchers::ActiveModel::EnsureInclusionOfMatcher do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
context 'an attribute which must be included in a range with excluded end' do
|
60
|
+
it 'accepts ensuring the correct range' do
|
61
|
+
validating_inclusion(:in => 2...5).
|
62
|
+
should ensure_inclusion_of(:attr).in_range(2...5)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'rejects ensuring a lower maximum value' do
|
66
|
+
validating_inclusion(:in => 2...5).
|
67
|
+
should_not ensure_inclusion_of(:attr).in_range(2...4)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
59
71
|
context 'an attribute with a custom ranged value validation' do
|
60
72
|
it 'accepts ensuring the correct range' do
|
61
73
|
validating_inclusion(:in => 2..4, :message => 'not good').
|
@@ -75,6 +87,17 @@ describe Shoulda::Matchers::ActiveModel::EnsureInclusionOfMatcher do
|
|
75
87
|
|
76
88
|
model.should ensure_inclusion_of(:attr).in_range(2..5).
|
77
89
|
with_low_message(/low/).with_high_message(/high/)
|
90
|
+
|
91
|
+
model = custom_validation do
|
92
|
+
if attr < 2
|
93
|
+
errors.add(:attr, 'too low')
|
94
|
+
elsif attr > 4
|
95
|
+
errors.add(:attr, 'too high')
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
model.should ensure_inclusion_of(:attr).in_range(2...5).
|
100
|
+
with_low_message(/low/).with_high_message(/high/)
|
78
101
|
end
|
79
102
|
end
|
80
103
|
|
@@ -105,6 +105,52 @@ describe Shoulda::Matchers::ActiveModel::EnsureLengthOfMatcher do
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
+
context 'using translations' do
|
109
|
+
after { I18n.backend.reload! }
|
110
|
+
|
111
|
+
context "a too_long translation containing %{attribute}, %{model}" do
|
112
|
+
before do
|
113
|
+
stub_translation(
|
114
|
+
"activerecord.errors.messages.too_long",
|
115
|
+
"The %{attribute} of your %{model} is too long (maximum is %{count} characters)")
|
116
|
+
end
|
117
|
+
|
118
|
+
it "does not raise an exception" do
|
119
|
+
expect {
|
120
|
+
validating_length(:maximum => 4).should ensure_length_of(:attr).is_at_most(4)
|
121
|
+
}.to_not raise_exception(I18n::MissingInterpolationArgument)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "a too_short translation containing %{attribute}, %{model}" do
|
126
|
+
before do
|
127
|
+
stub_translation(
|
128
|
+
"activerecord.errors.messages.too_short",
|
129
|
+
"The %{attribute} of your %{model} is too short (minimum is %{count} characters)")
|
130
|
+
end
|
131
|
+
|
132
|
+
it "does not raise an exception" do
|
133
|
+
expect {
|
134
|
+
validating_length(:minimum => 4).should ensure_length_of(:attr).is_at_least(4)
|
135
|
+
}.to_not raise_exception(I18n::MissingInterpolationArgument)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "a wrong_length translation containing %{attribute}, %{model}" do
|
140
|
+
before do
|
141
|
+
stub_translation(
|
142
|
+
"activerecord.errors.messages.wrong_length",
|
143
|
+
"The %{attribute} of your %{model} is the wrong length (should be %{count} characters)")
|
144
|
+
end
|
145
|
+
|
146
|
+
it "does not raise an exception" do
|
147
|
+
expect {
|
148
|
+
validating_length(:is => 4).should ensure_length_of(:attr).is_equal_to(4)
|
149
|
+
}.to_not raise_exception(I18n::MissingInterpolationArgument)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
108
154
|
def validating_length(options = {})
|
109
155
|
define_model(:example, :attr => :string) do
|
110
156
|
validates_length_of :attr, options
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Shoulda::Matchers::ActiveModel::OddEvenNumberMatcher do
|
4
|
+
context 'given an attribute that only allows odd number values' do
|
5
|
+
it 'matches' do
|
6
|
+
validating_odd_number.should new_odd_matcher
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'returns itself when given a message' do
|
10
|
+
matcher = new_odd_matcher
|
11
|
+
matcher.with_message('some message').should == matcher
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'given an attribute that only allows even number values' do
|
16
|
+
it 'matches' do
|
17
|
+
validating_even_number.should new_even_matcher
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns itself when given a message' do
|
21
|
+
matcher = new_even_matcher
|
22
|
+
matcher.with_message('some message').should == matcher
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'given an attribute that only allows odd number values with a custom validation message' do
|
27
|
+
it 'only accepts odd number values for that attribute with that message' do
|
28
|
+
validating_odd_number(:message => 'custom').should new_odd_matcher.with_message(/custom/)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'rejects odd number values for that attribute with another message' do
|
32
|
+
validating_odd_number(:message => 'custom').should_not new_odd_matcher.with_message(/wrong/)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'given an attribute that only allows even number values with a custom validation message' do
|
37
|
+
it 'only accepts even number values for that attribute with that message' do
|
38
|
+
validating_even_number(:message => 'custom').should new_even_matcher.with_message(/custom/)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'rejects even number values for that attribute with another message' do
|
42
|
+
validating_even_number(:message => 'custom').should_not new_even_matcher.with_message(/wrong/)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when the model does not have an odd validation' do
|
47
|
+
it 'does not match' do
|
48
|
+
define_model(:example, :attr => :string).new.should_not new_odd_matcher
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'fails with the ActiveRecord :odd message' do
|
52
|
+
matcher = new_odd_matcher
|
53
|
+
|
54
|
+
matcher.matches?(define_model(:example, :attr => :string).new)
|
55
|
+
|
56
|
+
matcher.failure_message_for_should.should include 'Expected errors to include "must be odd"'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when the model does not have an even validation' do
|
61
|
+
it 'does not match' do
|
62
|
+
define_model(:example, :attr => :string).new.should_not new_even_matcher
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'fails with the ActiveRecord :even message' do
|
66
|
+
matcher = new_even_matcher
|
67
|
+
|
68
|
+
matcher.matches?(define_model(:example, :attr => :string).new)
|
69
|
+
|
70
|
+
matcher.failure_message_for_should.should include 'Expected errors to include "must be even"'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def new_odd_matcher
|
75
|
+
described_class.new(:attr, :odd => true)
|
76
|
+
end
|
77
|
+
|
78
|
+
def new_even_matcher
|
79
|
+
described_class.new(:attr, :even => true)
|
80
|
+
end
|
81
|
+
|
82
|
+
def validating_odd_number(options = {})
|
83
|
+
define_model :example, :attr => :string do
|
84
|
+
validates_numericality_of :attr, { :odd => true }.merge(options)
|
85
|
+
end.new
|
86
|
+
end
|
87
|
+
|
88
|
+
def validating_even_number(options = {})
|
89
|
+
define_model :example, :attr => :string do
|
90
|
+
validates_numericality_of :attr, { :even => true }.merge(options)
|
91
|
+
end.new
|
92
|
+
end
|
93
|
+
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Shoulda::Matchers::ActiveModel::OnlyIntegerMatcher do
|
4
4
|
context 'given an attribute that only allows integer values' do
|
5
5
|
it 'matches' do
|
6
|
-
|
6
|
+
validating_only_integer.should new_matcher
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'allows integer types' do
|
@@ -18,11 +18,11 @@ describe Shoulda::Matchers::ActiveModel::OnlyIntegerMatcher do
|
|
18
18
|
|
19
19
|
context 'given an attribute that only allows integer values with a custom validation message' do
|
20
20
|
it 'only accepts integer values for that attribute with that message' do
|
21
|
-
|
21
|
+
validating_only_integer(:message => 'custom').should new_matcher.with_message(/custom/)
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'rejects integer values for that attribute with another message' do
|
25
|
-
|
25
|
+
validating_only_integer(:message => 'custom').should_not new_matcher.with_message(/wrong/)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -44,7 +44,7 @@ describe Shoulda::Matchers::ActiveModel::OnlyIntegerMatcher do
|
|
44
44
|
described_class.new(:attr)
|
45
45
|
end
|
46
46
|
|
47
|
-
def
|
47
|
+
def validating_only_integer(options = {})
|
48
48
|
define_model :example, :attr => :string do
|
49
49
|
validates_numericality_of :attr, { :only_integer => true }.merge(options)
|
50
50
|
end.new
|
@@ -22,6 +22,14 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|
22
22
|
define_model(:example, :attr => :string).new.should_not matcher
|
23
23
|
end
|
24
24
|
|
25
|
+
it 'rejects with the ActiveRecord :not_a_number message' do
|
26
|
+
the_matcher = matcher
|
27
|
+
|
28
|
+
the_matcher.matches?(define_model(:example, :attr => :string).new)
|
29
|
+
|
30
|
+
the_matcher.failure_message_for_should_not.should include 'Did not expect errors to include "is not a number"'
|
31
|
+
end
|
32
|
+
|
25
33
|
it 'rejects with the ActiveRecord :not_an_integer message' do
|
26
34
|
the_matcher = matcher.only_integer
|
27
35
|
|
@@ -29,6 +37,22 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|
29
37
|
|
30
38
|
the_matcher.failure_message_for_should.should include 'Expected errors to include "must be an integer"'
|
31
39
|
end
|
40
|
+
|
41
|
+
it 'rejects with the ActiveRecord :odd message' do
|
42
|
+
the_matcher = matcher.odd
|
43
|
+
|
44
|
+
the_matcher.matches?(define_model(:example, :attr => :string).new)
|
45
|
+
|
46
|
+
the_matcher.failure_message_for_should.should include 'Expected errors to include "must be odd"'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'rejects with the ActiveRecord :even message' do
|
50
|
+
the_matcher = matcher.even
|
51
|
+
|
52
|
+
the_matcher.matches?(define_model(:example, :attr => :string).new)
|
53
|
+
|
54
|
+
the_matcher.failure_message_for_should.should include 'Expected errors to include "must be even"'
|
55
|
+
end
|
32
56
|
end
|
33
57
|
|
34
58
|
context 'with the only_integer option' do
|
@@ -49,6 +73,42 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|
49
73
|
end
|
50
74
|
end
|
51
75
|
|
76
|
+
context 'with the odd option' do
|
77
|
+
it 'allows odd number values for that attribute' do
|
78
|
+
validating_numericality(:odd => true).should matcher.odd
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'rejects when the model does not enforce odd number values' do
|
82
|
+
validating_numericality.should_not matcher.odd
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'rejects with the ActiveRecord :odd message' do
|
86
|
+
the_matcher = matcher.odd
|
87
|
+
|
88
|
+
the_matcher.matches?(validating_numericality)
|
89
|
+
|
90
|
+
the_matcher.failure_message_for_should.should include 'Expected errors to include "must be odd"'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'with the even option' do
|
95
|
+
it 'allows even number values for that attribute' do
|
96
|
+
validating_numericality(:even => true).should matcher.even
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'rejects when the model does not enforce even number values' do
|
100
|
+
validating_numericality.should_not matcher.even
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'rejects with the ActiveRecord :even message' do
|
104
|
+
the_matcher = matcher.even
|
105
|
+
|
106
|
+
the_matcher.matches?(validating_numericality)
|
107
|
+
|
108
|
+
the_matcher.failure_message_for_should.should include 'Expected errors to include "must be even"'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
52
112
|
context 'with a custom validation message' do
|
53
113
|
it 'accepts when the messages match' do
|
54
114
|
validating_numericality(:message => 'custom').
|
@@ -82,6 +82,22 @@ describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher do
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
+
context "an i18n translation containing %{attribute} and %{model}" do
|
86
|
+
before do
|
87
|
+
stub_translation(
|
88
|
+
"activerecord.errors.messages.blank",
|
89
|
+
"Please enter a %{attribute} for your %{model}")
|
90
|
+
end
|
91
|
+
|
92
|
+
after { I18n.backend.reload! }
|
93
|
+
|
94
|
+
it "does not raise an exception" do
|
95
|
+
expect {
|
96
|
+
validating_presence.should validate_presence_of(:attr)
|
97
|
+
}.to_not raise_exception
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
85
101
|
if active_model_3_2?
|
86
102
|
context 'a strictly required attribute' do
|
87
103
|
it 'accepts when the :strict options match' do
|
@@ -112,21 +112,58 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
112
112
|
should_not matcher.scoped_to(:fake)
|
113
113
|
end
|
114
114
|
|
115
|
-
|
116
|
-
|
115
|
+
context 'when the scoped attribute is a date' do
|
116
|
+
it "accepts" do
|
117
|
+
validating_scoped_uniqueness([:scope1], :date, :scope1 => Date.today).
|
118
|
+
should matcher.scoped_to(:scope1)
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'when too narrow of a scope is specified' do
|
122
|
+
it 'rejects' do
|
123
|
+
validating_scoped_uniqueness([:scope1, :scope2], :date, :scope1 => Date.today, :scope2 => Date.today).
|
124
|
+
should_not matcher.scoped_to(:scope1, :scope2, :other)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'when the scoped attribute is a datetime' do
|
130
|
+
it 'accepts' do
|
131
|
+
validating_scoped_uniqueness([:scope1], :datetime, :scope1 => DateTime.now).
|
132
|
+
should matcher.scoped_to(:scope1)
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'with a nil value' do
|
136
|
+
it 'accepts' do
|
137
|
+
validating_scoped_uniqueness([:scope1], :datetime, :scope1 => nil).
|
138
|
+
should matcher.scoped_to(:scope1)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'when too narrow of a scope is specified' do
|
143
|
+
it 'rejects' do
|
144
|
+
validating_scoped_uniqueness([:scope1, :scope2], :datetime, :scope1 => DateTime.now, :scope2 => DateTime.now).
|
145
|
+
should_not matcher.scoped_to(:scope1, :scope2, :other)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def create_existing_record(attributes = {})
|
151
|
+
default_attributes = {:attr => 'value', :scope1 => 1, :scope2 => 2, :other => 3}
|
152
|
+
@existing ||= Example.create!(default_attributes.merge(attributes))
|
117
153
|
end
|
118
154
|
|
119
|
-
def define_scoped_model(scope)
|
120
|
-
define_model(:example, :attr => :string, :scope1 =>
|
121
|
-
|
155
|
+
def define_scoped_model(scope, scope_attr_type = :integer)
|
156
|
+
define_model(:example, :attr => :string, :scope1 => scope_attr_type,
|
157
|
+
:scope2 => scope_attr_type, :other => :integer) do
|
122
158
|
attr_accessible :attr, :scope1, :scope2, :other
|
123
159
|
validates_uniqueness_of :attr, :scope => scope
|
124
160
|
end
|
125
161
|
end
|
126
162
|
|
127
|
-
def validating_scoped_uniqueness(
|
128
|
-
|
129
|
-
|
163
|
+
def validating_scoped_uniqueness(*args)
|
164
|
+
attributes = args.extract_options!
|
165
|
+
model = define_scoped_model(*args).new
|
166
|
+
create_existing_record(attributes)
|
130
167
|
model
|
131
168
|
end
|
132
169
|
end
|
@@ -70,6 +70,19 @@ describe Shoulda::Matchers::ActiveModel::ValidationMessageFinder do
|
|
70
70
|
|
71
71
|
description.should == 'no errors'
|
72
72
|
end
|
73
|
+
|
74
|
+
it 'should not fetch attribute values for errors that were copied from an autosaved belongs_to association' do
|
75
|
+
instance = define_model(:example) do
|
76
|
+
validate do |record|
|
77
|
+
record.errors.add('association.association_attribute', 'is invalid')
|
78
|
+
end
|
79
|
+
end.new
|
80
|
+
finder = Shoulda::Matchers::ActiveModel::ValidationMessageFinder.new(instance, :attribute)
|
81
|
+
|
82
|
+
expected_messages = ['association.association_attribute is invalid']
|
83
|
+
finder.messages_description.should == "errors: #{expected_messages}"
|
84
|
+
end
|
85
|
+
|
73
86
|
end
|
74
87
|
|
75
88
|
context '#source_description' do
|