Add a new QA::ElementWithPattern cop

This cop forbids the use of `element :foo, 'pattern'` and
`element :bar, /pattern/` in QA files.
Signed-off-by: 's avatarRémy Coutable <remy@rymai.me>
parent 63cd88c6
require_relative '../../qa_helpers'
module RuboCop
module Cop
module QA
# This cop checks for the usage of factories in migration specs
#
# @example
#
# # bad
# let(:user) { create(:user) }
#
# # good
# let(:users) { table(:users) }
# let(:user) { users.create!(name: 'User 1', username: 'user1') }
class ElementWithPattern < RuboCop::Cop::Cop
include QAHelpers
MESSAGE = "Don't use a pattern for element, create a corresponding `%s` instead.".freeze
def on_send(node)
return unless in_qa_file?(node)
return unless method_name(node).to_s == 'element'
element_name, pattern = node.arguments
return unless pattern
add_offense(node, location: pattern.source_range, message: MESSAGE % "qa-#{element_name.value.to_s.tr('_', '-')}")
end
private
def method_name(node)
node.children[1]
end
end
end
end
end
module RuboCop
# Module containing helper methods for writing QA cops.
module QAHelpers
# Returns true if the given node originated from the qa/ directory.
def in_qa_file?(node)
path = node.location.expression.source_buffer.name
path.start_with?(File.join(Dir.pwd, 'qa'))
end
end
end
......@@ -29,6 +29,7 @@ require_relative 'cop/migration/update_large_table'
require_relative 'cop/project_path_helper'
require_relative 'cop/rspec/env_assignment'
require_relative 'cop/rspec/factories_in_migration_specs'
require_relative 'cop/qa/element_with_pattern'
require_relative 'cop/sidekiq_options_queue'
require_relative 'cop/destroy_all'
require_relative 'cop/ruby_interpolation_in_translation'
......
require 'spec_helper'
require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../../../../rubocop/cop/qa/element_with_pattern'
describe RuboCop::Cop::QA::ElementWithPattern do
include CopHelper
let(:source_file) { 'qa/page.rb' }
subject(:cop) { described_class.new }
context 'in a QA file' do
before do
allow(cop).to receive(:in_qa_file?).and_return(true)
end
it "registers an offense for elements with a pattern" do
expect_offense(<<-RUBY)
view 'app/views/shared/groups/_search_form.html.haml' do
element :groups_filter, 'search_field_tag :filter'
^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't use a pattern for element, create a corresponding `qa-groups-filter` instead.
element :groups_filter_placeholder, /Search by name/
^^^^^^^^^^^^^^^^ Don't use a pattern for element, create a corresponding `qa-groups-filter-placeholder` instead.
end
RUBY
end
it "does not register an offense for element without a pattern" do
expect_no_offenses(<<-RUBY)
view 'app/views/shared/groups/_search_form.html.haml' do
element :groups_filter
element :groups_filter_placeholder
end
RUBY
end
end
context 'outside of a migration spec file' do
it "does not register an offense" do
expect_no_offenses(<<-RUBY)
describe 'foo' do
let(:user) { create(:user) }
end
RUBY
end
end
end
# frozen_string_literal: true
require 'spec_helper'
require 'rubocop'
require_relative '../../rubocop/qa_helpers'
describe RuboCop::QAHelpers do
def parse_source(source, path = 'foo.rb')
buffer = Parser::Source::Buffer.new(path)
buffer.source = source
builder = RuboCop::AST::Builder.new
parser = Parser::CurrentRuby.new(builder)
parser.parse(buffer)
end
let(:cop) do
Class.new do
include RuboCop::QAHelpers
end.new
end
describe '#in_qa_file?' do
it 'returns true for a node in the qa/ directory' do
node = parse_source('10', Rails.root.join('qa', 'qa', 'page', 'dashboard', 'groups.rb'))
expect(cop.in_qa_file?(node)).to eq(true)
end
it 'returns false for a node outside the qa/ directory' do
node = parse_source('10', Rails.root.join('app', 'foo', 'foo.rb'))
expect(cop.in_qa_file?(node)).to eq(false)
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment