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 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