shoulda-matchers 4.4.0 → 5.0.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/LICENSE +22 -0
- data/README.md +18 -18
- data/lib/shoulda/matchers.rb +12 -13
- data/lib/shoulda/matchers/action_controller.rb +13 -13
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +4 -89
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +3 -2
- data/lib/shoulda/matchers/action_controller/flash_store.rb +2 -4
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +29 -27
- 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.rb +25 -15
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +29 -36
- 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 +2 -2
- data/lib/shoulda/matchers/active_model/numericality_matchers.rb +0 -5
- 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 +10 -2
- 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 +40 -27
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +4 -4
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +6 -8
- 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 +4 -9
- data/lib/shoulda/matchers/active_record.rb +26 -14
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +6 -3
- data/lib/shoulda/matchers/active_record/association_matcher.rb +101 -48
- data/lib/shoulda/matchers/active_record/association_matchers.rb +0 -12
- 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 +4 -4
- 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 +18 -9
- 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 +4 -4
- 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 +9 -9
- 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 +1 -0
- data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +14 -16
- data/lib/shoulda/matchers/integrations.rb +6 -6
- 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.rb +2 -4
- 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 -42
- data/lib/shoulda/matchers/util.rb +9 -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 +12 -9
- metadata +14 -14
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +0 -159
@@ -1,23 +1,35 @@
|
|
1
|
-
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'
|
2
27
|
|
3
28
|
module Shoulda
|
4
29
|
module Matchers
|
5
30
|
# This module provides matchers that are used to test behavior within
|
6
31
|
# ActiveRecord classes.
|
7
32
|
module ActiveRecord
|
8
|
-
autoload :AcceptNestedAttributesForMatcher, 'shoulda/matchers/active_record/accept_nested_attributes_for_matcher'
|
9
|
-
autoload :AssociationMatcher, 'shoulda/matchers/active_record/association_matcher'
|
10
|
-
autoload :AssociationMatchers, 'shoulda/matchers/active_record/association_matchers'
|
11
|
-
autoload :DefineEnumForMatcher, 'shoulda/matchers/active_record/define_enum_for_matcher'
|
12
|
-
autoload :HaveAttachedMatcher, 'shoulda/matchers/active_record/have_attached_matcher'
|
13
|
-
autoload :HaveDbColumnMatcher, 'shoulda/matchers/active_record/have_db_column_matcher'
|
14
|
-
autoload :HaveDbIndexMatcher, 'shoulda/matchers/active_record/have_db_index_matcher'
|
15
|
-
autoload :HaveImplicitOrderColumnMatcher, 'shoulda/matchers/active_record/have_implicit_order_column'
|
16
|
-
autoload :HaveReadonlyAttributeMatcher, 'shoulda/matchers/active_record/have_readonly_attribute_matcher'
|
17
|
-
autoload :HaveRichText, 'shoulda/matchers/active_record/have_rich_text_matcher'
|
18
|
-
autoload :HaveSecureTokenMatcher, 'shoulda/matchers/active_record/have_secure_token_matcher'
|
19
|
-
autoload :SerializeMatcher, 'shoulda/matchers/active_record/serialize_matcher'
|
20
|
-
autoload :Uniqueness, 'shoulda/matchers/active_record/uniqueness'
|
21
33
|
end
|
22
34
|
end
|
23
35
|
end
|
@@ -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
|
|
@@ -997,7 +1004,7 @@ module Shoulda
|
|
997
1004
|
@submatchers = []
|
998
1005
|
@missing = ''
|
999
1006
|
|
1000
|
-
if macro == :belongs_to
|
1007
|
+
if macro == :belongs_to
|
1001
1008
|
required(belongs_to_required_by_default?)
|
1002
1009
|
end
|
1003
1010
|
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
|
|
@@ -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,49 @@ module Shoulda
|
|
1376
1394
|
end
|
1377
1395
|
|
1378
1396
|
def class_has_foreign_key?(klass)
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1397
|
+
@missing = validate_foreign_key(klass)
|
1398
|
+
|
1399
|
+
@missing.nil?
|
1400
|
+
end
|
1401
|
+
|
1402
|
+
def validate_foreign_key(klass)
|
1403
|
+
if options.key?(:foreign_key) && !foreign_key_correct?
|
1404
|
+
foreign_key_failure_message(klass, options[:foreign_key])
|
1405
|
+
elsif !has_column?(klass, actual_foreign_key)
|
1406
|
+
foreign_key_failure_message(klass, actual_foreign_key)
|
1407
|
+
end
|
1408
|
+
end
|
1409
|
+
|
1410
|
+
def has_column?(klass, column)
|
1411
|
+
case column
|
1412
|
+
when Array
|
1413
|
+
column.all? { |c| has_column?(klass, c.to_s) }
|
1383
1414
|
else
|
1384
|
-
|
1385
|
-
false
|
1415
|
+
column_names_for(klass).include?(column.to_s)
|
1386
1416
|
end
|
1387
1417
|
end
|
1388
1418
|
|
1419
|
+
def foreign_key_correct?
|
1420
|
+
option_verifier.correct_for_string?(
|
1421
|
+
:foreign_key,
|
1422
|
+
options[:foreign_key],
|
1423
|
+
)
|
1424
|
+
end
|
1425
|
+
|
1426
|
+
def foreign_key_failure_message(klass, foreign_key)
|
1427
|
+
"#{klass} does not have a #{foreign_key} foreign key."
|
1428
|
+
end
|
1429
|
+
|
1389
1430
|
def primary_key_correct?(klass)
|
1390
1431
|
if options.key?(:primary_key)
|
1391
|
-
if option_verifier.correct_for_string?(
|
1432
|
+
if option_verifier.correct_for_string?(
|
1433
|
+
:primary_key,
|
1434
|
+
options[:primary_key],
|
1435
|
+
)
|
1392
1436
|
true
|
1393
1437
|
else
|
1394
|
-
@missing = "#{klass} does not have a #{options[:primary_key]}
|
1438
|
+
@missing = "#{klass} does not have a #{options[:primary_key]}"\
|
1439
|
+
' primary key'
|
1395
1440
|
false
|
1396
1441
|
end
|
1397
1442
|
else
|
@@ -1399,19 +1444,27 @@ module Shoulda
|
|
1399
1444
|
end
|
1400
1445
|
end
|
1401
1446
|
|
1402
|
-
def
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1447
|
+
def actual_foreign_key
|
1448
|
+
return unless foreign_key_reflection
|
1449
|
+
|
1450
|
+
if foreign_key_reflection.options[:foreign_key]
|
1451
|
+
foreign_key_reflection.options[:foreign_key]
|
1452
|
+
elsif foreign_key_reflection.respond_to?(:foreign_key)
|
1453
|
+
foreign_key_reflection.foreign_key
|
1454
|
+
else
|
1455
|
+
foreign_key_reflection.primary_key_name
|
1409
1456
|
end
|
1410
1457
|
end
|
1411
1458
|
|
1412
1459
|
def foreign_key_reflection
|
1413
|
-
if
|
1414
|
-
|
1460
|
+
if (
|
1461
|
+
[:has_one, :has_many].include?(macro) &&
|
1462
|
+
reflection.options.include?(:inverse_of) &&
|
1463
|
+
reflection.options[:inverse_of] != false
|
1464
|
+
)
|
1465
|
+
associated_class.reflect_on_association(
|
1466
|
+
reflection.options[:inverse_of],
|
1467
|
+
)
|
1415
1468
|
else
|
1416
1469
|
reflection
|
1417
1470
|
end
|
@@ -3,18 +3,6 @@ module Shoulda
|
|
3
3
|
module ActiveRecord
|
4
4
|
# @private
|
5
5
|
module AssociationMatchers
|
6
|
-
autoload :CounterCacheMatcher, 'shoulda/matchers/active_record/association_matchers/counter_cache_matcher'
|
7
|
-
autoload :InverseOfMatcher, 'shoulda/matchers/active_record/association_matchers/inverse_of_matcher'
|
8
|
-
autoload :JoinTableMatcher, 'shoulda/matchers/active_record/association_matchers/join_table_matcher'
|
9
|
-
autoload :OrderMatcher, 'shoulda/matchers/active_record/association_matchers/order_matcher'
|
10
|
-
autoload :ThroughMatcher, 'shoulda/matchers/active_record/association_matchers/through_matcher'
|
11
|
-
autoload :DependentMatcher, 'shoulda/matchers/active_record/association_matchers/dependent_matcher'
|
12
|
-
autoload :RequiredMatcher, 'shoulda/matchers/active_record/association_matchers/required_matcher'
|
13
|
-
autoload :OptionalMatcher, 'shoulda/matchers/active_record/association_matchers/optional_matcher'
|
14
|
-
autoload :SourceMatcher, 'shoulda/matchers/active_record/association_matchers/source_matcher'
|
15
|
-
autoload :ModelReflector, 'shoulda/matchers/active_record/association_matchers/model_reflector'
|
16
|
-
autoload :ModelReflection, 'shoulda/matchers/active_record/association_matchers/model_reflection'
|
17
|
-
autoload :OptionVerifier, 'shoulda/matchers/active_record/association_matchers/option_verifier'
|
18
6
|
end
|
19
7
|
end
|
20
8
|
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
|
@@ -18,7 +18,7 @@ module Shoulda
|
|
18
18
|
@reflector = reflector
|
19
19
|
end
|
20
20
|
|
21
|
-
def matches?(
|
21
|
+
def matches?(_subject)
|
22
22
|
join_table_option_correct? &&
|
23
23
|
join_table_exists? &&
|
24
24
|
join_table_has_correct_columns?
|
@@ -26,10 +26,14 @@ module Shoulda
|
|
26
26
|
|
27
27
|
def join_table_option_correct?
|
28
28
|
if options.key?(:join_table_name)
|
29
|
-
if option_verifier.correct_for_string?(
|
29
|
+
if option_verifier.correct_for_string?(
|
30
|
+
:join_table,
|
31
|
+
options[:join_table_name],
|
32
|
+
)
|
30
33
|
true
|
31
34
|
else
|
32
|
-
@failure_message = "#{name} should use
|
35
|
+
@failure_message = "#{name} should use"\
|
36
|
+
" #{options[:join_table_name].inspect} for :join_table option"
|
33
37
|
false
|
34
38
|
end
|
35
39
|
else
|
@@ -38,7 +42,8 @@ module Shoulda
|
|
38
42
|
end
|
39
43
|
|
40
44
|
def join_table_exists?
|
41
|
-
if
|
45
|
+
if connection.data_sources.
|
46
|
+
include?(join_table_name.to_s)
|
42
47
|
true
|
43
48
|
else
|
44
49
|
@failure_message = missing_table_message
|
@@ -64,8 +69,8 @@ module Shoulda
|
|
64
69
|
delegate :foreign_key, :association_foreign_key, to: :reflector
|
65
70
|
|
66
71
|
def missing_columns
|
67
|
-
@
|
68
|
-
|
72
|
+
@_missing_columns ||= expected_join_table_columns.reject do |key|
|
73
|
+
actual_join_table_columns.include?(key.to_s)
|
69
74
|
end
|
70
75
|
end
|
71
76
|
|