shoulda-matchers 2.2.0 → 2.3.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 +3 -0
- data/Gemfile.lock +1 -1
- data/NEWS.md +25 -1
- data/README.md +1 -2
- data/gemfiles/3.0.gemfile.lock +1 -1
- data/gemfiles/3.1.gemfile.lock +1 -1
- data/gemfiles/3.2.gemfile.lock +1 -1
- data/lib/shoulda/matchers/action_controller.rb +1 -0
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +81 -0
- data/lib/shoulda/matchers/active_model/comparison_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +5 -0
- data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +15 -1
- data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +2 -8
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +2 -0
- data/lib/shoulda/matchers/active_record.rb +5 -0
- data/lib/shoulda/matchers/active_record/association_matcher.rb +90 -113
- data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +35 -0
- data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +35 -0
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +37 -0
- data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +35 -0
- data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +57 -0
- data/lib/shoulda/matchers/version.rb +1 -1
- data/spec/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +63 -0
- data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +1 -1
- data/spec/shoulda/matchers/active_model/comparison_matcher_spec.rb +5 -0
- data/spec/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +18 -0
- data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +10 -0
- data/spec/shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb +3 -3
- data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +13 -0
- data/spec/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +14 -0
- data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +49 -1
- data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +39 -4
- metadata +11 -3
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
data/NEWS.md
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
# HEAD
|
2
2
|
|
3
|
+
# v 2.3.0
|
4
|
+
|
5
|
+
* Fix a bug in `ensure_inclusion_of` that would cause issues with using
|
6
|
+
`in_array` with an integer value.
|
7
|
+
|
8
|
+
* Add support for PostgreSQL UUID columns to `validates_uniqueness_of` (#334).
|
9
|
+
|
10
|
+
* Fix `validates_numericality_of` so that `is_equal_to` submatcher works
|
11
|
+
correctly (#326).
|
12
|
+
|
13
|
+
* Fix context support for validation matchers and disallowed values (#313).
|
14
|
+
|
15
|
+
* Add a `counter_cache` submatcher for `belongs_to` associations (#311).
|
16
|
+
|
17
|
+
* Add a `rescue_from` matcher for Rails controllers which checks that the
|
18
|
+
correct ActiveSupport call has been made and that the handlers exist without
|
19
|
+
actually throwing an exception (#287).
|
20
|
+
|
21
|
+
* Changed the scope of AssociationMatcher methods from protected to private.
|
22
|
+
|
23
|
+
* Extracted `#order`, `#through`, and `#dependent` from AssociationMatcher as
|
24
|
+
their own submatchers.
|
25
|
+
|
3
26
|
# v 2.2.0
|
4
27
|
|
5
28
|
* Fix `have_and_belong_to_many` matcher issue for Rails 4.
|
@@ -15,7 +38,8 @@
|
|
15
38
|
* Add missing `failure_message_for_should_not` implementations to
|
16
39
|
`validate_numericality_of` and its submatchers
|
17
40
|
|
18
|
-
* Support validation contexts for testing validations `on: :create` and when
|
41
|
+
* Support validation contexts for testing validations `on: :create` and when
|
42
|
+
using custom contexts like `model.valid?(:my_context)`.
|
19
43
|
|
20
44
|
* Fix a bug in validations with autosaved models.
|
21
45
|
|
data/README.md
CHANGED
@@ -51,8 +51,6 @@ Matchers to test common patterns:
|
|
51
51
|
|
52
52
|
```ruby
|
53
53
|
describe PostsController, "#show" do
|
54
|
-
it { should permit(:title, :body).for(:create) }
|
55
|
-
|
56
54
|
context "for a fictional user" do
|
57
55
|
before do
|
58
56
|
get :show, :id => 1
|
@@ -61,6 +59,7 @@ describe PostsController, "#show" do
|
|
61
59
|
it { should respond_with(:success) }
|
62
60
|
it { should render_template(:show) }
|
63
61
|
it { should_not set_the_flash }
|
62
|
+
it { should rescue_from(ActiveRecord::RecordNotFound).with(:render_404) }
|
64
63
|
end
|
65
64
|
end
|
66
65
|
```
|
data/gemfiles/3.0.gemfile.lock
CHANGED
data/gemfiles/3.1.gemfile.lock
CHANGED
data/gemfiles/3.2.gemfile.lock
CHANGED
@@ -6,6 +6,7 @@ require 'shoulda/matchers/action_controller/set_session_matcher'
|
|
6
6
|
require 'shoulda/matchers/action_controller/route_matcher'
|
7
7
|
require 'shoulda/matchers/action_controller/redirect_to_matcher'
|
8
8
|
require 'shoulda/matchers/action_controller/render_template_matcher'
|
9
|
+
require 'shoulda/matchers/action_controller/rescue_from_matcher'
|
9
10
|
|
10
11
|
module Shoulda
|
11
12
|
module Matchers
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActionController
|
4
|
+
def rescue_from(exception)
|
5
|
+
RescueFromMatcher.new exception
|
6
|
+
end
|
7
|
+
|
8
|
+
class RescueFromMatcher
|
9
|
+
def initialize(exception)
|
10
|
+
@exception = exception
|
11
|
+
end
|
12
|
+
|
13
|
+
def with(method)
|
14
|
+
@expected_method = method
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def matches?(controller)
|
19
|
+
@controller = controller
|
20
|
+
rescues_from_exception? && method_name_matches? && handler_exists?
|
21
|
+
end
|
22
|
+
|
23
|
+
def description
|
24
|
+
description = "rescues from #{exception}"
|
25
|
+
description << " with ##{expected_method}" if expected_method
|
26
|
+
description
|
27
|
+
end
|
28
|
+
|
29
|
+
def failure_message_for_should
|
30
|
+
"Expected #{expectation}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def failure_message_for_should_not
|
34
|
+
"Did not expect #{expectation}"
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_reader :controller, :exception, :expected_method, :handlers
|
40
|
+
|
41
|
+
def expectation
|
42
|
+
expectation = "#{controller} to rescue from #{exception}"
|
43
|
+
|
44
|
+
if expected_method && !method_name_matches?
|
45
|
+
expectation << " with ##{expected_method}"
|
46
|
+
end
|
47
|
+
|
48
|
+
unless handler_exists?
|
49
|
+
expectation << " but #{controller} does not respond to #{expected_method}"
|
50
|
+
end
|
51
|
+
expectation
|
52
|
+
end
|
53
|
+
|
54
|
+
def rescues_from_exception?
|
55
|
+
@handlers = controller.rescue_handlers.select do |handler|
|
56
|
+
handler.first == exception.to_s
|
57
|
+
end
|
58
|
+
handlers.any?
|
59
|
+
end
|
60
|
+
|
61
|
+
def method_name_matches?
|
62
|
+
if expected_method.present?
|
63
|
+
handlers.any? do |handler|
|
64
|
+
handler.last == expected_method
|
65
|
+
end
|
66
|
+
else
|
67
|
+
true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def handler_exists?
|
72
|
+
if expected_method.present?
|
73
|
+
controller.respond_to? expected_method
|
74
|
+
else
|
75
|
+
true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -23,6 +23,7 @@ module Shoulda # :nodoc:
|
|
23
23
|
|
24
24
|
class EnsureInclusionOfMatcher < ValidationMatcher # :nodoc:
|
25
25
|
ARBITRARY_OUTSIDE_STRING = 'shouldamatchersteststring'
|
26
|
+
ARBITRARY_OUTSIDE_FIXNUM = 123456789
|
26
27
|
|
27
28
|
def initialize(attribute)
|
28
29
|
super(attribute)
|
@@ -144,8 +145,21 @@ module Shoulda # :nodoc:
|
|
144
145
|
end
|
145
146
|
|
146
147
|
def value_outside_of_array
|
147
|
-
if @array.include?(
|
148
|
+
if @array.include?(outside_value)
|
148
149
|
raise CouldNotDetermineValueOutsideOfArray
|
150
|
+
else
|
151
|
+
outside_value
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def outside_value
|
156
|
+
@outside_value ||= find_outside_value
|
157
|
+
end
|
158
|
+
|
159
|
+
def find_outside_value
|
160
|
+
case @subject.send(@attribute.to_s)
|
161
|
+
when Fixnum
|
162
|
+
ARBITRARY_OUTSIDE_FIXNUM
|
149
163
|
else
|
150
164
|
ARBITRARY_OUTSIDE_STRING
|
151
165
|
end
|
@@ -122,7 +122,7 @@ module Shoulda # :nodoc:
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def failing_submatchers
|
125
|
-
@failing_submatchers ||= @submatchers.select { |matcher| !matcher.matches?(@subject
|
125
|
+
@failing_submatchers ||= @submatchers.select { |matcher| !matcher.matches?(@subject) }
|
126
126
|
end
|
127
127
|
|
128
128
|
def allowed_types
|
@@ -77,14 +77,6 @@ module Shoulda # :nodoc:
|
|
77
77
|
allows_nil?
|
78
78
|
end
|
79
79
|
|
80
|
-
def description
|
81
|
-
result = 'require '
|
82
|
-
result << 'case sensitive ' unless @options[:case_insensitive]
|
83
|
-
result << "unique value for #{@attribute}"
|
84
|
-
result << " scoped to #{@options[:scopes].join(', ')}" if @options[:scopes].present?
|
85
|
-
result
|
86
|
-
end
|
87
|
-
|
88
80
|
private
|
89
81
|
|
90
82
|
def allows_nil?
|
@@ -197,6 +189,8 @@ module Shoulda # :nodoc:
|
|
197
189
|
'0'
|
198
190
|
elsif column.type == :datetime
|
199
191
|
DateTime.now
|
192
|
+
elsif column.type == :uuid
|
193
|
+
SecureRandom.uuid
|
200
194
|
else
|
201
195
|
0
|
202
196
|
end
|
@@ -58,6 +58,7 @@ module Shoulda # :nodoc:
|
|
58
58
|
matcher = AllowValueMatcher.
|
59
59
|
new(value).
|
60
60
|
for(@attribute).
|
61
|
+
on(@context).
|
61
62
|
with_message(message)
|
62
63
|
|
63
64
|
if strict?
|
@@ -71,6 +72,7 @@ module Shoulda # :nodoc:
|
|
71
72
|
matcher = DisallowValueMatcher.
|
72
73
|
new(value).
|
73
74
|
for(@attribute).
|
75
|
+
on(@context).
|
74
76
|
with_message(message)
|
75
77
|
|
76
78
|
if strict?
|
@@ -1,4 +1,9 @@
|
|
1
1
|
require 'shoulda/matchers/active_record/association_matcher'
|
2
|
+
require 'shoulda/matchers/active_record/association_matchers/counter_cache_matcher'
|
3
|
+
require 'shoulda/matchers/active_record/association_matchers/order_matcher'
|
4
|
+
require 'shoulda/matchers/active_record/association_matchers/through_matcher'
|
5
|
+
require 'shoulda/matchers/active_record/association_matchers/dependent_matcher'
|
6
|
+
require 'shoulda/matchers/active_record/association_matchers/model_reflector'
|
2
7
|
require 'shoulda/matchers/active_record/have_db_column_matcher'
|
3
8
|
require 'shoulda/matchers/active_record/have_db_index_matcher'
|
4
9
|
require 'shoulda/matchers/active_record/have_readonly_attribute_matcher'
|
@@ -76,20 +76,31 @@ module Shoulda # :nodoc:
|
|
76
76
|
@macro = macro
|
77
77
|
@name = name
|
78
78
|
@options = {}
|
79
|
+
@submatchers = []
|
80
|
+
@missing = ''
|
79
81
|
end
|
80
82
|
|
81
83
|
def through(through)
|
82
|
-
|
84
|
+
through_matcher = AssociationMatchers::ThroughMatcher.new(through, name)
|
85
|
+
add_submatcher(through_matcher)
|
83
86
|
self
|
84
87
|
end
|
85
88
|
|
86
89
|
def dependent(dependent)
|
87
|
-
|
90
|
+
dependent_matcher = AssociationMatchers::DependentMatcher.new(dependent, name)
|
91
|
+
add_submatcher(dependent_matcher)
|
88
92
|
self
|
89
93
|
end
|
90
94
|
|
91
95
|
def order(order)
|
92
|
-
|
96
|
+
order_matcher = AssociationMatchers::OrderMatcher.new(order, name)
|
97
|
+
add_submatcher(order_matcher)
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
101
|
+
def counter_cache(counter_cache = true)
|
102
|
+
counter_cache_matcher = AssociationMatchers::CounterCacheMatcher.new(counter_cache, name)
|
103
|
+
add_submatcher(counter_cache_matcher)
|
93
104
|
self
|
94
105
|
end
|
95
106
|
|
@@ -118,51 +129,83 @@ module Shoulda # :nodoc:
|
|
118
129
|
self
|
119
130
|
end
|
120
131
|
|
132
|
+
def description
|
133
|
+
description = "#{macro_description} #{name}"
|
134
|
+
description += " class_name => #{options[:class_name]}" if options.key?(:class_name)
|
135
|
+
[description, submatchers.map(&:description)].flatten.join(' ')
|
136
|
+
end
|
137
|
+
|
138
|
+
def failure_message_for_should
|
139
|
+
"Expected #{expectation} (#{missing_options})"
|
140
|
+
end
|
141
|
+
|
142
|
+
def failure_message_for_should_not
|
143
|
+
"Did not expect #{expectation}"
|
144
|
+
end
|
145
|
+
|
121
146
|
def matches?(subject)
|
122
147
|
@subject = subject
|
123
148
|
association_exists? &&
|
124
149
|
macro_correct? &&
|
125
150
|
foreign_key_exists? &&
|
126
|
-
through_association_valid? &&
|
127
|
-
dependent_correct? &&
|
128
151
|
class_name_correct? &&
|
129
|
-
order_correct? &&
|
130
152
|
conditions_correct? &&
|
131
153
|
join_table_exists? &&
|
132
154
|
validate_correct? &&
|
133
|
-
touch_correct?
|
155
|
+
touch_correct? &&
|
156
|
+
submatchers_match?
|
134
157
|
end
|
135
158
|
|
136
|
-
|
137
|
-
|
159
|
+
private
|
160
|
+
|
161
|
+
attr_reader :submatchers, :missing, :subject, :macro, :name, :options
|
162
|
+
|
163
|
+
def add_submatcher(matcher)
|
164
|
+
@submatchers << matcher
|
138
165
|
end
|
139
166
|
|
140
|
-
def
|
141
|
-
|
167
|
+
def macro_description
|
168
|
+
case macro.to_s
|
169
|
+
when 'belongs_to'
|
170
|
+
'belong to'
|
171
|
+
when 'has_many'
|
172
|
+
'have many'
|
173
|
+
when 'has_one'
|
174
|
+
'have one'
|
175
|
+
when 'has_and_belongs_to_many'
|
176
|
+
'have and belong to many'
|
177
|
+
end
|
142
178
|
end
|
143
179
|
|
144
|
-
def
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
description
|
180
|
+
def expectation
|
181
|
+
"#{model_class.name} to have a #{macro} association called #{name}"
|
182
|
+
end
|
183
|
+
|
184
|
+
def missing_options
|
185
|
+
[missing, failing_submatchers.map(&:missing_option)].flatten.join
|
151
186
|
end
|
152
187
|
|
153
|
-
|
188
|
+
def failing_submatchers
|
189
|
+
@failing_submatchers ||= submatchers.select do |matcher|
|
190
|
+
!matcher.matches?(subject)
|
191
|
+
end
|
192
|
+
end
|
154
193
|
|
155
194
|
def association_exists?
|
156
195
|
if reflection.nil?
|
157
|
-
@missing = "no association called #{
|
196
|
+
@missing = "no association called #{name}"
|
158
197
|
false
|
159
198
|
else
|
160
199
|
true
|
161
200
|
end
|
162
201
|
end
|
163
202
|
|
203
|
+
def reflection
|
204
|
+
@reflection ||= model_class.reflect_on_association(name)
|
205
|
+
end
|
206
|
+
|
164
207
|
def macro_correct?
|
165
|
-
if reflection.macro ==
|
208
|
+
if reflection.macro == macro
|
166
209
|
true
|
167
210
|
else
|
168
211
|
@missing = "actual association type was #{reflection.macro}"
|
@@ -175,66 +218,33 @@ module Shoulda # :nodoc:
|
|
175
218
|
end
|
176
219
|
|
177
220
|
def belongs_foreign_key_missing?
|
178
|
-
|
221
|
+
macro == :belongs_to && !class_has_foreign_key?(model_class)
|
222
|
+
end
|
223
|
+
|
224
|
+
def model_class
|
225
|
+
subject.class
|
179
226
|
end
|
180
227
|
|
181
228
|
def has_foreign_key_missing?
|
182
|
-
[:has_many, :has_one].include?(
|
229
|
+
[:has_many, :has_one].include?(macro) &&
|
183
230
|
!through? &&
|
184
231
|
!class_has_foreign_key?(associated_class)
|
185
232
|
end
|
186
233
|
|
187
|
-
def
|
188
|
-
|
189
|
-
end
|
190
|
-
|
191
|
-
def through_association_exists?
|
192
|
-
if through_reflection.nil?
|
193
|
-
@missing = "#{model_class.name} does not have any relationship to #{@options[:through]}"
|
194
|
-
false
|
195
|
-
else
|
196
|
-
true
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def through_association_correct?
|
201
|
-
if @options[:through] == reflection.options[:through]
|
202
|
-
true
|
203
|
-
else
|
204
|
-
@missing = "Expected #{model_class.name} to have #{@name} through #{@options[:through]}, " +
|
205
|
-
"but got it through #{reflection.options[:through]}"
|
206
|
-
false
|
207
|
-
end
|
234
|
+
def through?
|
235
|
+
reflection.options[:through]
|
208
236
|
end
|
209
237
|
|
210
|
-
def
|
211
|
-
|
212
|
-
true
|
213
|
-
else
|
214
|
-
@missing = "#{@name} should have #{@options[:dependent]} dependency"
|
215
|
-
false
|
216
|
-
end
|
238
|
+
def associated_class
|
239
|
+
reflection.klass
|
217
240
|
end
|
218
241
|
|
219
242
|
def class_name_correct?
|
220
|
-
if
|
221
|
-
if
|
243
|
+
if options.key?(:class_name)
|
244
|
+
if options[:class_name].to_s == reflection.klass.to_s
|
222
245
|
true
|
223
246
|
else
|
224
|
-
@missing = "#{
|
225
|
-
false
|
226
|
-
end
|
227
|
-
else
|
228
|
-
true
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
def order_correct?
|
233
|
-
if @options.key?(:order)
|
234
|
-
if @options[:order].to_s == reflection.options[:order].to_s
|
235
|
-
true
|
236
|
-
else
|
237
|
-
@missing = "#{@name} should be ordered by #{@options[:order]}"
|
247
|
+
@missing = "#{name} should resolve to #{options[:class_name]} for class_name"
|
238
248
|
false
|
239
249
|
end
|
240
250
|
else
|
@@ -243,11 +253,11 @@ module Shoulda # :nodoc:
|
|
243
253
|
end
|
244
254
|
|
245
255
|
def conditions_correct?
|
246
|
-
if
|
247
|
-
if
|
256
|
+
if options.key?(:conditions)
|
257
|
+
if options[:conditions].to_s == reflection.options[:conditions].to_s
|
248
258
|
true
|
249
259
|
else
|
250
|
-
@missing = "#{
|
260
|
+
@missing = "#{name} should have the following conditions: #{options[:conditions]}"
|
251
261
|
false
|
252
262
|
end
|
253
263
|
else
|
@@ -256,7 +266,7 @@ module Shoulda # :nodoc:
|
|
256
266
|
end
|
257
267
|
|
258
268
|
def join_table_exists?
|
259
|
-
if
|
269
|
+
if macro != :has_and_belongs_to_many ||
|
260
270
|
model_class.connection.tables.include?(join_table)
|
261
271
|
true
|
262
272
|
else
|
@@ -269,7 +279,7 @@ module Shoulda # :nodoc:
|
|
269
279
|
if option_correct?(:validate)
|
270
280
|
true
|
271
281
|
else
|
272
|
-
@missing = "#{
|
282
|
+
@missing = "#{name} should have :validate => #{options[:validate]}"
|
273
283
|
false
|
274
284
|
end
|
275
285
|
end
|
@@ -278,22 +288,22 @@ module Shoulda # :nodoc:
|
|
278
288
|
if option_correct?(:touch)
|
279
289
|
true
|
280
290
|
else
|
281
|
-
@missing = "#{
|
291
|
+
@missing = "#{name} should have :touch => #{options[:touch]}"
|
282
292
|
false
|
283
293
|
end
|
284
294
|
end
|
285
295
|
|
286
296
|
def option_correct?(key)
|
287
|
-
|
297
|
+
!options.key?(key) || reflection_set_properly_for?(key)
|
288
298
|
end
|
289
299
|
|
290
300
|
def reflection_set_properly_for?(key)
|
291
|
-
|
301
|
+
options[key] == !!reflection.options[key]
|
292
302
|
end
|
293
303
|
|
294
304
|
def class_has_foreign_key?(klass)
|
295
|
-
if
|
296
|
-
reflection.options[:foreign_key] ==
|
305
|
+
if options.key?(:foreign_key)
|
306
|
+
reflection.options[:foreign_key] == options[:foreign_key]
|
297
307
|
else
|
298
308
|
if klass.column_names.include?(foreign_key)
|
299
309
|
true
|
@@ -304,10 +314,6 @@ module Shoulda # :nodoc:
|
|
304
314
|
end
|
305
315
|
end
|
306
316
|
|
307
|
-
def model_class
|
308
|
-
@subject.class
|
309
|
-
end
|
310
|
-
|
311
317
|
def join_table
|
312
318
|
if reflection.respond_to? :join_table
|
313
319
|
reflection.join_table.to_s
|
@@ -316,10 +322,6 @@ module Shoulda # :nodoc:
|
|
316
322
|
end
|
317
323
|
end
|
318
324
|
|
319
|
-
def associated_class
|
320
|
-
reflection.klass
|
321
|
-
end
|
322
|
-
|
323
325
|
def foreign_key
|
324
326
|
if foreign_key_reflection
|
325
327
|
if foreign_key_reflection.respond_to?(:foreign_key)
|
@@ -330,41 +332,16 @@ module Shoulda # :nodoc:
|
|
330
332
|
end
|
331
333
|
end
|
332
334
|
|
333
|
-
def through?
|
334
|
-
reflection.options[:through]
|
335
|
-
end
|
336
|
-
|
337
|
-
def reflection
|
338
|
-
@reflection ||= model_class.reflect_on_association(@name)
|
339
|
-
end
|
340
|
-
|
341
335
|
def foreign_key_reflection
|
342
|
-
if [:has_one, :has_many].include?(
|
336
|
+
if [:has_one, :has_many].include?(macro) && reflection.options.include?(:inverse_of)
|
343
337
|
associated_class.reflect_on_association(reflection.options[:inverse_of])
|
344
338
|
else
|
345
339
|
reflection
|
346
340
|
end
|
347
341
|
end
|
348
342
|
|
349
|
-
def
|
350
|
-
|
351
|
-
end
|
352
|
-
|
353
|
-
def expectation
|
354
|
-
"#{model_class.name} to have a #{@macro} association called #{@name}"
|
355
|
-
end
|
356
|
-
|
357
|
-
def macro_description
|
358
|
-
case @macro.to_s
|
359
|
-
when 'belongs_to'
|
360
|
-
'belong to'
|
361
|
-
when 'has_many'
|
362
|
-
'have many'
|
363
|
-
when 'has_one'
|
364
|
-
'have one'
|
365
|
-
when 'has_and_belongs_to_many'
|
366
|
-
'have and belong to many'
|
367
|
-
end
|
343
|
+
def submatchers_match?
|
344
|
+
failing_submatchers.empty?
|
368
345
|
end
|
369
346
|
end
|
370
347
|
end
|