rubocop-rspec 1.20.1 → 1.21.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc22359823d51921927c6eccc2042da9aeba3da2ce8587e23afdbe55bc3b2840
4
- data.tar.gz: 2444605d47dbe964004743b2581a849ccd571c0fbbdc0bd398a6c03755842e4c
3
+ metadata.gz: db6a354c4b2a3ba18944c5a6fc3ce076eaec380b3f84b67d3a825ab81a2f18a2
4
+ data.tar.gz: c15d5bb4a019e0ff6d419058e136959aa54af22a409e302c4cbd012f06960ba6
5
5
  SHA512:
6
- metadata.gz: dc6aaa5e37a13006b8e66478889cad7a51ce8599075d0304f21cd235cab42ae62209a2bede56a0dd984956302719ef00477680ac4bc6c3cd766a456fc8742d7c
7
- data.tar.gz: 597ed8a84f733c73bb489b722fb26fbc2120514bf19b6fd091641094a2da8d3f7b3942fe1be33150cfa2c0f96bc926d191658df42226ac19b6ff97e9d7955997
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 `%s` instead of `%s`.'.freeze
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], 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
- Regexp.union(rspec_pattern_config.map(&Regexp.public_method(:new)))
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 rspec_pattern_config
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 `%s` instead of `%s`.'.freeze
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, DESCRIBED_CLASS)
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 [%d/%d].'.freeze
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 `%s`.'.freeze
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(node, location: :expression, message: format(MSG, glob))
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 `%p` argument for RSpec hooks.'.freeze
64
- EXPLICIT_MSG = 'Use `%p` for RSpec hooks.'.freeze
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 `%s` over `%s` when including examples in '\
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(range, :left, false)
67
- range = range_with_surrounding_space(range, :right, true)
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 `%s` for setting message expectations.'.freeze
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
- add_offense(match, location: :selector, message: MSG % style) do
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 `%s` as a spy using `allow`'\
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 % receiver.source
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
- with_aggregated_failures?(example) &&
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 [%d/%d].'.freeze
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 `%s` over `%s`.'.freeze
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
@@ -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 = '1.20.1'.freeze
7
+ STRING = '1.21.0'.freeze
8
8
  end
9
9
  end
10
10
  end
@@ -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.51.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'
@@ -31,6 +31,7 @@ RSpec.describe RuboCop::Cop::RSpec::Cop do
31
31
  add_offense(node, location: :expression, message: 'I flag everything')
32
32
  end
33
33
  end
34
+ # rubocop:enable ClassAndModuleChildren
34
35
  RuboCop::RSpec::FakeCop
35
36
  end
36
37
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  # rubocop:disable Metrics/LineLength
4
4
  RSpec.describe RuboCop::Cop::RSpec::FactoryBot::DynamicAttributeDefinedStatically do
5
+ # rubocop:enable Metrics/LineLength
6
+
5
7
  subject(:cop) { described_class.new(config) }
6
8
 
7
9
  let(:config) { RuboCop::Config.new }
@@ -71,6 +71,7 @@ RSpec.describe RuboCop::Cop::RSpec::Focus do
71
71
  ^^^^^^ Focused spec found.
72
72
  RUBY
73
73
  end
74
+ # rubocop:enable RSpec/ExampleLength
74
75
 
75
76
  it 'does not flag unfocused specs' do
76
77
  expect_no_offenses(<<-RUBY)
@@ -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 eql(s(:str, 'does x'))
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 eql(s(:str, 'does x'))
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.20.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-11-15 00:00:00.000000000 Z
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.51.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.51.0
28
+ version: 0.52.0
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: rake
31
31
  requirement: !ruby/object:Gem::Requirement