Class: RSpecTelemetry::Analyzer

Inherits:
Object
  • Object
show all
Defined in:
lib/rspec_telemetry/analyzer.rb

Defined Under Namespace

Classes: Example, FileStat

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAnalyzer

Returns a new instance of Analyzer.



31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rspec_telemetry/analyzer.rb', line 31

def initialize
  @examples = {}
  @factory_acc = FactoryAggregation::Accumulator.new
  @files = {}
  # Factory events arrive before example.finished, so merge them after loading.
  @example_fb = Hash.new { |h, k| h[k] = [0.0, 0] }
  @example_count = 0
  @failure_count = 0
  @pending_count = 0
  @suite_duration_ms = 0.0
end

Instance Attribute Details

#example_countObject (readonly)

Returns the value of attribute example_count.



22
23
24
# File 'lib/rspec_telemetry/analyzer.rb', line 22

def example_count
  @example_count
end

#examplesObject (readonly)

Returns the value of attribute examples.



22
23
24
# File 'lib/rspec_telemetry/analyzer.rb', line 22

def examples
  @examples
end

#failure_countObject (readonly)

Returns the value of attribute failure_count.



22
23
24
# File 'lib/rspec_telemetry/analyzer.rb', line 22

def failure_count
  @failure_count
end

#filesObject (readonly)

Returns the value of attribute files.



22
23
24
# File 'lib/rspec_telemetry/analyzer.rb', line 22

def files
  @files
end

#pending_countObject (readonly)

Returns the value of attribute pending_count.



22
23
24
# File 'lib/rspec_telemetry/analyzer.rb', line 22

def pending_count
  @pending_count
end

#suite_duration_msObject (readonly)

Returns the value of attribute suite_duration_ms.



22
23
24
# File 'lib/rspec_telemetry/analyzer.rb', line 22

def suite_duration_ms
  @suite_duration_ms
end

Class Method Details

.events_for_example(paths, example_id) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/rspec_telemetry/analyzer.rb', line 104

def self.events_for_example(paths, example_id)
  events = []
  Array(paths).each do |path|
    File.foreach(path) do |line|
      event = Ndjson.parse(line)
      next unless event && event["example_id"] == example_id

      events << event
    end
  end

  events
end

.load(paths) ⇒ Object



43
44
45
46
47
48
49
50
51
52
# File 'lib/rspec_telemetry/analyzer.rb', line 43

def self.load(paths)
  new.tap do |analyzer|
    Array(paths).each do |path|
      File.foreach(path) do |line|
        event = Ndjson.parse(line)
        analyzer.add(event) if event
      end
    end
  end
end

Instance Method Details

#add(event) ⇒ Object



54
55
56
57
58
59
60
61
62
63
# File 'lib/rspec_telemetry/analyzer.rb', line 54

def add(event)
  case event["type"]
  when "example.finished"
    add_example(event)
  when "factory_bot.run_factory"
    add_factory(event)
  when "suite.finished"
    add_suite(event)
  end
end

#factoriesObject



69
70
71
# File 'lib/rspec_telemetry/analyzer.rb', line 69

def factories
  @factory_acc.stats
end

#factory_time_ratioObject



77
78
79
80
# File 'lib/rspec_telemetry/analyzer.rb', line 77

def factory_time_ratio
  total = total_example_ms
  total.zero? ? 0.0 : total_factory_self_ms / total
end

#merged_examplesObject



86
87
88
89
90
91
92
93
94
# File 'lib/rspec_telemetry/analyzer.rb', line 86

def merged_examples
  # Mutate the report structs at the read boundary; raw aggregates stay separate.
  @examples.values.map do |ex|
    self_total, count = @example_fb[ex.example_id]
    ex.fb_self_total_ms = self_total
    ex.fb_count = count
    ex
  end
end

#slow_examples(limit = 20) ⇒ Object



82
83
84
# File 'lib/rspec_telemetry/analyzer.rb', line 82

def slow_examples(limit = 20)
  merged_examples.sort_by { |e| -e.duration_ms.to_f }.first(limit)
end

#slow_files(limit = 20) ⇒ Object



100
101
102
# File 'lib/rspec_telemetry/analyzer.rb', line 100

def slow_files(limit = 20)
  @files.values.sort_by { |f| -f.duration_ms.to_f }.first(limit)
end

#top_factories(limit = 20) ⇒ Object



96
97
98
# File 'lib/rspec_telemetry/analyzer.rb', line 96

def top_factories(limit = 20)
  @factory_acc.top(limit)
end

#total_example_msObject



65
66
67
# File 'lib/rspec_telemetry/analyzer.rb', line 65

def total_example_ms
  @examples.values.sum { |e| e.duration_ms.to_f }
end

#total_factory_self_msObject



73
74
75
# File 'lib/rspec_telemetry/analyzer.rb', line 73

def total_factory_self_ms
  @factory_acc.stats.sum(&:self_total_ms)
end