rubocop-rspec 1.40.0 → 1.41.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: 59e10874a1394fa4741d2f03d4e3fc99fc86a708b8973024be0e33f568e20b0a
4
- data.tar.gz: b33b46623283aebafe40edd9509c58cabe052a4602fdebd97f69250e9f7ea206
3
+ metadata.gz: 4899c717a87d579939d5c1420800d2fe6c150e4421908e75b9d52c57c8362e60
4
+ data.tar.gz: 1155018e6595c843c1ade5cdecb748af349c1c2f94dbcd5b17fb4a4fb5d324be
5
5
  SHA512:
6
- metadata.gz: 1e109509a667750018f86fb3fbe6e05cce32a22fb99dde8bcd39ab4bdecb688af372baea3e05b1a156074b8c1f295ae129415356510c72a72face5b49e51b492
7
- data.tar.gz: fa38c3aa5e06adc57a1ca991e2dc42cb9511580a4214089323c1f76403f923940f845c709ff0393805035766184b2855fab4d31b4af11b5cdea9f278cdf2d87c
6
+ metadata.gz: 79d9dc291018b0551b52c85dc6b09a1151356e1c85fe4e6a8a7aca5ade036be690f9b5aae7301cf232a0d067b18c0321be44f9915d5485dcaf993786ed07d328
7
+ data.tar.gz: cd9db102d912c42b484c7a514f5954b5f35d29bb7f0f3e186ed946898ba1134de5bf452611812465103aa2effc67016e4536bfc6dd365681aa90b2f4c1957f39
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## Master (Unreleased)
4
4
 
5
+ ## 1.41.0 (2020-07-03)
6
+
7
+ * Extend the list of Rails spec types for `RSpec/DescribeClass`. ([@pirj][])
8
+ * Fix `FactoryBot/AttributeDefinedStatically` to allow `#traits_for_enum` without a block. ([@harrylewis][])
9
+ * Improve the performance of `FactoryBot/AttributeDefinedStatically`, `RSpec/InstanceVariable`, `RSpec/LetSetup`, `RSpec/NestedGroups` and `RSpec/ReturnFromStub`. ([@andrykonchin][])
10
+
5
11
  ## 1.40.0 (2020-06-11)
6
12
 
7
13
  * Add new `RSpec/VariableName` cop. ([@tejasbubane][])
@@ -518,3 +524,4 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
518
524
  [@robotdana]: https://github.com/robotdana
519
525
  [@rolfschmidt]: https://github.com/rolfschmidt
520
526
  [@andrykonchin]: https://github.com/andrykonchin
527
+ [@harrylewis]: https://github.com/harrylewis
@@ -0,0 +1,17 @@
1
+ # The RuboCop Community Code of Conduct
2
+
3
+ **Note:** We have picked the following code of conduct based on [Ruby's own
4
+ code of conduct](https://www.ruby-lang.org/en/conduct/).
5
+
6
+ This document provides a few simple community guidelines for a safe, respectful,
7
+ productive, and collaborative place for any person who is willing to contribute
8
+ to the RuboCop community. It applies to all "collaborative spaces", which are
9
+ defined as community communications channels (such as mailing lists, submitted
10
+ patches, commit comments, etc.).
11
+
12
+ * Participants will be tolerant of opposing views.
13
+ * Participants must ensure that their language and actions are free of personal
14
+ attacks and disparaging personal remarks.
15
+ * When interpreting the words and actions of others, participants should always
16
+ assume good intentions.
17
+ * Behaviour which can be reasonably considered harassment will not be tolerated.
@@ -13,6 +13,7 @@ require_relative 'rubocop/rspec/top_level_describe'
13
13
  require_relative 'rubocop/rspec/wording'
14
14
  require_relative 'rubocop/rspec/language'
15
15
  require_relative 'rubocop/rspec/language/node_pattern'
16
+ require_relative 'rubocop/rspec/top_level_group'
16
17
  require_relative 'rubocop/rspec/concept'
17
18
  require_relative 'rubocop/rspec/example_group'
18
19
  require_relative 'rubocop/rspec/example'
@@ -43,12 +43,14 @@ module RuboCop
43
43
  def_node_matcher :rails_metadata?, <<-PATTERN
44
44
  (pair
45
45
  (sym :type)
46
- (sym {:request :feature :system :routing :view})
46
+ (sym {
47
+ :channel :controller :helper :job :mailer :model :request
48
+ :routing :view :feature :system :mailbox
49
+ }
50
+ )
47
51
  )
48
52
  PATTERN
49
53
 
50
- def_node_matcher :shared_group?, SharedGroups::ALL.block_pattern
51
-
52
54
  def on_top_level_describe(node, (described_value, _))
53
55
  return if shared_group?(root_node)
54
56
  return if valid_describe?(node)
@@ -31,12 +31,15 @@ module RuboCop
31
31
  (send _ !#reserved_method? $...)
32
32
  PATTERN
33
33
 
34
- def_node_search :factory_attributes, <<-PATTERN
34
+ def_node_matcher :factory_attributes, <<-PATTERN
35
35
  (block (send _ #attribute_defining_method? ...) _ { (begin $...) $(send ...) } )
36
36
  PATTERN
37
37
 
38
38
  def on_block(node)
39
- factory_attributes(node).to_a.flatten.each do |attribute|
39
+ attributes = factory_attributes(node) || []
40
+ attributes = [attributes] unless attributes.is_a?(Array)
41
+
42
+ attributes.each do |attribute|
40
43
  next unless offensive_receiver?(attribute.receiver, node)
41
44
  next if proc?(attribute) || association?(attribute.first_argument)
42
45
 
@@ -47,13 +47,11 @@ module RuboCop
47
47
  # end
48
48
  #
49
49
  class InstanceVariable < Cop
50
+ include RuboCop::RSpec::TopLevelGroup
51
+
50
52
  MSG = 'Avoid instance variables – use let, ' \
51
53
  'a method call, or a local variable (if possible).'
52
54
 
53
- EXAMPLE_GROUP_METHODS = ExampleGroups::ALL + SharedGroups::ALL
54
-
55
- def_node_matcher :spec_group?, EXAMPLE_GROUP_METHODS.block_pattern
56
-
57
55
  def_node_matcher :dynamic_class?, <<-PATTERN
58
56
  (block (send (const nil? :Class) :new ...) ...)
59
57
  PATTERN
@@ -69,9 +67,7 @@ module RuboCop
69
67
 
70
68
  def_node_search :ivar_assigned?, '(ivasgn % ...)'
71
69
 
72
- def on_block(node)
73
- return unless spec_group?(node)
74
-
70
+ def on_top_level_group(node)
75
71
  ivar_usage(node) do |ivar, name|
76
72
  next if valid_usage?(ivar)
77
73
  next if assignment_only? && !ivar_assigned?(node, name)
@@ -119,11 +119,8 @@ module RuboCop
119
119
  private
120
120
 
121
121
  def inside_describe_block?(node)
122
- node.each_ancestor(:block).any?(&method(:in_example_or_shared_group?))
122
+ node.each_ancestor(:block).any?(&method(:spec_group?))
123
123
  end
124
-
125
- def_node_matcher :in_example_or_shared_group?,
126
- (ExampleGroups::ALL + SharedGroups::ALL).block_pattern
127
124
  end
128
125
  end
129
126
  end
@@ -28,14 +28,20 @@ module RuboCop
28
28
  class LetSetup < Cop
29
29
  MSG = 'Do not use `let!` to setup objects not referenced in tests.'
30
30
 
31
- def_node_search :let_bang, <<-PATTERN
31
+ def_node_matcher :example_or_shared_group_or_including?,
32
+ (
33
+ ExampleGroups::ALL + SharedGroups::ALL +
34
+ Includes::ALL
35
+ ).block_pattern
36
+
37
+ def_node_matcher :let_bang, <<-PATTERN
32
38
  (block $(send nil? :let! (sym $_)) args ...)
33
39
  PATTERN
34
40
 
35
41
  def_node_search :method_called?, '(send nil? %)'
36
42
 
37
43
  def on_block(node)
38
- return unless example_group?(node)
44
+ return unless example_or_shared_group_or_including?(node)
39
45
 
40
46
  unused_let_bang(node) do |let|
41
47
  add_offense(let)
@@ -45,10 +51,16 @@ module RuboCop
45
51
  private
46
52
 
47
53
  def unused_let_bang(node)
48
- let_bang(node) do |method_send, method_name|
54
+ child_let_bang(node) do |method_send, method_name|
49
55
  yield(method_send) unless method_called?(node, method_name)
50
56
  end
51
57
  end
58
+
59
+ def child_let_bang(node, &block)
60
+ RuboCop::RSpec::ExampleGroup.new(node).lets.each do |let|
61
+ let_bang(let, &block)
62
+ end
63
+ end
52
64
  end
53
65
  end
54
66
  end
@@ -97,13 +97,11 @@ module RuboCop
97
97
  "Configuration key `#{DEPRECATED_MAX_KEY}` for #{cop_name} is " \
98
98
  'deprecated in favor of `Max`. Please use that instead.'
99
99
 
100
- def_node_search :find_contexts, ExampleGroups::ALL.block_pattern
101
-
102
100
  def on_top_level_describe(node, _args)
103
- find_nested_contexts(node.parent) do |context, nesting|
101
+ find_nested_example_groups(node.parent) do |example_group, nesting|
104
102
  self.max = nesting
105
103
  add_offense(
106
- context.send_node,
104
+ example_group.send_node,
107
105
  message: message(nesting)
108
106
  )
109
107
  end
@@ -111,13 +109,14 @@ module RuboCop
111
109
 
112
110
  private
113
111
 
114
- def find_nested_contexts(node, nesting: 1, &block)
115
- find_contexts(node) do |nested_context|
116
- yield(nested_context, nesting) if nesting > max_nesting
112
+ def find_nested_example_groups(node, nesting: 1, &block)
113
+ example_group = example_group?(node)
114
+ yield node, nesting if example_group && nesting > max_nesting
115
+
116
+ next_nesting = example_group ? nesting + 1 : nesting
117
117
 
118
- nested_context.each_child_node do |child|
119
- find_nested_contexts(child, nesting: nesting + 1, &block)
120
- end
118
+ node.each_child_node(:block, :begin) do |child|
119
+ find_nested_example_groups(child, nesting: next_nesting, &block)
121
120
  end
122
121
  end
123
122
 
@@ -277,12 +277,12 @@ module RuboCop
277
277
  # expect(foo).to be_something
278
278
  #
279
279
  # # also good - It checks "true" strictly.
280
- # expect(foo).to be(true)
280
+ # expect(foo.something?).to be(true)
281
281
  #
282
282
  # @example Strict: false, EnforcedStyle: inflected
283
283
  # # bad
284
284
  # expect(foo.something?).to be_truthy
285
- # expect(foo).to be(true)
285
+ # expect(foo.something?).to be(true)
286
286
  #
287
287
  # # good
288
288
  # expect(foo).to be_something
@@ -40,20 +40,21 @@ module RuboCop
40
40
  MSG_BLOCK = 'Use block for static values.'
41
41
 
42
42
  def_node_search :contains_stub?, '(send nil? :receive (...))'
43
+ def_node_matcher :stub_with_block?, '(block #contains_stub? ...)'
43
44
  def_node_search :and_return_value, <<-PATTERN
44
45
  $(send _ :and_return $(...))
45
46
  PATTERN
46
47
 
47
48
  def on_send(node)
48
- return unless contains_stub?(node)
49
49
  return unless style == :block
50
+ return unless contains_stub?(node)
50
51
 
51
52
  check_and_return_call(node)
52
53
  end
53
54
 
54
55
  def on_block(node)
55
- return unless contains_stub?(node)
56
56
  return unless style == :and_return
57
+ return unless stub_with_block?(node)
57
58
 
58
59
  check_block_body(node)
59
60
  end
@@ -22,6 +22,8 @@ module RuboCop
22
22
  # end
23
23
  #
24
24
  class SubjectStub < Cop
25
+ include RuboCop::RSpec::TopLevelGroup
26
+
25
27
  MSG = 'Do not stub methods of the object under test.'
26
28
 
27
29
  # @!method subject(node)
@@ -75,11 +77,7 @@ module RuboCop
75
77
  } ...)
76
78
  PATTERN
77
79
 
78
- def on_block(node)
79
- return unless example_group?(node)
80
- return if (processed_example_groups & node.ancestors).any?
81
-
82
- processed_example_groups << node
80
+ def on_top_level_group(node)
83
81
  @explicit_subjects = find_all_explicit_subjects(node)
84
82
 
85
83
  find_subject_expectations(node) do |stub|
@@ -89,10 +87,6 @@ module RuboCop
89
87
 
90
88
  private
91
89
 
92
- def processed_example_groups
93
- @processed_example_groups ||= Set.new
94
- end
95
-
96
90
  def find_all_explicit_subjects(node)
97
91
  node.each_descendant(:block).with_object({}) do |child, h|
98
92
  name = subject(child)
@@ -14,72 +14,44 @@ module RuboCop
14
14
  ExampleGroups::ALL + SharedGroups::ALL + Includes::ALL
15
15
  ).block_pattern
16
16
 
17
+ def lets
18
+ find_all_in_scope(node, :let?)
19
+ end
20
+
17
21
  def subjects
18
- subjects_in_scope(node)
22
+ find_all_in_scope(node, :subject?)
19
23
  end
20
24
 
21
25
  def examples
22
- examples_in_scope(node).map(&Example.public_method(:new))
26
+ find_all_in_scope(node, :example?).map(&Example.public_method(:new))
23
27
  end
24
28
 
25
29
  def hooks
26
- hooks_in_scope(node).map(&Hook.public_method(:new))
30
+ find_all_in_scope(node, :hook?).map(&Hook.public_method(:new))
27
31
  end
28
32
 
29
33
  private
30
34
 
31
- def subjects_in_scope(node)
32
- node.each_child_node.flat_map do |child|
33
- find_subjects(child)
34
- end
35
- end
36
-
37
- def find_subjects(node)
38
- return [] if scope_change?(node)
39
-
40
- if subject?(node)
41
- [node]
42
- else
43
- subjects_in_scope(node)
44
- end
45
- end
46
-
47
- def hooks_in_scope(node)
48
- node.each_child_node.flat_map do |child|
49
- find_hooks(child)
50
- end
51
- end
52
-
53
- def find_hooks(node)
54
- return [] if scope_change?(node) || example?(node)
55
-
56
- if hook?(node)
57
- [node]
58
- else
59
- hooks_in_scope(node)
60
- end
61
- end
62
-
63
- def examples_in_scope(node, &blk)
64
- node.each_child_node.flat_map do |child|
65
- find_examples(child, &blk)
66
- end
67
- end
68
-
69
- # Recursively search for examples within the current scope
35
+ # Recursively search for predicate within the current scope
70
36
  #
71
- # Searches node for examples and halts when a scope change is detected
37
+ # Searches node and halts when a scope change is detected
72
38
  #
73
- # @param node [RuboCop::Node] node to recursively search for examples
39
+ # @param node [RuboCop::Node] node to recursively search
74
40
  #
75
- # @return [Array<RuboCop::Node>] discovered example nodes
76
- def find_examples(node)
77
- return [] if scope_change?(node)
41
+ # @return [Array<RuboCop::Node>] discovered nodes
42
+ def find_all_in_scope(node, predicate)
43
+ node.each_child_node.flat_map do |child|
44
+ find_all(child, predicate)
45
+ end
46
+ end
78
47
 
79
- if example?(node)
48
+ def find_all(node, predicate)
49
+ if public_send(predicate, node)
80
50
  [node]
51
+ elsif scope_change?(node) || example?(node)
52
+ []
81
53
  else
82
- examples_in_scope(node)
54
+ find_all_in_scope(node, predicate)
83
55
  end
84
56
  end
85
57
  end
@@ -4,7 +4,13 @@ module RuboCop
4
4
  module RSpec
5
5
  # RuboCop FactoryBot project namespace
6
6
  module FactoryBot
7
- ATTRIBUTE_DEFINING_METHODS = %i[factory trait transient ignore].freeze
7
+ ATTRIBUTE_DEFINING_METHODS = %i[
8
+ factory
9
+ ignore
10
+ trait
11
+ traits_for_enum
12
+ transient
13
+ ].freeze
8
14
 
9
15
  UNPROXIED_METHODS = %i[
10
16
  __send__
@@ -8,6 +8,10 @@ module RuboCop
8
8
  extend RuboCop::NodePattern::Macros
9
9
 
10
10
  def_node_matcher :example_group?, ExampleGroups::ALL.block_pattern
11
+ def_node_matcher :shared_group?, SharedGroups::ALL.block_pattern
12
+
13
+ spec_groups = ExampleGroups::ALL + SharedGroups::ALL
14
+ def_node_matcher :spec_group?, spec_groups.block_pattern
11
15
 
12
16
  def_node_matcher :example_group_with_body?, <<-PATTERN
13
17
  (block #{ExampleGroups::ALL.send_pattern} args [!nil?])
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module RSpec
5
+ # Helper methods for top level example group cops
6
+ module TopLevelGroup
7
+ extend RuboCop::NodePattern::Macros
8
+ include RuboCop::RSpec::Language
9
+
10
+ def_node_matcher :example_or_shared_group?,
11
+ (ExampleGroups::ALL + SharedGroups::ALL).block_pattern
12
+
13
+ def on_block(node)
14
+ return unless respond_to?(:on_top_level_group)
15
+ return unless top_level_group?(node)
16
+
17
+ on_top_level_group(node)
18
+ end
19
+
20
+ private
21
+
22
+ def top_level_group?(node)
23
+ top_level_groups.include?(node)
24
+ end
25
+
26
+ def top_level_groups
27
+ @top_level_groups ||=
28
+ top_level_nodes.select { |n| example_or_shared_group?(n) }
29
+ end
30
+
31
+ def top_level_nodes
32
+ if root_node.begin_type?
33
+ root_node.children
34
+ else
35
+ [root_node]
36
+ end
37
+ end
38
+
39
+ def root_node
40
+ processed_source.ast
41
+ end
42
+ end
43
+ end
44
+ 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 = '1.40.0'
7
+ STRING = '1.41.0'
8
8
  end
9
9
  end
10
10
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.40.0
4
+ version: 1.41.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Backus
8
8
  - Ian MacLeod
9
9
  - Nils Gemeinhardt
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-06-11 00:00:00.000000000 Z
13
+ date: 2020-07-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -110,6 +110,7 @@ extra_rdoc_files:
110
110
  - README.md
111
111
  files:
112
112
  - CHANGELOG.md
113
+ - CODE_OF_CONDUCT.md
113
114
  - MIT-LICENSE.md
114
115
  - README.md
115
116
  - config/default.yml
@@ -217,6 +218,7 @@ files:
217
218
  - lib/rubocop/rspec/language/node_pattern.rb
218
219
  - lib/rubocop/rspec/node.rb
219
220
  - lib/rubocop/rspec/top_level_describe.rb
221
+ - lib/rubocop/rspec/top_level_group.rb
220
222
  - lib/rubocop/rspec/variable.rb
221
223
  - lib/rubocop/rspec/version.rb
222
224
  - lib/rubocop/rspec/wording.rb
@@ -226,7 +228,7 @@ licenses:
226
228
  metadata:
227
229
  changelog_uri: https://github.com/rubocop-hq/rubocop-rspec/blob/master/CHANGELOG.md
228
230
  documentation_uri: https://rubocop-rspec.readthedocs.io/
229
- post_install_message:
231
+ post_install_message:
230
232
  rdoc_options: []
231
233
  require_paths:
232
234
  - lib
@@ -241,8 +243,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
241
243
  - !ruby/object:Gem::Version
242
244
  version: '0'
243
245
  requirements: []
244
- rubygems_version: 3.1.2
245
- signing_key:
246
+ rubygems_version: 3.0.3
247
+ signing_key:
246
248
  specification_version: 4
247
249
  summary: Code style checking for RSpec files
248
250
  test_files: []