class ParseOutput
def initialize
@class_name_idx = 0
@path_delim = nil
@xml_out = false
@array_list = false
@test_suite = nil
@total_tests = 0
@test_passed = 0
@test_failed = 0
@test_ignored = 0
end
def set_xml_output
@xml_out = true
end
def write_xml_output
output = File.open('report.xml', 'w')
output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
@array_list.each do |item|
output << item << "\n"
end
end
def push_xml_output_suite_info
heading = '<testsuite name="Unity" tests="' + @total_tests.to_s + '" failures="' + @test_failed.to_s + '"' + ' skips="' + @test_ignored.to_s + '">'
@array_list.insert(0, heading)
@array_list.push '</testsuite>'
end
def push_xml_output_passed(test_name)
@array_list.push ' <testcase classname="' + @test_suite + '" name="' + test_name + '"/>'
end
def push_xml_output_failed(test_name, reason)
@array_list.push ' <testcase classname="' + @test_suite + '" name="' + test_name + '">'
@array_list.push ' <failure type="ASSERT FAILED">' + reason + '</failure>'
@array_list.push ' </testcase>'
end
def push_xml_output_ignored(test_name, reason)
@array_list.push ' <testcase classname="' + @test_suite + '" name="' + test_name + '">'
@array_list.push ' <skipped type="TEST IGNORED">' + reason + '</skipped>'
@array_list.push ' </testcase>'
end
def test_suite_verify(test_suite_name)
test_name = test_suite_name.split(@path_delim)
base_name = test_name[test_name.size - 1].split('.')[0]
return unless base_name.to_s != @test_suite.to_s
@test_suite = base_name
printf "New Test: %s\n", @test_suite
end
def prepare_fixture_line(line)
line = line.sub('IGNORE_TEST(', '')
line = line.sub('TEST(', '')
line = line.sub(')', ',')
line = line.chomp
array = line.split(',')
array.map { |x| x.to_s.lstrip.chomp }
end
def test_passed_unity_fixture(array)
class_name = array[0]
test_name = array[1]
test_suite_verify(class_name)
printf "%-40s PASS\n", test_name
push_xml_output_passed(test_name) if @xml_out
end
def test_failed_unity_fixture(array)
class_name = array[0]
test_name = array[1]
test_suite_verify(class_name)
reason_array = array[2].split(':')
reason = reason_array[-1].lstrip.chomp + ' at line: ' + reason_array[-4]
printf "%-40s FAILED\n", test_name
push_xml_output_failed(test_name, reason) if @xml_out
end
def test_ignored_unity_fixture(array)
class_name = array[0]
test_name = array[1]
reason = 'No reason given'
if array.size > 2
reason_array = array[2].split(':')
tmp_reason = reason_array[-1].lstrip.chomp
reason = tmp_reason == 'IGNORE' ? 'No reason given' : tmp_reason
end
test_suite_verify(class_name)
printf "%-40s IGNORED\n", test_name
push_xml_output_ignored(test_name, reason) if @xml_out
end
def test_passed(array)
last_item = array.length - 1
test_name = array[last_item - 1]
test_suite_verify(array[@class_name_idx])
printf "%-40s PASS\n", test_name
return unless @xml_out
push_xml_output_passed(test_name) if @xml_out
end
def test_failed(array)
last_item = array.length - 1
test_name = array[last_item - 2]
reason = array[last_item].chomp.lstrip + ' at line: ' + array[last_item - 3]
class_name = array[@class_name_idx]
if test_name.start_with? 'TEST('
array2 = test_name.split(' ')
test_suite = array2[0].sub('TEST(', '')
test_suite = test_suite.sub(',', '')
class_name = test_suite
test_name = array2[1].sub(')', '')
end
test_suite_verify(class_name)
printf "%-40s FAILED\n", test_name
push_xml_output_failed(test_name, reason) if @xml_out
end
def test_ignored(array)
last_item = array.length - 1
test_name = array[last_item - 2]
reason = array[last_item].chomp.lstrip
class_name = array[@class_name_idx]
if test_name.start_with? 'TEST('
array2 = test_name.split(' ')
test_suite = array2[0].sub('TEST(', '')
test_suite = test_suite.sub(',', '')
class_name = test_suite
test_name = array2[1].sub(')', '')
end
test_suite_verify(class_name)
printf "%-40s IGNORED\n", test_name
push_xml_output_ignored(test_name, reason) if @xml_out
end
def detect_os_specifics(line)
if line.include? '\\'
@class_name_idx = 1
@path_delim = '\\'
else
@class_name_idx = 0
@path_delim = '/'
end
end
def process(file_name)
@array_list = []
puts 'Parsing file: ' + file_name
@test_passed = 0
@test_failed = 0
@test_ignored = 0
puts ''
puts '=================== RESULTS ====================='
puts ''
File.open(file_name).each do |line|
detect_os_specifics(line)
line_array = line.split(':')
next unless (line_array.size >= 4) || (line.start_with? 'TEST(') || (line.start_with? 'IGNORE_TEST(')
if (line.start_with? 'TEST(') || (line.start_with? 'IGNORE_TEST(')
line_array = prepare_fixture_line(line)
if line.include? ' PASS'
test_passed_unity_fixture(line_array)
@test_passed += 1
elsif line.include? 'FAIL'
test_failed_unity_fixture(line_array)
@test_failed += 1
elsif line.include? 'IGNORE'
test_ignored_unity_fixture(line_array)
@test_ignored += 1
end
elsif line.include? ':PASS'
test_passed(line_array)
@test_passed += 1
elsif line.include? ':FAIL'
test_failed(line_array)
@test_failed += 1
elsif line.include? ':IGNORE:'
test_ignored(line_array)
@test_ignored += 1
elsif line.include? ':IGNORE'
line_array.push('No reason given')
test_ignored(line_array)
@test_ignored += 1
end
@total_tests = @test_passed + @test_failed + @test_ignored
end
puts ''
puts '=================== SUMMARY ====================='
puts ''
puts 'Tests Passed : ' + @test_passed.to_s
puts 'Tests Failed : ' + @test_failed.to_s
puts 'Tests Ignored : ' + @test_ignored.to_s
return unless @xml_out
push_xml_output_suite_info
write_xml_output
end
end
parse_my_file = ParseOutput.new
if ARGV.size >= 1
ARGV.each do |arg|
if arg == '-xml'
parse_my_file.set_xml_output
else
parse_my_file.process(arg)
break
end
end
end