Class: Glib::Test::FullSuiteRubocop

Inherits:
ActiveSupport::TestCase
  • Object
show all
Defined in:
lib/glib/test/full_suite_rubocop.rb

Overview

Suite-wide RuboCop auto-remediation, lifted from the per-project test/linters/rubocop_test.rb convention (originated in neowork-str) so projects get it from the gem via a CONSCIOUS opt-in: include Glib::Test::RubocopGuards once in the test setup. Never auto-require this from Glib::TestHelpers — that would enable a file-rewriting test in every project without a decision. It lints the WHOLE repo, so files nobody touches cannot silently accumulate offenses.

Runs rubocop -a (safe autocorrect), which REWRITES files on disk to fix offenses, then asserts nothing remains AND nothing was rewritten. The mutation is deliberate (the repo's auto-remediation convention — i18n-tasks normalize runs the same way): a run that dirties a file is reported as a FAILURE so the rewrite cannot go unnoticed — that is the drift signal. Do NOT strip the -a; review the diff, keep the corrected output, and re-run. If a long-passing test suddenly breaks, investigate WHY first: usually a non-canonical file was committed, or a rubocop version bump changed a cop's rules.

It self-registers with Minitest, so it runs on EVERY rails test invocation, single-file runs included. That is cheap on purpose: RuboCop caches per-file results, so a full-repo run on an unchanged tree costs about a second on a mid-size app.

Deliberately does NOT skip under ENV: the local rails-test wrapper sets CI=true, and skipping here would silence this layer exactly where it runs. Opt out per-run with SKIP_FULL_SUITE_RUBOCOP=1.

Constant Summary collapse

OFFENSE_LINE =

--format simple offense lines: "C: 12: 3: [Correctable] Cop/Name: message" (line/column right-aligned to width 3, so the padding is 0-2 spaces).

/^[A-Z]: *\d+: *\d+: /

Instance Method Summary collapse

Instance Method Details

#test_rubocop_autocorrect_then_cleanObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/glib/test/full_suite_rubocop.rb', line 38

def test_rubocop_autocorrect_then_clean
  skip 'opted out via SKIP_FULL_SUITE_RUBOCOP' if ENV['SKIP_FULL_SUITE_RUBOCOP'] == '1'

  # `scrub`: stderr is merged in, and one invalid byte would turn the
  # scans below into an ArgumentError instead of a lint failure.
  output = `bundle exec rubocop -a --format simple 2>&1`.scrub
  clean = $CHILD_STATUS.success?

  # Three distinct outcomes hide in one output, and each needs a
  # different action — the message must say which, or an agent told
  # only "offenses detected" reaches for a `rubocop:disable`:
  #   [Corrected]   -a already rewrote it on disk (exit 0 if that's all)
  #   [Correctable] survived -a because only the UNSAFE -A can fix it
  #   neither       no autocorrect exists — semantic, read the cop
  # Counted on the offense LINES only, so a cop message that happens to
  # contain a marker cannot shift a bucket.
  offenses = output.lines.grep(OFFENSE_LINE)
  corrected = offenses.count { |line| line.include?('[Corrected]') }
  unsafe = offenses.count { |line| line.include?('[Correctable]') }
  semantic = offenses.size - corrected - unsafe

  # A Proc message is built only on failure (Minitest calls it lazily).
  assert(clean && corrected.zero?, -> { failure_message(output, corrected: corrected, unsafe: unsafe, semantic: semantic) })
end