Skip to content

Commit 932d12c

Browse files
committed
threadlocal console splitter
1 parent 4471183 commit 932d12c

File tree

2 files changed

+39
-37
lines changed

2 files changed

+39
-37
lines changed

tests/FSharp.Test.Utilities/CompilerAssert.fs

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -607,33 +607,20 @@ module rec CompilerAssertHelpers =
607607
compileCompilationAux outputDirectory (ResizeArray()) ignoreWarnings cmpl
608608

609609
let captureConsoleOutputs (func: unit -> unit) =
610-
let out = Console.Out
611-
let err = Console.Error
612-
613-
let stdout = StringBuilder ()
614-
let stderr = StringBuilder ()
615-
616-
use outWriter = new StringWriter (stdout)
617-
use errWriter = new StringWriter (stderr)
610+
Console.installWriters()
618611

619612
let succeeded, exn =
620613
try
621-
try
622-
Console.SetOut outWriter
623-
Console.SetError errWriter
624-
func ()
625-
true, None
626-
with e ->
627-
let errorMessage = if e.InnerException <> null then e.InnerException.ToString() else e.ToString()
628-
stderr.Append errorMessage |> ignore
629-
false, Some e
630-
finally
631-
Console.SetOut out
632-
Console.SetError err
633-
outWriter.Close()
634-
errWriter.Close()
635-
636-
succeeded, stdout.ToString(), stderr.ToString(), exn
614+
func ()
615+
true, None
616+
with e ->
617+
let errorMessage = if e.InnerException <> null then e.InnerException.ToString() else e.ToString()
618+
Console.Error.Write errorMessage
619+
false, Some e
620+
621+
let out, err = Console.getOutputs()
622+
623+
succeeded, out, err, exn
637624

638625
let executeBuiltAppAndReturnResult (outputFilePath: string) (deps: string list) isFsx : (int * string * string) =
639626
let succeeded, stdout, stderr, _ = executeBuiltApp outputFilePath deps isFsx

tests/FSharp.Test.Utilities/Utilities.fs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,32 @@ type FactForDESKTOPAttribute() =
3838
do base.Skip <- "NETCOREAPP is not supported runtime for this kind of test, it is intended for DESKTOP only"
3939
#endif
4040

41+
module Console =
42+
type ThreadLocalTextWriter() =
43+
inherit TextWriter()
44+
static let threadLocalWriter = new ThreadLocal<TextWriter>(fun () -> new StringWriter() :> TextWriter )
45+
override _.Encoding = threadLocalWriter.Value.Encoding
46+
override _.Write(value: char) = threadLocalWriter.Value.Write(value)
47+
override _.Write(value: string) = threadLocalWriter.Value.Write(value)
48+
override _.WriteLine(value: string) = threadLocalWriter.Value.WriteLine(value)
49+
member _.Reset() = threadLocalWriter.Value <- new StringWriter()
50+
member _.Set writer = threadLocalWriter.Value <- writer
51+
member _.GetText() = threadLocalWriter.Value.ToString()
52+
53+
let private out = new ThreadLocalTextWriter()
54+
let private err = new ThreadLocalTextWriter()
55+
56+
let installWriters() =
57+
out.Reset()
58+
err.Reset()
59+
Console.SetOut out
60+
Console.SetError err
61+
62+
let getOutputs() = out.GetText(), err.GetText()
63+
64+
let setOut writer = out.Set writer
65+
66+
let setError writer = err.Set writer
4167

4268
// This file mimics how Roslyn handles their compilation references for compilation testing
4369
module Utilities =
@@ -53,17 +79,6 @@ module Utilities =
5379
override _.Read() =
5480
if queue.Count > 0 then queue.Dequeue() |> int else -1
5581

56-
type RedirectConsoleInput() =
57-
let oldStdIn = Console.In
58-
let newStdIn = new CapturedTextReader()
59-
do Console.SetIn(newStdIn)
60-
member _.ProvideInput(text: string) =
61-
newStdIn.ProvideInput(text)
62-
interface IDisposable with
63-
member _.Dispose() =
64-
Console.SetIn(oldStdIn)
65-
newStdIn.Dispose()
66-
6782
type EventedTextWriter() =
6883
inherit TextWriter()
6984
let sb = StringBuilder()
@@ -90,8 +105,8 @@ module Utilities =
90105

91106
do newStdOut.LineWritten.Add outputProduced.Trigger
92107
do newStdErr.LineWritten.Add errorProduced.Trigger
93-
do Console.SetOut(newStdOut)
94-
do Console.SetError(newStdErr)
108+
do Console.setOut newStdOut
109+
do Console.setError newStdErr
95110

96111
member _.OutputProduced = outputProduced.Publish
97112

0 commit comments

Comments
 (0)