Return-Path: Delivered-To: apmail-buildr-commits-archive@www.apache.org Received: (qmail 16602 invoked from network); 3 Dec 2010 21:04:45 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 3 Dec 2010 21:04:45 -0000 Received: (qmail 512 invoked by uid 500); 3 Dec 2010 21:04:45 -0000 Delivered-To: apmail-buildr-commits-archive@buildr.apache.org Received: (qmail 493 invoked by uid 500); 3 Dec 2010 21:04:45 -0000 Mailing-List: contact commits-help@buildr.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@buildr.apache.org Delivered-To: mailing list commits@buildr.apache.org Received: (qmail 486 invoked by uid 99); 3 Dec 2010 21:04:43 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 03 Dec 2010 21:04:43 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 03 Dec 2010 21:04:40 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 7B80F238897D; Fri, 3 Dec 2010 21:03:07 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1041999 - /buildr/trunk/lib/buildr/java/jtestr_result.rb Date: Fri, 03 Dec 2010 21:03:07 -0000 To: commits@buildr.apache.org From: boisvert@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20101203210307.7B80F238897D@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: boisvert Date: Fri Dec 3 21:03:07 2010 New Revision: 1041999 URL: http://svn.apache.org/viewvc?rev=1041999&view=rev Log: Straggler from "JtestR specs now passing" commit (r1039804) Added: buildr/trunk/lib/buildr/java/jtestr_result.rb Added: buildr/trunk/lib/buildr/java/jtestr_result.rb URL: http://svn.apache.org/viewvc/buildr/trunk/lib/buildr/java/jtestr_result.rb?rev=1041999&view=auto ============================================================================== --- buildr/trunk/lib/buildr/java/jtestr_result.rb (added) +++ buildr/trunk/lib/buildr/java/jtestr_result.rb Fri Dec 3 21:03:07 2010 @@ -0,0 +1,295 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with this +# work for additional information regarding copyright ownership. The ASF +# licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +# necessary to require YAML even if it is mentioned by autoload as it fails on some platforms. +require 'yaml' +require 'fileutils' + +module Buildr #:nodoc: + + module JtestR + + # An Rspec formatter used by JtestR + class YamlFormatter + attr_reader :result + + attr_accessor :example_group, :options, :where + + def initialize(options, where) + @options = options + @where = where + end + + %w[ example_started + start_dump dump_failure dump_summary dump_pending ].each do |meth| + module_eval "def #{meth}(*args); end" + end + + def example_group_started(example_group) + @example_group = example_group + end + + def example_passed(example) + result.succeeded << example_name(example) + end + + def example_pending(example, counter) + result.succeeded << example_name(example) + end + + def example_failed(example, counter, failure) + result.failed << example_name(example) + end + + def start(example_count) + @result = Buildr::TestFramework::TestResult.new + end + + def close + result.succeeded = result.succeeded - result.failed + FileUtils.mkdir_p File.dirname(where) + File.open(where, 'w') { |f| f.puts YAML.dump(result) } + end + + private + def example_name(example) + if Spec::Example::ExampleProxy === example + example_group.location.gsub(/:\d+$/, '') + else + example.name.gsub(/(.+)(\..+\(\))/, '\1') + end + end + end # YamlFormatter + + # A JtestR ResultHandler + # Using this handler we can use RSpec formatters, like html/ci_reporter with JtestR + # Created for JTestrYamlFormatter + class ResultHandler + + # Workaround for http://jira.codehaus.org/browse/JTESTR-68 + module TestNGResultHandlerMixin + def onTestSuccess(test_result) + @result_handler.succeed_single(test_result.name) + end + end + + class BacktraceTweaker + attr_reader :ignore_patterns + def initialize + @ignore_patterns = ::Spec::Runner::QuietBacktraceTweaker::IGNORE_PATTERNS.dup + # ignore jruby/jtestr backtrace + ignore_patterns << /org\.jruby\.javasupport\.JavaMethod\./ + ignore_patterns << /jtestr.*\.jar!/i << /runner\.rb/ + end + + def clean_up_double_slashes(line) + line.gsub!('//','/') + end + + def tweak_backtrace(error) + return if error.backtrace.nil? + error.backtrace.collect! do |line| + clean_up_double_slashes(line) + ignore_patterns.each do |ignore| + if line =~ ignore + line = nil + break + end + end + line + end + error.backtrace.compact! + end + end + + class << self + # an rspec reporter used to proxy events to rspec formatters + attr_reader :reporter + attr_accessor :test_files + + def init(argv = [], out = STDOUT, err = STDERR) + ::JtestR::TestNGResultHandler.module_eval { include TestNGResultHandlerMixin } + rspec_parser = ::Spec::Runner::OptionParser.new(err, out) + rspec_parser.order!(argv) + rspec_parser.options.backtrace_tweaker = BacktraceTweaker.new + @reporter = Spec::Runner::Reporter.new(rspec_parser.options) + end + + def before + reporter.start(reporter.options.files.size) + end + + def after + reporter.end + reporter.dump + end + + end + + module ExampleMethods + attr_accessor :name, :description, :__full_description, :location + end + + def reporter + self.class.reporter + end + + attr_accessor :example_group, :current_example, :current_failure + + def initialize(name, desc, *args) + self.example_group = ::Spec::Example::ExampleGroup.new(desc) + example_group.extend ExampleMethods + example_group.name = name.to_s + if example_group.name[/Spec/] + example_group.description = desc.to_s + else + example_group.description = name.to_s + end + reporter.example_group_started(example_group) + end + + + def starting + end + + def ending + end + + def add_fault(fault) + self.current_failure = fault + end + + def add_pending(pending) + end + + def starting_single(name = nil) + self.current_failure = nil + self.current_example = Object.new + current_example.extend ::Spec::Example::ExampleMethods + current_example.extend ExampleMethods + name = name.to_s + current_example.location = name.to_s + current_example.name = name.gsub(/(.*)\((.+)\)/, '\2') + current_example.description = name + if example_group.name[/Spec/] + current_example.__full_description = "#{example_group.description} #{name}" + else + current_example.__full_description = "#{example_group.name}: #{name}" + end + reporter.example_started(current_example) + end + + def succeed_single(name = nil) + reporter.example_finished(current_example, nil) + end + + def fail_single(name = nil) + current_example.name = current_name + reporter.example_finished(current_example, current_error) + end + + def error_single(name = nil) + current_example.name = current_name + reporter.example_finished(current_example, current_error) + end + + def pending_single(name = nil) + error = ::Spec::Example::ExamplePendingError.new(name) + reporter.example_finished(current_example, error) + end + + private + def detect_file(trace) + # find first matching test file in stacktrace + file = nil + first_pos = nil + ResultHandler.test_files.each do |f| + pos = trace.index(f) + if pos && (first_pos.nil? || pos < first_pos) + file = f + first_pos = pos + end + end + file || fail("JTestR::ResultHandler.detect_file failed: #{trace}") + end + + def current_name(example = current_example, fault = current_failure) + return example.name unless fault + case fault + when Test::Unit::Error + detect_file(fault.long_display) + when Test::Unit::Failure + detect_file(fault.location.to_s) + when Spec::Runner::Reporter::Failure + detect_file(fault.exception.backtrace.to_s) + else + example.name + end + end + + def current_error(fault = current_failure) + case fault + when nil + nil + when Test::Unit::Failure + Buildr::TestFramework::TestResult::Error.new(fault.message, fault.location) + when Test::Unit::Error + if fault.exception.is_a?(NativeException) + exception = fault.exception.cause + bt = exception.stack_trace.to_a + else + exception = fault.exception + bt = exception.backtrace + end + Buildr::TestFramework::TestResult::Error.new(exception.message, bt) + when Expectations::Results::Error + fault.exception + when Spec::Runner::Reporter::Failure + ex = fault.exception + Buildr::TestFramework::TestResult::Error.new(ex.message, ex.backtrace) + when Expectations::Results + file = fault.file + line = fault.line + Buildr::TestFramework::TestResult::Error.new(fault.message, ["#{fault.file}:#{fault.line}"]) + else + if fault.respond_to?(:test_header) + fault.test_header[/\((.+)\)/] + test_cls, test_meth = $1.to_s, $`.to_s + exception = fault.exception + (class << exception; self; end).module_eval do + define_method(:backtrace) do + (["#{test_cls}:in `#{test_meth}'"] + stackTrace).map { |s| s.to_s } + end + end + exception + elsif fault.respond_to?(:method) + test_cls, test_meth = fault.method.test_class.name, fault.method.method_name + exception = fault.throwable + (class << exception; self; end).module_eval do + define_method(:backtrace) do + (["#{test_cls}:in `#{test_meth}'"] + stackTrace).map { |s| s.to_s } + end + end + exception + else + raise "Cannot handle fault #{fault.class}: #{fault.inspect}" + end + end + end + + end # ResultHandler + end +end +