shoulda-matchers 4.3.0 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +157 -77
  3. data/lib/shoulda/matchers.rb +13 -12
  4. data/lib/shoulda/matchers/action_controller.rb +13 -13
  5. data/lib/shoulda/matchers/active_model.rb +15 -26
  6. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +9 -0
  7. data/lib/shoulda/matchers/active_model/numericality_matchers.rb +5 -0
  8. data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +5 -1
  9. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +2 -21
  10. data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +27 -3
  11. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +32 -0
  12. data/lib/shoulda/matchers/active_model/validation_matcher.rb +27 -0
  13. data/lib/shoulda/matchers/active_record.rb +13 -23
  14. data/lib/shoulda/matchers/active_record/association_matcher.rb +20 -4
  15. data/lib/shoulda/matchers/active_record/association_matchers.rb +12 -0
  16. data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +2 -2
  17. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +12 -6
  18. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +20 -3
  19. data/lib/shoulda/matchers/active_record/have_attached_matcher.rb +147 -0
  20. data/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +106 -0
  21. data/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +28 -9
  22. data/lib/shoulda/matchers/active_record/uniqueness.rb +5 -5
  23. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +2 -2
  24. data/lib/shoulda/matchers/doublespeak.rb +8 -7
  25. data/lib/shoulda/matchers/independent.rb +0 -2
  26. data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +3 -0
  27. data/lib/shoulda/matchers/integrations.rb +6 -6
  28. data/lib/shoulda/matchers/integrations/test_frameworks.rb +4 -2
  29. data/lib/shoulda/matchers/rails_shim.rb +4 -0
  30. data/lib/shoulda/matchers/util.rb +9 -4
  31. data/lib/shoulda/matchers/util/word_wrap.rb +1 -1
  32. data/lib/shoulda/matchers/version.rb +1 -1
  33. metadata +8 -8
  34. data/MIT-LICENSE +0 -22
  35. data/lib/shoulda/matchers/independent/delegate_method_matcher/stubbed_target.rb +0 -37
@@ -1,34 +1,9 @@
1
+ require 'shoulda/matchers/active_model/allow_mass_assignment_of_matcher'
1
2
  require 'shoulda/matchers/active_model/helpers'
2
3
  require 'shoulda/matchers/active_model/qualifiers'
3
4
  require 'shoulda/matchers/active_model/validation_matcher'
4
- require 'shoulda/matchers/active_model/validation_matcher/build_description'
5
- require 'shoulda/matchers/active_model/validator'
6
- require 'shoulda/matchers/active_model/allow_value_matcher'
7
- require 'shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error'
8
- require 'shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error'
9
- require 'shoulda/matchers/active_model/allow_value_matcher/attribute_setter'
10
- require 'shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator'
11
- require 'shoulda/matchers/active_model/allow_value_matcher/attribute_setters'
12
- require 'shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators'
13
- require 'shoulda/matchers/active_model/allow_value_matcher/successful_check'
14
- require 'shoulda/matchers/active_model/allow_value_matcher/successful_setting'
15
- require 'shoulda/matchers/active_model/disallow_value_matcher'
16
- require 'shoulda/matchers/active_model/validate_length_of_matcher'
17
- require 'shoulda/matchers/active_model/validate_inclusion_of_matcher'
18
- require 'shoulda/matchers/active_model/validate_exclusion_of_matcher'
19
5
  require 'shoulda/matchers/active_model/validate_absence_of_matcher'
20
6
  require 'shoulda/matchers/active_model/validate_presence_of_matcher'
21
- require 'shoulda/matchers/active_model/validate_acceptance_of_matcher'
22
- require 'shoulda/matchers/active_model/validate_confirmation_of_matcher'
23
- require 'shoulda/matchers/active_model/validate_numericality_of_matcher'
24
- require 'shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher'
25
- require 'shoulda/matchers/active_model/numericality_matchers/comparison_matcher'
26
- require 'shoulda/matchers/active_model/numericality_matchers/odd_number_matcher'
27
- require 'shoulda/matchers/active_model/numericality_matchers/even_number_matcher'
28
- require 'shoulda/matchers/active_model/numericality_matchers/only_integer_matcher'
29
- require 'shoulda/matchers/active_model/allow_mass_assignment_of_matcher'
30
- require 'shoulda/matchers/active_model/errors'
31
- require 'shoulda/matchers/active_model/have_secure_password_matcher'
32
7
 
33
8
  module Shoulda
34
9
  module Matchers
@@ -89,6 +64,20 @@ module Shoulda
89
64
  # end
90
65
  #
91
66
  module ActiveModel
67
+ autoload :AllowValueMatcher, 'shoulda/matchers/active_model/allow_value_matcher'
68
+ autoload :CouldNotDetermineValueOutsideOfArray, 'shoulda/matchers/active_model/errors'
69
+ autoload :CouldNotSetPasswordError, 'shoulda/matchers/active_model/errors'
70
+ autoload :DisallowValueMatcher, 'shoulda/matchers/active_model/disallow_value_matcher'
71
+ autoload :HaveSecurePasswordMatcher, 'shoulda/matchers/active_model/have_secure_password_matcher'
72
+ autoload :NonNullableBooleanError, 'shoulda/matchers/active_model/errors'
73
+ autoload :NumericalityMatchers, 'shoulda/matchers/active_model/numericality_matchers'
74
+ autoload :ValidateAcceptanceOfMatcher, 'shoulda/matchers/active_model/validate_acceptance_of_matcher'
75
+ autoload :ValidateConfirmationOfMatcher, 'shoulda/matchers/active_model/validate_confirmation_of_matcher'
76
+ autoload :ValidateExclusionOfMatcher, 'shoulda/matchers/active_model/validate_exclusion_of_matcher'
77
+ autoload :ValidateInclusionOfMatcher, 'shoulda/matchers/active_model/validate_inclusion_of_matcher'
78
+ autoload :ValidateLengthOfMatcher, 'shoulda/matchers/active_model/validate_length_of_matcher'
79
+ autoload :ValidateNumericalityOfMatcher, 'shoulda/matchers/active_model/validate_numericality_of_matcher'
80
+ autoload :Validator, 'shoulda/matchers/active_model/validator'
92
81
  end
93
82
  end
94
83
  end
@@ -305,6 +305,15 @@ module Shoulda
305
305
 
306
306
  # @private
307
307
  class AllowValueMatcher
308
+ autoload :AttributeChangedValueError, 'shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error'
309
+ autoload :AttributeDoesNotExistError, 'shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error'
310
+ autoload :AttributeSetter, 'shoulda/matchers/active_model/allow_value_matcher/attribute_setter'
311
+ autoload :AttributeSetterAndValidator, 'shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator'
312
+ autoload :AttributeSetters, 'shoulda/matchers/active_model/allow_value_matcher/attribute_setters'
313
+ autoload :AttributeSettersAndValidators, 'shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators'
314
+ autoload :SuccessfulCheck, 'shoulda/matchers/active_model/allow_value_matcher/successful_check'
315
+ autoload :SuccessfulSetting, 'shoulda/matchers/active_model/allow_value_matcher/successful_setting'
316
+
308
317
  include Helpers
309
318
  include Qualifiers::IgnoringInterferenceByWriter
310
319
 
@@ -3,6 +3,11 @@ module Shoulda
3
3
  module ActiveModel
4
4
  # @private
5
5
  module NumericalityMatchers
6
+ autoload :ComparisonMatcher, 'shoulda/matchers/active_model/numericality_matchers/comparison_matcher'
7
+ autoload :EvenNumberMatcher, 'shoulda/matchers/active_model/numericality_matchers/even_number_matcher'
8
+ autoload :NumericTypeMatcher, 'shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher'
9
+ autoload :OddNumberMatcher, 'shoulda/matchers/active_model/numericality_matchers/odd_number_matcher'
10
+ autoload :OnlyIntegerMatcher, 'shoulda/matchers/active_model/numericality_matchers/only_integer_matcher'
6
11
  end
7
12
  end
8
13
  end
@@ -9,7 +9,8 @@ module Shoulda
9
9
  :>= => :greater_than_or_equal_to,
10
10
  :< => :less_than,
11
11
  :<= => :less_than_or_equal_to,
12
- :== => :equal_to
12
+ :== => :equal_to,
13
+ :!= => :other_than,
13
14
  }
14
15
 
15
16
  def initialize(numericality_matcher, value, operator)
@@ -125,6 +126,8 @@ module Shoulda
125
126
  [true, false, false]
126
127
  when :<=
127
128
  [true, true, false]
129
+ when :!=
130
+ [true, false, true]
128
131
  end
129
132
  end
130
133
 
@@ -146,6 +149,7 @@ module Shoulda
146
149
  when :== then "equal to"
147
150
  when :< then "less than"
148
151
  when :<= then "less than or equal to"
152
+ when :!= then 'other than'
149
153
  end
150
154
  end
151
155
  end
@@ -311,15 +311,6 @@ EOT
311
311
  self
312
312
  end
313
313
 
314
- def allow_blank
315
- @options[:allow_blank] = true
316
- self
317
- end
318
-
319
- def expects_to_allow_blank?
320
- @options[:allow_blank]
321
- end
322
-
323
314
  def allow_nil
324
315
  @options[:allow_nil] = true
325
316
  self
@@ -423,14 +414,14 @@ EOT
423
414
  allows_all_values_in_array? &&
424
415
  disallows_all_values_outside_of_array? &&
425
416
  allows_nil_value? &&
426
- allows_blank_value?
417
+ allow_blank_matches?
427
418
  end
428
419
 
429
420
  def does_not_match_for_array?
430
421
  disallows_any_values_in_array? ||
431
422
  allows_any_value_outside_of_array? ||
432
423
  disallows_nil_value? ||
433
- disallows_blank_value?
424
+ allow_blank_does_not_match?
434
425
  end
435
426
 
436
427
  def allows_lower_value
@@ -616,16 +607,6 @@ EOT
616
607
  @options[:allow_nil] && disallows_value_of(nil)
617
608
  end
618
609
 
619
- def allows_blank_value?
620
- @options[:allow_blank] != true ||
621
- BLANK_VALUES.all? { |value| allows_value_of(value) }
622
- end
623
-
624
- def disallows_blank_value?
625
- @options[:allow_blank] &&
626
- BLANK_VALUES.any? { |value| disallows_value_of(value) }
627
- end
628
-
629
610
  def inspected_array
630
611
  Shoulda::Matchers::Util.inspect_values(@array).to_sentence(
631
612
  two_words_connector: " or ",
@@ -232,13 +232,34 @@ module Shoulda
232
232
  # it { should validate_length_of(:bio).is_at_least(15).allow_nil }
233
233
  # end
234
234
  #
235
- # # Test::Unit
235
+ # # Minitest (Shoulda)
236
236
  # class UserTest < ActiveSupport::TestCase
237
237
  # should validate_length_of(:bio).is_at_least(15).allow_nil
238
238
  # end
239
239
  #
240
240
  # @return [ValidateLengthOfMatcher]
241
241
  #
242
+ # # ##### allow_blank
243
+ #
244
+ # Use `allow_blank` to assert that the attribute allows blank.
245
+ #
246
+ # class User
247
+ # include ActiveModel::Model
248
+ # attr_accessor :bio
249
+ #
250
+ # validates_length_of :bio, minimum: 15, allow_blank: true
251
+ # end
252
+ #
253
+ # # RSpec
254
+ # describe User do
255
+ # it { should validate_length_of(:bio).is_at_least(15).allow_blank }
256
+ # end
257
+ #
258
+ # # Minitest (Shoulda)
259
+ # class UserTest < ActiveSupport::TestCase
260
+ # should validate_length_of(:bio).is_at_least(15).allow_blank
261
+ # end
262
+ #
242
263
  def validate_length_of(attr)
243
264
  ValidateLengthOfMatcher.new(attr)
244
265
  end
@@ -331,7 +352,8 @@ module Shoulda
331
352
 
332
353
  lower_bound_matches? &&
333
354
  upper_bound_matches? &&
334
- allow_nil_matches?
355
+ allow_nil_matches? &&
356
+ allow_blank_matches?
335
357
  end
336
358
 
337
359
  def does_not_match?(subject)
@@ -339,7 +361,8 @@ module Shoulda
339
361
 
340
362
  lower_bound_does_not_match? ||
341
363
  upper_bound_does_not_match? ||
342
- allow_nil_does_not_match?
364
+ allow_nil_does_not_match? ||
365
+ allow_blank_does_not_match?
343
366
  end
344
367
 
345
368
  private
@@ -376,6 +399,7 @@ module Shoulda
376
399
  def disallows_lower_length?
377
400
  !@options.key?(:minimum) ||
378
401
  @options[:minimum] == 0 ||
402
+ (@options[:minimum] == 1 && expects_to_allow_blank?) ||
379
403
  disallows_length_of?(
380
404
  @options[:minimum] - 1,
381
405
  translated_short_message
@@ -204,6 +204,33 @@ module Shoulda
204
204
  # is_greater_than(21)
205
205
  # end
206
206
  #
207
+ # ##### is_other_than
208
+ #
209
+ # Use `is_other_than` to test usage of the `:other_than` option.
210
+ # This asserts that the attribute can take a number which is not equal to
211
+ # the given value.
212
+ #
213
+ # class Person
214
+ # include ActiveModel::Model
215
+ # attr_accessor :legal_age
216
+ #
217
+ # validates_numericality_of :legal_age, other_than: 21
218
+ # end
219
+ #
220
+ # # RSpec
221
+ # RSpec.describe Person, type: :model do
222
+ # it do
223
+ # should validate_numericality_of(:legal_age).
224
+ # is_other_than(21)
225
+ # end
226
+ # end
227
+ #
228
+ # # Minitest (Shoulda)
229
+ # class PersonTest < ActiveSupport::TestCase
230
+ # should validate_numericality_of(:legal_age).
231
+ # is_other_than(21)
232
+ # end
233
+ #
207
234
  # ##### even
208
235
  #
209
236
  # Use `even` to test usage of the `:even` option. This asserts that the
@@ -395,6 +422,11 @@ module Shoulda
395
422
  self
396
423
  end
397
424
 
425
+ def is_other_than(value)
426
+ prepare_submatcher(comparison_matcher_for(value, :!=).for(@attribute))
427
+ self
428
+ end
429
+
398
430
  def with_message(message)
399
431
  @expects_custom_validation_message = true
400
432
  @expected_message = message
@@ -3,6 +3,8 @@ module Shoulda
3
3
  module ActiveModel
4
4
  # @private
5
5
  class ValidationMatcher
6
+ autoload :BuildDescription, 'shoulda/matchers/active_model/validation_matcher/build_description'
7
+
6
8
  include Qualifiers::IgnoringInterferenceByWriter
7
9
 
8
10
  def initialize(attribute)
@@ -24,6 +26,11 @@ module Shoulda
24
26
  self
25
27
  end
26
28
 
29
+ def allow_blank
30
+ options[:allow_blank] = true
31
+ self
32
+ end
33
+
27
34
  def strict
28
35
  @expects_strict = true
29
36
  self
@@ -116,8 +123,20 @@ module Shoulda
116
123
  )
117
124
  end
118
125
 
126
+ def allow_blank_matches?
127
+ !expects_to_allow_blank? ||
128
+ blank_values.all? { |value| allows_value_of(value) }
129
+ end
130
+
131
+ def allow_blank_does_not_match?
132
+ expects_to_allow_blank? &&
133
+ blank_values.all? { |value| disallows_value_of(value) }
134
+ end
135
+
119
136
  private
120
137
 
138
+ attr_reader :options
139
+
121
140
  def overall_failure_message
122
141
  Shoulda::Matchers.word_wrap(
123
142
  "Expected #{model.name} to #{description}, but this could not be " +
@@ -161,6 +180,14 @@ module Shoulda
161
180
  @last_submatcher_run = matcher
162
181
  matcher.matches?(subject)
163
182
  end
183
+
184
+ def expects_to_allow_blank?
185
+ options[:allow_blank]
186
+ end
187
+
188
+ def blank_values
189
+ ['', ' ', "\n", "\r", "\t", "\f"]
190
+ end
164
191
  end
165
192
  end
166
193
  end
@@ -1,26 +1,3 @@
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_readonly_attribute_matcher"
18
- require "shoulda/matchers/active_record/have_rich_text_matcher"
19
- require "shoulda/matchers/active_record/have_secure_token_matcher"
20
- require "shoulda/matchers/active_record/serialize_matcher"
21
- require "shoulda/matchers/active_record/accept_nested_attributes_for_matcher"
22
- require "shoulda/matchers/active_record/define_enum_for_matcher"
23
- require "shoulda/matchers/active_record/uniqueness"
24
1
  require "shoulda/matchers/active_record/validate_uniqueness_of_matcher"
25
2
 
26
3
  module Shoulda
@@ -28,6 +5,19 @@ module Shoulda
28
5
  # This module provides matchers that are used to test behavior within
29
6
  # ActiveRecord classes.
30
7
  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'
31
21
  end
32
22
  end
33
23
  end
@@ -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: 'people_tickets'
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('people_tickets')
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('people_tickets')
937
+ # join_table(:people_tickets)
938
938
  # end
939
939
  #
940
940
  # ##### validate
@@ -1144,6 +1144,7 @@ module Shoulda
1144
1144
  @subject = subject
1145
1145
  association_exists? &&
1146
1146
  macro_correct? &&
1147
+ validate_inverse_of_through_association &&
1147
1148
  (polymorphic? || class_exists?) &&
1148
1149
  foreign_key_exists? &&
1149
1150
  primary_key_exists? &&
@@ -1198,7 +1199,14 @@ module Shoulda
1198
1199
  end
1199
1200
 
1200
1201
  def expectation
1201
- "#{model_class.name} to have a #{macro} association called #{name}"
1202
+ expectation =
1203
+ "#{model_class.name} to have a #{macro} association called #{name}"
1204
+
1205
+ if through?
1206
+ expectation << " through #{reflector.has_and_belongs_to_many_name}"
1207
+ end
1208
+
1209
+ expectation
1202
1210
  end
1203
1211
 
1204
1212
  def missing_options
@@ -1241,6 +1249,14 @@ module Shoulda
1241
1249
  end
1242
1250
  end
1243
1251
 
1252
+ def validate_inverse_of_through_association
1253
+ reflector.validate_inverse_of_through_association!
1254
+ true
1255
+ rescue ::ActiveRecord::ActiveRecordError => error
1256
+ @missing = error.message
1257
+ false
1258
+ end
1259
+
1244
1260
  def macro_supports_primary_key?
1245
1261
  macro == :belongs_to ||
1246
1262
  ([:has_many, :has_one].include?(macro) && !through?)
@@ -3,6 +3,18 @@ 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'
6
18
  end
7
19
  end
8
20
  end