mirror of
https://github.com/Tyrrrz/CliFx.git
synced 2025-10-25 15:19:17 +00:00
Expose raw streams in IConsole to allow writing/reading binary data
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
using CliFx.Tests.TestCommands;
|
using CliFx.Tests.TestCommands;
|
||||||
|
|
||||||
namespace CliFx.Tests
|
namespace CliFx.Tests
|
||||||
@@ -27,7 +26,7 @@ namespace CliFx.Tests
|
|||||||
.UseExecutableName("test")
|
.UseExecutableName("test")
|
||||||
.UseVersionText("test")
|
.UseVersionText("test")
|
||||||
.UseDescription("test")
|
.UseDescription("test")
|
||||||
.UseConsole(new VirtualConsole(TextWriter.Null))
|
.UseConsole(new VirtualConsole())
|
||||||
.UseTypeActivator(Activator.CreateInstance)
|
.UseTypeActivator(Activator.CreateInstance)
|
||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -320,8 +320,7 @@ namespace CliFx.Tests
|
|||||||
string? expectedStdOut = null)
|
string? expectedStdOut = null)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
await using var stdOutStream = new StringWriter();
|
using var console = new VirtualConsole();
|
||||||
var console = new VirtualConsole(stdOutStream);
|
|
||||||
|
|
||||||
var application = new CliApplicationBuilder()
|
var application = new CliApplicationBuilder()
|
||||||
.AddCommands(commandTypes)
|
.AddCommands(commandTypes)
|
||||||
@@ -333,7 +332,7 @@ namespace CliFx.Tests
|
|||||||
|
|
||||||
// Act
|
// Act
|
||||||
var exitCode = await application.RunAsync(commandLineArguments, environmentVariables);
|
var exitCode = await application.RunAsync(commandLineArguments, environmentVariables);
|
||||||
var stdOut = stdOutStream.ToString().Trim();
|
var stdOut = console.ReadOutputString().Trim();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
exitCode.Should().Be(0);
|
exitCode.Should().Be(0);
|
||||||
@@ -354,8 +353,7 @@ namespace CliFx.Tests
|
|||||||
int? expectedExitCode = null)
|
int? expectedExitCode = null)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
await using var stdErrStream = new StringWriter();
|
using var console = new VirtualConsole();
|
||||||
var console = new VirtualConsole(TextWriter.Null, stdErrStream);
|
|
||||||
|
|
||||||
var application = new CliApplicationBuilder()
|
var application = new CliApplicationBuilder()
|
||||||
.AddCommands(commandTypes)
|
.AddCommands(commandTypes)
|
||||||
@@ -367,19 +365,19 @@ namespace CliFx.Tests
|
|||||||
|
|
||||||
// Act
|
// Act
|
||||||
var exitCode = await application.RunAsync(commandLineArguments, environmentVariables);
|
var exitCode = await application.RunAsync(commandLineArguments, environmentVariables);
|
||||||
var stderr = stdErrStream.ToString().Trim();
|
var stdErr = console.ReadErrorString().Trim();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
exitCode.Should().NotBe(0);
|
exitCode.Should().NotBe(0);
|
||||||
stderr.Should().NotBeNullOrWhiteSpace();
|
stdErr.Should().NotBeNullOrWhiteSpace();
|
||||||
|
|
||||||
if (expectedExitCode != null)
|
if (expectedExitCode != null)
|
||||||
exitCode.Should().Be(expectedExitCode);
|
exitCode.Should().Be(expectedExitCode);
|
||||||
|
|
||||||
if (expectedStdErr != null)
|
if (expectedStdErr != null)
|
||||||
stderr.Should().Be(expectedStdErr);
|
stdErr.Should().Be(expectedStdErr);
|
||||||
|
|
||||||
Console.WriteLine(stderr);
|
Console.WriteLine(stdErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCaseSource(nameof(GetTestCases_RunAsync_Help))]
|
[TestCaseSource(nameof(GetTestCases_RunAsync_Help))]
|
||||||
@@ -389,8 +387,7 @@ namespace CliFx.Tests
|
|||||||
IReadOnlyList<string>? expectedSubstrings = null)
|
IReadOnlyList<string>? expectedSubstrings = null)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
await using var stdOutStream = new StringWriter();
|
using var console = new VirtualConsole();
|
||||||
var console = new VirtualConsole(stdOutStream);
|
|
||||||
|
|
||||||
var application = new CliApplicationBuilder()
|
var application = new CliApplicationBuilder()
|
||||||
.AddCommands(commandTypes)
|
.AddCommands(commandTypes)
|
||||||
@@ -404,7 +401,7 @@ namespace CliFx.Tests
|
|||||||
|
|
||||||
// Act
|
// Act
|
||||||
var exitCode = await application.RunAsync(commandLineArguments, environmentVariables);
|
var exitCode = await application.RunAsync(commandLineArguments, environmentVariables);
|
||||||
var stdOut = stdOutStream.ToString().Trim();
|
var stdOut = console.ReadOutputString().Trim();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
exitCode.Should().Be(0);
|
exitCode.Should().Be(0);
|
||||||
@@ -420,11 +417,7 @@ namespace CliFx.Tests
|
|||||||
public async Task RunAsync_Cancellation_Test()
|
public async Task RunAsync_Cancellation_Test()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
using var cancellationTokenSource = new CancellationTokenSource();
|
using var console = new VirtualConsole();
|
||||||
|
|
||||||
await using var stdOutStream = new StringWriter();
|
|
||||||
await using var stdErrStream = new StringWriter();
|
|
||||||
var console = new VirtualConsole(stdOutStream, stdErrStream, cancellationTokenSource.Token);
|
|
||||||
|
|
||||||
var application = new CliApplicationBuilder()
|
var application = new CliApplicationBuilder()
|
||||||
.AddCommand(typeof(CancellableCommand))
|
.AddCommand(typeof(CancellableCommand))
|
||||||
@@ -435,10 +428,11 @@ namespace CliFx.Tests
|
|||||||
var environmentVariables = new Dictionary<string, string>();
|
var environmentVariables = new Dictionary<string, string>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(0.2));
|
console.CancelAfter(TimeSpan.FromSeconds(0.2));
|
||||||
|
|
||||||
var exitCode = await application.RunAsync(commandLineArguments, environmentVariables);
|
var exitCode = await application.RunAsync(commandLineArguments, environmentVariables);
|
||||||
var stdOut = stdOutStream.ToString().Trim();
|
var stdOut = console.ReadOutputString().Trim();
|
||||||
var stdErr = stdErrStream.ToString().Trim();
|
var stdErr = console.ReadErrorString().Trim();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
exitCode.Should().NotBe(0);
|
exitCode.Should().NotBe(0);
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
using System;
|
|
||||||
using FluentAssertions;
|
|
||||||
using NUnit.Framework;
|
|
||||||
|
|
||||||
namespace CliFx.Tests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class SystemConsoleTests
|
|
||||||
{
|
|
||||||
[TearDown]
|
|
||||||
public void TearDown()
|
|
||||||
{
|
|
||||||
// Reset console color so it doesn't carry on into the next tests
|
|
||||||
Console.ResetColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test(Description = "Must be in sync with system console")]
|
|
||||||
public void Smoke_Test()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var console = new SystemConsole();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
console.ResetColor();
|
|
||||||
console.ForegroundColor = ConsoleColor.DarkMagenta;
|
|
||||||
console.BackgroundColor = ConsoleColor.DarkMagenta;
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
console.Input.Should().BeSameAs(Console.In);
|
|
||||||
console.IsInputRedirected.Should().Be(Console.IsInputRedirected);
|
|
||||||
console.Output.Should().BeSameAs(Console.Out);
|
|
||||||
console.IsOutputRedirected.Should().Be(Console.IsOutputRedirected);
|
|
||||||
console.Error.Should().BeSameAs(Console.Error);
|
|
||||||
console.IsErrorRedirected.Should().Be(Console.IsErrorRedirected);
|
|
||||||
console.ForegroundColor.Should().Be(Console.ForegroundColor);
|
|
||||||
console.BackgroundColor.Should().Be(Console.BackgroundColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
using System.Globalization;
|
using System.Linq;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using CliFx.Utilities;
|
using CliFx.Utilities;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@@ -14,31 +12,25 @@ namespace CliFx.Tests.Utilities
|
|||||||
public void Report_Test()
|
public void Report_Test()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var formatProvider = CultureInfo.InvariantCulture;
|
using var console = new VirtualConsole(false);
|
||||||
|
|
||||||
using var stdout = new StringWriter(formatProvider);
|
|
||||||
|
|
||||||
var console = new VirtualConsole(TextReader.Null, false, stdout, false, TextWriter.Null, false);
|
|
||||||
var ticker = console.CreateProgressTicker();
|
var ticker = console.CreateProgressTicker();
|
||||||
|
|
||||||
var progressValues = Enumerable.Range(0, 100).Select(p => p / 100.0).ToArray();
|
var progressValues = Enumerable.Range(0, 100).Select(p => p / 100.0).ToArray();
|
||||||
var progressStringValues = progressValues.Select(p => p.ToString("P2", formatProvider)).ToArray();
|
var progressStringValues = progressValues.Select(p => p.ToString("P2")).ToArray();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
foreach (var progress in progressValues)
|
foreach (var progress in progressValues)
|
||||||
ticker.Report(progress);
|
ticker.Report(progress);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
stdout.ToString().Should().ContainAll(progressStringValues);
|
console.ReadOutputString().Should().ContainAll(progressStringValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Report_Redirected_Test()
|
public void Report_Redirected_Test()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
using var stdout = new StringWriter();
|
using var console = new VirtualConsole();
|
||||||
|
|
||||||
var console = new VirtualConsole(stdout);
|
|
||||||
var ticker = console.CreateProgressTicker();
|
var ticker = console.CreateProgressTicker();
|
||||||
|
|
||||||
var progressValues = Enumerable.Range(0, 100).Select(p => p / 100.0).ToArray();
|
var progressValues = Enumerable.Range(0, 100).Select(p => p / 100.0).ToArray();
|
||||||
@@ -48,7 +40,7 @@ namespace CliFx.Tests.Utilities
|
|||||||
ticker.Report(progress);
|
ticker.Report(progress);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
stdout.ToString().Should().BeEmpty();
|
console.ReadOutputString().Should().BeEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
@@ -12,11 +11,8 @@ namespace CliFx.Tests
|
|||||||
public void Smoke_Test()
|
public void Smoke_Test()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
using var stdin = new StringReader("hello world");
|
using var console = new VirtualConsole();
|
||||||
using var stdout = new StringWriter();
|
console.WriteInputString("hello world");
|
||||||
using var stderr = new StringWriter();
|
|
||||||
|
|
||||||
var console = new VirtualConsole(stdin, stdout, stderr);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
console.ResetColor();
|
console.ResetColor();
|
||||||
@@ -24,13 +20,10 @@ namespace CliFx.Tests
|
|||||||
console.BackgroundColor = ConsoleColor.DarkMagenta;
|
console.BackgroundColor = ConsoleColor.DarkMagenta;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
console.Input.Should().BeSameAs(stdin);
|
|
||||||
console.Input.Should().NotBeSameAs(Console.In);
|
console.Input.Should().NotBeSameAs(Console.In);
|
||||||
console.IsInputRedirected.Should().BeTrue();
|
console.IsInputRedirected.Should().BeTrue();
|
||||||
console.Output.Should().BeSameAs(stdout);
|
|
||||||
console.Output.Should().NotBeSameAs(Console.Out);
|
console.Output.Should().NotBeSameAs(Console.Out);
|
||||||
console.IsOutputRedirected.Should().BeTrue();
|
console.IsOutputRedirected.Should().BeTrue();
|
||||||
console.Error.Should().BeSameAs(stderr);
|
|
||||||
console.Error.Should().NotBeSameAs(Console.Error);
|
console.Error.Should().NotBeSameAs(Console.Error);
|
||||||
console.IsErrorRedirected.Should().BeTrue();
|
console.IsErrorRedirected.Should().BeTrue();
|
||||||
console.ForegroundColor.Should().NotBe(Console.ForegroundColor);
|
console.ForegroundColor.Should().NotBe(Console.ForegroundColor);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace CliFx
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Input stream (stdin).
|
/// Input stream (stdin).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
TextReader Input { get; }
|
StreamReader Input { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the input stream is redirected.
|
/// Whether the input stream is redirected.
|
||||||
@@ -22,7 +22,7 @@ namespace CliFx
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Output stream (stdout).
|
/// Output stream (stdout).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
TextWriter Output { get; }
|
StreamWriter Output { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the output stream is redirected.
|
/// Whether the output stream is redirected.
|
||||||
@@ -32,7 +32,7 @@ namespace CliFx
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Error stream (stderr).
|
/// Error stream (stderr).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
TextWriter Error { get; }
|
StreamWriter Error { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the error stream is redirected.
|
/// Whether the error stream is redirected.
|
||||||
|
|||||||
@@ -12,19 +12,19 @@ namespace CliFx
|
|||||||
private CancellationTokenSource? _cancellationTokenSource;
|
private CancellationTokenSource? _cancellationTokenSource;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public TextReader Input => Console.In;
|
public StreamReader Input { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsInputRedirected => Console.IsInputRedirected;
|
public bool IsInputRedirected => Console.IsInputRedirected;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public TextWriter Output => Console.Out;
|
public StreamWriter Output { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsOutputRedirected => Console.IsOutputRedirected;
|
public bool IsOutputRedirected => Console.IsOutputRedirected;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public TextWriter Error => Console.Error;
|
public StreamWriter Error { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsErrorRedirected => Console.IsErrorRedirected;
|
public bool IsErrorRedirected => Console.IsErrorRedirected;
|
||||||
@@ -43,6 +43,16 @@ namespace CliFx
|
|||||||
set => Console.BackgroundColor = value;
|
set => Console.BackgroundColor = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes an instance of <see cref="SystemConsole"/>.
|
||||||
|
/// </summary>
|
||||||
|
public SystemConsole()
|
||||||
|
{
|
||||||
|
Input = new StreamReader(Console.OpenStandardInput(), Console.InputEncoding, false);
|
||||||
|
Output = new StreamWriter(Console.OpenStandardOutput(), Console.OutputEncoding) {AutoFlush = true};
|
||||||
|
Error = new StreamWriter(Console.OpenStandardError(), Console.OutputEncoding) {AutoFlush = true};
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void ResetColor() => Console.ResetColor();
|
public void ResetColor() => Console.ResetColor();
|
||||||
|
|
||||||
|
|||||||
@@ -9,24 +9,92 @@ namespace CliFx
|
|||||||
/// Does not leak to system console in any way.
|
/// Does not leak to system console in any way.
|
||||||
/// Use this class as a substitute for system console when running tests.
|
/// Use this class as a substitute for system console when running tests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class VirtualConsole : IConsole
|
public partial class VirtualConsole
|
||||||
{
|
{
|
||||||
private readonly CancellationToken _cancellationToken;
|
private readonly MemoryStream _inputStream = new MemoryStream();
|
||||||
|
private readonly MemoryStream _outputStream = new MemoryStream();
|
||||||
|
private readonly MemoryStream _errorStream = new MemoryStream();
|
||||||
|
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes an instance of <see cref="VirtualConsole"/>.
|
||||||
|
/// </summary>
|
||||||
|
public VirtualConsole(bool isRedirected)
|
||||||
|
{
|
||||||
|
Input = new StreamReader(_inputStream, Console.InputEncoding, false);
|
||||||
|
Output = new StreamWriter(_outputStream, Console.OutputEncoding) {AutoFlush = true};
|
||||||
|
Error = new StreamWriter(_errorStream, Console.OutputEncoding) {AutoFlush = true};
|
||||||
|
|
||||||
|
IsInputRedirected = isRedirected;
|
||||||
|
IsOutputRedirected = isRedirected;
|
||||||
|
IsErrorRedirected = isRedirected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes an instance of <see cref="VirtualConsole"/>.
|
||||||
|
/// </summary>
|
||||||
|
public VirtualConsole()
|
||||||
|
: this(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes raw data to input stream.
|
||||||
|
/// </summary>
|
||||||
|
public void WriteInputData(byte[] data) => _inputStream.Write(data, 0, data.Length);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes text to input stream.
|
||||||
|
/// </summary>
|
||||||
|
public void WriteInputString(string str) => WriteInputData(Input.CurrentEncoding.GetBytes(str));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads all data written to output stream thus far.
|
||||||
|
/// </summary>
|
||||||
|
public byte[] ReadOutputData() => _outputStream.ToArray();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads all text written to output stream thus far.
|
||||||
|
/// </summary>
|
||||||
|
public string ReadOutputString() => Output.Encoding.GetString(ReadOutputData());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads all data written to error stream thus far.
|
||||||
|
/// </summary>
|
||||||
|
public byte[] ReadErrorData() => _errorStream.ToArray();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads all text written to error stream thus far.
|
||||||
|
/// </summary>
|
||||||
|
public string ReadErrorString() => Error.Encoding.GetString(ReadErrorData());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends an interrupt signal.
|
||||||
|
/// </summary>
|
||||||
|
public void Cancel() => _cts.Cancel();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends an interrupt signal after a delay.
|
||||||
|
/// </summary>
|
||||||
|
public void CancelAfter(TimeSpan delay) => _cts.CancelAfter(delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class VirtualConsole : IConsole
|
||||||
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public TextReader Input { get; }
|
public StreamReader Input { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsInputRedirected { get; }
|
public bool IsInputRedirected { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public TextWriter Output { get; }
|
public StreamWriter Output { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsOutputRedirected { get; }
|
public bool IsOutputRedirected { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public TextWriter Error { get; }
|
public StreamWriter Error { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsErrorRedirected { get; }
|
public bool IsErrorRedirected { get; }
|
||||||
@@ -37,50 +105,6 @@ namespace CliFx
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ConsoleColor BackgroundColor { get; set; } = ConsoleColor.Black;
|
public ConsoleColor BackgroundColor { get; set; } = ConsoleColor.Black;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes an instance of <see cref="VirtualConsole"/>.
|
|
||||||
/// </summary>
|
|
||||||
public VirtualConsole(TextReader input, bool isInputRedirected,
|
|
||||||
TextWriter output, bool isOutputRedirected,
|
|
||||||
TextWriter error, bool isErrorRedirected,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
Input = input;
|
|
||||||
IsInputRedirected = isInputRedirected;
|
|
||||||
Output = output;
|
|
||||||
IsOutputRedirected = isOutputRedirected;
|
|
||||||
Error = error;
|
|
||||||
IsErrorRedirected = isErrorRedirected;
|
|
||||||
_cancellationToken = cancellationToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes an instance of <see cref="VirtualConsole"/>.
|
|
||||||
/// </summary>
|
|
||||||
public VirtualConsole(TextReader input, TextWriter output, TextWriter error,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
: this(input, true, output, true, error, true, cancellationToken)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes an instance of <see cref="VirtualConsole"/> using output stream (stdout) and error stream (stderr).
|
|
||||||
/// Input stream (stdin) is replaced with a no-op stub.
|
|
||||||
/// </summary>
|
|
||||||
public VirtualConsole(TextWriter output, TextWriter error, CancellationToken cancellationToken = default)
|
|
||||||
: this(TextReader.Null, output, error, cancellationToken)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes an instance of <see cref="VirtualConsole"/> using output stream (stdout).
|
|
||||||
/// Input stream (stdin) and error stream (stderr) are replaced with no-op stubs.
|
|
||||||
/// </summary>
|
|
||||||
public VirtualConsole(TextWriter output, CancellationToken cancellationToken = default)
|
|
||||||
: this(output, TextWriter.Null, cancellationToken)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void ResetColor()
|
public void ResetColor()
|
||||||
{
|
{
|
||||||
@@ -89,6 +113,21 @@ namespace CliFx
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public CancellationToken GetCancellationToken() => _cancellationToken;
|
public CancellationToken GetCancellationToken() => _cts.Token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class VirtualConsole : IDisposable
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_inputStream.Dispose();
|
||||||
|
_outputStream.Dispose();
|
||||||
|
_errorStream.Dispose();
|
||||||
|
_cts.Dispose();
|
||||||
|
Input.Dispose();
|
||||||
|
Output.Dispose();
|
||||||
|
Error.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user