2017-10-20 15:20:28 -04:00
|
|
|
module FactoryBot
|
2012-05-05 02:31:31 -04:00
|
|
|
# @api private
|
2011-10-28 17:01:27 -04:00
|
|
|
class Definition
|
2018-08-04 10:06:57 -04:00
|
|
|
attr_reader :defined_traits, :declarations, :name
|
2011-10-28 17:01:27 -04:00
|
|
|
|
2018-08-04 10:06:57 -04:00
|
|
|
def initialize(name, base_traits = [])
|
|
|
|
@name = name
|
2012-01-17 23:15:41 -05:00
|
|
|
@declarations = DeclarationList.new(name)
|
|
|
|
@callbacks = []
|
2013-12-11 08:53:05 -05:00
|
|
|
@defined_traits = Set.new
|
2012-05-06 16:56:37 -04:00
|
|
|
@to_create = nil
|
2012-01-17 23:15:41 -05:00
|
|
|
@base_traits = base_traits
|
|
|
|
@additional_traits = []
|
2012-05-11 11:43:08 -04:00
|
|
|
@constructor = nil
|
2012-06-12 23:11:55 -04:00
|
|
|
@attributes = nil
|
|
|
|
@compiled = false
|
2011-10-28 17:01:27 -04:00
|
|
|
end
|
|
|
|
|
2012-03-09 17:20:38 -05:00
|
|
|
delegate :declare_attribute, to: :declarations
|
2011-10-30 15:45:00 -04:00
|
|
|
|
|
|
|
def attributes
|
2012-06-12 23:11:55 -04:00
|
|
|
@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
|
2011-10-30 15:45:00 -04:00
|
|
|
end
|
|
|
|
|
2012-06-12 23:11:55 -04:00
|
|
|
def to_create(&block)
|
|
|
|
if block_given?
|
|
|
|
@to_create = block
|
|
|
|
else
|
|
|
|
aggregate_from_traits_and_self(:to_create) { @to_create }.last
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def constructor
|
|
|
|
aggregate_from_traits_and_self(:constructor) { @constructor }.last
|
|
|
|
end
|
|
|
|
|
|
|
|
def callbacks
|
|
|
|
aggregate_from_traits_and_self(:callbacks) { @callbacks }
|
2011-10-30 15:45:00 -04:00
|
|
|
end
|
|
|
|
|
2012-06-12 23:11:55 -04:00
|
|
|
def compile
|
|
|
|
unless @compiled
|
|
|
|
declarations.attributes
|
|
|
|
|
|
|
|
defined_traits.each do |defined_trait|
|
2013-12-14 22:33:15 -05:00
|
|
|
base_traits.each { |bt| bt.define_trait defined_trait }
|
|
|
|
additional_traits.each { |bt| bt.define_trait defined_trait }
|
2012-06-12 23:11:55 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
@compiled = true
|
|
|
|
end
|
2012-01-17 23:15:41 -05:00
|
|
|
end
|
|
|
|
|
2011-10-30 15:45:00 -04:00
|
|
|
def overridable
|
|
|
|
declarations.overridable
|
|
|
|
self
|
|
|
|
end
|
2011-10-28 17:01:27 -04:00
|
|
|
|
2011-10-28 23:01:50 -04:00
|
|
|
def inherit_traits(new_traits)
|
2012-05-06 16:56:37 -04:00
|
|
|
@base_traits += new_traits
|
|
|
|
end
|
|
|
|
|
|
|
|
def append_traits(new_traits)
|
2012-01-17 23:15:41 -05:00
|
|
|
@additional_traits += new_traits
|
2011-10-28 23:01:50 -04:00
|
|
|
end
|
|
|
|
|
2011-10-28 17:01:27 -04:00
|
|
|
def add_callback(callback)
|
|
|
|
@callbacks << callback
|
|
|
|
end
|
|
|
|
|
2012-05-12 00:42:44 -04:00
|
|
|
def skip_create
|
2018-09-27 21:35:05 -04:00
|
|
|
@to_create = ->(instance) {}
|
2012-05-12 00:42:44 -04:00
|
|
|
end
|
|
|
|
|
2011-10-28 17:01:27 -04:00
|
|
|
def define_trait(trait)
|
2013-12-11 08:53:05 -05:00
|
|
|
@defined_traits.add(trait)
|
2011-10-28 17:01:27 -04:00
|
|
|
end
|
|
|
|
|
2012-01-20 13:04:48 -05:00
|
|
|
def define_constructor(&block)
|
|
|
|
@constructor = block
|
|
|
|
end
|
|
|
|
|
2013-02-08 11:00:22 -05:00
|
|
|
def before(*names, &block)
|
2013-12-14 22:33:15 -05:00
|
|
|
callback(*names.map { |name| "before_#{name}" }, &block)
|
2013-02-08 11:00:22 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def after(*names, &block)
|
2013-12-14 22:33:15 -05:00
|
|
|
callback(*names.map { |name| "after_#{name}" }, &block)
|
2013-02-08 11:00:22 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def callback(*names, &block)
|
|
|
|
names.each do |name|
|
2019-04-26 15:48:37 -04:00
|
|
|
FactoryBot::Internal.register_callback(name)
|
2013-02-08 11:00:22 -05:00
|
|
|
add_callback(Callback.new(name, block))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-10-28 23:01:50 -04:00
|
|
|
private
|
|
|
|
|
2012-01-17 23:15:41 -05:00
|
|
|
def base_traits
|
|
|
|
@base_traits.map { |name| trait_by_name(name) }
|
|
|
|
end
|
|
|
|
|
|
|
|
def additional_traits
|
|
|
|
@additional_traits.map { |name| trait_by_name(name) }
|
|
|
|
end
|
|
|
|
|
2011-10-28 17:01:27 -04:00
|
|
|
def trait_by_name(name)
|
2019-04-19 16:01:32 -04:00
|
|
|
trait_for(name) || Internal.trait_by_name(name)
|
2011-10-28 17:01:27 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def trait_for(name)
|
2019-09-30 23:53:04 -04:00
|
|
|
@defined_traits_by_name ||= defined_traits.each_with_object({}) { |t, memo| memo[t.name] ||= t }
|
|
|
|
@defined_traits_by_name[name.to_s]
|
2011-10-28 17:01:27 -04:00
|
|
|
end
|
2012-06-12 23:11:55 -04:00
|
|
|
|
|
|
|
def initialize_copy(source)
|
|
|
|
super
|
|
|
|
@attributes = nil
|
|
|
|
@compiled = false
|
2019-09-30 23:53:04 -04:00
|
|
|
@defined_traits_by_name = nil
|
2012-06-12 23:11:55 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def aggregate_from_traits_and_self(method_name, &block)
|
|
|
|
compile
|
|
|
|
|
2016-04-02 15:42:40 -04:00
|
|
|
[
|
|
|
|
base_traits.map(&method_name),
|
|
|
|
instance_exec(&block),
|
|
|
|
additional_traits.map(&method_name),
|
|
|
|
].flatten.compact
|
2012-06-12 23:11:55 -04:00
|
|
|
end
|
2011-10-28 17:01:27 -04:00
|
|
|
end
|
|
|
|
end
|