Skip to content

Commit

Permalink
Make RSpec Hooks fully configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
sl4vr committed Aug 6, 2020
1 parent 5e2630d commit 89acc68
Show file tree
Hide file tree
Showing 88 changed files with 74 additions and 174 deletions.
9 changes: 9 additions & 0 deletions config/default.yml
Expand Up @@ -4,6 +4,15 @@ AllCops:
Patterns:
- _spec.rb
- "(?:^|/)spec/"
Language:
Hooks:
- prepend_before
- before
- append_before
- around
- prepend_after
- after
- append_after
RSpec/FactoryBot:
Patterns:
- spec/factories.rb
Expand Down
19 changes: 0 additions & 19 deletions lib/rubocop/rspec/language.rb
Expand Up @@ -67,25 +67,6 @@ def node_pattern
attr_reader :selectors
end

# Built in RSpec selectors
module BuiltIn
LANGUAGE = {
'Hooks' => %i[
prepend_before
before
append_before
around
prepend_after
after
append_after
]
}.freeze

def self.language_elements_for(*keys)
LANGUAGE.dig(*keys) || []
end
end

module ExampleGroups
GROUPS = SelectorSet.new(%i[describe context feature example_group])
SKIPPED = SelectorSet.new(%i[xdescribe xcontext xfeature])
Expand Down
24 changes: 9 additions & 15 deletions lib/rubocop/rspec/language/node_pattern.rb
Expand Up @@ -43,32 +43,26 @@ def rspec_all(keyword)

# TODO: Fully replace selectors with sets
def hooks_set
@hooks_set ||= Set.new(hook_selectors.send(:selectors))
@hooks_set ||= Set.new(rspec_language_config('Hooks'))
end

def all_set
@all_set ||= Set.new(all_selectors.send(:selectors))
end

def hook_selectors
selectors('Hooks')
end

def all_selectors
ExampleGroups::ALL +
SharedGroups::ALL +
Examples::ALL +
hook_selectors +
Helpers::ALL +
Subject::ALL +
Expectations::ALL +
ExampleGroups::ALL +
SharedGroups::ALL +
Examples::ALL +
selectors('Hooks') +
Helpers::ALL +
Subject::ALL +
Expectations::ALL +
Runners::ALL
end

def selectors(*keys)
SelectorSet.new(
BuiltIn.language_elements_for(*keys) + rspec_language_config(*keys)
)
SelectorSet.new(rspec_language_config(*keys))
end
end
end
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/align_left_let_brace_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::AlignLeftLetBrace do
subject(:cop) { described_class.new }

# rubocop:disable RSpec/ExampleLength
it 'registers offense for unaligned braces' do
expect_offense(<<-RUBY)
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/align_right_let_brace_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::AlignRightLetBrace do
subject(:cop) { described_class.new }

# rubocop:disable RSpec/ExampleLength
it 'registers offense for unaligned braces' do
expect_offense(<<-RUBY)
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/any_instance_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::AnyInstance do
subject(:cop) { described_class.new }

it 'finds `allow_any_instance_of` instead of an instance double' do
expect_offense(<<-RUBY)
before do
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/around_block_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::AroundBlock do
subject(:cop) { described_class.new }

context 'when no value is yielded' do
it 'registers an offense' do
expect_offense(<<-RUBY)
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/be_eql_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::BeEql do
subject(:cop) { described_class.new }

it 'registers an offense for `eql` when argument is a boolean' do
expect_offense(<<-RUBY)
it { expect(foo).to eql(true) }
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/be_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::Be do
subject(:cop) { described_class.new }

it 'registers an offense for `be` without an argument' do
expect_offense(<<-RUBY)
it { expect(foo).to be }
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/before_after_all_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::BeforeAfterAll do
subject(:cop) { described_class.new }

def message(hook)
"Beware of using `#{hook}` as it may cause state to leak between tests. "\
'If you are using `rspec-rails`, and `use_transactional_fixtures` is '\
Expand Down
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::Capybara::CurrentPathExpectation do
subject(:cop) { described_class.new }

it 'flags violations for `expect(current_path)`' do
expect_offense(<<-RUBY)
expect(current_path).to eq("/callback")
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cop/rspec/capybara/feature_methods_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::Capybara::FeatureMethods, :config do
RSpec.describe RuboCop::Cop::RSpec::Capybara::FeatureMethods do
it 'flags violations for `background`' do
expect_offense(<<-RUBY)
describe 'some feature' do
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/capybara/visibility_matcher_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::Capybara::VisibilityMatcher do
subject(:cop) { described_class.new }

it 'registers an offense when using `visible: true`' do
expect_offense(<<-RUBY)
expect(page).to have_selector('.my_element', visible: true)
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/context_method_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::ContextMethod do
subject(:cop) { described_class.new }

it 'ignores describe blocks' do
expect_no_offenses(<<-RUBY)
describe '.foo_bar' do
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cop/rspec/context_wording_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::ContextWording, :config do
RSpec.describe RuboCop::Cop::RSpec::ContextWording do
let(:cop_config) { { 'Prefixes' => %w[when with] } }

it 'skips describe blocks' do
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/describe_class_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::DescribeClass do
subject(:cop) { described_class.new }

it 'checks first-line describe statements' do
expect_offense(<<-RUBY)
describe "bad describe" do
Expand Down
4 changes: 1 addition & 3 deletions spec/rubocop/cop/rspec/describe_method_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::DescribeMethod do
subject(:cop) { described_class.new }

it 'ignores describes with only a class' do
expect_no_offenses('describe Some::Class do; end')
end
Expand All @@ -27,7 +25,7 @@

it 'skips specs not having a string second argument' do
expect_no_offenses(<<-RUBY)
describe Some::Class, :config do
describe Some::Class do
end
RUBY
end
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/describe_symbol_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::DescribeSymbol do
subject(:cop) { described_class.new }

it 'flags violations for `describe :symbol`' do
expect_offense(<<-RUBY)
describe(:some_method) { }
Expand Down
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::DescribedClassModuleWrapping do
subject(:cop) { described_class.new }

it 'allows a describe block in the outermost scope' do
expect_no_offenses(<<-RUBY)
RSpec.describe MyClass do
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cop/rspec/described_class_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::DescribedClass, :config do
RSpec.describe RuboCop::Cop::RSpec::DescribedClass do
let(:cop_config) { {} }

context 'when SkipBlocks is `true`' do
Expand Down
4 changes: 2 additions & 2 deletions spec/rubocop/cop/rspec/dialect_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::Dialect, :config do
RSpec.describe RuboCop::Cop::RSpec::Dialect do
let(:cop_config) do
{
'PreferredMethods' => {
Expand All @@ -9,7 +9,7 @@
}
end

it 'allows describe blocks' do
it 'allows describe blocks', x: true do
expect_no_offenses(<<-RUBY)
describe 'display name presence' do
end
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cop/rspec/empty_example_group_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::EmptyExampleGroup, :config do
RSpec.describe RuboCop::Cop::RSpec::EmptyExampleGroup do
it 'flags an empty example group' do
expect_offense(<<~RUBY)
describe Foo do
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/empty_hook_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::EmptyHook do
subject(:cop) { described_class.new }

context 'with `before` hook' do
it 'detects offense for empty `before`' do
expect_offense(<<~RUBY)
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/empty_line_after_example_group_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::EmptyLineAfterExampleGroup do
subject(:cop) { described_class.new }

it 'checks for empty line after describe' do
expect_offense(<<-RUBY)
RSpec.describe Foo do
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cop/rspec/empty_line_after_example_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::EmptyLineAfterExample, :config do
RSpec.describe RuboCop::Cop::RSpec::EmptyLineAfterExample do
it 'flags a missing empty line after `it`' do
expect_offense(<<-RUBY)
RSpec.describe Foo do
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/empty_line_after_final_let_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::EmptyLineAfterFinalLet do
subject(:cop) { described_class.new }

it 'checks for empty line after last let' do
expect_offense(<<-RUBY)
RSpec.describe User do
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/empty_line_after_hook_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::EmptyLineAfterHook do
subject(:cop) { described_class.new }

it 'checks for empty line after `before` hook' do
expect_offense(<<-RUBY)
RSpec.describe User do
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/empty_line_after_subject_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::EmptyLineAfterSubject do
subject(:cop) { described_class.new }

it 'checks for empty line after subject' do
expect_offense(<<-RUBY)
RSpec.describe User do
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cop/rspec/example_length_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::ExampleLength, :config do
RSpec.describe RuboCop::Cop::RSpec::ExampleLength do
let(:cop_config) { { 'Max' => 3 } }

it 'ignores non-spec blocks' do
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cop/rspec/example_without_description_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::ExampleWithoutDescription, :config do
RSpec.describe RuboCop::Cop::RSpec::ExampleWithoutDescription do
let(:cop_config) do
{ 'EnforcedStyle' => enforced_style }
end
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cop/rspec/example_wording_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::ExampleWording, :config do
RSpec.describe RuboCop::Cop::RSpec::ExampleWording do
it 'ignores non-example blocks' do
expect_no_offenses('foo "should do something" do; end')
end
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cop/rspec/expect_actual_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::ExpectActual, :config do
RSpec.describe RuboCop::Cop::RSpec::ExpectActual do
it 'flags numeric literal values within expect(...)' do
expect_offense(<<-RUBY)
describe Foo do
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cop/rspec/expect_change_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::ExpectChange, :config do
RSpec.describe RuboCop::Cop::RSpec::ExpectChange do
let(:cop_config) do
{ 'EnforcedStyle' => enforced_style }
end
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/expect_in_hook_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::ExpectInHook do
subject(:cop) { described_class.new }

it 'adds an offense for `expect` in `before` hook' do
expect_offense(<<-RUBY)
before do
Expand Down
2 changes: 0 additions & 2 deletions spec/rubocop/cop/rspec/expect_output_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::ExpectOutput do
subject(:cop) { described_class.new }

it 'registers an offense for overwriting $stdout within an example' do
expect_offense(<<-RUBY)
specify do
Expand Down
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::FactoryBot::AttributeDefinedStatically do
subject(:cop) { described_class.new }

it 'registers an offense for offending code' do
expect_offense(<<-RUBY)
FactoryBot.define do
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cop/rspec/factory_bot/create_list_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::FactoryBot::CreateList, :config do
RSpec.describe RuboCop::Cop::RSpec::FactoryBot::CreateList do
let(:cop_config) do
{ 'EnforcedStyle' => enforced_style }
end
Expand Down

0 comments on commit 89acc68

Please sign in to comment.