rubocop-rspec 3.10.0 → 3.10.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 +6 -0
- data/config/default.yml +4 -1
- data/lib/rubocop/cop/rspec/expect_change.rb +45 -15
- data/lib/rubocop/cop/rspec/match_with_simple_regex.rb +2 -0
- data/lib/rubocop/cop/rspec/mixin/repeated_items.rb +36 -0
- data/lib/rubocop/cop/rspec/repeated_example.rb +6 -4
- data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +6 -10
- data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +6 -10
- data/lib/rubocop/cop/rspec/repeated_include_example.rb +8 -11
- data/lib/rubocop/cop/rspec/scattered_setup.rb +6 -8
- data/lib/rubocop/cop/rspec/shared_context.rb +46 -6
- data/lib/rubocop/rspec/version.rb +1 -1
- data/lib/rubocop-rspec.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4dd90ecda80edb7aeadd84bf5866b0d6b7d44dca8d56601782b5686fa75c970e
|
|
4
|
+
data.tar.gz: 5205b01345d70457d949142a464639589df5f87f3cd1ddfe7c8a64439bb519a1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cca8c27b7c61499264c8dd30009dd00a1c3d13cc5dda8efa4ff930706845d8c7ce7630f1402520dd421d36a1ed2971dfa62f0f182fc032ebae7920618ba3aaa9
|
|
7
|
+
data.tar.gz: b605960f8d588ccab7ebfa78874fe317e0fdf9c7db3b5cd0bdf682d226ac5326475f0cb05a123b491c21ccde6c60f82cc2cee18c30e593b6dc0ac204520fdebc
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## Master (Unreleased)
|
|
4
4
|
|
|
5
|
+
## 3.10.1 (2026-06-05)
|
|
6
|
+
|
|
7
|
+
- Add `Strict` option to `RSpec/SharedContext` to flag `shared_context` whenever it contains examples, even alongside setup code. ([@Darhazer])
|
|
8
|
+
- Add `NegatedMatcher` configuration option `RSpec/ExpectChange`. ([@Darhazer])
|
|
9
|
+
- Fix `RSpec/MatchWithSimpleRegex` to ignore regular expressions with interpolations. ([@bquorning])
|
|
10
|
+
|
|
5
11
|
## 3.10.0 (2026-06-05)
|
|
6
12
|
|
|
7
13
|
- Add new cop `RSpec/MatchWithSimpleRegex` to suggest `include` matcher when `match` is used with simple string literals without regex-specific features. ([@bquorning])
|
data/config/default.yml
CHANGED
|
@@ -460,7 +460,8 @@ RSpec/ExpectChange:
|
|
|
460
460
|
- block
|
|
461
461
|
SafeAutoCorrect: false
|
|
462
462
|
VersionAdded: '1.22'
|
|
463
|
-
VersionChanged: '
|
|
463
|
+
VersionChanged: '3.10'
|
|
464
|
+
NegatedMatcher: ~
|
|
464
465
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExpectChange
|
|
465
466
|
|
|
466
467
|
RSpec/ExpectInHook:
|
|
@@ -915,7 +916,9 @@ RSpec/ScatteredSetup:
|
|
|
915
916
|
RSpec/SharedContext:
|
|
916
917
|
Description: Checks for proper shared_context and shared_examples usage.
|
|
917
918
|
Enabled: true
|
|
919
|
+
Strict: false
|
|
918
920
|
VersionAdded: '1.13'
|
|
921
|
+
VersionChanged: '3.10'
|
|
919
922
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SharedContext
|
|
920
923
|
|
|
921
924
|
RSpec/SharedExamples:
|
|
@@ -10,6 +10,10 @@ module RuboCop
|
|
|
10
10
|
#
|
|
11
11
|
# This cop can be configured using the `EnforcedStyle` option.
|
|
12
12
|
#
|
|
13
|
+
# When using compound expectations with `change` and a negated matcher
|
|
14
|
+
# (e.g., `not_change`), you can configure the `NegatedMatcher` option
|
|
15
|
+
# to ensure consistent style enforcement across both matchers.
|
|
16
|
+
#
|
|
13
17
|
# @safety
|
|
14
18
|
# Autocorrection is unsafe because `method_call` style calls the
|
|
15
19
|
# receiver *once* and sends the message to it before and after
|
|
@@ -48,23 +52,29 @@ module RuboCop
|
|
|
48
52
|
# # good
|
|
49
53
|
# expect { run }.to change { Foo.bar }
|
|
50
54
|
#
|
|
55
|
+
# @example `NegatedMatcher: not_change` (with compound expectations)
|
|
56
|
+
# # bad
|
|
57
|
+
# expect { run }.to change(Foo, :bar).and not_change { Foo.baz }
|
|
58
|
+
#
|
|
59
|
+
# # good
|
|
60
|
+
# expect { run }.to change(Foo, :bar).and not_change(Foo, :baz)
|
|
61
|
+
#
|
|
51
62
|
class ExpectChange < Base
|
|
52
63
|
extend AutoCorrector
|
|
53
64
|
include ConfigurableEnforcedStyle
|
|
54
65
|
|
|
55
|
-
MSG_BLOCK = 'Prefer
|
|
56
|
-
MSG_CALL = 'Prefer
|
|
57
|
-
RESTRICT_ON_SEND = %i[change].freeze
|
|
66
|
+
MSG_BLOCK = 'Prefer `%<matcher>s(%<obj>s, :%<attr>s)`.'
|
|
67
|
+
MSG_CALL = 'Prefer `%<matcher>s { %<obj>s.%<attr>s }`.'
|
|
58
68
|
|
|
59
|
-
# @!method
|
|
60
|
-
def_node_matcher :
|
|
61
|
-
(send nil?
|
|
69
|
+
# @!method expect_matcher_with_arguments(node)
|
|
70
|
+
def_node_matcher :expect_matcher_with_arguments, <<~PATTERN
|
|
71
|
+
(send nil? _ $_ ({sym str} $_))
|
|
62
72
|
PATTERN
|
|
63
73
|
|
|
64
|
-
# @!method
|
|
65
|
-
def_node_matcher :
|
|
74
|
+
# @!method expect_matcher_with_block(node)
|
|
75
|
+
def_node_matcher :expect_matcher_with_block, <<~PATTERN
|
|
66
76
|
(block
|
|
67
|
-
(send nil?
|
|
77
|
+
(send nil? _)
|
|
68
78
|
(args)
|
|
69
79
|
(send
|
|
70
80
|
${
|
|
@@ -78,11 +88,14 @@ module RuboCop
|
|
|
78
88
|
|
|
79
89
|
def on_send(node)
|
|
80
90
|
return unless style == :block
|
|
91
|
+
return unless matcher_method?(node.method_name)
|
|
81
92
|
|
|
82
|
-
|
|
83
|
-
|
|
93
|
+
expect_matcher_with_arguments(node) do |receiver, message|
|
|
94
|
+
matcher_name = node.method_name.to_s
|
|
95
|
+
msg = format(MSG_CALL, matcher: matcher_name,
|
|
96
|
+
obj: receiver.source, attr: message)
|
|
84
97
|
add_offense(node, message: msg) do |corrector|
|
|
85
|
-
replacement = "
|
|
98
|
+
replacement = "#{matcher_name} { #{receiver.source}.#{message} }"
|
|
86
99
|
corrector.replace(node, replacement)
|
|
87
100
|
end
|
|
88
101
|
end
|
|
@@ -90,15 +103,32 @@ module RuboCop
|
|
|
90
103
|
|
|
91
104
|
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
92
105
|
return unless style == :method_call
|
|
106
|
+
return unless matcher_method?(node.method_name)
|
|
93
107
|
|
|
94
|
-
|
|
95
|
-
|
|
108
|
+
expect_matcher_with_block(node) do |receiver, message|
|
|
109
|
+
matcher_name = node.method_name.to_s
|
|
110
|
+
msg = format(MSG_BLOCK, matcher: matcher_name,
|
|
111
|
+
obj: receiver.source, attr: message)
|
|
96
112
|
add_offense(node, message: msg) do |corrector|
|
|
97
|
-
replacement = "
|
|
113
|
+
replacement = "#{matcher_name}(#{receiver.source}, :#{message})"
|
|
98
114
|
corrector.replace(node, replacement)
|
|
99
115
|
end
|
|
100
116
|
end
|
|
101
117
|
end
|
|
118
|
+
|
|
119
|
+
private
|
|
120
|
+
|
|
121
|
+
def matcher_method_names
|
|
122
|
+
[:change, negated_matcher&.to_sym].compact
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def matcher_method?(method_name)
|
|
126
|
+
matcher_method_names.include?(method_name)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def negated_matcher
|
|
130
|
+
cop_config['NegatedMatcher']
|
|
131
|
+
end
|
|
102
132
|
end
|
|
103
133
|
end
|
|
104
134
|
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module RSpec
|
|
6
|
+
# Helps find repeated items in a collection
|
|
7
|
+
#
|
|
8
|
+
# Provides a generic method to find repeated items by grouping them
|
|
9
|
+
# by a key and returning pairs of [item, repeated_lines] for items
|
|
10
|
+
# that appear more than once.
|
|
11
|
+
module RepeatedItems
|
|
12
|
+
# Groups items by key and returns only groups with more than one item
|
|
13
|
+
#
|
|
14
|
+
# @param items [Enumerable] the filtered collection to group
|
|
15
|
+
# @param key_proc [Proc] block returning the grouping key for each item
|
|
16
|
+
# @return [Array<Array>] array of groups containing more than one item
|
|
17
|
+
# that share the same key and there are multiple items in the group
|
|
18
|
+
def find_repeated_groups(items, key_proc:)
|
|
19
|
+
items
|
|
20
|
+
.group_by(&key_proc)
|
|
21
|
+
.values
|
|
22
|
+
.reject(&:one?)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Maps a group of items to pairs of [item, repeated_lines]
|
|
26
|
+
#
|
|
27
|
+
# @param items [Array] array of items that share the same key
|
|
28
|
+
# @return [Array<Array>] array of [item, repeated_lines] pairs
|
|
29
|
+
def add_repeated_lines(items)
|
|
30
|
+
repeated_lines = items.map(&:first_line)
|
|
31
|
+
items.map { |item| [item, repeated_lines - [item.first_line]] }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -16,6 +16,8 @@ module RuboCop
|
|
|
16
16
|
# end
|
|
17
17
|
#
|
|
18
18
|
class RepeatedExample < Base
|
|
19
|
+
include RepeatedItems
|
|
20
|
+
|
|
19
21
|
MSG = "Don't repeat examples within an example group. " \
|
|
20
22
|
'Repeated on line(s) %<lines>s.'
|
|
21
23
|
|
|
@@ -32,10 +34,10 @@ module RuboCop
|
|
|
32
34
|
def find_repeated_examples(node)
|
|
33
35
|
examples = RuboCop::RSpec::ExampleGroup.new(node).examples
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
find_repeated_groups(
|
|
38
|
+
examples,
|
|
39
|
+
key_proc: ->(example) { build_example_signature(example) }
|
|
40
|
+
)
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
def build_example_signature(example)
|
|
@@ -44,6 +44,7 @@ module RuboCop
|
|
|
44
44
|
#
|
|
45
45
|
class RepeatedExampleGroupBody < Base
|
|
46
46
|
include SkipOrPending
|
|
47
|
+
include RepeatedItems
|
|
47
48
|
|
|
48
49
|
MSG = 'Repeated %<group>s block body on line(s) %<loc>s'
|
|
49
50
|
|
|
@@ -72,19 +73,14 @@ module RuboCop
|
|
|
72
73
|
private
|
|
73
74
|
|
|
74
75
|
def repeated_group_bodies(node)
|
|
75
|
-
node
|
|
76
|
-
.children
|
|
76
|
+
items = node.children
|
|
77
77
|
.select { |child| example_group_with_body?(child) }
|
|
78
78
|
.reject { |child| skip_or_pending_inside_block?(child) }
|
|
79
|
-
.group_by { |group| signature_keys(group) }
|
|
80
|
-
.values
|
|
81
|
-
.reject(&:one?)
|
|
82
|
-
.flat_map { |groups| add_repeated_lines(groups) }
|
|
83
|
-
end
|
|
84
79
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
80
|
+
find_repeated_groups(
|
|
81
|
+
items,
|
|
82
|
+
key_proc: ->(group) { signature_keys(group) }
|
|
83
|
+
).flat_map { |group| add_repeated_lines(group) }
|
|
88
84
|
end
|
|
89
85
|
|
|
90
86
|
def signature_keys(group)
|
|
@@ -44,6 +44,7 @@ module RuboCop
|
|
|
44
44
|
#
|
|
45
45
|
class RepeatedExampleGroupDescription < Base
|
|
46
46
|
include SkipOrPending
|
|
47
|
+
include RepeatedItems
|
|
47
48
|
|
|
48
49
|
MSG = 'Repeated %<group>s block description on line(s) %<loc>s'
|
|
49
50
|
|
|
@@ -71,20 +72,15 @@ module RuboCop
|
|
|
71
72
|
private
|
|
72
73
|
|
|
73
74
|
def repeated_group_descriptions(node)
|
|
74
|
-
node
|
|
75
|
-
.children
|
|
75
|
+
items = node.children
|
|
76
76
|
.select { |child| example_group?(child) }
|
|
77
77
|
.reject { |child| skip_or_pending_inside_block?(child) }
|
|
78
78
|
.reject { |child| empty_description?(child) }
|
|
79
|
-
.group_by { |group| doc_string_and_metadata(group) }
|
|
80
|
-
.values
|
|
81
|
-
.reject(&:one?)
|
|
82
|
-
.flat_map { |groups| add_repeated_lines(groups) }
|
|
83
|
-
end
|
|
84
79
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
80
|
+
find_repeated_groups(
|
|
81
|
+
items,
|
|
82
|
+
key_proc: ->(group) { doc_string_and_metadata(group) }
|
|
83
|
+
).flat_map { |group| add_repeated_lines(group) }
|
|
88
84
|
end
|
|
89
85
|
|
|
90
86
|
def message(group, repeats)
|
|
@@ -46,6 +46,8 @@ module RuboCop
|
|
|
46
46
|
# end
|
|
47
47
|
#
|
|
48
48
|
class RepeatedIncludeExample < Base
|
|
49
|
+
include RepeatedItems
|
|
50
|
+
|
|
49
51
|
MSG = 'Repeated include of shared_examples %<name>s ' \
|
|
50
52
|
'on line(s) %<repeat>s'
|
|
51
53
|
|
|
@@ -73,13 +75,13 @@ module RuboCop
|
|
|
73
75
|
private
|
|
74
76
|
|
|
75
77
|
def repeated_include_examples(node)
|
|
76
|
-
node
|
|
77
|
-
.children
|
|
78
|
+
items = node.children
|
|
78
79
|
.select { |child| literal_include_examples?(child) }
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
|
|
81
|
+
find_repeated_groups(
|
|
82
|
+
items,
|
|
83
|
+
key_proc: ->(child) { signature_keys(child) }
|
|
84
|
+
).flat_map { |group| add_repeated_lines(group) }
|
|
83
85
|
end
|
|
84
86
|
|
|
85
87
|
def literal_include_examples?(node)
|
|
@@ -87,11 +89,6 @@ module RuboCop
|
|
|
87
89
|
node.arguments.all?(&:recursive_literal_or_const?)
|
|
88
90
|
end
|
|
89
91
|
|
|
90
|
-
def add_repeated_lines(items)
|
|
91
|
-
repeated_lines = items.map(&:first_line)
|
|
92
|
-
items.map { |item| [item, repeated_lines - [item.first_line]] }
|
|
93
|
-
end
|
|
94
|
-
|
|
95
92
|
def signature_keys(item)
|
|
96
93
|
item.arguments
|
|
97
94
|
end
|
|
@@ -42,6 +42,7 @@ module RuboCop
|
|
|
42
42
|
class ScatteredSetup < Base
|
|
43
43
|
include FinalEndLocation
|
|
44
44
|
include RangeHelp
|
|
45
|
+
include RepeatedItems
|
|
45
46
|
extend AutoCorrector
|
|
46
47
|
|
|
47
48
|
MSG = 'Do not define multiple `%<hook_name>s` hooks in the same ' \
|
|
@@ -63,17 +64,14 @@ module RuboCop
|
|
|
63
64
|
private
|
|
64
65
|
|
|
65
66
|
def repeated_hooks(node) # rubocop:disable Metrics/CyclomaticComplexity
|
|
66
|
-
hooks = RuboCop::RSpec::ExampleGroup.new(node)
|
|
67
|
-
.hooks
|
|
67
|
+
hooks = RuboCop::RSpec::ExampleGroup.new(node).hooks
|
|
68
68
|
.reject(&:inside_class_method?)
|
|
69
69
|
.select { |hook| hook.knowable_scope? && hook.name != :around }
|
|
70
|
-
.group_by { |hook| [hook.name, hook.scope, hook.metadata] }
|
|
71
|
-
.values
|
|
72
|
-
.reject(&:one?)
|
|
73
70
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
find_repeated_groups(
|
|
72
|
+
hooks,
|
|
73
|
+
key_proc: ->(hook) { [hook.name, hook.scope, hook.metadata] }
|
|
74
|
+
).map { |hook_group| hook_group.map(&:to_node) }
|
|
77
75
|
end
|
|
78
76
|
|
|
79
77
|
def lines_msg(numbers)
|
|
@@ -8,6 +8,9 @@ module RuboCop
|
|
|
8
8
|
# If there are no examples defined, use shared_context.
|
|
9
9
|
# If there is no setup defined, use shared_examples.
|
|
10
10
|
#
|
|
11
|
+
# With `Strict: true`, `shared_context` is flagged whenever it contains
|
|
12
|
+
# any examples, even if it also contains setup code.
|
|
13
|
+
#
|
|
11
14
|
# @example
|
|
12
15
|
# # bad
|
|
13
16
|
# RSpec.shared_context 'only examples here' do
|
|
@@ -50,11 +53,31 @@ module RuboCop
|
|
|
50
53
|
# end
|
|
51
54
|
# end
|
|
52
55
|
#
|
|
56
|
+
# @example Strict: true
|
|
57
|
+
# # bad - shared_context with examples is flagged
|
|
58
|
+
# RSpec.shared_context 'setup and examples' do
|
|
59
|
+
# let(:foo) { :bar }
|
|
60
|
+
#
|
|
61
|
+
# it 'does x' do
|
|
62
|
+
# end
|
|
63
|
+
# end
|
|
64
|
+
#
|
|
65
|
+
# # good - split into separate shared_context and shared_examples
|
|
66
|
+
# RSpec.shared_context 'setup' do
|
|
67
|
+
# let(:foo) { :bar }
|
|
68
|
+
# end
|
|
69
|
+
#
|
|
70
|
+
# RSpec.shared_examples 'examples' do
|
|
71
|
+
# it 'does x' do
|
|
72
|
+
# end
|
|
73
|
+
# end
|
|
74
|
+
#
|
|
53
75
|
class SharedContext < Base
|
|
54
76
|
extend AutoCorrector
|
|
55
77
|
|
|
56
78
|
MSG_EXAMPLES = "Use `shared_examples` when you don't define context."
|
|
57
|
-
|
|
79
|
+
MSG_EXAMPLES_STRICT = 'Use `shared_examples` when you define examples.'
|
|
80
|
+
MSG_CONTEXT = "Use `shared_context` when you don't define examples."
|
|
58
81
|
|
|
59
82
|
# @!method examples?(node)
|
|
60
83
|
def_node_search :examples?, <<~PATTERN
|
|
@@ -79,9 +102,12 @@ module RuboCop
|
|
|
79
102
|
PATTERN
|
|
80
103
|
|
|
81
104
|
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
82
|
-
|
|
83
|
-
add_offense(node.send_node, message:
|
|
84
|
-
|
|
105
|
+
offending_node(node) do
|
|
106
|
+
add_offense(node.send_node, message: message) do |corrector|
|
|
107
|
+
if can_correct?(node)
|
|
108
|
+
corrector.replace(node.send_node.loc.selector,
|
|
109
|
+
'shared_examples')
|
|
110
|
+
end
|
|
85
111
|
end
|
|
86
112
|
end
|
|
87
113
|
|
|
@@ -94,8 +120,22 @@ module RuboCop
|
|
|
94
120
|
|
|
95
121
|
private
|
|
96
122
|
|
|
97
|
-
def
|
|
98
|
-
|
|
123
|
+
def strict?
|
|
124
|
+
cop_config.fetch('Strict', false)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def message
|
|
128
|
+
strict? ? MSG_EXAMPLES_STRICT : MSG_EXAMPLES
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def can_correct?(node)
|
|
132
|
+
!strict? || !context?(node)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def offending_node(node)
|
|
136
|
+
shared_context(node) do
|
|
137
|
+
yield if examples?(node) && (strict? || !context?(node))
|
|
138
|
+
end
|
|
99
139
|
end
|
|
100
140
|
|
|
101
141
|
def examples_with_only_context(node)
|
data/lib/rubocop-rspec.rb
CHANGED
|
@@ -19,6 +19,7 @@ require_relative 'rubocop/cop/rspec/mixin/inside_example_group'
|
|
|
19
19
|
require_relative 'rubocop/cop/rspec/mixin/location_help'
|
|
20
20
|
require_relative 'rubocop/cop/rspec/mixin/metadata'
|
|
21
21
|
require_relative 'rubocop/cop/rspec/mixin/namespace'
|
|
22
|
+
require_relative 'rubocop/cop/rspec/mixin/repeated_items'
|
|
22
23
|
require_relative 'rubocop/cop/rspec/mixin/skip_or_pending'
|
|
23
24
|
require_relative 'rubocop/cop/rspec/mixin/top_level_group'
|
|
24
25
|
require_relative 'rubocop/cop/rspec/mixin/variable'
|
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: 3.10.
|
|
4
|
+
version: 3.10.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- John Backus
|
|
@@ -158,6 +158,7 @@ files:
|
|
|
158
158
|
- lib/rubocop/cop/rspec/mixin/location_help.rb
|
|
159
159
|
- lib/rubocop/cop/rspec/mixin/metadata.rb
|
|
160
160
|
- lib/rubocop/cop/rspec/mixin/namespace.rb
|
|
161
|
+
- lib/rubocop/cop/rspec/mixin/repeated_items.rb
|
|
161
162
|
- lib/rubocop/cop/rspec/mixin/skip_or_pending.rb
|
|
162
163
|
- lib/rubocop/cop/rspec/mixin/top_level_group.rb
|
|
163
164
|
- lib/rubocop/cop/rspec/mixin/variable.rb
|