Merge lp:~simone.busoli/nunitv2/1066386 into lp:nunitv2

Proposed by Simone Busoli
Status: Merged
Approved by: Charlie Poole
Approved revision: 3431
Merged at revision: 3432
Proposed branch: lp:~simone.busoli/nunitv2/1066386
Merge into: lp:nunitv2
Diff against target: 775 lines (+370/-225)
9 files modified
src/NUnitCore/core/ContextDictionary.cs (+87/-10)
src/NUnitCore/core/TestExecutionContext.cs (+4/-6)
src/NUnitCore/core/TestThread.cs (+2/-2)
src/NUnitCore/tests-net45/NUnitAsyncTestMethodTests.cs (+107/-103)
src/NUnitCore/tests-net45/NUnitTestCaseBuilderTests.cs (+92/-90)
src/NUnitCore/tests/CallContextTests.cs (+3/-3)
src/NUnitCore/tests/TestContextTests.cs (+25/-6)
src/NUnitFramework/framework/TestContext.cs (+1/-1)
src/tests/test-assembly-net45/AsyncRealFixture.cs (+49/-4)
To merge this branch: bzr merge lp:~simone.busoli/nunitv2/1066386
Reviewer Review Type Date Requested Status
Charlie Poole Approve
Review via email: mp+129585@code.launchpad.net

Description of the change

No changes for support to async void tests are required.
Now the test context flows across threads, either created explicitly in the test body or as a consequence of writing async tests methods.

I tried to limit the changes to the minimum. ContextDictionary inherited Hashtable and was passed around as IDictionary but since I had to make it inherit from MarshalByRefObject I removed the inheritance from Hashtable, replaced with IDictionary and moved to composition, which in turn forced the implementation of the interface methods, all currently throwing NotImplementedException except the indexer.

To post a comment you must log in.
Revision history for this message
Simone Busoli (simone.busoli) wrote :

All tests using TestContext are currently failing when built for .net >= 4.0 for CAS violations, including the newly added ones.

Revision history for this message
Charlie Poole (charlie.poole) wrote :

Looks good... thanks.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/NUnitCore/core/ContextDictionary.cs'
2--- src/NUnitCore/core/ContextDictionary.cs 2012-09-25 16:39:42 +0000
3+++ src/NUnitCore/core/ContextDictionary.cs 2012-10-14 11:24:24 +0000
4@@ -5,22 +5,25 @@
5 // ****************************************************************
6
7 using System;
8-using System.Collections;
9-
10+using System.Collections;
11+using System.Runtime.Remoting.Messaging;
12+
13 namespace NUnit.Core
14 {
15- public class ContextDictionary : Hashtable
16+ [Serializable]
17+ public class ContextDictionary : MarshalByRefObject, IDictionary, ILogicalThreadAffinative
18 {
19 internal TestExecutionContext _context;
20+ private readonly Hashtable _storage = new Hashtable();
21
22 public ContextDictionary() { }
23
24 public ContextDictionary(TestExecutionContext context)
25 {
26 _context = context;
27- }
28-
29- public override object this[object key]
30+ }
31+
32+ public object this[object key]
33 {
34 get
35 {
36@@ -43,13 +46,87 @@
37 ? _context.TestPackage.Settings["WorkDirectory"]
38 : Environment.CurrentDirectory;
39 default:
40- return base[key];
41+ return _storage[key];
42 }
43 }
44 set
45 {
46- base[key] = value;
47+ _storage[key] = value;
48 }
49- }
50+ }
51+
52+ #region IDictionary Interface non-implementation
53+
54+ void IDictionary.Remove(object key)
55+ {
56+ throw new NotImplementedException();
57+ }
58+
59+ ICollection IDictionary.Keys
60+ {
61+ get { throw new NotImplementedException(); }
62+ }
63+
64+ ICollection IDictionary.Values
65+ {
66+ get { throw new NotImplementedException(); }
67+ }
68+
69+ bool IDictionary.IsReadOnly
70+ {
71+ get { throw new NotImplementedException(); }
72+ }
73+
74+ bool IDictionary.IsFixedSize
75+ {
76+ get { throw new NotImplementedException(); }
77+ }
78+
79+ bool IDictionary.Contains(object key)
80+ {
81+ throw new NotImplementedException();
82+ }
83+
84+ void IDictionary.Add(object key, object value)
85+ {
86+ throw new NotImplementedException();
87+ }
88+
89+ void IDictionary.Clear()
90+ {
91+ throw new NotImplementedException();
92+ }
93+
94+ IDictionaryEnumerator IDictionary.GetEnumerator()
95+ {
96+ throw new NotImplementedException();
97+ }
98+
99+ IEnumerator IEnumerable.GetEnumerator()
100+ {
101+ throw new NotImplementedException();
102+ }
103+
104+ void ICollection.CopyTo(Array array, int index)
105+ {
106+ throw new NotImplementedException();
107+ }
108+
109+ int ICollection.Count
110+ {
111+ get { throw new NotImplementedException(); }
112+ }
113+
114+ object ICollection.SyncRoot
115+ {
116+ get { throw new NotImplementedException(); }
117+ }
118+
119+ bool ICollection.IsSynchronized
120+ {
121+ get { throw new NotImplementedException(); }
122+ }
123+
124+ #endregion
125 }
126-}
127+}
128\ No newline at end of file
129
130=== modified file 'src/NUnitCore/core/TestExecutionContext.cs'
131--- src/NUnitCore/core/TestExecutionContext.cs 2012-09-25 16:39:42 +0000
132+++ src/NUnitCore/core/TestExecutionContext.cs 2012-10-14 11:24:24 +0000
133@@ -3,9 +3,7 @@
134 // This is free software licensed under the NUnit license. You may
135 // obtain a copy of the license at http://nunit.org.
136 // ****************************************************************
137-using System;
138-using System.Collections.Specialized;
139-using System.Configuration;
140+using System;
141 using System.IO;
142 using System.Diagnostics;
143 using System.Globalization;
144@@ -26,7 +24,7 @@
145 ///
146 /// Static methods for each setting forward to the internal
147 /// object on the top of the stack.
148- /// </summary>
149+ /// </summary>
150 public class TestExecutionContext
151 {
152 #region Static Fields
153@@ -398,7 +396,7 @@
154 public static void Save()
155 {
156 current = new TestExecutionContext(current);
157- CallContext.SetData("NUnit.Framework.TestContext", current.contextDictionary);
158+ CallContext.LogicalSetData("NUnit.Framework.TestContext", current.contextDictionary);
159 }
160
161 /// <summary>
162@@ -409,7 +407,7 @@
163 {
164 current.ReverseChanges();
165 current = current.prior;
166- CallContext.SetData("NUnit.Framework.TestContext", current.contextDictionary);
167+ CallContext.LogicalSetData("NUnit.Framework.TestContext", current.contextDictionary);
168 }
169 #endregion
170
171
172=== modified file 'src/NUnitCore/core/TestThread.cs'
173--- src/NUnitCore/core/TestThread.cs 2011-12-26 21:24:27 +0000
174+++ src/NUnitCore/core/TestThread.cs 2012-10-14 11:24:24 +0000
175@@ -91,7 +91,7 @@
176 this.thrownException = null;
177 this.listener = listener;
178 this.filter = filter;
179- this.contextDictionary = (ContextDictionary)CallContext.GetData("NUnit.Framework.TestContext");
180+ this.contextDictionary = (ContextDictionary)CallContext.LogicalGetData("NUnit.Framework.TestContext");
181
182 log.Debug("Starting test in separate thread");
183 thread.Start();
184@@ -133,7 +133,7 @@
185 /// </summary>
186 private void RunTestProc()
187 {
188- CallContext.SetData("NUnit.Framework.TestContext", contextDictionary);
189+ CallContext.LogicalSetData("NUnit.Framework.TestContext", contextDictionary);
190
191 try
192 {
193
194=== modified file 'src/NUnitCore/tests-net45/NUnitAsyncTestMethodTests.cs'
195--- src/NUnitCore/tests-net45/NUnitAsyncTestMethodTests.cs 2012-10-08 22:03:22 +0000
196+++ src/NUnitCore/tests-net45/NUnitAsyncTestMethodTests.cs 2012-10-14 11:24:24 +0000
197@@ -1,104 +1,108 @@
198-#if NET_3_5 || NET_4_0 || NET_4_5
199-using System;
200-using System.Collections;
201-using System.Diagnostics;
202-using System.Linq.Expressions;
203-using System.Reflection;
204-using System.Threading;
205-using NUnit.Core;
206-using NUnit.Core.Builders;
207-using NUnit.Framework;
208-using test_assembly_net45;
209-
210-namespace nunit.core.tests.net45
211-{
212- [TestFixture]
213- public class NUnitAsyncTestMethodTests
214- {
215- private NUnitTestCaseBuilder _builder;
216-
217- [SetUp]
218- public void Setup()
219- {
220- _builder = new NUnitTestCaseBuilder();
221- }
222-
223- public IEnumerable TestCases
224- {
225- get
226- {
227- yield return new object[] { Method("VoidTestSuccess"), ResultState.Success, 1 };
228- yield return new object[] { Method("VoidTestFailure"), ResultState.Failure, 1 };
229- yield return new object[] { Method("VoidTestError"), ResultState.Error, 0 };
230- yield return new object[] { Method("VoidTestExpectedException"), ResultState.Success, 0 };
231-
232- yield return new object[] { Method("TaskTestSuccess"), ResultState.Success, 1 };
233- yield return new object[] { Method("TaskTestFailure"), ResultState.Failure, 1 };
234- yield return new object[] { Method("TaskTestError"), ResultState.Error, 0 };
235- yield return new object[] { Method("TaskTestExpectedException"), ResultState.Success, 0 };
236-
237- yield return new object[] { Method("TaskTTestCaseWithResultCheckSuccess"), ResultState.Success, 0 };
238- yield return new object[] { Method("TaskTTestCaseWithResultCheckFailure"), ResultState.Failure, 0 };
239- yield return new object[] { Method("TaskTTestCaseWithResultCheckError"), ResultState.Failure, 0 };
240- yield return new object[] { Method("TaskTTestCaseWithResultCheckSuccessReturningNull"), ResultState.Success, 0 };
241- yield return new object[] { Method("TaskTTestCaseWithoutResultCheckExpectedExceptionSuccess"), ResultState.Success, 0 };
242-
243- yield return new object[] { Method("NestedVoidTestSuccess"), ResultState.Success, 1 };
244- yield return new object[] { Method("NestedVoidTestFailure"), ResultState.Failure, 1 };
245- yield return new object[] { Method("NestedVoidTestError"), ResultState.Error, 0 };
246-
247- yield return new object[] { Method("NestedTaskTestSuccess"), ResultState.Success, 1 };
248- yield return new object[] { Method("NestedTaskTestFailure"), ResultState.Failure, 1 };
249- yield return new object[] { Method("NestedTaskTestError"), ResultState.Error, 0 };
250-
251- yield return new object[] { Method("VoidTestMultipleSuccess"), ResultState.Success, 1 };
252- yield return new object[] { Method("VoidTestMultipleFailure"), ResultState.Failure, 1 };
253- yield return new object[] { Method("VoidTestMultipleError"), ResultState.Error, 0 };
254-
255- yield return new object[] { Method("TaskTestMultipleSuccess"), ResultState.Success, 1 };
256- yield return new object[] { Method("TaskTestMultipleFailure"), ResultState.Failure, 1 };
257- yield return new object[] { Method("TaskTestMultipleError"), ResultState.Error, 0 };
258- }
259- }
260-
261- [Test]
262- [TestCaseSource("TestCases")]
263- public void RunTests(MethodInfo testMethod, ResultState resultState, int assertionCount)
264- {
265- var method = _builder.BuildFrom(testMethod);
266-
267- var result = method.Run(new NullListener(), TestFilter.Empty);
268-
269- Assert.That(result.Executed, Is.True, "Was not executed");
270- Assert.That(result.ResultState, Is.EqualTo(resultState), "Wrong result state");
271- Assert.That(result.AssertCount, Is.EqualTo(assertionCount), "Wrong assertion count");
272- }
273-
274- [Test]
275- public void SynchronizationContextSwitching()
276- {
277- var context = new CustomSynchronizationContext();
278-
279- SynchronizationContext.SetSynchronizationContext(context);
280-
281- var method = _builder.BuildFrom(Method("VoidAssertSynchrnoizationContext"));
282-
283- var result = method.Run(new NullListener(), TestFilter.Empty);
284-
285- Assert.AreSame(context, SynchronizationContext.Current);
286- Assert.That(result.Executed, Is.True, "Was not executed");
287- Assert.That(result.ResultState, Is.EqualTo(ResultState.Success), "Wrong result state");
288- Assert.That(result.AssertCount, Is.EqualTo(1), "Wrong assertion count");
289- }
290-
291- private static MethodInfo Method(string name)
292- {
293- return typeof (AsyncRealFixture).GetMethod(name);
294- }
295-
296- public class CustomSynchronizationContext : SynchronizationContext
297- {
298- }
299- }
300-}
301+#if NET_3_5 || NET_4_0 || NET_4_5
302+using System;
303+using System.Collections;
304+using System.Linq.Expressions;
305+using System.Reflection;
306+using System.Threading;
307+using NUnit.Core;
308+using NUnit.Core.Builders;
309+using NUnit.Framework;
310+using test_assembly_net45;
311+
312+namespace nunit.core.tests.net45
313+{
314+ [TestFixture]
315+ public class NUnitAsyncTestMethodTests
316+ {
317+ private NUnitTestCaseBuilder _builder;
318+
319+ [SetUp]
320+ public void Setup()
321+ {
322+ _builder = new NUnitTestCaseBuilder();
323+ }
324+
325+ public IEnumerable TestCases
326+ {
327+ get
328+ {
329+ yield return new object[] { Method(f => f.VoidTestSuccess()), ResultState.Success, 1 };
330+ yield return new object[] { Method(f => f.VoidTestFailure()), ResultState.Failure, 1 };
331+ yield return new object[] { Method(f => f.VoidTestError()), ResultState.Error, 0 };
332+ yield return new object[] { Method(f => f.VoidTestExpectedException()), ResultState.Success, 0 };
333+
334+ yield return new object[] { Method(f => f.TaskTestSuccess()), ResultState.Success, 1 };
335+ yield return new object[] { Method(f => f.TaskTestFailure()), ResultState.Failure, 1 };
336+ yield return new object[] { Method(f => f.TaskTestError()), ResultState.Error, 0 };
337+ yield return new object[] { Method(f => f.TaskTestExpectedException()), ResultState.Success, 0 };
338+
339+ yield return new object[] { Method(f => f.TaskTTestCaseWithResultCheckSuccess()), ResultState.Success, 0 };
340+ yield return new object[] { Method(f => f.TaskTTestCaseWithResultCheckFailure()), ResultState.Failure, 0 };
341+ yield return new object[] { Method(f => f.TaskTTestCaseWithResultCheckError()), ResultState.Failure, 0 };
342+ yield return new object[] { Method(f => f.TaskTTestCaseWithResultCheckSuccessReturningNull()), ResultState.Success, 0 };
343+ yield return new object[] { Method(f => f.TaskTTestCaseWithoutResultCheckExpectedExceptionSuccess()), ResultState.Success, 0 };
344+
345+ yield return new object[] { Method(f => f.NestedVoidTestSuccess()), ResultState.Success, 1 };
346+ yield return new object[] { Method(f => f.NestedVoidTestFailure()), ResultState.Failure, 1 };
347+ yield return new object[] { Method(f => f.NestedVoidTestError()), ResultState.Error, 0 };
348+
349+ yield return new object[] { Method(f => f.NestedTaskTestSuccess()), ResultState.Success, 1 };
350+ yield return new object[] { Method(f => f.NestedTaskTestFailure()), ResultState.Failure, 1 };
351+ yield return new object[] { Method(f => f.NestedTaskTestError()), ResultState.Error, 0 };
352+
353+ yield return new object[] { Method(f => f.VoidTestMultipleSuccess()), ResultState.Success, 1 };
354+ yield return new object[] { Method(f => f.VoidTestMultipleFailure()), ResultState.Failure, 1 };
355+ yield return new object[] { Method(f => f.VoidTestMultipleError()), ResultState.Error, 0 };
356+
357+ yield return new object[] { Method(f => f.TaskTestMultipleSuccess()), ResultState.Success, 1 };
358+ yield return new object[] { Method(f => f.TaskTestMultipleFailure()), ResultState.Failure, 1 };
359+ yield return new object[] { Method(f => f.TaskTestMultipleError()), ResultState.Error, 0 };
360+
361+ yield return new object[] { Method(f => f.VoidCheckTestContextAcrossTasks()), ResultState.Success, 2 };
362+ yield return new object[] { Method(f => f.VoidCheckTestContextWithinTestBody()), ResultState.Success, 2 };
363+ yield return new object[] { Method(f => f.TaskCheckTestContextAcrossTasks()), ResultState.Success, 2 };
364+ yield return new object[] { Method(f => f.TaskCheckTestContextWithinTestBody()), ResultState.Success, 2 };
365+ }
366+ }
367+
368+ [Test]
369+ [TestCaseSource("TestCases")]
370+ public void RunTests(MethodInfo testMethod, ResultState resultState, int assertionCount)
371+ {
372+ var method = _builder.BuildFrom(testMethod);
373+
374+ var result = method.Run(new NullListener(), TestFilter.Empty);
375+
376+ Assert.That(result.Executed, Is.True, "Was not executed");
377+ Assert.That(result.ResultState, Is.EqualTo(resultState), "Wrong result state");
378+ Assert.That(result.AssertCount, Is.EqualTo(assertionCount), "Wrong assertion count");
379+ }
380+
381+ [Test]
382+ public void SynchronizationContextSwitching()
383+ {
384+ var context = new CustomSynchronizationContext();
385+
386+ SynchronizationContext.SetSynchronizationContext(context);
387+
388+ var method = _builder.BuildFrom(Method(f => f.VoidAssertSynchronizationContext()));
389+
390+ var result = method.Run(new NullListener(), TestFilter.Empty);
391+
392+ Assert.AreSame(context, SynchronizationContext.Current);
393+ Assert.That(result.Executed, Is.True, "Was not executed");
394+ Assert.That(result.ResultState, Is.EqualTo(ResultState.Success), "Wrong result state");
395+ Assert.That(result.AssertCount, Is.EqualTo(1), "Wrong assertion count");
396+ }
397+
398+ private static MethodInfo Method(Expression<Action<AsyncRealFixture>> action)
399+ {
400+ return ((MethodCallExpression)action.Body).Method;
401+ }
402+
403+ public class CustomSynchronizationContext : SynchronizationContext
404+ {
405+ }
406+ }
407+}
408 #endif
409\ No newline at end of file
410
411=== modified file 'src/NUnitCore/tests-net45/NUnitTestCaseBuilderTests.cs'
412--- src/NUnitCore/tests-net45/NUnitTestCaseBuilderTests.cs 2012-10-08 22:03:22 +0000
413+++ src/NUnitCore/tests-net45/NUnitTestCaseBuilderTests.cs 2012-10-14 11:24:24 +0000
414@@ -1,91 +1,93 @@
415-#if NET_3_5 || NET_4_0 || NET_4_5
416-using System.Collections;
417-using System.Reflection;
418-using NUnit.Core;
419-using NUnit.Core.Builders;
420-using NUnit.Framework;
421-using test_assembly_net45;
422-
423-namespace nunit.core.tests.net45
424-{
425- [TestFixture]
426- public class NUnitTestCaseBuilderTests
427- {
428- private NUnitTestCaseBuilder _sut;
429-
430- [SetUp]
431- public void Setup()
432- {
433- _sut = new NUnitTestCaseBuilder();
434- }
435-
436- public IEnumerable AsyncTestsSource
437- {
438- get
439- {
440- yield return new object[] { Method("AsyncVoidTest"), RunState.Runnable };
441- yield return new object[] { Method("AsyncTaskTest"), RunState.Runnable };
442- yield return new object[] { Method("AsyncTaskTTest"), RunState.NotRunnable };
443- }
444- }
445-
446- public IEnumerable AsyncTestCasesSource
447- {
448- get
449- {
450- yield return new object[] { Method("AsyncVoidTestCaseWithResultCheck"), RunState.NotRunnable };
451- yield return new object[] { Method("AsyncTaskTestCaseWithResultCheck"), RunState.NotRunnable };
452- yield return new object[] { Method("AsyncTaskTTestCaseWithResultCheck"), RunState.Runnable };
453- yield return new object[] { Method("AsyncVoidTestCaseWithoutResultCheck"), RunState.Runnable };
454- yield return new object[] { Method("AsyncTaskTestCaseWithoutResultCheck"), RunState.Runnable };
455- yield return new object[] { Method("AsyncTaskTTestCaseWithoutResultCheck"), RunState.NotRunnable };
456- yield return new object[] { Method("AsyncTaskTTestCaseExpectedExceptionWithoutResultCheck"), RunState.Runnable };
457- }
458- }
459-
460- [TestCaseSource("AsyncTestsSource")]
461- public void AsyncTests(MethodInfo method, RunState state)
462- {
463- var built = _sut.BuildFrom(method);
464-
465- Assert.That(built, Is.InstanceOf<NUnitAsyncTestMethod>());
466- Assert.That(built.RunState, Is.EqualTo(state));
467- }
468-
469- [TestCaseSource("AsyncTestCasesSource")]
470- public void AsyncTestCases(MethodInfo method, RunState state)
471- {
472- var built = _sut.BuildFrom(method);
473-
474- var testMethod = built.Tests[0] as NUnitAsyncTestMethod;
475-
476- Assert.IsNotNull(testMethod);
477-
478- Assert.That(testMethod.RunState, Is.EqualTo(state));
479- }
480-
481- [Test]
482- public void Non_async_task()
483- {
484- var built = _sut.BuildFrom(Method("NonAsyncTask"));
485-
486- Assert.That(built, Is.Not.InstanceOf<NUnitAsyncTestMethod>());
487- Assert.That(built.RunState, Is.EqualTo(RunState.NotRunnable));
488- }
489-
490- [Test]
491- public void Non_async_task_with_result()
492- {
493- var built = _sut.BuildFrom(Method("NonAsyncTaskWithResult"));
494-
495- Assert.That(built, Is.Not.InstanceOf<NUnitAsyncTestMethod>());
496- Assert.That(built.RunState, Is.EqualTo(RunState.NotRunnable));
497- }
498-
499- public MethodInfo Method(string name)
500- {
501- return typeof (AsyncDummyFixture).GetMethod(name);
502- }
503- }
504-}
505+#if NET_3_5 || NET_4_0 || NET_4_5
506+using System;
507+using System.Collections;
508+using System.Linq.Expressions;
509+using System.Reflection;
510+using NUnit.Core;
511+using NUnit.Core.Builders;
512+using NUnit.Framework;
513+using test_assembly_net45;
514+
515+namespace nunit.core.tests.net45
516+{
517+ [TestFixture]
518+ public class NUnitTestCaseBuilderTests
519+ {
520+ private NUnitTestCaseBuilder _sut;
521+
522+ [SetUp]
523+ public void Setup()
524+ {
525+ _sut = new NUnitTestCaseBuilder();
526+ }
527+
528+ public IEnumerable AsyncTestsSource
529+ {
530+ get
531+ {
532+ yield return new object[] { Method(f => f.AsyncVoidTest()), RunState.Runnable };
533+ yield return new object[] { Method(f => f.AsyncTaskTest()), RunState.Runnable };
534+ yield return new object[] { Method(f => f.AsyncTaskTTest()), RunState.NotRunnable };
535+ }
536+ }
537+
538+ public IEnumerable AsyncTestCasesSource
539+ {
540+ get
541+ {
542+ yield return new object[] { Method(f => f.AsyncVoidTestCaseWithResultCheck()), RunState.NotRunnable };
543+ yield return new object[] { Method(f => f.AsyncTaskTestCaseWithResultCheck()), RunState.NotRunnable };
544+ yield return new object[] { Method(f => f.AsyncTaskTTestCaseWithResultCheck()), RunState.Runnable };
545+ yield return new object[] { Method(f => f.AsyncVoidTestCaseWithoutResultCheck()), RunState.Runnable };
546+ yield return new object[] { Method(f => f.AsyncTaskTestCaseWithoutResultCheck()), RunState.Runnable };
547+ yield return new object[] { Method(f => f.AsyncTaskTTestCaseWithoutResultCheck()), RunState.NotRunnable };
548+ yield return new object[] { Method(f => f.AsyncTaskTTestCaseExpectedExceptionWithoutResultCheck()), RunState.Runnable };
549+ }
550+ }
551+
552+ [TestCaseSource("AsyncTestsSource")]
553+ public void AsyncTests(MethodInfo method, RunState state)
554+ {
555+ var built = _sut.BuildFrom(method);
556+
557+ Assert.That(built, Is.InstanceOf<NUnitAsyncTestMethod>());
558+ Assert.That(built.RunState, Is.EqualTo(state));
559+ }
560+
561+ [TestCaseSource("AsyncTestCasesSource")]
562+ public void AsyncTestCases(MethodInfo method, RunState state)
563+ {
564+ var built = _sut.BuildFrom(method);
565+
566+ var testMethod = built.Tests[0] as NUnitAsyncTestMethod;
567+
568+ Assert.IsNotNull(testMethod);
569+
570+ Assert.That(testMethod.RunState, Is.EqualTo(state));
571+ }
572+
573+ [Test]
574+ public void Non_async_task()
575+ {
576+ var built = _sut.BuildFrom(Method(f => f.NonAsyncTask()));
577+
578+ Assert.That(built, Is.Not.InstanceOf<NUnitAsyncTestMethod>());
579+ Assert.That(built.RunState, Is.EqualTo(RunState.NotRunnable));
580+ }
581+
582+ [Test]
583+ public void Non_async_task_with_result()
584+ {
585+ var built = _sut.BuildFrom(Method(f => f.NonAsyncTaskWithResult()));
586+
587+ Assert.That(built, Is.Not.InstanceOf<NUnitAsyncTestMethod>());
588+ Assert.That(built.RunState, Is.EqualTo(RunState.NotRunnable));
589+ }
590+
591+ private static MethodInfo Method(Expression<Action<AsyncDummyFixture>> action)
592+ {
593+ return ((MethodCallExpression) action.Body).Method;
594+ }
595+ }
596+}
597 #endif
598\ No newline at end of file
599
600=== modified file 'src/NUnitCore/tests/CallContextTests.cs'
601--- src/NUnitCore/tests/CallContextTests.cs 2009-04-18 20:57:20 +0000
602+++ src/NUnitCore/tests/CallContextTests.cs 2012-10-14 11:24:24 +0000
603@@ -41,13 +41,13 @@
604 [Test]
605 public void ILogicalThreadAffinativeTest()
606 {
607- CallContext.SetData( CONTEXT_DATA, new EmptyCallContextData() );
608+ CallContext.LogicalSetData( CONTEXT_DATA, new EmptyCallContextData() );
609 }
610
611 [Test]
612 public void ILogicalThreadAffinativeTestConsole()
613 {
614- CallContext.SetData( CONTEXT_DATA, new EmptyCallContextData() );
615+ CallContext.LogicalSetData( CONTEXT_DATA, new EmptyCallContextData() );
616 // TODO: make this Assertable
617 //Console.WriteLine("ILogicalThreadAffinativeTest");
618 Console.Out.Flush();
619@@ -60,7 +60,7 @@
620 GenericPrincipal prpal = new GenericPrincipal(ident,
621 new string[] {"Level1"});
622
623- CallContext.SetData( CONTEXT_DATA, new PrincipalCallContextData( prpal ) );
624+ CallContext.LogicalSetData( CONTEXT_DATA, new PrincipalCallContextData( prpal ) );
625 }
626
627 [Test]
628
629=== modified file 'src/NUnitCore/tests/TestContextTests.cs'
630--- src/NUnitCore/tests/TestContextTests.cs 2012-09-25 16:39:42 +0000
631+++ src/NUnitCore/tests/TestContextTests.cs 2012-10-14 11:24:24 +0000
632@@ -5,7 +5,8 @@
633 // ****************************************************************
634
635 using System;
636-using System.IO;
637+using System.IO;
638+using System.Threading;
639 using NUnit.Framework;
640 using NUnit.TestData.TestContextData;
641 using NUnit.TestUtilities;
642@@ -232,9 +233,27 @@
643 }
644
645 [Test, RequiresThread]
646- public void CanAccessTestContextOnSeparateThread()
647- {
648- Assert.That(TestContext.CurrentContext.Test.Name, Is.EqualTo("CanAccessTestContextOnSeparateThread"));
649- }
650+ public void CanAccessTestContextWhenRunningTestOnSeparateThread()
651+ {
652+ Assert.That(TestContext.CurrentContext.Test.Name, Is.EqualTo("CanAccessTestContextWhenRunningTestOnSeparateThread"));
653+ }
654+
655+ [Test]
656+ public void CanAccessTestContextFromThreadSpawnWithinTest()
657+ {
658+ var testName = new object[1];
659+
660+ var thread = new Thread(FillTestNameFromContext);
661+ thread.Start(testName);
662+ thread.Join();
663+
664+ Assert.IsNotNull(testName[0]);
665+ Assert.AreEqual(testName[0], TestContext.CurrentContext.Test.Name);
666+ }
667+
668+ private static void FillTestNameFromContext(object arg)
669+ {
670+ ((object[])arg)[0] = TestContext.CurrentContext.Test.Name;
671+ }
672 }
673-}
674+}
675\ No newline at end of file
676
677=== modified file 'src/NUnitFramework/framework/TestContext.cs'
678--- src/NUnitFramework/framework/TestContext.cs 2011-10-28 17:02:11 +0000
679+++ src/NUnitFramework/framework/TestContext.cs 2012-10-14 11:24:24 +0000
680@@ -47,7 +47,7 @@
681 {
682 get
683 {
684- return new TestContext((IDictionary)CallContext.GetData(contextKey));
685+ return new TestContext((IDictionary)CallContext.LogicalGetData(contextKey));
686 }
687 }
688
689
690=== modified file 'src/tests/test-assembly-net45/AsyncRealFixture.cs'
691--- src/tests/test-assembly-net45/AsyncRealFixture.cs 2012-10-08 22:03:22 +0000
692+++ src/tests/test-assembly-net45/AsyncRealFixture.cs 2012-10-14 11:24:24 +0000
693@@ -1,4 +1,4 @@
694-using System;
695+using System;
696 using System.Threading;
697 using System.Threading.Tasks;
698 using NUnit.Core;
699@@ -101,7 +101,7 @@
700 }
701
702 [Test]
703- public async void VoidAssertSynchrnoizationContext()
704+ public async void VoidAssertSynchronizationContext()
705 {
706 Assert.That(SynchronizationContext.Current, Is.InstanceOf<AsyncSynchronizationContext>());
707 await Task.Yield();
708@@ -174,7 +174,7 @@
709 [Test]
710 public async void VoidTestMultipleError()
711 {
712- var result = await ReturnOne();
713+ await ReturnOne();
714 await ThrowException();
715
716 Assert.Fail("Should never get here");
717@@ -199,12 +199,57 @@
718 [Test]
719 public async Task TaskTestMultipleError()
720 {
721- var result = await ReturnOne();
722+ await ReturnOne();
723 await ThrowException();
724
725 Assert.Fail("Should never get here");
726 }
727
728+ [Test]
729+ public async void VoidCheckTestContextAcrossTasks()
730+ {
731+ var testName = await GetTestNameFromContext();
732+
733+ Assert.IsNotNull(testName);
734+ Assert.AreEqual(testName, TestContext.CurrentContext.Test.Name);
735+ }
736+
737+ [Test]
738+ public async Task TaskCheckTestContextAcrossTasks()
739+ {
740+ var testName = await GetTestNameFromContext();
741+
742+ Assert.IsNotNull(testName);
743+ Assert.AreEqual(testName, TestContext.CurrentContext.Test.Name);
744+ }
745+
746+ [Test]
747+ public async void VoidCheckTestContextWithinTestBody()
748+ {
749+ var testName = TestContext.CurrentContext.Test.Name;
750+
751+ await ReturnOne();
752+
753+ Assert.IsNotNull(testName);
754+ Assert.AreEqual(testName, TestContext.CurrentContext.Test.Name);
755+ }
756+
757+ [Test]
758+ public async Task TaskCheckTestContextWithinTestBody()
759+ {
760+ var testName = TestContext.CurrentContext.Test.Name;
761+
762+ await ReturnOne();
763+
764+ Assert.IsNotNull(testName);
765+ Assert.AreEqual(testName, TestContext.CurrentContext.Test.Name);
766+ }
767+
768+ private static Task<string> GetTestNameFromContext()
769+ {
770+ return Task.Run(() => TestContext.CurrentContext.Test.Name);
771+ }
772+
773 private static Task<int> ReturnOne()
774 {
775 return Task.Run(() => 1);

Subscribers

People subscribed via source and target branches

to status/vote changes: