Skip to content

Commit 3925db7

Browse files
committed
Update code to meet style requirements
1 parent b46622c commit 3925db7

11 files changed

+99
-79
lines changed

Tvl.VisualStudio.MouseFastScroll.IntegrationTests/Threading/StaTaskScheduler.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,6 @@ namespace Tvl.VisualStudio.MouseFastScroll.IntegrationTests.Threading
99

1010
public sealed class StaTaskScheduler : IDisposable
1111
{
12-
/// <summary>Gets a <see cref="StaTaskScheduler"/> for the current <see cref="AppDomain"/>.</summary>
13-
/// <remarks>We use a count of 1, because the editor ends up re-using <see cref="DispatcherObject"/>
14-
/// instances between tests, so we need to always use the same thread for our Sta tests.</remarks>
15-
public static StaTaskScheduler DefaultSta { get; } = new StaTaskScheduler();
16-
17-
/// <summary>The STA threads used by the scheduler.</summary>
18-
public Thread StaThread { get; }
19-
20-
public bool IsRunningInScheduler => StaThread.ManagedThreadId == Thread.CurrentThread.ManagedThreadId;
21-
2212
/// <summary>Initializes a new instance of the <see cref="StaTaskScheduler"/> class.</summary>
2313
public StaTaskScheduler()
2414
{
@@ -30,7 +20,7 @@ public StaTaskScheduler()
3020
var oldContext = SynchronizationContext.Current;
3121
try
3222
{
33-
// All WPF Tests need a DispatcherSynchronizationContext and we dont want to block pending keyboard
23+
// All WPF Tests need a DispatcherSynchronizationContext and we don't want to block pending keyboard
3424
// or mouse input from the user. So use background priority which is a single level below user input.
3525
synchronizationContext = new DispatcherSynchronizationContext();
3626

@@ -54,9 +44,19 @@ public StaTaskScheduler()
5444

5545
threadStartedEvent.Wait();
5646
DispatcherSynchronizationContext = synchronizationContext;
57-
};
47+
}
5848
}
5949

50+
/// <summary>Gets a <see cref="StaTaskScheduler"/> for the current <see cref="AppDomain"/>.</summary>
51+
/// <remarks>We use a count of 1, because the editor ends up re-using <see cref="DispatcherObject"/>
52+
/// instances between tests, so we need to always use the same thread for our Sta tests.</remarks>
53+
public static StaTaskScheduler DefaultSta { get; } = new StaTaskScheduler();
54+
55+
/// <summary>Gets the STA threads used by the scheduler.</summary>
56+
public Thread StaThread { get; }
57+
58+
public bool IsRunningInScheduler => StaThread.ManagedThreadId == Thread.CurrentThread.ManagedThreadId;
59+
6060
public DispatcherSynchronizationContext DispatcherSynchronizationContext
6161
{
6262
get;

Tvl.VisualStudio.MouseFastScroll.IntegrationTests/Threading/SynchronizationContextTaskScheduler.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ internal SynchronizationContextTaskScheduler(SynchronizationContext synchronizat
2020
_synchronizationContext = synchronizationContext ?? throw new ArgumentNullException(nameof(synchronizationContext));
2121
}
2222

23-
public override Int32 MaximumConcurrencyLevel => 1;
23+
public override int MaximumConcurrencyLevel => 1;
2424

2525
protected override void QueueTask(Task task)
2626
{
2727
_synchronizationContext.Post(_postCallback, task);
2828
}
29+
2930
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
3031
{
3132
if (SynchronizationContext.Current == _synchronizationContext)

Tvl.VisualStudio.MouseFastScroll.IntegrationTests/Threading/TaskJoinExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public static void JoinUsingDispatcher(this Task task, CancellationToken cancell
2626
/// Joins a <see cref="Task{TResult}"/> to the current thread with a <see cref="Dispatcher"/> message pump in
2727
/// place during the join operation.
2828
/// </summary>
29+
/// <typeparam name="TResult">The type of value resulting from the asynchronous operation.</typeparam>
2930
public static TResult JoinUsingDispatcher<TResult>(this Task<TResult> task, CancellationToken cancellationToken)
3031
{
3132
JoinUsingDispatcherNoResult(task, cancellationToken);

Tvl.VisualStudio.MouseFastScroll.IntegrationTests/Threading/WpfFactDiscoverer.cs

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,20 @@
33

44
namespace Tvl.VisualStudio.MouseFastScroll.IntegrationTests.Threading
55
{
6-
using System.Collections.Generic;
76
using Xunit.Abstractions;
87
using Xunit.Sdk;
98

109
public class WpfFactDiscoverer : FactDiscoverer
1110
{
1211
private readonly IMessageSink _diagnosticMessageSink;
13-
14-
public WpfFactDiscoverer(IMessageSink diagnosticMessageSink) : base(diagnosticMessageSink)
12+
13+
public WpfFactDiscoverer(IMessageSink diagnosticMessageSink)
14+
: base(diagnosticMessageSink)
1515
{
1616
_diagnosticMessageSink = diagnosticMessageSink;
1717
}
1818

1919
protected override IXunitTestCase CreateTestCase(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
2020
=> new WpfTestCase(_diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), testMethod);
2121
}
22-
23-
public class WpfTheoryDiscoverer : TheoryDiscoverer
24-
{
25-
private readonly IMessageSink _diagnosticMessageSink;
26-
27-
public WpfTheoryDiscoverer(IMessageSink diagnosticMessageSink) : base(diagnosticMessageSink)
28-
{
29-
_diagnosticMessageSink = diagnosticMessageSink;
30-
}
31-
32-
protected override IEnumerable<IXunitTestCase> CreateTestCasesForDataRow(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute, object[] dataRow)
33-
{
34-
var testCase = new WpfTestCase(_diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), testMethod, dataRow);
35-
return new[] { testCase };
36-
}
37-
38-
protected override IEnumerable<IXunitTestCase> CreateTestCasesForTheory(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute)
39-
{
40-
var testCase = new WpfTheoryTestCase(_diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), testMethod);
41-
return new[] { testCase };
42-
}
43-
}
4422
}

Tvl.VisualStudio.MouseFastScroll.IntegrationTests/Threading/WpfTestCase.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,26 @@ namespace Tvl.VisualStudio.MouseFastScroll.IntegrationTests.Threading
1212

1313
public sealed class WpfTestCase : XunitTestCase
1414
{
15-
public WpfTestSharedData SharedData { get; private set; }
16-
1715
[EditorBrowsable(EditorBrowsableState.Never)]
18-
[Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")]
16+
[Obsolete("Called by the deserializer; should only be called by deriving classes for deserialization purposes")]
1917
public WpfTestCase()
2018
{
2119
}
22-
20+
2321
public WpfTestCase(IMessageSink diagnosticMessageSink, TestMethodDisplay defaultMethodDisplay, ITestMethod testMethod, object[] testMethodArguments = null)
2422
: base(diagnosticMessageSink, defaultMethodDisplay, testMethod, testMethodArguments)
2523
{
2624
SharedData = WpfTestSharedData.Instance;
2725
}
28-
26+
27+
public WpfTestSharedData SharedData { get; private set; }
28+
2929
public override Task<RunSummary> RunAsync(IMessageSink diagnosticMessageSink, IMessageBus messageBus, object[] constructorArguments, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource)
3030
{
3131
var runner = new WpfTestCaseRunner(SharedData, this, DisplayName, SkipReason, constructorArguments, TestMethodArguments, messageBus, aggregator, cancellationTokenSource);
3232
return runner.RunAsync();
3333
}
34-
34+
3535
public override void Deserialize(IXunitSerializationInfo data)
3636
{
3737
base.Deserialize(data);

Tvl.VisualStudio.MouseFastScroll.IntegrationTests/Threading/WpfTestCaseRunner.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ namespace Tvl.VisualStudio.MouseFastScroll.IntegrationTests.Threading
1212

1313
public sealed class WpfTestCaseRunner : XunitTestCaseRunner
1414
{
15-
public WpfTestSharedData SharedData { get; }
16-
1715
public WpfTestCaseRunner(
1816
WpfTestSharedData sharedData,
1917
IXunitTestCase testCase,
@@ -29,6 +27,8 @@ public WpfTestCaseRunner(
2927
SharedData = sharedData;
3028
}
3129

30+
public WpfTestSharedData SharedData { get; }
31+
3232
protected override XunitTestRunner CreateTestRunner(ITest test, IMessageBus messageBus, Type testClass, object[] constructorArguments, MethodInfo testMethod, object[] testMethodArguments, string skipReason, IReadOnlyList<BeforeAfterTestAttribute> beforeAfterAttributes, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource)
3333
{
3434
var runner = new WpfTestRunner(SharedData, test, messageBus, testClass, constructorArguments, testMethod, testMethodArguments, skipReason, beforeAfterAttributes, aggregator, cancellationTokenSource);

Tvl.VisualStudio.MouseFastScroll.IntegrationTests/Threading/WpfTestRunner.cs

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,15 @@ namespace Tvl.VisualStudio.MouseFastScroll.IntegrationTests.Threading
1515

1616
/// <summary>
1717
/// This type is actually responsible for spinning up the STA context to run all of the
18-
/// tests.
19-
///
20-
/// Overriding the <see cref="XunitTestInvoker"/> to setup the STA context is not the correct
21-
/// approach. That type begins constructing types before RunAsync and hence ctors end up
18+
/// tests.
19+
///
20+
/// Overriding the <see cref="XunitTestInvoker"/> to setup the STA context is not the correct
21+
/// approach. That type begins constructing types before RunAsync and hence constructors end up
2222
/// running on the current thread vs. the STA ones. Just completely wrapping the invocation
23-
/// here is the best case.
23+
/// here is the best case.
2424
/// </summary>
2525
public sealed class WpfTestRunner : XunitTestRunner
2626
{
27-
public WpfTestSharedData SharedData { get; }
28-
2927
public WpfTestRunner(
3028
WpfTestSharedData sharedData,
3129
ITest test,
@@ -43,31 +41,37 @@ public WpfTestRunner(
4341
SharedData = sharedData;
4442
}
4543

44+
public WpfTestSharedData SharedData { get; }
45+
4646
protected override Task<decimal> InvokeTestMethodAsync(ExceptionAggregator aggregator)
4747
{
4848
SharedData.ExecutingTest(TestMethod);
4949
var sta = StaTaskScheduler.DefaultSta;
50-
var task = Task.Factory.StartNew(async () =>
51-
{
52-
Debug.Assert(sta.StaThread == Thread.CurrentThread);
53-
54-
using (await SharedData.TestSerializationGate.DisposableWaitAsync(CancellationToken.None))
50+
var task = Task.Factory.StartNew(
51+
async () =>
5552
{
56-
try
57-
{
58-
Debug.Assert(SynchronizationContext.Current is DispatcherSynchronizationContext);
53+
Debug.Assert(sta.StaThread == Thread.CurrentThread, "Assertion failed: sta.StaThread == Thread.CurrentThread");
5954

60-
// Just call back into the normal xUnit dispatch process now that we are on an STA Thread with no synchronization context.
61-
var invoker = new XunitTestInvoker(Test, MessageBus, TestClass, ConstructorArguments, TestMethod, TestMethodArguments, BeforeAfterAttributes, aggregator, CancellationTokenSource);
62-
return invoker.RunAsync().JoinUsingDispatcher(CancellationTokenSource.Token);
63-
}
64-
finally
55+
using (await SharedData.TestSerializationGate.DisposableWaitAsync(CancellationToken.None))
6556
{
66-
// Cleanup the synchronization context even if the test is failing exceptionally
67-
SynchronizationContext.SetSynchronizationContext(null);
57+
try
58+
{
59+
Debug.Assert(SynchronizationContext.Current is DispatcherSynchronizationContext, "Assertion failed: SynchronizationContext.Current is DispatcherSynchronizationContext");
60+
61+
// Just call back into the normal xUnit dispatch process now that we are on an STA Thread with no synchronization context.
62+
var invoker = new XunitTestInvoker(Test, MessageBus, TestClass, ConstructorArguments, TestMethod, TestMethodArguments, BeforeAfterAttributes, aggregator, CancellationTokenSource);
63+
return invoker.RunAsync().JoinUsingDispatcher(CancellationTokenSource.Token);
64+
}
65+
finally
66+
{
67+
// Cleanup the synchronization context even if the test is failing exceptionally
68+
SynchronizationContext.SetSynchronizationContext(null);
69+
}
6870
}
69-
}
70-
}, CancellationTokenSource.Token, TaskCreationOptions.None, new SynchronizationContextTaskScheduler(sta.DispatcherSynchronizationContext));
71+
},
72+
CancellationTokenSource.Token,
73+
TaskCreationOptions.None,
74+
new SynchronizationContextTaskScheduler(sta.DispatcherSynchronizationContext));
7175

7276
return task.Unwrap();
7377
}

Tvl.VisualStudio.MouseFastScroll.IntegrationTests/Threading/WpfTestSharedData.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,19 @@ public sealed class WpfTestSharedData
2323
internal static readonly Guid TestSerializationGateName = Guid.NewGuid();
2424

2525
/// <summary>
26-
/// Holds the last 10 test cases executed: more recent test cases will occur later in the
27-
/// list. Useful for debugging deadlocks that occur because state leak between runs.
26+
/// Holds the last 10 test cases executed: more recent test cases will occur later in the
27+
/// list. Useful for debugging deadlocks that occur because state leak between runs.
2828
/// </summary>
2929
private readonly List<string> _recentTestCases = new List<string>();
3030

31-
public Semaphore TestSerializationGate = new Semaphore(1, 1, TestSerializationGateName.ToString("N"));
31+
private Semaphore _testSerializationGate = new Semaphore(1, 1, TestSerializationGateName.ToString("N"));
3232

3333
private WpfTestSharedData()
3434
{
3535
}
3636

37+
public Semaphore TestSerializationGate => _testSerializationGate;
38+
3739
public void ExecutingTest(ITestMethod testMethod)
3840
{
3941
var name = $"{testMethod.TestClass.Class.Name}::{testMethod.Method.Name}";
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the Apache License, Version 2.0. See LICENSE.txt in the project root for license information.
3+
4+
namespace Tvl.VisualStudio.MouseFastScroll.IntegrationTests.Threading
5+
{
6+
using System.Collections.Generic;
7+
using Xunit.Abstractions;
8+
using Xunit.Sdk;
9+
10+
public class WpfTheoryDiscoverer : TheoryDiscoverer
11+
{
12+
private readonly IMessageSink _diagnosticMessageSink;
13+
14+
public WpfTheoryDiscoverer(IMessageSink diagnosticMessageSink)
15+
: base(diagnosticMessageSink)
16+
{
17+
_diagnosticMessageSink = diagnosticMessageSink;
18+
}
19+
20+
protected override IEnumerable<IXunitTestCase> CreateTestCasesForDataRow(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute, object[] dataRow)
21+
{
22+
var testCase = new WpfTestCase(_diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), testMethod, dataRow);
23+
return new[] { testCase };
24+
}
25+
26+
protected override IEnumerable<IXunitTestCase> CreateTestCasesForTheory(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute)
27+
{
28+
var testCase = new WpfTheoryTestCase(_diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), testMethod);
29+
return new[] { testCase };
30+
}
31+
}
32+
}

Tvl.VisualStudio.MouseFastScroll.IntegrationTests/Threading/WpfTheoryTestCase.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,20 @@ namespace Tvl.VisualStudio.MouseFastScroll.IntegrationTests.Threading
1212

1313
public class WpfTheoryTestCase : XunitTheoryTestCase
1414
{
15-
public WpfTestSharedData SharedData { get; private set; }
16-
1715
[EditorBrowsable(EditorBrowsableState.Never)]
18-
[Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")]
19-
public WpfTheoryTestCase() { }
16+
[Obsolete("Called by the deserializer; should only be called by deriving classes for deserialization purposes")]
17+
public WpfTheoryTestCase()
18+
{
19+
}
2020

2121
public WpfTheoryTestCase(IMessageSink diagnosticMessageSink, TestMethodDisplay defaultMethodDisplay, ITestMethod testMethod)
2222
: base(diagnosticMessageSink, defaultMethodDisplay, testMethod)
2323
{
2424
SharedData = WpfTestSharedData.Instance;
2525
}
2626

27+
public WpfTestSharedData SharedData { get; private set; }
28+
2729
public override void Deserialize(IXunitSerializationInfo data)
2830
{
2931
base.Deserialize(data);

0 commit comments

Comments
 (0)