Class: Ctrf::RSpecFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/ctrf/r_spec_formatter.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(output) ⇒ RSpecFormatter

Returns a new instance of RSpecFormatter.



9
10
11
# File 'lib/ctrf/r_spec_formatter.rb', line 9

def initialize(output)
  @output = output
end

Instance Attribute Details

#outputObject (readonly)

Returns the value of attribute output.



7
8
9
# File 'lib/ctrf/r_spec_formatter.rb', line 7

def output
  @output
end

Instance Method Details

#example_finished(notification) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/ctrf/r_spec_formatter.rb', line 52

def example_finished(notification)
  test = @tests[notification.example.hash]

  test[:duration] = notification.example.execution_result.run_time * 1000
  test[:start] = notification.example.execution_result.started_at.to_i
  test[:stop] = notification.example.execution_result.finished_at.to_i

  test[:status] = notification.example.execution_result.status.to_s
  test[:rawStatus] = notification.example.execution_result.status

  # If we passed but retries is >0, the test is flaky
  test[:flaky] = test[:status] == 'passed' && @retries > 0
  test[:retries] = @retries

  # Attach error information, if any
  exception = notification.example.exception
  test[:message] = exception.detailed_message if exception

  # If this wasn't the first run, move the trace to extra
  if test.key?(:trace)
    test[:extra][:previous_traces] = [] unless test[:extra].key?(:previous_traces)
    test.delete(:trace)
  end
  test[:trace] = notification.formatted_backtrace.join("\n") if exception
end

#example_started(notification) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/ctrf/r_spec_formatter.rb', line 18

def example_started(notification)
  @retries = 0

  # Set up the object for use if it doesn't exist already
  # It might, if retries
  return if @tests.key?(notification.example.hash)

  @tests[notification.example.hash] = {
    name: notification.example.full_description,
    suite: notification.example.example_group.name,
    # We use id here because it's location + test scope, e.g. what we need to rerun the test
    # Otherwise, this could is the location of the `it` - even if that's in a helper file unrelated to the test
    filePath: notification.example.id,
    extra: {
      hash: notification.example.hash
    }
  }
end

#retry(example) ⇒ Object

Gets hit if rspec-retry is enabled, for flaky support



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/ctrf/r_spec_formatter.rb', line 38

def retry(example)
  @retries += 1

  # We add the previous traces here, because we only hit example_finished once
  test = @tests[example.hash]
  test[:extra][:previous_traces] = [] unless test[:extra].key?(:previous_traces)
  backtrace_formatter = RSpec.configuration.backtrace_formatter
  return unless example.exception

  test[:extra][:previous_traces].push("#{example.exception.detailed_message}\n" + backtrace_formatter.format_backtrace(
    example.exception.backtrace, example.
  ).join("\n"))
end

#start(_notification) ⇒ Object



13
14
15
16
# File 'lib/ctrf/r_spec_formatter.rb', line 13

def start(_notification)
  @tests = {}
  @run_start = Time.now.to_i
end

#stop(_notification) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ctrf/r_spec_formatter.rb', line 78

def stop(_notification)
  # Build the final result object
  result = {
    results: {
      tool: {
        name: 'rspec'
      },
      summary: {
        tests: @tests.count,
        passed: @tests.values.select { |test| test[:status] == 'passed' }.count,
        failed: @tests.values.select { |test| test[:status] == 'failed' }.count,
        pending: @tests.values.select { |test| test[:status] == 'pending' }.count,
        skipped: @tests.values.select { |test| test[:status] == 'skipped' }.count,
        other: @tests.values.select { |test| test[:status] == 'other' }.count,
        start: @run_start,
        stop: Time.now.to_i
      },
      tests: @tests.values
    }
  }

  @output.write(JSON.pretty_generate(result))
end