class RSpecTracer::Reporter

Attributes

all_examples[R]
all_files[R]
deleted_files[R]
dependency[R]
examples_coverage[R]
flaky_examples[R]
last_run[R]
modified_files[R]
pending_examples[R]
possibly_flaky_examples[R]
reverse_dependency[R]

Public Class Methods

new() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 9
def initialize
  initialize_examples
  initialize_files
  initialize_dependency
  initialize_coverage
end

Public Instance Methods

example_deleted?(example_id) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 81
def example_deleted?(example_id)
  @deleted_examples.include?(example_id)
end
example_failed?(example_id) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 73
def example_failed?(example_id)
  @failed_examples.include?(example_id)
end
example_passed?(example_id) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 65
def example_passed?(example_id)
  @passed_examples.include?(example_id)
end
example_pending?(example_id) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 77
def example_pending?(example_id)
  @pending_examples.include?(example_id)
end
example_skipped?(example_id) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 69
def example_skipped?(example_id)
  @skipped_examples.include?(example_id)
end
file_changed?(file_name) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 105
def file_changed?(file_name)
  file_deleted?(file_name) || file_modified?(file_name)
end
file_deleted?(file_name) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 97
def file_deleted?(file_name)
  @deleted_files.include?(file_name)
end
file_modified?(file_name) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 101
def file_modified?(file_name)
  @modified_files.include?(file_name)
end
generate_last_run_report() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 130
def generate_last_run_report
  @last_run = {
    run_id: @run_id,
    pid: RSpecTracer.pid,
    actual_count: RSpec.world.example_count + @skipped_examples.count,
    example_count: RSpec.world.example_count,
    failed_examples: @failed_examples.count,
    skipped_examples: @skipped_examples.count,
    pending_examples: @pending_examples.count
  }
end
generate_reverse_dependency_report() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 117
def generate_reverse_dependency_report
  @dependency.each_pair do |example_id, files|
    example_file = @all_examples[example_id][:rerun_file_name]

    files.each do |file_name|
      @reverse_dependency[file_name][:example_count] += 1
      @reverse_dependency[file_name][:examples][example_file] += 1
    end
  end

  format_reverse_dependency_report
end
on_example_failed(example_id, result) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 29
def on_example_failed(example_id, result)
  @failed_examples << example_id
  @all_examples[example_id][:execution_result] = formatted_execution_result(result)
end
on_example_passed(example_id, result) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 24
def on_example_passed(example_id, result)
  @passed_examples << example_id
  @all_examples[example_id][:execution_result] = formatted_execution_result(result)
end
on_example_pending(example_id, result) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 34
def on_example_pending(example_id, result)
  @pending_examples << example_id
  @all_examples[example_id][:execution_result] = formatted_execution_result(result)
end
on_example_skipped(example_id) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 20
def on_example_skipped(example_id)
  @skipped_examples << example_id
end
on_file_deleted(file_name) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 89
def on_file_deleted(file_name)
  @deleted_files << file_name
end
on_file_modified(file_name) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 93
def on_file_modified(file_name)
  @modified_files << file_name
end
register_deleted_examples(seen_examples) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 39
def register_deleted_examples(seen_examples)
  @deleted_examples = seen_examples.keys.to_set - (@skipped_examples | @all_examples.keys)

  @deleted_examples.select! do |example_id|
    example = seen_examples[example_id]

    file_changed?(example[:file_name]) || file_changed?(example[:rerun_file_name])
  end
end
register_dependency(example_id, file_name) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 109
def register_dependency(example_id, file_name)
  @dependency[example_id] << file_name
end
register_example(example) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 16
def register_example(example)
  @all_examples[example[:example_id]] = example
end
register_examples_coverage(examples_coverage) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 113
def register_examples_coverage(examples_coverage)
  @examples_coverage = examples_coverage
end
register_failed_example(example_id) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 57
def register_failed_example(example_id)
  @failed_examples << example_id
end
register_flaky_example(example_id) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 53
def register_flaky_example(example_id)
  @flaky_examples << example_id
end
register_pending_example(example_id) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 61
def register_pending_example(example_id)
  @pending_examples << example_id
end
register_possibly_flaky_example(example_id) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 49
def register_possibly_flaky_example(example_id)
  @possibly_flaky_examples << example_id
end
register_source_file(source_file) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 85
def register_source_file(source_file)
  @all_files[source_file[:file_name]] = source_file
end
write_reports() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 142
def write_reports
  starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)

  @run_id = Digest::MD5.hexdigest(@all_examples.keys.sort.to_json)
  @cache_dir = File.join(RSpecTracer.cache_path, @run_id)

  FileUtils.mkdir_p(@cache_dir)

  %i[
    all_examples
    flaky_examples
    failed_examples
    pending_examples
    all_files
    dependency
    reverse_dependency
    examples_coverage
    last_run
  ].each { |report_type| send("write_#{report_type}_report") }

  ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  elpased = RSpecTracer::TimeFormatter.format_time(ending - starting)

  puts "RSpec tracer reports written to #{@cache_dir} (took #{elpased})"
end

Private Instance Methods

format_reverse_dependency_report() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 214
def format_reverse_dependency_report
  @reverse_dependency.transform_values! do |data|
    {
      example_count: data[:example_count],
      examples: data[:examples].sort_by { |file_name, count| [-count, file_name] }.to_h
    }
  end

  report = @reverse_dependency.sort_by do |file_name, data|
    [-data[:example_count], file_name]
  end

  @reverse_dependency = report.to_h
end
formatted_execution_result(result) click to toggle source
# File lib/rspec_tracer/reporter.rb, line 205
def formatted_execution_result(result)
  {
    started_at: result.started_at.utc,
    finished_at: result.finished_at.utc,
    run_time: result.run_time,
    status: result.status.to_s
  }
end
initialize_coverage() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 197
def initialize_coverage
  @examples_coverage = Hash.new do |examples, example_id|
    examples[example_id] = Hash.new do |files, file_name|
      files[file_name] = {}
    end
  end
end
initialize_dependency() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 187
def initialize_dependency
  @dependency = Hash.new { |hash, key| hash[key] = Set.new }
  @reverse_dependency = Hash.new do |examples, file_name|
    examples[file_name] = {
      example_count: 0,
      examples: Hash.new(0)
    }
  end
end
initialize_examples() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 170
def initialize_examples
  @all_examples = {}
  @passed_examples = Set.new
  @possibly_flaky_examples = Set.new
  @flaky_examples = Set.new
  @failed_examples = Set.new
  @skipped_examples = Set.new
  @pending_examples = Set.new
  @deleted_examples = Set.new
end
initialize_files() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 181
def initialize_files
  @all_files = {}
  @modified_files = Set.new
  @deleted_files = Set.new
end
write_all_examples_report() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 229
def write_all_examples_report
  file_name = File.join(@cache_dir, 'all_examples.json')

  File.write(file_name, JSON.pretty_generate(@all_examples))
end
write_all_files_report() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 253
def write_all_files_report
  file_name = File.join(@cache_dir, 'all_files.json')

  File.write(file_name, JSON.pretty_generate(@all_files))
end
write_dependency_report() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 259
def write_dependency_report
  file_name = File.join(@cache_dir, 'dependency.json')

  File.write(file_name, JSON.pretty_generate(@dependency))
end
write_examples_coverage_report() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 271
def write_examples_coverage_report
  file_name = File.join(@cache_dir, 'examples_coverage.json')

  File.write(file_name, JSON.pretty_generate(@examples_coverage))
end
write_failed_examples_report() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 241
def write_failed_examples_report
  file_name = File.join(@cache_dir, 'failed_examples.json')

  File.write(file_name, JSON.pretty_generate(@failed_examples.to_a))
end
write_flaky_examples_report() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 235
def write_flaky_examples_report
  file_name = File.join(@cache_dir, 'flaky_examples.json')

  File.write(file_name, JSON.pretty_generate(@flaky_examples.to_a))
end
write_last_run_report() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 277
def write_last_run_report
  file_name = File.join(RSpecTracer.cache_path, 'last_run.json')
  last_run_data = @last_run.merge(run_id: @run_id, timestamp: Time.now.utc)

  File.write(file_name, JSON.pretty_generate(last_run_data))
end
write_pending_examples_report() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 247
def write_pending_examples_report
  file_name = File.join(@cache_dir, 'pending_examples.json')

  File.write(file_name, JSON.pretty_generate(@pending_examples.to_a))
end
write_reverse_dependency_report() click to toggle source
# File lib/rspec_tracer/reporter.rb, line 265
def write_reverse_dependency_report
  file_name = File.join(@cache_dir, 'reverse_dependency.json')

  File.write(file_name, JSON.pretty_generate(@reverse_dependency))
end