[mono/monodevelop] [4 commits] a857484d: [NUnit] Improve support for guiunit

"Lluis Sanchez ([email protected])" <[email protected]>
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <0000014193408698-eb91ecd6-0d8b-4c22-9655-10abefd1bc12-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/monodevelop
  Compare: https://github.com/mono/monodevelop/compare/b651c0aa4fe2...f44289407e88

   Commit: a857484d60790c9b070e712393e8234f27d3a4eb
   Author: Lluis Sanchez <[email protected]> (slluis)
     Date: 2013-10-07 14:05:15 GMT
      URL: https://github.com/mono/monodevelop/commit/a857484d60790c9b070e712393e8234f27d3a4eb

[NUnit] Improve support for guiunit

When running on guiunit there is no need to parse the resulting xml
file, since all results come through the tcp connection.

Improved TcpTestListener. It now properly reports the status for all
the sections (nodes) of a test suite.

Fixed 15165 - Xamarin Studio cannot run single tests using an external
test runner correctly.

Changed paths:
  M main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs
  M main/src/addins/NUnit/Services/TcpTestListener.cs

Modified: main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs
===================================================================
@@ -477,7 +477,7 @@ UnitTestResult RunWithConsoleRunner (ProcessExecutionCommand cmd, UnitTest test,
 				else if (!string.IsNullOrEmpty (suiteName))
 					cmd.Arguments += " -run=" + suiteName;
 				if (automaticUpdates) {
-					var tcpListener = new MonoDevelop.NUnit.External.TcpTestListener (localMonitor);
+					var tcpListener = new MonoDevelop.NUnit.External.TcpTestListener (localMonitor, suiteName);
 					cmd.Arguments += " -port=" + tcpListener.Port;
 				}
 				var p = testContext.ExecutionContext.Execute (cmd, cons);
@@ -489,7 +489,13 @@ UnitTestResult RunWithConsoleRunner (ProcessExecutionCommand cmd, UnitTest test,
 				
 				if (new FileInfo (outFile).Length == 0)
 					throw new Exception ("Command failed");
-				
+
+				if (automaticUpdates) {
+					if (testName != null)
+						return localMonitor.SingleTestResult;
+					return test.GetLastResult ();
+				}
+
 				XDocument doc = XDocument.Load (outFile);
 
 				if (doc.Root != null) {
@@ -511,7 +517,10 @@ UnitTestResult RunWithConsoleRunner (ProcessExecutionCommand cmd, UnitTest test,
 						}
 
 						bool macunitStyle = doc.Root.Element ("environment") != null && doc.Root.Element ("environment").Attribute ("macunit-version") != null;
-						return ReportXmlResult (localMonitor, root, "", macunitStyle);
+						var result = ReportXmlResult (localMonitor, root, "", macunitStyle);
+						if (testName != null)
+							result = localMonitor.SingleTestResult;
+						return result;
 					}
 				}
 				throw new Exception ("Test results could not be parsed.");

Modified: main/src/addins/NUnit/Services/TcpTestListener.cs
===================================================================
@@ -34,11 +34,18 @@
 using System.Xml.Linq;
 using System.Collections.Generic;
 using System.Linq;
+using MonoDevelop.Core;
 
 namespace MonoDevelop.NUnit.External
 {
 	class TcpTestListener
 	{
+		string testSuiteName;
+		string rootTestName;
+
+		List<Tuple<string,UnitTestResult>> suiteStack = new List<Tuple<string, UnitTestResult>> ();
+		IRemoteEventListener listener;
+
 		TcpListener TcpListener {
 			get; set;
 		}
@@ -48,8 +55,12 @@ class TcpTestListener
 		}
 
 
-		public TcpTestListener (IRemoteEventListener listener)
+		public TcpTestListener (IRemoteEventListener listener, string suiteName)
 		{
+			this.testSuiteName = suiteName;
+			this.listener = listener;
+			bool rootSuiteStarted = false;
+
 			TcpListener = new TcpListener (new IPEndPoint (IPAddress.Loopback, 0));
 			TcpListener.Start ();
 			Task.Factory.StartNew (() => {
@@ -61,29 +72,114 @@ public TcpTestListener (IRemoteEventListener listener)
 						string line = null;
 						while ((line = reader.ReadLine ()) != null) {
 							var element = XElement.Parse (line);
+							string testName = element.Attribute ("name").Value;
+							var action = element.Name.LocalName;
+
+							if (testSuiteName.Length == 0 && !rootSuiteStarted) {
+								// Running the whole assembly
+								rootTestName = testName;
+								rootSuiteStarted = true;
+								continue;
+							}
+							if (testSuiteName == testName && !rootSuiteStarted) {
+								// Running a test suite
+								rootTestName = testName;
+								rootSuiteStarted = true;
+								listener.SuiteStarted ("<root>");
+								continue;
+							}
 
-							Gtk.Application.Invoke (delegate {
-								var testName = element.Attribute ("name").Value;
-								if (element.Name.LocalName == "suite-started") {
-									listener.SuiteStarted (testName);
-								} else if (element.Name.LocalName == "test-started") {
-									listener.TestStarted (testName);
-								} else if (element.Name.LocalName == "test-finished") {
-									listener.TestFinished (testName, CreateResult (element));
-								} else if (element.Name.LocalName == "suite-finished") {
-									listener.SuiteFinished (testName, CreateResult (element));
+							if (!rootSuiteStarted)
+								continue;
+
+							switch (action) {
+							case "suite-started":
+								UpdateTestSuiteStatus (testName, false); break;
+							case "test-started":
+								UpdateTestSuiteStatus (testName, true);
+								listener.TestStarted (testName); break;
+							case "test-finished":
+								var res = CreateResult (element);
+								AddTestResult (res);
+								listener.TestFinished (testName, res); break;
+							case "suite-finished":
+								if (testName == rootTestName) {
+									FinishSuites (0);
+									listener.SuiteFinished ("<root>", CreateResult (element));
+									rootSuiteStarted = false;
 								}
-							});
+								break;
+							}
 						}
 					}
-				} catch {
-
+				} catch (Exception ex) {
+					LoggingService.LogError ("Exception in test listener", ex);
 				} finally {
 					TcpListener.Stop ();
 				}
 			});
 		}
 
+		void UpdateTestSuiteStatus (string name, bool isTest)
+		{
+			if (testSuiteName.Length > 0)
+				name = name.Substring (testSuiteName.Length + 1);
+			string[] parts = name.Split ('.');
+			for (int n = 0; n < parts.Length; n++) {
+				if (n >= suiteStack.Count) {
+					StartSuite (parts[n]);
+				} else if (parts [n] != suiteStack [n].Item1) {
+					FinishSuites (n);
+					StartSuite (parts[n]);
+				}
+			}
+		}
+
+		void FinishSuites (int stackLevel)
+		{
+			if (stackLevel + 1 < suiteStack.Count)
+				FinishSuites (stackLevel + 1);
+
+			if (stackLevel >= suiteStack.Count)
+				return;
+
+			var tname = GetTestSuiteName (stackLevel);
+			var res = suiteStack [stackLevel].Item2;
+
+			suiteStack.RemoveAt (stackLevel);
+
+			listener.SuiteFinished (tname, res);
+		}
+
+		void StartSuite (string name)
+		{
+			suiteStack.Add (new Tuple<string, UnitTestResult> (name, new UnitTestResult ()));
+			name = GetTestSuiteName (suiteStack.Count - 1);
+			listener.SuiteStarted (name);
+		}
+
+		void AddTestResult (UnitTestResult res)
+		{
+			foreach (var r in suiteStack)
+				r.Item2.Add (res);
+		}
+
+		string GetTestSuiteName (int stackLevel)
+		{
+			var info = suiteStack [stackLevel];
+
+			string name;
+			if (stackLevel > 0) {
+				var prefix = string.Join (".", suiteStack.Select (s => s.Item1).Take (stackLevel));
+				name = prefix + "." + info.Item1;
+			} else
+				name = info.Item1;
+
+			if (testSuiteName.Length > 0)
+				name = testSuiteName + "." + name;
+			return name;
+		}
+
 		UnitTestResult CreateResult (XElement element)
 		{
 			var result = (ResultStatus)Enum.Parse (typeof(ResultStatus), element.Attribute ("result").Value);
@@ -92,12 +188,17 @@ UnitTestResult CreateResult (XElement element)
 			var ignored = int.Parse (element.Attribute ("ignored").Value);
 			var inconclusive = int.Parse (element.Attribute ("inconclusive").Value);
 
+			var message = (string)element.Attribute ("message");
+			var stackTrace = (string)element.Attribute ("stack-trace");
+
 			return new UnitTestResult {
 				Status = result,
 				Passed = passed,
 				Failures = failures,
 				Ignored = ignored,
-				Inconclusive = inconclusive
+				Inconclusive = inconclusive,
+				Message = message,
+				StackTrace = stackTrace
 			};
 		}
 	}

   Commit: 227ed70c97dec07e6bcc06ecbb73b5b05b027e53
   Author: Lluis Sanchez <[email protected]> (slluis)
     Date: 2013-10-07 14:05:15 GMT
      URL: https://github.com/mono/monodevelop/commit/227ed70c97dec07e6bcc06ecbb73b5b05b027e53

[NUnit] Fix minor status reporting issue

Changed paths:
  M main/src/addins/NUnit/Services/TcpTestListener.cs

Modified: main/src/addins/NUnit/Services/TcpTestListener.cs
===================================================================
@@ -125,7 +125,8 @@ void UpdateTestSuiteStatus (string name, bool isTest)
 			if (testSuiteName.Length > 0)
 				name = name.Substring (testSuiteName.Length + 1);
 			string[] parts = name.Split ('.');
-			for (int n = 0; n < parts.Length; n++) {
+			int len = isTest ? parts.Length - 1 : parts.Length;
+			for (int n = 0; n < len; n++) {
 				if (n >= suiteStack.Count) {
 					StartSuite (parts[n]);
 				} else if (parts [n] != suiteStack [n].Item1) {

   Commit: e700b33c97a32cfc407e887d8b32edef92b4a751
   Author: Lluis Sanchez <[email protected]> (slluis)
     Date: 2013-10-07 14:05:15 GMT
      URL: https://github.com/mono/monodevelop/commit/e700b33c97a32cfc407e887d8b32edef92b4a751

[NUnit] There is no need to explicitly initialize the results pad

Changed paths:
  M main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs
  M main/src/addins/NUnit/Services/TestContext.cs

Modified: main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs
===================================================================
@@ -499,12 +499,6 @@ UnitTestResult RunWithConsoleRunner (ProcessExecutionCommand cmd, UnitTest test,
 				XDocument doc = XDocument.Load (outFile);
 
 				if (doc.Root != null) {
-					if (automaticUpdates) {
-						DispatchService.GuiDispatch (delegate {
-							testContext.ResultsPad.InitializeTestRun (test);
-						});
-					}
-
 					var root = doc.Root.Elements ("test-suite").FirstOrDefault ();
 					if (root != null) {
 						cons.SetDone ();

Modified: main/src/addins/NUnit/Services/TestContext.cs
===================================================================
@@ -44,7 +44,6 @@ public class TestContext
 		public TestContext (ITestProgressMonitor monitor, TestResultsPad resultsPad, IExecutionHandler executionContext, DateTime testDate)
 		{
 			this.monitor = monitor;
-			ResultsPad = resultsPad;
 			if (executionContext == null)
 				executionContext = Runtime.ProcessService.DefaultExecutionHandler;
 			this.executionContext = executionContext;
@@ -68,10 +67,6 @@ public TestContext (ITestProgressMonitor monitor, TestResultsPad resultsPad, IEx
 		public IExecutionHandler ExecutionContext {
 			get { return executionContext; }
 		}
-
-		internal TestResultsPad ResultsPad {
-			get; private set;
-		}
 	}
 }
 

   Commit: f44289407e88e371b6ff37ed303d62039d34784f
   Author: Lluis Sanchez <[email protected]> (slluis)
     Date: 2013-10-07 14:05:15 GMT
      URL: https://github.com/mono/monodevelop/commit/f44289407e88e371b6ff37ed303d62039d34784f

[NUnit] Improve reporting of Ignored status

Changed paths:
  M main/src/addins/NUnit/Gui/TestNodeBuilder.cs

Modified: main/src/addins/NUnit/Gui/TestNodeBuilder.cs
===================================================================
@@ -92,6 +92,8 @@ public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref
 				UnitTestResult res = test.GetLastResult ();
 				if (res == null)
 					icon = CircleImage.None;
+				else if (res.Status == ResultStatus.Ignored)
+					icon = CircleImage.NotRun;
 				else if (res.ErrorsAndFailures > 0 && res.Passed > 0)
 					icon = test.IsHistoricResult ? CircleImage.OldSuccessAndFailure : CircleImage.SuccessAndFailure;
 				else if (res.IsInconclusive)
@@ -100,7 +102,7 @@ public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref
 					icon = test.IsHistoricResult ? CircleImage.OldFailure : CircleImage.Failure;
 				else if (res.IsSuccess)
 					icon = test.IsHistoricResult ? CircleImage.OldSuccess : CircleImage.Success;
-				else if (res.IsNotRun)
+				else if (res.IsNotRun || res.Ignored > 0)
 					icon = CircleImage.NotRun;
 				else
 					icon = CircleImage.None;


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.