module RuboCop::Cop::RSpec::ExplicitHelper
def allowed_explicit_matchers
def allowed_explicit_matchers cop_config.fetch('AllowedExplicitMatchers', []) + BUILT_IN_MATCHERS end
def autocorrect_explicit(node)
def autocorrect_explicit(node) autocorrect_explicit_send(node) || autocorrect_explicit_block(node) end
def autocorrect_explicit_block(node)
def autocorrect_explicit_block(node) predicate_matcher_block?(node) do |actual, matcher| to_node = node.send_node corrector_explicit(to_node, actual, matcher, to_node) end end
def autocorrect_explicit_send(node)
def autocorrect_explicit_send(node) predicate_matcher?(node) do |actual, matcher| corrector_explicit(node, actual, matcher, matcher) end 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) ) 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) ) end end
def corrector_explicit(to_node, actual, matcher, block_child)
def corrector_explicit(to_node, actual, matcher, block_child) lambda do |corrector| 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 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_name == :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', 'respond_to' matcher + '?' when /^have_(.+)/ "has_#{Regexp.last_match(1)}?" else matcher[/^be_(.+)/, 1] + '?' end end