rubocop-rspec-guide 0.2.2 → 0.4.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 +4 -4
- data/.rubocop.yml +6 -6
- data/.yardopts +9 -0
- data/CHANGELOG.md +86 -0
- data/CONTRIBUTING.md +358 -0
- data/INTEGRATION_TESTING.md +324 -0
- data/README.md +443 -16
- data/Rakefile +49 -0
- data/benchmark/README.md +349 -0
- data/benchmark/baseline_v0.3.1.txt +67 -0
- data/benchmark/baseline_v0.4.0.txt +167 -0
- data/benchmark/benchmark_helper.rb +92 -0
- data/benchmark/compare_versions.rb +136 -0
- data/benchmark/cops_benchmark.rb +428 -0
- data/benchmark/cops_performance.rb +109 -0
- data/benchmark/quick_comparison.rb +58 -0
- data/benchmark/quick_invariant_bench.rb +52 -0
- data/benchmark/rspec_base_integration.rb +86 -0
- data/benchmark/save_baseline.rb +18 -0
- data/benchmark/scalability_benchmark.rb +181 -0
- data/config/default.yml +43 -2
- data/config/obsoletion.yml +6 -0
- data/lib/rubocop/cop/factory_bot_guide/dynamic_attribute_evaluation.rb +193 -0
- data/lib/rubocop/cop/factory_bot_guide/dynamic_attributes_for_time_and_random.rb +10 -106
- data/lib/rubocop/cop/rspec_guide/characteristics_and_contexts.rb +13 -78
- data/lib/rubocop/cop/rspec_guide/context_setup.rb +81 -30
- data/lib/rubocop/cop/rspec_guide/duplicate_before_hooks.rb +89 -22
- data/lib/rubocop/cop/rspec_guide/duplicate_let_values.rb +89 -22
- data/lib/rubocop/cop/rspec_guide/happy_path_first.rb +52 -21
- data/lib/rubocop/cop/rspec_guide/invariant_examples.rb +60 -19
- data/lib/rubocop/cop/rspec_guide/minimum_behavioral_coverage.rb +165 -0
- data/lib/rubocop/rspec/guide/inject.rb +26 -0
- data/lib/rubocop/rspec/guide/plugin.rb +45 -0
- data/lib/rubocop/rspec/guide/version.rb +1 -1
- data/lib/rubocop-rspec-guide.rb +4 -0
- metadata +49 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bcebf8b42eee358b662dc641b3e07c805897742a37cb5dd88464b6423b7ca2fa
|
|
4
|
+
data.tar.gz: 8b903dbd42050fbef4a51e61ed961ac6c1175ac997ca80ed4305b4cdfa529027
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30c52761374276952c116c748486a52373b4d8f3158826d1d5ed59e2e1e3a993e460e76e1c9a267a1545cfd5fb21d985a0d947b818ad31d850d24ce2d0fa0ab5
|
|
7
|
+
data.tar.gz: 13833dbdb0ff5094a33e683f248fb4b1378fdb5e57d6afb40906dc78da0a843622a87fa604d3e07eee617eef7425e3fc834c26b42b0d6d2839e6b9d2b2d2afec
|
data/.rubocop.yml
CHANGED
|
@@ -8,13 +8,13 @@ AllCops:
|
|
|
8
8
|
NewCops: enable
|
|
9
9
|
TargetRubyVersion: 3.0
|
|
10
10
|
Exclude:
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
11
|
+
- "vendor/**/*"
|
|
12
|
+
- "tmp/**/*"
|
|
13
|
+
- "bin/**/*"
|
|
14
|
+
- ".devbox/**/*"
|
|
15
15
|
|
|
16
16
|
# Enable our custom cops
|
|
17
|
-
RSpecGuide/
|
|
17
|
+
RSpecGuide/MinimumBehavioralCoverage:
|
|
18
18
|
Enabled: true
|
|
19
19
|
|
|
20
20
|
RSpecGuide/HappyPathFirst:
|
|
@@ -33,5 +33,5 @@ RSpecGuide/InvariantExamples:
|
|
|
33
33
|
Enabled: true
|
|
34
34
|
MinLeafContexts: 3
|
|
35
35
|
|
|
36
|
-
FactoryBotGuide/
|
|
36
|
+
FactoryBotGuide/DynamicAttributeEvaluation:
|
|
37
37
|
Enabled: true
|
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,91 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.4.0] - 2025-10-30
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **Integration with RuboCop::Cop::RSpec::Base**: All 6 RSpec cops now inherit from `RuboCop::Cop::RSpec::Base`
|
|
7
|
+
- Leverages rubocop-rspec Language API for better RSpec DSL detection
|
|
8
|
+
- Native support for `let_it_be` and `let_it_be!` from rspec-rails
|
|
9
|
+
- More accurate detection of RSpec constructs
|
|
10
|
+
- **RSpec Language configuration**: Added comprehensive RSpec/Language config in `config/default.yml`
|
|
11
|
+
- Enables rubocop-rspec API matchers: `example_group?()`, `example?()`, `let?()`, `hook?()`
|
|
12
|
+
- Supports ExampleGroups, Examples, Helpers, Hooks, and Subjects
|
|
13
|
+
- **Configuration injection**: Created `lib/rubocop/rspec/guide/inject.rb` to automatically load gem config
|
|
14
|
+
- **Test helper improvements**: Added `rubocop_config_with_rspec_language` helper for consistent test setup
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- **Removed duplicate node matchers**: Eliminated ~30 lines of code that duplicated rubocop-rspec functionality
|
|
18
|
+
- `example_group?()` - now uses API instead of custom matcher
|
|
19
|
+
- `example?()` - now uses API instead of custom matcher
|
|
20
|
+
- `let?()` - now uses API (also recognizes let_it_be/let_it_be!)
|
|
21
|
+
- `hook?()` - now uses API instead of custom matcher
|
|
22
|
+
- **Kept strategic custom matchers**: Retained specific matchers where needed
|
|
23
|
+
- `context_only?()` - for filtering only context blocks
|
|
24
|
+
- `let_with_name_and_value?()` - captures let name and value
|
|
25
|
+
- `before_hook_with_body?()` - captures hook body
|
|
26
|
+
- `example_with_description?()` - captures example description
|
|
27
|
+
|
|
28
|
+
### Performance
|
|
29
|
+
- **Optimized for production use**: Applied two-level optimization strategy
|
|
30
|
+
- Fast pre-checks: Added `node.method?(:describe)` checks before API calls
|
|
31
|
+
- Local matchers for hot paths: InvariantExamples uses fast local matching in O(n²) loops
|
|
32
|
+
- **InvariantExamples**: **4.25x faster** than v0.3.1 baseline (1,504 → 6,395 i/s) 🚀
|
|
33
|
+
- **Other cops**: 10-25% slower than baseline, acceptable trade-off for correctness and maintainability
|
|
34
|
+
- **Real-world impact**: All cops remain fast enough for CI/CD pipelines (1,200-6,395 i/s)
|
|
35
|
+
- **Detailed analysis**: See `PERFORMANCE_REPORT.md` for comprehensive performance documentation
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
- **ContextSetup**: Now correctly recognizes `let_it_be` and `let_it_be!` as valid context setup
|
|
39
|
+
|
|
40
|
+
## [0.3.1] - 2025-10-30
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
- **Plugin support for RuboCop 1.72+**: Added `lib/rubocop/rspec/guide/plugin.rb` for modern plugin system
|
|
44
|
+
- Now supports both `plugins:` (recommended for RuboCop 1.72+) and `require:` (legacy) configuration
|
|
45
|
+
- Fully backward compatible with older RuboCop versions
|
|
46
|
+
- **Version metadata in config/default.yml**: Added `VersionAdded` and `VersionChanged` fields to all cops
|
|
47
|
+
- Follows RuboCop conventions for tracking cop history
|
|
48
|
+
- Helps users understand when cops were introduced and modified
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
- **README.md**: Updated with both modern (`plugins:`) and legacy (`require:`) configuration examples
|
|
52
|
+
- Clear documentation for different RuboCop versions
|
|
53
|
+
- Migration guidance for users upgrading RuboCop
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
- **Build process**: Added `*.gem` to `.gitignore` to prevent built gems from being committed
|
|
57
|
+
|
|
58
|
+
## [0.3.0] - 2025-10-30
|
|
59
|
+
|
|
60
|
+
### Added
|
|
61
|
+
- **RSpecGuide/MinimumBehavioralCoverage**: New cop replacing CharacteristicsAndContexts with enhanced functionality
|
|
62
|
+
- Now supports two patterns for behavioral variations:
|
|
63
|
+
1. Traditional: 2+ sibling context blocks
|
|
64
|
+
2. New: it-blocks (default behavior) + context-blocks (edge cases)
|
|
65
|
+
- Better reflects the goal: ensuring minimum behavioral coverage in tests
|
|
66
|
+
- **FactoryBotGuide/DynamicAttributeEvaluation**: New cop replacing DynamicAttributesForTimeAndRandom
|
|
67
|
+
- More accurate name reflecting broader scope: checks ALL method calls, not just Time/Random
|
|
68
|
+
- Covers Time.now, SecureRandom.hex, 1.day.from_now, Array.new, and any other method calls
|
|
69
|
+
- Ensures dynamic evaluation by requiring block syntax for all method-based attributes
|
|
70
|
+
- **config/obsoletion.yml**: Added cop obsoletion configuration for tracking renamed cops
|
|
71
|
+
|
|
72
|
+
### Changed
|
|
73
|
+
- **RSpecGuide/MinimumBehavioralCoverage**: Enhanced to accept it-blocks + context-blocks pattern
|
|
74
|
+
- Validates that it-blocks appear before context-blocks (strict ordering)
|
|
75
|
+
- Allows tests with before/let setup + it-blocks + context-blocks
|
|
76
|
+
- Updated error messages to explain both valid patterns
|
|
77
|
+
- Improved documentation and examples in README.md
|
|
78
|
+
- Added examples for new it-blocks + context-blocks pattern
|
|
79
|
+
- Clarified that deprecated cop names still work as aliases
|
|
80
|
+
|
|
81
|
+
### Deprecated
|
|
82
|
+
- **RSpecGuide/CharacteristicsAndContexts**: Deprecated in favor of MinimumBehavioralCoverage
|
|
83
|
+
- Still works as an alias for backward compatibility
|
|
84
|
+
- Will be removed in a future major version
|
|
85
|
+
- **FactoryBotGuide/DynamicAttributesForTimeAndRandom**: Deprecated in favor of DynamicAttributeEvaluation
|
|
86
|
+
- Still works as an alias for backward compatibility
|
|
87
|
+
- Will be removed in a future major version
|
|
88
|
+
|
|
3
89
|
## [0.2.2] - 2025-10-29
|
|
4
90
|
|
|
5
91
|
### Fixed
|
data/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
# Contributing to RuboCop RSpec Guide
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing! This guide will help you get started.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Code of Conduct](#code-of-conduct)
|
|
8
|
+
- [Getting Started](#getting-started)
|
|
9
|
+
- [Development Setup](#development-setup)
|
|
10
|
+
- [Creating a New Cop](#creating-a-new-cop)
|
|
11
|
+
- [Writing Tests](#writing-tests)
|
|
12
|
+
- [Code Style Guidelines](#code-style-guidelines)
|
|
13
|
+
- [Submitting Changes](#submitting-changes)
|
|
14
|
+
- [Commit Message Guidelines](#commit-message-guidelines)
|
|
15
|
+
|
|
16
|
+
## Code of Conduct
|
|
17
|
+
|
|
18
|
+
This project follows the [Contributor Covenant Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/). By participating, you are expected to uphold this code.
|
|
19
|
+
|
|
20
|
+
## Getting Started
|
|
21
|
+
|
|
22
|
+
1. Fork the repository on GitHub
|
|
23
|
+
2. Clone your fork locally:
|
|
24
|
+
```bash
|
|
25
|
+
git clone https://github.com/YOUR-USERNAME/rubocop-rspec-guide.git
|
|
26
|
+
cd rubocop-rspec-guide
|
|
27
|
+
```
|
|
28
|
+
3. Add the upstream repository:
|
|
29
|
+
```bash
|
|
30
|
+
git remote add upstream https://github.com/AlexeyMatskevich/rubocop-rspec-guide.git
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Development Setup
|
|
34
|
+
|
|
35
|
+
### Prerequisites
|
|
36
|
+
|
|
37
|
+
- Ruby 3.0 or higher
|
|
38
|
+
- Bundler
|
|
39
|
+
|
|
40
|
+
### Install Dependencies
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
bundle install
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Run Tests
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
bundle exec rspec
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
All tests should pass before you start making changes.
|
|
53
|
+
|
|
54
|
+
### Run RuboCop
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
bundle exec rubocop
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Make sure your code follows the project's style guidelines.
|
|
61
|
+
|
|
62
|
+
## Creating a New Cop
|
|
63
|
+
|
|
64
|
+
### 1. Generate Cop File
|
|
65
|
+
|
|
66
|
+
Create a new file in the appropriate directory:
|
|
67
|
+
|
|
68
|
+
- For RSpec cops: `lib/rubocop/cop/rspec_guide/your_cop_name.rb`
|
|
69
|
+
- For FactoryBot cops: `lib/rubocop/cop/factory_bot_guide/your_cop_name.rb`
|
|
70
|
+
|
|
71
|
+
### 2. Basic Cop Structure
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
# frozen_string_literal: true
|
|
75
|
+
|
|
76
|
+
module RuboCop
|
|
77
|
+
module Cop
|
|
78
|
+
module RSpecGuide
|
|
79
|
+
# Short description of what the cop checks.
|
|
80
|
+
#
|
|
81
|
+
# Longer explanation of WHY this is important and what problems
|
|
82
|
+
# it prevents or solves.
|
|
83
|
+
#
|
|
84
|
+
# @safety
|
|
85
|
+
# Describe if the cop is safe to run automatically.
|
|
86
|
+
#
|
|
87
|
+
# @example Bad code
|
|
88
|
+
# # bad - explain what's wrong
|
|
89
|
+
# describe 'Something' do
|
|
90
|
+
# # problematic code
|
|
91
|
+
# end
|
|
92
|
+
#
|
|
93
|
+
# @example Good code
|
|
94
|
+
# # good - explain why this is better
|
|
95
|
+
# describe 'Something' do
|
|
96
|
+
# # correct code
|
|
97
|
+
# end
|
|
98
|
+
#
|
|
99
|
+
# @example Edge cases
|
|
100
|
+
# # good - explain edge case
|
|
101
|
+
# describe 'Something' do
|
|
102
|
+
# # edge case example
|
|
103
|
+
# end
|
|
104
|
+
#
|
|
105
|
+
class YourCopName < Base
|
|
106
|
+
MSG = "Your cop's message to the user"
|
|
107
|
+
|
|
108
|
+
# @!method pattern_to_match?(node)
|
|
109
|
+
def_node_matcher :pattern_to_match?, <<~PATTERN
|
|
110
|
+
(block
|
|
111
|
+
(send nil? :describe ...)
|
|
112
|
+
...)
|
|
113
|
+
PATTERN
|
|
114
|
+
|
|
115
|
+
def on_block(node)
|
|
116
|
+
return unless pattern_to_match?(node)
|
|
117
|
+
|
|
118
|
+
# Your cop logic here
|
|
119
|
+
add_offense(node) if offense_detected?(node)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
private
|
|
123
|
+
|
|
124
|
+
def offense_detected?(node)
|
|
125
|
+
# Your detection logic
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 3. Key Components
|
|
134
|
+
|
|
135
|
+
- **MSG**: The message shown to users when an offense is detected
|
|
136
|
+
- **Node Matchers**: Use `def_node_matcher` to match AST patterns
|
|
137
|
+
- **Callbacks**: Implement `on_block`, `on_send`, etc. to inspect nodes
|
|
138
|
+
- **YARD Documentation**: Add comprehensive examples and explanations
|
|
139
|
+
|
|
140
|
+
### 4. Register Your Cop
|
|
141
|
+
|
|
142
|
+
Add your cop to `lib/rubocop-rspec-guide.rb`:
|
|
143
|
+
|
|
144
|
+
```ruby
|
|
145
|
+
require_relative "rubocop/cop/rspec_guide/your_cop_name"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 5. Add Default Configuration
|
|
149
|
+
|
|
150
|
+
Add your cop to `config/default.yml`:
|
|
151
|
+
|
|
152
|
+
```yaml
|
|
153
|
+
RSpecGuide/YourCopName:
|
|
154
|
+
Description: "Short description of your cop"
|
|
155
|
+
Enabled: true
|
|
156
|
+
VersionAdded: 'X.Y.Z'
|
|
157
|
+
StyleGuideUrl: "https://github.com/AlexeyMatskevich/rspec-guide"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Writing Tests
|
|
161
|
+
|
|
162
|
+
### Test File Location
|
|
163
|
+
|
|
164
|
+
Create a test file in `spec/rubocop/cop/`:
|
|
165
|
+
|
|
166
|
+
- For RSpec cops: `spec/rubocop/cop/rspec_guide/your_cop_name_spec.rb`
|
|
167
|
+
- For FactoryBot cops: `spec/rubocop/cop/factory_bot_guide/your_cop_name_spec.rb`
|
|
168
|
+
|
|
169
|
+
### Test Structure
|
|
170
|
+
|
|
171
|
+
```ruby
|
|
172
|
+
# frozen_string_literal: true
|
|
173
|
+
|
|
174
|
+
RSpec.describe RuboCop::Cop::RSpecGuide::YourCopName, :config do
|
|
175
|
+
let(:config) { RuboCop::Config.new }
|
|
176
|
+
|
|
177
|
+
context 'when code has offense' do
|
|
178
|
+
it 'registers an offense' do
|
|
179
|
+
expect_offense(<<~RUBY)
|
|
180
|
+
describe 'Something' do
|
|
181
|
+
^^^^^^^^^^^^^^^^^^^^^^^ Your cop's message
|
|
182
|
+
# problematic code
|
|
183
|
+
end
|
|
184
|
+
RUBY
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
context 'when code is correct' do
|
|
189
|
+
it 'does not register an offense' do
|
|
190
|
+
expect_no_offenses(<<~RUBY)
|
|
191
|
+
describe 'Something' do
|
|
192
|
+
# correct code
|
|
193
|
+
end
|
|
194
|
+
RUBY
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
context 'with edge case' do
|
|
199
|
+
it 'does not register an offense' do
|
|
200
|
+
expect_no_offenses(<<~RUBY)
|
|
201
|
+
describe 'Something' do
|
|
202
|
+
# edge case code
|
|
203
|
+
end
|
|
204
|
+
RUBY
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Testing Best Practices
|
|
211
|
+
|
|
212
|
+
1. **Test both offenses and non-offenses**: Ensure your cop correctly identifies problems AND doesn't create false positives
|
|
213
|
+
2. **Test edge cases**: Cover boundary conditions and unusual patterns
|
|
214
|
+
3. **Test with configuration options**: If your cop has configuration options, test different settings
|
|
215
|
+
4. **Use descriptive context names**: Make it clear what scenario each test covers
|
|
216
|
+
5. **Follow the behavior-first pattern**: Describe WHAT behavior is being tested, not implementation details
|
|
217
|
+
|
|
218
|
+
### Running Specific Tests
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# Run all tests
|
|
222
|
+
bundle exec rspec
|
|
223
|
+
|
|
224
|
+
# Run tests for a specific cop
|
|
225
|
+
bundle exec rspec spec/rubocop/cop/rspec_guide/your_cop_name_spec.rb
|
|
226
|
+
|
|
227
|
+
# Run a specific test
|
|
228
|
+
bundle exec rspec spec/rubocop/cop/rspec_guide/your_cop_name_spec.rb:10
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Code Style Guidelines
|
|
232
|
+
|
|
233
|
+
This project follows standard RuboCop style guidelines:
|
|
234
|
+
|
|
235
|
+
1. **Use 2 spaces for indentation** (no tabs)
|
|
236
|
+
2. **Keep lines under 120 characters**
|
|
237
|
+
3. **Use frozen string literals** (`# frozen_string_literal: true`)
|
|
238
|
+
4. **Write descriptive variable names**
|
|
239
|
+
5. **Add YARD documentation** for public methods and classes
|
|
240
|
+
6. **Follow RuboCop's own style guide**
|
|
241
|
+
|
|
242
|
+
Run `bundle exec rubocop` to check your code style.
|
|
243
|
+
|
|
244
|
+
## Submitting Changes
|
|
245
|
+
|
|
246
|
+
### Before Submitting
|
|
247
|
+
|
|
248
|
+
1. **Run all tests**: `bundle exec rspec`
|
|
249
|
+
2. **Run RuboCop**: `bundle exec rubocop`
|
|
250
|
+
3. **Update CHANGELOG.md**: Add a note about your change under `[Unreleased]`
|
|
251
|
+
4. **Update documentation**: If you added a new cop, update README.md
|
|
252
|
+
|
|
253
|
+
### Pull Request Process
|
|
254
|
+
|
|
255
|
+
1. **Create a feature branch**:
|
|
256
|
+
```bash
|
|
257
|
+
git checkout -b feature/your-feature-name
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
2. **Make your changes and commit**:
|
|
261
|
+
```bash
|
|
262
|
+
git add .
|
|
263
|
+
git commit -m "Add YourCopName to detect X pattern"
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
3. **Push to your fork**:
|
|
267
|
+
```bash
|
|
268
|
+
git push origin feature/your-feature-name
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
4. **Open a Pull Request** on GitHub
|
|
272
|
+
|
|
273
|
+
5. **PR Checklist**:
|
|
274
|
+
- [ ] Tests pass (`bundle exec rspec`)
|
|
275
|
+
- [ ] RuboCop passes (`bundle exec rubocop`)
|
|
276
|
+
- [ ] New cop has comprehensive YARD documentation (3+ examples)
|
|
277
|
+
- [ ] New cop has tests covering offenses, non-offenses, and edge cases
|
|
278
|
+
- [ ] CHANGELOG.md updated
|
|
279
|
+
- [ ] README.md updated (if adding new cop)
|
|
280
|
+
- [ ] config/default.yml updated (if adding new cop)
|
|
281
|
+
|
|
282
|
+
### PR Title Format
|
|
283
|
+
|
|
284
|
+
- **For new cops**: `Add RSpecGuide/YourCopName cop`
|
|
285
|
+
- **For bug fixes**: `Fix RSpecGuide/YourCopName false positive on X`
|
|
286
|
+
- **For improvements**: `Improve RSpecGuide/YourCopName to handle Y`
|
|
287
|
+
- **For documentation**: `Update documentation for RSpecGuide/YourCopName`
|
|
288
|
+
|
|
289
|
+
## Commit Message Guidelines
|
|
290
|
+
|
|
291
|
+
Follow these conventions for commit messages:
|
|
292
|
+
|
|
293
|
+
### Format
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
Short summary (50 chars or less)
|
|
297
|
+
|
|
298
|
+
Detailed explanation if needed. Wrap at 72 characters.
|
|
299
|
+
Explain WHAT changed and WHY, not HOW (code shows how).
|
|
300
|
+
|
|
301
|
+
- Bullet points are okay
|
|
302
|
+
- Use present tense: "Add feature" not "Added feature"
|
|
303
|
+
- Reference issues: "Fixes #123" or "Closes #456"
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Examples
|
|
307
|
+
|
|
308
|
+
**Good commit messages:**
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
Add MinimumBehavioralCoverage cop
|
|
312
|
+
|
|
313
|
+
Checks that describe blocks test at least 2 behavioral variations.
|
|
314
|
+
Supports both traditional (2+ contexts) and new (it-blocks + contexts)
|
|
315
|
+
patterns.
|
|
316
|
+
|
|
317
|
+
Closes #42
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
Fix ContextSetup false positive on nested describes
|
|
322
|
+
|
|
323
|
+
The cop was incorrectly flagging contexts inside nested describes
|
|
324
|
+
when setup was present in the parent describe block.
|
|
325
|
+
|
|
326
|
+
Fixes #89
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Bad commit messages:**
|
|
330
|
+
|
|
331
|
+
```
|
|
332
|
+
fix bug
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
updated code
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
```
|
|
340
|
+
WIP - will finish later
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Questions?
|
|
344
|
+
|
|
345
|
+
If you have questions or need help:
|
|
346
|
+
|
|
347
|
+
1. Check existing [Issues](https://github.com/AlexeyMatskevich/rubocop-rspec-guide/issues)
|
|
348
|
+
2. Check existing [Pull Requests](https://github.com/AlexeyMatskevich/rubocop-rspec-guide/pulls)
|
|
349
|
+
3. Open a new issue with the `question` label
|
|
350
|
+
|
|
351
|
+
## Resources
|
|
352
|
+
|
|
353
|
+
- [RuboCop Development Guide](https://docs.rubocop.org/rubocop/development.html)
|
|
354
|
+
- [RuboCop AST Documentation](https://docs.rubocop.org/rubocop-ast/)
|
|
355
|
+
- [RSpec Style Guide](https://github.com/AlexeyMatskevich/rspec-guide)
|
|
356
|
+
- [Parser AST Explorer](https://ruby-ast-explorer.herokuapp.com/) - Visualize Ruby AST
|
|
357
|
+
|
|
358
|
+
Thank you for contributing! 🎉
|