Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/NUnitLite.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kyte <alexmkyte@fastmail.com>2016-01-13 02:35:19 +0300
committerAlexander Kyte <alexmkyte@fastmail.com>2016-01-14 02:51:26 +0300
commit88c3edc80cc1172ecd91a4c0e9d3269b4c9e0928 (patch)
treeaa9987f4ba85ed85755dc2cf1efe07fe5c32ae3a
parentdaa5838cbe2f112b065c26d2e653556e282785f6 (diff)
Add the FinallyDelegate class. This ensures that when there are
unhandled exceptions that the test-failure bookkeeping can run.
-rw-r--r--NUnitLite-1.0.0/src/framework/FinallyDelegate.cs90
1 files changed, 90 insertions, 0 deletions
diff --git a/NUnitLite-1.0.0/src/framework/FinallyDelegate.cs b/NUnitLite-1.0.0/src/framework/FinallyDelegate.cs
new file mode 100644
index 0000000..313c1f9
--- /dev/null
+++ b/NUnitLite-1.0.0/src/framework/FinallyDelegate.cs
@@ -0,0 +1,90 @@
+// ***********************************************************************
+// Author:
+// Alexander Kyte <alexander.kyte@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Diagnostics;
+using System.Threading;
+using NUnit.Framework.Api;
+using System.Collections.Generic;
+
+namespace NUnit.Framework.Internal
+{
+ public class FinallyDelegate
+ {
+ // If our test spawns a thread that throws, we will bubble
+ // up to the top level. To handle this, we need to have the
+ // failure logic in a place that can be called from the top level.
+ // The UnhandledException callback should run on a thread that isn't
+ // the one dispatching the tests so this should work to ensure
+ // progress in the face of exceptions on other threads
+ //
+ // Essentially this is a poor-man's finally clause that's
+ // guaranteed to run because we pin it to the UnhandledException
+ // callback
+
+ // Because of CompositeWorkItem, we have a runtime stack of work items
+ // so we need a stack of finally delegate continuations
+ Stack<Tuple<TestExecutionContext, long, TestResult>> testStack;
+
+ public FinallyDelegate () {
+ this.testStack = new Stack<Tuple<TestExecutionContext, long, TestResult>>();
+ }
+
+ public void Set (TestExecutionContext context, long startTicks, TestResult result) {
+ var frame = new Tuple<TestExecutionContext, long, TestResult>(context, startTicks, result);
+ this.testStack.Push(frame);
+ }
+
+ public void HandleUnhandledExc (Exception ex) {
+ TestExecutionContext context = this.testStack.Peek().Item1;
+ context.CurrentResult.RecordException(ex);
+ context.CurrentResult.ThreadCrashFail = true;
+ }
+
+ public void Complete () {
+ var frame = this.testStack.Pop();
+
+ TestExecutionContext context = frame.Item1;
+ long startTicks = frame.Item2;
+ TestResult result = frame.Item3;
+
+#if (CLR_2_0 || CLR_4_0) && !SILVERLIGHT && !NETCF_2_0
+ long tickCount = Stopwatch.GetTimestamp() - startTicks;
+ double seconds = (double)tickCount / Stopwatch.Frequency;
+ result.Duration = TimeSpan.FromSeconds(seconds);
+#else
+ result.Duration = DateTime.Now - Context.StartTime;
+#endif
+
+ result.AssertCount = context.AssertCount;
+
+ context.Listener.TestFinished(result);
+
+ context = context.Restore();
+ context.AssertCount += result.AssertCount;
+ }
+ }
+}