rubocop-fourshark 0.10.0 → 0.11.1
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 +4 -4
- data/CHANGELOG.md +29 -0
- data/README.md +2 -1
- data/config/default.yml +5 -0
- data/lib/rubocop/cop/layout/single_line_statement_spacing.rb +93 -2
- data/lib/rubocop/fourshark/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 69cc71527797fec14e62169599832f3807636964ae36c971a625002392f2eb8f
|
|
4
|
+
data.tar.gz: b48916db29a2562de541d537a5204c2a11029cff89f91b2d8bd90c932dbeabc6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 74d395cab432995d01f8b5b7a86c3fbe1bb3bab3f4166452fc01c72ff18d3ef07d177bbeb4970d797a48812028c5c84e82e1623c0e860022d9baca5c530ea960
|
|
7
|
+
data.tar.gz: 3ac8c3575cbbefc7bbfd843cb6c21a651a80e15ff60a8eb89442e86e60b7f241917eface0fc2db701678647f60160ef8d3d37aff96c98cabac9b043ea1a649f3
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
## [Unreleased]
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
- `Layout/SingleLineStatementSpacing` coverage for RSpec cops that forbid consecutive one-liners
|
|
6
|
+
|
|
7
|
+
## [0.11.1] - 2026-10-07
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `Layout/SingleLineStatementSpacing` — the blank line after a `let`, `subject`, hook or example run is no longer removed
|
|
12
|
+
- `Layout/SingleLineStatementSpacing` — the blank line between two gem sections is no longer removed
|
|
13
|
+
- `Layout/SingleLineStatementSpacing` — the blank line after a hook or example written with a numbered or `it` block parameter is no longer removed
|
|
14
|
+
- `Layout/SingleLineStatementSpacing` — the blank line between two subjects or after a one-line example group is no longer removed
|
|
15
|
+
- `Layout/SingleLineStatementSpacing` — consecutive one-line hooks and examples are joined only while their RSpec cop allows it
|
|
16
|
+
|
|
17
|
+
## [0.11.0] - 2026-10-07
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- `RSpec/MultipleMemoizedHelpers` disabled
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Dependency age check failing on a transient registry error
|
|
26
|
+
- Dependency age check failing on a transient GitHub API error
|
|
27
|
+
- Dependency age check stalling on an unresponsive registry
|
|
28
|
+
- Dependency age check stalling on an unresponsive GitHub API
|
|
29
|
+
|
|
1
30
|
## [0.10.0] - 2026-10-02
|
|
2
31
|
|
|
3
32
|
### Added
|
data/README.md
CHANGED
|
@@ -61,12 +61,13 @@ Cop names follow RuboCop's empirical convention — a noun phrase describing the
|
|
|
61
61
|
|
|
62
62
|
### Stock cops disabled
|
|
63
63
|
|
|
64
|
-
Where a 4Shark cop supersedes or contradicts a stock cop, `config/default.yml` turns the stock one off:
|
|
64
|
+
Where a 4Shark cop supersedes or contradicts a stock cop, or a stock cop contradicts a 4Shark convention, `config/default.yml` turns the stock one off:
|
|
65
65
|
|
|
66
66
|
| Disabled stock cop | Why |
|
|
67
67
|
|---|---|
|
|
68
68
|
| `Rails/Delegate` | contradicts `Style/DisallowDelegate` — it turns an explicit method into `delegate`, we forbid the macro |
|
|
69
69
|
| `Rails/InverseOf` | superseded by `Rails/MandatoryInverseOf` (covers its cases and more) |
|
|
70
|
+
| `RSpec/MultipleMemoizedHelpers` | contradicts the spec convention of keeping every `let` at the top level, which the cop's default `Max: 5` cannot hold |
|
|
70
71
|
| `Style/MultilineTernaryOperator` | superseded by `Style/DisallowTernary` — it shapes a construct we forbid outright |
|
|
71
72
|
| `Style/NestedTernaryOperator` | superseded by `Style/DisallowTernary` — same |
|
|
72
73
|
| `Style/SafeNavigation` | contradicts `Style/DisallowSafeNavigation` — it pushes `&.`, we forbid it |
|
data/config/default.yml
CHANGED
|
@@ -106,6 +106,11 @@ RSpec/Dialect:
|
|
|
106
106
|
Include:
|
|
107
107
|
- 'spec/**/*_spec.rb'
|
|
108
108
|
|
|
109
|
+
# Stock cop disabled (not superseded by a 4Shark cop): the spec convention keeps
|
|
110
|
+
# every `let` at the top level, which the cop's default `Max: 5` cannot hold.
|
|
111
|
+
RSpec/MultipleMemoizedHelpers:
|
|
112
|
+
Enabled: false
|
|
113
|
+
|
|
109
114
|
RSpec/InverseOfMatcher:
|
|
110
115
|
Description: 'Root models must include `.inverse_of` in association specs; subclasses must not.'
|
|
111
116
|
Enabled: true
|
|
@@ -8,19 +8,65 @@ module RuboCop
|
|
|
8
8
|
# Forbids a blank line between two consecutive single-line statements —
|
|
9
9
|
# they are one run, so the blank reveals nothing. A blank that separates
|
|
10
10
|
# code from an adjacent comment is kept, as is one owned by another cop
|
|
11
|
-
# (a guard clause, a flow-control statement, an access modifier
|
|
12
|
-
#
|
|
11
|
+
# (a guard clause, a flow-control statement, an access modifier, the end
|
|
12
|
+
# of an RSpec `let`/`subject`/hook/example run, a Bundler gem section) or
|
|
13
|
+
# one beside a multi-line or heredoc neighbour. Autocorrects by removing it.
|
|
13
14
|
class SingleLineStatementSpacing < ::RuboCop::Cop::Base
|
|
14
15
|
extend ::RuboCop::Cop::AutoCorrector
|
|
15
16
|
ACCESS_MODIFIERS = %i[private protected public module_function].freeze
|
|
16
17
|
FLOW_CONTROL_METHODS = %i[raise fail throw].freeze
|
|
17
18
|
FLOW_CONTROL_TYPES = %i[return next break redo retry].freeze
|
|
18
19
|
MSG = 'Remove the blank line between consecutive single-line statements.'
|
|
20
|
+
ONE_LINER_RUN_COPS = { example: 'RSpec/EmptyLineAfterExample', hook: 'RSpec/EmptyLineAfterHook' }.freeze
|
|
21
|
+
|
|
22
|
+
RSPEC_KINDS = {
|
|
23
|
+
after: :hook,
|
|
24
|
+
append_after: :hook,
|
|
25
|
+
append_before: :hook,
|
|
26
|
+
around: :hook,
|
|
27
|
+
before: :hook,
|
|
28
|
+
context: :example_group,
|
|
29
|
+
describe: :example_group,
|
|
30
|
+
example: :example,
|
|
31
|
+
example_group: :example_group,
|
|
32
|
+
fcontext: :example_group,
|
|
33
|
+
fdescribe: :example_group,
|
|
34
|
+
feature: :example_group,
|
|
35
|
+
fexample: :example,
|
|
36
|
+
ffeature: :example_group,
|
|
37
|
+
fit: :example,
|
|
38
|
+
focus: :example,
|
|
39
|
+
fscenario: :example,
|
|
40
|
+
fspecify: :example,
|
|
41
|
+
it: :example,
|
|
42
|
+
its: :example,
|
|
43
|
+
let: :let,
|
|
44
|
+
let!: :let,
|
|
45
|
+
pending: :example,
|
|
46
|
+
prepend_after: :hook,
|
|
47
|
+
prepend_before: :hook,
|
|
48
|
+
scenario: :example,
|
|
49
|
+
shared_context: :example_group,
|
|
50
|
+
shared_examples: :example_group,
|
|
51
|
+
shared_examples_for: :example_group,
|
|
52
|
+
skip: :example,
|
|
53
|
+
specify: :example,
|
|
54
|
+
subject: :subject,
|
|
55
|
+
subject!: :subject,
|
|
56
|
+
xcontext: :example_group,
|
|
57
|
+
xdescribe: :example_group,
|
|
58
|
+
xexample: :example,
|
|
59
|
+
xfeature: :example_group,
|
|
60
|
+
xit: :example,
|
|
61
|
+
xscenario: :example,
|
|
62
|
+
xspecify: :example
|
|
63
|
+
}.freeze
|
|
19
64
|
|
|
20
65
|
def on_begin(node)
|
|
21
66
|
node.children.each_cons(2) do |first, second|
|
|
22
67
|
next unless first.is_a?(::RuboCop::AST::Node) && second.is_a?(::RuboCop::AST::Node)
|
|
23
68
|
next if structural?(first) || structural?(second)
|
|
69
|
+
next if rspec_run_ends?(first, second) || gem_section_boundary?(first, second)
|
|
24
70
|
|
|
25
71
|
blanks = removable_blank_lines(first, second)
|
|
26
72
|
|
|
@@ -64,6 +110,51 @@ module RuboCop
|
|
|
64
110
|
node.send_type? && node.receiver.nil? && ACCESS_MODIFIERS.include?(node.method_name)
|
|
65
111
|
end
|
|
66
112
|
|
|
113
|
+
# The `RSpec/EmptyLineAfter*` cops demand a blank after the last `let`,
|
|
114
|
+
# `subject`, hook, example or example group of a run; removing it makes the two cops fight.
|
|
115
|
+
def rspec_run_ends?(first, second)
|
|
116
|
+
kind = rspec_kind(first)
|
|
117
|
+
|
|
118
|
+
return false if kind.nil?
|
|
119
|
+
return true if kind != rspec_kind(second)
|
|
120
|
+
|
|
121
|
+
!one_liner_run_allowed?(kind)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Only `let`s always run together; hooks and examples do while their cop keeps
|
|
125
|
+
# `AllowConsecutiveOneLiners`, and subjects and example groups never do.
|
|
126
|
+
def one_liner_run_allowed?(kind)
|
|
127
|
+
return true if kind == :let
|
|
128
|
+
|
|
129
|
+
cop_name = ONE_LINER_RUN_COPS[kind]
|
|
130
|
+
|
|
131
|
+
return false if cop_name.nil?
|
|
132
|
+
|
|
133
|
+
config.for_cop(cop_name).fetch('AllowConsecutiveOneLiners', true)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def rspec_kind(node)
|
|
137
|
+
call =
|
|
138
|
+
if node.any_block_type?
|
|
139
|
+
node.send_node
|
|
140
|
+
else
|
|
141
|
+
node
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
return nil if !call.send_type? || call.receiver
|
|
145
|
+
|
|
146
|
+
RSPEC_KINDS[call.method_name]
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# `Bundler/OrderedGems` reads a blank between two `gem` lines as a section break.
|
|
150
|
+
def gem_section_boundary?(first, second)
|
|
151
|
+
gem_declaration?(first) && gem_declaration?(second)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def gem_declaration?(node)
|
|
155
|
+
node.send_type? && node.receiver.nil? && node.method?(:gem)
|
|
156
|
+
end
|
|
157
|
+
|
|
67
158
|
# A blank whose nearest non-blank line on each side is the same kind
|
|
68
159
|
# (code-to-code or comment-to-comment). A blank on a code/comment border
|
|
69
160
|
# separates the two deliberately and is left alone.
|