lib/rspec_tracer/report_merger.rb
# frozen_string_literal: true
module RSpecTracer
class ReportMerger
attr_reader :all_examples, :duplicate_examples, :interrupted_examples,
:flaky_examples, :failed_examples, :pending_examples, :skipped_examples,
:all_files, :dependency, :reverse_dependency, :examples_coverage, :last_run
def initialize
@last_run = {}
@all_examples = {}
@duplicate_examples = {}
@interrupted_examples = Set.new
@flaky_examples = Set.new
@failed_examples = Set.new
@pending_examples = Set.new
@skipped_examples = Set.new
@all_files = {}
@dependency = Hash.new { |hash, key| hash[key] = Set.new }
@reverse_dependency = {}
@examples_coverage = {}
end
def merge(reports_dir)
reports_dir.each do |report_dir|
next unless File.directory?(report_dir)
merge_cache(load_cache(report_dir))
merge_last_run_report(File.dirname(report_dir))
end
@dependency.transform_values!(&:to_a)
@reverse_dependency = RSpecTracer::ReportGenerator.new(self, nil).reverse_dependency_report
end
private
def load_cache(cache_dir)
cache = RSpecTracer::Cache.new
cache.send(:load_all_examples_cache, cache_dir, discard_run_reason: false)
cache.send(:load_duplicate_examples_cache, cache_dir)
cache.send(:load_interrupted_examples_cache, cache_dir)
cache.send(:load_flaky_examples_cache, cache_dir)
cache.send(:load_failed_examples_cache, cache_dir)
cache.send(:load_pending_examples_cache, cache_dir)
cache.send(:load_skipped_examples_cache, cache_dir)
cache.send(:load_all_files_cache, cache_dir)
cache.send(:load_dependency_cache, cache_dir)
cache.send(:load_examples_coverage_cache, cache_dir)
cache
end
def merge_cache(cache)
@all_examples.merge!(cache.all_examples) { |_, v1, v2| v1[:run_reason] ? v1 : v2 }
@duplicate_examples.merge!(cache.duplicate_examples) { |_, v1, v2| v1 + v2 }
@interrupted_examples.merge(cache.interrupted_examples)
@flaky_examples.merge(cache.flaky_examples)
@failed_examples.merge(cache.failed_examples)
@pending_examples.merge(cache.pending_examples)
@skipped_examples.merge(cache.skipped_examples)
@all_files.merge!(cache.all_files)
@dependency.merge!(cache.dependency) { |_, v1, v2| v1.merge(v2) }
@examples_coverage.merge!(cache.examples_coverage) do |_, v1, v2|
v1.merge(v2) { |_, v3, v4| v3.merge(v4) { |_, v5, v6| v5 + v6 } }
end
end
def merge_last_run_report(cache_dir)
file_name = File.join(cache_dir, 'last_run.json')
cached_last_run = JSON.parse(File.read(file_name), symbolize_names: true)
cached_last_run[:pid] = [cached_last_run[:pid]]
cached_last_run.delete_if { |key, _| %i[run_id timestamp].include?(key) }
@last_run.merge!(cached_last_run) { |_, v1, v2| v1 + v2 }
end
end
end