shoulda-matchers 4.4.1 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/LICENSE +22 -0
 - data/README.md +7 -9
 - data/lib/shoulda/matchers/action_controller/callback_matcher.rb +4 -2
 - data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +3 -2
 - data/lib/shoulda/matchers/action_controller/permit_matcher.rb +26 -21
 - data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +6 -8
 - data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +6 -8
 - data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +16 -13
 - data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +2 -1
 - data/lib/shoulda/matchers/action_controller/route_matcher.rb +5 -6
 - data/lib/shoulda/matchers/action_controller/route_params.rb +1 -1
 - data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +19 -13
 - data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +18 -16
 - data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +29 -27
 - data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +1 -1
 - data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +5 -5
 - data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +2 -2
 - data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +1 -1
 - data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +1 -1
 - data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +1 -1
 - data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +51 -25
 - data/lib/shoulda/matchers/active_model/helpers.rb +1 -1
 - data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +32 -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 +9 -1
 - data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +2 -2
 - data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +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 +39 -26
 - data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +2 -2
 - data/lib/shoulda/matchers/active_model/validation_matcher.rb +6 -6
 - data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +2 -4
 - data/lib/shoulda/matchers/active_model/validation_message_finder.rb +2 -4
 - data/lib/shoulda/matchers/active_model/validator.rb +3 -3
 - data/lib/shoulda/matchers/active_record.rb +26 -26
 - data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +6 -3
 - data/lib/shoulda/matchers/active_record/association_matcher.rb +80 -40
 - 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 +3 -3
 - data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +3 -2
 - data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +7 -5
 - data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +8 -8
 - data/lib/shoulda/matchers/active_record/have_attached_matcher.rb +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 +1 -1
 - data/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +1 -3
 - data/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +0 -2
 - data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +78 -71
 - data/lib/shoulda/matchers/doublespeak.rb +2 -1
 - data/lib/shoulda/matchers/doublespeak/double.rb +1 -1
 - data/lib/shoulda/matchers/doublespeak/double_collection.rb +3 -3
 - data/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +8 -5
 - data/lib/shoulda/matchers/doublespeak/object_double.rb +1 -1
 - data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +1 -5
 - data/lib/shoulda/matchers/doublespeak/world.rb +2 -2
 - data/lib/shoulda/matchers/error.rb +1 -1
 - data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +14 -13
 - data/lib/shoulda/matchers/integrations/configuration.rb +1 -1
 - data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +1 -1
 - data/lib/shoulda/matchers/integrations/libraries/rails.rb +2 -2
 - data/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +1 -1
 - data/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +1 -1
 - data/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +1 -1
 - data/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +1 -1
 - data/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +1 -1
 - data/lib/shoulda/matchers/rails_shim.rb +5 -3
 - data/lib/shoulda/matchers/util.rb +7 -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 +10 -7
 - metadata +11 -10
 
| 
         @@ -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 RailsShim.tables_and_views(connection). 
     | 
| 
      
 45 
     | 
    
         
            +
                        if RailsShim.tables_and_views(connection).
         
     | 
| 
      
 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 
     | 
    
         | 
| 
         @@ -26,12 +26,7 @@ module Shoulda 
     | 
|
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                      def join_table_name
         
     | 
| 
       28 
28 
     | 
    
         
             
                        join_table_name =
         
     | 
| 
       29 
     | 
    
         
            -
                           
     | 
| 
       30 
     | 
    
         
            -
                            has_and_belongs_to_many_name_table_name
         
     | 
| 
       31 
     | 
    
         
            -
                          else
         
     | 
| 
       32 
     | 
    
         
            -
                            reflection.join_table
         
     | 
| 
       33 
     | 
    
         
            -
                          end
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
      
 29 
     | 
    
         
            +
                          has_and_belongs_to_many_name_table_name || reflection.join_table
         
     | 
| 
       35 
30 
     | 
    
         
             
                        join_table_name.to_s
         
     | 
| 
       36 
31 
     | 
    
         
             
                      end
         
     | 
| 
       37 
32 
     | 
    
         | 
| 
         @@ -82,9 +77,7 @@ module Shoulda 
     | 
|
| 
       82 
77 
     | 
    
         
             
                      private
         
     | 
| 
       83 
78 
     | 
    
         | 
| 
       84 
79 
     | 
    
         
             
                      def has_and_belongs_to_many_name_table_name
         
     | 
| 
       85 
     | 
    
         
            -
                         
     | 
| 
       86 
     | 
    
         
            -
                          has_and_belongs_to_many_reflection.table_name
         
     | 
| 
       87 
     | 
    
         
            -
                        end
         
     | 
| 
      
 80 
     | 
    
         
            +
                        has_and_belongs_to_many_reflection&.table_name
         
     | 
| 
       88 
81 
     | 
    
         
             
                      end
         
     | 
| 
       89 
82 
     | 
    
         | 
| 
       90 
83 
     | 
    
         
             
                      def has_and_belongs_to_many_reflection
         
     | 
| 
         @@ -12,13 +12,13 @@ module Shoulda 
     | 
|
| 
       12 
12 
     | 
    
         
             
                        :join_table_name,
         
     | 
| 
       13 
13 
     | 
    
         
             
                        :polymorphic?,
         
     | 
| 
       14 
14 
     | 
    
         
             
                        :validate_inverse_of_through_association!,
         
     | 
| 
       15 
     | 
    
         
            -
                        to: :reflection
         
     | 
| 
      
 15 
     | 
    
         
            +
                        to: :reflection,
         
     | 
| 
       16 
16 
     | 
    
         
             
                      )
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
                      delegate(
         
     | 
| 
       19 
19 
     | 
    
         
             
                        :through?,
         
     | 
| 
       20 
20 
     | 
    
         
             
                        to: :reflection,
         
     | 
| 
       21 
     | 
    
         
            -
                        allow_nil: true
         
     | 
| 
      
 21 
     | 
    
         
            +
                        allow_nil: true,
         
     | 
| 
       22 
22 
     | 
    
         
             
                      )
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
                      def initialize(subject, name)
         
     | 
| 
         @@ -31,7 +31,7 @@ module Shoulda 
     | 
|
| 
       31 
31 
     | 
    
         
             
                      end
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
                      def reflection
         
     | 
| 
       34 
     | 
    
         
            -
                        @ 
     | 
| 
      
 34 
     | 
    
         
            +
                        @_reflection ||= reflect_on_association(name)
         
     | 
| 
       35 
35 
     | 
    
         
             
                      end
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
                      def reflect_on_association(name)
         
     | 
| 
         @@ -48,9 +48,12 @@ module Shoulda 
     | 
|
| 
       48 
48 
     | 
    
         | 
| 
       49 
49 
     | 
    
         
             
                      def build_relation_with_clause(name, value)
         
     | 
| 
       50 
50 
     | 
    
         
             
                        case name
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                           
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
      
 51 
     | 
    
         
            +
                        when :conditions
         
     | 
| 
      
 52 
     | 
    
         
            +
                          associated_class.where(value)
         
     | 
| 
      
 53 
     | 
    
         
            +
                        when :order
         
     | 
| 
      
 54 
     | 
    
         
            +
                          associated_class.order(value)
         
     | 
| 
      
 55 
     | 
    
         
            +
                        else
         
     | 
| 
      
 56 
     | 
    
         
            +
                          raise ArgumentError, "Unknown clause '#{name}'"
         
     | 
| 
       54 
57 
     | 
    
         
             
                        end
         
     | 
| 
       55 
58 
     | 
    
         
             
                      end
         
     | 
| 
       56 
59 
     | 
    
         | 
| 
         @@ -59,7 +62,9 @@ module Shoulda 
     | 
|
| 
       59 
62 
     | 
    
         
             
                        when :conditions
         
     | 
| 
       60 
63 
     | 
    
         
             
                          relation.where_values_hash
         
     | 
| 
       61 
64 
     | 
    
         
             
                        when :order
         
     | 
| 
       62 
     | 
    
         
            -
                          relation.order_values.map  
     | 
| 
      
 65 
     | 
    
         
            +
                          relation.order_values.map do |value|
         
     | 
| 
      
 66 
     | 
    
         
            +
                            value_as_sql(value)
         
     | 
| 
      
 67 
     | 
    
         
            +
                          end.join(', ')
         
     | 
| 
       63 
68 
     | 
    
         
             
                        else
         
     | 
| 
       64 
69 
     | 
    
         
             
                          raise ArgumentError, "Unknown clause '#{name}'"
         
     | 
| 
       65 
70 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -6,7 +6,12 @@ module Shoulda 
     | 
|
| 
       6 
6 
     | 
    
         
             
                    class OptionVerifier
         
     | 
| 
       7 
7 
     | 
    
         
             
                      delegate :reflection, to: :reflector
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                       
     | 
| 
      
 9 
     | 
    
         
            +
                      DEFAULT_VALUE_OF_OPTIONS = {
         
     | 
| 
      
 10 
     | 
    
         
            +
                        has_many: {
         
     | 
| 
      
 11 
     | 
    
         
            +
                          validate: true,
         
     | 
| 
      
 12 
     | 
    
         
            +
                        },
         
     | 
| 
      
 13 
     | 
    
         
            +
                      }.freeze
         
     | 
| 
      
 14 
     | 
    
         
            +
                      RELATION_OPTIONS = [:conditions, :order].freeze
         
     | 
| 
       10 
15 
     | 
    
         | 
| 
       11 
16 
     | 
    
         
             
                      def initialize(reflector)
         
     | 
| 
       12 
17 
     | 
    
         
             
                        @reflector = reflector
         
     | 
| 
         @@ -40,7 +45,7 @@ module Shoulda 
     | 
|
| 
       40 
45 
     | 
    
         
             
                        else
         
     | 
| 
       41 
46 
     | 
    
         
             
                          type_cast_expected_value = type_cast(
         
     | 
| 
       42 
47 
     | 
    
         
             
                            type,
         
     | 
| 
       43 
     | 
    
         
            -
                            expected_value_for(type, name, expected_value)
         
     | 
| 
      
 48 
     | 
    
         
            +
                            expected_value_for(type, name, expected_value),
         
     | 
| 
       44 
49 
     | 
    
         
             
                          )
         
     | 
| 
       45 
50 
     | 
    
         
             
                          actual_value = type_cast(type, actual_value_for(name))
         
     | 
| 
       46 
51 
     | 
    
         
             
                          type_cast_expected_value == actual_value
         
     | 
| 
         @@ -55,7 +60,7 @@ module Shoulda 
     | 
|
| 
       55 
60 
     | 
    
         
             
                          if respond_to?(method_name, true)
         
     | 
| 
       56 
61 
     | 
    
         
             
                            __send__(method_name)
         
     | 
| 
       57 
62 
     | 
    
         
             
                          else
         
     | 
| 
       58 
     | 
    
         
            -
                             
     | 
| 
      
 63 
     | 
    
         
            +
                            actual_value_for_option(name)
         
     | 
| 
       59 
64 
     | 
    
         
             
                          end
         
     | 
| 
       60 
65 
     | 
    
         
             
                        end
         
     | 
| 
       61 
66 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -94,7 +99,7 @@ module Shoulda 
     | 
|
| 
       94 
99 
     | 
    
         | 
| 
       95 
100 
     | 
    
         
             
                      def expected_value_for_constant(name)
         
     | 
| 
       96 
101 
     | 
    
         
             
                        namespace = Shoulda::Matchers::Util.deconstantize(
         
     | 
| 
       97 
     | 
    
         
            -
                          reflector.model_class.to_s
         
     | 
| 
      
 102 
     | 
    
         
            +
                          reflector.model_class.to_s,
         
     | 
| 
       98 
103 
     | 
    
         
             
                        )
         
     | 
| 
       99 
104 
     | 
    
         | 
| 
       100 
105 
     | 
    
         
             
                        ["#{namespace}::#{name}", name].each do |path|
         
     | 
| 
         @@ -107,12 +112,25 @@ module Shoulda 
     | 
|
| 
       107 
112 
     | 
    
         
             
                      end
         
     | 
| 
       108 
113 
     | 
    
         | 
| 
       109 
114 
     | 
    
         
             
                      def actual_value_for_relation_clause(name)
         
     | 
| 
       110 
     | 
    
         
            -
                        reflector.extract_relation_clause_from( 
     | 
| 
      
 115 
     | 
    
         
            +
                        reflector.extract_relation_clause_from(
         
     | 
| 
      
 116 
     | 
    
         
            +
                          reflector.association_relation,
         
     | 
| 
      
 117 
     | 
    
         
            +
                          name,
         
     | 
| 
      
 118 
     | 
    
         
            +
                        )
         
     | 
| 
       111 
119 
     | 
    
         
             
                      end
         
     | 
| 
       112 
120 
     | 
    
         | 
| 
       113 
121 
     | 
    
         
             
                      def actual_value_for_class_name
         
     | 
| 
       114 
122 
     | 
    
         
             
                        reflector.associated_class
         
     | 
| 
       115 
123 
     | 
    
         
             
                      end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                      def actual_value_for_option(name)
         
     | 
| 
      
 126 
     | 
    
         
            +
                        option_value = reflection.options[name]
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                        if option_value.nil?
         
     | 
| 
      
 129 
     | 
    
         
            +
                          DEFAULT_VALUE_OF_OPTIONS.dig(reflection.macro, name)
         
     | 
| 
      
 130 
     | 
    
         
            +
                        else
         
     | 
| 
      
 131 
     | 
    
         
            +
                          option_value
         
     | 
| 
      
 132 
     | 
    
         
            +
                        end
         
     | 
| 
      
 133 
     | 
    
         
            +
                      end
         
     | 
| 
       116 
134 
     | 
    
         
             
                    end
         
     | 
| 
       117 
135 
     | 
    
         
             
                  end
         
     | 
| 
       118 
136 
     | 
    
         
             
                end
         
     | 
| 
         @@ -32,9 +32,9 @@ module Shoulda 
     | 
|
| 
       32 
32 
     | 
    
         
             
                            end
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
                          missing_option << (
         
     | 
| 
       35 
     | 
    
         
            -
                            'fail validation if ' 
     | 
| 
       36 
     | 
    
         
            -
                            ":#{attribute_name} is unset; i.e., either the association " 
     | 
| 
       37 
     | 
    
         
            -
                            'should have been defined with `optional: ' 
     | 
| 
      
 35 
     | 
    
         
            +
                            'fail validation if '\
         
     | 
| 
      
 36 
     | 
    
         
            +
                            ":#{attribute_name} is unset; i.e., either the association "\
         
     | 
| 
      
 37 
     | 
    
         
            +
                            'should have been defined with `optional: '\
         
     | 
| 
       38 
38 
     | 
    
         
             
                            "#{optional.inspect}`, or there "
         
     | 
| 
       39 
39 
     | 
    
         
             
                          )
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
         @@ -33,9 +33,9 @@ module Shoulda 
     | 
|
| 
       33 
33 
     | 
    
         
             
                            end
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
35 
     | 
    
         
             
                          missing_option << (
         
     | 
| 
       36 
     | 
    
         
            -
                            'fail validation if ' 
     | 
| 
       37 
     | 
    
         
            -
                            ":#{attribute_name} is unset; i.e., either the association " 
     | 
| 
       38 
     | 
    
         
            -
                            'should have been defined with `required: ' 
     | 
| 
      
 36 
     | 
    
         
            +
                            'fail validation if '\
         
     | 
| 
      
 37 
     | 
    
         
            +
                            ":#{attribute_name} is unset; i.e., either the association "\
         
     | 
| 
      
 38 
     | 
    
         
            +
                            'should have been defined with `required: '\
         
     | 
| 
       39 
39 
     | 
    
         
             
                            "#{required.inspect}`, or there "
         
     | 
| 
       40 
40 
     | 
    
         
             
                          )
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
         @@ -22,7 +22,8 @@ module Shoulda 
     | 
|
| 
       22 
22 
     | 
    
         
             
                        if option_verifier.correct_for_string?(:source, source)
         
     | 
| 
       23 
23 
     | 
    
         
             
                          true
         
     | 
| 
       24 
24 
     | 
    
         
             
                        else
         
     | 
| 
       25 
     | 
    
         
            -
                          self.missing_option = 
     | 
| 
      
 25 
     | 
    
         
            +
                          self.missing_option =
         
     | 
| 
      
 26 
     | 
    
         
            +
                            "#{name} should have #{source} as source option"
         
     | 
| 
       26 
27 
     | 
    
         
             
                          false
         
     | 
| 
       27 
28 
     | 
    
         
             
                        end
         
     | 
| 
       28 
29 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -32,7 +33,7 @@ module Shoulda 
     | 
|
| 
       32 
33 
     | 
    
         
             
                      attr_accessor :subject, :source, :name
         
     | 
| 
       33 
34 
     | 
    
         | 
| 
       34 
35 
     | 
    
         
             
                      def option_verifier
         
     | 
| 
       35 
     | 
    
         
            -
                        @ 
     | 
| 
      
 36 
     | 
    
         
            +
                        @_option_verifier ||= OptionVerifier.new(subject)
         
     | 
| 
       36 
37 
     | 
    
         
             
                      end
         
     | 
| 
       37 
38 
     | 
    
         
             
                    end
         
     | 
| 
       38 
39 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -29,13 +29,14 @@ module Shoulda 
     | 
|
| 
       29 
29 
     | 
    
         
             
                        if through_reflection.present?
         
     | 
| 
       30 
30 
     | 
    
         
             
                          true
         
     | 
| 
       31 
31 
     | 
    
         
             
                        else
         
     | 
| 
       32 
     | 
    
         
            -
                          self.missing_option = 
     | 
| 
      
 32 
     | 
    
         
            +
                          self.missing_option =
         
     | 
| 
      
 33 
     | 
    
         
            +
                            "#{name} does not have any relationship to #{through}"
         
     | 
| 
       33 
34 
     | 
    
         
             
                          false
         
     | 
| 
       34 
35 
     | 
    
         
             
                        end
         
     | 
| 
       35 
36 
     | 
    
         
             
                      end
         
     | 
| 
       36 
37 
     | 
    
         | 
| 
       37 
38 
     | 
    
         
             
                      def through_reflection
         
     | 
| 
       38 
     | 
    
         
            -
                        @ 
     | 
| 
      
 39 
     | 
    
         
            +
                        @_through_reflection ||= subject.reflect_on_association(through)
         
     | 
| 
       39 
40 
     | 
    
         
             
                      end
         
     | 
| 
       40 
41 
     | 
    
         | 
| 
       41 
42 
     | 
    
         
             
                      def through_association_correct?
         
     | 
| 
         @@ -43,8 +44,9 @@ module Shoulda 
     | 
|
| 
       43 
44 
     | 
    
         
             
                          true
         
     | 
| 
       44 
45 
     | 
    
         
             
                        else
         
     | 
| 
       45 
46 
     | 
    
         
             
                          self.missing_option =
         
     | 
| 
       46 
     | 
    
         
            -
                            "Expected #{name} to have #{name} through #{through}, " 
     | 
| 
       47 
     | 
    
         
            -
                             
     | 
| 
      
 47 
     | 
    
         
            +
                            "Expected #{name} to have #{name} through #{through}, "\
         
     | 
| 
      
 48 
     | 
    
         
            +
                            'but got it through ' +
         
     | 
| 
      
 49 
     | 
    
         
            +
                            option_verifier.actual_value_for(:through).to_s
         
     | 
| 
       48 
50 
     | 
    
         
             
                          false
         
     | 
| 
       49 
51 
     | 
    
         
             
                        end
         
     | 
| 
       50 
52 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -54,7 +56,7 @@ module Shoulda 
     | 
|
| 
       54 
56 
     | 
    
         
             
                      attr_accessor :through, :name, :subject
         
     | 
| 
       55 
57 
     | 
    
         | 
| 
       56 
58 
     | 
    
         
             
                      def option_verifier
         
     | 
| 
       57 
     | 
    
         
            -
                        @ 
     | 
| 
      
 59 
     | 
    
         
            +
                        @_option_verifier ||= OptionVerifier.new(subject)
         
     | 
| 
       58 
60 
     | 
    
         
             
                      end
         
     | 
| 
       59 
61 
     | 
    
         
             
                    end
         
     | 
| 
       60 
62 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -237,7 +237,7 @@ module Shoulda 
     | 
|
| 
       237 
237 
     | 
    
         
             
                          "Expected #{model} to #{expectation}, but "
         
     | 
| 
       238 
238 
     | 
    
         
             
                        end
         
     | 
| 
       239 
239 
     | 
    
         | 
| 
       240 
     | 
    
         
            -
                      message << failure_message_continuation 
     | 
| 
      
 240 
     | 
    
         
            +
                      message << "#{failure_message_continuation}."
         
     | 
| 
       241 
241 
     | 
    
         | 
| 
       242 
242 
     | 
    
         
             
                      Shoulda::Matchers.word_wrap(message)
         
     | 
| 
       243 
243 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -252,7 +252,7 @@ module Shoulda 
     | 
|
| 
       252 
252 
     | 
    
         
             
                    attr_reader :attribute_name, :options, :record,
         
     | 
| 
       253 
253 
     | 
    
         
             
                      :failure_message_continuation
         
     | 
| 
       254 
254 
     | 
    
         | 
| 
       255 
     | 
    
         
            -
                    def expectation
         
     | 
| 
      
 255 
     | 
    
         
            +
                    def expectation # rubocop:disable Metrics/MethodLength
         
     | 
| 
       256 
256 
     | 
    
         
             
                      if enum_defined?
         
     | 
| 
       257 
257 
     | 
    
         
             
                        expectation = "#{simple_description} backed by "
         
     | 
| 
       258 
258 
     | 
    
         
             
                        expectation << Shoulda::Matchers::Util.a_or_an(expected_column_type)
         
     | 
| 
         @@ -358,8 +358,8 @@ module Shoulda 
     | 
|
| 
       358 
358 
     | 
    
         
             
                        true
         
     | 
| 
       359 
359 
     | 
    
         
             
                      else
         
     | 
| 
       360 
360 
     | 
    
         
             
                        @failure_message_continuation =
         
     | 
| 
       361 
     | 
    
         
            -
                          "However, #{attribute_name.inspect} is " 
     | 
| 
       362 
     | 
    
         
            -
                          Shoulda::Matchers::Util.a_or_an(column.type) 
     | 
| 
      
 361 
     | 
    
         
            +
                          "However, #{attribute_name.inspect} is "\
         
     | 
| 
      
 362 
     | 
    
         
            +
                          "#{Shoulda::Matchers::Util.a_or_an(column.type)}"\
         
     | 
| 
       363 
363 
     | 
    
         
             
                          ' column'
         
     | 
| 
       364 
364 
     | 
    
         
             
                        false
         
     | 
| 
       365 
365 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -421,9 +421,9 @@ module Shoulda 
     | 
|
| 
       421 
421 
     | 
    
         
             
                    def expected_prefix
         
     | 
| 
       422 
422 
     | 
    
         
             
                      if options.include?(:prefix)
         
     | 
| 
       423 
423 
     | 
    
         
             
                        if options[:prefix] == true
         
     | 
| 
       424 
     | 
    
         
            -
                          attribute_name 
     | 
| 
      
 424 
     | 
    
         
            +
                          attribute_name
         
     | 
| 
       425 
425 
     | 
    
         
             
                        else
         
     | 
| 
       426 
     | 
    
         
            -
                          options[:prefix] 
     | 
| 
      
 426 
     | 
    
         
            +
                          options[:prefix]
         
     | 
| 
       427 
427 
     | 
    
         
             
                        end
         
     | 
| 
       428 
428 
     | 
    
         
             
                      end
         
     | 
| 
       429 
429 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -431,9 +431,9 @@ module Shoulda 
     | 
|
| 
       431 
431 
     | 
    
         
             
                    def expected_suffix
         
     | 
| 
       432 
432 
     | 
    
         
             
                      if options.include?(:suffix)
         
     | 
| 
       433 
433 
     | 
    
         
             
                        if options[:suffix] == true
         
     | 
| 
       434 
     | 
    
         
            -
                          attribute_name 
     | 
| 
      
 434 
     | 
    
         
            +
                          attribute_name
         
     | 
| 
       435 
435 
     | 
    
         
             
                        else
         
     | 
| 
       436 
     | 
    
         
            -
                          options[:suffix] 
     | 
| 
      
 436 
     | 
    
         
            +
                          options[:suffix]
         
     | 
| 
       437 
437 
     | 
    
         
             
                        end
         
     | 
| 
       438 
438 
     | 
    
         
             
                      end
         
     | 
| 
       439 
439 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -1,10 +1,52 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Shoulda
         
     | 
| 
       2 
2 
     | 
    
         
             
              module Matchers
         
     | 
| 
       3 
3 
     | 
    
         
             
                module ActiveRecord
         
     | 
| 
      
 4 
     | 
    
         
            +
                  # The `have_one_attached` matcher tests usage of the
         
     | 
| 
      
 5 
     | 
    
         
            +
                  # `has_one_attached` macro.
         
     | 
| 
      
 6 
     | 
    
         
            +
                  #
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # #### Example
         
     | 
| 
      
 8 
     | 
    
         
            +
                  #
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #     class User < ApplicationRecord
         
     | 
| 
      
 10 
     | 
    
         
            +
                  #       has_one_attached :avatar
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #     # RSpec
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #     RSpec.describe User, type: :model do
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #       it { should have_one_attached(:avatar) }
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #     # Minitest (Shoulda)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  #     class UserTest < ActiveSupport::TestCase
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #       should have_one_attached(:avatar)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # @return [HaveAttachedMatcher]
         
     | 
| 
      
 24 
     | 
    
         
            +
                  #
         
     | 
| 
       4 
25 
     | 
    
         
             
                  def have_one_attached(name)
         
     | 
| 
       5 
26 
     | 
    
         
             
                    HaveAttachedMatcher.new(:one, name)
         
     | 
| 
       6 
27 
     | 
    
         
             
                  end
         
     | 
| 
       7 
28 
     | 
    
         | 
| 
      
 29 
     | 
    
         
            +
                  # The `have_many_attached` matcher tests usage of the
         
     | 
| 
      
 30 
     | 
    
         
            +
                  # `has_many_attached` macro.
         
     | 
| 
      
 31 
     | 
    
         
            +
                  #
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # #### Example
         
     | 
| 
      
 33 
     | 
    
         
            +
                  #
         
     | 
| 
      
 34 
     | 
    
         
            +
                  #     class Message < ApplicationRecord
         
     | 
| 
      
 35 
     | 
    
         
            +
                  #       has_many_attached :images
         
     | 
| 
      
 36 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 37 
     | 
    
         
            +
                  #
         
     | 
| 
      
 38 
     | 
    
         
            +
                  #     # RSpec
         
     | 
| 
      
 39 
     | 
    
         
            +
                  #     RSpec.describe Message, type: :model do
         
     | 
| 
      
 40 
     | 
    
         
            +
                  #       it { should have_many_attached(:images) }
         
     | 
| 
      
 41 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  #
         
     | 
| 
      
 43 
     | 
    
         
            +
                  #     # Minitest (Shoulda)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  #     class MessageTest < ActiveSupport::TestCase
         
     | 
| 
      
 45 
     | 
    
         
            +
                  #       should have_many_attached(:images)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 47 
     | 
    
         
            +
                  #
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # @return [HaveAttachedMatcher]
         
     | 
| 
      
 49 
     | 
    
         
            +
                  #
         
     | 
| 
       8 
50 
     | 
    
         
             
                  def have_many_attached(name)
         
     | 
| 
       9 
51 
     | 
    
         
             
                    HaveAttachedMatcher.new(:many, name)
         
     | 
| 
       10 
52 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -92,10 +134,8 @@ Did not expect #{expectation}, but it does. 
     | 
|
| 
       92 
134 
     | 
    
         | 
| 
       93 
135 
     | 
    
         
             
                    def attachments_association_name
         
     | 
| 
       94 
136 
     | 
    
         
             
                      case macro
         
     | 
| 
       95 
     | 
    
         
            -
                      when :one then
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
                      when :many then
         
     | 
| 
       98 
     | 
    
         
            -
                        "#{name}_attachments"
         
     | 
| 
      
 137 
     | 
    
         
            +
                      when :one then "#{name}_attachment"
         
     | 
| 
      
 138 
     | 
    
         
            +
                      when :many then "#{name}_attachments"
         
     | 
| 
       99 
139 
     | 
    
         
             
                      end
         
     | 
| 
       100 
140 
     | 
    
         
             
                    end
         
     | 
| 
       101 
141 
     | 
    
         | 
| 
         @@ -121,10 +161,8 @@ Did not expect #{expectation}, but it does. 
     | 
|
| 
       121 
161 
     | 
    
         | 
| 
       122 
162 
     | 
    
         
             
                    def blobs_association_name
         
     | 
| 
       123 
163 
     | 
    
         
             
                      case macro
         
     | 
| 
       124 
     | 
    
         
            -
                      when :one then
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
                      when :many then
         
     | 
| 
       127 
     | 
    
         
            -
                        "#{name}_blobs"
         
     | 
| 
      
 164 
     | 
    
         
            +
                      when :one then "#{name}_blob"
         
     | 
| 
      
 165 
     | 
    
         
            +
                      when :many then "#{name}_blobs"
         
     | 
| 
       128 
166 
     | 
    
         
             
                      end
         
     | 
| 
       129 
167 
     | 
    
         
             
                    end
         
     | 
| 
       130 
168 
     | 
    
         |