# frozen_string_literal: true module Gitlab module QA module Report class TestResult def self.from_json(report) JsonTestResult.new(report) end def self.from_junit(report) JUnitTestResult.new(report) end attr_accessor :report, :failures def initialize(report) self.report = report self.failures = failures_from_exceptions end def name raise NotImplementedError end def file raise NotImplementedError end def skipped raise NotImplementedError end private def failures_from_exceptions raise NotImplementedError end class JsonTestResult < TestResult def name report['full_description'] end def file report['file_path'] end def skipped report['status'] == 'pending' end def testcase report['testcase'] end def testcase=(new_testcase) report['testcase'] = new_testcase end private # rubocop:disable Metrics/AbcSize def failures_from_exceptions return [] unless report.key?('exceptions') report['exceptions'].map do |exception| spec_file_first_index = exception['backtrace'].rindex do |line| line.include?(File.basename(report['file_path'])) end { 'message' => "#{exception['class']}: #{exception['message']}", 'stacktrace' => "#{exception['message_lines'].join("\n")}\n#{exception['backtrace'].slice(0..spec_file_first_index).join("\n")}" } end end # rubocop:enable Metrics/AbcSize end class JUnitTestResult < TestResult def name report['name'] end def file report['file'] end def skipped report.search('skipped').any? end attr_accessor :testcase # Ignore it for now private def failures_from_exceptions failures = report.search('failure') return [] if failures.empty? failures.map do |exception| trace = exception.content.split("\n").map(&:strip) spec_file_first_index = trace.rindex do |line| line.include?(File.basename(report['file'])) end { 'message' => "#{exception['type']}: #{exception['message']}", 'stacktrace' => trace.slice(0..spec_file_first_index).join("\n") } end end end end end end end