Skip to content

Commit

Permalink
Add a cop to check for consistent method usage in feature specs.
Browse files Browse the repository at this point in the history
  • Loading branch information
rspeicher committed Aug 5, 2017
1 parent a237ccf commit a443b44
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Add `RSpec/LetBeforeExamples` cop. ([@Darhazer][])
* Add `RSpec/MultipleSubjects` cop. ([@backus][])
* Add `RSpec/ReturnFromStub` cop. ([@Darhazer][])
* Add `RSpec/FeatureMethods` cop. ([@tsigo][])

## 1.15.1 (2017-04-30)

Expand Down
5 changes: 5 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ RSpec/ExpectOutput:
Enabled: true
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExpectOutput

RSpec/FeatureMethods:
Description: Checks for consistent method usage in feature specs.
Enabled: true
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FeatureMethods

RSpec/FilePath:
Description: Checks that spec file paths are consistent with the test subject.
Enabled: true
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop-rspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
require 'rubocop/cop/rspec/expect_actual'
require 'rubocop/cop/rspec/expect_output'
require 'rubocop/cop/rspec/factory_girl/dynamic_attribute_defined_statically'
require 'rubocop/cop/rspec/feature_methods'
require 'rubocop/cop/rspec/file_path'
require 'rubocop/cop/rspec/focus'
require 'rubocop/cop/rspec/hook_argument'
Expand Down
65 changes: 65 additions & 0 deletions lib/rubocop/cop/rspec/feature_methods.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# frozen_string_literal: true

module RuboCop
module Cop
module RSpec
# Checks for consistent method usage in feature specs.
#
# @example
# # bad
# feature 'User logs in' do
# given(:user) { User.new }
#
# background do
# visit new_session_path
# end
#
# scenario 'with OAuth' do
# # ...
# end
# end
#
# # good
# describe 'User logs in' do
# let(:user) { User.new }
#
# before do
# visit new_session_path
# end
#
# it 'with OAuth' do
# # ...
# end
# end
class FeatureMethods < Cop
MSG = 'Use `%s` instead of `%s`.'.freeze

# https://git.io/v7rLu
MAP = {
background: :before,
scenario: :it,
xscenario: :xit,
given: :let,
given!: :let!,
feature: :describe
}.freeze

def_node_matcher :feature_method?, <<-PATTERN
(send {(const nil :RSpec) nil} ${:#{MAP.keys.join(' :')}} ...)
PATTERN

def on_send(node)
feature_method?(node) do |match|
add_offense(node, :selector, format(MSG, MAP[match], match))
end
end

def autocorrect(node)
lambda do |corrector|
corrector.replace(node.loc.selector, MAP[node.method_name].to_s)
end
end
end
end
end
end
52 changes: 52 additions & 0 deletions spec/rubocop/cop/rspec/feature_methods_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
RSpec.describe RuboCop::Cop::RSpec::FeatureMethods do
subject(:cop) { described_class.new }

it 'flags violations for `background`' do
expect_offense(<<-RUBY)
background do; end
^^^^^^^^^^ Use `before` instead of `background`.
RUBY
end

it 'flags violations for `scenario`' do
expect_offense(<<-RUBY)
scenario 'Foo' do; end
^^^^^^^^ Use `it` instead of `scenario`.
RUBY
end

it 'flags violations for `xscenario`' do
expect_offense(<<-RUBY)
RSpec.xscenario 'Foo' do; end
^^^^^^^^^ Use `xit` instead of `xscenario`.
RUBY
end

it 'flags violations for `given`' do
expect_offense(<<-RUBY)
given(:foo) { :foo }
^^^^^ Use `let` instead of `given`.
RUBY
end

it 'flags violations for `given!`' do
expect_offense(<<-RUBY)
given!(:foo) { :foo }
^^^^^^ Use `let!` instead of `given!`.
RUBY
end

it 'flags violations for `feature`' do
expect_offense(<<-RUBY)
RSpec.feature 'Foo' do; end
^^^^^^^ Use `describe` instead of `feature`.
RUBY
end

include_examples 'autocorrect', 'background { }', 'before { }'
include_examples 'autocorrect', 'scenario { }', 'it { }'
include_examples 'autocorrect', 'xscenario { }', 'xit { }'
include_examples 'autocorrect', 'given(:foo) { }', 'let(:foo) { }'
include_examples 'autocorrect', 'given!(:foo) { }', 'let!(:foo) { }'
include_examples 'autocorrect', 'RSpec.feature { }', 'RSpec.describe { }'
end

0 comments on commit a443b44

Please sign in to comment.