shoulda-matchers 4.4.1 → 4.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +22 -0
- data/README.md +7 -9
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +4 -2
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +3 -2
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +26 -21
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +6 -8
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +6 -8
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +16 -13
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +2 -1
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +5 -6
- data/lib/shoulda/matchers/action_controller/route_params.rb +1 -1
- data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +19 -13
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +18 -16
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +29 -27
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +1 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +5 -5
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +2 -2
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +1 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +1 -1
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +51 -25
- data/lib/shoulda/matchers/active_model/helpers.rb +1 -1
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +32 -34
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +9 -1
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +8 -7
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +26 -25
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +6 -6
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +39 -26
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +6 -6
- data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +2 -4
- data/lib/shoulda/matchers/active_model/validation_message_finder.rb +2 -4
- data/lib/shoulda/matchers/active_model/validator.rb +3 -3
- data/lib/shoulda/matchers/active_record.rb +26 -26
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +6 -3
- data/lib/shoulda/matchers/active_record/association_matcher.rb +80 -40
- data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +5 -2
- data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +4 -4
- data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +11 -6
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +2 -9
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +12 -7
- data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +23 -5
- data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +3 -2
- data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +7 -5
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +8 -8
- data/lib/shoulda/matchers/active_record/have_attached_matcher.rb +46 -8
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +39 -17
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +7 -7
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +12 -10
- data/lib/shoulda/matchers/active_record/have_rich_text_matcher.rb +11 -7
- data/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +2 -0
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +13 -9
- data/lib/shoulda/matchers/active_record/uniqueness.rb +1 -1
- data/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +1 -3
- data/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +0 -2
- data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +78 -71
- data/lib/shoulda/matchers/doublespeak.rb +2 -1
- data/lib/shoulda/matchers/doublespeak/double.rb +1 -1
- data/lib/shoulda/matchers/doublespeak/double_collection.rb +3 -3
- data/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +8 -5
- data/lib/shoulda/matchers/doublespeak/object_double.rb +1 -1
- data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +1 -5
- data/lib/shoulda/matchers/doublespeak/world.rb +2 -2
- data/lib/shoulda/matchers/error.rb +1 -1
- data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +14 -13
- data/lib/shoulda/matchers/integrations/configuration.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/rails.rb +2 -2
- data/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +1 -1
- data/lib/shoulda/matchers/rails_shim.rb +5 -3
- data/lib/shoulda/matchers/util.rb +7 -2
- data/lib/shoulda/matchers/util/word_wrap.rb +7 -7
- data/lib/shoulda/matchers/version.rb +1 -1
- data/lib/shoulda/matchers/warn.rb +3 -3
- data/shoulda-matchers.gemspec +10 -7
- metadata +11 -10
@@ -260,11 +260,11 @@ validation for you? Instead of using `validate_presence_of`, try
|
|
260
260
|
|
261
261
|
def reason_for_existing_presence_validation
|
262
262
|
if belongs_to_association_configured_to_be_required?
|
263
|
-
"you've instructed your `belongs_to` association to add a "
|
263
|
+
"you've instructed your `belongs_to` association to add a "\
|
264
264
|
'presence validation to the attribute'
|
265
265
|
else
|
266
266
|
# assume ::ActiveRecord::Base.belongs_to_required_by_default == true
|
267
|
-
'ActiveRecord is configured to add a presence validation to all '
|
267
|
+
'ActiveRecord is configured to add a presence validation to all '\
|
268
268
|
'`belongs_to` associations, and this includes yours'
|
269
269
|
end
|
270
270
|
end
|
@@ -67,7 +67,7 @@ module Shoulda
|
|
67
67
|
message << "\n"
|
68
68
|
message << Shoulda::Matchers.word_wrap(
|
69
69
|
failure_reason,
|
70
|
-
indent: 2
|
70
|
+
indent: 2,
|
71
71
|
)
|
72
72
|
end
|
73
73
|
end
|
@@ -79,7 +79,7 @@ module Shoulda
|
|
79
79
|
message << "\n"
|
80
80
|
message << Shoulda::Matchers.word_wrap(
|
81
81
|
failure_reason,
|
82
|
-
indent: 2
|
82
|
+
indent: 2,
|
83
83
|
)
|
84
84
|
end
|
85
85
|
end
|
@@ -137,15 +137,15 @@ module Shoulda
|
|
137
137
|
|
138
138
|
def overall_failure_message
|
139
139
|
Shoulda::Matchers.word_wrap(
|
140
|
-
"Expected #{model.name} to #{description}, but this could not be "
|
141
|
-
'proved.'
|
140
|
+
"Expected #{model.name} to #{description}, but this could not be "\
|
141
|
+
'proved.',
|
142
142
|
)
|
143
143
|
end
|
144
144
|
|
145
145
|
def overall_failure_message_when_negated
|
146
146
|
Shoulda::Matchers.word_wrap(
|
147
|
-
"Expected #{model.name} not to #{description}, but this could "
|
148
|
-
'not be proved.'
|
147
|
+
"Expected #{model.name} not to #{description}, but this could "\
|
148
|
+
'not be proved.',
|
149
149
|
)
|
150
150
|
end
|
151
151
|
|
@@ -15,10 +15,8 @@ module Shoulda
|
|
15
15
|
|
16
16
|
def call
|
17
17
|
if description_clauses_for_qualifiers.any?
|
18
|
-
main_description
|
19
|
-
|
20
|
-
', ' +
|
21
|
-
description_clauses_for_qualifiers.to_sentence
|
18
|
+
"#{main_description}#{clause_for_allow_blank_or_nil},"\
|
19
|
+
" #{description_clauses_for_qualifiers.to_sentence}"
|
22
20
|
else
|
23
21
|
main_description + clause_for_allow_blank_or_nil
|
24
22
|
end
|
@@ -5,7 +5,7 @@ module Shoulda
|
|
5
5
|
class ValidationMessageFinder
|
6
6
|
include Helpers
|
7
7
|
|
8
|
-
def initialize(instance, attribute, context=nil)
|
8
|
+
def initialize(instance, attribute, context = nil)
|
9
9
|
@instance = instance
|
10
10
|
@attribute = attribute
|
11
11
|
@context = context
|
@@ -50,7 +50,7 @@ module Shoulda
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def validated_instance
|
53
|
-
@
|
53
|
+
@_validated_instance ||= validate_instance
|
54
54
|
end
|
55
55
|
|
56
56
|
def validate_instance
|
@@ -58,8 +58,6 @@ module Shoulda
|
|
58
58
|
@instance
|
59
59
|
end
|
60
60
|
end
|
61
|
-
|
62
61
|
end
|
63
62
|
end
|
64
63
|
end
|
65
|
-
|
@@ -108,14 +108,14 @@ module Shoulda
|
|
108
108
|
{
|
109
109
|
all_validation_errors: all_validation_errors,
|
110
110
|
validation_error_messages: validation_error_messages,
|
111
|
-
validation_exception_message: nil
|
111
|
+
validation_exception_message: nil,
|
112
112
|
}
|
113
|
-
rescue ::ActiveModel::StrictValidationFailed =>
|
113
|
+
rescue ::ActiveModel::StrictValidationFailed => e
|
114
114
|
@captured_validation_exception = true
|
115
115
|
{
|
116
116
|
all_validation_errors: nil,
|
117
117
|
validation_error_messages: [],
|
118
|
-
validation_exception_message:
|
118
|
+
validation_exception_message: e.message,
|
119
119
|
}
|
120
120
|
end
|
121
121
|
end
|
@@ -1,29 +1,29 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
23
|
-
require
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
1
|
+
require 'shoulda/matchers/active_record/association_matcher'
|
2
|
+
require 'shoulda/matchers/active_record/association_matchers'
|
3
|
+
require 'shoulda/matchers/active_record/association_matchers/counter_cache_matcher'
|
4
|
+
require 'shoulda/matchers/active_record/association_matchers/inverse_of_matcher'
|
5
|
+
require 'shoulda/matchers/active_record/association_matchers/join_table_matcher'
|
6
|
+
require 'shoulda/matchers/active_record/association_matchers/order_matcher'
|
7
|
+
require 'shoulda/matchers/active_record/association_matchers/through_matcher'
|
8
|
+
require 'shoulda/matchers/active_record/association_matchers/dependent_matcher'
|
9
|
+
require 'shoulda/matchers/active_record/association_matchers/required_matcher'
|
10
|
+
require 'shoulda/matchers/active_record/association_matchers/optional_matcher'
|
11
|
+
require 'shoulda/matchers/active_record/association_matchers/source_matcher'
|
12
|
+
require 'shoulda/matchers/active_record/association_matchers/model_reflector'
|
13
|
+
require 'shoulda/matchers/active_record/association_matchers/model_reflection'
|
14
|
+
require 'shoulda/matchers/active_record/association_matchers/option_verifier'
|
15
|
+
require 'shoulda/matchers/active_record/have_db_column_matcher'
|
16
|
+
require 'shoulda/matchers/active_record/have_db_index_matcher'
|
17
|
+
require 'shoulda/matchers/active_record/have_implicit_order_column'
|
18
|
+
require 'shoulda/matchers/active_record/have_readonly_attribute_matcher'
|
19
|
+
require 'shoulda/matchers/active_record/have_rich_text_matcher'
|
20
|
+
require 'shoulda/matchers/active_record/have_secure_token_matcher'
|
21
|
+
require 'shoulda/matchers/active_record/serialize_matcher'
|
22
|
+
require 'shoulda/matchers/active_record/accept_nested_attributes_for_matcher'
|
23
|
+
require 'shoulda/matchers/active_record/define_enum_for_matcher'
|
24
|
+
require 'shoulda/matchers/active_record/uniqueness'
|
25
|
+
require 'shoulda/matchers/active_record/validate_uniqueness_of_matcher'
|
26
|
+
require 'shoulda/matchers/active_record/have_attached_matcher'
|
27
27
|
|
28
28
|
module Shoulda
|
29
29
|
module Matchers
|
@@ -158,17 +158,20 @@ module Shoulda
|
|
158
158
|
end
|
159
159
|
|
160
160
|
def allow_destroy_correct?
|
161
|
-
failure_message = "#{should_or_should_not(@options[:allow_destroy])}
|
161
|
+
failure_message = "#{should_or_should_not(@options[:allow_destroy])}"\
|
162
|
+
' allow destroy'
|
162
163
|
verify_option_is_correct(:allow_destroy, failure_message)
|
163
164
|
end
|
164
165
|
|
165
166
|
def limit_correct?
|
166
|
-
failure_message = "limit should be #{@options[:limit]},
|
167
|
+
failure_message = "limit should be #{@options[:limit]},"\
|
168
|
+
" got #{config[:limit]}"
|
167
169
|
verify_option_is_correct(:limit, failure_message)
|
168
170
|
end
|
169
171
|
|
170
172
|
def update_only_correct?
|
171
|
-
failure_message = "#{should_or_should_not(@options[:update_only])}
|
173
|
+
failure_message = "#{should_or_should_not(@options[:update_only])}"\
|
174
|
+
' be update only'
|
172
175
|
verify_option_is_correct(:update_only, failure_message)
|
173
176
|
end
|
174
177
|
|
@@ -985,6 +985,13 @@ module Shoulda
|
|
985
985
|
|
986
986
|
# @private
|
987
987
|
class AssociationMatcher
|
988
|
+
MACROS = {
|
989
|
+
'belongs_to' => 'belong to',
|
990
|
+
'has_many' => 'have many',
|
991
|
+
'has_one' => 'have one',
|
992
|
+
'has_and_belongs_to_many' => 'have and belong to many',
|
993
|
+
}.freeze
|
994
|
+
|
988
995
|
delegate :reflection, :model_class, :associated_class, :through?,
|
989
996
|
:polymorphic?, to: :reflector
|
990
997
|
|
@@ -1128,7 +1135,9 @@ module Shoulda
|
|
1128
1135
|
|
1129
1136
|
def description
|
1130
1137
|
description = "#{macro_description} #{name}"
|
1131
|
-
|
1138
|
+
if options.key?(:class_name)
|
1139
|
+
description += " class_name => #{options[:class_name]}"
|
1140
|
+
end
|
1132
1141
|
[description, submatchers.map(&:description)].flatten.join(' ')
|
1133
1142
|
end
|
1134
1143
|
|
@@ -1163,7 +1172,8 @@ module Shoulda
|
|
1163
1172
|
end
|
1164
1173
|
|
1165
1174
|
def option_verifier
|
1166
|
-
@
|
1175
|
+
@_option_verifier ||=
|
1176
|
+
AssociationMatchers::OptionVerifier.new(reflector)
|
1167
1177
|
end
|
1168
1178
|
|
1169
1179
|
protected
|
@@ -1171,7 +1181,7 @@ module Shoulda
|
|
1171
1181
|
attr_reader :submatchers, :missing, :subject, :macro
|
1172
1182
|
|
1173
1183
|
def reflector
|
1174
|
-
@
|
1184
|
+
@_reflector ||= AssociationMatchers::ModelReflector.new(subject, name)
|
1175
1185
|
end
|
1176
1186
|
|
1177
1187
|
def add_submatcher(matcher_class, *args)
|
@@ -1186,16 +1196,7 @@ module Shoulda
|
|
1186
1196
|
end
|
1187
1197
|
|
1188
1198
|
def macro_description
|
1189
|
-
|
1190
|
-
when 'belongs_to'
|
1191
|
-
'belong to'
|
1192
|
-
when 'has_many'
|
1193
|
-
'have many'
|
1194
|
-
when 'has_one'
|
1195
|
-
'have one'
|
1196
|
-
when 'has_and_belongs_to_many'
|
1197
|
-
'have and belong to many'
|
1198
|
-
end
|
1199
|
+
MACROS[macro.to_s]
|
1199
1200
|
end
|
1200
1201
|
|
1201
1202
|
def expectation
|
@@ -1215,14 +1216,14 @@ module Shoulda
|
|
1215
1216
|
end
|
1216
1217
|
|
1217
1218
|
def failing_submatchers
|
1218
|
-
@
|
1219
|
-
|
1219
|
+
@_failing_submatchers ||= submatchers.reject do |matcher|
|
1220
|
+
matcher.matches?(subject)
|
1220
1221
|
end
|
1221
1222
|
end
|
1222
1223
|
|
1223
1224
|
def missing_options_for_failing_submatchers
|
1224
|
-
if defined?(@
|
1225
|
-
@
|
1225
|
+
if defined?(@_failing_submatchers)
|
1226
|
+
@_failing_submatchers.map(&:missing_option)
|
1226
1227
|
else
|
1227
1228
|
[]
|
1228
1229
|
end
|
@@ -1252,8 +1253,8 @@ module Shoulda
|
|
1252
1253
|
def validate_inverse_of_through_association
|
1253
1254
|
reflector.validate_inverse_of_through_association!
|
1254
1255
|
true
|
1255
|
-
rescue ::ActiveRecord::ActiveRecordError =>
|
1256
|
-
@missing =
|
1256
|
+
rescue ::ActiveRecord::ActiveRecordError => e
|
1257
|
+
@missing = e.message
|
1257
1258
|
false
|
1258
1259
|
end
|
1259
1260
|
|
@@ -1282,10 +1283,14 @@ module Shoulda
|
|
1282
1283
|
|
1283
1284
|
def class_name_correct?
|
1284
1285
|
if options.key?(:class_name)
|
1285
|
-
if option_verifier.correct_for_constant?(
|
1286
|
+
if option_verifier.correct_for_constant?(
|
1287
|
+
:class_name,
|
1288
|
+
options[:class_name],
|
1289
|
+
)
|
1286
1290
|
true
|
1287
1291
|
else
|
1288
|
-
@missing = "#{name} should resolve to #{options[:class_name]}
|
1292
|
+
@missing = "#{name} should resolve to #{options[:class_name]}"\
|
1293
|
+
' for class_name'
|
1289
1294
|
false
|
1290
1295
|
end
|
1291
1296
|
else
|
@@ -1294,7 +1299,10 @@ module Shoulda
|
|
1294
1299
|
end
|
1295
1300
|
|
1296
1301
|
def join_table_correct?
|
1297
|
-
if
|
1302
|
+
if (
|
1303
|
+
macro != :has_and_belongs_to_many ||
|
1304
|
+
join_table_matcher.matches?(@subject)
|
1305
|
+
)
|
1298
1306
|
true
|
1299
1307
|
else
|
1300
1308
|
@missing = join_table_matcher.failure_message
|
@@ -1303,8 +1311,10 @@ module Shoulda
|
|
1303
1311
|
end
|
1304
1312
|
|
1305
1313
|
def join_table_matcher
|
1306
|
-
@
|
1307
|
-
|
1314
|
+
@_join_table_matcher ||= AssociationMatchers::JoinTableMatcher.new(
|
1315
|
+
self,
|
1316
|
+
reflector,
|
1317
|
+
)
|
1308
1318
|
end
|
1309
1319
|
|
1310
1320
|
def class_exists?
|
@@ -1317,10 +1327,14 @@ module Shoulda
|
|
1317
1327
|
|
1318
1328
|
def autosave_correct?
|
1319
1329
|
if options.key?(:autosave)
|
1320
|
-
if option_verifier.correct_for_boolean?(
|
1330
|
+
if option_verifier.correct_for_boolean?(
|
1331
|
+
:autosave,
|
1332
|
+
options[:autosave],
|
1333
|
+
)
|
1321
1334
|
true
|
1322
1335
|
else
|
1323
|
-
@missing = "#{name} should have autosave set to
|
1336
|
+
@missing = "#{name} should have autosave set to"\
|
1337
|
+
" #{options[:autosave]}"
|
1324
1338
|
false
|
1325
1339
|
end
|
1326
1340
|
else
|
@@ -1333,23 +1347,27 @@ module Shoulda
|
|
1333
1347
|
|
1334
1348
|
if option_verifier.correct_for_boolean?(
|
1335
1349
|
:index_errors,
|
1336
|
-
options[:index_errors]
|
1350
|
+
options[:index_errors],
|
1337
1351
|
)
|
1338
1352
|
true
|
1339
1353
|
else
|
1340
1354
|
@missing =
|
1341
1355
|
"#{name} should have index_errors set to " +
|
1342
|
-
|
1356
|
+
options[:index_errors].to_s
|
1343
1357
|
false
|
1344
1358
|
end
|
1345
1359
|
end
|
1346
1360
|
|
1347
1361
|
def conditions_correct?
|
1348
1362
|
if options.key?(:conditions)
|
1349
|
-
if option_verifier.correct_for_relation_clause?(
|
1363
|
+
if option_verifier.correct_for_relation_clause?(
|
1364
|
+
:conditions,
|
1365
|
+
options[:conditions],
|
1366
|
+
)
|
1350
1367
|
true
|
1351
1368
|
else
|
1352
|
-
@missing = "#{name} should have the following conditions:
|
1369
|
+
@missing = "#{name} should have the following conditions:" +
|
1370
|
+
" #{options[:conditions]}"
|
1353
1371
|
false
|
1354
1372
|
end
|
1355
1373
|
else
|
@@ -1376,22 +1394,38 @@ module Shoulda
|
|
1376
1394
|
end
|
1377
1395
|
|
1378
1396
|
def class_has_foreign_key?(klass)
|
1379
|
-
if options.key?(:foreign_key)
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
@missing = "#{klass} does not have a #{foreign_key} foreign key."
|
1397
|
+
if options.key?(:foreign_key) && !foreign_key_correct?
|
1398
|
+
@missing = foreign_key_failure_message(klass, options[:foreign_key])
|
1399
|
+
false
|
1400
|
+
elsif !column_names_for(klass).include?(foreign_key)
|
1401
|
+
@missing = foreign_key_failure_message(klass, foreign_key)
|
1385
1402
|
false
|
1403
|
+
else
|
1404
|
+
true
|
1386
1405
|
end
|
1387
1406
|
end
|
1388
1407
|
|
1408
|
+
def foreign_key_correct?
|
1409
|
+
option_verifier.correct_for_string?(
|
1410
|
+
:foreign_key,
|
1411
|
+
options[:foreign_key],
|
1412
|
+
)
|
1413
|
+
end
|
1414
|
+
|
1415
|
+
def foreign_key_failure_message(klass, foreign_key)
|
1416
|
+
"#{klass} does not have a #{foreign_key} foreign key."
|
1417
|
+
end
|
1418
|
+
|
1389
1419
|
def primary_key_correct?(klass)
|
1390
1420
|
if options.key?(:primary_key)
|
1391
|
-
if option_verifier.correct_for_string?(
|
1421
|
+
if option_verifier.correct_for_string?(
|
1422
|
+
:primary_key,
|
1423
|
+
options[:primary_key],
|
1424
|
+
)
|
1392
1425
|
true
|
1393
1426
|
else
|
1394
|
-
@missing = "#{klass} does not have a #{options[:primary_key]}
|
1427
|
+
@missing = "#{klass} does not have a #{options[:primary_key]}"\
|
1428
|
+
' primary key'
|
1395
1429
|
false
|
1396
1430
|
end
|
1397
1431
|
else
|
@@ -1410,8 +1444,14 @@ module Shoulda
|
|
1410
1444
|
end
|
1411
1445
|
|
1412
1446
|
def foreign_key_reflection
|
1413
|
-
if
|
1414
|
-
|
1447
|
+
if (
|
1448
|
+
[:has_one, :has_many].include?(macro) &&
|
1449
|
+
reflection.options.include?(:inverse_of) &&
|
1450
|
+
reflection.options[:inverse_of] != false
|
1451
|
+
)
|
1452
|
+
associated_class.reflect_on_association(
|
1453
|
+
reflection.options[:inverse_of],
|
1454
|
+
)
|
1415
1455
|
else
|
1416
1456
|
reflection
|
1417
1457
|
end
|
@@ -19,7 +19,10 @@ module Shoulda
|
|
19
19
|
def matches?(subject)
|
20
20
|
self.subject = ModelReflector.new(subject, name)
|
21
21
|
|
22
|
-
if option_verifier.correct_for_string?(
|
22
|
+
if option_verifier.correct_for_string?(
|
23
|
+
:counter_cache,
|
24
|
+
counter_cache,
|
25
|
+
)
|
23
26
|
true
|
24
27
|
else
|
25
28
|
self.missing_option = "#{name} should have #{description}"
|
@@ -32,7 +35,7 @@ module Shoulda
|
|
32
35
|
attr_accessor :subject, :counter_cache, :name
|
33
36
|
|
34
37
|
def option_verifier
|
35
|
-
@
|
38
|
+
@_option_verifier ||= OptionVerifier.new(subject)
|
36
39
|
end
|
37
40
|
end
|
38
41
|
end
|