class RSpec::Matchers::BuiltIn::RespondTo
@api private Provides the implementation for `respond_to`. Not intended to be instantiated directly.
Public Class Methods
new(*names)
click to toggle source
# File lib/rspec/matchers/built_in/respond_to.rb, line 12 def initialize(*names) @names = names @expected_arity = nil @expected_keywords = [] @ignoring_method_signature_failure = false @unlimited_arguments = nil @arbitrary_keywords = nil end
Public Instance Methods
argument()
click to toggle source
@api public No-op. Intended to be used as syntactic sugar when using `with`.
@example
expect(obj).to respond_to(:message).with(3).arguments
# File lib/rspec/matchers/built_in/respond_to.rb, line 73 def argument self end
Also aliased as: arguments
description()
click to toggle source
@api private @return [String]
# File lib/rspec/matchers/built_in/respond_to.rb, line 102 def description "respond to #{pp_names}#{with_arity}" end
does_not_match?(actual)
click to toggle source
@private
# File lib/rspec/matchers/built_in/respond_to.rb, line 84 def does_not_match?(actual) find_failing_method_names(actual, :select).empty? end
failure_message()
click to toggle source
@api private @return [String]
# File lib/rspec/matchers/built_in/respond_to.rb, line 90 def failure_message "expected #{actual_formatted} to respond to #{@failing_method_names.map { |name| description_of(name) }.join(', ')}#{with_arity}" end
failure_message_when_negated()
click to toggle source
@api private @return [String]
# File lib/rspec/matchers/built_in/respond_to.rb, line 96 def failure_message_when_negated failure_message.sub(/to respond to/, 'not to respond to') end
ignoring_method_signature_failure!()
click to toggle source
@api private Used by other matchers to suppress a check
# File lib/rspec/matchers/built_in/respond_to.rb, line 108 def ignoring_method_signature_failure! @ignoring_method_signature_failure = true end
matches?(actual)
click to toggle source
@private
# File lib/rspec/matchers/built_in/respond_to.rb, line 79 def matches?(actual) find_failing_method_names(actual, :reject).empty? end
with(n)
click to toggle source
@api public Specifies the number of expected arguments.
@example
expect(obj).to respond_to(:message).with(3).arguments
# File lib/rspec/matchers/built_in/respond_to.rb, line 26 def with(n) @expected_arity = n self end
with_any_keywords()
click to toggle source
@api public Specifies that the method accepts any keyword, i.e. the method has
a splatted keyword parameter of the form **kw_args.
@example
expect(obj).to respond_to(:message).with_any_keywords
# File lib/rspec/matchers/built_in/respond_to.rb, line 50 def with_any_keywords @arbitrary_keywords = true self end
Also aliased as: and_any_keywords
with_keywords(*keywords)
click to toggle source
@api public Specifies keyword arguments, if any.
@example
expect(obj).to respond_to(:message).with_keywords(:color, :shape)
@example with an expected number of arguments
expect(obj).to respond_to(:message).with(3).arguments.and_keywords(:color, :shape)
# File lib/rspec/matchers/built_in/respond_to.rb, line 38 def with_keywords(*keywords) @expected_keywords = keywords self end
Also aliased as: and_keywords
with_unlimited_arguments()
click to toggle source
@api public Specifies that the number of arguments has no upper limit, i.e. the
method has a splatted parameter of the form *args.
@example
expect(obj).to respond_to(:message).with_unlimited_arguments
# File lib/rspec/matchers/built_in/respond_to.rb, line 62 def with_unlimited_arguments @unlimited_arguments = true self end
Also aliased as: and_unlimited_arguments
Private Instance Methods
find_failing_method_names(actual, filter_method)
click to toggle source
# File lib/rspec/matchers/built_in/respond_to.rb, line 114 def find_failing_method_names(actual, filter_method) @actual = actual @failing_method_names = @names.__send__(filter_method) do |name| @actual.respond_to?(name) && matches_arity?(actual, name) end end
matches_arity?(actual, name)
click to toggle source
# File lib/rspec/matchers/built_in/respond_to.rb, line 138 def matches_arity?(actual, name) expectation = setup_method_signature_expectation return true if expectation.empty? begin Support::StrictSignatureVerifier.new(method_signature_for(actual, name)). with_expectation(expectation).valid? rescue NameError return true if @ignoring_method_signature_failure raise ArgumentError, "The #{matcher_name} matcher requires that " \ "the actual object define the method(s) in " \ "order to check arity, but the method " \ "`#{name}` is not defined. Remove the arity " \ "check or define the method to continue." end end
method_signature_for(actual, name)
click to toggle source
# File lib/rspec/matchers/built_in/respond_to.rb, line 156 def method_signature_for(actual, name) method_handle = Support.method_handle_for(actual, name) if name == :new && method_handle.owner === ::Class && ::Class === actual Support::MethodSignature.new(actual.instance_method(:initialize)) else Support::MethodSignature.new(method_handle) end end
pp_names()
click to toggle source
# File lib/rspec/matchers/built_in/respond_to.rb, line 192 def pp_names @names.length == 1 ? "##{@names.first}" : description_of(@names) end
setup_method_signature_expectation()
click to toggle source
# File lib/rspec/matchers/built_in/respond_to.rb, line 121 def setup_method_signature_expectation expectation = Support::MethodSignatureExpectation.new if @expected_arity.is_a?(Range) expectation.min_count = @expected_arity.min expectation.max_count = @expected_arity.max else expectation.min_count = @expected_arity end expectation.keywords = @expected_keywords expectation.expect_unlimited_arguments = @unlimited_arguments expectation.expect_arbitrary_keywords = @arbitrary_keywords expectation end
with_arity()
click to toggle source
# File lib/rspec/matchers/built_in/respond_to.rb, line 166 def with_arity str = ''.dup str << " with #{with_arity_string}" if @expected_arity str << " #{str.length == 0 ? 'with' : 'and'} #{with_keywords_string}" if @expected_keywords && @expected_keywords.count > 0 str << " #{str.length == 0 ? 'with' : 'and'} unlimited arguments" if @unlimited_arguments str << " #{str.length == 0 ? 'with' : 'and'} any keywords" if @arbitrary_keywords str end
with_arity_string()
click to toggle source
# File lib/rspec/matchers/built_in/respond_to.rb, line 175 def with_arity_string "#{@expected_arity} argument#{@expected_arity == 1 ? '' : 's'}" end
with_keywords_string()
click to toggle source
# File lib/rspec/matchers/built_in/respond_to.rb, line 179 def with_keywords_string kw_str = case @expected_keywords.count when 1 @expected_keywords.first.inspect when 2 @expected_keywords.map(&:inspect).join(' and ') else "#{@expected_keywords[0...-1].map(&:inspect).join(', ')}, and #{@expected_keywords.last.inspect}" end "keyword#{@expected_keywords.count == 1 ? '' : 's'} #{kw_str}" end