module TestProf::FactoryProf
def config
def config @config ||= Configuration.new end
def configure
def configure yield config end
def flush_stack
def flush_stack return unless config.flamegraph? @stacks << @current_stack unless @current_stack.nil? || @current_stack.empty? @current_stack = [] end
def hash_template(name)
def hash_template(name) { name: name, total_count: 0, top_level_count: 0, total_time: 0.0, top_level_time: 0.0 } end
def init
def init @running = false log :info, "FactoryProf enabled (#{config.mode} mode)" patch! end
def patch!
def patch! return if @patched FACTORY_BUILDERS.each(&:patch) @patched = true end
def print(started_at)
def print(started_at) printer = config.printer printer.dump(result, start_time: started_at, threshold: config.threshold) end
def reset!
def reset! @stacks = [] if config.flamegraph? @depth = 0 @stats = Hash.new do |h, k| h[k] = hash_template(k) h[k][:variations] = Hash.new { |hh, variation_key| hh[variation_key] = hash_template(variation_key) } h[k] end flush_stack end
def result
def result Result.new(@stacks, @stats) end
def run
Inits FactoryProf and setups at exit hook,
def run init started_at = TestProf.now at_exit do print(started_at) end start end
def running?
def running? @running == true end
def start
def start reset! @running = true end
def stop
def stop @running = false end
def track(factory, variation:)
def track(factory, variation:) return yield unless running? @depth += 1 @current_stack << factory if config.flamegraph? track_count(@stats[factory]) track_count(@stats[factory][:variations][variation_name(variation)]) if config.include_variations? t1 = TestProf.now begin yield ensure t2 = TestProf.now track_time(@stats[factory], t1, t2) track_time(@stats[factory][:variations][variation_name(variation)], t1, t2) if config.include_variations? @depth -= 1 flush_stack if @depth.zero? end end
def track_count(factory)
def track_count(factory) factory[:total_count] += 1 factory[:top_level_count] += 1 if @depth == 1 end
def track_time(factory, t1, t2)
def track_time(factory, t1, t2) elapsed = t2 - t1 factory[:total_time] += elapsed factory[:top_level_time] += elapsed if @depth == 1 end
def variation_name(variation)
def variation_name(variation) return "-" if variation.empty? variations_count = variation.to_s.scan(/[\w]+/).size return "[...]" if variations_count > config.variations_limit variation end