lib/rubocop/cop/rspec/example_wording.rb in rubocop-rspec-1.12.0 vs lib/rubocop/cop/rspec/example_wording.rb in rubocop-rspec-1.13.0

- old
+ new

@@ -1,12 +1,14 @@ # frozen_string_literal: true module RuboCop module Cop module RSpec - # Checks that example descriptions do not start with "should". + # Checks for common mistakes in example descriptions. # + # This cop will correct docstrings that begin with 'should' and 'it'. + # # @see http://betterspecs.org/#should # # The autocorrect is experimental - use with care! It can be configured # with CustomTransform (e.g. have => has) and IgnoredWords (e.g. only). # @@ -16,44 +18,76 @@ # end # # # good # it 'finds nothing' do # end + # + # @example + # # bad + # it 'it does things' do + # end + # + # # good + # it 'does things' do + # end class ExampleWording < Cop - MSG = 'Do not use should when describing your tests.'.freeze + MSG_SHOULD = 'Do not use should when describing your tests.'.freeze + MSG_IT = "Do not repeat 'it' when describing your tests.".freeze - def on_block(node) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/LineLength - method, = *node - _, method_name, *args = *method + SHOULD_PREFIX = 'should'.freeze + IT_PREFIX = 'it '.freeze - return unless method_name.equal?(:it) + def_node_matcher( + :it_description, + '(block (send _ :it $(str $_) ...) ...)' + ) - arguments = args.first.to_a - message = arguments.first.to_s - return unless message.downcase.start_with?('should') + def on_block(node) + it_description(node) do |description_node, message| + text = message.downcase - arg1 = args.first.loc.expression - message = Parser::Source::Range.new(arg1.source_buffer, - arg1.begin_pos + 1, - arg1.end_pos - 1) - - add_offense(message, message) + if text.start_with?(SHOULD_PREFIX) + add_wording_offense(description_node, MSG_SHOULD) + elsif text.start_with?(IT_PREFIX) + add_wording_offense(description_node, MSG_IT) + end + end end def autocorrect(range) lambda do |corrector| - corrector.replace( - range, - RuboCop::RSpec::Wording.new( - range.source, - ignore: ignored_words, - replace: custom_transform - ).rewrite - ) + corrector.replace(range, replacement_text(range)) end end private + + def add_wording_offense(node, message) + expr = node.loc.expression + + docstring = + Parser::Source::Range.new( + expr.source_buffer, + expr.begin_pos + 1, + expr.end_pos - 1 + ) + + add_offense(docstring, docstring, message) + end + + def replacement_text(range) + text = range.source + + if text.start_with?('should') + RuboCop::RSpec::Wording.new( + text, + ignore: ignored_words, + replace: custom_transform + ).rewrite + elsif text.start_with?(IT_PREFIX) + text.sub(IT_PREFIX, '') + end + end def custom_transform cop_config.fetch('CustomTransform', {}) end