shoulda-matchers 4.3.0 → 4.4.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.
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