-
Notifications
You must be signed in to change notification settings - Fork 420
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add RunTestsInContext Command #1782
Merged
Merged
Changes from 1 commit
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
fa096c3
Use 3.1 SDK
333fred dfc26f3
Asyncify existing test command runners.
333fred 3cd7cd7
Add RunTestsInContextComment
333fred 27da006
Remove extra unused variables.
333fred 90e0cc6
Add DebugTestsInContextGetStartInfo command.
333fred 467dd6d
Clean up formatting.
333fred 800a0a6
Ensure all test projects are also using netcoreapp3.1.
333fred a921905
Bump MSTest project version.
333fred a1863f0
Merge branch 'master' into tests-in-containing-symbol
JoeRobich a7be80d
Update test frameworks as approprate
333fred 2943b1f
Added comment after boundary testing space to stop formatters.
333fred 147c96b
Use windows-latest pool
333fred ca3e321
Refactor the test-finder to run before actually running a full build,…
333fred f9310a2
Merge branch 'master' into tests-in-containing-symbol
filipw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
src/OmniSharp.DotNetTest/Models/BaseTestsInContextRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
|
||
#nullable enable | ||
|
||
using OmniSharp.Mef; | ||
using OmniSharp.Models; | ||
|
||
namespace OmniSharp.DotNetTest.Models | ||
{ | ||
public abstract class BaseTestsInContextRequest : Request | ||
{ | ||
public string? RunSettings { get; set; } | ||
/// <summary> | ||
/// e.g. .NETCoreApp, Version=2.0 | ||
/// </summary> | ||
public string? TargetFrameworkVersion { get; set; } | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/OmniSharp.DotNetTest/Models/DebugTestsInContextGetStartInfoRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
#nullable enable | ||
|
||
using OmniSharp.Mef; | ||
|
||
namespace OmniSharp.DotNetTest.Models | ||
{ | ||
[OmniSharpEndpoint(OmniSharpEndpoints.V2.DebugTestsInContextGetStartInfo, typeof(DebugTestsInContextGetStartInfoRequest), typeof(DebugTestGetStartInfoResponse))] | ||
public class DebugTestsInContextGetStartInfoRequest : BaseTestsInContextRequest | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,11 @@ | ||
#nullable enable | ||
|
||
using OmniSharp.Mef; | ||
using OmniSharp.Models; | ||
|
||
namespace OmniSharp.DotNetTest.Models | ||
{ | ||
[OmniSharpEndpoint(OmniSharpEndpoints.V2.RunTestsInContext, typeof(RunTestsInContextRequest), typeof(RunTestResponse))] | ||
public class RunTestsInContextRequest : Request | ||
public class RunTestsInContextRequest : BaseTestsInContextRequest | ||
{ | ||
public string? RunSettings { get; set; } | ||
public string TestFrameworkName { get; set; } = null!; | ||
/// <summary> | ||
/// e.g. .NETCoreApp, Version=2.0 | ||
/// </summary> | ||
public string? TargetFrameworkVersion { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
src/OmniSharp.DotNetTest/Services/DebugTestsInContextService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#nullable enable | ||
|
||
using System; | ||
using System.Composition; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.Extensions.Logging; | ||
using OmniSharp.DotNetTest.Models; | ||
using OmniSharp.Eventing; | ||
using OmniSharp.Mef; | ||
using OmniSharp.Services; | ||
|
||
namespace OmniSharp.DotNetTest.Services | ||
{ | ||
[Shared] | ||
[OmniSharpHandler(OmniSharpEndpoints.V2.DebugTestsInContextGetStartInfo, LanguageNames.CSharp)] | ||
internal class DebugTestsInContextService : BaseTestService, | ||
IRequestHandler<DebugTestsInContextGetStartInfoRequest, DebugTestGetStartInfoResponse> | ||
{ | ||
private readonly DebugSessionManager _debugSessionManager; | ||
|
||
[ImportingConstructor] | ||
public DebugTestsInContextService(DebugSessionManager debugSessionManager, OmniSharpWorkspace workspace, IDotNetCliService dotNetCli, IEventEmitter eventEmitter, ILoggerFactory loggerFactory) | ||
: base(workspace, dotNetCli, eventEmitter, loggerFactory) | ||
{ | ||
_debugSessionManager = debugSessionManager; | ||
} | ||
|
||
public Task<DebugTestGetStartInfoResponse> Handle(DebugTestsInContextGetStartInfoRequest request) | ||
{ | ||
var testManager = CreateTestManager(request.FileName); | ||
if (testManager.IsConnected) | ||
{ | ||
_debugSessionManager.StartSession(testManager); | ||
return _debugSessionManager.DebugGetStartInfoAsync( | ||
request.Line, request.Column, Workspace.GetDocument(request.FileName), | ||
request.RunSettings, request.TargetFrameworkVersion, | ||
CancellationToken.None); | ||
} | ||
|
||
throw new InvalidOperationException("The debugger could not be started"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,6 @@ | |
using System.Diagnostics; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis; | ||
|
@@ -148,6 +147,22 @@ public override async Task<GetTestStartInfoResponse> GetTestStartInfoAsync(strin | |
}; | ||
} | ||
|
||
#nullable enable | ||
public override async Task<DebugTestGetStartInfoResponse> DebugGetStartInfoAsync(int line, int column, Document contextDocument, string? runSettings, string? targetFrameworkVersion, CancellationToken cancellationToken) | ||
{ | ||
var (methodNames, testFramework) = await GetContextTestMethodNames(line, column, contextDocument, cancellationToken); | ||
|
||
if (methodNames is null) | ||
{ | ||
throw new InvalidOperationException("Could not find a test to debug"); | ||
} | ||
|
||
Debug.Assert(testFramework is object); | ||
|
||
return await DebugGetStartInfoAsync(methodNames, runSettings, testFramework, targetFrameworkVersion, cancellationToken); | ||
} | ||
#nullable restore | ||
|
||
public override async Task<DebugTestGetStartInfoResponse> DebugGetStartInfoAsync(string methodName, string runSettings, string testFrameworkName, string targetFrameworkVersion, CancellationToken cancellationToken) | ||
=> await DebugGetStartInfoAsync(new string[] { methodName }, runSettings, testFrameworkName, targetFrameworkVersion, cancellationToken); | ||
|
||
|
@@ -209,27 +224,19 @@ public override async Task DebugLaunchAsync(CancellationToken cancellationToken) | |
} | ||
|
||
#nullable enable | ||
public override async Task<RunTestResponse> RunTestsInContextAsync(int line, int column, Document contextDocument, string? runSettings, string testFrameworkName, string? targetFrameworkVersion, CancellationToken cancellationToken) | ||
private async Task<(string[]? MethodNames, string? TestFramework)> GetContextTestMethodNames(int line, int column, Document contextDocument, CancellationToken cancellationToken) | ||
{ | ||
Logger.LogDebug($"Loading info for {contextDocument.FilePath} {line}:{column}"); | ||
var syntaxTree = await contextDocument.GetSyntaxTreeAsync(cancellationToken); | ||
if (syntaxTree is null) | ||
{ | ||
return new RunTestResponse() | ||
{ | ||
Pass = false, | ||
Failure = $"Could not get syntax for {contextDocument.FilePath}" | ||
}; | ||
return default; | ||
} | ||
|
||
var semanticModel = await contextDocument.GetSemanticModelAsync(cancellationToken); | ||
if (semanticModel is null) | ||
{ | ||
return new RunTestResponse() | ||
{ | ||
Pass = false, | ||
Failure = $"Could not get semantic model for {contextDocument.FilePath}" | ||
}; | ||
return default; | ||
} | ||
|
||
var sourceText = await contextDocument.GetTextAsync(); | ||
|
@@ -238,6 +245,7 @@ public override async Task<RunTestResponse> RunTestsInContextAsync(int line, int | |
var node = (await syntaxTree.GetRootAsync()).FindToken(position).Parent; | ||
|
||
string[]? methodNames = null; | ||
TestFramework? testFramework = null; | ||
|
||
while (node is object) | ||
{ | ||
|
@@ -261,7 +269,7 @@ public override async Task<RunTestResponse> RunTestsInContextAsync(int line, int | |
continue; | ||
} | ||
|
||
if (isTestMethod(methodSymbol)) | ||
if (isTestMethod(methodSymbol, ref testFramework)) | ||
{ | ||
methodNames = new[] { methodSymbol.GetMetadataName() }; | ||
Logger.LogDebug($"Found test method {methodNames[0]}"); | ||
|
@@ -285,7 +293,7 @@ public override async Task<RunTestResponse> RunTestsInContextAsync(int line, int | |
|
||
foreach (var member in members) | ||
{ | ||
if (!(member is IMethodSymbol methodSymbol) || !isTestMethod(methodSymbol)) | ||
if (!(member is IMethodSymbol methodSymbol) || !isTestMethod(methodSymbol, ref testFramework)) | ||
{ | ||
continue; | ||
} | ||
|
@@ -309,6 +317,32 @@ public override async Task<RunTestResponse> RunTestsInContextAsync(int line, int | |
node = node.Parent; | ||
} | ||
|
||
return (methodNames, testFramework?.Name); | ||
|
||
static bool isTestMethod(IMethodSymbol methodSymbol, ref TestFramework? framework) | ||
{ | ||
if (framework is object) | ||
{ | ||
return framework.IsTestMethod(methodSymbol); | ||
} | ||
|
||
foreach (var f in TestFramework.Frameworks) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically, this means that you can't combine multiple testing framework types in a single file and have them run all at once. I think that's probably fine. |
||
{ | ||
if (f.IsTestMethod(methodSymbol)) | ||
{ | ||
framework = f; | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} | ||
|
||
public override async Task<RunTestResponse> RunTestsInContextAsync(int line, int column, Document contextDocument, string? runSettings, string? targetFrameworkVersion, CancellationToken cancellationToken) | ||
{ | ||
var (methodNames, testFrameworkName) = await GetContextTestMethodNames(line, column, contextDocument, cancellationToken); | ||
|
||
if (methodNames is null) | ||
{ | ||
return new RunTestResponse | ||
|
@@ -318,9 +352,10 @@ public override async Task<RunTestResponse> RunTestsInContextAsync(int line, int | |
}; | ||
} | ||
|
||
Debug.Assert(testFrameworkName is object); | ||
|
||
return await RunTestAsync(methodNames, runSettings, testFrameworkName, targetFrameworkVersion, cancellationToken); | ||
|
||
static bool isTestMethod(IMethodSymbol methodSymbol) => TestFramework.GetFrameworks().Any(f => f.IsTestMethod(methodSymbol)); | ||
} | ||
#nullable restore | ||
|
||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These seem unfortunate, especially for the
InContext
version of the command, but the existingDebugTestGetStartInfoResponse
doesn't have a place for a failure and failure message. I would have modified that to add a field, but I'm unsure if that will break existing clients. Is that a safe change to make, or should I add a new response that adds a failure/reason to it?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure whether this would be a problem for other clients. Maybe @filipw knows definitively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should be fine - additive changes are generally fine since it's json based.
moreover, the debug tests protocl is - I am pretty sure - only used by VS Code extension since the debugger is proprietary