free_mutant/lib/mutant/matcher/methods.rb

140 lines
2.9 KiB
Ruby
Raw Normal View History

module Mutant
class Matcher
2013-07-28 13:59:25 -04:00
# Abstract base class for matcher that returns method subjects from scope
class Methods < self
include AbstractType, Concord::Public.new(:env, :scope)
# Enumerate subjects
#
# @return [self]
# if block given
#
2013-04-17 23:31:21 -04:00
# @return [Enumerator<Subject>]
# otherwise
#
# @api private
def each(&block)
return to_enum unless block_given?
2012-12-07 17:27:21 -05:00
2014-06-30 08:53:48 -04:00
subjects.each(&block)
self
end
private
# method matcher class
#
# @return [Class:Matcher::Method]
#
# @api private
def matcher
self.class::MATCHER
end
# Available methods scope
#
# @return [Enumerable<Method, UnboundMethod>]
#
# @api private
def methods
candidate_names.each_with_object([]) do |name, methods|
method = access(name)
2014-06-16 06:50:32 -04:00
methods << method if method.owner.equal?(candidate_scope)
end
end
memoize :methods
# Subjects detected on scope
#
2014-06-30 08:53:48 -04:00
# @return [Array<Subject>]
2013-04-27 09:52:49 -04:00
#
# @api private
2014-06-30 08:53:48 -04:00
def subjects
methods.map do |method|
matcher.build(env, scope, method)
2014-06-30 08:53:48 -04:00
end.flat_map(&:to_a)
2013-04-27 09:52:49 -04:00
end
2014-06-30 08:53:48 -04:00
memoize :subjects
2013-04-27 09:52:49 -04:00
# Candidate method names on target scope
2013-04-27 09:52:49 -04:00
#
2013-04-17 23:31:21 -04:00
# @return [Enumerable<Symbol>]
#
# @api private
def candidate_names
2014-06-30 08:53:48 -04:00
(
2013-06-15 11:14:33 -04:00
candidate_scope.public_instance_methods(false) +
candidate_scope.private_instance_methods(false) +
candidate_scope.protected_instance_methods(false)
2014-06-30 08:53:48 -04:00
).sort
2013-04-27 09:52:49 -04:00
end
# Candidate scope
#
# @return [Class, Module]
#
# @api private
abstract_method :candidate_scope
2013-06-15 11:13:01 -04:00
# Matcher for singleton methods
class Singleton < self
MATCHER = Matcher::Method::Singleton
private
# Method object on scope
2012-12-07 17:27:21 -05:00
#
# @param [Symbol] method_name
#
# @return [Method]
#
# @api private
def access(method_name)
scope.method(method_name)
end
# Candidate scope
#
# @return [Class]
#
# @api private
def candidate_scope
scope.singleton_class
end
memoize :candidate_scope, freezer: :noop
2013-06-14 14:54:02 -04:00
end # Singleton
2013-06-15 11:13:01 -04:00
# Matcher for instance methods
class Instance < self
MATCHER = Matcher::Method::Instance
private
# Method object on scope
2012-12-07 17:27:21 -05:00
#
# @param [Symbol] method_name
#
# @return [UnboundMethod]
#
# @api private
def access(method_name)
scope.instance_method(method_name)
end
# Candidate scope
#
# @return [Class, Module]
2013-06-14 14:54:02 -04:00
#
# @api private
def candidate_scope
scope
end
2013-06-14 14:54:02 -04:00
end # Instance
end # Methods
end # Matcher
end # Mutant