1
0
Fork 0
mirror of https://github.com/thoughtbot/factory_bot.git synced 2022-11-09 11:43:51 -05:00
thoughtbot--factory_bot/lib/factory_bot/attribute_assigner.rb

113 lines
2.9 KiB
Ruby
Raw Normal View History

module FactoryBot
2012-05-05 02:31:31 -04:00
# @api private
class AttributeAssigner
def initialize(evaluator, build_class, &instance_builder)
2019-04-10 08:57:43 -04:00
@build_class = build_class
@instance_builder = instance_builder
2011-12-05 20:08:47 -05:00
@evaluator = evaluator
2012-01-03 09:31:40 -05:00
@attribute_list = evaluator.class.attribute_list
@attribute_names_assigned = []
end
def object
@evaluator.instance = build_class_instance
build_class_instance.tap do |instance|
attributes_to_set_on_instance.each do |attribute|
instance.public_send("#{attribute}=", get(attribute))
@attribute_names_assigned << attribute
end
end
end
def hash
@evaluator.instance = build_hash
2018-10-07 18:02:54 -04:00
attributes_to_set_on_hash.reduce({}) do |result, attribute|
result[attribute] = get(attribute)
result
end
end
private
def method_tracking_evaluator
@method_tracking_evaluator ||= Decorator::AttributeHash.new(
decorated_evaluator,
attribute_names_to_assign,
)
end
def decorated_evaluator
2012-07-27 14:10:38 -04:00
Decorator::InvocationTracker.new(
2018-10-07 18:02:54 -04:00
Decorator::NewConstructor.new(@evaluator, @build_class),
)
end
def methods_invoked_on_evaluator
2012-06-08 14:18:12 -04:00
method_tracking_evaluator.__invoked_methods__
end
def build_class_instance
2012-07-27 14:10:38 -04:00
@build_class_instance ||= method_tracking_evaluator.instance_exec(&@instance_builder)
end
def build_hash
@build_hash ||= NullObject.new(hash_instance_methods_to_respond_to)
end
def get(attribute_name)
2011-12-05 20:08:47 -05:00
@evaluator.send(attribute_name)
end
def attributes_to_set_on_instance
(attribute_names_to_assign - @attribute_names_assigned - methods_invoked_on_evaluator).uniq
end
def attributes_to_set_on_hash
attribute_names_to_assign - association_names
end
def attribute_names_to_assign
@attribute_names_to_assign ||=
non_ignored_attribute_names +
override_names -
ignored_attribute_names -
alias_names_to_ignore
end
def non_ignored_attribute_names
@attribute_list.non_ignored.names
end
def ignored_attribute_names
@attribute_list.ignored.names
end
def association_names
@attribute_list.associations.names
end
2011-12-16 12:13:59 -05:00
def override_names
@evaluator.__override_names__
2011-12-16 12:13:59 -05:00
end
def hash_instance_methods_to_respond_to
@attribute_list.names + override_names + @build_class.instance_methods
end
2011-12-16 14:45:03 -05:00
def alias_names_to_ignore
2014-11-13 22:06:55 -05:00
@attribute_list.non_ignored.flat_map do |attribute|
override_names.map do |override|
attribute.name if ignorable_alias?(attribute, override)
end
2014-11-13 22:06:55 -05:00
end.compact
2011-12-16 12:13:59 -05:00
end
def ignorable_alias?(attribute, override)
attribute.alias_for?(override) &&
attribute.name != override &&
!ignored_attribute_names.include?(override)
end
end
end