class FactoryBot::Definition

@api private

def add_callback(callback)

def add_callback(callback)
  @callbacks << callback
end

def additional_traits

def additional_traits
  @additional_traits.map { |name| trait_by_name(name) }
end

def after(*names, &block)

def after(*names, &block)
  callback(*names.map { |name| "after_#{name}" }, &block)
end

def aggregate_from_traits_and_self(method_name, &block)

def aggregate_from_traits_and_self(method_name, &block)
  compile
  [
    base_traits.map(&method_name),
    instance_exec(&block),
    additional_traits.map(&method_name)
  ].flatten.compact
end

def append_traits(new_traits)

def append_traits(new_traits)
  @additional_traits += new_traits
end

def attributes

def attributes
  @attributes ||= AttributeList.new.tap do |attribute_list|
    attribute_lists = aggregate_from_traits_and_self(:attributes) { declarations.attributes }
    attribute_lists.each do |attributes|
      attribute_list.apply_attributes attributes
    end
  end
end

def automatically_register_defined_enums(klass)

def automatically_register_defined_enums(klass)
  klass.defined_enums.each_key { |name| register_enum(Enum.new(name)) }
end

def automatically_register_defined_enums?(klass)

def automatically_register_defined_enums?(klass)
  FactoryBot.automatically_define_enum_traits &&
    klass.respond_to?(:defined_enums)
end

def base_traits

def base_traits
  @base_traits.map { |name| trait_by_name(name) }
rescue KeyError => error
  raise error_with_definition_name(error)
end

def before(*names, &block)

def before(*names, &block)
  callback(*names.map { |name| "before_#{name}" }, &block)
end

def callback(*names, &block)

def callback(*names, &block)
  names.each do |name|
    add_callback(Callback.new(name, block))
  end
end

def callbacks

def callbacks
  aggregate_from_traits_and_self(:callbacks) { @callbacks }
end

def compile(klass = nil)

def compile(klass = nil)
  unless @compiled
    expand_enum_traits(klass) unless klass.nil?
    declarations.attributes
    self.klass ||= klass
    defined_traits.each do |defined_trait|
      defined_trait.klass ||= klass
      base_traits.each { |bt| bt.define_trait defined_trait }
      additional_traits.each { |at| at.define_trait defined_trait }
    end
    @compiled = true
    ActiveSupport::Notifications.instrument "factory_bot.compile_factory", {
      name: name,
      attributes: declarations.attributes,
      traits: defined_traits,
      class: klass || self.klass
    }
  end
end

def constructor

def constructor
  aggregate_from_traits_and_self(:constructor) { @constructor }.last
end

def define_constructor(&block)

def define_constructor(&block)
  @constructor = block
end

def define_trait(trait)

def define_trait(trait)
  @defined_traits.add(trait)
end

def error_with_definition_name(error)

def error_with_definition_name(error)
  message = error.message + " referenced within \"#{name}\" definition"
  error.class.new(message, key: error.key, receiver: error.receiver)
    .tap { |new_error| new_error.set_backtrace(error.backtrace) }
end

def error_with_definition_name(error)

def error_with_definition_name(error)
  message = error.message
  message.insert(
    message.index("\nDid you mean?") || message.length,
    " referenced within \"#{name}\" definition"
  )
  error.class.new(message).tap do |new_error|
    new_error.set_backtrace(error.backtrace)
  end
end

def expand_enum_traits(klass)

def expand_enum_traits(klass)
  return if @expanded_enum_traits
  if automatically_register_defined_enums?(klass)
    automatically_register_defined_enums(klass)
  end
  registered_enums.each do |enum|
    traits = enum.build_traits(klass)
    traits.each { |trait| define_trait(trait) }
  end
  @expanded_enum_traits = true
end

def inherit_traits(new_traits)

def inherit_traits(new_traits)
  @base_traits += new_traits
end

def initialize(name, base_traits = [])

def initialize(name, base_traits = [])
  @name = name
  @declarations = DeclarationList.new(name)
  @callbacks = []
  @defined_traits = Set.new
  @registered_enums = []
  @to_create = nil
  @base_traits = base_traits
  @additional_traits = []
  @constructor = nil
  @attributes = nil
  @compiled = false
  @expanded_enum_traits = false
end

def initialize_copy(source)

def initialize_copy(source)
  super
  @attributes = nil
  @compiled = false
  @defined_traits_by_name = nil
end

def overridable

def overridable
  declarations.overridable
  self
end

def register_enum(enum)

def register_enum(enum)
  @registered_enums << enum
end

def skip_create

def skip_create
  @to_create = ->(instance) {}
end

def to_create(&block)

def to_create(&block)
  if block
    @to_create = block
  else
    aggregate_from_traits_and_self(:to_create) { @to_create }.last
  end
end

def trait_by_name(name)

def trait_by_name(name)
  trait_for(name) || Internal.trait_by_name(name, klass)
end

def trait_for(name)

def trait_for(name)
  @defined_traits_by_name ||= defined_traits.each_with_object({}) { |t, memo| memo[t.name] ||= t }
  @defined_traits_by_name[name.to_s]
end