Skip to content

Commit

Permalink
All built-in matchers implement expects_call_stack_jump?.
Browse files Browse the repository at this point in the history
Given the fact that our compound matcher logic calls this
(with `rescue NoMethodError`) rather than using a `respond_to?`
check, it’ll perform better to always define it.

This also changes several matcher to subclass `BaseMatcher`,
as that provides the default implementation of this new method.
It’s simpler than defining the method in the same way on all
these matchers.
  • Loading branch information
myronmarston committed Jun 22, 2014
1 parent 5cc8b66 commit d04879f
Show file tree
Hide file tree
Showing 9 changed files with 21 additions and 47 deletions.
5 changes: 5 additions & 0 deletions lib/rspec/matchers/built_in/base_matcher.rb
Expand Up @@ -95,6 +95,11 @@ def supports_block_expectations?
false
end

# @api private
def expects_call_stack_jump?
false
end

private

def assert_ivars(*expected_ivars)
Expand Down
9 changes: 1 addition & 8 deletions lib/rspec/matchers/built_in/be_within.rb
Expand Up @@ -4,9 +4,7 @@ module BuiltIn
# @api private
# Provides the implementation for `be_within`.
# Not intended to be instantiated directly.
class BeWithin
include Composable

class BeWithin < BaseMatcher
def initialize(delta)
@delta = delta
end
Expand Down Expand Up @@ -55,11 +53,6 @@ def description
"be within #{@delta}#{@unit} of #{@expected}"
end

# @private
def supports_block_expectations?
false
end

private

def numeric?
Expand Down
11 changes: 3 additions & 8 deletions lib/rspec/matchers/built_in/change.rb
Expand Up @@ -4,9 +4,7 @@ module BuiltIn
# @api private
# Provides the implementation for `change`.
# Not intended to be instantiated directly.
class Change
include Composable

class Change < BaseMatcher
# @api public
# Specifies the delta of the expected change.
def by(expected_delta)
Expand Down Expand Up @@ -104,9 +102,7 @@ def negative_failure_reason

# Used to specify a relative change.
# @api private
class ChangeRelatively
include Composable

class ChangeRelatively < BaseMatcher
def initialize(change_details, expected_delta, relativity, &comparer)
@change_details = change_details
@expected_delta = expected_delta
Expand Down Expand Up @@ -152,8 +148,7 @@ def failure_reason

# @api private
# Base class for specifying a change from and/or to specific values.
class SpecificValuesChange
include Composable
class SpecificValuesChange < BaseMatcher
# @private
MATCH_ANYTHING = ::Object.ancestors.last

Expand Down
9 changes: 1 addition & 8 deletions lib/rspec/matchers/built_in/has.rb
Expand Up @@ -4,9 +4,7 @@ module BuiltIn
# @api private
# Provides the implementation for `has_<predicate>`.
# Not intended to be instantiated directly.
class Has
include Composable

class Has < BaseMatcher
def initialize(method_name, *args, &block)
@method_name, @args, @block = method_name, args, block
end
Expand Down Expand Up @@ -43,11 +41,6 @@ def description
[method_description, args_description].compact.join(' ')
end

# @private
def supports_block_expectations?
false
end

private

def predicate_accessible?
Expand Down
9 changes: 1 addition & 8 deletions lib/rspec/matchers/built_in/respond_to.rb
Expand Up @@ -6,9 +6,7 @@ module BuiltIn
# @api private
# Provides the implementation for `respond_to`.
# Not intended to be instantiated directly.
class RespondTo
include Composable

class RespondTo < BaseMatcher
def initialize(*names)
@names = names
@expected_arity = nil
Expand Down Expand Up @@ -62,11 +60,6 @@ def description
"respond to #{pp_names}#{with_arity}"
end

# @private
def supports_block_expectations?
false
end

private

def find_failing_method_names(actual, filter_method)
Expand Down
9 changes: 1 addition & 8 deletions lib/rspec/matchers/built_in/satisfy.rb
Expand Up @@ -4,9 +4,7 @@ module BuiltIn
# @api private
# Provides the implementation for `satisfy`.
# Not intended to be instantiated directly.
class Satisfy
include Composable

class Satisfy < BaseMatcher
def initialize(&block)
@block = block
end
Expand Down Expand Up @@ -35,11 +33,6 @@ def failure_message_when_negated
def description
"satisfy block"
end

# @private
def supports_block_expectations?
false
end
end
end
end
Expand Down
8 changes: 2 additions & 6 deletions lib/rspec/matchers/built_in/yield.rb
Expand Up @@ -255,9 +255,7 @@ def negative_failure_reason
# @api private
# Provides the implementation for `yield_with_args`.
# Not intended to be instantiated directly.
class YieldWithArgs
include Composable

class YieldWithArgs < BaseMatcher
def initialize(*args)
@expected = args
end
Expand Down Expand Up @@ -344,9 +342,7 @@ def all_args_match?
# @api private
# Provides the implementation for `yield_successive_args`.
# Not intended to be instantiated directly.
class YieldSuccessiveArgs
include Composable

class YieldSuccessiveArgs < BaseMatcher
def initialize(*args)
@expected = args
end
Expand Down
5 changes: 5 additions & 0 deletions lib/rspec/matchers/dsl.rb
Expand Up @@ -267,6 +267,11 @@ def failure_message_when_negated
def supports_block_expectations?
false
end

# Most matchers do not expect call stack jumps.
def expects_call_stack_jump?
false
end
end

# The class used for custom matchers. The block passed to
Expand Down
3 changes: 2 additions & 1 deletion spec/support/shared_examples.rb
Expand Up @@ -58,7 +58,8 @@
:matches?,
:failure_message,
:description,
:supports_block_expectations?
:supports_block_expectations?,
:expects_call_stack_jump?
)

# We do not require failure_message_when_negated and does_not_match?
Expand Down

0 comments on commit d04879f

Please sign in to comment.