rubocop-rspec 3.8.0 → 3.9.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: abe85fc893e4ec59cb9b5f1e999d35bb41692feacc4dba579d135b3eefd6e4c7
4
- data.tar.gz: 953ba29bf3fce28b79943e69039b638574d74432dac8b896f3dc8e589a20581c
3
+ metadata.gz: 9159cd716027712a72b3a3e675f83a92c55070200ae0f628a8b00c7333bc99f0
4
+ data.tar.gz: 5e84a7c7108c0f745cfa3e32ab75fd9fe50a1b0f2dae4ba6e0433d6cf5cd30dc
5
5
  SHA512:
6
- metadata.gz: acdf813781e2081ec34540e83a9a48fc289dab5cc8bff69d9610beb4a3f21c30955794eb4226d40b9f0460a04d38665c2aa4ce0857f35d8bd3a7325d91a861be
7
- data.tar.gz: 752074b0fdce204596efc71e2358982c73c2fccff07da5da364c88b8ad5e99d5a8bfdbc855a9dd422169adeddf278266352f732092b5aa86d14502016ca77837
6
+ metadata.gz: bc41fe5a7eccbb4452fd4bc6459d03ceb5dcd8a13316245b223db3088ea25e38bfa029e834f527dbb511b80ce5b553c83673a6e6f957c974f599d7140d4f7d40
7
+ data.tar.gz: 0c6a077dd4b221d68524ed4b2734727000efb97c5fb553c31016aab51f57e0049f67c701727f6d7eeb04c42ad2866b96592793bc768bac7361ca4e7ca0d81248
data/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## Master (Unreleased)
4
4
 
5
+ ## 3.9.0 (2026-01-07)
6
+
7
+ - Fix a false positive for `RSpec/LeakyLocalVariable` when variables are used only in example metadata (e.g., skip messages). ([@ydah])
8
+ - Fix a false positive for `RSpec/ScatteredSetup` when the hook is defined inside a class method. ([@d4rky-pl])
9
+ - Fix a false positive for `RSpec/DescribedClass` inside dynamically evaluated blocks (`class_eval`, `module_eval`, `instance_eval`, `class_exec`, `module_exec`, `instance_exec`). ([@sucicfilip])
10
+ - Add new cop `RSpec/Output`. ([@kevinrobell-st])
11
+
5
12
  ## 3.8.0 (2025-11-12)
6
13
 
7
14
  - Add new cop `RSpec/LeakyLocalVariable`. ([@lovro-bikic])
@@ -981,6 +988,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
981
988
  [@composerinteralia]: https://github.com/composerinteralia
982
989
  [@corsonknowles]: https://github.com/corsonknowles
983
990
  [@corydiamand]: https://github.com/corydiamand
991
+ [@d4rky-pl]: https://github.com/d4rky-pl
984
992
  [@darhazer]: https://github.com/Darhazer
985
993
  [@daveworth]: https://github.com/daveworth
986
994
  [@dduugg]: https://github.com/dduugg
@@ -1023,6 +1031,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
1023
1031
  [@jtannas]: https://github.com/jtannas
1024
1032
  [@k-s-a]: https://github.com/K-S-A
1025
1033
  [@kellysutton]: https://github.com/kellysutton
1034
+ [@kevinrobell-st]: https://github.com/kevinrobell-st
1026
1035
  [@koic]: https://github.com/koic
1027
1036
  [@krororo]: https://github.com/krororo
1028
1037
  [@kuahyeow]: https://github.com/kuahyeow
@@ -1077,6 +1086,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
1077
1086
  [@smcgivern]: https://github.com/smcgivern
1078
1087
  [@splattael]: https://github.com/splattael
1079
1088
  [@stephannv]: https://github.com/stephannv
1089
+ [@sucicfilip]: https://github.com/sucicfilip
1080
1090
  [@swelther]: https://github.com/swelther
1081
1091
  [@t3h2mas]: https://github.com/t3h2mas
1082
1092
  [@tdeo]: https://github.com/tdeo
data/config/default.yml CHANGED
@@ -758,6 +758,14 @@ RSpec/NotToNot:
758
758
  VersionAdded: '1.4'
759
759
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NotToNot
760
760
 
761
+ RSpec/Output:
762
+ Description: Checks for the use of output calls like puts and print in specs.
763
+ Enabled: pending
764
+ AutoCorrect: contextual
765
+ SafeAutoCorrect: false
766
+ VersionAdded: '3.9'
767
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Output
768
+
761
769
  RSpec/OverwritingSetup:
762
770
  Description: Checks if there is a let/subject that overwrites an existing one.
763
771
  Enabled: true
@@ -87,6 +87,8 @@ module RuboCop
87
87
  {
88
88
  (send (const nil? {:Class :Module :Struct}) :new ...)
89
89
  (send (const nil? :Data) :define ...)
90
+ (send _ {:class_eval :module_eval :instance_eval} ...)
91
+ (send _ {:class_exec :module_exec :instance_exec} ...)
90
92
  }
91
93
  ...
92
94
  )
@@ -57,6 +57,13 @@ module RuboCop
57
57
  # expectations
58
58
  # end
59
59
  #
60
+ # # good - when variable is used only in example metadata
61
+ # skip_message = 'not yet implemented'
62
+ #
63
+ # it 'does something', skip: skip_message do
64
+ # expectations
65
+ # end
66
+ #
60
67
  # # good - when variable is used only to include other examples
61
68
  # examples = foo ? 'some examples' : 'other examples'
62
69
  #
@@ -103,6 +110,8 @@ module RuboCop
103
110
  def allowed_reference?(node)
104
111
  node.each_ancestor.any? do |ancestor|
105
112
  next true if example_method?(ancestor)
113
+ next true if in_example_arguments?(ancestor, node)
114
+
106
115
  if includes_method?(ancestor)
107
116
  next allowed_includes_arguments?(ancestor, node)
108
117
  end
@@ -111,6 +120,15 @@ module RuboCop
111
120
  end
112
121
  end
113
122
 
123
+ def in_example_arguments?(ancestor, node)
124
+ return false unless ancestor.send_type?
125
+ return false unless Examples.all(ancestor.method_name)
126
+
127
+ ancestor.arguments.any? do |arg|
128
+ arg.equal?(node) || arg.each_descendant.any?(node)
129
+ end
130
+ end
131
+
114
132
  def allowed_includes_arguments?(node, argument)
115
133
  node.arguments[1..].all? do |argument_node|
116
134
  next true if argument_node.type?(:dstr, :dsym)
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # NOTE: Originally based on the `Rails/Output` cop.
6
+ module RSpec
7
+ # Checks for the use of output calls like puts and print in specs.
8
+ #
9
+ # @safety
10
+ # This autocorrection is marked as unsafe because, in rare cases, print
11
+ # statements can be used on purpose for integration testing and deleting
12
+ # them will cause tests to fail.
13
+ #
14
+ # @example
15
+ # # bad
16
+ # puts 'A debug message'
17
+ # pp 'A debug message'
18
+ # print 'A debug message'
19
+ class Output < Base
20
+ extend AutoCorrector
21
+
22
+ MSG = 'Do not write to stdout in specs.'
23
+
24
+ KERNEL_METHODS = %i[
25
+ ap
26
+ p
27
+ pp
28
+ pretty_print
29
+ print
30
+ puts
31
+ ].to_set.freeze
32
+ private_constant :KERNEL_METHODS
33
+
34
+ IO_METHODS = %i[
35
+ binwrite
36
+ syswrite
37
+ write
38
+ write_nonblock
39
+ ].to_set.freeze
40
+ private_constant :IO_METHODS
41
+
42
+ RESTRICT_ON_SEND = (KERNEL_METHODS + IO_METHODS).to_a.freeze
43
+
44
+ # @!method output?(node)
45
+ def_node_matcher :output?, <<~PATTERN
46
+ (send nil? KERNEL_METHODS ...)
47
+ PATTERN
48
+
49
+ # @!method io_output?(node)
50
+ def_node_matcher :io_output?, <<~PATTERN
51
+ (send
52
+ {
53
+ (gvar #match_gvar?)
54
+ (const {nil? cbase} {:STDOUT :STDERR})
55
+ }
56
+ IO_METHODS
57
+ ...)
58
+ PATTERN
59
+
60
+ def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity
61
+ return if node.parent&.call_type? || node.block_node
62
+ return if !output?(node) && !io_output?(node)
63
+ return if node.arguments.any? { |arg| arg.type?(:hash, :block_pass) }
64
+
65
+ add_offense(node) do |corrector|
66
+ corrector.remove(node)
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def match_gvar?(sym)
73
+ %i[$stdout $stderr].include?(sym)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -8,6 +8,7 @@ module RuboCop
8
8
  # Unify `before` and `after` hooks when possible.
9
9
  # However, `around` hooks are allowed to be defined multiple times,
10
10
  # as unifying them would typically make the code harder to read.
11
+ # Hooks defined in class methods are also ignored.
11
12
  #
12
13
  # @example
13
14
  # # bad
@@ -30,6 +31,14 @@ module RuboCop
30
31
  # around { |example| before2; example.call; after2 }
31
32
  # end
32
33
  #
34
+ # # good
35
+ # describe Foo do
36
+ # before { setup1 }
37
+ # def self.setup
38
+ # before { setup2 }
39
+ # end
40
+ # end
41
+ #
33
42
  class ScatteredSetup < Base
34
43
  include FinalEndLocation
35
44
  include RangeHelp
@@ -53,9 +62,10 @@ module RuboCop
53
62
 
54
63
  private
55
64
 
56
- def repeated_hooks(node)
65
+ def repeated_hooks(node) # rubocop:disable Metrics/CyclomaticComplexity
57
66
  hooks = RuboCop::RSpec::ExampleGroup.new(node)
58
67
  .hooks
68
+ .reject(&:inside_class_method?)
59
69
  .select { |hook| hook.knowable_scope? && hook.name != :around }
60
70
  .group_by { |hook| [hook.name, hook.scope, hook.metadata] }
61
71
  .values
@@ -75,6 +75,7 @@ require_relative 'rspec/named_subject'
75
75
  require_relative 'rspec/nested_groups'
76
76
  require_relative 'rspec/no_expectation_example'
77
77
  require_relative 'rspec/not_to_not'
78
+ require_relative 'rspec/output'
78
79
  require_relative 'rspec/overwriting_setup'
79
80
  require_relative 'rspec/pending'
80
81
  require_relative 'rspec/pending_without_reason'
@@ -25,6 +25,13 @@ module RuboCop
25
25
  scope.equal?(:each)
26
26
  end
27
27
 
28
+ def inside_class_method? # rubocop:disable Metrics/CyclomaticComplexity
29
+ parent = node.parent
30
+ return false unless parent
31
+
32
+ parent.defs_type? || (parent.def_type? && inside_class_self?(parent))
33
+ end
34
+
28
35
  def scope
29
36
  return :each if scope_argument&.hash_type?
30
37
 
@@ -76,6 +83,12 @@ module RuboCop
76
83
  def scope_argument
77
84
  node.send_node.first_argument
78
85
  end
86
+
87
+ def inside_class_self?(node)
88
+ node.parent&.sclass_type? ||
89
+ (node.parent&.begin_type? && node.parent.parent&.sclass_type?) ||
90
+ false
91
+ end
79
92
  end
80
93
  end
81
94
  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 = '3.8.0'
7
+ STRING = '3.9.0'
8
8
  end
9
9
  end
10
10
  end
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: 3.8.0
4
+ version: 3.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Backus
@@ -146,6 +146,7 @@ files:
146
146
  - lib/rubocop/cop/rspec/nested_groups.rb
147
147
  - lib/rubocop/cop/rspec/no_expectation_example.rb
148
148
  - lib/rubocop/cop/rspec/not_to_not.rb
149
+ - lib/rubocop/cop/rspec/output.rb
149
150
  - lib/rubocop/cop/rspec/overwriting_setup.rb
150
151
  - lib/rubocop/cop/rspec/pending.rb
151
152
  - lib/rubocop/cop/rspec/pending_without_reason.rb
@@ -222,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
223
  - !ruby/object:Gem::Version
223
224
  version: '0'
224
225
  requirements: []
225
- rubygems_version: 3.6.9
226
+ rubygems_version: 4.0.3
226
227
  specification_version: 4
227
228
  summary: Code style checking for RSpec files
228
229
  test_files: []