Skip to content

Commit 85a4e0f

Browse files
committed
Split the VSTest wrapper code from TestServer contracts for clarity
1 parent 72728d2 commit 85a4e0f

File tree

3 files changed

+196
-195
lines changed

3 files changed

+196
-195
lines changed

src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<Compile Include="Debug.fs" />
2020
<Compile Include="Utils.fsi" />
2121
<Compile Include="Utils.fs" />
22+
<Compile Include="VSTestWrapper.fs" />
2223
<Compile Include="TestServer.fs" />
2324
<Compile Include="TestAdapter.fs" />
2425
<Compile Include="DotnetNewTemplate.fs" />

src/FsAutoComplete.Core/TestServer.fs

Lines changed: 0 additions & 195 deletions
Original file line numberDiff line numberDiff line change
@@ -2,201 +2,6 @@ namespace FsAutoComplete.TestServer
22

33
open System
44

5-
module VSTestWrapper =
6-
open Microsoft.TestPlatform.VsTestConsole.TranslationLayer
7-
open Microsoft.VisualStudio.TestPlatform.ObjectModel
8-
open Microsoft.VisualStudio.TestPlatform.ObjectModel.Client
9-
open Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging
10-
open System.Text.RegularExpressions
11-
open Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces
12-
13-
type TestProjectDll = string
14-
15-
type TestDiscoveryUpdate =
16-
| Progress of TestCase list
17-
| LogMessage of TestMessageLevel * string
18-
19-
type private TestDiscoveryHandler(notifyDiscoveryProgress: TestDiscoveryUpdate -> unit) =
20-
21-
member val DiscoveredTests: TestCase ResizeArray = ResizeArray() with get, set
22-
23-
interface ITestDiscoveryEventsHandler with
24-
member this.HandleDiscoveredTests(discoveredTestCases: System.Collections.Generic.IEnumerable<TestCase>) : unit =
25-
if (not << isNull) discoveredTestCases then
26-
this.DiscoveredTests.AddRange(discoveredTestCases)
27-
notifyDiscoveryProgress (discoveredTestCases |> List.ofSeq |> Progress)
28-
29-
member this.HandleDiscoveryComplete
30-
(_totalTests: int64, lastChunk: System.Collections.Generic.IEnumerable<TestCase>, _isAborted: bool)
31-
: unit =
32-
if (not << isNull) lastChunk then
33-
this.DiscoveredTests.AddRange(lastChunk)
34-
notifyDiscoveryProgress (lastChunk |> List.ofSeq |> Progress)
35-
36-
member this.HandleLogMessage(level: TestMessageLevel, message: string) : unit =
37-
notifyDiscoveryProgress (LogMessage(level, message))
38-
39-
member this.HandleRawMessage(_rawMessage: string) : unit = ()
40-
41-
let discoverTestsAsync
42-
(vstestPath: string)
43-
(onDiscoveryProgress: TestDiscoveryUpdate -> unit)
44-
(sources: TestProjectDll list)
45-
: Async<TestCase list> =
46-
async {
47-
let consoleParams = ConsoleParameters()
48-
let vstest = new VsTestConsoleWrapper(vstestPath, consoleParams)
49-
let discoveryHandler = TestDiscoveryHandler(onDiscoveryProgress)
50-
51-
use! _onCancel = Async.OnCancel(fun () -> vstest.CancelDiscovery())
52-
53-
vstest.DiscoverTests(sources, null, discoveryHandler)
54-
return discoveryHandler.DiscoveredTests |> List.ofSeq
55-
}
56-
57-
type ProcessId = int
58-
type DidDebuggerAttach = bool
59-
60-
type TestRunUpdate =
61-
| Progress of TestRunChangedEventArgs
62-
| LogMessage of TestMessageLevel * string
63-
64-
type TestRunHandler(notifyTestRunProgress: TestRunUpdate -> unit) =
65-
66-
member val TestResults: TestResult ResizeArray = ResizeArray() with get, set
67-
68-
interface ITestRunEventsHandler with
69-
member _.HandleLogMessage(level: TestMessageLevel, message: string) : unit =
70-
notifyTestRunProgress (LogMessage(level, message))
71-
72-
member _.HandleRawMessage(_rawMessage: string) : unit = ()
73-
74-
member this.HandleTestRunComplete
75-
(
76-
_testRunCompleteArgs: TestRunCompleteEventArgs,
77-
lastChunkArgs: TestRunChangedEventArgs,
78-
_runContextAttachments: System.Collections.Generic.ICollection<AttachmentSet>,
79-
_executorUris: System.Collections.Generic.ICollection<string>
80-
) : unit =
81-
if ((not << isNull) lastChunkArgs && (not << isNull) lastChunkArgs.NewTestResults) then
82-
this.TestResults.AddRange(lastChunkArgs.NewTestResults)
83-
notifyTestRunProgress (Progress lastChunkArgs)
84-
85-
member this.HandleTestRunStatsChange(testRunChangedArgs: TestRunChangedEventArgs) : unit =
86-
if
87-
((not << isNull) testRunChangedArgs
88-
&& (not << isNull) testRunChangedArgs.NewTestResults)
89-
then
90-
this.TestResults.AddRange(testRunChangedArgs.NewTestResults)
91-
notifyTestRunProgress (Progress testRunChangedArgs)
92-
93-
member _.LaunchProcessWithDebuggerAttached(_testProcessStartInfo: TestProcessStartInfo) : int =
94-
raise (System.NotImplementedException())
95-
96-
type TestHostLauncher(isDebug: bool, onAttachDebugger: ProcessId -> DidDebuggerAttach) =
97-
// IMPORTANT: RunTestsWithCustomTestHost says it takes an ITestHostLauncher, but it actually calls a method that is only available on ITestHostLauncher3
98-
99-
interface ITestHostLauncher3 with
100-
member _.IsDebug: bool = isDebug
101-
102-
member _.LaunchTestHost(_defaultTestHostStartInfo: TestProcessStartInfo) : int = raise (NotImplementedException())
103-
104-
member _.LaunchTestHost
105-
(_defaultTestHostStartInfo: TestProcessStartInfo, _cancellationToken: Threading.CancellationToken)
106-
: int =
107-
raise (NotImplementedException())
108-
109-
member _.AttachDebuggerToProcess
110-
(attachDebuggerInfo: AttachDebuggerInfo, _cancellationToken: Threading.CancellationToken)
111-
: bool =
112-
onAttachDebugger attachDebuggerInfo.ProcessId
113-
114-
member _.AttachDebuggerToProcess(pid: int) : bool = onAttachDebugger pid
115-
116-
member _.AttachDebuggerToProcess(pid: int, _cancellationToken: Threading.CancellationToken) : bool =
117-
onAttachDebugger pid
118-
119-
120-
module TestPlatformOptions =
121-
let withTestCaseFilter (options: TestPlatformOptions) filterExpression = options.TestCaseFilter <- filterExpression
122-
123-
module RunSettings =
124-
let defaultRunSettings =
125-
"<RunSettings>
126-
<RunConfiguration>
127-
<DesignMode>False</DesignMode>
128-
</RunConfiguration>
129-
</RunSettings>"
130-
131-
/// onAttachDebugger assumes that the debugger is attached when the method returns. The test project will continue execution as soon as attachDebugger returns
132-
let runTestsAsync
133-
(vstestPath: string)
134-
(onTestRunProgress: TestRunUpdate -> unit)
135-
(onAttachDebugger: ProcessId -> DidDebuggerAttach)
136-
(sources: TestProjectDll list)
137-
(testCaseFilter: string option)
138-
(shouldDebug: bool)
139-
: Async<TestResult list> =
140-
async {
141-
let consoleParams = ConsoleParameters()
142-
let vstest = new VsTestConsoleWrapper(vstestPath, consoleParams)
143-
let runHandler = TestRunHandler(onTestRunProgress)
144-
let runSettings = RunSettings.defaultRunSettings
145-
146-
let options = new TestPlatformOptions()
147-
testCaseFilter |> Option.iter (TestPlatformOptions.withTestCaseFilter options)
148-
149-
use! _cancel =
150-
Async.OnCancel(fun () ->
151-
printfn "Cancelling test run"
152-
vstest.CancelTestRun()
153-
printfn "Test Run Cancelled")
154-
155-
if shouldDebug then
156-
let hostLauncher = TestHostLauncher(shouldDebug, onAttachDebugger)
157-
vstest.RunTestsWithCustomTestHost(sources, runSettings, options, runHandler, hostLauncher)
158-
else
159-
vstest.RunTests(sources, runSettings, options, runHandler)
160-
161-
return runHandler.TestResults |> List.ofSeq
162-
}
163-
164-
165-
open System.IO
166-
167-
let tryFindVsTestFromDotnetRoot (dotnetRoot: string) (workspaceRoot: string option) : Result<FileInfo, string> =
168-
let cwd =
169-
defaultArg workspaceRoot System.Environment.CurrentDirectory |> DirectoryInfo
170-
171-
let dotnetBinary =
172-
if dotnetRoot |> Directory.Exists then
173-
if
174-
System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
175-
System.Runtime.InteropServices.OSPlatform.Windows
176-
)
177-
then
178-
FileInfo(Path.Combine(dotnetRoot, "dotnet.exe"))
179-
else
180-
FileInfo(Path.Combine(dotnetRoot, "dotnet"))
181-
else
182-
dotnetRoot |> FileInfo
183-
184-
match Ionide.ProjInfo.SdkDiscovery.versionAt cwd dotnetBinary with
185-
| Ok sdkVersion ->
186-
let sdks = Ionide.ProjInfo.SdkDiscovery.sdks dotnetBinary
187-
188-
match sdks |> Array.tryFind (fun sdk -> sdk.Version = sdkVersion) with
189-
| Some sdk ->
190-
let vstestBinary = Path.Combine(sdk.Path.FullName, "vstest.console.dll") |> FileInfo
191-
192-
if vstestBinary.Exists then
193-
Ok vstestBinary
194-
else
195-
Error $"Found the correct dotnet sdk, but vstest was not at the expected sub-path: {vstestBinary.FullName}"
196-
| None -> Error $"Couldn't find the install location for dotnet sdk version: {sdkVersion}"
197-
| Error _ -> Error $"Couldn't identify the dotnet version for working directory: {cwd.FullName}"
198-
199-
2005
type TestFileRange = { StartLine: int; EndLine: int }
2016

2027
type TestItem =

0 commit comments

Comments
 (0)