rubocop-rspec 1.15.0 → 1.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/Rakefile +1 -1
- data/config/default.yml +2 -1
- data/lib/rubocop/cop/rspec/cop.rb +3 -2
- data/lib/rubocop/cop/rspec/describe_method.rb +2 -2
- data/lib/rubocop/cop/rspec/example_wording.rb +7 -11
- data/lib/rubocop/cop/rspec/expect_actual.rb +4 -4
- data/lib/rubocop/cop/rspec/iterated_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/leading_subject.rb +1 -1
- data/lib/rubocop/cop/rspec/message_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/message_spies.rb +1 -1
- data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +23 -3
- data/lib/rubocop/rspec/concept.rb +3 -2
- data/lib/rubocop/rspec/hook.rb +1 -1
- data/lib/rubocop/rspec/language.rb +17 -17
- data/lib/rubocop/rspec/version.rb +1 -1
- data/lib/rubocop/rspec/wording.rb +53 -19
- data/spec/expect_violation/expectation_spec.rb +1 -1
- data/spec/project/default_config_spec.rb +2 -2
- data/spec/rubocop/cop/rspec/cop_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/described_class_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/empty_example_group_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/example_wording_spec.rb +41 -2
- data/spec/rubocop/cop/rspec/iterated_expectation_spec.rb +8 -0
- data/spec/rubocop/cop/rspec/multiple_expectations_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/single_argument_message_chain_spec.rb +39 -0
- data/spec/rubocop/rspec/example_spec.rb +1 -1
- data/spec/rubocop/rspec/language/selector_set_spec.rb +4 -4
- data/spec/rubocop/rspec/wording_spec.rb +14 -8
- data/spec/support/expect_violation.rb +10 -8
- metadata +3 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 6a604474acdd504b70582e29579a8ec65a6bbbfa
         | 
| 4 | 
            +
              data.tar.gz: f8fa3ac1215089b95341115ca35edb73ddb148c3
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: a0d4f97983ce7f1147d32b8948d22d5c7b30490a946e5500e2aa78f60daad47f9e68eac81e6da2825e83f8248a8a8ed4dfd538a30e4b7dcc9af462fee16bda2c
         | 
| 7 | 
            +
              data.tar.gz: dd3bc63ff868cef005a10da71f873dc804d333fd8950de8636d980064341b386a74e281ba698d051859c7c4ddceb7ee257d527ac68c7129fd660f7321014b9ac
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -2,7 +2,13 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            ## Master (Unreleased)
         | 
| 4 4 |  | 
| 5 | 
            -
            ## 1.15. | 
| 5 | 
            +
            ## 1.15.1 (2017-04-30)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * Fix the handling of various edge cases in the `RSpec/ExampleWording` cop, including one that would cause autocorrect to crash. ([@dgollahon][])
         | 
| 8 | 
            +
            * Fix `RSpec/IteratedExpectation` crashing when there is an assignment in the iteration. ([@Darhazer][])
         | 
| 9 | 
            +
            * Fix false positive in `RSpec/SingleArgumentMessageChain` cop when the single argument is a hash. ([@Darhazer][])
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            ## 1.15.0 (2017-03-26)
         | 
| 6 12 |  | 
| 7 13 | 
             
            * Add `RSpec/DescribeSymbol` cop. ([@tsigo][])
         | 
| 8 14 | 
             
            * Fix error when `RSpec/OverwritingSetup` and `RSpec/ScatteredLet` analyzed empty example groups. ([@backus][])
         | 
    
        data/Rakefile
    CHANGED
    
    
    
        data/config/default.yml
    CHANGED
    
    
| @@ -33,11 +33,12 @@ module RuboCop | |
| 33 33 | 
             
                  #       - '_test.rb$'
         | 
| 34 34 | 
             
                  #       - '(?:^|/)test/'
         | 
| 35 35 | 
             
                  class Cop < WorkaroundCop
         | 
| 36 | 
            +
                    include RuboCop::RSpec::Language
         | 
| 37 | 
            +
                    include RuboCop::RSpec::Language::NodePattern
         | 
| 38 | 
            +
             | 
| 36 39 | 
             
                    DEFAULT_CONFIGURATION =
         | 
| 37 40 | 
             
                      RuboCop::RSpec::CONFIG.fetch('AllCops').fetch('RSpec')
         | 
| 38 41 |  | 
| 39 | 
            -
                    include RuboCop::RSpec::Language, RuboCop::RSpec::Language::NodePattern
         | 
| 40 | 
            -
             | 
| 41 42 | 
             
                    # Invoke the original inherited hook so our cops are recognized
         | 
| 42 43 | 
             
                    def self.inherited(subclass)
         | 
| 43 44 | 
             
                      RuboCop::Cop::Cop.inherited(subclass)
         | 
| @@ -17,8 +17,8 @@ module RuboCop | |
| 17 17 | 
             
                  #   describe MyClass, '.my_class_method' do
         | 
| 18 18 | 
             
                  #   end
         | 
| 19 19 | 
             
                  class DescribeMethod < Cop
         | 
| 20 | 
            -
                    include RuboCop::RSpec::TopLevelDescribe | 
| 21 | 
            -
             | 
| 20 | 
            +
                    include RuboCop::RSpec::TopLevelDescribe
         | 
| 21 | 
            +
                    include RuboCop::RSpec::Util
         | 
| 22 22 |  | 
| 23 23 | 
             
                    MSG = 'The second argument to describe should be the method '\
         | 
| 24 24 | 
             
                          "being tested. '#instance' or '.class'.".freeze
         | 
| @@ -33,8 +33,8 @@ module RuboCop | |
| 33 33 | 
             
                    MSG_SHOULD = 'Do not use should when describing your tests.'.freeze
         | 
| 34 34 | 
             
                    MSG_IT     = "Do not repeat 'it' when describing your tests.".freeze
         | 
| 35 35 |  | 
| 36 | 
            -
                    SHOULD_PREFIX = ' | 
| 37 | 
            -
                    IT_PREFIX     =  | 
| 36 | 
            +
                    SHOULD_PREFIX = /\Ashould(?:n't)?\b/i
         | 
| 37 | 
            +
                    IT_PREFIX     = /\Ait /i
         | 
| 38 38 |  | 
| 39 39 | 
             
                    def_node_matcher(
         | 
| 40 40 | 
             
                      :it_description,
         | 
| @@ -43,20 +43,16 @@ module RuboCop | |
| 43 43 |  | 
| 44 44 | 
             
                    def on_block(node)
         | 
| 45 45 | 
             
                      it_description(node) do |description_node, message|
         | 
| 46 | 
            -
                         | 
| 47 | 
            -
             | 
| 48 | 
            -
                        if text.start_with?(SHOULD_PREFIX)
         | 
| 46 | 
            +
                        if message =~ SHOULD_PREFIX
         | 
| 49 47 | 
             
                          add_wording_offense(description_node, MSG_SHOULD)
         | 
| 50 | 
            -
                        elsif  | 
| 48 | 
            +
                        elsif message =~ IT_PREFIX
         | 
| 51 49 | 
             
                          add_wording_offense(description_node, MSG_IT)
         | 
| 52 50 | 
             
                        end
         | 
| 53 51 | 
             
                      end
         | 
| 54 52 | 
             
                    end
         | 
| 55 53 |  | 
| 56 54 | 
             
                    def autocorrect(range)
         | 
| 57 | 
            -
                       | 
| 58 | 
            -
                        corrector.replace(range, replacement_text(range))
         | 
| 59 | 
            -
                      end
         | 
| 55 | 
            +
                      ->(corrector) { corrector.replace(range, replacement_text(range)) }
         | 
| 60 56 | 
             
                    end
         | 
| 61 57 |  | 
| 62 58 | 
             
                    private
         | 
| @@ -77,13 +73,13 @@ module RuboCop | |
| 77 73 | 
             
                    def replacement_text(range)
         | 
| 78 74 | 
             
                      text = range.source
         | 
| 79 75 |  | 
| 80 | 
            -
                      if text | 
| 76 | 
            +
                      if text =~ SHOULD_PREFIX
         | 
| 81 77 | 
             
                        RuboCop::RSpec::Wording.new(
         | 
| 82 78 | 
             
                          text,
         | 
| 83 79 | 
             
                          ignore:  ignored_words,
         | 
| 84 80 | 
             
                          replace: custom_transform
         | 
| 85 81 | 
             
                        ).rewrite
         | 
| 86 | 
            -
                       | 
| 82 | 
            +
                      else
         | 
| 87 83 | 
             
                        text.sub(IT_PREFIX, '')
         | 
| 88 84 | 
             
                      end
         | 
| 89 85 | 
             
                    end
         | 
| @@ -19,7 +19,7 @@ module RuboCop | |
| 19 19 | 
             
                  class ExpectActual < Cop
         | 
| 20 20 | 
             
                    MSG = 'Provide the actual you are testing to `expect(...)`.'.freeze
         | 
| 21 21 |  | 
| 22 | 
            -
                    SIMPLE_LITERALS = %i | 
| 22 | 
            +
                    SIMPLE_LITERALS = %i[
         | 
| 23 23 | 
             
                      true
         | 
| 24 24 | 
             
                      false
         | 
| 25 25 | 
             
                      nil
         | 
| @@ -30,16 +30,16 @@ module RuboCop | |
| 30 30 | 
             
                      complex
         | 
| 31 31 | 
             
                      rational
         | 
| 32 32 | 
             
                      regopt
         | 
| 33 | 
            -
                     | 
| 33 | 
            +
                    ].freeze
         | 
| 34 34 |  | 
| 35 | 
            -
                    COMPLEX_LITERALS = %i | 
| 35 | 
            +
                    COMPLEX_LITERALS = %i[
         | 
| 36 36 | 
             
                      array
         | 
| 37 37 | 
             
                      hash
         | 
| 38 38 | 
             
                      pair
         | 
| 39 39 | 
             
                      irange
         | 
| 40 40 | 
             
                      erange
         | 
| 41 41 | 
             
                      regexp
         | 
| 42 | 
            -
                     | 
| 42 | 
            +
                    ].freeze
         | 
| 43 43 |  | 
| 44 44 | 
             
                    def_node_matcher :expect_literal, '(send _ :expect $#literal?)'
         | 
| 45 45 |  | 
| @@ -29,7 +29,7 @@ module RuboCop | |
| 29 29 |  | 
| 30 30 | 
             
                    MSG = 'Prefer `%s` for setting message expectations.'.freeze
         | 
| 31 31 |  | 
| 32 | 
            -
                    SUPPORTED_STYLES = %w | 
| 32 | 
            +
                    SUPPORTED_STYLES = %w[allow expect].freeze
         | 
| 33 33 |  | 
| 34 34 | 
             
                    def_node_matcher :message_expectation, <<-PATTERN
         | 
| 35 35 | 
             
                      (send $(send nil {:expect :allow} ...) :to #receive_message?)
         | 
| @@ -34,7 +34,7 @@ module RuboCop | |
| 34 34 | 
             
                                        'expectations. Setup `%s` as a spy using `allow`'\
         | 
| 35 35 | 
             
                                        ' or `instance_spy`.'.freeze
         | 
| 36 36 |  | 
| 37 | 
            -
                    SUPPORTED_STYLES = %w | 
| 37 | 
            +
                    SUPPORTED_STYLES = %w[have_received receive].freeze
         | 
| 38 38 |  | 
| 39 39 | 
             
                    def_node_matcher :message_expectation, %(
         | 
| 40 40 | 
             
                      (send (send nil :expect $_) {:to :to_not :not_to} ...)
         | 
| @@ -19,12 +19,16 @@ module RuboCop | |
| 19 19 | 
             
                          '`%<called>s` with a single argument.'.freeze
         | 
| 20 20 |  | 
| 21 21 | 
             
                    def_node_matcher :message_chain, <<-PATTERN
         | 
| 22 | 
            -
                      (send _ #{Matchers::MESSAGE_CHAIN.node_pattern_union}  | 
| 22 | 
            +
                      (send _ #{Matchers::MESSAGE_CHAIN.node_pattern_union} $_)
         | 
| 23 23 | 
             
                    PATTERN
         | 
| 24 24 |  | 
| 25 | 
            +
                    def_node_matcher :single_key_hash?, '(hash pair)'
         | 
| 26 | 
            +
             | 
| 25 27 | 
             
                    def on_send(node)
         | 
| 26 | 
            -
                      message_chain(node) do | | 
| 27 | 
            -
                        return if  | 
| 28 | 
            +
                      message_chain(node) do |arg|
         | 
| 29 | 
            +
                        return if arg.to_s.include?('.')
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                        return if arg.hash_type? && !single_key_hash?(arg)
         | 
| 28 32 |  | 
| 29 33 | 
             
                        add_offense(node, :selector)
         | 
| 30 34 | 
             
                      end
         | 
| @@ -33,11 +37,27 @@ module RuboCop | |
| 33 37 | 
             
                    def autocorrect(node)
         | 
| 34 38 | 
             
                      lambda do |corrector|
         | 
| 35 39 | 
             
                        corrector.replace(node.loc.selector, replacement(node.method_name))
         | 
| 40 | 
            +
                        message_chain(node) do |arg|
         | 
| 41 | 
            +
                          autocorrect_hash_arg(corrector, arg) if single_key_hash?(arg)
         | 
| 42 | 
            +
                        end
         | 
| 36 43 | 
             
                      end
         | 
| 37 44 | 
             
                    end
         | 
| 38 45 |  | 
| 39 46 | 
             
                    private
         | 
| 40 47 |  | 
| 48 | 
            +
                    def autocorrect_hash_arg(corrector, arg)
         | 
| 49 | 
            +
                      key, value = *arg.children.first
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                      corrector.replace(arg.loc.expression, key_to_arg(key))
         | 
| 52 | 
            +
                      corrector.insert_after(arg.parent.loc.end,
         | 
| 53 | 
            +
                                             ".and_return(#{value.source})")
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    def key_to_arg(node)
         | 
| 57 | 
            +
                      key, = *node
         | 
| 58 | 
            +
                      node.sym_type? ? ":#{key}" : node.source
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
             | 
| 41 61 | 
             
                    def replacement(method)
         | 
| 42 62 | 
             
                      method.equal?(:receive_message_chain) ? 'receive' : 'stub'
         | 
| 43 63 | 
             
                    end
         | 
| @@ -4,7 +4,8 @@ module RuboCop | |
| 4 4 | 
             
              module RSpec
         | 
| 5 5 | 
             
                # Wrapper for RSpec DSL methods
         | 
| 6 6 | 
             
                class Concept
         | 
| 7 | 
            -
                  include Language | 
| 7 | 
            +
                  include Language
         | 
| 8 | 
            +
                  include Language::NodePattern
         | 
| 8 9 | 
             
                  extend NodePattern::Macros
         | 
| 9 10 |  | 
| 10 11 | 
             
                  def initialize(node)
         | 
| @@ -12,7 +13,7 @@ module RuboCop | |
| 12 13 | 
             
                  end
         | 
| 13 14 |  | 
| 14 15 | 
             
                  def eql?(other)
         | 
| 15 | 
            -
                    node | 
| 16 | 
            +
                    node == other.node
         | 
| 16 17 | 
             
                  end
         | 
| 17 18 |  | 
| 18 19 | 
             
                  alias == eql?
         | 
    
        data/lib/rubocop/rspec/hook.rb
    CHANGED
    
    
| @@ -44,49 +44,49 @@ module RuboCop | |
| 44 44 | 
             
                  end
         | 
| 45 45 |  | 
| 46 46 | 
             
                  module Matchers
         | 
| 47 | 
            -
                    MESSAGE_CHAIN = SelectorSet.new(%i | 
| 47 | 
            +
                    MESSAGE_CHAIN = SelectorSet.new(%i[receive_message_chain stub_chain])
         | 
| 48 48 | 
             
                  end
         | 
| 49 49 |  | 
| 50 50 | 
             
                  module ExampleGroups
         | 
| 51 | 
            -
                    GROUPS  = SelectorSet.new(%i | 
| 52 | 
            -
                    SKIPPED = SelectorSet.new(%i | 
| 53 | 
            -
                    FOCUSED = SelectorSet.new(%i | 
| 51 | 
            +
                    GROUPS  = SelectorSet.new(%i[describe context feature example_group])
         | 
| 52 | 
            +
                    SKIPPED = SelectorSet.new(%i[xdescribe xcontext xfeature])
         | 
| 53 | 
            +
                    FOCUSED = SelectorSet.new(%i[fdescribe fcontext ffeature])
         | 
| 54 54 |  | 
| 55 55 | 
             
                    ALL = GROUPS + SKIPPED + FOCUSED
         | 
| 56 56 | 
             
                  end
         | 
| 57 57 |  | 
| 58 58 | 
             
                  module SharedGroups
         | 
| 59 | 
            -
                    EXAMPLES = SelectorSet.new(%i | 
| 60 | 
            -
                    CONTEXT = SelectorSet.new(%i | 
| 59 | 
            +
                    EXAMPLES = SelectorSet.new(%i[shared_examples shared_examples_for])
         | 
| 60 | 
            +
                    CONTEXT = SelectorSet.new(%i[shared_context])
         | 
| 61 61 |  | 
| 62 62 | 
             
                    ALL = EXAMPLES + CONTEXT
         | 
| 63 63 | 
             
                  end
         | 
| 64 64 |  | 
| 65 65 | 
             
                  module Includes
         | 
| 66 66 | 
             
                    EXAMPLES = SelectorSet.new(
         | 
| 67 | 
            -
                      %i | 
| 67 | 
            +
                      %i[
         | 
| 68 68 | 
             
                        it_behaves_like
         | 
| 69 69 | 
             
                        it_should_behave_like
         | 
| 70 70 | 
             
                        include_examples
         | 
| 71 | 
            -
                       | 
| 71 | 
            +
                      ]
         | 
| 72 72 | 
             
                    )
         | 
| 73 | 
            -
                    CONTEXT = SelectorSet.new(%i | 
| 73 | 
            +
                    CONTEXT = SelectorSet.new(%i[include_context])
         | 
| 74 74 |  | 
| 75 75 | 
             
                    ALL = EXAMPLES + CONTEXT
         | 
| 76 76 | 
             
                  end
         | 
| 77 77 |  | 
| 78 78 | 
             
                  module Examples
         | 
| 79 | 
            -
                    EXAMPLES = SelectorSet.new(%i | 
| 80 | 
            -
                    FOCUSED  = SelectorSet.new(%i | 
| 81 | 
            -
                    SKIPPED  = SelectorSet.new(%i | 
| 82 | 
            -
                    PENDING  = SelectorSet.new(%i | 
| 79 | 
            +
                    EXAMPLES = SelectorSet.new(%i[it specify example scenario its])
         | 
| 80 | 
            +
                    FOCUSED  = SelectorSet.new(%i[fit fspecify fexample fscenario focus])
         | 
| 81 | 
            +
                    SKIPPED  = SelectorSet.new(%i[xit xspecify xexample xscenario skip])
         | 
| 82 | 
            +
                    PENDING  = SelectorSet.new(%i[pending])
         | 
| 83 83 |  | 
| 84 84 | 
             
                    ALL = EXAMPLES + FOCUSED + SKIPPED + PENDING
         | 
| 85 85 | 
             
                  end
         | 
| 86 86 |  | 
| 87 87 | 
             
                  module Hooks
         | 
| 88 88 | 
             
                    ALL = SelectorSet.new(
         | 
| 89 | 
            -
                      %i | 
| 89 | 
            +
                      %i[
         | 
| 90 90 | 
             
                        prepend_before
         | 
| 91 91 | 
             
                        before
         | 
| 92 92 | 
             
                        append_before
         | 
| @@ -94,16 +94,16 @@ module RuboCop | |
| 94 94 | 
             
                        prepend_after
         | 
| 95 95 | 
             
                        after
         | 
| 96 96 | 
             
                        append_after
         | 
| 97 | 
            -
                       | 
| 97 | 
            +
                      ]
         | 
| 98 98 | 
             
                    )
         | 
| 99 99 | 
             
                  end
         | 
| 100 100 |  | 
| 101 101 | 
             
                  module Helpers
         | 
| 102 | 
            -
                    ALL = SelectorSet.new(%i | 
| 102 | 
            +
                    ALL = SelectorSet.new(%i[let let!])
         | 
| 103 103 | 
             
                  end
         | 
| 104 104 |  | 
| 105 105 | 
             
                  module Subject
         | 
| 106 | 
            -
                    ALL = SelectorSet.new(%i | 
| 106 | 
            +
                    ALL = SelectorSet.new(%i[subject subject!])
         | 
| 107 107 | 
             
                  end
         | 
| 108 108 |  | 
| 109 109 | 
             
                  ALL =
         | 
| @@ -4,6 +4,11 @@ module RuboCop | |
| 4 4 | 
             
              module RSpec
         | 
| 5 5 | 
             
                # RSpec example wording rewriter
         | 
| 6 6 | 
             
                class Wording
         | 
| 7 | 
            +
                  SHOULDNT_PREFIX    = /\Ashould(?:n't| not)\b/i
         | 
| 8 | 
            +
                  SHOULDNT_BE_PREFIX = /#{SHOULDNT_PREFIX} be\b/i
         | 
| 9 | 
            +
                  ES_SUFFIX_PATTERN  = /(?:o|s|x|ch|sh|z)\z/i
         | 
| 10 | 
            +
                  IES_SUFFIX_PATTERN = /[^aeou]y\z/i
         | 
| 11 | 
            +
             | 
| 7 12 | 
             
                  def initialize(text, ignore:, replace:)
         | 
| 8 13 | 
             
                    @text         = text
         | 
| 9 14 | 
             
                    @ignores      = ignore
         | 
| @@ -11,37 +16,66 @@ module RuboCop | |
| 11 16 | 
             
                  end
         | 
| 12 17 |  | 
| 13 18 | 
             
                  def rewrite
         | 
| 14 | 
            -
                    text | 
| 15 | 
            -
             | 
| 16 | 
            -
                       | 
| 17 | 
            -
             | 
| 18 | 
            -
                       | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
                      end
         | 
| 23 | 
            -
                    end.join(' ')
         | 
| 19 | 
            +
                    case text
         | 
| 20 | 
            +
                    when SHOULDNT_BE_PREFIX
         | 
| 21 | 
            +
                      replace_prefix(SHOULDNT_BE_PREFIX, 'is not')
         | 
| 22 | 
            +
                    when SHOULDNT_PREFIX
         | 
| 23 | 
            +
                      replace_prefix(SHOULDNT_PREFIX, 'does not')
         | 
| 24 | 
            +
                    else
         | 
| 25 | 
            +
                      remove_should_and_pluralize
         | 
| 26 | 
            +
                    end
         | 
| 24 27 | 
             
                  end
         | 
| 25 28 |  | 
| 26 29 | 
             
                  private
         | 
| 27 30 |  | 
| 28 31 | 
             
                  attr_reader :text, :ignores, :replacements
         | 
| 29 32 |  | 
| 30 | 
            -
                  def  | 
| 31 | 
            -
                     | 
| 33 | 
            +
                  def replace_prefix(pattern, replacement)
         | 
| 34 | 
            +
                    text.sub(pattern) do |shouldnt|
         | 
| 35 | 
            +
                      uppercase?(shouldnt) ? replacement.upcase : replacement
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  def uppercase?(word)
         | 
| 40 | 
            +
                    word.upcase.eql?(word)
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  def remove_should_and_pluralize
         | 
| 44 | 
            +
                    _should, *words = text.split
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    words.each_with_index do |word, index|
         | 
| 47 | 
            +
                      next if ignored_word?(word)
         | 
| 32 48 |  | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
                       | 
| 49 | 
            +
                      words[index] = substitute(word)
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                      break
         | 
| 36 52 | 
             
                    end
         | 
| 37 53 |  | 
| 38 | 
            -
                     | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 54 | 
            +
                    words.join(' ')
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  def ignored_word?(word)
         | 
| 58 | 
            +
                    ignores.any? { |ignore| ignore.casecmp(word).zero? }
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  def substitute(word)
         | 
| 62 | 
            +
                    # NOTE: Custom replacements are case sensitive.
         | 
| 63 | 
            +
                    return replacements.fetch(word) if replacements.key?(word)
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    case word
         | 
| 66 | 
            +
                    when ES_SUFFIX_PATTERN  then append_suffix(word, 'es')
         | 
| 67 | 
            +
                    when IES_SUFFIX_PATTERN then append_suffix(word[0..-2], 'ies')
         | 
| 68 | 
            +
                    else append_suffix(word, 's')
         | 
| 41 69 | 
             
                    end
         | 
| 70 | 
            +
                  end
         | 
| 42 71 |  | 
| 43 | 
            -
             | 
| 72 | 
            +
                  def append_suffix(word, suffix)
         | 
| 73 | 
            +
                    suffix = suffix.upcase if uppercase?(word)
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                    "#{word}#{suffix}"
         | 
| 44 76 | 
             
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  private_constant(*constants(false))
         | 
| 45 79 | 
             
                end
         | 
| 46 80 | 
             
              end
         | 
| 47 81 | 
             
            end
         | 
| @@ -14,11 +14,11 @@ RSpec.describe 'config/default.yml' do | |
| 14 14 | 
             
                    "RSpec/#{cop_name}"
         | 
| 15 15 | 
             
                  end
         | 
| 16 16 |  | 
| 17 | 
            -
                cop_names - %w | 
| 17 | 
            +
                cop_names - %w[RSpec/Cop]
         | 
| 18 18 | 
             
              end
         | 
| 19 19 |  | 
| 20 20 | 
             
              let(:config_keys) do
         | 
| 21 | 
            -
                cop_names + %w | 
| 21 | 
            +
                cop_names + %w[AllCops]
         | 
| 22 22 | 
             
              end
         | 
| 23 23 |  | 
| 24 24 | 
             
              def cop_configuration(config_key)
         | 
| @@ -63,7 +63,7 @@ RSpec.describe RuboCop::Cop::RSpec::EmptyExampleGroup, :config do | |
| 63 63 |  | 
| 64 64 | 
             
              context 'when a custom include method is specified' do
         | 
| 65 65 | 
             
                let(:cop_config) do
         | 
| 66 | 
            -
                  { 'CustomIncludeMethods' => %w | 
| 66 | 
            +
                  { 'CustomIncludeMethods' => %w[it_has_special_behavior] }
         | 
| 67 67 | 
             
                end
         | 
| 68 68 |  | 
| 69 69 | 
             
                it 'does not flag an otherwise empty example group' do
         | 
| @@ -4,8 +4,8 @@ RSpec.describe RuboCop::Cop::RSpec::ExampleWording, :config do | |
| 4 4 | 
             
              context 'with configuration' do
         | 
| 5 5 | 
             
                let(:cop_config) do
         | 
| 6 6 | 
             
                  {
         | 
| 7 | 
            -
                    'CustomTransform' => { 'have' => 'has' | 
| 8 | 
            -
                    'IgnoredWords'    => %w | 
| 7 | 
            +
                    'CustomTransform' => { 'have' => 'has' },
         | 
| 8 | 
            +
                    'IgnoredWords'    => %w[only really]
         | 
| 9 9 | 
             
                  }
         | 
| 10 10 | 
             
                end
         | 
| 11 11 |  | 
| @@ -37,6 +37,22 @@ RSpec.describe RuboCop::Cop::RSpec::ExampleWording, :config do | |
| 37 37 | 
             
                  RUBY
         | 
| 38 38 | 
             
                end
         | 
| 39 39 |  | 
| 40 | 
            +
                it 'flags a lone should' do
         | 
| 41 | 
            +
                  expect_violation(<<-RUBY)
         | 
| 42 | 
            +
                    it 'should' do
         | 
| 43 | 
            +
                        ^^^^^^ Do not use should when describing your tests.
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                  RUBY
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                it 'flags a lone should not' do
         | 
| 49 | 
            +
                  expect_violation(<<-RUBY)
         | 
| 50 | 
            +
                    it 'should not' do
         | 
| 51 | 
            +
                        ^^^^^^^^^^ Do not use should when describing your tests.
         | 
| 52 | 
            +
                    end
         | 
| 53 | 
            +
                  RUBY
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 40 56 | 
             
                it 'finds leading its' do
         | 
| 41 57 | 
             
                  expect_violation(<<-RUBY)
         | 
| 42 58 | 
             
                    it "it does something" do
         | 
| @@ -59,13 +75,36 @@ RSpec.describe RuboCop::Cop::RSpec::ExampleWording, :config do | |
| 59 75 | 
             
                  RUBY
         | 
| 60 76 | 
             
                end
         | 
| 61 77 |  | 
| 78 | 
            +
                it 'skips descriptions starting with words that begin with `should`' do
         | 
| 79 | 
            +
                  expect_no_violations(<<-RUBY)
         | 
| 80 | 
            +
                    it 'shoulders the burden' do
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
                  RUBY
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 62 85 | 
             
                include_examples 'autocorrect',
         | 
| 63 86 | 
             
                                 'it "should only have trait" do end',
         | 
| 64 87 | 
             
                                 'it "only has trait" do end'
         | 
| 65 88 |  | 
| 89 | 
            +
                include_examples 'autocorrect',
         | 
| 90 | 
            +
                                 'it "SHOULDN\'T only have trait" do end',
         | 
| 91 | 
            +
                                 'it "DOES NOT only have trait" do end'
         | 
| 92 | 
            +
             | 
| 66 93 | 
             
                include_examples 'autocorrect',
         | 
| 67 94 | 
             
                                 'it "it does something" do end',
         | 
| 68 95 | 
             
                                 'it "does something" do end'
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                include_examples 'autocorrect',
         | 
| 98 | 
            +
                                 'it "It does something" do end',
         | 
| 99 | 
            +
                                 'it "does something" do end'
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                include_examples 'autocorrect',
         | 
| 102 | 
            +
                                 'it "should" do end',
         | 
| 103 | 
            +
                                 'it "" do end'
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                include_examples 'autocorrect',
         | 
| 106 | 
            +
                                 'it "should not" do end',
         | 
| 107 | 
            +
                                 'it "does not" do end'
         | 
| 69 108 | 
             
              end
         | 
| 70 109 |  | 
| 71 110 | 
             
              context 'when configuration is empty' do
         | 
| @@ -59,6 +59,14 @@ RSpec.describe RuboCop::Cop::RSpec::IteratedExpectation do | |
| 59 59 | 
             
                RUBY
         | 
| 60 60 | 
             
              end
         | 
| 61 61 |  | 
| 62 | 
            +
              it 'ignores assignments in the iteration' do
         | 
| 63 | 
            +
                expect_no_violations(<<-RUBY)
         | 
| 64 | 
            +
                  it 'validates users' do
         | 
| 65 | 
            +
                    [user1, user2, user3].each { |user| array = array.concat(user) }
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                RUBY
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
             | 
| 62 70 | 
             
              it 'ignores `each` when there is a negative expectation' do
         | 
| 63 71 | 
             
                expect_no_violations(<<-RUBY)
         | 
| 64 72 | 
             
                  it 'validates users' do
         | 
| @@ -4,7 +4,7 @@ RSpec.describe RuboCop::Cop::RSpec::MultipleExpectations, :config do | |
| 4 4 | 
             
              subject(:cop) { described_class.new(config) }
         | 
| 5 5 |  | 
| 6 6 | 
             
              context 'without configuration' do
         | 
| 7 | 
            -
                let(:cop_config) {  | 
| 7 | 
            +
                let(:cop_config) { {} }
         | 
| 8 8 |  | 
| 9 9 | 
             
                it 'flags multiple expectations' do
         | 
| 10 10 | 
             
                  expect_violation(<<-RUBY)
         | 
| @@ -47,6 +47,45 @@ RSpec.describe RuboCop::Cop::RSpec::SingleArgumentMessageChain do | |
| 47 47 | 
             
                    end
         | 
| 48 48 | 
             
                  RUBY
         | 
| 49 49 | 
             
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                context 'with single-key hash argument' do
         | 
| 52 | 
            +
                  it 'reports an offence' do
         | 
| 53 | 
            +
                    expect_violation(<<-RUBY)
         | 
| 54 | 
            +
                      before do
         | 
| 55 | 
            +
                        allow(foo).to receive_message_chain(bar: 42)
         | 
| 56 | 
            +
                                      ^^^^^^^^^^^^^^^^^^^^^ Use `receive` instead of calling `receive_message_chain` with a single argument.
         | 
| 57 | 
            +
                      end
         | 
| 58 | 
            +
                    RUBY
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  include_examples(
         | 
| 62 | 
            +
                    'autocorrect',
         | 
| 63 | 
            +
                    'before { allow(foo).to receive_message_chain(bar: 42) }',
         | 
| 64 | 
            +
                    'before { allow(foo).to receive(:bar).and_return(42) }'
         | 
| 65 | 
            +
                  )
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  include_examples(
         | 
| 68 | 
            +
                    'autocorrect',
         | 
| 69 | 
            +
                    'before { allow(foo).to receive_message_chain("bar" => 42) }',
         | 
| 70 | 
            +
                    'before { allow(foo).to receive("bar").and_return(42) }'
         | 
| 71 | 
            +
                  )
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  include_examples(
         | 
| 74 | 
            +
                    'autocorrect',
         | 
| 75 | 
            +
                    'before { allow(foo).to receive_message_chain(:"#{foo}" => 42) }',
         | 
| 76 | 
            +
                    'before { allow(foo).to receive(:"#{foo}").and_return(42) }'
         | 
| 77 | 
            +
                  )
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                context 'with multiple keys hash argument' do
         | 
| 81 | 
            +
                  it "doesn't report an offence" do
         | 
| 82 | 
            +
                    expect_no_violations(<<-RUBY)
         | 
| 83 | 
            +
                      before do
         | 
| 84 | 
            +
                        allow(foo).to receive_message_chain(bar: 42, baz: 42)
         | 
| 85 | 
            +
                      end
         | 
| 86 | 
            +
                    RUBY
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
                end
         | 
| 50 89 | 
             
              end
         | 
| 51 90 |  | 
| 52 91 | 
             
              describe 'stub_chain' do
         | 
| @@ -28,7 +28,7 @@ RSpec.describe RuboCop::RSpec::Example do | |
| 28 28 |  | 
| 29 29 | 
             
              it 'extracts implementation' do
         | 
| 30 30 | 
             
                expect(example('it("foo") { bar; baz }').implementation)
         | 
| 31 | 
            -
                  .to  | 
| 31 | 
            +
                  .to eq(s(:begin, s(:send, nil, :bar), s(:send, nil, :baz)))
         | 
| 32 32 | 
             
              end
         | 
| 33 33 |  | 
| 34 34 | 
             
              it 'returns node' do
         | 
| @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            RSpec.describe RuboCop::RSpec::Language::SelectorSet do
         | 
| 2 | 
            -
              subject(:selector_set) { described_class.new(%i | 
| 2 | 
            +
              subject(:selector_set) { described_class.new(%i[foo bar]) }
         | 
| 3 3 |  | 
| 4 4 | 
             
              it 'composes sets' do
         | 
| 5 | 
            -
                combined = selector_set + described_class.new(%i | 
| 5 | 
            +
                combined = selector_set + described_class.new(%i[baz])
         | 
| 6 6 |  | 
| 7 | 
            -
                expect(combined).to eq(described_class.new(%i | 
| 7 | 
            +
                expect(combined).to eq(described_class.new(%i[foo bar baz]))
         | 
| 8 8 | 
             
              end
         | 
| 9 9 |  | 
| 10 10 | 
             
              it 'compares by value' do
         | 
| 11 | 
            -
                expect(selector_set).not_to eq(described_class.new(%i | 
| 11 | 
            +
                expect(selector_set).not_to eq(described_class.new(%i[foo bar baz]))
         | 
| 12 12 | 
             
              end
         | 
| 13 13 |  | 
| 14 14 | 
             
              context '#include?' do
         | 
| @@ -1,11 +1,6 @@ | |
| 1 1 | 
             
            RSpec.describe RuboCop::RSpec::Wording do
         | 
| 2 | 
            -
              let(:replacements)  | 
| 3 | 
            -
             | 
| 4 | 
            -
              end
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              let(:ignores) do
         | 
| 7 | 
            -
                %w(only really)
         | 
| 8 | 
            -
              end
         | 
| 2 | 
            +
              let(:replacements) { { 'have' => 'has' } }
         | 
| 3 | 
            +
              let(:ignores)      { %w[only really]     }
         | 
| 9 4 |  | 
| 10 5 | 
             
              expected_rewrites =
         | 
| 11 6 | 
             
                {
         | 
| @@ -26,7 +21,18 @@ RSpec.describe RuboCop::RSpec::Wording do | |
| 26 21 | 
             
                  'should search the internet'         => 'searches the internet',
         | 
| 27 22 | 
             
                  'should wish me luck'                => 'wishes me luck',
         | 
| 28 23 | 
             
                  'should really only return one item' => 'really only returns one item',
         | 
| 29 | 
            -
                  "shouldn't return something"         => 'does not return something'
         | 
| 24 | 
            +
                  "shouldn't return something"         => 'does not return something',
         | 
| 25 | 
            +
                  'SHOULD RETAIN UPPERCASE'            => 'RETAINS UPPERCASE',
         | 
| 26 | 
            +
                  "shouldn't be true"                  => 'is not true',
         | 
| 27 | 
            +
                  "SHOULDN'T BE true"                  => 'IS NOT true',
         | 
| 28 | 
            +
                  "SHOULDN'T NOT RETAIN UPPERCASE"     => 'DOES NOT NOT RETAIN UPPERCASE',
         | 
| 29 | 
            +
                  'should WORRY'                       => 'WORRIES',
         | 
| 30 | 
            +
                  'should WISH me luck'                => 'WISHES me luck',
         | 
| 31 | 
            +
                  ''                                   => '',
         | 
| 32 | 
            +
                  'should'                             => '',
         | 
| 33 | 
            +
                  "shouldn't"                          => 'does not',
         | 
| 34 | 
            +
                  'should not'                         => 'does not',
         | 
| 35 | 
            +
                  'should fizz'                        => 'fizzes'
         | 
| 30 36 | 
             
                }
         | 
| 31 37 |  | 
| 32 38 | 
             
              expected_rewrites.each do |old, new|
         | 
| @@ -39,13 +39,14 @@ module ExpectViolation | |
| 39 39 | 
             
              end
         | 
| 40 40 |  | 
| 41 41 | 
             
              class Expectation
         | 
| 42 | 
            +
                include Adamantium
         | 
| 43 | 
            +
                include Concord.new(:string)
         | 
| 44 | 
            +
             | 
| 42 45 | 
             
                VIOLATION_LINE_PATTERN = /\A *\^/
         | 
| 43 46 |  | 
| 44 47 | 
             
                VIOLATION = :violation
         | 
| 45 48 | 
             
                SOURCE    = :line
         | 
| 46 49 |  | 
| 47 | 
            -
                include Adamantium, Concord.new(:string)
         | 
| 48 | 
            -
             | 
| 49 50 | 
             
                def source
         | 
| 50 51 | 
             
                  source_map.to_s
         | 
| 51 52 | 
             
                end
         | 
| @@ -117,6 +118,10 @@ module ExpectViolation | |
| 117 118 | 
             
                end
         | 
| 118 119 |  | 
| 119 120 | 
             
                class Assertion
         | 
| 121 | 
            +
                  include Adamantium
         | 
| 122 | 
            +
                  include Anima.new(:message, :column_range, :line_number)
         | 
| 123 | 
            +
                  include Comparable
         | 
| 124 | 
            +
             | 
| 120 125 | 
             
                  def self.parse(text:, line_number:)
         | 
| 121 126 | 
             
                    parser = Parser.new(text)
         | 
| 122 127 |  | 
| @@ -127,10 +132,6 @@ module ExpectViolation | |
| 127 132 | 
             
                    )
         | 
| 128 133 | 
             
                  end
         | 
| 129 134 |  | 
| 130 | 
            -
                  include Anima.new(:message, :column_range, :line_number),
         | 
| 131 | 
            -
                          Adamantium,
         | 
| 132 | 
            -
                          Comparable
         | 
| 133 | 
            -
             | 
| 134 135 | 
             
                  def <=>(other)
         | 
| 135 136 | 
             
                    to_a <=> other.to_a
         | 
| 136 137 | 
             
                  end
         | 
| @@ -142,9 +143,10 @@ module ExpectViolation | |
| 142 143 | 
             
                  end
         | 
| 143 144 |  | 
| 144 145 | 
             
                  class Parser
         | 
| 145 | 
            -
                     | 
| 146 | 
            +
                    include Adamantium
         | 
| 147 | 
            +
                    include Concord.new(:text)
         | 
| 146 148 |  | 
| 147 | 
            -
                     | 
| 149 | 
            +
                    COLUMN_PATTERN = /^ *(?<carets>\^\^*) (?<message>.+)$/
         | 
| 148 150 |  | 
| 149 151 | 
             
                    def column_range
         | 
| 150 152 | 
             
                      Range.new(*match.offset(:carets), true)
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rubocop-rspec
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.15. | 
| 4 | 
            +
              version: 1.15.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - John Backus
         | 
| @@ -10,7 +10,7 @@ authors: | |
| 10 10 | 
             
            autorequire: 
         | 
| 11 11 | 
             
            bindir: bin
         | 
| 12 12 | 
             
            cert_chain: []
         | 
| 13 | 
            -
            date: 2017- | 
| 13 | 
            +
            date: 2017-05-01 00:00:00.000000000 Z
         | 
| 14 14 | 
             
            dependencies:
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 16 16 | 
             
              name: rubocop
         | 
| @@ -281,7 +281,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 281 281 | 
             
                  version: '0'
         | 
| 282 282 | 
             
            requirements: []
         | 
| 283 283 | 
             
            rubyforge_project: 
         | 
| 284 | 
            -
            rubygems_version: 2.6. | 
| 284 | 
            +
            rubygems_version: 2.6.11
         | 
| 285 285 | 
             
            signing_key: 
         | 
| 286 286 | 
             
            specification_version: 4
         | 
| 287 287 | 
             
            summary: Code style checking for RSpec files
         |