diff --git a/auto/parse_output.rb b/auto/parse_output.rb index d72c6e8..864104b 100644 --- a/auto/parse_output.rb +++ b/auto/parse_output.rb @@ -14,10 +14,14 @@ # - normal output (raw unity) # - fixture output (unity_fixture.h/.c) # - fixture output with verbose flag set ("-v") +# - time output flag set (UNITY_INCLUDE_EXEC_TIME define enabled with milliseconds output) # # To use this parser use the following command # ruby parseOutput.rb [options] [file] # options: -xml : produce a JUnit compatible XML file +# -suiteRequiredSuiteName +# : replace default test suite name to +# "RequiredSuiteName" (can be any name) # file: file to scan for results #============================================================ @@ -26,6 +30,7 @@ class ParseOutput def initialize # internal data @class_name_idx = 0 + @result_usual_idx = 3 @path_delim = nil # xml output related @@ -33,6 +38,9 @@ class ParseOutput @array_list = false # current suite name and statistics + ## testsuite name + @real_test_suite_name = 'Unity' + ## classname for testcase @test_suite = nil @total_tests = 0 @test_passed = 0 @@ -45,6 +53,16 @@ class ParseOutput @xml_out = true end + # Set the flag to indicate if there will be an XML output file or not + def test_suite_name=(cli_arg) + @real_test_suite_name = cli_arg + puts 'Real test suite name will be \'' + @real_test_suite_name + '\'' + end + + def xml_encode_s(str) + str.encode(:xml => :attr) + end + # If write our output to XML def write_xml_output output = File.open('report.xml', 'w') @@ -57,27 +75,27 @@ class ParseOutput # Pushes the suite info as xml to the array list, which will be written later def push_xml_output_suite_info # Insert opening tag at front - heading = '' + heading = '' @array_list.insert(0, heading) # Push back the closing tag @array_list.push '' end # Pushes xml output data to the array list, which will be written later - def push_xml_output_passed(test_name) - @array_list.push ' ' + def push_xml_output_passed(test_name, execution_time = 0) + @array_list.push ' ' end # Pushes xml output data to the array list, which will be written later - def push_xml_output_failed(test_name, reason) - @array_list.push ' ' + def push_xml_output_failed(test_name, reason, execution_time = 0) + @array_list.push ' ' @array_list.push ' ' + reason + '' @array_list.push ' ' end # Pushes xml output data to the array list, which will be written later - def push_xml_output_ignored(test_name, reason) - @array_list.push ' ' + def push_xml_output_ignored(test_name, reason, execution_time = 0) + @array_list.push ' ' @array_list.push ' ' + reason + '' @array_list.push ' ' end @@ -152,19 +170,29 @@ class ParseOutput # Test was flagged as having passed so format the output def test_passed(array) + # ':' symbol will be valid in function args now + real_method_name = array[@result_usual_idx - 1..-2].join(':') + array = array[0..@result_usual_idx - 2] + [real_method_name] + [array[-1]] + last_item = array.length - 1 + test_time = get_test_time(array[last_item]) test_name = array[last_item - 1] test_suite_verify(array[@class_name_idx]) - printf "%-40s PASS\n", test_name + printf "%-40s PASS %10d ms\n", test_name, test_time return unless @xml_out - push_xml_output_passed(test_name) if @xml_out + push_xml_output_passed(test_name, test_time) if @xml_out end # Test was flagged as having failed so format the line def test_failed(array) + # ':' symbol will be valid in function args now + real_method_name = array[@result_usual_idx - 1..-3].join(':') + array = array[0..@result_usual_idx - 3] + [real_method_name] + array[-2..-1] + last_item = array.length - 1 + test_time = get_test_time(array[last_item]) test_name = array[last_item - 2] reason = array[last_item].chomp.lstrip + ' at line: ' + array[last_item - 3] class_name = array[@class_name_idx] @@ -180,14 +208,19 @@ class ParseOutput end test_suite_verify(class_name) - printf "%-40s FAILED\n", test_name + printf "%-40s FAILED %10d ms\n", test_name, test_time - push_xml_output_failed(test_name, reason) if @xml_out + push_xml_output_failed(test_name, reason, test_time) if @xml_out end # Test was flagged as being ignored so format the output def test_ignored(array) + # ':' symbol will be valid in function args now + real_method_name = array[@result_usual_idx - 1..-3].join(':') + array = array[0..@result_usual_idx - 3] + [real_method_name] + array[-2..-1] + last_item = array.length - 1 + test_time = get_test_time(array[last_item]) test_name = array[last_item - 2] reason = array[last_item].chomp.lstrip class_name = array[@class_name_idx] @@ -203,9 +236,18 @@ class ParseOutput end test_suite_verify(class_name) - printf "%-40s IGNORED\n", test_name + printf "%-40s IGNORED %10d ms\n", test_name, test_time - push_xml_output_ignored(test_name, reason) if @xml_out + push_xml_output_ignored(test_name, reason, test_time) if @xml_out + end + + # Test time will be in ms + def get_test_time(value_with_time) + test_time_array = value_with_time.scan(/\((-?\d+.?\d*) ms\)\s*$/).flatten.map do |arg_value_str| + arg_value_str.include?('.') ? arg_value_str.to_f : arg_value_str.to_i + end + + test_time_array.any? ? test_time_array[0] : 0 end # Adjusts the os specific members according to the current path style @@ -234,7 +276,8 @@ class ParseOutput puts '' puts '=================== RESULTS =====================' puts '' - File.open(file_name).each do |line| + # Apply binary encoding. Bad symbols will be unchanged + File.open(file_name, 'rb').each do |line| # Typical test lines look like these: # ---------------------------------------------------- # 1. normal output: @@ -288,6 +331,22 @@ class ParseOutput line_array.push('No reason given') test_ignored(line_array) @test_ignored += 1 + elsif line_array.size >= 4 + # We will check output from color compilation + if line_array[@result_usual_idx..-1].any? { |l| l.include? 'PASS' } + test_passed(line_array) + @test_passed += 1 + elsif line_array[@result_usual_idx..-1].any? { |l| l.include? 'FAIL' } + test_failed(line_array) + @test_failed += 1 + elsif line_array[@result_usual_idx..-2].any? { |l| l.include? 'IGNORE' } + test_ignored(line_array) + @test_ignored += 1 + elsif line_array[@result_usual_idx..-1].any? { |l| l.include? 'IGNORE' } + line_array.push('No reason given (' + get_test_time(line_array[@result_usual_idx..-1]).to_s + ' ms)') + test_ignored(line_array) + @test_ignored += 1 + end end @total_tests = @test_passed + @test_failed + @test_ignored end @@ -314,6 +373,8 @@ if ARGV.size >= 1 ARGV.each do |arg| if arg == '-xml' parse_my_file.set_xml_output + elsif arg.start_with?('-suite') + parse_my_file.test_suite_name = arg.delete_prefix('-suite') else parse_my_file.process(arg) break