File: local_static_assignment.rb

package info (click to toggle)
gitlab 17.6.5-19
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 629,368 kB
  • sloc: ruby: 1,915,304; javascript: 557,307; sql: 60,639; xml: 6,509; sh: 4,567; makefile: 1,239; python: 406
file content (67 lines) | stat: -rw-r--r-- 1,815 bytes parent folder | download
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