module TestProf::FactoryDefault
def config
def config @config ||= Configuration.new end
def configure
def configure yield config end
def disable!
def disable! was_enabled = @enabled @enabled = false return unless block_given? yield ensure @enabled = was_enabled end
def enable!
def enable! was_enabled = @enabled @enabled = true return unless block_given? yield ensure @enabled = was_enabled end
def enabled?
def enabled? @enabled end
def get(name, traits = nil, overrides = nil, skip_stats: false)
def get(name, traits = nil, overrides = nil, skip_stats: false) return unless enabled? record = store[name] return unless record if traits && (trait_key = record[:traits][traits]) name = trait_key record = store[name] traits = nil end stats[name][:miss] += 1 unless skip_stats if traits && !traits.empty? && record[:preserve_traits] return end object = record[:object] if overrides && !overrides.empty? && record[:preserve_attributes] overrides.each do |name, value| return unless object.respond_to?(name) # rubocop:disable Lint/NonLocalExitFromIterator return if object.public_send(name) != value # rubocop:disable Lint/NonLocalExitFromIterator end end unless skip_stats stats[name][:miss] -= 1 stats[name][:hit] += 1 end if record[:context] && (record[:context] != :example) object.refind else object end end
def init
def init FactoryBotPatch.patch FabricationPatch.patch @profiler = config.profiling_enabled? ? Profiler.new : NoopProfiler.new @enabled = ENV["FACTORY_DEFAULT_DISABLED"] != "1" @stats = {} end
def preserve_attributes=(val)
def preserve_attributes=(val) config.preserve_attributes = val end
def preserve_traits=(val)
def preserve_traits=(val) config.preserve_traits = val end
def print_report
def print_report profiler.print_report return unless config.report_stats || config.report_summary if stats.empty? log :info, "FactoryDefault has not been used" return end msgs = [] if config.report_stats msgs << <<~MSG FactoryDefault usage stats: MSG first_column = stats.keys.map(&:size).max + 2 msgs << format( "%#{first_column}s %9s %9s", "factory", "hit", "miss" ) msgs << "" end total_hit = 0 total_miss = 0 stats.to_a.sort_by { |(_, v)| -v[:hit] }.each do |(key, record_stats)| total_hit += record_stats[:hit] total_miss += record_stats[:miss] if config.report_stats msgs << format( "%#{first_column}s %9d %9d", key, record_stats[:hit], record_stats[:miss] ) end end msgs << "" if config.report_stats msgs << <<~MSG FactoryDefault summary: hit=#{total_hit} miss=#{total_miss} MSG log :info, msgs.join("\n") end
def refind
def refind self end
def register(name, obj, **options)
def register(name, obj, **options) # Name with traits if name.is_a?(Array) register_traited_record(*name, obj, **options) else register_default_record(name, obj, **options) end obj end
def register_default_record(name, obj, **options)
def register_default_record(name, obj, **options) store[name] = {object: obj, traits: {}, context: current_context, **options} stats[name] ||= {hit: 0, miss: 0} end
def register_traited_record(name, *traits, obj, **options)
def register_traited_record(name, *traits, obj, **options) name_with_traits = "#{name}[#{traits.join(",")}]" register_default_record(name_with_traits, obj, **options) register_default_record(name, obj, **options) unless store[name] # Add reference to the traited default to the original default record store[name][:traits][traits] = name_with_traits end
def remove(name)
def remove(name) store.delete(name) end
def reset(context: nil)
def reset(context: nil) return store.clear unless context store.delete_if do |_name, metadata| metadata[:context] == context end end
def store
def store Thread.current[:testprof_factory_default_store] ||= {} end
def to_override_key
def to_override_key "<#{self.class.name}::$id$#{object_id}$di$>" end
def to_override_key
def to_override_key "<#{self.class.name}\#$id$#{public_send(self.class.primary_key)}$di$>" end
def to_override_key
def to_override_key inspect end