133 lines
3.6 KiB
Ruby
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
|