1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
# frozen_string_literal: true
require 'rubocop-rspec'
module RuboCop
module Cop
module RSpec
module FactoryBot
# Flags local assignments during factory "load time". This leads to
# static data definitions.
#
# Move these definitions into attribute block or
# `transient` block to ensure that the data is evaluated during
# "runtime" and remains dynamic.
#
# @example
# # bad
# factory :foo do
# random = rand(23)
# baz { "baz-#{random}" }
#
# trait :a_trait do
# random = rand(23)
# baz { "baz-#{random}" }
# end
#
# transient do
# random = rand(23)
# baz { "baz-#{random}" }
# end
# end
#
# # good
# factory :foo do
# baz { "baz-#{random}" }
#
# trait :a_trait do
# baz { "baz-#{random}" }
# end
#
# transient do
# random { rand(23) }
# end
# end
class LocalStaticAssignment < RuboCop::Cop::Base
MSG = 'Avoid local static assignemnts in factories which lead to static data definitions.'
RESTRICT_ON_SEND = %i[factory transient trait].freeze
def_node_search :local_assignment, <<~PATTERN
(begin $(lvasgn ...))
PATTERN
def on_send(node)
return unless node.parent&.block_type?
node.parent.each_child_node(:begin) do |begin_node|
begin_node.each_child_node(:lvasgn) do |lvasgn_node|
add_offense(lvasgn_node)
end
end
end
end
end
end
end
end
|