// NAnt - A .NET build tool
// Copyright (C) 2001-2002 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// Ian MacLean (ian_maclean@another.com)
// Gerry Shaw (gerry_shaw@yahoo.com)
using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;
using NUnit.Framework;
using NAnt.Core.Util;
namespace NAnt.NUnit1.Types {
///
/// Prints detailed information about running tests in XML format.
///
public class XmlResultFormatter : IResultFormatter {
#region Public Instance Constructors
///
/// Initializes a new instance of the
/// class.
///
public XmlResultFormatter() {
_document = new XmlDocument();
}
#endregion Public Instance Constructors
#region Public Instance Properties
public TextWriter Writer {
get { return _writer; }
set { _writer = value; }
}
#endregion Public Instance Properties
#region Implemenation of IResultFormatter
///
/// Sets the the formatter is supposed to
/// write its results to.
///
public void SetOutput(TextWriter writer) {
Writer = writer;
}
///
/// Called when the whole test suite has started.
///
public void StartTestSuite(NUnitTestData suite) {
XmlDeclaration decl = _document.CreateXmlDeclaration("1.0", null, null);
_document.AppendChild(decl);
_suiteElement = _document.CreateElement(ElementTestSuite);
//
// if this is a testsuite, use it's name
//
string suiteName = suite.Suite.ToString();
if (StringUtils.IsNullOrEmpty(suiteName)) {
suiteName = "test";
}
_suiteElement.SetAttribute(AttributeName, suiteName );
}
///
/// Called when the whole test suite has ended.
///
public void EndTestSuite(TestResultExtra result) {
_suiteElement.SetAttribute(AttributeTests , result.RunCount.ToString(NumberFormatInfo.InvariantInfo));
double time = result.RunTime;
time /= 1000D;
_suiteElement.SetAttribute(AttributeTime, time.ToString("#####0.000", NumberFormatInfo.InvariantInfo));
_document.AppendChild(_suiteElement);
_suiteElement.SetAttribute(AttributeErrors , result.ErrorCount.ToString(NumberFormatInfo.InvariantInfo));
_suiteElement.SetAttribute(AttributeFailures , result.FailureCount.ToString(NumberFormatInfo.InvariantInfo));
// Send all output to here
_document.Save(Writer);
Writer.Flush();
Writer.Close();
}
#endregion Implemenation of IResultFormatter
#region Implemenation of ITestListener
public void AddError(ITest test, Exception t) {
FormatError(ElementError, test, t);
}
public void AddFailure(ITest test, AssertionFailedError t) {
FormatError(ElementFailure, test, (Exception)t);
}
public void StartTest(ITest test) {
_testStartTime = DateTime.Now;
_currentTest = _document.CreateElement(ElementTestCase);
_currentTest.SetAttribute(AttributeName, ((TestCase ) test).ToString());
string className = test.GetType().FullName;
_currentTest.SetAttribute(AttributeClassname, className);
_suiteElement.AppendChild(_currentTest);
}
public void EndTest(ITest test) {
TimeSpan elapsedTime = DateTime.Now - _testStartTime;
double time = elapsedTime.Milliseconds;
time /= 1000D;
_currentTest.SetAttribute(AttributeTime, time.ToString("#####0.000", NumberFormatInfo.InvariantInfo));
}
#endregion Implemenation of ITestListener
#region Private Instance Methods
private void FormatError(string type, ITest test, Exception t) {
if (test != null) {
EndTest(test);
}
XmlElement nested = _document.CreateElement(type);
if (test != null) {
_currentTest.AppendChild(nested);
} else {
_suiteElement.AppendChild(nested);
}
string message = t.Message;
if (message != null && message.Length > 0) {
nested.SetAttribute( AttributeMessage, message );
}
nested.SetAttribute(AttributeType, t.GetType().FullName);
XmlText traceElement = _document.CreateTextNode(t.StackTrace);
nested.AppendChild(traceElement);
}
#endregion Private Instance Methods
#region Private Instance Fields
TextWriter _writer;
XmlDocument _document;
XmlElement _suiteElement;
XmlElement _currentTest;
DateTime _testStartTime;
#endregion Private Instance Fields
#region Private Static Fields
const string ElementTestSuite = "testsuite";
const string ElementTestCase = "testcase";
const string ElementError = "error";
const string ElementFailure = "failure";
const string AttributeName = "name";
const string AttributeTime = "time";
const string AttributeErrors = "errors";
const string AttributeFailures = "failures";
const string AttributeTests = "tests";
const string AttributeType = "type";
const string AttributeMessage = "message";
const string AttributeClassname = "classname";
#endregion Private Static Fields
}
}