1284990Scy# ========================================== 2284990Scy# Unity Project - A Test Framework for C 3284990Scy# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams 4284990Scy# [Released under MIT License. Please refer to license.txt for details] 5289764Sglebius# ========================================== 6284990Scy 7284990Scy#!/usr/bin/ruby 8284990Scy# 9284990Scy# unity_test_summary.rb 10284990Scy# 11284990Scyrequire 'fileutils' 12284990Scyrequire 'set' 13284990Scy 14284990Scyclass UnityTestSummary 15284990Scy include FileUtils::Verbose 16284990Scy 17284990Scy attr_reader :report, :total_tests, :failures, :ignored 18289764Sglebius 19289764Sglebius def initialize(opts = {}) 20284990Scy @report = '' 21284990Scy @total_tests = 0 22284990Scy @failures = 0 23284990Scy @ignored = 0 24289764Sglebius 25289764Sglebius 26284990Scy end 27289764Sglebius 28284990Scy def run 29284990Scy # Clean up result file names 30284990Scy results = @targets.map {|target| target.gsub(/\\/,'/')} 31289764Sglebius 32289764Sglebius # Dig through each result file, looking for details on pass/fail: 33284990Scy failure_output = [] 34284990Scy ignore_output = [] 35289764Sglebius 36284990Scy results.each do |result_file| 37284990Scy lines = File.readlines(result_file).map { |line| line.chomp } 38284990Scy if lines.length == 0 39284990Scy raise "Empty test result file: #{result_file}" 40284990Scy else 41284990Scy output = get_details(result_file, lines) 42284990Scy failure_output << output[:failures] unless output[:failures].empty? 43284990Scy ignore_output << output[:ignores] unless output[:ignores].empty? 44284990Scy tests,failures,ignored = parse_test_summary(lines) 45284990Scy @total_tests += tests 46284990Scy @failures += failures 47284990Scy @ignored += ignored 48284990Scy end 49284990Scy end 50289764Sglebius 51284990Scy if @ignored > 0 52284990Scy @report += "\n" 53284990Scy @report += "--------------------------\n" 54284990Scy @report += "UNITY IGNORED TEST SUMMARY\n" 55284990Scy @report += "--------------------------\n" 56284990Scy @report += ignore_output.flatten.join("\n") 57284990Scy end 58289764Sglebius 59284990Scy if @failures > 0 60284990Scy @report += "\n" 61284990Scy @report += "--------------------------\n" 62284990Scy @report += "UNITY FAILED TEST SUMMARY\n" 63284990Scy @report += "--------------------------\n" 64284990Scy @report += failure_output.flatten.join("\n") 65284990Scy end 66289764Sglebius 67284990Scy @report += "\n" 68284990Scy @report += "--------------------------\n" 69284990Scy @report += "OVERALL UNITY TEST SUMMARY\n" 70284990Scy @report += "--------------------------\n" 71284990Scy @report += "#{@total_tests} TOTAL TESTS #{@failures} TOTAL FAILURES #{@ignored} IGNORED\n" 72284990Scy @report += "\n" 73284990Scy end 74289764Sglebius 75284990Scy def set_targets(target_array) 76284990Scy @targets = target_array 77284990Scy end 78289764Sglebius 79284990Scy def set_root_path(path) 80284990Scy @root = path 81284990Scy end 82284990Scy 83284990Scy def usage(err_msg=nil) 84289764Sglebius puts "\nERROR: " 85284990Scy puts err_msg if err_msg 86289764Sglebius puts "\nUsage: unity_test_summary.rb result_file_directory/ root_path/" 87289764Sglebius puts " result_file_directory - The location of your results files." 88289764Sglebius puts " Defaults to current directory if not specified." 89289764Sglebius puts " Should end in / if specified." 90289764Sglebius puts " root_path - Helpful for producing more verbose output if using relative paths." 91284990Scy exit 1 92284990Scy end 93289764Sglebius 94284990Scy protected 95284990Scy 96284990Scy def get_details(result_file, lines) 97284990Scy results = { :failures => [], :ignores => [], :successes => [] } 98284990Scy lines.each do |line| 99284990Scy src_file,src_line,test_name,status,msg = line.split(/:/) 100289764Sglebius line_out = ((@root && (@root != 0)) ? "#{@root}#{line}" : line ).gsub(/\//, "\\") 101284990Scy case(status) 102284990Scy when 'IGNORE' then results[:ignores] << line_out 103284990Scy when 'FAIL' then results[:failures] << line_out 104284990Scy when 'PASS' then results[:successes] << line_out 105284990Scy end 106284990Scy end 107284990Scy return results 108284990Scy end 109289764Sglebius 110284990Scy def parse_test_summary(summary) 111289764Sglebius if summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ } 112284990Scy [$1.to_i,$2.to_i,$3.to_i] 113284990Scy else 114284990Scy raise "Couldn't parse test results: #{summary}" 115284990Scy end 116284990Scy end 117284990Scy 118284990Scy def here; File.expand_path(File.dirname(__FILE__)); end 119289764Sglebius 120284990Scyend 121284990Scy 122284990Scyif $0 == __FILE__ 123289764Sglebius 124289764Sglebius #parse out the command options 125289764Sglebius opts, args = ARGV.partition {|v| v =~ /^--\w+/} 126289764Sglebius opts.map! {|v| v[2..-1].to_sym } 127289764Sglebius 128289764Sglebius #create an instance to work with 129289764Sglebius uts = UnityTestSummary.new(opts) 130289764Sglebius 131284990Scy begin 132289764Sglebius #look in the specified or current directory for result files 133289764Sglebius args[0] ||= './' 134289764Sglebius targets = "#{ARGV[0].gsub(/\\/, '/')}**/*.test*" 135289764Sglebius results = Dir[targets] 136289764Sglebius raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty? 137289764Sglebius uts.set_targets(results) 138289764Sglebius 139289764Sglebius #set the root path 140289764Sglebius args[1] ||= Dir.pwd + '/' 141289764Sglebius uts.set_root_path(ARGV[1]) 142289764Sglebius 143289764Sglebius #run the summarizer 144289764Sglebius puts uts.run 145284990Scy rescue Exception => e 146289764Sglebius uts.usage e.message 147284990Scy end 148284990Scyend 149289764Sglebius 150