rubocop-vibe 0.1.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 +7 -0
- data/config/default.yml +126 -0
- data/lib/rubocop/cop/vibe/blank_line_before_expectation.rb +141 -0
- data/lib/rubocop/cop/vibe/class_organization.rb +609 -0
- data/lib/rubocop/cop/vibe/consecutive_assignment_alignment.rb +219 -0
- data/lib/rubocop/cop/vibe/describe_block_order.rb +262 -0
- data/lib/rubocop/cop/vibe/is_expected_one_liner.rb +108 -0
- data/lib/rubocop/cop/vibe/mixin/spec_file_helper.rb +20 -0
- data/lib/rubocop/cop/vibe/no_assigns_attribute_testing.rb +62 -0
- data/lib/rubocop/cop/vibe/no_rubocop_disable.rb +60 -0
- data/lib/rubocop/cop/vibe/no_skipped_tests.rb +115 -0
- data/lib/rubocop/cop/vibe/no_unless_guard_clause.rb +250 -0
- data/lib/rubocop/cop/vibe/prefer_one_liner_expectation.rb +185 -0
- data/lib/rubocop/cop/vibe/service_call_method.rb +82 -0
- data/lib/rubocop/cop/vibe_cops.rb +15 -0
- data/lib/rubocop/vibe/plugin.rb +41 -0
- data/lib/rubocop/vibe/version.rb +7 -0
- data/lib/rubocop/vibe.rb +9 -0
- data/lib/rubocop-vibe.rb +9 -0
- metadata +131 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 66c4596677b86001b40036ed73d0ce8300b9010cc3ea16af13436cc7a1ab3cfd
|
|
4
|
+
data.tar.gz: b27f79a610368b858a565c70c90fcf7db80e0b258e7efc3ce17942ccfdef79cc
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 57f43f61aba7ac210141f1d3aafff845f9b9a356ab88a42174de2344035825377bfc3ed1603d37e4b9662208f013a027be6be28cf2da40a514acb44f517469a6
|
|
7
|
+
data.tar.gz: fbe66437855c42030400323044fa53d3526e017fea1db8962d342aa9df7484072746a31c86791d7448c7f100b465ce72430318117d11967dfbb19fde09ee3d46
|
data/config/default.yml
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
plugins:
|
|
2
|
+
- rubocop-performance
|
|
3
|
+
- rubocop-rake
|
|
4
|
+
- rubocop-rspec
|
|
5
|
+
|
|
6
|
+
AllCops:
|
|
7
|
+
Exclude:
|
|
8
|
+
- "tmp/**/*"
|
|
9
|
+
- "vendor/**/*"
|
|
10
|
+
NewCops: enable
|
|
11
|
+
TargetRubyVersion: 4.0
|
|
12
|
+
|
|
13
|
+
Layout/HashAlignment:
|
|
14
|
+
EnforcedColonStyle: table
|
|
15
|
+
EnforcedHashRocketStyle: table
|
|
16
|
+
|
|
17
|
+
Naming/RescuedExceptionsVariableName:
|
|
18
|
+
Enabled: true
|
|
19
|
+
PreferredName: error
|
|
20
|
+
|
|
21
|
+
Naming/VariableNumber:
|
|
22
|
+
EnforcedStyle: snake_case
|
|
23
|
+
|
|
24
|
+
Style/ArgumentsForwarding:
|
|
25
|
+
UseAnonymousForwarding: false
|
|
26
|
+
|
|
27
|
+
Style/Documentation:
|
|
28
|
+
Enabled: false
|
|
29
|
+
|
|
30
|
+
Style/DocumentationMethod:
|
|
31
|
+
Enabled: true
|
|
32
|
+
Exclude:
|
|
33
|
+
- "db/**/*"
|
|
34
|
+
- "spec/**/*"
|
|
35
|
+
RequireForNonPublicMethods: true
|
|
36
|
+
|
|
37
|
+
Style/ExpandPathArguments:
|
|
38
|
+
Enabled: true
|
|
39
|
+
Exclude:
|
|
40
|
+
- bin/*
|
|
41
|
+
|
|
42
|
+
Style/GuardClause:
|
|
43
|
+
Enabled: false
|
|
44
|
+
|
|
45
|
+
Style/HashSyntax:
|
|
46
|
+
Enabled: false
|
|
47
|
+
|
|
48
|
+
Style/IfUnlessModifier:
|
|
49
|
+
Enabled: false
|
|
50
|
+
|
|
51
|
+
Style/PercentLiteralDelimiters:
|
|
52
|
+
PreferredDelimiters:
|
|
53
|
+
"%i": "()"
|
|
54
|
+
"%w": "()"
|
|
55
|
+
|
|
56
|
+
Style/RaiseArgs:
|
|
57
|
+
EnforcedStyle: compact
|
|
58
|
+
|
|
59
|
+
Style/StringLiterals:
|
|
60
|
+
EnforcedStyle: double_quotes
|
|
61
|
+
|
|
62
|
+
Style/StringLiteralsInInterpolation:
|
|
63
|
+
EnforcedStyle: double_quotes
|
|
64
|
+
|
|
65
|
+
Vibe/BlankLineBeforeExpectation:
|
|
66
|
+
Description: "Enforces a blank line before expectation calls when there is setup code above."
|
|
67
|
+
Enabled: true
|
|
68
|
+
SafeAutoCorrect: true
|
|
69
|
+
VersionAdded: "0.1.0"
|
|
70
|
+
|
|
71
|
+
Vibe/ConsecutiveAssignmentAlignment:
|
|
72
|
+
Description: "Enforces alignment of consecutive variable assignments at the = operator."
|
|
73
|
+
Enabled: true
|
|
74
|
+
SafeAutoCorrect: true
|
|
75
|
+
VersionAdded: "0.1.0"
|
|
76
|
+
|
|
77
|
+
Vibe/DescribeBlockOrder:
|
|
78
|
+
Description: "Enforces consistent ordering of describe blocks in RSpec files."
|
|
79
|
+
Enabled: true
|
|
80
|
+
SafeAutoCorrect: false
|
|
81
|
+
VersionAdded: "0.1.0"
|
|
82
|
+
|
|
83
|
+
Vibe/IsExpectedOneLiner:
|
|
84
|
+
Description: "Enforces that is_expected is only used in one-liner it { } blocks."
|
|
85
|
+
Enabled: true
|
|
86
|
+
SafeAutoCorrect: true
|
|
87
|
+
VersionAdded: "0.1.0"
|
|
88
|
+
|
|
89
|
+
Vibe/ClassOrganization:
|
|
90
|
+
Description: "Enforces consistent organization of class definitions."
|
|
91
|
+
Enabled: true
|
|
92
|
+
SafeAutoCorrect: false
|
|
93
|
+
VersionAdded: "0.1.0"
|
|
94
|
+
|
|
95
|
+
Vibe/NoAssignsAttributeTesting:
|
|
96
|
+
Description: "Enforces that controller specs only test assignment identity, not attributes or associations."
|
|
97
|
+
Enabled: true
|
|
98
|
+
SafeAutoCorrect: false
|
|
99
|
+
VersionAdded: "0.1.0"
|
|
100
|
+
|
|
101
|
+
Vibe/NoRubocopDisable:
|
|
102
|
+
Description: "Enforces that rubocop:disable comments are not used inline."
|
|
103
|
+
Enabled: true
|
|
104
|
+
VersionAdded: "0.1.0"
|
|
105
|
+
|
|
106
|
+
Vibe/NoSkippedTests:
|
|
107
|
+
Description: "Enforces that tests are not skipped or marked as pending."
|
|
108
|
+
Enabled: true
|
|
109
|
+
VersionAdded: "0.1.0"
|
|
110
|
+
|
|
111
|
+
Vibe/NoUnlessGuardClause:
|
|
112
|
+
Description: "Enforces using positive if conditions instead of unless for guard clauses."
|
|
113
|
+
Enabled: true
|
|
114
|
+
SafeAutoCorrect: true
|
|
115
|
+
VersionAdded: "0.1.0"
|
|
116
|
+
|
|
117
|
+
Vibe/PreferOneLinerExpectation:
|
|
118
|
+
Description: "Enforces one-liner syntax for simple RSpec expectations."
|
|
119
|
+
Enabled: true
|
|
120
|
+
SafeAutoCorrect: true
|
|
121
|
+
VersionAdded: "0.1.0"
|
|
122
|
+
|
|
123
|
+
Vibe/ServiceCallMethod:
|
|
124
|
+
Description: "Service objects should define `self.call` and `call` methods."
|
|
125
|
+
Enabled: true
|
|
126
|
+
VersionAdded: "0.1.0"
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Vibe
|
|
6
|
+
# Enforces a blank line before expectation calls when there's setup code above.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# # bad
|
|
10
|
+
# it "processes the record" do
|
|
11
|
+
# record.process
|
|
12
|
+
# expect(record).to be_processed
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# # good
|
|
16
|
+
# it "processes the record" do
|
|
17
|
+
# record.process
|
|
18
|
+
#
|
|
19
|
+
# expect(record).to be_processed
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# # good - no setup code above
|
|
23
|
+
# it "is valid" do
|
|
24
|
+
# expect(record).to be_valid
|
|
25
|
+
# end
|
|
26
|
+
class BlankLineBeforeExpectation < Base
|
|
27
|
+
extend AutoCorrector
|
|
28
|
+
include SpecFileHelper
|
|
29
|
+
|
|
30
|
+
MSG = "Add a blank line before expectation when there is setup code above."
|
|
31
|
+
|
|
32
|
+
# @!method example_block?(node)
|
|
33
|
+
# Check if block is an example block (it, specify, scenario).
|
|
34
|
+
def_node_matcher :example_block?, <<~PATTERN
|
|
35
|
+
(block (send nil? {:it :specify :scenario} ...) ...)
|
|
36
|
+
PATTERN
|
|
37
|
+
|
|
38
|
+
# @!method expect_call?(node)
|
|
39
|
+
# Check if node is an expect call.
|
|
40
|
+
def_node_matcher :expect_call?, <<~PATTERN
|
|
41
|
+
(send nil? :expect ...)
|
|
42
|
+
PATTERN
|
|
43
|
+
|
|
44
|
+
# Check block nodes for expect calls in example blocks.
|
|
45
|
+
#
|
|
46
|
+
# @param [RuboCop::AST::Node] node The block node.
|
|
47
|
+
# @return [void]
|
|
48
|
+
def on_block(node)
|
|
49
|
+
if processable_block?(node)
|
|
50
|
+
check_statements(extract_statements(node.body))
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
alias on_numblock on_block
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
# Check if the block should be processed.
|
|
58
|
+
#
|
|
59
|
+
# @param [RuboCop::AST::Node] node The block node.
|
|
60
|
+
# @return [Boolean]
|
|
61
|
+
def processable_block?(node)
|
|
62
|
+
spec_file? && example_block?(node) && node.body
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Extract statements from the block body.
|
|
66
|
+
#
|
|
67
|
+
# @param [RuboCop::AST::Node] body The block body.
|
|
68
|
+
# @return [Array<RuboCop::AST::Node>]
|
|
69
|
+
def extract_statements(body)
|
|
70
|
+
body.begin_type? ? body.children : [body]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Check statements for missing blank lines before expectations.
|
|
74
|
+
#
|
|
75
|
+
# @param [Array<RuboCop::AST::Node>] statements The statements to check.
|
|
76
|
+
# @return [void]
|
|
77
|
+
def check_statements(statements)
|
|
78
|
+
statements.each_with_index do |statement, index|
|
|
79
|
+
next if index.zero?
|
|
80
|
+
|
|
81
|
+
check_statement_pair(statements[index - 1], statement)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Check a pair of statements for missing blank line.
|
|
86
|
+
#
|
|
87
|
+
# @param [RuboCop::AST::Node] previous_statement The previous statement.
|
|
88
|
+
# @param [RuboCop::AST::Node] current_statement The current statement.
|
|
89
|
+
# @return [void]
|
|
90
|
+
def check_statement_pair(previous_statement, current_statement)
|
|
91
|
+
expect_node = find_expect_node(current_statement)
|
|
92
|
+
return unless expect_node
|
|
93
|
+
return if blank_line_between?(previous_statement, current_statement)
|
|
94
|
+
return if find_expect_node(previous_statement)
|
|
95
|
+
|
|
96
|
+
register_offense(expect_node, previous_statement)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Register an offense for missing blank line.
|
|
100
|
+
#
|
|
101
|
+
# @param [RuboCop::AST::Node] expect_node The expect node.
|
|
102
|
+
# @param [RuboCop::AST::Node] previous_statement The previous statement.
|
|
103
|
+
# @return [void]
|
|
104
|
+
def register_offense(expect_node, previous_statement)
|
|
105
|
+
add_offense(expect_node.loc.selector) do |corrector|
|
|
106
|
+
corrector.insert_after(previous_statement, "\n")
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Find the expect node within a statement.
|
|
111
|
+
#
|
|
112
|
+
# Searches the node and its descendants for expect calls.
|
|
113
|
+
# Only searches within the statement's method chain, not into
|
|
114
|
+
# nested blocks like those passed to other methods.
|
|
115
|
+
#
|
|
116
|
+
# @param [RuboCop::AST::Node] node The statement node.
|
|
117
|
+
# @return [RuboCop::AST::Node] The expect node if found.
|
|
118
|
+
# @return [nil] When no expect call is found.
|
|
119
|
+
def find_expect_node(node)
|
|
120
|
+
return unless node.send_type?
|
|
121
|
+
|
|
122
|
+
# Check if this node itself is an expect call.
|
|
123
|
+
return node if expect_call?(node)
|
|
124
|
+
|
|
125
|
+
# Search descendants for expect calls.
|
|
126
|
+
# This includes expect { ... } which has a block attached.
|
|
127
|
+
node.each_descendant(:send).find { |send_node| expect_call?(send_node) }
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Check if there's a blank line between two statements.
|
|
131
|
+
#
|
|
132
|
+
# @param [RuboCop::AST::Node] previous_node The previous statement.
|
|
133
|
+
# @param [RuboCop::AST::Node] current_node The current statement.
|
|
134
|
+
# @return [Boolean]
|
|
135
|
+
def blank_line_between?(previous_node, current_node)
|
|
136
|
+
current_node.loc.line - previous_node.loc.last_line > 1
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|