diff options
Diffstat (limited to 'rubocop/cop/rspec/factory_bot/local_static_assignment.rb')
-rw-r--r-- | rubocop/cop/rspec/factory_bot/local_static_assignment.rb | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/rubocop/cop/rspec/factory_bot/local_static_assignment.rb b/rubocop/cop/rspec/factory_bot/local_static_assignment.rb new file mode 100644 index 00000000000..1a26bc31c78 --- /dev/null +++ b/rubocop/cop/rspec/factory_bot/local_static_assignment.rb @@ -0,0 +1,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 |