class RuboCop::Cop::RSpec::FactoryBot::AttributeDefinedStatically

Always declare attribute values as blocks.

@example

# bad
kind [:active, :rejected].sample

# good
kind { [:active, :rejected].sample }

# bad
closed_at 1.day.from_now

# good
closed_at { 1.day.from_now }

# bad
count 1

# good
count { 1 }

Constants

MSG

Public Instance Methods

autocorrect(node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 47
def autocorrect(node)
  if node.parenthesized?
    autocorrect_replacing_parens(node)
  else
    autocorrect_without_parens(node)
  end
end
on_block(node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 38
def on_block(node)
  factory_attributes(node).to_a.flatten.each do |attribute|
    next unless offensive_receiver?(attribute.receiver, node)
    next if proc?(attribute) || association?(attribute)

    add_offense(attribute, location: :expression)
  end
end

Private Instance Methods

association?(attribute) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 75
def association?(attribute)
  argument = attribute.first_argument
  argument.hash_type? && factory_key?(argument)
end
attribute_defining_method?(method_name) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 120
def attribute_defining_method?(method_name)
  RuboCop::RSpec::FactoryBot.attribute_defining_methods
    .include?(method_name)
end
autocorrect_replacing_parens(node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 84
def autocorrect_replacing_parens(node)
  left_braces, right_braces = braces(node)

  lambda do |corrector|
    corrector.replace(node.location.begin, ' ' + left_braces)
    corrector.replace(node.location.end, right_braces)
  end
end
autocorrect_without_parens(node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 93
def autocorrect_without_parens(node)
  left_braces, right_braces = braces(node)

  lambda do |corrector|
    argument = node.first_argument
    expression = argument.location.expression
    corrector.insert_before(expression, left_braces)
    corrector.insert_after(expression, right_braces)
  end
end
braces(node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 104
def braces(node)
  if value_hash_without_braces?(node.first_argument)
    ['{ { ', ' } }']
  else
    ['{ ', ' }']
  end
end
factory_key?(hash_node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 80
def factory_key?(hash_node)
  hash_node.keys.any? { |key| key.sym_type? && key.value == :factory }
end
offensive_receiver?(receiver, node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 57
def offensive_receiver?(receiver, node)
  receiver.nil? ||
    receiver.self_type? ||
    receiver_matches_first_block_argument?(receiver, node)
end
proc?(attribute) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 71
def proc?(attribute)
  value_matcher(attribute).to_a.all?(&:block_pass_type?)
end
receiver_matches_first_block_argument?(receiver, node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 63
def receiver_matches_first_block_argument?(receiver, node)
  first_block_argument = node.arguments.first

  !first_block_argument.nil? &&
    receiver.lvar_type? &&
    receiver.node_parts == first_block_argument.node_parts
end
reserved_method?(method_name) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 116
def reserved_method?(method_name)
  RuboCop::RSpec::FactoryBot.reserved_methods.include?(method_name)
end
value_hash_without_braces?(node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 112
def value_hash_without_braces?(node)
  node.hash_type? && !node.braces?
end