-
-
Notifications
You must be signed in to change notification settings - Fork 763
/
base_formatter.rb
157 lines (126 loc) · 4.76 KB
/
base_formatter.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
module RSpec
module Core
module Formatters
class BaseFormatter
include Helpers
attr_accessor :example_group
attr_reader :duration, :examples, :output
attr_reader :example_count, :pending_count, :failure_count
attr_reader :failed_examples, :pending_examples
def initialize(output)
@output = output
@example_count = @pending_count = @failure_count = 0
@examples = []
@failed_examples = []
@pending_examples = []
@example_group = nil
end
# This method is invoked before any examples are run, right after
# they have all been collected. This can be useful for special
# formatters that need to provide progress on feedback (graphical ones)
#
# This will only be invoked once, and the next one to be invoked
# is #example_group_started
def start(example_count)
start_sync_output
@example_count = example_count
end
# This method is invoked at the beginning of the execution of each example group.
# +example_group+ is the example_group.
#
# The next method to be invoked after this is +example_passed+,
# +example_pending+, or +example_finished+
def example_group_started(example_group)
@example_group = example_group
end
# This method is invoked at the end of the execution of each example group.
# +example_group+ is the example_group.
def example_group_finished(example_group)
end
def add_example_group(example_group)
RSpec.deprecate("add_example_group", "example_group_started")
example_group_started(example_group)
end
def example_started(example)
examples << example
end
def example_passed(example)
end
def example_pending(example)
@pending_examples << example
end
def example_failed(example)
@failed_examples << example
end
def message(message)
end
def stop
end
# This method is invoked after all of the examples have executed. The next method
# to be invoked after this one is #dump_failure (once for each failed example),
def start_dump
end
# Dumps detailed information about each example failure.
def dump_failures
end
# This method is invoked after the dumping of examples and failures.
def dump_summary(duration, example_count, failure_count, pending_count)
@duration = duration
@example_count = example_count
@failure_count = failure_count
@pending_count = pending_count
end
# This gets invoked after the summary if option is set to do so.
def dump_pending
end
# This method is invoked at the very end. Allows the formatter to clean up, like closing open streams.
def close
restore_sync_output
end
def format_backtrace(backtrace, example)
return "" unless backtrace
return backtrace if example.metadata[:full_backtrace] == true
cleansed = backtrace.map { |line| backtrace_line(line) }.compact
cleansed.empty? ? backtrace : cleansed
end
protected
def configuration
RSpec.configuration
end
def backtrace_line(line)
return nil if configuration.cleaned_from_backtrace?(line)
line = line.sub(File.expand_path("."), ".")
line = line.sub(/\A([^:]+:\d+)$/, '\\1')
return nil if line == '-e:1'
line
end
def read_failed_line(exception, example)
original_file = example.file_path.to_s.downcase
matching_line = exception.backtrace.detect { |line| line.match(/(.+?):(\d+)(|:\d+)/)[1].downcase == original_file.downcase }
return "Unable to find matching line from backtrace" if matching_line.nil?
file_path, line_number = matching_line.match(/(.+?):(\d+)(|:\d+)/)[1..2]
if File.exist?(file_path)
open(file_path, 'r') { |f| f.readlines[line_number.to_i - 1] }
else
"Unable to find #{file_path} to read failed line"
end
end
def start_sync_output
@old_sync, output.sync = output.sync, true if output_supports_sync
end
def restore_sync_output
output.sync = @old_sync if output_supports_sync and !output.closed?
end
def output_supports_sync
output.respond_to?(:sync=)
end
def profile_examples?
configuration.profile_examples
end
def color_enabled?
configuration.color_enabled?
end
end
end
end
end