module RuboCop::Cop::RSpec::ExplicitHelper
def allowed_explicit_matchers
def allowed_explicit_matchers cop_config.fetch('AllowedExplicitMatchers', []) + BUILT_IN_MATCHERS end
def check_explicit(node) # rubocop:disable Metrics/MethodLength
def check_explicit(node) # rubocop:disable Metrics/MethodLength predicate_matcher_block?(node) do |actual, matcher| add_offense(node, message: message_explicit(matcher)) do |corrector| to_node = node.send_node corrector_explicit(corrector, to_node, actual, matcher, to_node) end ignore_node(node.children.first) return end return if part_of_ignored_node?(node) predicate_matcher?(node) do |actual, matcher| add_offense(node, message: message_explicit(matcher)) do |corrector| corrector_explicit(corrector, node, actual, matcher, matcher) end end end
def corrector_explicit(corrector, to_node, actual, matcher, block_child)
def corrector_explicit(corrector, to_node, actual, matcher, block_child) replacement_matcher = replacement_matcher(to_node) corrector.replace(matcher.loc.expression, replacement_matcher) move_predicate(corrector, actual, matcher, block_child) corrector.replace(to_node.loc.selector, 'to') end
def message_explicit(matcher)
def message_explicit(matcher) format(MSG_EXPLICIT, predicate_name: to_predicate_method(matcher.method_name), matcher_name: matcher.method_name) end
def move_predicate(corrector, actual, matcher, block_child)
def move_predicate(corrector, actual, matcher, block_child) predicate = to_predicate_method(matcher.method_name) args = args_loc(matcher).source block_loc = block_loc(block_child) block = block_loc ? block_loc.source : '' corrector.remove(block_loc) if block_loc corrector.insert_after(actual.loc.expression, ".#{predicate}" + args + block) end
def predicate_matcher_name?(name)
def predicate_matcher_name?(name) name = name.to_s return false if allowed_explicit_matchers.include?(name) name.start_with?('be_', 'have_') && !name.end_with?('?') end
def replacement_matcher(node)
def replacement_matcher(node) case [cop_config['Strict'], node.method?(:to)] when [true, true] 'be(true)' when [true, false] 'be(false)' when [false, true] 'be_truthy' when [false, false] 'be_falsey' end end
def to_predicate_method(matcher)
def to_predicate_method(matcher) case matcher = matcher.to_s when 'be_a', 'be_an', 'be_a_kind_of', 'a_kind_of', 'be_kind_of' 'is_a?' when 'be_an_instance_of', 'be_instance_of', 'an_instance_of' 'instance_of?' when 'include' 'include?' when 'respond_to' 'respond_to?' when /^have_(.+)/ "has_#{Regexp.last_match(1)}?" else "#{matcher[/^be_(.+)/, 1]}?" end end