lib/rspec/matchers/built_in/match.rb
module RSpec module Matchers module BuiltIn # @api private # Provides the implementation for `match`. # Not intended to be instantiated directly. class Match < BaseMatcher def initialize(expected) super(expected) @expected_captures = nil end # @api private # @return [String] def description if @expected_captures && @expected.match(actual) "match #{surface_descriptions_in(expected).inspect} with captures #{surface_descriptions_in(@expected_captures).inspect}" else "match #{surface_descriptions_in(expected).inspect}" end end # @api private # @return [Boolean] def diffable? true end # Used to specify the captures we match against # @return [self] def with_captures(*captures) @expected_captures = captures self end private def match(expected, actual) return match_captures(expected, actual) if @expected_captures return true if values_match?(expected, actual) return false unless can_safely_call_match?(expected, actual) actual.match(expected) end def can_safely_call_match?(expected, actual) return false unless actual.respond_to?(:match) !(RSpec::Matchers.is_a_matcher?(expected) && (String === actual || Regexp === actual)) end def match_captures(expected, actual) match = actual.match(expected) if match match = ReliableMatchData.new(match) if match.names.empty? values_match?(@expected_captures, match.captures) else expected_matcher = @expected_captures.last values_match?(expected_matcher, Hash[match.names.zip(match.captures)]) || values_match?(expected_matcher, Hash[match.names.map(&:to_sym).zip(match.captures)]) || values_match?(@expected_captures, match.captures) end else false end end end # @api private # Used to wrap match data and make it reliable for 1.8.7 class ReliableMatchData def initialize(match_data) @match_data = match_data end if RUBY_VERSION == "1.8.7" # @api private # Returns match data names for named captures # @return Array # :nocov: def names [] end # :nocov: else # @api private # Returns match data names for named captures # @return Array def names match_data.names end end # @api private # returns an array of captures from the match data # @return Array def captures match_data.captures end protected attr_reader :match_data end end end end