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

on_block(node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 42
def on_block(node)
  attributes = factory_attributes(node) || []
  attributes = [attributes] unless attributes.is_a?(Array) # rubocop:disable Style/ArrayCoercion, Lint/RedundantCopDisableDirective

  attributes.each do |attribute|
    next unless offensive_receiver?(attribute.receiver, node)
    next if proc?(attribute) || association?(attribute.first_argument)

    add_offense(attribute) do |corrector|
      autocorrect(corrector, attribute)
    end
  end
end

Private Instance Methods

attribute_defining_method?(method_name) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 119
def attribute_defining_method?(method_name)
  RuboCop::RSpec::FactoryBot.attribute_defining_methods
    .include?(method_name)
end
autocorrect(corrector, node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 58
def autocorrect(corrector, node)
  if node.parenthesized?
    autocorrect_replacing_parens(corrector, node)
  else
    autocorrect_without_parens(corrector, node)
  end
end
autocorrect_replacing_parens(corrector, node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 87
def autocorrect_replacing_parens(corrector, node)
  left_braces, right_braces = braces(node)

  corrector.replace(node.location.begin, " #{left_braces}")
  corrector.replace(node.location.end, right_braces)
end
autocorrect_without_parens(corrector, node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 94
def autocorrect_without_parens(corrector, node)
  left_braces, right_braces = braces(node)

  argument = node.first_argument
  expression = argument.location.expression
  corrector.insert_before(expression, left_braces)
  corrector.insert_after(expression, right_braces)
end
braces(node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 103
def braces(node)
  if value_hash_without_braces?(node.first_argument)
    ['{ { ', ' } }']
  else
    ['{ ', ' }']
  end
end
offensive_receiver?(receiver, node) click to toggle source
# File lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb, line 66
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 80
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 72
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 115
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 111
def value_hash_without_braces?(node)
  node.hash_type? && !node.braces?
end