Class: SpecForge::Factory

Inherits:
Object
  • Object
show all
Defined in:
lib/spec_forge/factory.rb

Overview

Manages factory definitions and registration with FactoryBot Provides methods for loading factories from YAML files

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, **input) ⇒ Factory

Creates a new Factory instance

Parameters:

  • name (String, Symbol)

    The name of the factory

  • input (Hash)

    The attributes defining the factory



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/spec_forge/factory.rb', line 78

def initialize(name:, **input)
  @name = name
  input = Normalizer.normalize!(input, using: :factory)

  @input = input
  @model_class = input[:model_class]

  @variables = Attribute.from(input[:variables])
  @attributes = Attribute.from(input[:attributes], context: @variables)
  @traits = extract_traits(input[:traits], context: @variables)
end

Instance Attribute Details

#attributesHash<Symbol, Attribute> (readonly)

Returns The attributes that define this factory.

Returns:

  • (Hash<Symbol, Attribute>)

    The attributes that define this factory



65
66
67
# File 'lib/spec_forge/factory.rb', line 65

def attributes
  @attributes
end

#inputHash (readonly)

Returns The raw input that defined this factory.

Returns:

  • (Hash)

    The raw input that defined this factory



56
57
58
# File 'lib/spec_forge/factory.rb', line 56

def input
  @input
end

#model_classString? (readonly)

Returns The model class name this factory represents, if specified.

Returns:

  • (String, nil)

    The model class name this factory represents, if specified



59
60
61
# File 'lib/spec_forge/factory.rb', line 59

def model_class
  @model_class
end

#nameSymbol, String (readonly)

Returns The name of the factory.

Returns:

  • (Symbol, String)

    The name of the factory



53
54
55
# File 'lib/spec_forge/factory.rb', line 53

def name
  @name
end

#traitsHash<Symbol, Hash<Symbol, Attribute>> (readonly)

Returns Traits defined for this factory.

Returns:

  • (Hash<Symbol, Hash<Symbol, Attribute>>)

    Traits defined for this factory



68
69
70
# File 'lib/spec_forge/factory.rb', line 68

def traits
  @traits
end

#variablesHash<Symbol, Attribute> (readonly)

Returns Variables defined for this factory.

Returns:

  • (Hash<Symbol, Attribute>)

    Variables defined for this factory



62
63
64
# File 'lib/spec_forge/factory.rb', line 62

def variables
  @variables
end

Class Method Details

.load_and_registerObject

Loads factories from files and registers them with FactoryBot Sets up paths and loads definitions based on configuration



13
14
15
16
17
18
19
20
21
22
# File 'lib/spec_forge/factory.rb', line 13

def self.load_and_register
  if SpecForge.configuration.factories.paths?
    FactoryBot.definition_file_paths = SpecForge.configuration.factories.paths
  end

  FactoryBot.find_definitions if SpecForge.configuration.factories.auto_discover?

  factories = load_from_files
  factories.each(&:register)
end

.load_from_filesArray<Factory>

Loads factory definitions from YAML files Creates Factory instances but doesn't register them with FactoryBot

Factory names are derived from the filename (e.g., user.yml -> :user)

Returns:



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/spec_forge/factory.rb', line 32

def self.load_from_files
  path = SpecForge.forge_path.join("factories", "**/*.yml")

  factories = []

  Dir[path].each do |file_path|
    hash = YAML.load_file(file_path, symbolize_names: true)

    # Extract factory name from filename (e.g., "user.yml" -> :user)
    factory_name = File.basename(file_path, ".yml").to_sym
    hash[:name] = factory_name

    factories << new(**hash)
  end

  factories
end

Instance Method Details

#registerself

Registers this factory with FactoryBot Makes the factory available for use in specs

Returns:

  • (self)

    Returns self for method chaining



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/spec_forge/factory.rb', line 96

def register
  dsl = FactoryBot::Syntax::Default::DSL.new

  options = {}
  options[:class] = model_class if model_class.present?

  # This creates the factory in FactoryBot
  factory_forge = self
  dsl.factory(name, options) do
    # Register base attributes
    factory_forge.attributes.each do |attr_name, attribute|
      add_attribute(attr_name) { attribute.resolve }
    end

    # Register traits
    factory_forge.traits.each do |trait_name, trait_attributes|
      trait(trait_name) do
        trait_attributes.each do |attr_name, attribute|
          add_attribute(attr_name) { attribute.resolve }
        end
      end
    end
  end

  self
end