Class: RuboCop::Cop::FactoryBotGuide::DynamicAttributeEvaluation
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::FactoryBotGuide::DynamicAttributeEvaluation
- Extended by:
- AutoCorrector
- Defined in:
- lib/rubocop/cop/factory_bot_guide/dynamic_attribute_evaluation.rb
Overview
Checks that method calls in FactoryBot attribute definitions are wrapped in blocks for dynamic evaluation.
Without blocks, method calls are evaluated once at factory definition time, not at factory instantiation time. This causes all factory instances to share the same value, leading to subtle bugs and test pollution.
This is particularly problematic for:
- Time-related methods (Time.now, Date.today, 1.day.from_now, etc.)
- Random values (SecureRandom.hex, SecureRandom.uuid, etc.)
- Object constructors (Array.new, Hash.new, etc.)
- Any method calls that should return different values per instance
Direct Known Subclasses
Constant Summary collapse
- MSG =
"Use block syntax for attribute `%<attribute>s` because `%<method>s` " \ "is evaluated once at factory definition time. " \ "Wrap in block: `%<attribute>s { %<value>s }`"
- TIME_CLASSES =
%w[Time Date DateTime].freeze
- RANDOM_CLASSES =
%w[SecureRandom].freeze
Instance Method Summary collapse
Instance Method Details
#attribute_assignment?(node) ⇒ Object
109 110 111 |
# File 'lib/rubocop/cop/factory_bot_guide/dynamic_attribute_evaluation.rb', line 109 def_node_matcher :attribute_assignment?, "(send nil? $_ $_value)\n" |
#factory_block?(node) ⇒ Object
102 103 104 105 106 |
# File 'lib/rubocop/cop/factory_bot_guide/dynamic_attribute_evaluation.rb', line 102 def_node_matcher :factory_block?, "(block\n (send {nil? (const {nil? cbase} :FactoryBot)} :factory ...)\n ...)\n" |
#on_block(node) ⇒ Object
113 114 115 116 117 118 119 120 |
# File 'lib/rubocop/cop/factory_bot_guide/dynamic_attribute_evaluation.rb', line 113 def on_block(node) return unless factory_block?(node) # Check all attribute assignments within the factory node.each_descendant(:send) do |send_node| check_attribute(send_node) end end |