shoulda-matchers 4.1.2 → 4.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.
- 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
|