Class: FactoryBot::With::AssocInfo
- Inherits:
-
Object
- Object
- FactoryBot::With::AssocInfo
- Defined in:
- lib/factory_bot/with/assoc_info.rb
Overview
An association information of a FactoryBot factory.
Instance Attribute Summary collapse
-
#factory_names ⇒ Set<Symbol>
readonly
List of factory names to be considered compatible with this factory.
-
#map ⇒ {Symbol => Symbol}
readonly
A map from factory names to association names.
Class Method Summary collapse
- .cache ⇒ {Symbol => AssocInfo}
- .exists?(factory_name) ⇒ Boolean
- .from_factory_bot_factory(factory_name) ⇒ AssocInfo
- .get(factory_name) ⇒ AssocInfo
- .perform_factory_name_completion(ancestors, partial_factory_name) ⇒ Symbol
Instance Method Summary collapse
Instance Attribute Details
#factory_names ⇒ Set<Symbol> (readonly)
Returns List of factory names to be considered compatible with this factory.
8 9 10 |
# File 'lib/factory_bot/with/assoc_info.rb', line 8 def factory_names @factory_names end |
#map ⇒ {Symbol => Symbol} (readonly)
Returns a map from factory names to association names.
10 11 12 |
# File 'lib/factory_bot/with/assoc_info.rb', line 10 def map @map end |
Class Method Details
.cache ⇒ {Symbol => AssocInfo}
101 |
# File 'lib/factory_bot/with/assoc_info.rb', line 101 def cache = @cache ||= {} |
.exists?(factory_name) ⇒ Boolean
65 66 67 |
# File 'lib/factory_bot/with/assoc_info.rb', line 65 def exists?(factory_name) !!cache.fetch(factory_name) { FactoryBot.factories.registered?(factory_name) } end |
.from_factory_bot_factory(factory_name) ⇒ AssocInfo
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/factory_bot/with/assoc_info.rb', line 77 def from_factory_bot_factory(factory_name) unless FactoryBot.factories.registered?(factory_name) raise ArgumentError, "FactoryBot factory #{factory_name} is not defined" end factory = FactoryBot.factories.find(factory_name) # NOTE: We consider aliases to be incompatible with each other factory_names = Set[factory_name] map = {} while factory.is_a?(FactoryBot::Factory) factory_names << factory.name # Here, we use reverse_each to prioritize the upper association factory.with_traits(factory.defined_traits.map(&:name)).associations.reverse_each do |assoc| map[Array(assoc.factory)[0].to_sym] = assoc.name end factory = factory.__send__(:parent) end new(factory_names, map) end |
.get(factory_name) ⇒ AssocInfo
71 72 73 |
# File 'lib/factory_bot/with/assoc_info.rb', line 71 def get(factory_name) cache.fetch(factory_name) { cache[factory_name] = from_factory_bot_factory(factory_name) } end |
.perform_factory_name_completion(ancestors, partial_factory_name) ⇒ Symbol
48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/factory_bot/with/assoc_info.rb', line 48 def perform_factory_name_completion(ancestors, partial_factory_name) ancestors.each do |(ancestor_assoc_info, _)| ancestor_assoc_info.factory_names.each do |ancestor_factory_name| factory_name = :"#{ancestor_factory_name}_#{partial_factory_name}" return factory_name if exists?(factory_name) end end # Attempt to resolve with the completed names, then attempt to resolve with the original name. # If we want to avoid completion, we should be able to simply use a factory such as build or create. return partial_factory_name if exists?(partial_factory_name) raise ArgumentError, "FactoryBot factory #{partial_factory_name} is not defined" end |
Instance Method Details
#perform_automatic_association_resolution(ancestors, dest) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/factory_bot/with/assoc_info.rb', line 27 def perform_automatic_association_resolution(ancestors, dest) priorities = {} map.each do |factory_name, attribute| # skip if this attribute is explicitly specified next if dest.member?(attribute) && !priorities.member?(attribute) # closer ancestors have higher (lower integer) priority ancestor, priority = ancestors.each_with_index.find do |(ancestor_assoc_info, _), _| ancestor_assoc_info.factory_names.include?(factory_name) end next if !ancestor || priorities.fetch(attribute, Float::INFINITY) <= priority priorities[attribute] = priority dest[attribute] = ancestor[1] end end |