rubocop-rspec 2.14.2 → 2.16.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/config/default.yml +48 -29
  4. data/lib/rubocop/cop/rspec/be.rb +2 -0
  5. data/lib/rubocop/cop/rspec/be_eq.rb +3 -0
  6. data/lib/rubocop/cop/rspec/be_eql.rb +3 -0
  7. data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +3 -3
  8. data/lib/rubocop/cop/rspec/capybara/negation_matcher.rb +1 -1
  9. data/lib/rubocop/cop/rspec/capybara/specific_actions.rb +1 -1
  10. data/lib/rubocop/cop/rspec/capybara/specific_finders.rb +1 -1
  11. data/lib/rubocop/cop/rspec/capybara/specific_matcher.rb +3 -5
  12. data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +1 -1
  13. data/lib/rubocop/cop/rspec/duplicated_metadata.rb +58 -0
  14. data/lib/rubocop/cop/rspec/empty_line_after_example.rb +2 -0
  15. data/lib/rubocop/cop/rspec/expect_actual.rb +2 -0
  16. data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +1 -1
  17. data/lib/rubocop/cop/rspec/factory_bot/consistent_parentheses_style.rb +16 -9
  18. data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +9 -2
  19. data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +1 -1
  20. data/lib/rubocop/cop/rspec/factory_bot/factory_name_style.rb +74 -0
  21. data/lib/rubocop/cop/rspec/implicit_expect.rb +2 -0
  22. data/lib/rubocop/cop/rspec/leading_subject.rb +2 -2
  23. data/lib/rubocop/cop/rspec/message_spies.rb +2 -0
  24. data/lib/rubocop/cop/rspec/mixin/metadata.rb +49 -0
  25. data/lib/rubocop/cop/rspec/named_subject.rb +81 -6
  26. data/lib/rubocop/cop/rspec/nested_groups.rb +1 -1
  27. data/lib/rubocop/cop/rspec/pending_without_reason.rb +123 -0
  28. data/lib/rubocop/cop/rspec/predicate_matcher.rb +2 -0
  29. data/lib/rubocop/cop/rspec/rails/have_http_status.rb +5 -2
  30. data/lib/rubocop/cop/rspec/rails/inferred_spec_type.rb +1 -1
  31. data/lib/rubocop/cop/rspec/repeated_description.rb +25 -2
  32. data/lib/rubocop/cop/rspec/scattered_setup.rb +2 -0
  33. data/lib/rubocop/cop/rspec/sort_metadata.rb +4 -35
  34. data/lib/rubocop/cop/rspec/stubbed_mock.rb +2 -0
  35. data/lib/rubocop/cop/rspec/unspecified_exception.rb +2 -0
  36. data/lib/rubocop/cop/rspec_cops.rb +3 -0
  37. data/lib/rubocop/rspec/config_formatter.rb +2 -2
  38. data/lib/rubocop/rspec/description_extractor.rb +5 -10
  39. data/lib/rubocop/rspec/language.rb +9 -3
  40. data/lib/rubocop/rspec/shared_contexts/default_rspec_language_config_context.rb +29 -0
  41. data/lib/rubocop/rspec/version.rb +1 -1
  42. data/lib/rubocop-rspec.rb +18 -13
  43. metadata +7 -2
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Helper methods to find RSpec metadata.
7
+ module Metadata
8
+ extend RuboCop::NodePattern::Macros
9
+
10
+ include RuboCop::RSpec::Language
11
+
12
+ # @!method rspec_metadata(node)
13
+ def_node_matcher :rspec_metadata, <<~PATTERN
14
+ (block
15
+ (send
16
+ #rspec? {#Examples.all #ExampleGroups.all #SharedGroups.all #Hooks.all} _ ${send str sym}* (hash $...)?)
17
+ ...)
18
+ PATTERN
19
+
20
+ # @!method rspec_configure(node)
21
+ def_node_matcher :rspec_configure, <<~PATTERN
22
+ (block (send #rspec? :configure) (args (arg $_)) ...)
23
+ PATTERN
24
+
25
+ # @!method metadata_in_block(node)
26
+ def_node_search :metadata_in_block, <<~PATTERN
27
+ (send (lvar %) #Hooks.all _ ${send str sym}* (hash $...)?)
28
+ PATTERN
29
+
30
+ def on_block(node)
31
+ rspec_configure(node) do |block_var|
32
+ metadata_in_block(node, block_var) do |symbols, pairs|
33
+ on_metadata(symbols, pairs.flatten)
34
+ end
35
+ end
36
+
37
+ rspec_metadata(node) do |symbols, pairs|
38
+ on_metadata(symbols, pairs.flatten)
39
+ end
40
+ end
41
+ alias on_numblock on_block
42
+
43
+ def on_metadata(_symbols, _pairs)
44
+ raise ::NotImplementedError
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -12,11 +12,11 @@ module RuboCop
12
12
  # should be the most important object in your tests so they deserve
13
13
  # a descriptive name.
14
14
  #
15
- # This cop can be configured in your configuration using the
16
- # `IgnoreSharedExamples` which will not report offenses for implicit
15
+ # This cop can be configured in your configuration using `EnforcedStyle`,
16
+ # and `IgnoreSharedExamples` which will not report offenses for implicit
17
17
  # subjects in shared example groups.
18
18
  #
19
- # @example
19
+ # @example `EnforcedStyle: always` (default)
20
20
  # # bad
21
21
  # RSpec.describe User do
22
22
  # subject { described_class.new }
@@ -27,7 +27,7 @@ module RuboCop
27
27
  # end
28
28
  #
29
29
  # # good
30
- # RSpec.describe Foo do
30
+ # RSpec.describe User do
31
31
  # subject(:user) { described_class.new }
32
32
  #
33
33
  # it 'is valid' do
@@ -36,13 +36,49 @@ module RuboCop
36
36
  # end
37
37
  #
38
38
  # # also good
39
- # RSpec.describe Foo do
39
+ # RSpec.describe User do
40
+ # subject(:user) { described_class.new }
41
+ #
42
+ # it { is_expected.to be_valid }
43
+ # end
44
+ #
45
+ # @example `EnforcedStyle: named_only`
46
+ # # bad
47
+ # RSpec.describe User do
48
+ # subject(:user) { described_class.new }
49
+ #
50
+ # it 'is valid' do
51
+ # expect(subject.valid?).to be(true)
52
+ # end
53
+ # end
54
+ #
55
+ # # good
56
+ # RSpec.describe User do
40
57
  # subject(:user) { described_class.new }
41
58
  #
59
+ # it 'is valid' do
60
+ # expect(user.valid?).to be(true)
61
+ # end
62
+ # end
63
+ #
64
+ # # also good
65
+ # RSpec.describe User do
66
+ # subject { described_class.new }
67
+ #
42
68
  # it { is_expected.to be_valid }
43
69
  # end
44
70
  #
71
+ # # acceptable
72
+ # RSpec.describe User do
73
+ # subject { described_class.new }
74
+ #
75
+ # it 'is valid' do
76
+ # expect(subject.valid?).to be(true)
77
+ # end
78
+ # end
45
79
  class NamedSubject < Base
80
+ include ConfigurableEnforcedStyle
81
+
46
82
  MSG = 'Name your test subject if you need to reference it explicitly.'
47
83
 
48
84
  # @!method example_or_hook_block?(node)
@@ -62,14 +98,53 @@ module RuboCop
62
98
  end
63
99
 
64
100
  subject_usage(node) do |subject_node|
65
- add_offense(subject_node.loc.selector)
101
+ check_explicit_subject(subject_node)
66
102
  end
67
103
  end
68
104
 
105
+ private
106
+
69
107
  def ignored_shared_example?(node)
70
108
  cop_config['IgnoreSharedExamples'] &&
71
109
  node.each_ancestor(:block).any?(&method(:shared_example?))
72
110
  end
111
+
112
+ def check_explicit_subject(node)
113
+ return if allow_explicit_subject?(node)
114
+
115
+ add_offense(node.loc.selector)
116
+ end
117
+
118
+ def allow_explicit_subject?(node)
119
+ !always? && !named_only?(node)
120
+ end
121
+
122
+ def always?
123
+ style == :always
124
+ end
125
+
126
+ def named_only?(node)
127
+ style == :named_only &&
128
+ subject_definition_is_named?(node)
129
+ end
130
+
131
+ def subject_definition_is_named?(node)
132
+ subject = nearest_subject(node)
133
+
134
+ subject&.send_node&.arguments?
135
+ end
136
+
137
+ def nearest_subject(node)
138
+ node
139
+ .each_ancestor(:block)
140
+ .lazy
141
+ .map { |block_node| find_subject(block_node) }
142
+ .find(&:itself)
143
+ end
144
+
145
+ def find_subject(block_node)
146
+ block_node.body.child_nodes.find { |send_node| subject?(send_node) }
147
+ end
73
148
  end
74
149
  end
75
150
  end
@@ -133,7 +133,7 @@ module RuboCop
133
133
  def count_up_nesting?(node, example_group)
134
134
  example_group &&
135
135
  (node.block_type? &&
136
- !allowed_groups.include?(node.method_name))
136
+ !allowed_groups.include?(node.method_name.to_s))
137
137
  end
138
138
 
139
139
  def message(nesting)
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Checks for pending or skipped examples without reason.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # pending 'does something' do
11
+ # end
12
+ #
13
+ # # bad
14
+ # it 'does something', :pending do
15
+ # end
16
+ #
17
+ # # bad
18
+ # it 'does something' do
19
+ # pending
20
+ # end
21
+ #
22
+ # # bad
23
+ # xdescribe 'something' do
24
+ # end
25
+ #
26
+ # # bad
27
+ # skip 'does something' do
28
+ # end
29
+ #
30
+ # # bad
31
+ # it 'does something', :skip do
32
+ # end
33
+ #
34
+ # # bad
35
+ # it 'does something' do
36
+ # skip
37
+ # end
38
+ #
39
+ # # bad
40
+ # it 'does something'
41
+ #
42
+ # # good
43
+ # it 'does something' do
44
+ # pending 'reason'
45
+ # end
46
+ #
47
+ # # good
48
+ # it 'does something' do
49
+ # skip 'reason'
50
+ # end
51
+ #
52
+ # # good
53
+ # it 'does something', pending: 'reason' do
54
+ # end
55
+ #
56
+ # # good
57
+ # it 'does something', skip: 'reason' do
58
+ # end
59
+ class PendingWithoutReason < Base
60
+ MSG = 'Give the reason for pending or skip.'
61
+
62
+ # @!method pending_by_example_method?(node)
63
+ def_node_matcher :pending_by_example_method?, block_pattern(<<~PATTERN)
64
+ #Examples.pending
65
+ PATTERN
66
+
67
+ # @!method pending_by_metadata_without_reason?(node)
68
+ def_node_matcher :pending_by_metadata_without_reason?, <<~PATTERN
69
+ (send #rspec? {#ExampleGroups.all #Examples.all} ... {<(sym :pending) ...> (hash <(pair (sym :pending) true) ...>)})
70
+ PATTERN
71
+
72
+ # @!method skipped_by_example_method?(node)
73
+ def_node_matcher :skipped_by_example_method?, block_pattern(<<~PATTERN)
74
+ #Examples.skipped
75
+ PATTERN
76
+
77
+ # @!method skipped_by_example_group_method?(node)
78
+ def_node_matcher(
79
+ :skipped_by_example_group_method?,
80
+ block_pattern(<<~PATTERN)
81
+ #ExampleGroups.skipped
82
+ PATTERN
83
+ )
84
+
85
+ # @!method skipped_by_metadata_without_reason?(node)
86
+ def_node_matcher :skipped_by_metadata_without_reason?, <<~PATTERN
87
+ (send #rspec? {#ExampleGroups.all #Examples.all} ... {<(sym :skip) ...> (hash <(pair (sym :skip) true) ...>)})
88
+ PATTERN
89
+
90
+ def on_send(node)
91
+ if pending_without_reason?(node)
92
+ add_offense(node, message: 'Give the reason for pending.')
93
+ elsif skipped_without_reason?(node)
94
+ add_offense(node, message: 'Give the reason for skip.')
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ def pending_by_pending_step_without_reason?(node)
101
+ node.method?(:pending) && node.first_argument.nil?
102
+ end
103
+
104
+ def pending_without_reason?(node)
105
+ pending_by_example_method?(node.block_node) ||
106
+ pending_by_metadata_without_reason?(node) ||
107
+ pending_by_pending_step_without_reason?(node)
108
+ end
109
+
110
+ def skipped_by_skip_step_without_reason?(node)
111
+ node.method?(:skip) && node.first_argument.nil?
112
+ end
113
+
114
+ def skipped_without_reason?(node)
115
+ skipped_by_example_group_method?(node.block_node) ||
116
+ skipped_by_example_method?(node.block_node) ||
117
+ skipped_by_metadata_without_reason?(node) ||
118
+ skipped_by_skip_step_without_reason?(node)
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -283,6 +283,8 @@ module RuboCop
283
283
  include InflectedHelper
284
284
  include ExplicitHelper
285
285
 
286
+ RESTRICT_ON_SEND = Runners.all
287
+
286
288
  def on_send(node)
287
289
  case style
288
290
  when :inflected
@@ -13,20 +13,23 @@ module RuboCop
13
13
  # # good
14
14
  # expect(response).to have_http_status(200)
15
15
  #
16
- class HaveHttpStatus < Base
16
+ class HaveHttpStatus < ::RuboCop::Cop::Base
17
17
  extend AutoCorrector
18
18
 
19
19
  MSG =
20
20
  'Prefer `expect(response).%<to>s have_http_status(%<status>i)` ' \
21
21
  'over `expect(response.status).%<to>s %<match>s`.'
22
22
 
23
+ RUNNERS = %i[to to_not not_to].to_set
24
+ RESTRICT_ON_SEND = RUNNERS
25
+
23
26
  # @!method match_status(node)
24
27
  def_node_matcher :match_status, <<-PATTERN
25
28
  (send
26
29
  (send nil? :expect
27
30
  $(send (send nil? :response) :status)
28
31
  )
29
- $#Runners.all
32
+ $RUNNERS
30
33
  $(send nil? {:be :eq :eql :equal} (int $_))
31
34
  )
32
35
  PATTERN
@@ -33,7 +33,7 @@ module RuboCop
33
33
  #
34
34
  # @example `Inferences` configuration
35
35
  # # .rubocop.yml
36
- # # RSpec/InferredSpecType:
36
+ # # RSpec/Rails/InferredSpecType:
37
37
  # # Inferences:
38
38
  # # services: service
39
39
  #
@@ -45,8 +45,12 @@ module RuboCop
45
45
  def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
46
46
  return unless example_group?(node)
47
47
 
48
- repeated_descriptions(node).each do |repeated_description|
49
- add_offense(repeated_description)
48
+ repeated_descriptions(node).each do |description|
49
+ add_offense(description)
50
+ end
51
+
52
+ repeated_its(node).each do |its|
53
+ add_offense(its)
50
54
  end
51
55
  end
52
56
 
@@ -57,6 +61,7 @@ module RuboCop
57
61
  grouped_examples =
58
62
  RuboCop::RSpec::ExampleGroup.new(node)
59
63
  .examples
64
+ .reject { |n| n.definition.method?(:its) }
60
65
  .group_by { |example| example_signature(example) }
61
66
 
62
67
  grouped_examples
@@ -66,9 +71,27 @@ module RuboCop
66
71
  .map(&:definition)
67
72
  end
68
73
 
74
+ def repeated_its(node)
75
+ grouped_its =
76
+ RuboCop::RSpec::ExampleGroup.new(node)
77
+ .examples
78
+ .select { |n| n.definition.method?(:its) }
79
+ .group_by { |example| its_signature(example) }
80
+
81
+ grouped_its
82
+ .select { |signatures, group| signatures.any? && group.size > 1 }
83
+ .values
84
+ .flatten
85
+ .map(&:to_node)
86
+ end
87
+
69
88
  def example_signature(example)
70
89
  [example.metadata, example.doc_string]
71
90
  end
91
+
92
+ def its_signature(example)
93
+ [example.doc_string, example]
94
+ end
72
95
  end
73
96
  end
74
97
  end
@@ -41,6 +41,8 @@ module RuboCop
41
41
  end
42
42
  end
43
43
 
44
+ private
45
+
44
46
  def repeated_hooks(node)
45
47
  hooks = RuboCop::RSpec::ExampleGroup.new(node)
46
48
  .hooks
@@ -18,45 +18,12 @@ module RuboCop
18
18
  #
19
19
  class SortMetadata < Base
20
20
  extend AutoCorrector
21
+ include Metadata
21
22
  include RangeHelp
22
23
 
23
24
  MSG = 'Sort metadata alphabetically.'
24
25
 
25
- # @!method rspec_metadata(node)
26
- def_node_matcher :rspec_metadata, <<~PATTERN
27
- (block
28
- (send
29
- #rspec? {#Examples.all #ExampleGroups.all #SharedGroups.all #Hooks.all} _ ${send str sym}* (hash $...)?)
30
- ...)
31
- PATTERN
32
-
33
- # @!method rspec_configure(node)
34
- def_node_matcher :rspec_configure, <<~PATTERN
35
- (block (send #rspec? :configure) (args (arg $_)) ...)
36
- PATTERN
37
-
38
- # @!method metadata_in_block(node)
39
- def_node_search :metadata_in_block, <<~PATTERN
40
- (send (lvar %) #Hooks.all _ ${send str sym}* (hash $...)?)
41
- PATTERN
42
-
43
- def on_block(node)
44
- rspec_configure(node) do |block_var|
45
- metadata_in_block(node, block_var) do |symbols, pairs|
46
- investigate(symbols, pairs.flatten)
47
- end
48
- end
49
-
50
- rspec_metadata(node) do |symbols, pairs|
51
- investigate(symbols, pairs.flatten)
52
- end
53
- end
54
-
55
- alias on_numblock on_block
56
-
57
- private
58
-
59
- def investigate(symbols, pairs)
26
+ def on_metadata(symbols, pairs)
60
27
  return if sorted?(symbols, pairs)
61
28
 
62
29
  crime_scene = crime_scene(symbols, pairs)
@@ -65,6 +32,8 @@ module RuboCop
65
32
  end
66
33
  end
67
34
 
35
+ private
36
+
68
37
  def crime_scene(symbols, pairs)
69
38
  metadata = symbols + pairs
70
39
 
@@ -133,6 +133,8 @@ module RuboCop
133
133
  }
134
134
  PATTERN
135
135
 
136
+ RESTRICT_ON_SEND = %i[to].freeze
137
+
136
138
  def on_send(node)
137
139
  expectation(node, &method(:on_expectation))
138
140
  end
@@ -50,6 +50,8 @@ module RuboCop
50
50
  add_offense(node.children.last)
51
51
  end
52
52
 
53
+ private
54
+
53
55
  def empty_exception_matcher?(node)
54
56
  empty_raise_error_or_exception(node) && !block_with_args?(node.parent)
55
57
  end
@@ -12,6 +12,7 @@ require_relative 'rspec/factory_bot/attribute_defined_statically'
12
12
  require_relative 'rspec/factory_bot/consistent_parentheses_style'
13
13
  require_relative 'rspec/factory_bot/create_list'
14
14
  require_relative 'rspec/factory_bot/factory_class_name'
15
+ require_relative 'rspec/factory_bot/factory_name_style'
15
16
  require_relative 'rspec/factory_bot/syntax_methods'
16
17
 
17
18
  require_relative 'rspec/rails/avoid_setup_hook'
@@ -42,6 +43,7 @@ require_relative 'rspec/describe_symbol'
42
43
  require_relative 'rspec/described_class'
43
44
  require_relative 'rspec/described_class_module_wrapping'
44
45
  require_relative 'rspec/dialect'
46
+ require_relative 'rspec/duplicated_metadata'
45
47
  require_relative 'rspec/empty_example_group'
46
48
  require_relative 'rspec/empty_hook'
47
49
  require_relative 'rspec/empty_line_after_example'
@@ -87,6 +89,7 @@ require_relative 'rspec/no_expectation_example'
87
89
  require_relative 'rspec/not_to_not'
88
90
  require_relative 'rspec/overwriting_setup'
89
91
  require_relative 'rspec/pending'
92
+ require_relative 'rspec/pending_without_reason'
90
93
  require_relative 'rspec/predicate_matcher'
91
94
  require_relative 'rspec/receive_counts'
92
95
  require_relative 'rspec/receive_never'
@@ -9,7 +9,7 @@ module RuboCop
9
9
  EXTENSION_ROOT_DEPARTMENT = %r{^(RSpec/)}.freeze
10
10
  SUBDEPARTMENTS = %(RSpec/Capybara RSpec/FactoryBot RSpec/Rails)
11
11
  AMENDMENTS = %(Metrics/BlockLength)
12
- COP_DOC_BASE_URL = 'https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/'
12
+ COP_DOC_BASE_URL = 'https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/'
13
13
 
14
14
  def initialize(config, descriptions)
15
15
  @config = config
@@ -47,7 +47,7 @@ module RuboCop
47
47
  end
48
48
 
49
49
  def reference(cop)
50
- COP_DOC_BASE_URL + cop.sub('RSpec/', '')
50
+ COP_DOC_BASE_URL + cop
51
51
  end
52
52
 
53
53
  attr_reader :config, :descriptions
@@ -21,7 +21,8 @@ module RuboCop
21
21
 
22
22
  # Decorator of a YARD code object for working with documented rspec cops
23
23
  class CodeObject
24
- COP_CLASS_NAME = 'RuboCop::Cop::RSpec::Base'
24
+ RSPEC_COP_CLASS_NAME = 'RuboCop::Cop::RSpec::Base'
25
+ RUBOCOP_COP_CLASS_NAME = 'RuboCop::Cop::Base'
25
26
  RSPEC_NAMESPACE = 'RuboCop::Cop::RSpec'
26
27
 
27
28
  def initialize(yardoc)
@@ -32,10 +33,7 @@ module RuboCop
32
33
  #
33
34
  # @return [Boolean]
34
35
  def rspec_cop?
35
- class_documentation? &&
36
- rspec_cop_namespace? &&
37
- cop_subclass? &&
38
- !abstract?
36
+ cop_subclass? && !abstract? && rspec_cop_namespace?
39
37
  end
40
38
 
41
39
  # Configuration for the documented cop that would live in default.yml
@@ -55,10 +53,6 @@ module RuboCop
55
53
  yardoc.docstring.split("\n\n").first.to_s
56
54
  end
57
55
 
58
- def class_documentation?
59
- yardoc.type.equal?(:class)
60
- end
61
-
62
56
  def rspec_cop_namespace?
63
57
  documented_constant.start_with?(RSPEC_NAMESPACE)
64
58
  end
@@ -68,7 +62,8 @@ module RuboCop
68
62
  end
69
63
 
70
64
  def cop_subclass?
71
- yardoc.superclass.path == COP_CLASS_NAME
65
+ yardoc.superclass.path == RSPEC_COP_CLASS_NAME ||
66
+ yardoc.superclass.path == RUBOCOP_COP_CLASS_NAME
72
67
  end
73
68
 
74
69
  def abstract?
@@ -135,8 +135,9 @@ module RuboCop
135
135
  end
136
136
 
137
137
  module HookScopes # :nodoc:
138
+ ALL = %i[each example context all suite].freeze
138
139
  def self.all(element)
139
- Language.config['HookScopes'].include?(element.to_s)
140
+ ALL.include?(element)
140
141
  end
141
142
  end
142
143
 
@@ -158,8 +159,13 @@ module RuboCop
158
159
  end
159
160
 
160
161
  module Runners # :nodoc:
161
- def self.all(element)
162
- Language.config['Runners'].include?(element.to_s)
162
+ ALL = %i[to to_not not_to].freeze
163
+ class << self
164
+ def all(element = nil)
165
+ return ALL if element.nil?
166
+
167
+ ALL.include?(element)
168
+ end
163
169
  end
164
170
  end
165
171
 
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_context 'with default RSpec/Language config' do
4
+ include_context 'config'
5
+
6
+ # Deep duplication is needed to prevent config leakage between examples
7
+ let(:other_cops) do
8
+ default_language = RuboCop::ConfigLoader
9
+ .default_configuration['RSpec']['Language']
10
+ default_include = RuboCop::ConfigLoader
11
+ .default_configuration['RSpec']['Include']
12
+ { 'RSpec' =>
13
+ {
14
+ 'Include' => default_include,
15
+ 'Language' => deep_dup(default_language)
16
+ } }
17
+ end
18
+
19
+ def deep_dup(object)
20
+ case object
21
+ when Array
22
+ object.map { |item| deep_dup(item) }
23
+ when Hash
24
+ object.transform_values(&method(:deep_dup))
25
+ else
26
+ object # only collections undergo modifications and need duping
27
+ end
28
+ end
29
+ end
@@ -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.14.2'
7
+ STRING = '2.16.0'
8
8
  end
9
9
  end
10
10
  end