提交 2960d57f 编写于 作者: S Sam Harwell

Extract helper class TestFixtureHelper<TFixture>

上级 5d594694
...@@ -38,8 +38,7 @@ public abstract class AbstractCompletionProviderTests<TWorkspaceFixture> : TestB ...@@ -38,8 +38,7 @@ public abstract class AbstractCompletionProviderTests<TWorkspaceFixture> : TestB
{ {
private static readonly TestComposition s_baseComposition = EditorTestCompositions.EditorFeatures.AddExcludedPartTypes(typeof(CompletionProvider)); private static readonly TestComposition s_baseComposition = EditorTestCompositions.EditorFeatures.AddExcludedPartTypes(typeof(CompletionProvider));
private readonly object _workspaceFixtureGate = new(); private readonly TestFixtureHelper<TWorkspaceFixture> _fixtureHelper = new();
private ReferenceCountedDisposable<TWorkspaceFixture>.WeakReference _weakWorkspaceFixture;
protected readonly Mock<ICompletionSession> MockCompletionSession; protected readonly Mock<ICompletionSession> MockCompletionSession;
private ExportProvider _lazyExportProvider; private ExportProvider _lazyExportProvider;
...@@ -56,17 +55,7 @@ protected virtual TestComposition GetComposition() ...@@ -56,17 +55,7 @@ protected virtual TestComposition GetComposition()
=> s_baseComposition.AddParts(GetCompletionProviderType()); => s_baseComposition.AddParts(GetCompletionProviderType());
private protected ReferenceCountedDisposable<TWorkspaceFixture> GetOrCreateWorkspaceFixture() private protected ReferenceCountedDisposable<TWorkspaceFixture> GetOrCreateWorkspaceFixture()
{ => _fixtureHelper.GetOrCreateFixture();
lock (_workspaceFixtureGate)
{
if (_weakWorkspaceFixture.TryAddReference() is { } workspaceFixture)
return workspaceFixture;
var result = new ReferenceCountedDisposable<TWorkspaceFixture>(new TWorkspaceFixture());
_weakWorkspaceFixture = new ReferenceCountedDisposable<TWorkspaceFixture>.WeakReference(result);
return result;
}
}
protected static async Task<bool> CanUseSpeculativeSemanticModelAsync(Document document, int position) protected static async Task<bool> CanUseSpeculativeSemanticModelAsync(Document document, int position)
{ {
......
...@@ -22,21 +22,10 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.RefactoringHelpers ...@@ -22,21 +22,10 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.RefactoringHelpers
public abstract class RefactoringHelpersTestBase<TWorkspaceFixture> : TestBase public abstract class RefactoringHelpersTestBase<TWorkspaceFixture> : TestBase
where TWorkspaceFixture : TestWorkspaceFixture, new() where TWorkspaceFixture : TestWorkspaceFixture, new()
{ {
private readonly object _workspaceFixtureGate = new(); private readonly TestFixtureHelper<TWorkspaceFixture> _fixtureHelper = new();
private ReferenceCountedDisposable<TWorkspaceFixture>.WeakReference _weakWorkspaceFixture;
private protected ReferenceCountedDisposable<TWorkspaceFixture> GetOrCreateWorkspaceFixture() private protected ReferenceCountedDisposable<TWorkspaceFixture> GetOrCreateWorkspaceFixture()
{ => _fixtureHelper.GetOrCreateFixture();
lock (_workspaceFixtureGate)
{
if (_weakWorkspaceFixture.TryAddReference() is { } workspaceFixture)
return workspaceFixture;
var result = new ReferenceCountedDisposable<TWorkspaceFixture>(new TWorkspaceFixture());
_weakWorkspaceFixture = new ReferenceCountedDisposable<TWorkspaceFixture>.WeakReference(result);
return result;
}
}
protected Task TestAsync<TNode>(string text) where TNode : SyntaxNode => TestAsync<TNode>(text, Functions<TNode>.True); protected Task TestAsync<TNode>(string text) where TNode : SyntaxNode => TestAsync<TNode>(text, Functions<TNode>.True);
......
...@@ -28,23 +28,12 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.SignatureHelp ...@@ -28,23 +28,12 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.SignatureHelp
public abstract class AbstractSignatureHelpProviderTests<TWorkspaceFixture> : TestBase public abstract class AbstractSignatureHelpProviderTests<TWorkspaceFixture> : TestBase
where TWorkspaceFixture : TestWorkspaceFixture, new() where TWorkspaceFixture : TestWorkspaceFixture, new()
{ {
private readonly object _workspaceFixtureGate = new(); private readonly TestFixtureHelper<TWorkspaceFixture> _fixtureHelper = new();
private ReferenceCountedDisposable<TWorkspaceFixture>.WeakReference _weakWorkspaceFixture;
internal abstract Type GetSignatureHelpProviderType(); internal abstract Type GetSignatureHelpProviderType();
private protected ReferenceCountedDisposable<TWorkspaceFixture> GetOrCreateWorkspaceFixture() private protected ReferenceCountedDisposable<TWorkspaceFixture> GetOrCreateWorkspaceFixture()
{ => _fixtureHelper.GetOrCreateFixture();
lock (_workspaceFixtureGate)
{
if (_weakWorkspaceFixture.TryAddReference() is { } workspaceFixture)
return workspaceFixture;
var result = new ReferenceCountedDisposable<TWorkspaceFixture>(new TWorkspaceFixture());
_weakWorkspaceFixture = new ReferenceCountedDisposable<TWorkspaceFixture>.WeakReference(result);
return result;
}
}
/// <summary> /// <summary>
/// Verifies that sighelp comes up at the indicated location in markup ($$), with the indicated span [| ... |]. /// Verifies that sighelp comes up at the indicated location in markup ($$), with the indicated span [| ... |].
......
...@@ -17,21 +17,10 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.TypeInferrer ...@@ -17,21 +17,10 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.TypeInferrer
public abstract class TypeInferrerTestBase<TWorkspaceFixture> : TestBase public abstract class TypeInferrerTestBase<TWorkspaceFixture> : TestBase
where TWorkspaceFixture : TestWorkspaceFixture, new() where TWorkspaceFixture : TestWorkspaceFixture, new()
{ {
private readonly object _workspaceFixtureGate = new(); private readonly TestFixtureHelper<TWorkspaceFixture> _fixtureHelper = new();
private ReferenceCountedDisposable<TWorkspaceFixture>.WeakReference _weakWorkspaceFixture;
private protected ReferenceCountedDisposable<TWorkspaceFixture> GetOrCreateWorkspaceFixture() private protected ReferenceCountedDisposable<TWorkspaceFixture> GetOrCreateWorkspaceFixture()
{ => _fixtureHelper.GetOrCreateFixture();
lock (_workspaceFixtureGate)
{
if (_weakWorkspaceFixture.TryAddReference() is { } workspaceFixture)
return workspaceFixture;
var result = new ReferenceCountedDisposable<TWorkspaceFixture>(new TWorkspaceFixture());
_weakWorkspaceFixture = new ReferenceCountedDisposable<TWorkspaceFixture>.WeakReference(result);
return result;
}
}
private static async Task<bool> CanUseSpeculativeSemanticModelAsync(Document document, int position) private static async Task<bool> CanUseSpeculativeSemanticModelAsync(Document document, int position)
{ {
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.UnitTests
{
internal sealed class TestFixtureHelper<TFixture>
where TFixture : class, IDisposable, new()
{
private readonly object _gate = new();
/// <summary>
/// Holds a weak reference to the current test fixture instance. This reference allows
/// <see cref="GetOrCreateFixture"/> to access and add a reference to the current test fixture if one exists,
/// but does not prevent the fixture from being disposed after the last reference to it is released.
/// </summary>
private ReferenceCountedDisposable<TFixture>.WeakReference _weakFixture;
/// <summary>
/// Gets a reference to a test fixture, or creates it if one does not already exist.
/// </summary>
/// <remarks>
/// <para>The resulting test fixture will not be disposed until the last referencer disposes of its reference.
/// It is possible for more than one test fixture to be created during the life of any single test, but only one
/// test fixture will be live at any given point.</para>
///
/// <para>The following shows how a block of test code can ensure a single test fixture is created and used
/// within any given block of code:</para>
///
/// <code>
/// using (var fixture = GetOrCreateFixture())
/// {
/// // The test fixture 'fixture' is guaranteed to not be released or replaced within this block
/// }
/// </code>
/// </remarks>
/// <returns>The test fixture instance.</returns>
internal ReferenceCountedDisposable<TFixture> GetOrCreateFixture()
{
lock (_gate)
{
if (_weakFixture.TryAddReference() is { } fixture)
return fixture;
var result = new ReferenceCountedDisposable<TFixture>(new TFixture());
_weakFixture = new ReferenceCountedDisposable<TFixture>.WeakReference(result);
return result;
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册