Class: RuboCop::Cop::DevDoc::Test::RequireGlibIntegrationBase

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/dev_doc/test/require_glib_integration_base.rb

Overview

In HTTP-driven test directories, integration tests must subclass the project base (RequiredBase, default Glib::IntegrationTest) rather than a raw framework base (LegacyBases, default ActionDispatch::IntegrationTest).

Rationale

The project base is where behavioural enforcement and plumbing are attached: DevDoc::Test::Lints::HttpDrivenControllerTests (which fails any test under test/controllers/ that completes without making an HTTP request), plus the glib helpers (submit_form, glib_travel, parallel coverage). A test that inherits the framework base directly sidesteps all of it — and that is an observed evasion shape: when the runtime lint fails a disguised unit test, switching the superclass to the raw framework base would silence the lint without fixing the test. This cop closes that hop statically, completing the loop with DevDoc/Test/RequireUnitTestJustification (which forbids unit bases in these directories and integration bases in unit directories).

Framework-specific bases for other test types (ActionMailer::TestCase, ActionCable::Connection::TestCase, ...) are not flagged — only the configured legacy integration bases.

Examples:

# bad
class NotesControllerTest < ActionDispatch::IntegrationTest
end

# good
class NotesControllerTest < Glib::IntegrationTest
end

Constant Summary collapse

MSG =
'`%<base>s` is the raw framework base — subclass `%<required>s` instead. The project ' \
'base carries the runtime HTTP-driven enforcement and the glib test plumbing; ' \
'inheriting the framework base directly sidesteps both.'.freeze

Instance Method Summary collapse

Instance Method Details

#on_class(node) ⇒ Object



40
41
42
43
44
45
46
# File 'lib/rubocop/cop/dev_doc/test/require_glib_integration_base.rb', line 40

def on_class(node)
  superclass = node.parent_class
  return unless superclass&.const_type?
  return unless legacy_bases.include?(superclass.const_name)

  add_offense(superclass, message: format(MSG, base: superclass.const_name, required: required_base))
end