Module: DevDoc::Test::Lints::CopDriftCheck

Defined in:
lib/dev_doc/test/lints/cop_drift_check.rb

Overview

Cop-inventory tripwire: every DevDoc cop the installed gem registers must be MENTIONED BY FULL NAME in the project's .rubocop.yml — enabled, disabled-with-reason, or a commented adoption-TODO all count. A mention proves a reviewed decision; a cop nobody has named is a cop nobody has decided about.

Why offenses alone can't guard this

A new cop WITH offenses announces itself by failing rubocop. Two shapes stay silent forever without this check:

  • Cops shipped Enabled: false (review aids) never produce an offense, so no run ever surfaces them.
  • Zero-offense auto-enables that need PROJECT configuration to bite (AllowedMethods / RolePredicates-style lists) run at weak gem defaults while looking like coverage. Agent memory and human habit don't transfer between machines; a suite-failing check does.

Usage

This file holds only the pure, Rails-free core (so the gem's own spec suite can load it). Projects require the test-class wrapper instead, from the test helper (Rails test env):

require 'dev_doc/test/lints/cop_drift_test'

Constant Summary collapse

COP_NAME =
%r{^(DevDoc/[A-Za-z0-9]+/[A-Za-z0-9]+):}

Class Method Summary collapse

Class Method Details

.unmentioned_cops(show_cops_output, config_text) ⇒ Object

Pure core, spec-covered: which registered cops does the config text never mention? Boundary-aware match — a plain substring check would let a cop whose name PREFIXES another mentioned cop pass for free (RequireGlibTravel riding on RequireGlibTravelBlock).



36
37
38
39
# File 'lib/dev_doc/test/lints/cop_drift_check.rb', line 36

def unmentioned_cops(show_cops_output, config_text)
  registered = show_cops_output.scan(COP_NAME).flatten.uniq
  registered.reject { |cop| config_text.match?(/#{Regexp.escape(cop)}(?![A-Za-z0-9])/) }
end