Skip to content

Commit

Permalink
Add :restore_registry context and stub_cop_class helper class
Browse files Browse the repository at this point in the history
  • Loading branch information
marcandre committed Aug 24, 2020
1 parent 112ae91 commit 20db6e1
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 48 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -13,6 +13,7 @@
* [#8472](https://github.com/rubocop-hq/rubocop/issues/8472): Add new `Lint/UselessMethodDefinition` cop. ([@fatkodima][])
* [#8531](https://github.com/rubocop-hq/rubocop/issues/8531): Add new `Lint/EmptyFile` cop. ([@fatkodima][])
* Add new `Lint/TrailingCommaInAttributeDeclaration` cop. ([@drenmi][])
* [#8578](https://github.com/rubocop-hq/rubocop/pull/8578): Add `:restore_registry` context and `stub_cop_class` helper class. ([@marcandre][])

### Bug fixes

Expand Down
12 changes: 12 additions & 0 deletions lib/rubocop/rspec/shared_contexts.rb
Expand Up @@ -40,6 +40,18 @@
end
end

RSpec.shared_context 'maintain registry', :restore_registry do
around(:each) do |example|
RuboCop::Cop::Registry.with_temporary_global { example.run }
end

def stub_cop_class(name, inherit: RuboCop::Cop::Base, &block)
klass = Class.new(inherit, &block)
stub_const(name, klass)
klass
end
end

# This context assumes nothing and defines `cop`, among others.
RSpec.shared_context 'config', :config do # rubocop:disable Metrics/BlockLength
### Meant to be overridden at will
Expand Down
6 changes: 1 addition & 5 deletions spec/rubocop/config_loader_spec.rb
Expand Up @@ -621,11 +621,7 @@ def enabled?(cop)
include_examples 'resolves enabled/disabled for all cops', true, false
end

context 'when a third party require defines a new gem' do
around do |example|
RuboCop::Cop::Registry.with_temporary_global { example.run }
end

context 'when a third party require defines a new gem', :restore_registry do
context 'when the gem is not loaded' do
before do
create_file('.rubocop.yml', <<~YAML)
Expand Down
10 changes: 2 additions & 8 deletions spec/rubocop/config_spec.rb
Expand Up @@ -845,22 +845,16 @@ def cop_enabled(cop_class)
end
end

describe '#for_department' do
describe '#for_department', :restore_registry do
let(:hash) do
{
'Foo' => { 'Bar' => 42, 'Baz' => true },
'Foo/Foo' => { 'Bar' => 42, 'Qux' => true }
}
end

around do |test|
RuboCop::Cop::Registry.with_temporary_global do
test.run
end
end

before do
stub_const('RuboCop::Foo::Foo', Class.new(RuboCop::Cop::Base))
stub_cop_class('RuboCop::Foo::Foo')
end

it "always returns the department's config" do
Expand Down
5 changes: 2 additions & 3 deletions spec/rubocop/cop/cop_spec.rb
Expand Up @@ -166,12 +166,11 @@
end
end

context 'when cop supports autocorrection' do
context 'when cop supports autocorrection', :restore_registry do
let(:cop_class) do
stub_cop = Class.new(RuboCop::Cop::Cop) do
stub_cop_class('RuboCop::Cop::Test::StubCop', inherit: described_class) do
def autocorrect(node); end
end
stub_const('RuboCop::Cop::Test::StubCop', stub_cop)
end

context 'when offense was corrected' do
Expand Down
14 changes: 2 additions & 12 deletions spec/rubocop/cop/mixin/enforce_superclass_spec.rb
@@ -1,15 +1,14 @@
# frozen_string_literal: true

# rubocop:disable RSpec/FilePath
RSpec.describe RuboCop::Cop::EnforceSuperclass do
RSpec.describe RuboCop::Cop::EnforceSuperclass, :restore_registry do
subject(:cop) { cop_class.new }

let(:cop_class) { RuboCop::Cop::RSpec::ApplicationRecord }
let(:msg) { 'Models should subclass `ApplicationRecord`' }

before do
stub_const('RuboCop::Cop::RSpec::ApplicationRecord',
Class.new(RuboCop::Cop::Cop))
stub_cop_class('RuboCop::Cop::RSpec::ApplicationRecord')
stub_const("#{cop_class}::MSG",
'Models should subclass `ApplicationRecord`')
stub_const("#{cop_class}::SUPERCLASS", 'ApplicationRecord')
Expand All @@ -18,15 +17,6 @@
RuboCop::Cop::RSpec::ApplicationRecord.include(described_class)
end

# `RuboCop::Cop::Cop` mutates its `registry` when inherited from.
# This can introduce nondeterministic failures in other parts of the
# specs if this mutation occurs before code that depends on this global cop
# store. The workaround is to replace the global cop store with a temporary
# store during these tests
around do |test|
RuboCop::Cop::Registry.with_temporary_global { test.run }
end

shared_examples 'no offense' do |code|
it "registers no offenses for `#{code}`" do
expect_no_offenses(code)
Expand Down
25 changes: 12 additions & 13 deletions spec/rubocop/cop/team_spec.rb
Expand Up @@ -211,13 +211,13 @@ def a
end
end

context 'when done twice' do
context 'when done twice', :restore_registry do
let(:persisting_cop_class) do
klass = Class.new(RuboCop::Cop::Base)
klass.exclude_from_registry
klass.define_singleton_method(:support_multiple_source?) { true }
stub_const('Test::Persisting', klass)
klass
stub_cop_class('Test::Persisting') do
def self.support_multiple_source?
true
end
end
end
let(:cop_classes) { [persisting_cop_class, RuboCop::Cop::Base] }

Expand Down Expand Up @@ -358,14 +358,13 @@ def a
end
end

context 'when cop with different checksum joins' do
context 'when cop with different checksum joins', :restore_registry do
before do
stub_const('Test::CopWithExternalDeps',
Class.new(::RuboCop::Cop::Cop) do
def external_dependency_checksum
'something other than nil'
end
end)
stub_cop_class('Test::CopWithExternalDeps') do
def external_dependency_checksum
'something other than nil'
end
end
end

let(:new_cop_classes) do
Expand Down
11 changes: 4 additions & 7 deletions spec/rubocop/formatter/disabled_config_formatter_spec.rb
Expand Up @@ -249,14 +249,11 @@ def io.path
end
end

context 'with auto-correct supported cop' do
context 'with auto-correct supported cop', :restore_registry do
before do
stub_const('Test::Cop3',
Class.new(::RuboCop::Cop::Cop) do
def autocorrect
# Dummy method to respond to #support_autocorrect?
end
end)
stub_cop_class('Test::Cop3') do
extend RuboCop::Cop::AutoCorrector
end

formatter.started(['test_auto_correct.rb'])
formatter.file_started('test_auto_correct.rb', {})
Expand Down

0 comments on commit 20db6e1

Please sign in to comment.