Skip to content

Commit 6c9d8a5

Browse files
authored
Merge pull request OmniSharp#1782 from 333fred/tests-in-containing-symbol
Add RunTestsInContext Command
2 parents 7278aba + f9310a2 commit 6c9d8a5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+816
-180
lines changed

.pipelines/init.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
parameters:
22
# Configuration: Release
33
Verbosity: Normal
4-
DotNetVersion: "3.0.100"
4+
DotNetVersion: "3.1.201"
55
CakeVersion: "0.32.1"
66
NuGetVersion: "4.9.2"
77
steps:

azure-pipelines.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ resources:
2222

2323
variables:
2424
Verbosity: Diagnostic
25-
DotNetVersion: "3.0.100"
25+
DotNetVersion: "3.1.201"
2626
CakeVersion: "0.32.1"
2727
NuGetVersion: "4.9.2"
2828
GitVersionVersion: "5.0.1"
@@ -105,7 +105,7 @@ jobs:
105105

106106
- job: Windows
107107
pool:
108-
vmImage: "VS2017-Win2016"
108+
vmImage: "windows-latest"
109109
dependsOn: GitVersion
110110
steps:
111111
- template: ./.pipelines/init.yml

build.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"DotNetInstallScriptURL": "https://dot.net/v1",
33
"DotNetChannel": "Preview",
44
"DotNetVersions": [
5-
"3.0.100",
5+
"3.1.201",
66
"5.0.100-preview.2.20169.1"
77
],
88
"RequiredMonoVersion": "6.6.0",
@@ -41,7 +41,7 @@
4141
"ProjectWithDisabledAnalyzers",
4242
"ProjectWithDisabledAnalyzers2",
4343
"ProjectWithAnalyzers",
44-
"NetCore30Project",
44+
"NetCore31Project",
4545
"Net50Project",
4646
"ProjectWithAnalyzersAndEditorConfig",
4747
"ProjectWithParentEditorConfig"

global.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"sdk": {
3-
"version": "3.0.100"
3+
"version": "3.1.201"
44
}
55
}

omnisharp.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"script": {
33
"enableScriptNuGetReferences": true,
4-
"defaultTargetFramework": "netcoreapp3.0"
4+
"defaultTargetFramework": "netcoreapp3.1"
55
}
6-
}
6+
}

src/OmniSharp.Abstractions/OmniSharpEndpoints.cs

+2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@ public static class V2
5555
public const string RunAllTestsInClass = "/v2/runtestsinclass";
5656
public const string DebugTestGetStartInfo = "/v2/debugtest/getstartinfo";
5757
public const string DebugTestLaunch = "/v2/debugtest/launch";
58+
public const string DebugTestsInContextGetStartInfo = "/v2/debugtestsincontext/getstartinfo";
5859
public const string DebugTestStop = "/v2/debugtest/stop";
5960
public const string DebugTestsInClassGetStartInfo = "/v2/debugtestsinclass/getstartinfo";
61+
public const string RunTestsInContext = "/v2/runtestsincontext";
6062

6163
public const string BlockStructure = "/v2/blockstructure";
6264
public const string CodeStructure = "/v2/codestructure";

src/OmniSharp.DotNetTest/DebugSessionManager.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Diagnostics;
44
using System.Threading;
55
using System.Threading.Tasks;
6+
using Microsoft.CodeAnalysis;
67
using Microsoft.Extensions.Logging;
78
using OmniSharp.DotNetTest.Models;
89
using OmniSharp.Utilities;
@@ -79,7 +80,7 @@ public void EndSession()
7980

8081
public Task<DebugTestGetStartInfoResponse> DebugGetStartInfoAsync(string methodName, string runSettings, string testFrameworkName, string targetFrameworkVersion, CancellationToken cancellationToken)
8182
=> DebugGetStartInfoAsync(new string[] { methodName }, runSettings, testFrameworkName, targetFrameworkVersion, cancellationToken);
82-
83+
8384
public Task<DebugTestGetStartInfoResponse> DebugGetStartInfoAsync(string[] methodNames, string runSettings, string testFrameworkName, string targetFrameworkVersion, CancellationToken cancellationToken)
8485
{
8586
VerifySession(isStarted: true);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#nullable enable
2+
3+
using OmniSharp.Models;
4+
5+
namespace OmniSharp.DotNetTest.Models
6+
{
7+
public abstract class BaseTestsInContextRequest : Request
8+
{
9+
public string? RunSettings { get; set; }
10+
/// <summary>
11+
/// e.g. .NETCoreApp, Version=2.0
12+
/// </summary>
13+
public string? TargetFrameworkVersion { get; set; }
14+
}
15+
}

src/OmniSharp.DotNetTest/Models/DebugTestGetStartInfoResponse.cs

+3
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,8 @@ public class DebugTestGetStartInfoResponse
88
public string Arguments { get; set; }
99
public string WorkingDirectory { get; set; }
1010
public IDictionary<string, string> EnvironmentVariables { get; set; }
11+
public bool Succeeded { get; set; }
12+
public bool ContextHadNoTests { get; set; }
13+
public string FailureReason { get; set; }
1114
}
1215
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#nullable enable
2+
3+
using OmniSharp.Mef;
4+
5+
namespace OmniSharp.DotNetTest.Models
6+
{
7+
[OmniSharpEndpoint(OmniSharpEndpoints.V2.DebugTestsInContextGetStartInfo, typeof(DebugTestsInContextGetStartInfoRequest), typeof(DebugTestGetStartInfoResponse))]
8+
public class DebugTestsInContextGetStartInfoRequest : BaseTestsInContextRequest
9+
{
10+
}
11+
}

src/OmniSharp.DotNetTest/Models/RunTestResponse.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ public class RunTestResponse
55
public DotNetTestResult[] Results { get; set; }
66
public bool Pass { get; set; }
77
public string Failure { get; set; }
8+
public bool ContextHadNoTests { get; set; }
89
}
9-
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#nullable enable
2+
3+
using OmniSharp.Mef;
4+
5+
namespace OmniSharp.DotNetTest.Models
6+
{
7+
[OmniSharpEndpoint(OmniSharpEndpoints.V2.RunTestsInContext, typeof(RunTestsInContextRequest), typeof(RunTestResponse))]
8+
public class RunTestsInContextRequest : BaseTestsInContextRequest
9+
{
10+
}
11+
}

src/OmniSharp.DotNetTest/Services/BaseTestService`2.cs

+4-7
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,12 @@ protected BaseTestService(OmniSharpWorkspace workspace, IDotNetCliService dotNet
1717
{
1818
}
1919

20-
protected abstract TResponse HandleRequest(TRequest request, TestManager testManager);
20+
protected abstract Task<TResponse> HandleRequest(TRequest request, TestManager testManager);
2121

22-
public Task<TResponse> Handle(TRequest request)
22+
public async Task<TResponse> Handle(TRequest request)
2323
{
24-
using (var testManager = CreateTestManager(request.FileName))
25-
{
26-
var response = HandleRequest(request, testManager);
27-
return Task.FromResult(response);
28-
}
24+
using var testManager = CreateTestManager(request.FileName);
25+
return await HandleRequest(request, testManager);
2926
}
3027
}
3128
}

src/OmniSharp.DotNetTest/Services/DebugTestService.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ internal class DebugTestService : BaseTestService,
2020
IRequestHandler<DebugTestLaunchRequest, DebugTestLaunchResponse>,
2121
IRequestHandler<DebugTestStopRequest, DebugTestStopResponse>
2222
{
23-
private DebugSessionManager _debugSessionManager;
23+
private readonly DebugSessionManager _debugSessionManager;
2424

2525
[ImportingConstructor]
2626
public DebugTestService(DebugSessionManager debugSessionManager, OmniSharpWorkspace workspace, IDotNetCliService dotNetCli, IEventEmitter eventEmitter, ILoggerFactory loggerFactory)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#nullable enable
2+
3+
using System;
4+
using System.Composition;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
using Microsoft.CodeAnalysis;
8+
using Microsoft.Extensions.Logging;
9+
using OmniSharp.DotNetTest.Models;
10+
using OmniSharp.Eventing;
11+
using OmniSharp.Mef;
12+
using OmniSharp.Services;
13+
14+
namespace OmniSharp.DotNetTest.Services
15+
{
16+
[Shared]
17+
[OmniSharpHandler(OmniSharpEndpoints.V2.DebugTestsInContextGetStartInfo, LanguageNames.CSharp)]
18+
internal class DebugTestsInContextService : BaseTestService,
19+
IRequestHandler<DebugTestsInContextGetStartInfoRequest, DebugTestGetStartInfoResponse>
20+
{
21+
private readonly DebugSessionManager _debugSessionManager;
22+
23+
[ImportingConstructor]
24+
public DebugTestsInContextService(DebugSessionManager debugSessionManager, OmniSharpWorkspace workspace, IDotNetCliService dotNetCli, IEventEmitter eventEmitter, ILoggerFactory loggerFactory)
25+
: base(workspace, dotNetCli, eventEmitter, loggerFactory)
26+
{
27+
_debugSessionManager = debugSessionManager;
28+
}
29+
30+
public async Task<DebugTestGetStartInfoResponse> Handle(DebugTestsInContextGetStartInfoRequest request)
31+
{
32+
var document = Workspace.GetDocument(request.FileName);
33+
if (document is null)
34+
{
35+
return new DebugTestGetStartInfoResponse
36+
{
37+
Succeeded = false,
38+
FailureReason = "File is not part of a C# project in the loaded solution.",
39+
ContextHadNoTests = true,
40+
};
41+
}
42+
43+
var testManager = TestManager.Create(document.Project, DotNetCli, EventEmitter, LoggerFactory);
44+
45+
var (methodNames, testFramework) = await testManager.GetContextTestMethodNames(request.Line, request.Column, document, CancellationToken.None);
46+
47+
if (methodNames is null)
48+
{
49+
return new DebugTestGetStartInfoResponse
50+
{
51+
Succeeded = false,
52+
FailureReason = "Could not find any tests to run",
53+
ContextHadNoTests = true,
54+
55+
};
56+
}
57+
58+
testManager.Connect();
59+
60+
if (testManager.IsConnected)
61+
{
62+
_debugSessionManager.StartSession(testManager);
63+
return await _debugSessionManager.DebugGetStartInfoAsync(methodNames, request.RunSettings, testFramework, request.TargetFrameworkVersion, CancellationToken.None);
64+
}
65+
66+
return new DebugTestGetStartInfoResponse
67+
{
68+
FailureReason = "Failed to connect to the 'dotnet test' process",
69+
Succeeded = false
70+
};
71+
}
72+
}
73+
}

src/OmniSharp.DotNetTest/Services/GetTestStartInfoService.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Composition;
2+
using System.Threading.Tasks;
23
using Microsoft.CodeAnalysis;
34
using Microsoft.Extensions.Logging;
45
using OmniSharp.DotNetTest.Models;
@@ -17,9 +18,9 @@ public GetTestStartInfoService(OmniSharpWorkspace workspace, IDotNetCliService d
1718
{
1819
}
1920

20-
protected override GetTestStartInfoResponse HandleRequest(GetTestStartInfoRequest request, TestManager testManager)
21+
protected override Task<GetTestStartInfoResponse> HandleRequest(GetTestStartInfoRequest request, TestManager testManager)
2122
{
22-
return testManager.GetTestStartInfo(request.MethodName, request.RunSettings, request.TestFrameworkName, request.TargetFrameworkVersion);
23+
return testManager.GetTestStartInfoAsync(request.MethodName, request.RunSettings, request.TestFrameworkName, request.TargetFrameworkVersion, cancellationToken: default);
2324
}
2425
}
2526
}

src/OmniSharp.DotNetTest/Services/RunTestService.cs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System.Composition;
2+
using System.Threading;
3+
using System.Threading.Tasks;
24
using Microsoft.CodeAnalysis;
35
using Microsoft.Extensions.Logging;
46
using OmniSharp.DotNetTest.Models;
@@ -17,20 +19,21 @@ public RunTestService(OmniSharpWorkspace workspace, IDotNetCliService dotNetCli,
1719
{
1820
}
1921

20-
protected override RunTestResponse HandleRequest(RunTestRequest request, TestManager testManager)
22+
protected override Task<RunTestResponse> HandleRequest(RunTestRequest request, TestManager testManager)
2123
{
2224
if (testManager.IsConnected)
2325
{
24-
return testManager.RunTest(request.MethodName, request.RunSettings, request.TestFrameworkName, request.TargetFrameworkVersion);
26+
return testManager.RunTestAsync(request.MethodName, request.RunSettings, request.TestFrameworkName, request.TargetFrameworkVersion, CancellationToken.None);
2527
}
2628

2729
var response = new RunTestResponse
2830
{
2931
Failure = "Failed to connect to 'dotnet test' process",
30-
Pass = false
32+
Pass = false,
33+
ContextHadNoTests = false
3134
};
3235

33-
return response;
36+
return Task.FromResult(response);
3437
}
3538
}
3639
}

src/OmniSharp.DotNetTest/Services/RunTestsInClassService.cs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System.Composition;
2+
using System.Threading;
3+
using System.Threading.Tasks;
24
using Microsoft.CodeAnalysis;
35
using Microsoft.Extensions.Logging;
46
using OmniSharp.DotNetTest.Models;
@@ -17,17 +19,18 @@ public RunTestsInClassService(OmniSharpWorkspace workspace, IDotNetCliService do
1719
{
1820
}
1921

20-
protected override RunTestResponse HandleRequest(RunTestsInClassRequest request, TestManager testManager)
22+
protected override async Task<RunTestResponse> HandleRequest(RunTestsInClassRequest request, TestManager testManager)
2123
{
2224
if (testManager.IsConnected)
2325
{
24-
return testManager.RunTest(request.MethodNames, request.RunSettings, request.TestFrameworkName, request.TargetFrameworkVersion);
26+
return await testManager.RunTestAsync(request.MethodNames, request.RunSettings, request.TestFrameworkName, request.TargetFrameworkVersion, CancellationToken.None);
2527
}
2628

2729
var response = new RunTestResponse
2830
{
2931
Failure = "Failed to connect to 'dotnet test' process",
30-
Pass = false
32+
Pass = false,
33+
ContextHadNoTests = false
3134
};
3235

3336
return response;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#nullable enable
2+
3+
using System.Composition;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using Microsoft.CodeAnalysis;
7+
using Microsoft.Extensions.Logging;
8+
using OmniSharp.DotNetTest.Models;
9+
using OmniSharp.Eventing;
10+
using OmniSharp.Mef;
11+
using OmniSharp.Services;
12+
13+
namespace OmniSharp.DotNetTest.Services
14+
{
15+
[OmniSharpHandler(OmniSharpEndpoints.V2.RunTestsInContext, LanguageNames.CSharp)]
16+
internal class RunTestsInContextService : BaseTestService, IRequestHandler<RunTestsInContextRequest, RunTestResponse>
17+
{
18+
[ImportingConstructor]
19+
public RunTestsInContextService(OmniSharpWorkspace workspace, IDotNetCliService dotNetCli, IEventEmitter eventEmitter, ILoggerFactory loggerFactory)
20+
: base(workspace, dotNetCli, eventEmitter, loggerFactory)
21+
{
22+
}
23+
24+
public async Task<RunTestResponse> Handle(RunTestsInContextRequest request)
25+
{
26+
var document = Workspace.GetDocument(request.FileName);
27+
if (document is null)
28+
{
29+
return new RunTestResponse
30+
{
31+
Failure = "File is not part of a C# project in the loaded solution.",
32+
Pass = false,
33+
ContextHadNoTests = true
34+
};
35+
}
36+
37+
using var testManager = TestManager.Create(document.Project, DotNetCli, EventEmitter, LoggerFactory);
38+
39+
var (methodNames, testFramework) = await testManager.GetContextTestMethodNames(request.Line, request.Column, document, CancellationToken.None);
40+
41+
if (methodNames is null)
42+
{
43+
return new RunTestResponse
44+
{
45+
Pass = false,
46+
Failure = "Could not find any tests to run",
47+
ContextHadNoTests = true
48+
};
49+
}
50+
51+
testManager.Connect();
52+
53+
if (testManager.IsConnected)
54+
{
55+
return await testManager.RunTestAsync(methodNames, request.RunSettings, testFramework, request.TargetFrameworkVersion, CancellationToken.None);
56+
}
57+
58+
var response = new RunTestResponse
59+
{
60+
Failure = "Failed to connect to 'dotnet test' process",
61+
Pass = false,
62+
ContextHadNoTests = false
63+
};
64+
65+
return response;
66+
}
67+
}
68+
}

0 commit comments

Comments
 (0)