This file is indexed.

/usr/lib/ruby/vendor_ruby/rspec/mocks/argument_list_matcher.rb is in ruby-rspec-mocks 3.4.0c3e0m1s1-1ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
# We intentionally do not use the `RSpec::Support.require...` methods
# here so that this file can be loaded individually, as documented
# below.
require 'rspec/mocks/argument_matchers'
require 'rspec/support/fuzzy_matcher'

module RSpec
  module Mocks
    # Wrapper for matching arguments against a list of expected values. Used by
    # the `with` method on a `MessageExpectation`:
    #
    #     expect(object).to receive(:message).with(:a, 'b', 3)
    #     object.message(:a, 'b', 3)
    #
    # Values passed to `with` can be literal values or argument matchers that
    # match against the real objects .e.g.
    #
    #     expect(object).to receive(:message).with(hash_including(:a => 'b'))
    #
    # Can also be used directly to match the contents of any `Array`. This
    # enables 3rd party mocking libs to take advantage of rspec's argument
    # matching without using the rest of rspec-mocks.
    #
    #     require 'rspec/mocks/argument_list_matcher'
    #     include RSpec::Mocks::ArgumentMatchers
    #
    #     arg_list_matcher = RSpec::Mocks::ArgumentListMatcher.new(123, hash_including(:a => 'b'))
    #     arg_list_matcher.args_match?(123, :a => 'b')
    #
    # This class is immutable.
    #
    # @see ArgumentMatchers
    class ArgumentListMatcher
      # @private
      attr_reader :expected_args

      # @api public
      # @param [Array] expected_args a list of expected literals and/or argument matchers
      #
      # Initializes an `ArgumentListMatcher` with a collection of literal
      # values and/or argument matchers.
      #
      # @see ArgumentMatchers
      # @see #args_match?
      def initialize(*expected_args)
        @expected_args = expected_args
        ensure_expected_args_valid!
      end

      # @api public
      # @param [Array] args
      #
      # Matches each element in the `expected_args` against the element in the same
      # position of the arguments passed to `new`.
      #
      # @see #initialize
      def args_match?(*args)
        Support::FuzzyMatcher.values_match?(resolve_expected_args_based_on(args), args)
      end

      # @private
      # Resolves abstract arg placeholders like `no_args` and `any_args` into
      # a more concrete arg list based on the provided `actual_args`.
      def resolve_expected_args_based_on(actual_args)
        return [] if [ArgumentMatchers::NoArgsMatcher::INSTANCE] == expected_args

        any_args_index = expected_args.index { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a }
        return expected_args unless any_args_index

        replace_any_args_with_splat_of_anything(any_args_index, actual_args.count)
      end

    private

      def replace_any_args_with_splat_of_anything(before_count, actual_args_count)
        any_args_count  = actual_args_count   - expected_args.count + 1
        after_count     = expected_args.count - before_count        - 1

        any_args = 1.upto(any_args_count).map { ArgumentMatchers::AnyArgMatcher::INSTANCE }
        expected_args.first(before_count) + any_args + expected_args.last(after_count)
      end

      def ensure_expected_args_valid!
        if expected_args.count { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a } > 1
          raise ArgumentError, "`any_args` can only be passed to " \
                "`with` once but you have passed it multiple times."
        elsif expected_args.count > 1 && expected_args.any? { |a| ArgumentMatchers::NoArgsMatcher::INSTANCE == a }
          raise ArgumentError, "`no_args` can only be passed as a " \
                "singleton argument to `with` (i.e. `with(no_args)`), " \
                "but you have passed additional arguments."
        end
      end

      # Value that will match all argument lists.
      #
      # @private
      MATCH_ALL = new(ArgumentMatchers::AnyArgsMatcher::INSTANCE)
    end
  end
end