debian-mirror-gitlab/spec/rubocop/cop/rspec/factory_bot/inline_association_spec.rb
2021-04-17 20:07:23 +05:30

133 lines
3.6 KiB
Ruby

# frozen_string_literal: true
require 'fast_spec_helper'
require 'rspec-parameterized'
require_relative '../../../../../rubocop/cop/rspec/factory_bot/inline_association'
RSpec.describe RuboCop::Cop::RSpec::FactoryBot::InlineAssociation do
subject(:cop) { described_class.new }
shared_examples 'offense' do |code_snippet, autocorrected|
# We allow `create` or `FactoryBot.create` or `::FactoryBot.create`
let(:type) { code_snippet[/^(?:::)?(?:FactoryBot\.)?(\w+)/, 1] }
let(:offense_marker) { '^' * code_snippet.size }
let(:offense_msg) { msg(type) }
let(:offense) { "#{offense_marker} #{offense_msg}" }
let(:source) do
<<~RUBY
FactoryBot.define do
factory :project do
attribute { #{code_snippet} }
#{offense}
end
end
RUBY
end
let(:corrected_source) do
<<~RUBY
FactoryBot.define do
factory :project do
attribute { #{autocorrected} }
end
end
RUBY
end
it 'registers an offense and corrects', :aggregate_failures do
expect_offense(source)
expect_correction(corrected_source)
end
end
shared_examples 'no offense' do |code_snippet|
first_line = code_snippet.lines.first.chomp
context "for `#{first_line}`" do
it 'does not register any offenses' do
expect_no_offenses <<~RUBY
FactoryBot.define do
factory :project do
#{code_snippet}
end
end
RUBY
end
end
end
context 'offenses' do
using RSpec::Parameterized::TableSyntax
where(:code_snippet, :autocorrected) do
# create
'create(:user)' | 'association(:user)'
'FactoryBot.create(:user)' | 'association(:user)'
'::FactoryBot.create(:user)' | 'association(:user)'
'create(:user, :admin)' | 'association(:user, :admin)'
'create(:user, name: "any")' | 'association(:user, name: "any")'
# build
'build(:user)' | 'association(:user)'
'FactoryBot.build(:user)' | 'association(:user)'
'::FactoryBot.build(:user)' | 'association(:user)'
'build(:user, :admin)' | 'association(:user, :admin)'
'build(:user, name: "any")' | 'association(:user, name: "any")'
end
with_them do
include_examples 'offense', params[:code_snippet], params[:autocorrected]
end
it 'recognizes `add_attribute`' do
expect_offense <<~RUBY
FactoryBot.define do
factory :project, class: 'Project' do
add_attribute(:method) { create(:user) }
^^^^^^^^^^^^^ #{msg(:create)}
end
end
RUBY
end
it 'recognizes `transient` attributes' do
expect_offense <<~RUBY
FactoryBot.define do
factory :project, class: 'Project' do
transient do
creator { create(:user) }
^^^^^^^^^^^^^ #{msg(:create)}
end
end
end
RUBY
end
end
context 'no offenses' do
include_examples 'no offense', 'association(:user)'
include_examples 'no offense', 'association(:user, :admin)'
include_examples 'no offense', 'association(:user, name: "any")'
include_examples 'no offense', <<~RUBY
after(:build) do |object|
object.user = create(:user)
end
RUBY
include_examples 'no offense', <<~RUBY
initialize_with do
create(:user)
end
RUBY
include_examples 'no offense', <<~RUBY
user_id { create(:user).id }
RUBY
end
def msg(type)
format(described_class::MSG, type: type)
end
end