class FactoryBot::Definition

@api private

Attributes

declarations[R]
defined_traits[R]
name[R]
registered_enums[R]

Public Class Methods

new(name, base_traits = []) click to toggle source
# File lib/factory_bot/definition.rb, line 6
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

Public Instance Methods

add_callback(callback) click to toggle source
# File lib/factory_bot/definition.rb, line 76
def add_callback(callback)
  @callbacks << callback
end
after(*names, &block) click to toggle source
# File lib/factory_bot/definition.rb, line 100
def after(*names, &block)
  callback(*names.map { |name| "after_#{name}" }, &block)
end
append_traits(new_traits) click to toggle source
# File lib/factory_bot/definition.rb, line 72
def append_traits(new_traits)
  @additional_traits += new_traits
end
attributes() click to toggle source
# File lib/factory_bot/definition.rb, line 23
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
before(*names, &block) click to toggle source
# File lib/factory_bot/definition.rb, line 96
def before(*names, &block)
  callback(*names.map { |name| "before_#{name}" }, &block)
end
callback(*names, &block) click to toggle source
# File lib/factory_bot/definition.rb, line 104
def callback(*names, &block)
  names.each do |name|
    add_callback(Callback.new(name, block))
  end
end
callbacks() click to toggle source
# File lib/factory_bot/definition.rb, line 44
def callbacks
  aggregate_from_traits_and_self(:callbacks) { @callbacks }
end
compile(klass = nil) click to toggle source
# File lib/factory_bot/definition.rb, line 48
def compile(klass = nil)
  unless @compiled
    expand_enum_traits(klass) unless klass.nil?

    declarations.attributes

    defined_traits.each do |defined_trait|
      base_traits.each { |bt| bt.define_trait defined_trait }
      additional_traits.each { |at| at.define_trait defined_trait }
    end

    @compiled = true
  end
end
constructor() click to toggle source
# File lib/factory_bot/definition.rb, line 40
def constructor
  aggregate_from_traits_and_self(:constructor) { @constructor }.last
end
define_constructor(&block) click to toggle source
# File lib/factory_bot/definition.rb, line 92
def define_constructor(&block)
  @constructor = block
end
define_trait(trait) click to toggle source
# File lib/factory_bot/definition.rb, line 84
def define_trait(trait)
  @defined_traits.add(trait)
end
inherit_traits(new_traits) click to toggle source
# File lib/factory_bot/definition.rb, line 68
def inherit_traits(new_traits)
  @base_traits += new_traits
end
overridable() click to toggle source
# File lib/factory_bot/definition.rb, line 63
def overridable
  declarations.overridable
  self
end
register_enum(enum) click to toggle source
# File lib/factory_bot/definition.rb, line 88
def register_enum(enum)
  @registered_enums << enum
end
skip_create() click to toggle source
# File lib/factory_bot/definition.rb, line 80
def skip_create
  @to_create = ->(instance) {}
end
to_create(&block) click to toggle source
# File lib/factory_bot/definition.rb, line 32
def to_create(&block)
  if block
    @to_create = block
  else
    aggregate_from_traits_and_self(:to_create) { @to_create }.last
  end
end

Private Instance Methods

additional_traits() click to toggle source
# File lib/factory_bot/definition.rb, line 141
def additional_traits
  @additional_traits.map { |name| trait_by_name(name) }
end
aggregate_from_traits_and_self(method_name, &block) click to toggle source
# File lib/factory_bot/definition.rb, line 161
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
automatically_register_defined_enums(klass) click to toggle source
# File lib/factory_bot/definition.rb, line 186
def automatically_register_defined_enums(klass)
  klass.defined_enums.each_key { |name| register_enum(Enum.new(name)) }
end
automatically_register_defined_enums?(klass) click to toggle source
# File lib/factory_bot/definition.rb, line 190
def automatically_register_defined_enums?(klass)
  FactoryBot.automatically_define_enum_traits &&
    klass.respond_to?(:defined_enums)
end
base_traits() click to toggle source
# File lib/factory_bot/definition.rb, line 112
def base_traits
  @base_traits.map { |name| trait_by_name(name) }
rescue KeyError => error
  raise error_with_definition_name(error)
end
error_with_definition_name(error) click to toggle source
# File lib/factory_bot/definition.rb, line 121
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
expand_enum_traits(klass) click to toggle source
# File lib/factory_bot/definition.rb, line 171
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
initialize_copy(source) click to toggle source
Calls superclass method
# File lib/factory_bot/definition.rb, line 154
def initialize_copy(source)
  super
  @attributes = nil
  @compiled = false
  @defined_traits_by_name = nil
end
trait_by_name(name) click to toggle source
# File lib/factory_bot/definition.rb, line 145
def trait_by_name(name)
  trait_for(name) || Internal.trait_by_name(name)
end
trait_for(name) click to toggle source
# File lib/factory_bot/definition.rb, line 149
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