rubocop-rspec 1.20.1 → 1.21.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/config/default.yml +1 -0
- data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +2 -2
- data/lib/rubocop/cop/rspec/cop.rb +22 -2
- data/lib/rubocop/cop/rspec/described_class.rb +4 -3
- data/lib/rubocop/cop/rspec/example_length.rb +2 -2
- data/lib/rubocop/cop/rspec/file_path.rb +6 -2
- data/lib/rubocop/cop/rspec/hook_argument.rb +6 -5
- data/lib/rubocop/cop/rspec/it_behaves_like.rb +3 -3
- data/lib/rubocop/cop/rspec/leading_subject.rb +6 -2
- data/lib/rubocop/cop/rspec/message_expectation.rb +3 -2
- data/lib/rubocop/cop/rspec/message_spies.rb +3 -3
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +6 -1
- data/lib/rubocop/cop/rspec/nested_groups.rb +3 -2
- data/lib/rubocop/cop/rspec/not_to_not.rb +2 -2
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +2 -2
- data/lib/rubocop/rspec/version.rb +1 -1
- data/rubocop-rspec.gemspec +1 -1
- data/spec/rubocop/cop/rspec/cop_spec.rb +1 -0
- data/spec/rubocop/cop/rspec/factory_bot/dynamic_attribute_defined_statically_spec.rb +2 -0
- data/spec/rubocop/cop/rspec/focus_spec.rb +1 -0
- data/spec/rubocop/cop/rspec/multiple_expectations_spec.rb +52 -1
- data/spec/rubocop/rspec/example_spec.rb +2 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db6a354c4b2a3ba18944c5a6fc3ce076eaec380b3f84b67d3a825ab81a2f18a2
|
4
|
+
data.tar.gz: c15d5bb4a019e0ff6d419058e136959aa54af22a409e302c4cbd012f06960ba6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd09459ea1199299104e462a6592ffe6ecba612f6560e4f5003c13c302cf47a9b21b5da186cb7237378c2187f83c63894fb0a89780ce9c22d328b4cfb9795c81
|
7
|
+
data.tar.gz: 2f24de47526a5719c96772d5c4e557fc37d2cc39472c372e0c3c6d4913a47cee1568bb06547de1d67684d1afd60b8875c7073e162b8e637e5718b4b4f8972839
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
## Master (Unreleased)
|
4
4
|
|
5
|
+
## 1.21.0 (2017-12-13)
|
6
|
+
|
7
|
+
* Compatibility with RuboCop v0.52.0. ([@bquorning][])
|
8
|
+
* Improve performance when user does not override default RSpec Pattern config. ([@walf443][])
|
9
|
+
* Add `AggregateFailuresByDefault` configuration for `RSpec/MultipleExpectations` cop. ([@onk][])
|
10
|
+
|
5
11
|
## 1.20.1 (2017-11-15)
|
6
12
|
|
7
13
|
* Add "without" to list of default allowed prefixes for `RSpec/ContextWording`. ([@bquorning][])
|
data/config/default.yml
CHANGED
@@ -237,6 +237,7 @@ RSpec/MultipleExpectations:
|
|
237
237
|
Description: Checks if examples contain too many `expect` calls.
|
238
238
|
Enabled: true
|
239
239
|
Max: 1
|
240
|
+
AggregateFailuresByDefault: false
|
240
241
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleExpectations
|
241
242
|
|
242
243
|
RSpec/MultipleSubjects:
|
@@ -33,7 +33,7 @@ module RuboCop
|
|
33
33
|
# end
|
34
34
|
# end
|
35
35
|
class FeatureMethods < Cop
|
36
|
-
MSG = 'Use
|
36
|
+
MSG = 'Use `%<replacement>s` instead of `%<method>s`.'.freeze
|
37
37
|
|
38
38
|
# https://git.io/v7Kwr
|
39
39
|
MAP = {
|
@@ -56,7 +56,7 @@ module RuboCop
|
|
56
56
|
add_offense(
|
57
57
|
send_node,
|
58
58
|
location: :selector,
|
59
|
-
message: format(MSG, MAP[match]
|
59
|
+
message: format(MSG, method: match, replacement: MAP[match])
|
60
60
|
)
|
61
61
|
end
|
62
62
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RuboCop
|
2
4
|
module Cop # rubocop:disable Style/Documentation
|
3
5
|
WorkaroundCop = Cop.dup
|
@@ -42,6 +44,11 @@ module RuboCop
|
|
42
44
|
DEFAULT_CONFIGURATION =
|
43
45
|
RuboCop::RSpec::CONFIG.fetch('AllCops').fetch('RSpec')
|
44
46
|
|
47
|
+
DEFAULT_PATTERN_RE = Regexp.union(
|
48
|
+
DEFAULT_CONFIGURATION.fetch('Patterns')
|
49
|
+
.map(&Regexp.public_method(:new))
|
50
|
+
)
|
51
|
+
|
45
52
|
# Invoke the original inherited hook so our cops are recognized
|
46
53
|
def self.inherited(subclass)
|
47
54
|
RuboCop::Cop::Cop.inherited(subclass)
|
@@ -58,12 +65,25 @@ module RuboCop
|
|
58
65
|
end
|
59
66
|
|
60
67
|
def rspec_pattern
|
61
|
-
|
68
|
+
if rspec_pattern_config?
|
69
|
+
Regexp.union(rspec_pattern_config.map(&Regexp.public_method(:new)))
|
70
|
+
else
|
71
|
+
DEFAULT_PATTERN_RE
|
72
|
+
end
|
62
73
|
end
|
63
74
|
|
64
|
-
def
|
75
|
+
def all_cops_config
|
65
76
|
config
|
66
77
|
.for_all_cops
|
78
|
+
end
|
79
|
+
|
80
|
+
def rspec_pattern_config?
|
81
|
+
return unless all_cops_config.key?('RSpec')
|
82
|
+
all_cops_config.fetch('RSpec').key?('Patterns')
|
83
|
+
end
|
84
|
+
|
85
|
+
def rspec_pattern_config
|
86
|
+
all_cops_config
|
67
87
|
.fetch('RSpec', DEFAULT_CONFIGURATION)
|
68
88
|
.fetch('Patterns')
|
69
89
|
end
|
@@ -37,7 +37,7 @@ module RuboCop
|
|
37
37
|
include ConfigurableEnforcedStyle
|
38
38
|
|
39
39
|
DESCRIBED_CLASS = 'described_class'.freeze
|
40
|
-
MSG = 'Use
|
40
|
+
MSG = 'Use `%<replacement>s` instead of `%<src>s`.'.freeze
|
41
41
|
|
42
42
|
def_node_matcher :common_instance_exec_closure?, <<-PATTERN
|
43
43
|
(block (send (const nil? {:Class :Module}) :new ...) ...)
|
@@ -91,9 +91,10 @@ module RuboCop
|
|
91
91
|
|
92
92
|
def message(offense)
|
93
93
|
if style == :described_class
|
94
|
-
format(MSG, DESCRIBED_CLASS, offense)
|
94
|
+
format(MSG, replacement: DESCRIBED_CLASS, src: offense)
|
95
95
|
else
|
96
|
-
format(MSG, @described_class.const_name,
|
96
|
+
format(MSG, replacement: @described_class.const_name,
|
97
|
+
src: DESCRIBED_CLASS)
|
97
98
|
end
|
98
99
|
end
|
99
100
|
|
@@ -28,7 +28,7 @@ module RuboCop
|
|
28
28
|
class ExampleLength < Cop
|
29
29
|
include CodeLength
|
30
30
|
|
31
|
-
MSG = 'Example has too many lines [
|
31
|
+
MSG = 'Example has too many lines [%<total>d/%<max>d].'.freeze
|
32
32
|
|
33
33
|
def on_block(node)
|
34
34
|
return unless example?(node)
|
@@ -47,7 +47,7 @@ module RuboCop
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def message(length)
|
50
|
-
format(MSG, length, max_length)
|
50
|
+
format(MSG, total: length, max: max_length)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
@@ -44,7 +44,7 @@ module RuboCop
|
|
44
44
|
class FilePath < Cop
|
45
45
|
include RuboCop::RSpec::TopLevelDescribe
|
46
46
|
|
47
|
-
MSG = 'Spec path should end with
|
47
|
+
MSG = 'Spec path should end with `%<suffix>s`.'.freeze
|
48
48
|
|
49
49
|
def_node_search :const_described?, '(send _ :describe (const ...) ...)'
|
50
50
|
def_node_search :routing_metadata?, '(pair (sym :type) (sym :routing))'
|
@@ -57,7 +57,11 @@ module RuboCop
|
|
57
57
|
|
58
58
|
return if filename_ends_with?(glob)
|
59
59
|
|
60
|
-
add_offense(
|
60
|
+
add_offense(
|
61
|
+
node,
|
62
|
+
location: :expression,
|
63
|
+
message: format(MSG, suffix: glob)
|
64
|
+
)
|
61
65
|
end
|
62
66
|
|
63
67
|
private
|
@@ -60,8 +60,9 @@ module RuboCop
|
|
60
60
|
class HookArgument < Cop
|
61
61
|
include ConfigurableEnforcedStyle
|
62
62
|
|
63
|
-
IMPLICIT_MSG = 'Omit the default
|
64
|
-
|
63
|
+
IMPLICIT_MSG = 'Omit the default `%<scope>p` ' \
|
64
|
+
'argument for RSpec hooks.'.freeze
|
65
|
+
EXPLICIT_MSG = 'Use `%<scope>p` for RSpec hooks.'.freeze
|
65
66
|
|
66
67
|
HOOKS = Hooks::ALL.node_pattern_union.freeze
|
67
68
|
|
@@ -102,15 +103,15 @@ module RuboCop
|
|
102
103
|
add_offense(
|
103
104
|
method_send,
|
104
105
|
location: :selector,
|
105
|
-
message: format(EXPLICIT_MSG, style)
|
106
|
+
message: format(EXPLICIT_MSG, scope: style)
|
106
107
|
)
|
107
108
|
end
|
108
109
|
|
109
110
|
def explicit_message(scope)
|
110
111
|
if implicit_style?
|
111
|
-
format(IMPLICIT_MSG, scope)
|
112
|
+
format(IMPLICIT_MSG, scope: scope)
|
112
113
|
else
|
113
|
-
format(EXPLICIT_MSG, style)
|
114
|
+
format(EXPLICIT_MSG, scope: style)
|
114
115
|
end
|
115
116
|
end
|
116
117
|
|
@@ -21,8 +21,8 @@ module RuboCop
|
|
21
21
|
class ItBehavesLike < Cop
|
22
22
|
include ConfigurableEnforcedStyle
|
23
23
|
|
24
|
-
MSG = 'Prefer
|
25
|
-
'a nested context.'.freeze
|
24
|
+
MSG = 'Prefer `%<replacement>s` over `%<original>s` when including '\
|
25
|
+
'examples in a nested context.'.freeze
|
26
26
|
|
27
27
|
def_node_matcher :example_inclusion_offense, '(send _ % ...)'
|
28
28
|
|
@@ -39,7 +39,7 @@ module RuboCop
|
|
39
39
|
private
|
40
40
|
|
41
41
|
def message(_node)
|
42
|
-
format(MSG, style, alternative_style)
|
42
|
+
format(MSG, replacement: style, original: alternative_style)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
@@ -63,8 +63,12 @@ module RuboCop
|
|
63
63
|
|
64
64
|
def node_range(node)
|
65
65
|
range = node.source_range
|
66
|
-
range = range_with_surrounding_space(
|
67
|
-
|
66
|
+
range = range_with_surrounding_space(
|
67
|
+
range: range, side: :left, newlines: false
|
68
|
+
)
|
69
|
+
range = range_with_surrounding_space(
|
70
|
+
range: range, side: :right, newlines: true
|
71
|
+
)
|
68
72
|
range
|
69
73
|
end
|
70
74
|
|
@@ -27,7 +27,7 @@ module RuboCop
|
|
27
27
|
class MessageExpectation < Cop
|
28
28
|
include ConfigurableEnforcedStyle
|
29
29
|
|
30
|
-
MSG = 'Prefer
|
30
|
+
MSG = 'Prefer `%<style>s` for setting message expectations.'.freeze
|
31
31
|
|
32
32
|
SUPPORTED_STYLES = %w[allow expect].freeze
|
33
33
|
|
@@ -41,7 +41,8 @@ module RuboCop
|
|
41
41
|
message_expectation(node) do |match|
|
42
42
|
return correct_style_detected if preferred_style?(match)
|
43
43
|
|
44
|
-
|
44
|
+
message = format(MSG, style: style)
|
45
|
+
add_offense(match, location: :selector, message: message) do
|
45
46
|
opposite_style_detected
|
46
47
|
end
|
47
48
|
end
|
@@ -31,8 +31,8 @@ module RuboCop
|
|
31
31
|
'expectations.'.freeze
|
32
32
|
|
33
33
|
MSG_HAVE_RECEIVED = 'Prefer `have_received` for setting message '\
|
34
|
-
'expectations. Setup
|
35
|
-
' or `instance_spy`.'.freeze
|
34
|
+
'expectations. Setup `%<source>s` as a spy using '\
|
35
|
+
'`allow` or `instance_spy`.'.freeze
|
36
36
|
|
37
37
|
SUPPORTED_STYLES = %w[have_received receive].freeze
|
38
38
|
|
@@ -73,7 +73,7 @@ module RuboCop
|
|
73
73
|
when :receive
|
74
74
|
MSG_RECEIVE
|
75
75
|
when :have_received
|
76
|
-
MSG_HAVE_RECEIVED
|
76
|
+
format(MSG_HAVE_RECEIVED, source: receiver.source)
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
@@ -79,7 +79,8 @@ module RuboCop
|
|
79
79
|
def example_with_aggregated_failures?(node)
|
80
80
|
example = node.children.first
|
81
81
|
|
82
|
-
|
82
|
+
(aggregated_failures_by_default? ||
|
83
|
+
with_aggregated_failures?(example)) &&
|
83
84
|
!disabled_aggregated_failures?(example)
|
84
85
|
end
|
85
86
|
|
@@ -111,6 +112,10 @@ module RuboCop
|
|
111
112
|
def max_expectations
|
112
113
|
Integer(cop_config.fetch('Max', 1))
|
113
114
|
end
|
115
|
+
|
116
|
+
def aggregated_failures_by_default?
|
117
|
+
cop_config.fetch('AggregateFailuresByDefault', false)
|
118
|
+
end
|
114
119
|
end
|
115
120
|
end
|
116
121
|
end
|
@@ -87,7 +87,8 @@ module RuboCop
|
|
87
87
|
class NestedGroups < Cop
|
88
88
|
include RuboCop::RSpec::TopLevelDescribe
|
89
89
|
|
90
|
-
MSG = 'Maximum example group nesting exceeded
|
90
|
+
MSG = 'Maximum example group nesting exceeded ' \
|
91
|
+
'[%<total>d/%<max>d].'.freeze
|
91
92
|
|
92
93
|
DEPRECATED_MAX_KEY = 'MaxNesting'.freeze
|
93
94
|
|
@@ -120,7 +121,7 @@ module RuboCop
|
|
120
121
|
end
|
121
122
|
|
122
123
|
def message(nesting)
|
123
|
-
format(MSG, nesting, max_nesting)
|
124
|
+
format(MSG, total: nesting, max: max_nesting)
|
124
125
|
end
|
125
126
|
|
126
127
|
def max_nesting
|
@@ -16,7 +16,7 @@ module RuboCop
|
|
16
16
|
class NotToNot < Cop
|
17
17
|
include ConfigurableEnforcedStyle
|
18
18
|
|
19
|
-
MSG = 'Prefer
|
19
|
+
MSG = 'Prefer `%<replacement>s` over `%<original>s`.'.freeze
|
20
20
|
|
21
21
|
def_node_matcher :not_to_not_offense, '(send _ % ...)'
|
22
22
|
|
@@ -33,7 +33,7 @@ module RuboCop
|
|
33
33
|
private
|
34
34
|
|
35
35
|
def message(_node)
|
36
|
-
format(MSG, style, alternative_style)
|
36
|
+
format(MSG, replacement: style, original: alternative_style)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -311,8 +311,6 @@ module RuboCop
|
|
311
311
|
check_explicit(node) if style == :explicit
|
312
312
|
end
|
313
313
|
|
314
|
-
private
|
315
|
-
|
316
314
|
def autocorrect(node)
|
317
315
|
case style
|
318
316
|
when :inflected
|
@@ -322,6 +320,8 @@ module RuboCop
|
|
322
320
|
end
|
323
321
|
end
|
324
322
|
|
323
|
+
private
|
324
|
+
|
325
325
|
# returns args location with whitespace
|
326
326
|
# @example
|
327
327
|
# foo 1, 2
|
data/rubocop-rspec.gemspec
CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.test_files = spec.files.grep(%r{^spec/})
|
33
33
|
spec.extra_rdoc_files = ['MIT-LICENSE.md', 'README.md']
|
34
34
|
|
35
|
-
spec.add_runtime_dependency 'rubocop', '>= 0.
|
35
|
+
spec.add_runtime_dependency 'rubocop', '>= 0.52.0'
|
36
36
|
|
37
37
|
spec.add_development_dependency 'rake'
|
38
38
|
spec.add_development_dependency 'rspec', '>= 3.4'
|
@@ -132,7 +132,7 @@ RSpec.describe RuboCop::Cop::RSpec::MultipleExpectations, :config do
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
|
-
context 'with configuration' do
|
135
|
+
context 'with Max configuration' do
|
136
136
|
let(:cop_config) do
|
137
137
|
{ 'Max' => '2' }
|
138
138
|
end
|
@@ -162,6 +162,57 @@ RSpec.describe RuboCop::Cop::RSpec::MultipleExpectations, :config do
|
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
165
|
+
context 'with AggregateFailuresByDefault configuration' do
|
166
|
+
let(:cop_config) do
|
167
|
+
{ 'AggregateFailuresByDefault' => true }
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'ignores examples without metadata' do
|
171
|
+
expect_no_offenses(<<-RUBY)
|
172
|
+
describe Foo do
|
173
|
+
it 'uses expect twice' do
|
174
|
+
expect(foo).to eq(bar)
|
175
|
+
expect(baz).to eq(bar)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
RUBY
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'ignores examples with `:aggregate_failures`' do
|
182
|
+
expect_no_offenses(<<-RUBY)
|
183
|
+
describe Foo do
|
184
|
+
it 'uses expect twice', :aggregate_failures do
|
185
|
+
expect(foo).to eq(bar)
|
186
|
+
expect(baz).to eq(bar)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
RUBY
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'ignores examples with `aggregate_failures: true`' do
|
193
|
+
expect_no_offenses(<<-RUBY)
|
194
|
+
describe Foo do
|
195
|
+
it 'uses expect twice', aggregate_failures: true do
|
196
|
+
expect(foo).to eq(bar)
|
197
|
+
expect(baz).to eq(bar)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
RUBY
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'checks examples with `aggregate_failures: false`' do
|
204
|
+
expect_offense(<<-RUBY)
|
205
|
+
describe Foo do
|
206
|
+
it 'uses expect twice', aggregate_failures: false do
|
207
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Example has too many expectations [2/1].
|
208
|
+
expect(foo).to eq(bar)
|
209
|
+
expect(baz).to eq(bar)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
RUBY
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
165
216
|
it 'generates a todo based on the worst violation' do
|
166
217
|
inspect_source(<<-RUBY, 'spec/foo_spec.rb')
|
167
218
|
describe Foo do
|
@@ -9,12 +9,12 @@ RSpec.describe RuboCop::RSpec::Example do
|
|
9
9
|
|
10
10
|
it 'extracts doc string' do
|
11
11
|
expect(example("it('does x') { foo }").doc_string)
|
12
|
-
.to
|
12
|
+
.to eq(s(:str, 'does x'))
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'extracts doc string for unimplemented examples' do
|
16
16
|
expect(example("it('does x')").doc_string)
|
17
|
-
.to
|
17
|
+
.to eq(s(:str, 'does x'))
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'returns nil for examples without doc strings' do
|
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.
|
4
|
+
version: 1.21.0
|
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-12-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rubocop
|
@@ -18,14 +18,14 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.
|
21
|
+
version: 0.52.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 0.
|
28
|
+
version: 0.52.0
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: rake
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|