shoulda-matchers 4.4.0 → 5.0.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 +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
|
|