rubocop-rspec 1.40.0 → 1.41.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: 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: []