rubocop-rspec 2.11.1 → 2.13.0

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.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +125 -81
  3. data/config/default.yml +59 -6
  4. data/lib/rubocop/cop/rspec/align_left_let_brace.rb +8 -9
  5. data/lib/rubocop/cop/rspec/align_right_let_brace.rb +8 -9
  6. data/lib/rubocop/cop/rspec/any_instance.rb +1 -0
  7. data/lib/rubocop/cop/rspec/around_block.rb +26 -3
  8. data/lib/rubocop/cop/rspec/be.rb +0 -1
  9. data/lib/rubocop/cop/rspec/be_eq.rb +0 -1
  10. data/lib/rubocop/cop/rspec/be_eql.rb +0 -1
  11. data/lib/rubocop/cop/rspec/before_after_all.rb +1 -0
  12. data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +9 -3
  13. data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +2 -1
  14. data/lib/rubocop/cop/rspec/capybara/specific_finders.rb +86 -0
  15. data/lib/rubocop/cop/rspec/capybara/specific_matcher.rb +158 -0
  16. data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +0 -1
  17. data/lib/rubocop/cop/rspec/change_by_zero.rb +67 -7
  18. data/lib/rubocop/cop/rspec/class_check.rb +101 -0
  19. data/lib/rubocop/cop/rspec/context_method.rb +2 -1
  20. data/lib/rubocop/cop/rspec/context_wording.rb +49 -18
  21. data/lib/rubocop/cop/rspec/describe_class.rb +1 -1
  22. data/lib/rubocop/cop/rspec/describe_method.rb +1 -0
  23. data/lib/rubocop/cop/rspec/described_class.rb +5 -15
  24. data/lib/rubocop/cop/rspec/dialect.rb +1 -0
  25. data/lib/rubocop/cop/rspec/empty_example_group.rb +19 -4
  26. data/lib/rubocop/cop/rspec/empty_hook.rb +4 -5
  27. data/lib/rubocop/cop/rspec/empty_line_after_example.rb +4 -9
  28. data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +1 -1
  29. data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +2 -1
  30. data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +32 -2
  31. data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +2 -1
  32. data/lib/rubocop/cop/rspec/example_length.rb +3 -2
  33. data/lib/rubocop/cop/rspec/example_without_description.rb +3 -2
  34. data/lib/rubocop/cop/rspec/example_wording.rb +2 -1
  35. data/lib/rubocop/cop/rspec/excessive_docstring_spacing.rb +1 -0
  36. data/lib/rubocop/cop/rspec/expect_actual.rb +5 -0
  37. data/lib/rubocop/cop/rspec/expect_change.rb +9 -9
  38. data/lib/rubocop/cop/rspec/expect_in_hook.rb +4 -1
  39. data/lib/rubocop/cop/rspec/expect_output.rb +1 -0
  40. data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +2 -1
  41. data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +50 -13
  42. data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +1 -0
  43. data/lib/rubocop/cop/rspec/factory_bot/syntax_methods.rb +1 -1
  44. data/lib/rubocop/cop/rspec/file_path.rb +8 -4
  45. data/lib/rubocop/cop/rspec/focus.rb +20 -4
  46. data/lib/rubocop/cop/rspec/hook_argument.rb +10 -5
  47. data/lib/rubocop/cop/rspec/hooks_before_examples.rb +10 -9
  48. data/lib/rubocop/cop/rspec/identical_equality_assertion.rb +0 -1
  49. data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +1 -0
  50. data/lib/rubocop/cop/rspec/implicit_expect.rb +1 -3
  51. data/lib/rubocop/cop/rspec/instance_spy.rb +1 -1
  52. data/lib/rubocop/cop/rspec/instance_variable.rb +0 -1
  53. data/lib/rubocop/cop/rspec/it_behaves_like.rb +3 -2
  54. data/lib/rubocop/cop/rspec/iterated_expectation.rb +16 -0
  55. data/lib/rubocop/cop/rspec/leading_subject.rb +15 -15
  56. data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +1 -1
  57. data/lib/rubocop/cop/rspec/let_before_examples.rb +7 -8
  58. data/lib/rubocop/cop/rspec/let_setup.rb +4 -4
  59. data/lib/rubocop/cop/rspec/message_chain.rb +1 -1
  60. data/lib/rubocop/cop/rspec/message_expectation.rb +1 -1
  61. data/lib/rubocop/cop/rspec/message_spies.rb +7 -1
  62. data/lib/rubocop/cop/rspec/missing_example_group_argument.rb +2 -1
  63. data/lib/rubocop/cop/rspec/mixin/css_selector.rb +99 -0
  64. data/lib/rubocop/cop/rspec/mixin/empty_line_separation.rb +13 -4
  65. data/lib/rubocop/cop/rspec/mixin/namespace.rb +23 -0
  66. data/lib/rubocop/cop/rspec/multiple_describes.rb +1 -0
  67. data/lib/rubocop/cop/rspec/multiple_expectations.rb +19 -3
  68. data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +1 -3
  69. data/lib/rubocop/cop/rspec/multiple_subjects.rb +17 -2
  70. data/lib/rubocop/cop/rspec/named_subject.rb +2 -1
  71. data/lib/rubocop/cop/rspec/nested_groups.rb +45 -25
  72. data/lib/rubocop/cop/rspec/no_expectation_example.rb +64 -0
  73. data/lib/rubocop/cop/rspec/not_to_not.rb +13 -1
  74. data/lib/rubocop/cop/rspec/overwriting_setup.rb +2 -1
  75. data/lib/rubocop/cop/rspec/pending.rb +1 -0
  76. data/lib/rubocop/cop/rspec/predicate_matcher.rb +2 -1
  77. data/lib/rubocop/cop/rspec/rails/avoid_setup_hook.rb +1 -2
  78. data/lib/rubocop/cop/rspec/rails/have_http_status.rb +47 -0
  79. data/lib/rubocop/cop/rspec/receive_counts.rb +14 -15
  80. data/lib/rubocop/cop/rspec/receive_never.rb +4 -5
  81. data/lib/rubocop/cop/rspec/repeated_description.rb +25 -26
  82. data/lib/rubocop/cop/rspec/repeated_example.rb +1 -1
  83. data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +28 -29
  84. data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +28 -29
  85. data/lib/rubocop/cop/rspec/repeated_include_example.rb +32 -33
  86. data/lib/rubocop/cop/rspec/return_from_stub.rb +12 -12
  87. data/lib/rubocop/cop/rspec/scattered_let.rb +1 -5
  88. data/lib/rubocop/cop/rspec/scattered_setup.rb +2 -2
  89. data/lib/rubocop/cop/rspec/shared_context.rb +1 -1
  90. data/lib/rubocop/cop/rspec/stubbed_mock.rb +0 -1
  91. data/lib/rubocop/cop/rspec/subject_declaration.rb +0 -1
  92. data/lib/rubocop/cop/rspec/subject_stub.rb +2 -2
  93. data/lib/rubocop/cop/rspec/unspecified_exception.rb +15 -15
  94. data/lib/rubocop/cop/rspec/variable_definition.rb +1 -0
  95. data/lib/rubocop/cop/rspec/variable_name.rb +6 -7
  96. data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -0
  97. data/lib/rubocop/cop/rspec/void_expect.rb +2 -1
  98. data/lib/rubocop/cop/rspec/yield.rb +3 -2
  99. data/lib/rubocop/cop/rspec_cops.rb +5 -0
  100. data/lib/rubocop/rspec/config_formatter.rb +14 -3
  101. data/lib/rubocop/rspec/inject.rb +1 -3
  102. data/lib/rubocop/rspec/language/node_pattern.rb +4 -0
  103. data/lib/rubocop/rspec/language.rb +6 -1
  104. data/lib/rubocop/rspec/node.rb +1 -1
  105. data/lib/rubocop/rspec/version.rb +1 -1
  106. data/lib/rubocop/rspec/wording.rb +2 -2
  107. data/lib/rubocop/rspec.rb +14 -0
  108. data/lib/rubocop-rspec.rb +3 -0
  109. metadata +12 -88
@@ -6,45 +6,44 @@ module RuboCop
6
6
  # Check for repeated include of shared examples.
7
7
  #
8
8
  # @example
9
+ # # bad
10
+ # describe 'foo' do
11
+ # include_examples 'cool stuff'
12
+ # include_examples 'cool stuff'
13
+ # end
9
14
  #
10
- # # bad
11
- # describe 'foo' do
12
- # include_examples 'cool stuff'
13
- # include_examples 'cool stuff'
14
- # end
15
+ # # bad
16
+ # describe 'foo' do
17
+ # it_behaves_like 'a cool', 'thing'
18
+ # it_behaves_like 'a cool', 'thing'
19
+ # end
15
20
  #
16
- # # bad
17
- # describe 'foo' do
18
- # it_behaves_like 'a cool', 'thing'
19
- # it_behaves_like 'a cool', 'thing'
20
- # end
21
+ # # bad
22
+ # context 'foo' do
23
+ # it_should_behave_like 'a duck'
24
+ # it_should_behave_like 'a duck'
25
+ # end
21
26
  #
22
- # # bad
23
- # context 'foo' do
24
- # it_should_behave_like 'a duck'
25
- # it_should_behave_like 'a duck'
26
- # end
27
+ # # good
28
+ # describe 'foo' do
29
+ # include_examples 'cool stuff'
30
+ # end
27
31
  #
28
- # # good
29
- # describe 'foo' do
30
- # include_examples 'cool stuff'
31
- # end
32
+ # describe 'bar' do
33
+ # include_examples 'cool stuff'
34
+ # end
32
35
  #
33
- # describe 'bar' do
34
- # include_examples 'cool stuff'
35
- # end
36
+ # # good
37
+ # describe 'foo' do
38
+ # it_behaves_like 'a cool', 'thing'
39
+ # it_behaves_like 'a cool', 'person'
40
+ # end
36
41
  #
37
- # # good
38
- # describe 'foo' do
39
- # it_behaves_like 'a cool', 'thing'
40
- # it_behaves_like 'a cool', 'person'
41
- # end
42
- #
43
- # # good
44
- # context 'foo' do
45
- # it_should_behave_like 'a duck'
46
- # it_should_behave_like 'a goose'
47
- # end
42
+ # # good
43
+ # context 'foo' do
44
+ # it_should_behave_like 'a duck'
45
+ # it_should_behave_like 'a goose'
46
+ # end
48
47
  #
49
48
  class RepeatedIncludeExample < Base
50
49
  MSG = 'Repeated include of shared_examples %<name>s ' \
@@ -11,6 +11,17 @@ module RuboCop
11
11
  #
12
12
  # This cop can be configured using the `EnforcedStyle` option
13
13
  #
14
+ # @example `EnforcedStyle: and_return` (default)
15
+ # # bad
16
+ # allow(Foo).to receive(:bar) { "baz" }
17
+ # expect(Foo).to receive(:bar) { "baz" }
18
+ #
19
+ # # good
20
+ # allow(Foo).to receive(:bar).and_return("baz")
21
+ # expect(Foo).to receive(:bar).and_return("baz")
22
+ # # also good as the returned value is dynamic
23
+ # allow(Foo).to receive(:bar) { bar.baz }
24
+ #
14
25
  # @example `EnforcedStyle: block`
15
26
  # # bad
16
27
  # allow(Foo).to receive(:bar).and_return("baz")
@@ -22,17 +33,6 @@ module RuboCop
22
33
  # # also good as the returned value is dynamic
23
34
  # allow(Foo).to receive(:bar).and_return(bar.baz)
24
35
  #
25
- # @example `EnforcedStyle: and_return`
26
- # # bad
27
- # allow(Foo).to receive(:bar) { "baz" }
28
- # expect(Foo).to receive(:bar) { "baz" }
29
- #
30
- # # good
31
- # allow(Foo).to receive(:bar).and_return("baz")
32
- # expect(Foo).to receive(:bar).and_return("baz")
33
- # # also good as the returned value is dynamic
34
- # allow(Foo).to receive(:bar) { bar.baz }
35
- #
36
36
  class ReturnFromStub < Base
37
37
  extend AutoCorrector
38
38
  include ConfigurableEnforcedStyle
@@ -59,7 +59,7 @@ module RuboCop
59
59
  check_and_return_call(node)
60
60
  end
61
61
 
62
- def on_block(node)
62
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
63
63
  return unless style == :and_return
64
64
  return unless stub_with_block?(node)
65
65
 
@@ -31,7 +31,7 @@ module RuboCop
31
31
 
32
32
  MSG = 'Group all let/let! blocks in the example group together.'
33
33
 
34
- def on_block(node)
34
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
35
35
  return unless example_group_with_body?(node)
36
36
 
37
37
  check_let_declarations(node.body)
@@ -53,10 +53,6 @@ module RuboCop
53
53
  end
54
54
  end
55
55
  end
56
-
57
- def find_first_let(node)
58
- node.children.find { |child| let?(child) }
59
- end
60
56
  end
61
57
  end
62
58
  end
@@ -26,7 +26,7 @@ module RuboCop
26
26
  MSG = 'Do not define multiple `%<hook_name>s` hooks in the same ' \
27
27
  'example group (also defined on %<lines>s).'
28
28
 
29
- def on_block(node)
29
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
30
30
  return unless example_group?(node)
31
31
 
32
32
  repeated_hooks(node).each do |occurrences|
@@ -35,7 +35,7 @@ module RuboCop
35
35
  occurrences.each do |occurrence|
36
36
  lines_except_current = lines - [occurrence.first_line]
37
37
  message = format(MSG, hook_name: occurrences.first.method_name,
38
- lines: lines_msg(lines_except_current))
38
+ lines: lines_msg(lines_except_current))
39
39
  add_offense(occurrence, message: message)
40
40
  end
41
41
  end
@@ -79,7 +79,7 @@ module RuboCop
79
79
  def_node_matcher :shared_example,
80
80
  block_pattern('#SharedGroups.examples')
81
81
 
82
- def on_block(node)
82
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
83
83
  context_with_only_examples(node) do
84
84
  add_offense(node.send_node, message: MSG_EXAMPLES) do |corrector|
85
85
  corrector.replace(node.send_node.loc.selector, 'shared_examples')
@@ -6,7 +6,6 @@ module RuboCop
6
6
  # Checks that message expectations do not have a configured response.
7
7
  #
8
8
  # @example
9
- #
10
9
  # # bad
11
10
  # expect(foo).to receive(:bar).with(42).and_return("hello world")
12
11
  #
@@ -6,7 +6,6 @@ module RuboCop
6
6
  # Ensure that subject is defined using subject helper.
7
7
  #
8
8
  # @example
9
- #
10
9
  # # bad
11
10
  # let(:subject) { foo }
12
11
  # let!(:subject) { foo }
@@ -11,7 +11,7 @@ module RuboCop
11
11
  # when subject is also defined in parent example groups.
12
12
  #
13
13
  # @see https://robots.thoughtbot.com/don-t-stub-the-system-under-test
14
- # @see https://samphippen.com/introducing-rspec-smells-and-where-to-find-them#smell-1-stubject
14
+ # @see https://penelope.zone/2015/12/27/introducing-rspec-smells-and-where-to-find-them.html#smell-1-stubjec
15
15
  # @see https://github.com/rubocop-hq/rspec-style-guide#dont-stub-subject
16
16
  #
17
17
  # @example
@@ -72,7 +72,7 @@ module RuboCop
72
72
  def_node_matcher :subject?, <<-PATTERN
73
73
  (block
74
74
  (send nil?
75
- {:subject (sym $_) | $:subject}
75
+ { #Subjects.all (sym $_) | $#Subjects.all }
76
76
  ) args ...)
77
77
  PATTERN
78
78
 
@@ -10,26 +10,26 @@ module RuboCop
10
10
  # to `raise_error`
11
11
  #
12
12
  # @example
13
+ # # bad
14
+ # expect {
15
+ # raise StandardError.new('error')
16
+ # }.to raise_error
13
17
  #
14
- # # bad
15
- # expect {
16
- # raise StandardError.new('error')
17
- # }.to raise_error
18
+ # # good
19
+ # expect {
20
+ # raise StandardError.new('error')
21
+ # }.to raise_error(StandardError)
18
22
  #
19
- # # good
20
- # expect {
21
- # raise StandardError.new('error')
22
- # }.to raise_error(StandardError)
23
+ # expect {
24
+ # raise StandardError.new('error')
25
+ # }.to raise_error('error')
23
26
  #
24
- # expect {
25
- # raise StandardError.new('error')
26
- # }.to raise_error('error')
27
+ # expect {
28
+ # raise StandardError.new('error')
29
+ # }.to raise_error(/err/)
27
30
  #
28
- # expect {
29
- # raise StandardError.new('error')
30
- # }.to raise_error(/err/)
31
+ # expect { do_something }.not_to raise_error
31
32
  #
32
- # expect { do_something }.not_to raise_error
33
33
  class UnspecifiedException < Base
34
34
  MSG = 'Specify the exception being captured'
35
35
  RESTRICT_ON_SEND = %i[to].freeze
@@ -22,6 +22,7 @@ module RuboCop
22
22
  # # good
23
23
  # subject('user') { create_user }
24
24
  # let('user_name') { 'Adam' }
25
+ #
25
26
  class VariableDefinition < Base
26
27
  extend AutoCorrector
27
28
  include ConfigurableEnforcedStyle
@@ -5,7 +5,7 @@ module RuboCop
5
5
  module RSpec
6
6
  # Checks that memoized helper names use the configured style.
7
7
  #
8
- # Variables can be excluded from checking using the `IgnoredPatterns`
8
+ # Variables can be excluded from checking using the `AllowedPatterns`
9
9
  # option.
10
10
  #
11
11
  # @example EnforcedStyle: snake_case (default)
@@ -26,22 +26,21 @@ module RuboCop
26
26
  # subject(:userName1) { 'Adam' }
27
27
  # let(:userName2) { 'Adam' }
28
28
  #
29
- # @example IgnoredPatterns configuration
30
- #
29
+ # @example AllowedPatterns configuration
31
30
  # # rubocop.yml
32
31
  # # RSpec/VariableName:
33
32
  # # EnforcedStyle: snake_case
34
- # # IgnoredPatterns:
33
+ # # AllowedPatterns:
35
34
  # # - ^userFood
36
35
  #
37
36
  # @example
38
- # # okay because it matches the `^userFood` regex in `IgnoredPatterns`
37
+ # # okay because it matches the `^userFood` regex in `AllowedPatterns`
39
38
  # subject(:userFood_1) { 'spaghetti' }
40
39
  # let(:userFood_2) { 'fettuccine' }
41
40
  #
42
41
  class VariableName < Base
43
42
  include ConfigurableNaming
44
- include IgnoredPattern
43
+ include AllowedPattern
45
44
  include Variable
46
45
 
47
46
  MSG = 'Use %<style>s for variable names.'
@@ -49,7 +48,7 @@ module RuboCop
49
48
  def on_send(node)
50
49
  variable_definition?(node) do |variable|
51
50
  return if variable.dstr_type? || variable.dsym_type?
52
- return if matches_ignored_pattern?(variable.value)
51
+ return if matches_allowed_pattern?(variable.value)
53
52
 
54
53
  check_name(node, variable.value, variable.loc.expression)
55
54
  end
@@ -22,6 +22,7 @@ module RuboCop
22
22
  # let(:foo) do
23
23
  # instance_double("ClassName", method_name: 'returned value')
24
24
  # end
25
+ #
25
26
  class VerifiedDoubles < Base
26
27
  MSG = 'Prefer using verifying doubles over normal doubles.'
27
28
  RESTRICT_ON_SEND = %i[double spy].freeze
@@ -11,6 +11,7 @@ module RuboCop
11
11
  #
12
12
  # # good
13
13
  # expect(something).to be(1)
14
+ #
14
15
  class VoidExpect < Base
15
16
  MSG = 'Do not use `expect()` without `.to` or `.not_to`. ' \
16
17
  'Chain the methods or remove it.'
@@ -32,7 +33,7 @@ module RuboCop
32
33
  check_expect(node)
33
34
  end
34
35
 
35
- def on_block(node)
36
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
36
37
  return unless expect_block?(node)
37
38
 
38
39
  check_expect(node)
@@ -11,6 +11,7 @@ module RuboCop
11
11
  #
12
12
  # # good
13
13
  # expect(foo).to receive(:bar).and_yield(1)
14
+ #
14
15
  class Yield < Base
15
16
  extend AutoCorrector
16
17
  include RangeHelp
@@ -26,7 +27,7 @@ module RuboCop
26
27
  # @!method block_call?(node)
27
28
  def_node_matcher :block_call?, '(send (lvar %) :call ...)'
28
29
 
29
- def on_block(node)
30
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
30
31
  return unless method_on_stub?(node.send_node)
31
32
 
32
33
  block_arg(node.arguments) do |block|
@@ -44,7 +45,7 @@ module RuboCop
44
45
 
45
46
  def autocorrect(corrector, node, range)
46
47
  corrector.replace(
47
- range_with_surrounding_space(range: range, side: :left),
48
+ range_with_surrounding_space(range, side: :left),
48
49
  generate_replacement(node.body)
49
50
  )
50
51
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require_relative 'rspec/capybara/current_path_expectation'
4
4
  require_relative 'rspec/capybara/feature_methods'
5
+ require_relative 'rspec/capybara/specific_finders'
6
+ require_relative 'rspec/capybara/specific_matcher'
5
7
  require_relative 'rspec/capybara/visibility_matcher'
6
8
 
7
9
  require_relative 'rspec/factory_bot/attribute_defined_statically'
@@ -10,6 +12,7 @@ require_relative 'rspec/factory_bot/factory_class_name'
10
12
  require_relative 'rspec/factory_bot/syntax_methods'
11
13
 
12
14
  require_relative 'rspec/rails/avoid_setup_hook'
15
+ require_relative 'rspec/rails/have_http_status'
13
16
  begin
14
17
  require_relative 'rspec/rails/http_status'
15
18
  rescue LoadError
@@ -26,6 +29,7 @@ require_relative 'rspec/be_eql'
26
29
  require_relative 'rspec/be_nil'
27
30
  require_relative 'rspec/before_after_all'
28
31
  require_relative 'rspec/change_by_zero'
32
+ require_relative 'rspec/class_check'
29
33
  require_relative 'rspec/context_method'
30
34
  require_relative 'rspec/context_wording'
31
35
  require_relative 'rspec/describe_class'
@@ -75,6 +79,7 @@ require_relative 'rspec/multiple_memoized_helpers'
75
79
  require_relative 'rspec/multiple_subjects'
76
80
  require_relative 'rspec/named_subject'
77
81
  require_relative 'rspec/nested_groups'
82
+ require_relative 'rspec/no_expectation_example'
78
83
  require_relative 'rspec/not_to_not'
79
84
  require_relative 'rspec/overwriting_setup'
80
85
  require_relative 'rspec/pending'
@@ -21,17 +21,18 @@ module RuboCop
21
21
  .gsub(EXTENSION_ROOT_DEPARTMENT, "\n\\1")
22
22
  .gsub(*AMENDMENTS, "\n\\0")
23
23
  .gsub(/^(\s+)- /, '\1 - ')
24
+ .gsub('"~"', '~')
24
25
  end
25
26
 
26
27
  private
27
28
 
28
29
  def unified_config
29
30
  cops.each_with_object(config.dup) do |cop, unified|
30
- next if SUBDEPARTMENTS.include?(cop)
31
- next if AMENDMENTS.include?(cop)
31
+ next if SUBDEPARTMENTS.include?(cop) || AMENDMENTS.include?(cop)
32
32
 
33
+ replace_nil(unified[cop])
33
34
  unified[cop].merge!(descriptions.fetch(cop))
34
- unified[cop]['Reference'] = COP_DOC_BASE_URL + cop.sub('RSpec/', '')
35
+ unified[cop]['Reference'] = reference(cop)
35
36
  end
36
37
  end
37
38
 
@@ -39,6 +40,16 @@ module RuboCop
39
40
  (descriptions.keys | config.keys).grep(EXTENSION_ROOT_DEPARTMENT)
40
41
  end
41
42
 
43
+ def replace_nil(config)
44
+ config.each do |key, value|
45
+ config[key] = '~' if value.nil?
46
+ end
47
+ end
48
+
49
+ def reference(cop)
50
+ COP_DOC_BASE_URL + cop.sub('RSpec/', '')
51
+ end
52
+
42
53
  attr_reader :config, :descriptions
43
54
  end
44
55
  end
@@ -6,9 +6,7 @@ module RuboCop
6
6
  # bit of our configuration.
7
7
  module Inject
8
8
  def self.defaults!
9
- project_root = Pathname.new(__dir__).parent.parent.parent.expand_path
10
- config_default = project_root.join('config', 'default.yml')
11
- path = config_default.to_s
9
+ path = CONFIG_DEFAULT.to_s
12
10
  hash = ConfigLoader.send(:load_yaml_configuration, path)
13
11
  config = RuboCop::Config.new(hash, path)
14
12
  puts "configuration from #{path}" if ConfigLoader.debug?
@@ -12,6 +12,10 @@ module RuboCop
12
12
  def block_pattern(string)
13
13
  "(block #{send_pattern(string)} ...)"
14
14
  end
15
+
16
+ def numblock_pattern(string)
17
+ "(numblock #{send_pattern(string)} ...)"
18
+ end
15
19
  end
16
20
  end
17
21
  end
@@ -41,7 +41,12 @@ module RuboCop
41
41
  def_node_matcher :example?, block_pattern('#Examples.all')
42
42
 
43
43
  # @!method hook?(node)
44
- def_node_matcher :hook?, block_pattern('#Hooks.all')
44
+ def_node_matcher :hook?, <<-PATTERN
45
+ {
46
+ #{block_pattern('#Hooks.all')}
47
+ #{numblock_pattern('#Hooks.all')}
48
+ }
49
+ PATTERN
45
50
 
46
51
  # @!method let?(node)
47
52
  def_node_matcher :let?, <<-PATTERN
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module RSpec
5
5
  # RuboCop RSpec specific extensions of RuboCop::AST::Node
6
6
  module Node
7
- # In various cops we want to regard const as literal althought it's not
7
+ # In various cops we want to regard const as literal although it's not
8
8
  # strictly literal.
9
9
  def recursive_literal_or_const?
10
10
  case type
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module RSpec
5
5
  # Version information for the RSpec RuboCop plugin.
6
6
  module Version
7
- STRING = '2.11.1'
7
+ STRING = '2.13.0'
8
8
  end
9
9
  end
10
10
  end
@@ -31,8 +31,8 @@ module RuboCop
31
31
  attr_reader :text, :ignores, :replacements
32
32
 
33
33
  def replace_prefix(pattern, replacement)
34
- text.sub(pattern) do |shouldnt|
35
- uppercase?(shouldnt) ? replacement.upcase : replacement
34
+ text.sub(pattern) do |matched|
35
+ uppercase?(matched) ? replacement.upcase : replacement
36
36
  end
37
37
  end
38
38
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ # RuboCop RSpec project namespace
5
+ module RSpec
6
+ PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
7
+ CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
8
+
9
+ private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
10
+
11
+ ::RuboCop::ConfigObsoletion.files << PROJECT_ROOT.join('config',
12
+ 'obsoletion.yml')
13
+ end
14
+ end
data/lib/rubocop-rspec.rb CHANGED
@@ -5,6 +5,7 @@ require 'yaml'
5
5
 
6
6
  require 'rubocop'
7
7
 
8
+ require_relative 'rubocop/rspec'
8
9
  require_relative 'rubocop/rspec/version'
9
10
  require_relative 'rubocop/rspec/inject'
10
11
  require_relative 'rubocop/rspec/node'
@@ -20,6 +21,8 @@ require_relative 'rubocop/cop/rspec/mixin/final_end_location'
20
21
  require_relative 'rubocop/cop/rspec/mixin/comments_help'
21
22
  require_relative 'rubocop/cop/rspec/mixin/empty_line_separation'
22
23
  require_relative 'rubocop/cop/rspec/mixin/inside_example_group'
24
+ require_relative 'rubocop/cop/rspec/mixin/namespace'
25
+ require_relative 'rubocop/cop/rspec/mixin/css_selector'
23
26
 
24
27
  require_relative 'rubocop/rspec/concept'
25
28
  require_relative 'rubocop/rspec/example_group'