class FactoryBot::DefinitionProxy

def __declare_attribute__(name, block)

def __declare_attribute__(name, block)
  if block.nil?
    declaration = Declaration::Implicit.new(name, @definition, @ignore)
    @definition.declare_attribute(declaration)
  else
    add_attribute(name, &block)
  end
end

def __valid_association_options?(options)

def __valid_association_options?(options)
  options.respond_to?(:has_key?) && options.has_key?(:factory)
end

def add_attribute(name, &block)

generated instances.
The name of this attribute. This will be assigned using "name=" for
* name: +Symbol+ or +String+
Arguments:

attribute is overridden for a specific instance.
The block will not be called if the
by calling the block whenever an instance is generated.
The attribute value will be generated "lazily"
Adds an attribute to the factory.
def add_attribute(name, &block)
  declaration = Declaration::Dynamic.new(name, @ignore, block)
  @definition.declare_attribute(declaration)
end

def association(name, *options)

default use the "user" factory.
name of the factory. For example, a "user" association will by
If no name is given, the name of the attribute is assumed to be the
The name of the factory to use when building the associated instance.
* factory: +Symbol+ or +String+
Options:

* options: +Hash+
The name of this attribute.
* name: +Symbol+
Arguments:

end
association :author, factory: :user
factory :post do

end
name 'Joey'
factory :user do
Example:

be built using the same build strategy as the parent instance.
Adds an attribute that builds an association. The associated instance will
def association(name, *options)
  if block_given?
    raise AssociationDefinitionError.new(
      "Unexpected block passed to '#{name}' association " \
      "in '#{@definition.name}' factory"
    )
  else
    declaration = Declaration::Association.new(name, *options)
    @definition.declare_attribute(declaration)
  end
end

def factory(name, options = {}, &block)

def factory(name, options = {}, &block)
  @child_factories << [name, options, block]
end

def initialize(definition, ignore = false)

def initialize(definition, ignore = false)
  @definition = definition
  @ignore = ignore
  @child_factories = []
end

def initialize_with(&block)

def initialize_with(&block)
  @definition.define_constructor(&block)
end

def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondToMissing

rubocop:disable Style/MissingRespondToMissing
are equivalent.

end
account
email
admin
factory :user do

and:

end
association :account
email { generate(:email) }
factory :user, traits: [:admin] do

"account" factory:
name. This means that given an "admin" trait, an "email" sequence, and an
association, then for a sequence, and finally for a trait with the same
If no argument or block is given, factory_bot will first look for an

are equivalent.

end
add_attribute(:name) { 'Billy Idol' }
factory :user do

and:

end
name { 'Billy Idol' }
factory :user do

attribute, so that:
Calls add_attribute using the missing method name as the name of the
def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondToMissing
  association_options = args.first
  if association_options.nil?
    __declare_attribute__(name, block)
  elsif __valid_association_options?(association_options)
    association(name, association_options)
  else
    raise NoMethodError.new(<<~MSG)
      undefined method '#{name}' in '#{@definition.name}' factory
      Did you mean? '#{name} { #{association_options.inspect} }'
    MSG
  end
end

def sequence(name, ...)

Except that no globally available sequence will be defined.

end
email { FactoryBot.generate(:email) }
factory :user do

sequence(:email) { |n| "person#{n}@example.com" }
Is equal to:

end
sequence(:email) { |n| "person#{n}@example.com" }
factory :user do
The result of:

a specified format.
Adds an attribute that will have unique values generated by a sequence with
def sequence(name, ...)
  sequence = Sequence.new(name, ...)
  FactoryBot::Internal.register_inline_sequence(sequence)
  add_attribute(name) { increment_sequence(sequence) }
end

def singleton_method_added(name)

def singleton_method_added(name)
  message = "Defining methods in blocks (trait or factory) is not supported (#{name})"
  raise FactoryBot::MethodDefinitionError, message
end

def skip_create

def skip_create
  @definition.skip_create
end

def to_create(&block)

def to_create(&block)
  @definition.to_create(&block)
end

def trait(name, &block)

def trait(name, &block)
  @definition.define_trait(Trait.new(name, &block))
end

def traits_for_enum(attribute_name, values = nil)

class method.
attempt to get the values by calling the pluralized `attribute_name`
those traits. When this argument is not provided, factory_bot will
An array of trait names, or a mapping of trait names to values for
values: +Array+, +Hash+, or other +Enumerable+
the name of the attribute these traits will set the value of
attribute_name: +Symbol+ or +String+
Arguments:


end
end
status { 2 }
trait :finished do

end
status { 1 }
trait :started do
factory :task do
Both equivalent to:

end
traits_for_enum :status
factory :task do

end
end
{started: 1, finished: 2}
def statuses
class Task
Example:

end
traits_for_enum :status, {started: 1, finished: 2}
factory :task do
Example:

end
end
status { :finished }
trait :finished do

end
status { :started }
trait :started do
factory :task do
Equivalent to:

end
traits_for_enum :status, [:started, :finished]
factory :task do
Example:

Creates traits for enumerable values.
def traits_for_enum(attribute_name, values = nil)
  @definition.register_enum(Enum.new(attribute_name, values))
end

def transient(&block)

def transient(&block)
  proxy = DefinitionProxy.new(@definition, true)
  proxy.instance_eval(&block)
end