lib/rubocop/cop/rspec/shared_examples.rb in rubocop-rspec-2.25.0 vs lib/rubocop/cop/rspec/shared_examples.rb in rubocop-rspec-2.26.0

- old
+ new

@@ -1,13 +1,17 @@ # frozen_string_literal: true module RuboCop module Cop module RSpec - # Enforces use of string to titleize shared examples. + # Checks for consistent style for shared example names. # - # @example + # Enforces either `string` or `symbol` for shared example names. + # + # This cop can be configured using the `EnforcedStyle` option + # + # @example `EnforcedStyle: string` (default) # # bad # it_behaves_like :foo_bar_baz # it_should_behave_like :foo_bar_baz # shared_examples :foo_bar_baz # shared_examples_for :foo_bar_baz @@ -18,12 +22,28 @@ # it_should_behave_like 'foo bar baz' # shared_examples 'foo bar baz' # shared_examples_for 'foo bar baz' # include_examples 'foo bar baz' # + # @example `EnforcedStyle: symbol` + # # bad + # it_behaves_like 'foo bar baz' + # it_should_behave_like 'foo bar baz' + # shared_examples 'foo bar baz' + # shared_examples_for 'foo bar baz' + # include_examples 'foo bar baz' + # + # # good + # it_behaves_like :foo_bar_baz + # it_should_behave_like :foo_bar_baz + # shared_examples :foo_bar_baz + # shared_examples_for :foo_bar_baz + # include_examples :foo_bar_baz + # class SharedExamples < Base extend AutoCorrector + include ConfigurableEnforcedStyle # @!method shared_examples(node) def_node_matcher :shared_examples, <<~PATTERN { (send #rspec? #SharedGroups.all ...) @@ -32,46 +52,73 @@ PATTERN def on_send(node) shared_examples(node) do ast_node = node.first_argument - next unless ast_node&.sym_type? + next unless offense?(ast_node) - checker = Checker.new(ast_node) - add_offense(checker.node, message: checker.message) do |corrector| - corrector.replace(checker.node, checker.preferred_style) + checker = new_checker(ast_node) + add_offense(ast_node, message: checker.message) do |corrector| + corrector.replace(ast_node, checker.preferred_style) end end end + private + + def offense?(ast_node) + if style == :symbol + ast_node.str_type? + else # string + ast_node.sym_type? + end + end + + def new_checker(ast_node) + if style == :symbol + SymbolChecker.new(ast_node) + else # string + StringChecker.new(ast_node) + end + end + # :nodoc: - class Checker + class SymbolChecker MSG = 'Prefer %<prefer>s over `%<current>s` ' \ - 'to titleize shared examples.' + 'to symbolize shared examples.' attr_reader :node def initialize(node) @node = node end def message - format(MSG, prefer: preferred_style, current: symbol.inspect) + format(MSG, prefer: preferred_style, current: node.value.inspect) end def preferred_style - string = symbol.to_s.tr('_', ' ') - wrap_with_single_quotes(string) + ":#{node.value.to_s.downcase.tr(' ', '_')}" end + end - private + # :nodoc: + class StringChecker + MSG = 'Prefer %<prefer>s over `%<current>s` ' \ + 'to titleize shared examples.' - def symbol - node.value + attr_reader :node + + def initialize(node) + @node = node end - def wrap_with_single_quotes(string) - "'#{string}'" + def message + format(MSG, prefer: preferred_style, current: node.value.inspect) + end + + def preferred_style + "'#{node.value.to_s.tr('_', ' ')}'" end end end end end