Class: Woods::Extractors::FactoryExtractor

Inherits:
Object
  • Object
show all
Includes:
SharedDependencyScanner, SharedUtilityMethods
Defined in:
lib/woods/extractors/factory_extractor.rb

Overview

FactoryExtractor handles extraction of FactoryBot factory definitions.

Scans spec/factories/ and test/factories/ for FactoryBot definitions and produces one ExtractedUnit per factory block. Uses a line-by-line state machine parser (never evals factory files).

Supports: basic factories, explicit class override, traits, associations, sequences, callbacks, parent inheritance, transient attributes, and nested factory definitions (each becomes its own unit).

Examples:

extractor = FactoryExtractor.new
units = extractor.extract_all
user = units.find { |u| u.identifier == "user" }
user.[:traits] # => ["admin", "with_avatar"]

Constant Summary collapse

FACTORY_DIRECTORIES =
%w[spec/factories test/factories].freeze

Constants included from SharedDependencyScanner

SharedDependencyScanner::FORM_ACTION_HELPER, SharedDependencyScanner::ROUTE_HELPER_PATTERN

Instance Method Summary collapse

Methods included from SharedDependencyScanner

#extract_constantize_targets, #scan_common_dependencies, #scan_form_dependencies, #scan_job_dependencies, #scan_mailer_dependencies, #scan_model_dependencies, #scan_navigation_dependencies, #scan_service_dependencies

Methods included from SharedUtilityMethods

#app_source?, #condition_label, #count_loc, #detect_entry_points, #extract_action_filter_actions, #extract_callback_conditions, #extract_class_methods, #extract_class_name, #extract_custom_errors, #extract_initialize_params, #extract_namespace, #extract_parent_class, #extract_public_methods, #resolve_source_location, #skip_file?

Constructor Details

#initializeFactoryExtractor

Returns a new instance of FactoryExtractor.



30
31
32
# File 'lib/woods/extractors/factory_extractor.rb', line 30

def initialize
  @directories = FACTORY_DIRECTORIES.map { |d| Rails.root.join(d) }.select(&:directory?)
end

Instance Method Details

#extract_allArray<ExtractedUnit>

Extract all factory definitions from all discovered directories.

Returns:



37
38
39
40
41
# File 'lib/woods/extractors/factory_extractor.rb', line 37

def extract_all
  @directories.flat_map do |dir|
    Dir[dir.join('**/*.rb')].flat_map { |file| extract_factory_file(file) }
  end
end

#extract_factory_file(file_path) ⇒ Array<ExtractedUnit>

Extract factory definitions from a single factory file.

Returns an Array because each file may contain multiple factory definitions.

Parameters:

  • file_path (String)

    Path to the factory file

Returns:



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/woods/extractors/factory_extractor.rb', line 49

def extract_factory_file(file_path)
  return [] unless file_path.to_s.end_with?('.rb')

  source = File.read(file_path)
  factories = parse_factories(source)

  factories.map { |factory_data| build_unit(factory_data, file_path, source) }
rescue StandardError => e
  Rails.logger.error("Failed to extract factories from #{file_path}: #{e.message}")
  []
end