rubocop-rspec-guide 0.2.1 → 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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -6
  3. data/.yardopts +9 -0
  4. data/CHANGELOG.md +92 -0
  5. data/CONTRIBUTING.md +358 -0
  6. data/INTEGRATION_TESTING.md +324 -0
  7. data/README.md +443 -16
  8. data/Rakefile +49 -0
  9. data/benchmark/README.md +349 -0
  10. data/benchmark/baseline_v0.3.1.txt +67 -0
  11. data/benchmark/baseline_v0.4.0.txt +167 -0
  12. data/benchmark/benchmark_helper.rb +92 -0
  13. data/benchmark/compare_versions.rb +136 -0
  14. data/benchmark/cops_benchmark.rb +428 -0
  15. data/benchmark/cops_performance.rb +109 -0
  16. data/benchmark/quick_comparison.rb +58 -0
  17. data/benchmark/quick_invariant_bench.rb +52 -0
  18. data/benchmark/rspec_base_integration.rb +86 -0
  19. data/benchmark/save_baseline.rb +18 -0
  20. data/benchmark/scalability_benchmark.rb +181 -0
  21. data/config/default.yml +43 -2
  22. data/config/obsoletion.yml +6 -0
  23. data/lib/rubocop/cop/factory_bot_guide/dynamic_attribute_evaluation.rb +193 -0
  24. data/lib/rubocop/cop/factory_bot_guide/dynamic_attributes_for_time_and_random.rb +10 -106
  25. data/lib/rubocop/cop/rspec_guide/characteristics_and_contexts.rb +13 -78
  26. data/lib/rubocop/cop/rspec_guide/context_setup.rb +81 -30
  27. data/lib/rubocop/cop/rspec_guide/duplicate_before_hooks.rb +89 -22
  28. data/lib/rubocop/cop/rspec_guide/duplicate_let_values.rb +91 -22
  29. data/lib/rubocop/cop/rspec_guide/happy_path_first.rb +52 -21
  30. data/lib/rubocop/cop/rspec_guide/invariant_examples.rb +60 -19
  31. data/lib/rubocop/cop/rspec_guide/minimum_behavioral_coverage.rb +165 -0
  32. data/lib/rubocop/rspec/guide/inject.rb +26 -0
  33. data/lib/rubocop/rspec/guide/plugin.rb +45 -0
  34. data/lib/rubocop/rspec/guide/version.rb +1 -1
  35. data/lib/rubocop-rspec-guide.rb +4 -0
  36. metadata +49 -1
@@ -0,0 +1,324 @@
1
+ # Integration Testing Guide
2
+
3
+ This document describes how to test rubocop-rspec-guide on real-world projects to catch false positives and edge cases.
4
+
5
+ ## Why Integration Testing?
6
+
7
+ Unit tests verify cops work on isolated code examples. Integration testing verifies:
8
+ - ✅ No crashes on real codebases
9
+ - ✅ No false positives on valid patterns
10
+ - ✅ Performance is acceptable on large projects
11
+ - ✅ Edge cases not covered by unit tests
12
+
13
+ ## Manual Integration Testing
14
+
15
+ ### Step 1: Choose a Test Project
16
+
17
+ Use a real Ruby project with RSpec tests. Good candidates:
18
+ - Your own projects (best - you know the codebase)
19
+ - Open-source gems you maintain
20
+ - Popular gems: rspec-core, factory_bot, etc.
21
+
22
+ **Current test project**: [model_settings](https://github.com/AlexeyMatskevich/model_settings)
23
+
24
+ ### Step 2: Add rubocop-rspec-guide to Project
25
+
26
+ In the test project's Gemfile:
27
+
28
+ ```ruby
29
+ group :development do
30
+ gem 'rubocop-rspec-guide', path: '/path/to/rubocop-rspec-guide'
31
+ # Or from git:
32
+ # gem 'rubocop-rspec-guide', git: 'https://github.com/AlexeyMatskevich/rubocop-rspec-guide'
33
+ end
34
+ ```
35
+
36
+ Run:
37
+ ```bash
38
+ bundle install
39
+ ```
40
+
41
+ ### Step 3: Configure RuboCop
42
+
43
+ Create or update `.rubocop.yml` in the test project:
44
+
45
+ ```yaml
46
+ require:
47
+ - rubocop-rspec-guide
48
+
49
+ AllCops:
50
+ NewCops: enable
51
+ Include:
52
+ - 'spec/**/*'
53
+
54
+ # Enable all RSpecGuide cops
55
+ RSpecGuide/MinimumBehavioralCoverage:
56
+ Enabled: true
57
+
58
+ RSpecGuide/HappyPathFirst:
59
+ Enabled: true
60
+
61
+ RSpecGuide/ContextSetup:
62
+ Enabled: true
63
+
64
+ RSpecGuide/DuplicateLetValues:
65
+ Enabled: true
66
+ WarnOnPartialDuplicates: true # More strict
67
+
68
+ RSpecGuide/DuplicateBeforeHooks:
69
+ Enabled: true
70
+
71
+ RSpecGuide/InvariantExamples:
72
+ Enabled: true
73
+
74
+ FactoryBotGuide/DynamicAttributeEvaluation:
75
+ Enabled: true
76
+ ```
77
+
78
+ ### Step 4: Run RuboCop
79
+
80
+ ```bash
81
+ cd /path/to/test-project
82
+ bundle exec rubocop --only RSpecGuide,FactoryBotGuide
83
+ ```
84
+
85
+ ### Step 5: Analyze Results
86
+
87
+ #### ✅ No Offenses
88
+
89
+ Perfect! Cops work correctly on this project.
90
+
91
+ ```
92
+ Inspecting 25 files
93
+ .........................
94
+
95
+ 25 files inspected, no offenses detected
96
+ ```
97
+
98
+ #### ⚠️ Offenses Found
99
+
100
+ Review each offense:
101
+
102
+ ```
103
+ spec/model_settings_spec.rb:10:1: C: RSpecGuide/MinimumBehavioralCoverage:
104
+ Describe block should test at least 2 behavioral variations
105
+ RSpec.describe ModelSettings do
106
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
107
+
108
+ 25 files inspected, 5 offenses detected
109
+ ```
110
+
111
+ For each offense, determine:
112
+
113
+ 1. **Legitimate offense** - Real code smell that should be fixed
114
+ - Action: Fix the test code
115
+ - This validates the cop is useful!
116
+
117
+ 2. **False positive** - Cop incorrectly flagged valid code
118
+ - Action: File an issue with example
119
+ - Add regression test
120
+ - Fix the cop logic
121
+
122
+ 3. **Debatable** - Valid pattern but cop is opinionated
123
+ - Action: Consider adding configuration option
124
+ - Document the rationale
125
+ - May be acceptable to leave as-is
126
+
127
+ #### ❌ RuboCop Crashes
128
+
129
+ If RuboCop crashes with an error:
130
+
131
+ ```
132
+ An error occurred while RSpecGuide/MinimumBehavioralCoverage cop was inspecting...
133
+ ```
134
+
135
+ This is a **critical bug**:
136
+ 1. Note the error message and backtrace
137
+ 2. Identify the problematic file and line
138
+ 3. Create minimal reproduction
139
+ 4. Fix the cop to handle this edge case
140
+ 5. Add regression test
141
+
142
+ ### Step 6: Document Findings
143
+
144
+ Create an issue or document in this file:
145
+
146
+ ```markdown
147
+ ## Integration Test: model_settings (2025-10-30)
148
+
149
+ **Project**: https://github.com/AlexeyMatskevich/model_settings
150
+ **Files**: 25 spec files
151
+ **Result**: ✅ No false positives
152
+
153
+ ### Offenses Found
154
+
155
+ 1. `spec/model_settings_spec.rb:10` - MinimumBehavioralCoverage
156
+ - **Assessment**: Legitimate - only tests one scenario
157
+ - **Action**: Fixed in project
158
+
159
+ 2. `spec/configuration_spec.rb:45` - ContextSetup
160
+ - **Assessment**: Legitimate - context without setup
161
+ - **Action**: Fixed in project
162
+
163
+ ### Performance
164
+
165
+ - **Time**: 0.95 seconds for 25 files
166
+ - **Assessment**: ✅ Excellent
167
+
168
+ ### Edge Cases Discovered
169
+
170
+ None - cops handled all patterns correctly.
171
+ ```
172
+
173
+ ## Automated Integration Testing (Future)
174
+
175
+ For CI/CD, we could automate this:
176
+
177
+ ```yaml
178
+ # .github/workflows/integration.yml
179
+ name: Integration Tests
180
+
181
+ on: [push, pull_request]
182
+
183
+ jobs:
184
+ test-on-model-settings:
185
+ runs-on: ubuntu-latest
186
+ steps:
187
+ - uses: actions/checkout@v2
188
+ - name: Clone test project
189
+ run: git clone --depth 1 https://github.com/AlexeyMatskevich/model_settings.git
190
+
191
+ - name: Add gem to test project
192
+ run: |
193
+ cd model_settings
194
+ echo "gem 'rubocop-rspec-guide', path: '..'" >> Gemfile
195
+ bundle install
196
+
197
+ - name: Run RuboCop
198
+ run: |
199
+ cd model_settings
200
+ bundle exec rubocop --only RSpecGuide,FactoryBotGuide
201
+ continue-on-error: true
202
+
203
+ - name: Check for crashes
204
+ run: |
205
+ cd model_settings
206
+ bundle exec rubocop --only RSpecGuide,FactoryBotGuide > output.txt 2>&1
207
+ if grep -q "An error occurred" output.txt; then
208
+ echo "RuboCop crashed!"
209
+ exit 1
210
+ fi
211
+ ```
212
+
213
+ ## Best Practices
214
+
215
+ ### When to Run Integration Tests
216
+
217
+ - ✅ Before each release
218
+ - ✅ After adding/modifying cops
219
+ - ✅ After refactoring cop internals
220
+ - ✅ When users report false positives
221
+ - ✅ Periodically (monthly) on updated projects
222
+
223
+ ### What to Test
224
+
225
+ - **Diverse projects**: Different styles, patterns, gems
226
+ - **Your own projects**: Easiest to debug and fix
227
+ - **Popular gems**: Representative of community usage
228
+ - **Edge cases**: Projects using advanced RSpec features
229
+
230
+ ### What to Look For
231
+
232
+ 1. **Crashes**: Unhandled exceptions
233
+ 2. **False positives**: Valid code flagged as offense
234
+ 3. **Performance**: > 2 seconds per file is slow
235
+ 4. **Confusing messages**: Users won't understand
236
+ 5. **Edge cases**: Patterns not in unit tests
237
+
238
+ ## Regression Testing
239
+
240
+ When you find a false positive:
241
+
242
+ 1. **Create minimal example**:
243
+ ```ruby
244
+ # This was incorrectly flagged by MinimumBehavioralCoverage
245
+ RSpec.describe User do
246
+ it_behaves_like "active record model"
247
+
248
+ context "with custom validation" do
249
+ it "validates email" do
250
+ expect(user.valid?).to be true
251
+ end
252
+ end
253
+ end
254
+ ```
255
+
256
+ 2. **Add to unit tests**:
257
+ ```ruby
258
+ it "does not flag shared examples + context pattern" do
259
+ expect_no_offenses(<<~RUBY)
260
+ RSpec.describe User do
261
+ it_behaves_like "active record model"
262
+
263
+ context "with custom validation" do
264
+ it "validates email" do
265
+ expect(user.valid?).to be true
266
+ end
267
+ end
268
+ end
269
+ RUBY
270
+ end
271
+ ```
272
+
273
+ 3. **Fix the cop** to handle this pattern
274
+
275
+ 4. **Re-run integration test** to verify fix
276
+
277
+ ## Integration Test Results
278
+
279
+ ### model_settings (2025-10-30)
280
+
281
+ **Project**: https://github.com/AlexeyMatskevich/model_settings
282
+ **Branch**: main
283
+ **Commit**: latest
284
+ **Gem Version**: 0.3.1
285
+
286
+ **Configuration**:
287
+ - All RSpecGuide cops enabled
288
+ - All FactoryBotGuide cops enabled
289
+ - Default configuration (no customization)
290
+
291
+ **Results**:
292
+ - ✅ No crashes
293
+ - ⏱️ Performance: 0.95s for 25 spec files
294
+ - 📊 Offenses: TBD (run test to populate)
295
+
296
+ **Offenses Found**: TBD
297
+
298
+ **False Positives**: None
299
+
300
+ **Edge Cases**: None
301
+
302
+ **Conclusion**: Cops work correctly on this real-world project.
303
+
304
+ ---
305
+
306
+ ## Adding Your Project
307
+
308
+ If you use rubocop-rspec-guide on your project, please document your experience:
309
+
310
+ ```markdown
311
+ ### your-project (YYYY-MM-DD)
312
+
313
+ **Project**: URL
314
+ **Files**: X spec files
315
+ **Result**: ✅/⚠️/❌
316
+
317
+ **Offenses**: X found, Y false positives
318
+ **Performance**: X.XX seconds
319
+ **Notes**: Any interesting findings
320
+
321
+ **Would you recommend**: Yes/No
322
+ ```
323
+
324
+ This helps us understand real-world usage and improve the cops!