-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy path.rubocop.yml
More file actions
655 lines (621 loc) · 24.1 KB
/
Copy path.rubocop.yml
File metadata and controls
655 lines (621 loc) · 24.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
# RuboCop configuration
# https://docs.rubocop.org/rubocop/configuration.html
inherit_from: .rubocop_todo.yml
inherit_mode:
merge:
- Exclude
plugins:
- rubocop-capybara
- rubocop-minitest
- rubocop-performance
- rubocop-rails
require:
- ./lib/rubocop/cop/mo/dry_test_render_helper
- ./lib/rubocop/cop/mo/initialize_without_prop
- ./lib/rubocop/cop/mo/lowercase_translation_tag
- ./lib/rubocop/cop/mo/no_active_record_relation_prop
- ./lib/rubocop/cop/mo/no_hand_rolled_form_tag
- ./lib/rubocop/cop/mo/no_hand_rolled_method_field
- ./lib/rubocop/cop/mo/no_raw_bootstrap_component
- ./lib/rubocop/cop/mo/no_raw_link_or_button_to
- ./lib/rubocop/cop/mo/no_render_phlex_method_name
- ./lib/rubocop/cop/mo/no_resolved_errors_add_type
- ./lib/rubocop/cop/mo/prefer_kit_syntax
- ./lib/rubocop/cop/mo/redundant_render_view_invalid
- ./lib/rubocop/cop/mo/self_status_outside_invalid_method
- ./lib/rubocop/cop/mo/status_kwarg_outside_invalid_method
- ./lib/rubocop/cop/mo/unguarded_params_to_prop
AllCops:
NewCops: enable
########################### Excluded files ###################################
# Completely ignore the following
Exclude:
- .codeclimate.yml
- app/assets/javascripts/bootstrap.js
- app/assets/javascripts/jquery.js
- app/assets/javascripts/jstz.js
- app/assets/javascripts/lightbox.js
- "db/**/*"
- "log/**/*"
- "projects/**/*"
- public/design_test/jquery-1.5.2.min.js
# We need not check these scripts, and some of them cause Rubocop errors
- "script/old/**/*"
# not Ruby
- script/perf_monitor
- "tmp/**/*"
# ------------------------------------------------------------------------------
########### Individual cops for which MO uses a non-default configuration
MO/DryTestRenderHelper:
Description: >-
render(SomeClass.new(...)) repeated inline across sibling test_*
methods must go through a private render_x helper instead -- see
lib/rubocop/cop/mo/dry_test_render_helper.rb and "Extract DRY
Render Helper" in .claude/rules/testing.md.
Enabled: true
Include:
- "test/components/**/*_test.rb"
- "test/views/**/*_test.rb"
MO/InitializeWithoutProp:
Description: >-
A Phlex class defining `initialize` with hand-assigned `@ivar =`
state and no `prop` of its own should use Literal props instead --
see lib/rubocop/cop/mo/initialize_without_prop.rb and the #5020
prop-conversion sweep.
Enabled: true
Include:
- "app/components/**/*.rb"
- "app/views/**/*.rb"
Exclude:
# Every field class here takes a Superform::Field or FieldProxy --
# both are duck-typed, so the only prop type available is a vague
# _Interface(:dom, :value), not a concrete class; `wrapper_options`/
# `attributes` are already-generic Hash catch-alls. Converting
# doesn't buy real type safety here the way it does elsewhere, and
# several files subclass Superform's own component classes
# directly (third-party initialize signatures, positional `field`
# args, no dedicated test coverage). Not worth the risk/reward;
# left as manual initialize.
- "app/components/application_form/**/*.rb"
MO/LowercaseTranslationTag:
Description: >-
Translation tag symbols (used with .l/.t/.tl/.tp/.tpl/.ti) must be
lowercase -- see lib/rubocop/cop/mo/lowercase_translation_tag.rb
and GH issue #4843.
Enabled: true
MO/NoActiveRecordRelationProp:
Description: >-
Phlex `prop` types must not reference ActiveRecord::Relation --
materialize with .to_a at the call site and use _Array(<Model>)
instead, so the element type is checked too -- see
lib/rubocop/cop/mo/no_active_record_relation_prop.rb.
Enabled: true
Include:
- "app/components/**/*.rb"
- "app/views/**/*.rb"
MO/NoHandRolledFormTag:
Description: >-
Phlex views/components must not call the bare form(...) tag helper
directly -- use Components::ApplicationForm (Superform) instead --
see lib/rubocop/cop/mo/no_hand_rolled_form_tag.rb and issue #5100.
Every legitimate raw form(...) call site is inline-disabled at the
call site itself, not file-excluded here -- a file-level Exclude
would give the whole file blanket immunity to any FUTURE raw
form(...) call added anywhere else in it, not just the one
reviewed site.
Enabled: true
Include:
- "app/components/**/*.rb"
- "app/views/**/*.rb"
MO/NoHandRolledMethodField:
Description: >-
Superform-based forms must not hand-roll a `_method` hidden field
via `hidden_field("_method", ...)` -- Superform already emits one,
driven by `persisted?`/an explicit `method:` on the constructor.
A second one produces two `_method` hiddens, and turbo-rails
silently strips the override rather than picking either -- see
lib/rubocop/cop/mo/no_hand_rolled_method_field.rb and #5088.
Enabled: true
Include:
- "app/components/**/*.rb"
- "app/views/**/*.rb"
MO/NoResolvedErrorsAddType:
Description: >-
errors.add's type argument must be a bare tag symbol, resolved
lazily at display time -- not an eagerly-resolved .t/.l/.tl/.tp/
.tpl call -- see lib/rubocop/cop/mo/no_resolved_errors_add_type.rb
and #4901/#4920.
Enabled: true
MO/NoRawBootstrapComponent:
Description: >-
Phlex views/components must not hand-roll the markup for a
top-level Bootstrap UI component MO already has a Components::*
wrapper for (Alert, Modal, Dropdown, ListGroup, NavTabs, Panel,
Navbar, Carousel, InputGroup, ButtonGroup) -- see
lib/rubocop/cop/mo/no_raw_bootstrap_component.rb.
Enabled: true
Include:
- "app/components/**/*.rb"
- "app/views/**/*.rb"
Exclude:
# Superform-based field classes (Components::Form::Input <
# Superform::Rails::Components::Input) don't share an inheritance
# line with Components::Base, so they have no Kit-sugar/Components
# infrastructure to swap into -- see app/components/form/input.rb's
# own comment. autocompleter_field.rb's `.dropdown-menu` div is a
# Stimulus-driven autocomplete pulldown reusing the class for
# styling only, not Bootstrap's actual toggle-button JS behavior.
- "app/components/application_form/**/*.rb"
# NavTabs' own implementation -- legitimately builds the
# `<ul class="nav nav-tabs">` this cop exists to make everyone
# else use NavTabs(...) for instead.
- "app/components/nav_tabs.rb"
# Deliberate: the sidebar's `.list-group` wrapper holds several
# independently `cache(...)`-wrapped sections that render
# Components::ListGroup::Item/LinkItem directly, not via a
# `ListGroup(...) do |list| ... end` builder block -- swapping in
# Components::ListGroup here would route those renders through
# `vanish`/deferred registration, which silently breaks fragment
# caching (see list_group.rb's own docs, which name this file as
# the deliberate exception).
- "app/views/layouts/sidebar.rb"
MO/NoRawLinkOrButtonTo:
Description: >-
Phlex views/components must use Components::Link/Components::Button
(Link(...)/Button(...) Kit syntax) instead of calling link_to/
button_to directly -- see
lib/rubocop/cop/mo/no_raw_link_or_button_to.rb.
Enabled: true
Include:
- "app/components/**/*.rb"
- "app/views/**/*.rb"
Exclude:
# The Link/Button component family's own implementations -- these
# legitimately call link_to/button_to to BUILD the abstraction
# every other Phlex file is required to use instead.
- "app/components/button.rb"
- "app/components/button/**/*.rb"
- "app/components/link.rb"
- "app/components/link/**/*.rb"
- "app/components/link_rendering.rb"
# Emails can't use interactive Bootstrap/Stimulus components --
# they need plain, inline-styled tags with no JS dependency.
- "app/views/mailers/**/*.rb"
# A copy-to-clipboard <button role="button"> styled as a .badge,
# not an action button -- Components::Button's whole abstraction
# is .btn-family styling/variants, which doesn't fit a badge.
# Genuinely a different primitive, not a bypass of Button.
- "app/components/id_badge.rb"
MO/NoRenderPhlexMethodName:
Description: >-
A controller render-dispatch method named render_phlex_* -- the
whole app is Phlex now, so the qualifier carries no information.
Use render_<action>_view instead (render_new_view,
render_edit_view, render_show_view, ...) -- see
lib/rubocop/cop/mo/no_render_phlex_method_name.rb and
.claude/rules/turbo_submit_forms.md (issue #5052).
Enabled: true
Include:
- "app/controllers/**/*.rb"
MO/PreferKitSyntax:
Description: >-
Phlex views/components should call Foo(...) (Kit syntax) rather
than render(Components::Foo.new(...)) for a single-level
Components class -- see lib/rubocop/cop/mo/prefer_kit_syntax.rb.
Enabled: true
Include:
- "app/components/**/*.rb"
- "app/views/**/*.rb"
MO/RedundantRenderViewInvalid:
Description: >-
A controller/concern defining its own render_new_view_invalid/
render_edit_view_invalid duplicates ApplicationController's
generic dispatcher -- see
lib/rubocop/cop/mo/redundant_render_view_invalid.rb and
.claude/rules/turbo_submit_forms.md (issue #5052).
Enabled: true
Include:
- "app/controllers/**/*.rb"
Exclude:
- "app/controllers/application_controller.rb"
MO/SelfStatusOutsideInvalidMethod:
Description: >-
self.status = ... written outside a *_invalid-named method is the
hand-rolled anti-pattern this sweep exists to prevent -- fold it
into a *_invalid method instead. See
lib/rubocop/cop/mo/self_status_outside_invalid_method.rb and
.claude/rules/turbo_submit_forms.md (issue #5052).
Enabled: true
Include:
- "app/controllers/**/*.rb"
MO/StatusKwargOutsideInvalidMethod:
Description: >-
status: :unprocessable_content passed as a kwarg outside a
*_invalid-named method is the same hand-rolled anti-pattern
MO/SelfStatusOutsideInvalidMethod bans for `self.status = ...` --
fold it into a *_invalid method instead. See
lib/rubocop/cop/mo/status_kwarg_outside_invalid_method.rb and
.claude/rules/turbo_submit_forms.md (issue #5052).
Enabled: true
Include:
- "app/controllers/**/*.rb"
MO/UnguardedParamsToProp:
Description: >-
A controller passing a raw params[...]/params.dig(...) read (or an
ivar assigned from one) straight into a Components::/Views::
constructor kwarg can raise Literal::TypeError on a nested-hash
param -- guard with params.permit first. See
lib/rubocop/cop/mo/unguarded_params_to_prop.rb and
.claude/rules/params_to_literal_props.md.
Enabled: true
Include:
- "app/controllers/**/*.rb"
Gemspec:
# Not relevent (MO is not a gem)
Enabled: false
Layout/BeginEndAlignment:
# Rubocop default: start_of_line
# which aligns "end" with **start of the line** that includes "begin"
# MO: align with "begin". This is how we've almost always done it.
# And it's consistent with Layout/EndAlignment for other keywords.
EnforcedStyleAlignWith: begin
Layout/DotPosition:
# Rubocop default: leading
EnforcedStyle: trailing
Layout/HashAlignment:
# Repeat the Rubocop default because Codeclimate ignores it as of 2019-07-09
EnforcedColonStyle: key
Layout/LineEndStringConcatenationIndentation:
# We most consistently align the start of the continued line
# with the start of the string on the previous line.
# This does not correspond to any available EnforcedStyle.
Enabled: false
Layout/LineLength:
# RuboCop default: 120
# Use 80 instead because some developers have smaller screens
Max: 80
Layout/MultilineMethodParameterLineBreaks:
# Makes Each param in a multi-line method definition start on a separate line.
# RuboCop default: true
# Cop seems like overkill; MO has many relevant methods with >1 param per line
Enabled: false
Lint/AmbiguousOperatorPrecedence:
# We do this only in rare cases; Always doing it would add uneeded clutter
Enabled: false
Lint/NonAtomicFileOperation:
# Disable until I understand the cop's implications - jdc 2022-07-14
# https://docs.rubocop.org/rubocop/1.31/cops_lint.html#lintnonatomicfileoperation
Enabled: false
Metrics/AbcSize:
# This Cop makes less sense in tests, we regularly ignore it.
Exclude:
- "test//**/*"
Metrics/BlockLength:
# This Cop makes less sense in tests, we regularly ignore it.
Exclude:
- "test//**/*"
# Concerns define two blocks with `included` (instance) and `class_methods`
AllowedMethods:
- included
- class_methods
Metrics/ClassLength:
# Rubocop default: 100
# Relaxed metric based on actual practice
Max: 250
Exclude:
# This Cop makes less sense in tests, we regularly ignore it.
- "test//**/*"
Metrics/CyclomaticComplexity:
# This Cop makes less sense in tests, we regularly ignore it.
Exclude:
- "test//**/*"
Metrics/MethodLength:
# Rubocop default: 10
# Relaxed metric based on Codeclimate's default .rubocop.yml
Max: 30
# This Cop makes less sense in tests, we regularly ignore it.
Exclude:
- "test//**/*"
Metrics/ModuleLength:
# Rubocop default: 100
# Relaxed metric based on Codeclimate's default .rubocop.yml
Max: 250
# This Cop makes less sense in tests, we regularly ignore it.
Exclude:
- "test//**/*"
Metrics/PerceivedComplexity:
# This Cop makes less sense in tests, we regularly ignore it.
Exclude:
- "test//**/*"
Naming/BlockForwarding:
# In Ruby 3.1, anonymous block forwarding has been added.
# This cop identifies places where `do_something(&block)`
# can be replaced by `do_something(&)`.
# Default is `anonymous`
# Keeping it `explicit` until we're ready to switch.
EnforcedStyle: explicit
Naming/PredicateMethod:
# NOTE: I disabled the cop for methods with side effects. jdc 2025-07-03
AllowedMethods:
- allowed_to_see!
- already_have_personal_herbarium!
- block_suspended_users
- cant_make_this_personal_herbarium!
- check_date
- check_dest_exists!
- check_dest_permission!
- check_external_link_permission!
- check_for_qr_code
- check_if_preference_filters_applied
- check_last_obs
- check_name
- check_observation_permission!
- check_params_or_flash_errors!
- check_permission_or_redirect!
- check_src_exists!
- check_src_permission!
- check_time
- check_year
- delete_vote
- deprecate_others
- enforce_default_reasons
- execute_destroy!
- flash_error
- flash_error_and_reload_if_form_has_errors
- flash_notice
- flash_warning
- get_image_transferred_state_externally
- google_parse_one_clause
- image_or_projects_updated
- init_ivars_for_edit
- kick_out_excessive_traffic
- kick_out_robots
- login_required
- make_sure_can_delete!
- make_sure_can_edit!
- make_sure_genus_has_classification!
- make_sure_name_below_genus!
- make_sure_name_is_at_or_above_genus!
- make_sure_name_is_genus!
- make_sure_parent_has_classification!
- make_sure_parent_higher_rank!
- make_sure_theme_is_valid!
- match_ignoring_some_bits
- nonpersonal!
- ok_field_slip_count
- parsing
- public_write_was
- redirect_non_admins!
- redirect_to_referrer
- remove_observations
- request_merge
- require_successful_user
- save_location
- save_observation
- save_with_log
- show_url
- set_locale
- testing
- to_boolean
- too_many_results
- try_finding_matching_anchor
- try_finding_matching_button
- try_to_save_new_observation
- update_admin_status
- update_and_save_names
- update_object
- update_redirect_and_flash_notices
- update_trust_status
- valid_dates
- valid_title
- validate_and_save_new_user!
- validate_herbarium_name!
- validate_images
- validate_location!
- validate_name
- validate_naming
- validate_objects!
- validate_observation
- validate_personal_herbarium!
- validate_place_name
- validate_projects
- validate_vote
- verify_ip
- verify_user_owns_key
- we_have_a_what!
Naming/VariableNumber:
# We have a mix of snake_case and normal case.
# Standardizing plus creating exceptions, would take some effort,
# is low priority, and the devs are good with disabling the cop.
# 2025-05-08 jdc
Enabled: false
Performance/Casecmp:
# This cop does not work with Unicode in Ruby 2.4
Enabled: false
Performance/RegexpMatch:
# Autocorrect changes "something.match(regexp)" to "something.match?(regexp)".
# The latter throws an error when something is not a Regexp, String or Symbol
# Example: undefined method `match?' for nil:NilClass
# So manually correct to: regexp.match?(something)
AutoCorrect: false
Performance/StringInclude:
# "This cop’s offenses are not safe to auto-correct if a receiver is nil."
Enabled: false
Rails/ActionOrder:
# Allow `edit` after `create`
# See https://github.com/MushroomObserver/mushroom-observer/pull/1241#issuecomment-1364636450
ExpectedOrder:
- index
- show
- new
# - edit
- create
- update
- destroy
Rails/DynamicFindBy:
# Make autocorrect saf(er) by whitelisting our find_by methods
AllowedMethods: find_by_sql, find_by_code_with_wildcards, find_by_name_with_wildcards, find_by_name_or_reverse_name, find_by_scientific_name_with_wildcards, find_by_title_with_wildcards, find_by_title_with_wildcards
AutoCorrect: true
Rails/RedundantPresenceValidationOnBelongsTo: # new in 2.13
# Cop gives false positives
# Perhaps because we don't load Rails defaults in config, and also don't have
# config.active_record.belongs_to_required_by_default
# See also https://github.com/MushroomObserver/mushroom-observer/issues/1072
Enabled: false
Rails/RenderInline:
# https://github.com/MushroomObserver/mushroom-observer/pull/1079#discussion_r917332451
Exclude:
- "app/controllers/ajax_controller/**/*"
Rails/WhereExists:
# Can be unsafe depending on eager_load vs pre_load
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railswhereexists
Enabled: false
Style/AccessorGrouping:
# https://github.com/MushroomObserver/mushroom-observer/pull/988
Enabled: false
# The following are Exclude in case we re-enable the cop
# Exclude files that individually comment accessors
# else Rubocop concatenates the accessors and comments on a single line.
# Disabling Style/AccessorGrouping around the accessors doesn't
# work in this context because Rubocop v1.30.0 generates a
# Style/EmptyLinesAroundAttributeAccessor offense
# See https://github.com/rubocop/rubocop/issues/10693
Exclude:
- "app/classes/country_counter.rb"
- "app/classes/mo_paginator.rb"
Style/AsciiComments:
# Allow non-ascii characters in comments; we need to use accented chars
Enabled: false
Style/ClassAndModuleChildren:
# Allow nested or compact module declaration
Enabled: false
Style/DateTime:
# Repeat the RuboCop default because CodeClimate silently overrides it
# Is this still true? JDC 2020-08-17
Enabled: false
Style/Documentation:
# We often ignore this and bare-bones comments add nothing useful.
# And see Martin, Clean Code, ch. 4
# (Redundant Comments and Mandated Comments are Bad Comments)
Enabled: false
Style/DoubleNegation:
# Rubocop default: true
# Allow double bang. In the rare places we do this, its use is justified.
Enabled: false
Style/EmptyHeredoc:
# Empty Heredoc is usedful as a placeholder in script/refresh_sitemap
Exclude:
- script/refresh_sitemap
Style/FormatStringToken:
# It doesn't seem like we gain much by doing this.
Enabled: false
# The commented-out lines below are in case we re-enable the cop
# # This doesn't work for redirect in config/routes.rb.
# AllowedMethods:
# - "redirect"
Style/HashSyntax:
# Ruby 3.1 supports a new JS-like shorthand hash key/val assignment
# as long as key names and value variable names are the same.
# e.g. { foo: } is evaluated like { foo: foo }
# https://dev.to/baweaver/ruby-3-1-shorthand-hash-syntax-first-impressions-19op
# This setting allows for a transition while we get used to the new style.
# AN 2022-10-09
EnforcedShorthandSyntax: either
Style/MethodCallWithArgsParentheses:
# MO uses parentheses (except for some macro-style methods)
Enabled: true
Style/PercentLiteralDelimiters:
# Repeat the RuboCop defaults because Codeclimate silently overrides them
# Is that still true? JDC 2020-08-17?
PreferredDelimiters:
default: "()"
"%i": "[]"
"%I": "[]"
"%r": "{}"
"%w": "[]"
"%W": "[]"
Style/RaiseArgs:
# Rubocop defaiult: exploded
# I can't figure out how to get exploded to work with API.
EnforcedStyle: compact
Style/StringLiterals:
# Rubocop default: single_quotes
EnforcedStyle: double_quotes
Style/StringLiteralsInInterpolation:
# Rubocop default: single_quotes
EnforcedStyle: double_quotes
Style/SymbolArray:
# Rubocop default: percent. Ex: %i[foo bar baz]
# MO uses plain brackets. Ex: [:foo, :bar, :baz]
EnforcedStyle: brackets
Rails/SkipsModelValidations:
# We skip validations all the time. I'm tired of disabling this cop.
Enabled: false
# ------------------------------------------------------------------------------
# rubocop-minitest plugin cops permanently disabled.
#
# These live here (not in `.rubocop_todo.yml`) because
# `rubocop --auto-gen-config` regenerates `.rubocop_todo.yml` from
# scratch based on the offenses RuboCop currently reports — and a
# cop set to `Enabled: false` reports zero offenses, so the
# regenerator emits nothing for it and silently drops the
# `Enabled: false` line plus its rationale comment. Permanent
# disables must live in `.rubocop.yml`, which is not regenerated.
Minitest/AssertIncludes:
# 152 offenses on disable. `assert(arr.include?(x))` is more
# readable than `assert_includes(arr, x)`. Also catches and
# rewrites `assert(obj.member?(other))` where `obj` is a custom
# `member?`-predicate object (e.g. `Project#member?` checks user
# membership, not collection inclusion) — those break.
Enabled: false
Minitest/AssertOperator:
# 188 offenses on disable. `assert(x > y)` is more readable than
# `assert_operator(x, :>, y)`. Also confuses assignment-expression
# inside `assert(…)` with comparison (e.g.
# `assert(qb[i] = qa[i].subquery_of(model))` got rewritten as
# `assert_operator(qb, :[]=, i)`).
Enabled: false
Minitest/AssertPredicate:
# 399 offenses on disable. `assert(x.present?)` is more readable
# than `assert_predicate(x, :present?)`.
Enabled: false
Minitest/AssertTruthy:
# 75 offenses on disable. The cop rewrites `assert_equal(true, x)`
# to `assert(x)`, which relaxes a literal-`true` assertion to a
# truthy check. Test code that says `assert_equal(true, foo?)`
# documents the author's expectation that the method returns the
# boolean `true` itself, not any truthy value; the autocorrect
# erases that intent.
Enabled: false
Minitest/EmptyLineBeforeAssertionMethods:
# 5902 offenses on disable — pure cosmetic churn at that volume.
# The autocorrect inserts a blank line before every assertion that
# follows non-whitespace; no readability win for MO's style at the
# cost of touching almost every test file.
Enabled: false
Minitest/MultipleAssertions:
# 1564 offenses on disable. The cop counts assertions per test
# method; MO's test suite has many long property/integration-style
# tests (highest single test: 94 assertions) where consolidating
# assertions per render is actively encouraged by the project's
# component-test conventions (see `.claude/rules/testing.md`).
# Threshold-policing the assertion count doesn't fit how MO writes
# tests.
Enabled: false
Minitest/RefuteFalse:
# 59 offenses on disable. Same reasoning as `Minitest/AssertTruthy`
# above. The cop's autocorrect rewrites `assert_equal(false, x)`
# to (via the `Rails/RefuteMethods` chain) `assert_not(x)`, which
# accepts `nil` in addition to literal `false`. `assert_equal(false,
# x)` documents that the method returns the boolean `false`
# itself, not any falsy value; the relaxation would silently hide
# a regression that started returning `nil`.
Enabled: false
Capybara/SpecificActions:
Enabled: true
Rails/TimeZone:
# standalone_image_dhash.rb runs on the images server with plain Ruby
# (no ActiveSupport) -- Time.zone does not exist there, so the cop's
# autocorrect would break it.
Exclude:
- script/standalone_image_dhash.rb