shoulda-matchers 4.1.2 → 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/{MIT-LICENSE → LICENSE} +1 -1
- data/README.md +168 -86
- 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 +31 -29
- 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 -30
- 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 +9 -8
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +28 -46
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +33 -9
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +71 -26
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +31 -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 -23
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +6 -3
- data/lib/shoulda/matchers/active_record/association_matcher.rb +100 -44
- 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 +14 -15
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +30 -8
- 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 +185 -0
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +40 -18
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +106 -0
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +12 -10
- data/lib/shoulda/matchers/active_record/have_rich_text_matcher.rb +83 -0
- data/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +30 -9
- 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 +80 -73
- 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.rb +0 -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 +10 -21
- data/lib/shoulda/matchers/util.rb +16 -4
- data/lib/shoulda/matchers/util/word_wrap.rb +8 -8
- data/lib/shoulda/matchers/version.rb +1 -1
- data/lib/shoulda/matchers/warn.rb +3 -3
- data/shoulda-matchers.gemspec +10 -7
- metadata +11 -9
- data/lib/shoulda/matchers/independent/delegate_method_matcher/stubbed_target.rb +0 -37
@@ -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,26 +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
|
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'
|
24
27
|
|
25
28
|
module Shoulda
|
26
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
|
|
@@ -920,21 +920,21 @@ module Shoulda
|
|
920
920
|
# asserts that the table you're referring to actually exists.
|
921
921
|
#
|
922
922
|
# class Person < ActiveRecord::Base
|
923
|
-
# has_and_belongs_to_many :issues, join_table:
|
923
|
+
# has_and_belongs_to_many :issues, join_table: :people_tickets
|
924
924
|
# end
|
925
925
|
#
|
926
926
|
# # RSpec
|
927
927
|
# RSpec.describe Person, type: :model do
|
928
928
|
# it do
|
929
929
|
# should have_and_belong_to_many(:issues).
|
930
|
-
# join_table(
|
930
|
+
# join_table(:people_tickets)
|
931
931
|
# end
|
932
932
|
# end
|
933
933
|
#
|
934
934
|
# # Minitest (Shoulda)
|
935
935
|
# class PersonTest < ActiveSupport::TestCase
|
936
936
|
# should have_and_belong_to_many(:issues).
|
937
|
-
# join_table(
|
937
|
+
# join_table(:people_tickets)
|
938
938
|
# end
|
939
939
|
#
|
940
940
|
# ##### validate
|
@@ -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
|
|
@@ -1096,12 +1103,12 @@ module Shoulda
|
|
1096
1103
|
self
|
1097
1104
|
end
|
1098
1105
|
|
1099
|
-
def optional
|
1106
|
+
def optional(optional = true)
|
1100
1107
|
remove_submatcher(AssociationMatchers::RequiredMatcher)
|
1101
1108
|
add_submatcher(
|
1102
1109
|
AssociationMatchers::OptionalMatcher,
|
1103
1110
|
name,
|
1104
|
-
|
1111
|
+
optional,
|
1105
1112
|
)
|
1106
1113
|
self
|
1107
1114
|
end
|
@@ -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
|
|
@@ -1144,6 +1153,7 @@ module Shoulda
|
|
1144
1153
|
@subject = subject
|
1145
1154
|
association_exists? &&
|
1146
1155
|
macro_correct? &&
|
1156
|
+
validate_inverse_of_through_association &&
|
1147
1157
|
(polymorphic? || class_exists?) &&
|
1148
1158
|
foreign_key_exists? &&
|
1149
1159
|
primary_key_exists? &&
|
@@ -1162,7 +1172,8 @@ module Shoulda
|
|
1162
1172
|
end
|
1163
1173
|
|
1164
1174
|
def option_verifier
|
1165
|
-
@
|
1175
|
+
@_option_verifier ||=
|
1176
|
+
AssociationMatchers::OptionVerifier.new(reflector)
|
1166
1177
|
end
|
1167
1178
|
|
1168
1179
|
protected
|
@@ -1170,7 +1181,7 @@ module Shoulda
|
|
1170
1181
|
attr_reader :submatchers, :missing, :subject, :macro
|
1171
1182
|
|
1172
1183
|
def reflector
|
1173
|
-
@
|
1184
|
+
@_reflector ||= AssociationMatchers::ModelReflector.new(subject, name)
|
1174
1185
|
end
|
1175
1186
|
|
1176
1187
|
def add_submatcher(matcher_class, *args)
|
@@ -1185,20 +1196,18 @@ module Shoulda
|
|
1185
1196
|
end
|
1186
1197
|
|
1187
1198
|
def macro_description
|
1188
|
-
|
1189
|
-
when 'belongs_to'
|
1190
|
-
'belong to'
|
1191
|
-
when 'has_many'
|
1192
|
-
'have many'
|
1193
|
-
when 'has_one'
|
1194
|
-
'have one'
|
1195
|
-
when 'has_and_belongs_to_many'
|
1196
|
-
'have and belong to many'
|
1197
|
-
end
|
1199
|
+
MACROS[macro.to_s]
|
1198
1200
|
end
|
1199
1201
|
|
1200
1202
|
def expectation
|
1201
|
-
|
1203
|
+
expectation =
|
1204
|
+
"#{model_class.name} to have a #{macro} association called #{name}"
|
1205
|
+
|
1206
|
+
if through?
|
1207
|
+
expectation << " through #{reflector.has_and_belongs_to_many_name}"
|
1208
|
+
end
|
1209
|
+
|
1210
|
+
expectation
|
1202
1211
|
end
|
1203
1212
|
|
1204
1213
|
def missing_options
|
@@ -1207,14 +1216,14 @@ module Shoulda
|
|
1207
1216
|
end
|
1208
1217
|
|
1209
1218
|
def failing_submatchers
|
1210
|
-
@
|
1211
|
-
|
1219
|
+
@_failing_submatchers ||= submatchers.reject do |matcher|
|
1220
|
+
matcher.matches?(subject)
|
1212
1221
|
end
|
1213
1222
|
end
|
1214
1223
|
|
1215
1224
|
def missing_options_for_failing_submatchers
|
1216
|
-
if defined?(@
|
1217
|
-
@
|
1225
|
+
if defined?(@_failing_submatchers)
|
1226
|
+
@_failing_submatchers.map(&:missing_option)
|
1218
1227
|
else
|
1219
1228
|
[]
|
1220
1229
|
end
|
@@ -1241,6 +1250,14 @@ module Shoulda
|
|
1241
1250
|
end
|
1242
1251
|
end
|
1243
1252
|
|
1253
|
+
def validate_inverse_of_through_association
|
1254
|
+
reflector.validate_inverse_of_through_association!
|
1255
|
+
true
|
1256
|
+
rescue ::ActiveRecord::ActiveRecordError => e
|
1257
|
+
@missing = e.message
|
1258
|
+
false
|
1259
|
+
end
|
1260
|
+
|
1244
1261
|
def macro_supports_primary_key?
|
1245
1262
|
macro == :belongs_to ||
|
1246
1263
|
([:has_many, :has_one].include?(macro) && !through?)
|
@@ -1266,10 +1283,14 @@ module Shoulda
|
|
1266
1283
|
|
1267
1284
|
def class_name_correct?
|
1268
1285
|
if options.key?(:class_name)
|
1269
|
-
if option_verifier.correct_for_constant?(
|
1286
|
+
if option_verifier.correct_for_constant?(
|
1287
|
+
:class_name,
|
1288
|
+
options[:class_name],
|
1289
|
+
)
|
1270
1290
|
true
|
1271
1291
|
else
|
1272
|
-
@missing = "#{name} should resolve to #{options[:class_name]}
|
1292
|
+
@missing = "#{name} should resolve to #{options[:class_name]}"\
|
1293
|
+
' for class_name'
|
1273
1294
|
false
|
1274
1295
|
end
|
1275
1296
|
else
|
@@ -1278,7 +1299,10 @@ module Shoulda
|
|
1278
1299
|
end
|
1279
1300
|
|
1280
1301
|
def join_table_correct?
|
1281
|
-
if
|
1302
|
+
if (
|
1303
|
+
macro != :has_and_belongs_to_many ||
|
1304
|
+
join_table_matcher.matches?(@subject)
|
1305
|
+
)
|
1282
1306
|
true
|
1283
1307
|
else
|
1284
1308
|
@missing = join_table_matcher.failure_message
|
@@ -1287,8 +1311,10 @@ module Shoulda
|
|
1287
1311
|
end
|
1288
1312
|
|
1289
1313
|
def join_table_matcher
|
1290
|
-
@
|
1291
|
-
|
1314
|
+
@_join_table_matcher ||= AssociationMatchers::JoinTableMatcher.new(
|
1315
|
+
self,
|
1316
|
+
reflector,
|
1317
|
+
)
|
1292
1318
|
end
|
1293
1319
|
|
1294
1320
|
def class_exists?
|
@@ -1301,10 +1327,14 @@ module Shoulda
|
|
1301
1327
|
|
1302
1328
|
def autosave_correct?
|
1303
1329
|
if options.key?(:autosave)
|
1304
|
-
if option_verifier.correct_for_boolean?(
|
1330
|
+
if option_verifier.correct_for_boolean?(
|
1331
|
+
:autosave,
|
1332
|
+
options[:autosave],
|
1333
|
+
)
|
1305
1334
|
true
|
1306
1335
|
else
|
1307
|
-
@missing = "#{name} should have autosave set to
|
1336
|
+
@missing = "#{name} should have autosave set to"\
|
1337
|
+
" #{options[:autosave]}"
|
1308
1338
|
false
|
1309
1339
|
end
|
1310
1340
|
else
|
@@ -1317,23 +1347,27 @@ module Shoulda
|
|
1317
1347
|
|
1318
1348
|
if option_verifier.correct_for_boolean?(
|
1319
1349
|
:index_errors,
|
1320
|
-
options[:index_errors]
|
1350
|
+
options[:index_errors],
|
1321
1351
|
)
|
1322
1352
|
true
|
1323
1353
|
else
|
1324
1354
|
@missing =
|
1325
1355
|
"#{name} should have index_errors set to " +
|
1326
|
-
|
1356
|
+
options[:index_errors].to_s
|
1327
1357
|
false
|
1328
1358
|
end
|
1329
1359
|
end
|
1330
1360
|
|
1331
1361
|
def conditions_correct?
|
1332
1362
|
if options.key?(:conditions)
|
1333
|
-
if option_verifier.correct_for_relation_clause?(
|
1363
|
+
if option_verifier.correct_for_relation_clause?(
|
1364
|
+
:conditions,
|
1365
|
+
options[:conditions],
|
1366
|
+
)
|
1334
1367
|
true
|
1335
1368
|
else
|
1336
|
-
@missing = "#{name} should have the following conditions:
|
1369
|
+
@missing = "#{name} should have the following conditions:" +
|
1370
|
+
" #{options[:conditions]}"
|
1337
1371
|
false
|
1338
1372
|
end
|
1339
1373
|
else
|
@@ -1360,22 +1394,38 @@ module Shoulda
|
|
1360
1394
|
end
|
1361
1395
|
|
1362
1396
|
def class_has_foreign_key?(klass)
|
1363
|
-
if options.key?(:foreign_key)
|
1364
|
-
|
1365
|
-
elsif column_names_for(klass).include?(foreign_key)
|
1366
|
-
true
|
1367
|
-
else
|
1368
|
-
@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])
|
1369
1399
|
false
|
1400
|
+
elsif !column_names_for(klass).include?(foreign_key)
|
1401
|
+
@missing = foreign_key_failure_message(klass, foreign_key)
|
1402
|
+
false
|
1403
|
+
else
|
1404
|
+
true
|
1370
1405
|
end
|
1371
1406
|
end
|
1372
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
|
+
|
1373
1419
|
def primary_key_correct?(klass)
|
1374
1420
|
if options.key?(:primary_key)
|
1375
|
-
if option_verifier.correct_for_string?(
|
1421
|
+
if option_verifier.correct_for_string?(
|
1422
|
+
:primary_key,
|
1423
|
+
options[:primary_key],
|
1424
|
+
)
|
1376
1425
|
true
|
1377
1426
|
else
|
1378
|
-
@missing = "#{klass} does not have a #{options[:primary_key]}
|
1427
|
+
@missing = "#{klass} does not have a #{options[:primary_key]}"\
|
1428
|
+
' primary key'
|
1379
1429
|
false
|
1380
1430
|
end
|
1381
1431
|
else
|
@@ -1394,8 +1444,14 @@ module Shoulda
|
|
1394
1444
|
end
|
1395
1445
|
|
1396
1446
|
def foreign_key_reflection
|
1397
|
-
if
|
1398
|
-
|
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
|
+
)
|
1399
1455
|
else
|
1400
1456
|
reflection
|
1401
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
|
@@ -34,7 +34,7 @@ module Shoulda
|
|
34
34
|
private
|
35
35
|
|
36
36
|
def option_verifier
|
37
|
-
@
|
37
|
+
@_option_verifier ||= OptionVerifier.new(subject)
|
38
38
|
end
|
39
39
|
|
40
40
|
def option_matches?
|
@@ -43,8 +43,8 @@ module Shoulda
|
|
43
43
|
|
44
44
|
def option_type
|
45
45
|
case dependent
|
46
|
-
|
47
|
-
|
46
|
+
when true, false then :boolean
|
47
|
+
else :string
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -52,7 +52,7 @@ module Shoulda
|
|
52
52
|
[
|
53
53
|
"#{name} should have",
|
54
54
|
(dependent == true ? 'a' : dependent),
|
55
|
-
'dependency'
|
55
|
+
'dependency',
|
56
56
|
].join(' ')
|
57
57
|
end
|
58
58
|
end
|