# Author:: Nicolas Despres . # Copyright:: Copyright (c) 2004, 2005 Uttk team. All rights reserved. # License:: LGPL # $Id: /w/fey/uttk/trunk/lib/uttk/strategies/JUnit.rb 8778 2005-09-26T04:34:48.103938Z ertai $ #FIXME: adapt me #FIXME: remove $debug module Uttk module Strategies # I'm not currently usable, I will be fixed soon. class JUnit < Strategy include Concrete def initialize ( *a, &b ) super @failure = true @output = "" @result = { } end def parse_outcome(line) case line when /^OK \((\d+) test(s|)\)$/ @result['total tests'] = $1.to_i @failure = false when /^FAILURES!!!$/ line = next_line if line =~ /^Tests run: (\d+), Failures: (\d+), Errors: (\d+)$/ then @result['total tests'] = $1.to_i @result['total failures'] = $2.to_i @result['total errors' ] = $3.to_i end else @result['outcome'] = "not found" if $debug >= 1 end next_line end protected :parse_outcome def parse_location(test_name, line) location = [] i = 0 while line =~ /^\t(at.+\))$/ location[i] = $1 i += 1 line = next_line end if location.length != 0 then @result[test_name].update({ 'location' => location }) else @result[test_name].update({ 'location' => 'not found' }) if $debug >= 1 end line end protected :parse_location def parse_failures(line) if line =~ /^There (was|were) \d+ failure(s|):$/ then line = next_line while line =~ /(\d)+\) (\w+)\(([\w.]+)\)junit.framework.(\w+): expected:<(.*)> but was:<(.*)>$/ @result["failure #$1"] = {'name' => $3 + "." + $2, 'reason' => $4, 'expected' => $5, 'was' => $6 } line = parse_location("failure #$1", next_line) end else @result['failures'] = "not found" if $debug >= 1 end line end protected :parse_failures def parse_errors(line) if line =~ /^There (was|were) \d+ error(s|):$/ then line = next_line while line =~ /(\d)+\) (\w+)\(([\w.]+)\)([.\w]+)$/ @result["error #$1"] = {'name' => $3 + "." + $2, 'reason' => $4 } line = parse_location("error #$1", next_line) end else @result['errors'] = "not found" if $debug >= 1 end line end protected :parse_errors def parse_time(line) if line =~ /^Time: ([\d.]+)$/ then @result['time'] = $1.to_f else @result['time'] = "not found" if $debug >= 1 end next_line end protected :parse_time def assert_line(line, re) if not line =~ re raise(Failure, "cannot recognized JUnit output '#{line}'.") end next_line end protected :assert_line def parse_output(line) line = assert_line(line, /^[.FE]*$/) line = parse_time(line) line = parse_errors(line) line = parse_failures(line) line = assert_line(line, /^$/) line = parse_outcome(line) line = assert_line(line, /^$/) end protected :parse_output def next_line line = @output.gets line.chomp unless line.nil? end protected :next_line def check_workdir if not File.exist?(@workdir) then raise Failure, "the work dir '#{workdir}' doesn't exist." elsif not File.directory?(@workdir) then raise Failure, "the work dir '#{workdir}' is not a directory." elsif not File.readable?(@workdir) then raise Failure, "the work dir '#{workdir}' isn unreadable." end end protected :check_workdir def check_testclasses_validity @testclasses.gsub!(/\.class(\s+|$)/, ' ') @testclasses.chomp!(' ') testclasses_tbl = @testclasses.split(/\s+/) if testclasses_tbl.length == 0 then raise Failure, "no testclass are specified." end testclasses_tbl.each do |x| filename = @workdir + "/" + x.gsub(/\./, '/') + ".class" if not File.exist?(filename) then raise Failure, "the testclass '#{filename}' doesn't exist." elsif not File.file?(filename) then raise Failure, "the testclass '#{filename}' is not a regular file." elsif not File.readable?(filename) then raise Failure, "the testclass '#{filename}' is unreadable." end end end protected :check_testclasses_validity def prologue super check_workdir check_testclasses_validity @old_classpath = ENV['CLASSPATH']; ENV['CLASSPATH'] = "" if ENV['CLASSPATH'].nil? ENV['CLASSPATH'] += ':/usr/share/java/junit.jar:.' @old_workdir = Dir.pwd Dir.chdir(@workdir) @log['real working dir is'] = Dir.pwd if $debug >= 1 end protected :prologue def run_impl @output = IO.popen("java junit.textui.TestRunner #@testclasses") parse_output(next_line) @output.close end protected :run_impl def assertion @failure ? fail : pass end protected :assertion def epilogue ENV['CLASSPATH'] = @old_classpath Dir.chdir(@old_workdir) print_result super end protected :epilogue def print_result @result.sort.each { |k,v| @log[k] = v } end protected :print_result attribute :testclasses, 'the name of the JUnit classes to test', "", :mandatory attribute :workdir, 'the working directory where java is runned', '.' attribute :options, 'extra options to pass to java', '' end # class JUnit end # module Strategies end # module Uttk