Permalink
Browse files

- Prepare for 1.2 release

git-svn-id: http://svn.caldersphere.net/svn/main/rubyforge/ci_reporter/trunk@75 b03c2d0b-2f10-0410-a2f9-fc8001506dfa
  • Loading branch information...
1 parent ad7a2ef commit 582f9f121cea65bd484dcfd9f91ab5735c880cca @nicksieger nicksieger committed Mar 26, 2007
Showing with 99 additions and 6 deletions.
  1. +2 −0 History.txt
  2. +2 −6 README.txt
  3. +42 −0 lib/ci/reporter/test_suite.rb
  4. +53 −0 spec/ci/reporter/output_capture_spec.rb
View
@@ -1,5 +1,7 @@
== 1.2
+- Capture standard output and standard error during each individual test suite and include in the XML file in system-out and system-err elements, respectively. [Tracker #9054]
+
== 1.1
- Add +assertions+ attribute to the +testsuite+ element that will contain per-suite assertion counts when used with Test::Unit. Not useful with applications that read Ant/JUnit XML, but custom applications may wish to access it.
View
@@ -1,16 +1,12 @@
-CI::Reporter is an add-on to Test::Unit and RSpec that allows you to generate
-XML reports of your test and/or spec runs. The resulting files can be read by
-a continuous integration system that understands Ant's JUnit report XML
-format, thus allowing your CI system to track test/spec successes and
-failures.
+CI::Reporter is an add-on to Test::Unit and RSpec that allows you to generate XML reports of your test and/or spec runs. The resulting files can be read by a continuous integration system that understands Ant's JUnit report XML format, thus allowing your CI system to track test/spec successes and failures.
== Dependencies
CI::Reporter has one required dependency on Builder, but since many will have a viable version of Builder via Rails' ActiveSupport gem, Builder is not a direct dependency of the project at the moment. Instead, ensure that you have either the +builder+ or +activesupport+ gem installed before continuing.
== Installation
-CI::Reporter is available as a gem. To install the gem, use the usual gem command:
+CI::Reporter is available as a gem. To install the gem, use the usual gem command:
gem install ci_reporter
@@ -1,8 +1,40 @@
+require 'delegate'
+require 'stringio'
+
module CI
module Reporter
+ # Emulates/delegates IO to $stdout or $stderr in order to capture output to report in the XML file.
+ class OutputCapture < DelegateClass(IO)
+ # Start capturing IO, using the given block to assign self to the proper IO global.
+ def initialize(io, &assign)
+ super
+ @delegate_io = io
+ @captured_io = StringIO.new
+ @assign_block = assign
+ @assign_block.call self
+ end
+
+ # Finalize the capture and reset to the original IO object.
+ def finish
+ @assign_block.call @delegate_io
+ @captured_io.string
+ end
+
+ # setup tee methods
+ %w(<< print printf putc puts write).each do |m|
+ module_eval(<<-EOS, __FILE__, __LINE__)
+ def #{m}(*args, &block)
+ @delegate_io.send(:#{m}, *args, &block)
+ @captured_io.send(:#{m}, *args, &block)
+ end
+ EOS
+ end
+ end
+
# Basic structure representing the running of a test suite. Used to time tests and store results.
class TestSuite < Struct.new(:name, :tests, :time, :failures, :errors, :assertions)
attr_accessor :testcases
+ attr_accessor :stdout, :stderr
def initialize(name)
super
@testcases = []
@@ -11,6 +43,8 @@ def initialize(name)
# Starts timing the test suite.
def start
@start = Time.now
+ @capture_out = OutputCapture.new($stdout) {|io| $stdout = io }
+ @capture_err = OutputCapture.new($stderr) {|io| $stderr = io }
end
# Finishes timing the test suite.
@@ -19,6 +53,8 @@ def finish
self.time = Time.now - @start
self.failures = testcases.select {|tc| tc.failure? }.size
self.errors = testcases.select {|tc| tc.error? }.size
+ self.stdout = @capture_out.finish
+ self.stderr = @capture_err.finish
end
# Creates the xml builder instance used to create the report xml document.
@@ -58,6 +94,12 @@ def builder.trunc!(txt)
@testcases.each do |tc|
tc.to_xml(builder)
end
+ builder.tag! "system-out" do
+ builder.cdata! self.stdout
+ end
+ builder.tag! "system-err" do
+ builder.cdata! self.stderr
+ end
end
end
end
@@ -0,0 +1,53 @@
+require File.dirname(__FILE__) + "/../../spec_helper.rb"
+require 'rexml/document'
+
+context "Output capture" do
+ setup do
+ @suite = CI::Reporter::TestSuite.new "test"
+ end
+
+ specify "should save stdout and stderr messages written during the test run" do
+ @suite.start
+ puts "Hello"
+ $stderr.print "Hi"
+ @suite.finish
+ @suite.stdout.should == "Hello\n"
+ @suite.stderr.should == "Hi"
+ end
+
+ specify "should include system-out and system-err elements in the xml output" do
+ @suite.start
+ puts "Hello"
+ $stderr.print "Hi"
+ @suite.finish
+
+ root = REXML::Document.new(@suite.to_xml).root
+ root.elements.to_a('//system-out').length.should == 1
+ root.elements.to_a('//system-err').length.should == 1
+ root.elements.to_a('//system-out').first.cdatas.first.to_s.should == "Hello\n"
+ root.elements.to_a('//system-err').first.cdatas.first.to_s.should == "Hi"
+ end
+
+ specify "should return $stdout and $stderr to original value after finish" do
+ out, err = $stdout, $stderr
+ @suite.start
+ $stdout.object_id.should_not == out.object_id
+ $stderr.object_id.should_not == err.object_id
+ @suite.finish
+ $stdout.object_id.should == out.object_id
+ $stderr.object_id.should == err.object_id
+ end
+
+ specify "should capture only during run of owner test suite" do
+ $stdout.print "A"
+ $stderr.print "A"
+ @suite.start
+ $stdout.print "B"
+ $stderr.print "B"
+ @suite.finish
+ $stdout.print "C"
+ $stderr.print "C"
+ @suite.stdout.should == "B"
+ @suite.stderr.should == "B"
+ end
+end

0 comments on commit 582f9f1

Please sign in to comment.