rubocop-rspec 2.14.2 → 2.16.0

Sign up to get free protection for your applications and to get access to all the features.
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