Class: Jenkins::Build::TestReport::StackTrace

Inherits:
Object
  • Object
show all
Defined in:
lib/jenkins/build/test_report.rb

Constant Summary collapse

TEST_PATHS =
%w[test spec features]
RUBY_STACK_FRAME =
/[^\w\/](\.?\/[\w._-][\/\w._-]+:\d+)/.freeze
CUCUMBER_STACK_FRAME =
/(features\/[\w._-][\/\w._-]+:\d+)/.freeze
SYSTEM_PATHS =
%w[/usr/lib /lib]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stderr) ⇒ StackTrace



98
99
100
101
102
# File 'lib/jenkins/build/test_report.rb', line 98

def initialize(stderr)
  @stderr = stderr
  @stack_trace = extract_stack_frames(stderr.to_s).flatten.compact.reject(&method(:system_path?))
  @root_path = longest_common_substr(stack_trace) || ''
end

Instance Attribute Details

#root_pathObject (readonly)

Returns the value of attribute root_path.



96
97
98
# File 'lib/jenkins/build/test_report.rb', line 96

def root_path
  @root_path
end

#stack_traceObject (readonly)

Returns the value of attribute stack_trace.



96
97
98
# File 'lib/jenkins/build/test_report.rb', line 96

def stack_trace
  @stack_trace
end

#stderrObject (readonly)

Returns the value of attribute stderr.



96
97
98
# File 'lib/jenkins/build/test_report.rb', line 96

def stderr
  @stderr
end

Instance Method Details

#cause(project_path = root_path) ⇒ Object



104
105
106
107
108
# File 'lib/jenkins/build/test_report.rb', line 104

def cause(project_path = root_path)
  stack_trace.lazy.reverse_each.
    map { |path| relative_path(path, project_path || root_path) }.
    find(&method(:test_stack_frame?))
end

#extract_stack_frames(text) ⇒ Object



123
124
125
# File 'lib/jenkins/build/test_report.rb', line 123

def extract_stack_frames(text)
  text.scan(RUBY_STACK_FRAME) + text.scan(CUCUMBER_STACK_FRAME)
end

#longest_common_substr(strings) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/jenkins/build/test_report.rb', line 134

def longest_common_substr(strings)
  return unless strings.length > 1
  shortest = strings.min_by(&:length) or return
  maxlen = shortest.length
  maxlen.downto(0) do |len|
    0.upto(maxlen - len) do |start|
      substr = shortest[start,len]
      return substr if strings.all?{|str| str.start_with?(substr) }
    end
  end

  nil
end

#relative_path(full_frame, project_path) ⇒ Object



116
117
118
# File 'lib/jenkins/build/test_report.rb', line 116

def relative_path(full_frame, project_path)
  full_frame.sub(project_path, ''.freeze)
end

#system_path?(path) ⇒ Boolean



129
130
131
# File 'lib/jenkins/build/test_report.rb', line 129

def system_path?(path)
  SYSTEM_PATHS.any?(&path.method(:start_with?))
end

#test_stack_frame?(project_frame) ⇒ Boolean



112
113
114
# File 'lib/jenkins/build/test_report.rb', line 112

def test_stack_frame?(project_frame)
  TEST_PATHS.any?(&project_frame.method(:start_with?))
end