diff --git a/src/AddIns/Analysis/UnitTesting/Interfaces/IUnitTestProcessRunner.cs b/src/AddIns/Analysis/UnitTesting/Interfaces/IUnitTestProcessRunner.cs
index 9706138701..10a47ab395 100644
--- a/src/AddIns/Analysis/UnitTesting/Interfaces/IUnitTestProcessRunner.cs
+++ b/src/AddIns/Analysis/UnitTesting/Interfaces/IUnitTestProcessRunner.cs
@@ -7,7 +7,7 @@ using ICSharpCode.SharpDevelop.Util;
namespace ICSharpCode.UnitTesting
{
- public interface IUnitTestProcessRunner
+ public interface IUnitTestProcessRunner : IDisposable
{
bool LogStandardOutputAndError { get; set; }
string WorkingDirectory { get; set; }
diff --git a/src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestProcessRunner.cs b/src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestProcessRunner.cs
index 3d60a93130..3467ecd5d8 100644
--- a/src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestProcessRunner.cs
+++ b/src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestProcessRunner.cs
@@ -54,5 +54,10 @@ namespace ICSharpCode.UnitTesting
{
runner.Kill();
}
+
+ public void Dispose()
+ {
+ runner.Dispose();
+ }
}
}
diff --git a/src/AddIns/Analysis/UnitTesting/NUnit/NUnitConsoleApplication.cs b/src/AddIns/Analysis/UnitTesting/NUnit/NUnitConsoleApplication.cs
index 5ae1495847..e9b3a3fc19 100644
--- a/src/AddIns/Analysis/UnitTesting/NUnit/NUnitConsoleApplication.cs
+++ b/src/AddIns/Analysis/UnitTesting/NUnit/NUnitConsoleApplication.cs
@@ -141,9 +141,9 @@ namespace ICSharpCode.UnitTesting
public string Test;
///
- /// File to write test results to.
+ /// Pipe to write test results to.
///
- public string Results;
+ public string ResultsPipe;
///
/// The namespace that tests need to be a part of if they are to
@@ -206,9 +206,9 @@ namespace ICSharpCode.UnitTesting
b.Append(XmlOutputFile);
b.Append('"');
}
- if (Results != null) {
- b.Append(" /results=\"");
- b.Append(Results);
+ if (ResultsPipe != null) {
+ b.Append(" /pipe=\"");
+ b.Append(ResultsPipe);
b.Append('"');
}
string run = null;
diff --git a/src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestDebugger.cs b/src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestDebugger.cs
index d0886ce178..f94a4e8667 100644
--- a/src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestDebugger.cs
+++ b/src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestDebugger.cs
@@ -18,16 +18,16 @@ namespace ICSharpCode.UnitTesting
public NUnitTestDebugger()
: this(new UnitTestDebuggerService(),
SD.MessageService,
- new TestResultsMonitor(),
+ new TestResultsReader(),
UnitTestingOptions.Instance.Clone())
{
}
public NUnitTestDebugger(IUnitTestDebuggerService debuggerService,
IMessageService messageService,
- ITestResultsMonitor testResultsMonitor,
+ ITestResultsReader testResultsReader,
UnitTestingOptions options)
- : base(debuggerService, messageService, testResultsMonitor)
+ : base(debuggerService, messageService, testResultsReader)
{
this.options = options;
}
@@ -35,7 +35,7 @@ namespace ICSharpCode.UnitTesting
protected override ProcessStartInfo GetProcessStartInfo(IEnumerable selectedTests)
{
NUnitConsoleApplication app = new NUnitConsoleApplication(selectedTests, options);
- app.Results = base.TestResultsMonitor.FileName;
+ app.ResultsPipe = base.TestResultsReader.PipeName;
return app.GetProcessStartInfo();
}
@@ -43,5 +43,10 @@ namespace ICSharpCode.UnitTesting
{
return new NUnitTestResult(testResult);
}
+
+ public override int GetExpectedNumberOfTestResults(IEnumerable selectedTests)
+ {
+ return NUnitTestRunner.GetNumberOfTestMethods(selectedTests);
+ }
}
}
diff --git a/src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestRunner.cs b/src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestRunner.cs
index cecc5eb4e4..171de60d4e 100644
--- a/src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestRunner.cs
+++ b/src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestRunner.cs
@@ -30,7 +30,7 @@ namespace ICSharpCode.UnitTesting
protected override ProcessStartInfo GetProcessStartInfo(IEnumerable selectedTests)
{
NUnitConsoleApplication app = new NUnitConsoleApplication(selectedTests, options);
- app.Results = base.TestResultsMonitor.FileName;
+ app.ResultsPipe = base.TestResultsReader.PipeName;
return app.GetProcessStartInfo();
}
@@ -38,5 +38,22 @@ namespace ICSharpCode.UnitTesting
{
return new NUnitTestResult(testResult);
}
+
+ public override int GetExpectedNumberOfTestResults(IEnumerable selectedTests)
+ {
+ return GetNumberOfTestMethods(selectedTests);
+ }
+
+ public static int GetNumberOfTestMethods(IEnumerable selectedTests)
+ {
+ int count = 0;
+ foreach (ITest test in selectedTests) {
+ if (test is NUnitTestMethod)
+ count++;
+ else
+ count += GetNumberOfTestMethods(test.NestedTests);
+ }
+ return count;
+ }
}
}
diff --git a/src/AddIns/Analysis/UnitTesting/Test/NUnit/NUnitConsoleCommandLineTests.cs b/src/AddIns/Analysis/UnitTesting/Test/NUnit/NUnitConsoleCommandLineTests.cs
index 9ea19fbeb0..b90bd4d3f9 100644
--- a/src/AddIns/Analysis/UnitTesting/Test/NUnit/NUnitConsoleCommandLineTests.cs
+++ b/src/AddIns/Analysis/UnitTesting/Test/NUnit/NUnitConsoleCommandLineTests.cs
@@ -38,9 +38,9 @@ namespace UnitTesting.Tests.NUnit
app.NoLogo = false;
app.ShadowCopy = true;
app.NoXmlOutputFile = false;
- app.Results = @"C:\results.txt";
+ app.ResultsPipe = @"C:\results.txt";
- string expectedCommandLine = "\"C:\\Projects\\MyTests\\MyTests.dll\" /results=\"C:\\results.txt\"";
+ string expectedCommandLine = "\"C:\\Projects\\MyTests\\MyTests.dll\" /pipe=\"C:\\results.txt\"";
Assert.AreEqual(expectedCommandLine, app.GetArguments());
}
@@ -229,13 +229,13 @@ namespace UnitTesting.Tests.NUnit
app.Assemblies.Add("SecondAssembly.dll");
app.NoLogo = false;
app.ShadowCopy = true;
- app.Results = @"C:\results.txt";
+ app.ResultsPipe = @"C:\results.txt";
app.NoXmlOutputFile = false;
string expectedCommandLine =
"\"C:\\Projects\\MyTests\\MyTests.dll\" " +
"\"SecondAssembly.dll\" " +
- "/results=\"C:\\results.txt\"";
+ "/pipe=\"C:\\results.txt\"";
Assert.AreEqual(expectedCommandLine, app.GetArguments());
}
diff --git a/src/AddIns/Analysis/UnitTesting/Test/TestRunner/TestResultsReaderTests.cs b/src/AddIns/Analysis/UnitTesting/Test/TestRunner/TestResultsReaderTests.cs
index ddb9204ea9..45ddb56468 100644
--- a/src/AddIns/Analysis/UnitTesting/Test/TestRunner/TestResultsReaderTests.cs
+++ b/src/AddIns/Analysis/UnitTesting/Test/TestRunner/TestResultsReaderTests.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.IO;
using ICSharpCode.UnitTesting;
using NUnit.Framework;
@@ -17,10 +18,12 @@ namespace UnitTesting.Tests.TestRunner
string resultsText = "Name: MyTest\r\n" +
"Result: Success\r\n";
- TestResultsReader reader = new TestResultsReader();
- TestResult[] results = reader.Read(resultsText);
+ TestResultsReader reader = new TestResultsReader(new StringReader(resultsText));
+ List results = new List();
+ reader.TestFinished += (sender, e) => results.Add(e.Result);
+ reader.Run();
- Assert.AreEqual(1, results.Length);
+ Assert.AreEqual(1, results.Count);
TestResult result = results[0];
Assert.AreEqual("MyTest", result.Name);
@@ -34,10 +37,12 @@ namespace UnitTesting.Tests.TestRunner
string resultsText = "Name: MyTest\r\n" +
"Result: Ignored\r\n";
- TestResultsReader reader = new TestResultsReader();
- TestResult[] results = reader.Read(resultsText);
+ TestResultsReader reader = new TestResultsReader(new StringReader(resultsText));
+ List results = new List();
+ reader.TestFinished += (sender, e) => results.Add(e.Result);
+ reader.Run();
- Assert.AreEqual(1, results.Length);
+ Assert.AreEqual(1, results.Count);
TestResult result = results[0];
Assert.AreEqual("MyTest", result.Name);
@@ -45,7 +50,7 @@ namespace UnitTesting.Tests.TestRunner
Assert.IsFalse(result.IsSuccess);
Assert.AreEqual(TestResultType.Ignored, result.ResultType);
}
-
+ /*
[Test]
public void OneTestPassInParts()
{
@@ -70,17 +75,19 @@ namespace UnitTesting.Tests.TestRunner
Assert.AreEqual("MyTest", result.Name);
Assert.IsTrue(result.IsSuccess);
}
-
+ */
[Test]
public void OneTestFailure()
{
string resultsText = "Name: MyTest\r\n" +
"Result: Failure\r\n";
- TestResultsReader reader = new TestResultsReader();
- TestResult[] results = reader.Read(resultsText);
+ TestResultsReader reader = new TestResultsReader(new StringReader(resultsText));
+ List results = new List();
+ reader.TestFinished += (sender, e) => results.Add(e.Result);
+ reader.Run();
- Assert.AreEqual(1, results.Length);
+ Assert.AreEqual(1, results.Count);
TestResult result = results[0];
Assert.AreEqual("MyTest", result.Name);
@@ -97,10 +104,12 @@ namespace UnitTesting.Tests.TestRunner
"Message: Should not be 0.\r\n" +
"Result: Failure\r\n";
- TestResultsReader reader = new TestResultsReader();
- TestResult[] results = reader.Read(resultsText);
+ TestResultsReader reader = new TestResultsReader(new StringReader(resultsText));
+ List results = new List();
+ reader.TestFinished += (sender, e) => results.Add(e.Result);
+ reader.Run();
- Assert.AreEqual(1, results.Length);
+ Assert.AreEqual(1, results.Count);
TestResult result = results[0];
Assert.AreEqual("Test", result.Name);
@@ -115,10 +124,12 @@ namespace UnitTesting.Tests.TestRunner
"StackTrace: stack trace\r\n" +
"Result: Failure\r\n";
- TestResultsReader reader = new TestResultsReader();
- TestResult[] results = reader.Read(resultsText);
+ TestResultsReader reader = new TestResultsReader(new StringReader(resultsText));
+ List results = new List();
+ reader.TestFinished += (sender, e) => results.Add(e.Result);
+ reader.Run();
- Assert.AreEqual(1, results.Length);
+ Assert.AreEqual(1, results.Count);
TestResult result = results[0];
Assert.AreEqual("Test", result.Name);
@@ -131,10 +142,12 @@ namespace UnitTesting.Tests.TestRunner
{
string resultsText = "Result: Failure\r\n";
- TestResultsReader reader = new TestResultsReader();
- TestResult[] results = reader.Read(resultsText);
+ TestResultsReader reader = new TestResultsReader(new StringReader(resultsText));
+ List results = new List();
+ reader.TestFinished += (sender, e) => results.Add(e.Result);
+ reader.Run();
- Assert.AreEqual(0, results.Length);
+ Assert.AreEqual(0, results.Count);
}
[Test]
@@ -144,10 +157,12 @@ namespace UnitTesting.Tests.TestRunner
"Name: Test\r\n" +
"Result: Failure\r\n";
- TestResultsReader reader = new TestResultsReader();
- TestResult[] results = reader.Read(resultsText);
+ TestResultsReader reader = new TestResultsReader(new StringReader(resultsText));
+ List results = new List();
+ reader.TestFinished += (sender, e) => results.Add(e.Result);
+ reader.Run();
- Assert.AreEqual(1, results.Length);
+ Assert.AreEqual(1, results.Count);
TestResult result = results[0];
Assert.AreEqual("Test", result.Name);
@@ -162,10 +177,12 @@ namespace UnitTesting.Tests.TestRunner
" Should be 1.\r\n" +
"Result: Failure\r\n";
- TestResultsReader reader = new TestResultsReader();
- TestResult[] results = reader.Read(resultsText);
+ TestResultsReader reader = new TestResultsReader(new StringReader(resultsText));
+ List results = new List();
+ reader.TestFinished += (sender, e) => results.Add(e.Result);
+ reader.Run();
- Assert.AreEqual(1, results.Length);
+ Assert.AreEqual(1, results.Count);
TestResult result = results[0];
Assert.AreEqual("Test", result.Name);
@@ -182,10 +199,12 @@ namespace UnitTesting.Tests.TestRunner
" End of message.\r\n" +
"Result: Failure\r\n";
- TestResultsReader reader = new TestResultsReader();
- TestResult[] results = reader.Read(resultsText);
+ TestResultsReader reader = new TestResultsReader(new StringReader(resultsText));
+ List results = new List();
+ reader.TestFinished += (sender, e) => results.Add(e.Result);
+ reader.Run();
- Assert.AreEqual(1, results.Length);
+ Assert.AreEqual(1, results.Count);
TestResult result = results[0];
Assert.AreEqual("Test", result.Name);
@@ -201,10 +220,12 @@ namespace UnitTesting.Tests.TestRunner
"Name: MyTest2\r\n" +
"Result: Failure\r\n";
- TestResultsReader reader = new TestResultsReader();
- TestResult[] results = reader.Read(resultsText);
+ TestResultsReader reader = new TestResultsReader(new StringReader(resultsText));
+ List results = new List();
+ reader.TestFinished += (sender, e) => results.Add(e.Result);
+ reader.Run();
- Assert.AreEqual(2, results.Length);
+ Assert.AreEqual(2, results.Count);
TestResult result1 = results[0];
Assert.AreEqual("MyTest1", result1.Name);
@@ -228,10 +249,12 @@ namespace UnitTesting.Tests.TestRunner
" ThirdLine\r\n" +
"Result: Failure\r\n";
- TestResultsReader reader = new TestResultsReader();
- TestResult[] results = reader.Read(resultsText);
+ TestResultsReader reader = new TestResultsReader(new StringReader(resultsText));
+ List results = new List();
+ reader.TestFinished += (sender, e) => results.Add(e.Result);
+ reader.Run();
- Assert.AreEqual(2, results.Length);
+ Assert.AreEqual(2, results.Count);
TestResult result1 = results[0];
Assert.AreEqual("MyTest1", result1.Name);
diff --git a/src/AddIns/Analysis/UnitTesting/TestRunner/ITestResultsMonitor.cs b/src/AddIns/Analysis/UnitTesting/TestRunner/ITestResultsMonitor.cs
deleted file mode 100644
index 6a67c16e74..0000000000
--- a/src/AddIns/Analysis/UnitTesting/TestRunner/ITestResultsMonitor.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
-
-using System;
-
-namespace ICSharpCode.UnitTesting
-{
- public interface ITestResultsMonitor : IDisposable
- {
- event EventHandler TestFinished;
-
- string FileName { get; set; }
-
- void Stop();
- void Start();
- void Read();
-
- long InitialFilePosition { get; set; }
- }
-}
diff --git a/src/AddIns/Analysis/UnitTesting/TestRunner/TestDebuggerBase.cs b/src/AddIns/Analysis/UnitTesting/TestRunner/TestDebuggerBase.cs
index 865aeabfeb..acb320b8b1 100644
--- a/src/AddIns/Analysis/UnitTesting/TestRunner/TestDebuggerBase.cs
+++ b/src/AddIns/Analysis/UnitTesting/TestRunner/TestDebuggerBase.cs
@@ -16,29 +16,29 @@ namespace ICSharpCode.UnitTesting
IUnitTestDebuggerService debuggerService;
IMessageService messageService;
IDebugger debugger;
- ITestResultsMonitor testResultsMonitor;
+ ITestResultsReader testResultsReader;
public TestDebuggerBase()
: this(new UnitTestDebuggerService(),
SD.MessageService,
- new TestResultsMonitor())
+ new TestResultsReader())
{
}
public TestDebuggerBase(IUnitTestDebuggerService debuggerService,
IMessageService messageService,
- ITestResultsMonitor testResultsMonitor)
+ ITestResultsReader testResultsReader)
{
this.debuggerService = debuggerService;
this.messageService = messageService;
- this.testResultsMonitor = testResultsMonitor;
+ this.testResultsReader = testResultsReader;
this.debugger = debuggerService.CurrentDebugger;
- testResultsMonitor.TestFinished += OnTestFinished;
+ testResultsReader.TestFinished += OnTestFinished;
}
- protected ITestResultsMonitor TestResultsMonitor {
- get { return testResultsMonitor; }
+ protected ITestResultsReader TestResultsReader {
+ get { return testResultsReader; }
}
public override void Start(IEnumerable selectedTests)
@@ -67,7 +67,7 @@ namespace ICSharpCode.UnitTesting
void Start(ProcessStartInfo startInfo)
{
- testResultsMonitor.Start();
+ testResultsReader.Start();
StartDebugger(startInfo);
}
@@ -90,6 +90,7 @@ namespace ICSharpCode.UnitTesting
void DebugStopped(object source, EventArgs e)
{
debugger.DebugStopped -= DebugStopped;
+ testResultsReader.Join();
OnAllTestsFinished(source, e);
}
@@ -98,15 +99,12 @@ namespace ICSharpCode.UnitTesting
if (debugger.IsDebugging) {
debugger.Stop();
}
-
- testResultsMonitor.Stop();
- testResultsMonitor.Read();
}
public override void Dispose()
{
- Stop();
- testResultsMonitor.Dispose();
+ testResultsReader.Dispose();
+ testResultsReader.TestFinished -= OnTestFinished;
}
}
}
diff --git a/src/AddIns/Analysis/UnitTesting/TestRunner/TestProcessRunnerBase.cs b/src/AddIns/Analysis/UnitTesting/TestRunner/TestProcessRunnerBase.cs
index 9595482b47..c76080b0c6 100644
--- a/src/AddIns/Analysis/UnitTesting/TestRunner/TestProcessRunnerBase.cs
+++ b/src/AddIns/Analysis/UnitTesting/TestRunner/TestProcessRunnerBase.cs
@@ -11,17 +11,17 @@ using ICSharpCode.SharpDevelop.Util;
namespace ICSharpCode.UnitTesting
{
- public class TestProcessRunnerBase : TestRunnerBase
+ public abstract class TestProcessRunnerBase : TestRunnerBase
{
IUnitTestProcessRunner processRunner;
- ITestResultsMonitor testResultsMonitor;
+ ITestResultsReader testResultsReader;
IFileSystem fileSystem;
IMessageService messageService;
public TestProcessRunnerBase(TestProcessRunnerBaseContext context)
{
this.processRunner = context.TestProcessRunner;
- this.testResultsMonitor = context.TestResultsMonitor;
+ this.testResultsReader = context.TestResultsReader;
this.fileSystem = context.FileSystem;
this.messageService = context.MessageService;
@@ -29,11 +29,11 @@ namespace ICSharpCode.UnitTesting
processRunner.OutputLineReceived += OutputLineReceived;
processRunner.ErrorLineReceived += OutputLineReceived;
processRunner.ProcessExited += OnAllTestsFinished;
- testResultsMonitor.TestFinished += OnTestFinished;
+ testResultsReader.TestFinished += OnTestFinished;
}
- protected ITestResultsMonitor TestResultsMonitor {
- get { return testResultsMonitor; }
+ protected ITestResultsReader TestResultsReader {
+ get { return testResultsReader; }
}
protected IUnitTestProcessRunner ProcessRunner {
@@ -56,7 +56,7 @@ namespace ICSharpCode.UnitTesting
LogCommandLine(processStartInfo);
if (ApplicationFileNameExists(processStartInfo.FileName)) {
- testResultsMonitor.Start();
+ testResultsReader.Start();
processRunner.WorkingDirectory = processStartInfo.WorkingDirectory;
processRunner.Start(processStartInfo.FileName, processStartInfo.Arguments);
} else {
@@ -75,17 +75,23 @@ namespace ICSharpCode.UnitTesting
messageService.ShowErrorFormatted(resourceString, fileName);
}
+ protected override void OnAllTestsFinished(object source, EventArgs e)
+ {
+ testResultsReader.Join();
+ base.OnAllTestsFinished(source, e);
+ }
+
public override void Stop()
{
+ SD.Log.Info("Killing unit test runner");
processRunner.Kill();
- testResultsMonitor.Stop();
- testResultsMonitor.Read();
}
public override void Dispose()
{
- testResultsMonitor.Dispose();
- testResultsMonitor.TestFinished -= OnTestFinished;
+ processRunner.Dispose();
+ testResultsReader.Dispose();
+ testResultsReader.TestFinished -= OnTestFinished;
processRunner.ErrorLineReceived -= OutputLineReceived;
processRunner.OutputLineReceived -= OutputLineReceived;
}
diff --git a/src/AddIns/Analysis/UnitTesting/TestRunner/TestProcessRunnerBaseContext.cs b/src/AddIns/Analysis/UnitTesting/TestRunner/TestProcessRunnerBaseContext.cs
index 56f2e6c38d..2a8288b55e 100644
--- a/src/AddIns/Analysis/UnitTesting/TestRunner/TestProcessRunnerBaseContext.cs
+++ b/src/AddIns/Analysis/UnitTesting/TestRunner/TestProcessRunnerBaseContext.cs
@@ -11,25 +11,25 @@ namespace ICSharpCode.UnitTesting
public class TestProcessRunnerBaseContext
{
IUnitTestProcessRunner processRunner;
- ITestResultsMonitor testResultsMonitor;
+ ITestResultsReader testResultsReader;
IFileSystem fileSystem;
IMessageService messageService;
public TestProcessRunnerBaseContext()
: this(new UnitTestProcessRunner(),
- new TestResultsMonitor(),
+ new TestResultsReader(),
new UnitTestFileService(),
SD.MessageService)
{
}
public TestProcessRunnerBaseContext(IUnitTestProcessRunner processRunner,
- ITestResultsMonitor testResultsMonitor,
+ ITestResultsReader testResultsMonitor,
IFileSystem fileSystem,
IMessageService messageService)
{
this.processRunner = processRunner;
- this.testResultsMonitor = testResultsMonitor;
+ this.testResultsReader = testResultsMonitor;
this.fileSystem = fileSystem;
this.messageService = messageService;
}
@@ -38,8 +38,8 @@ namespace ICSharpCode.UnitTesting
get { return processRunner; }
}
- public ITestResultsMonitor TestResultsMonitor {
- get { return testResultsMonitor; }
+ public ITestResultsReader TestResultsReader {
+ get { return testResultsReader; }
}
public IFileSystem FileSystem {
diff --git a/src/AddIns/Analysis/UnitTesting/TestRunner/TestResultsMonitor.cs b/src/AddIns/Analysis/UnitTesting/TestRunner/TestResultsMonitor.cs
deleted file mode 100644
index 297dc87fb5..0000000000
--- a/src/AddIns/Analysis/UnitTesting/TestRunner/TestResultsMonitor.cs
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
-
-using System;
-using System.IO;
-using System.Text;
-
-namespace ICSharpCode.UnitTesting
-{
- ///
- /// Watches for new test results as they occur. Test results
- /// are written to a file and read in by this class.
- ///
- public class TestResultsMonitor : ITestResultsMonitor
- {
- FileInfo fileInfo;
- TestResultsReader testResultsReader;
- FileSystemWatcher fileSystemWatcher;
-
- long initialFilePosition = 3;
- long filePosition;
-
- const int BytesBufferLength = 1024;
- byte[] bytes = new byte[BytesBufferLength];
-
- ///
- /// Raised when a single test has been completed.
- ///
- public event EventHandler TestFinished;
-
- public TestResultsMonitor(string fileName)
- {
- fileInfo = new FileInfo(fileName);
- ResetFilePosition();
- }
-
- public TestResultsMonitor()
- : this(Path.GetTempFileName())
- {
- ResetFilePosition();
- }
-
- public long InitialFilePosition {
- get { return initialFilePosition; }
- set { initialFilePosition = value; }
- }
-
- ///
- /// Gets or sets the test results filename.
- ///
- public string FileName {
- get { return fileInfo.FullName; }
- set { fileInfo = new FileInfo(value); }
- }
-
- ///
- /// Starts monitoring for test results.
- ///
- public void Start()
- {
- testResultsReader = new TestResultsReader();
- ResetFilePosition();
-
- string filter = fileInfo.Name;
- fileSystemWatcher = new FileSystemWatcher(fileInfo.DirectoryName, filter);
-
- if (File.Exists(fileInfo.FullName)) {
- fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
- fileSystemWatcher.Changed += FileChanged;
- } else {
- fileSystemWatcher.Created += FileCreated;
- }
- fileSystemWatcher.Error += FileSystemWatcherError;
- fileSystemWatcher.EnableRaisingEvents = true;
- }
-
- ///
- /// Stops monitoring.
- ///
- public void Stop()
- {
- if (fileSystemWatcher != null) {
- fileSystemWatcher.Dispose();
- fileSystemWatcher = null;
- }
- }
-
- ///
- /// Reads the rest of the file from the current position.
- /// Raises the TestFinished event for each test result
- /// still in the file.
- ///
- public void Read()
- {
- string text = ReadTextAdded();
- if (text != null) {
- TestResult[] results = testResultsReader.Read(text);
- OnTestResultsReceived(results);
- }
- }
-
- ///
- /// Stops monitoring and releases any resources used
- /// by the TestResultsMonitor.
- ///
- public void Dispose()
- {
- Stop();
-
- try {
- File.Delete(FileName);
- } catch { }
- }
-
- void FileCreated(object source, FileSystemEventArgs e)
- {
- fileSystemWatcher.Created -= FileCreated;
- fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
- fileSystemWatcher.Changed += FileChanged;
- }
-
- void FileChanged(object source, FileSystemEventArgs e)
- {
- Read();
- }
-
- void OnTestResultsReceived(TestResult[] results)
- {
- if ((results.Length > 0) && (TestFinished != null)) {
- foreach (TestResult result in results) {
- TestFinished(this, new TestFinishedEventArgs(result));
- }
- }
- }
-
- ///
- /// Reads the text added to the end of the file from the last
- /// position we read from.
- ///
- string ReadTextAdded()
- {
- StringBuilder text = null;
- try {
- using (FileStream fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
- if (fs.Length > 0) {
- text = new StringBuilder();
- int bytesRead = 0;
- fs.Seek(filePosition, SeekOrigin.Begin);
- do {
- bytesRead = fs.Read(bytes, 0, BytesBufferLength);
- if (bytesRead > 0) {
- filePosition += bytesRead;
- text.Append(UTF8Encoding.UTF8.GetString(bytes, 0, bytesRead));
- }
- } while ((bytesRead > 0) && (filePosition < fs.Length));
- }
- }
- } catch (FileNotFoundException) {
- // Test was aborted before it even started execution
- return null;
- }
- if (text != null) {
- return text.ToString();
- }
- return null;
- }
-
- void FileSystemWatcherError(object source, ErrorEventArgs e)
- {
- Console.WriteLine(e.GetException().ToString());
- }
-
- void ResetFilePosition()
- {
- filePosition = initialFilePosition;
- }
- }
-}
diff --git a/src/AddIns/Analysis/UnitTesting/TestRunner/TestResultsReader.cs b/src/AddIns/Analysis/UnitTesting/TestRunner/TestResultsReader.cs
index 35b13b7ee7..c3bffa260d 100644
--- a/src/AddIns/Analysis/UnitTesting/TestRunner/TestResultsReader.cs
+++ b/src/AddIns/Analysis/UnitTesting/TestRunner/TestResultsReader.cs
@@ -2,52 +2,118 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
-using System.Collections.Generic;
+using System.IO;
+using System.IO.Pipes;
using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
namespace ICSharpCode.UnitTesting
{
- ///
- /// Reads the test results file produced by the custom
- /// nunit-console application.
- ///
- public class TestResultsReader
+ public interface ITestResultsReader : IDisposable
{
- StringBuilder nameBuilder = new StringBuilder();
- StringBuilder valueBuilder = new StringBuilder();
- bool firstNameChar = true;
- TestResult result;
+ event EventHandler TestFinished;
+ string PipeName { get; }
+ void Start();
+ void Join();
+ }
+
+ public class TestResultsReader : ITestResultsReader
+ {
+ TextReader reader;
+ readonly NamedPipeServerStream namedPipe;
+ readonly string pipeName;
+ TaskCompletionSource