Skip to content

Commit

Permalink
Clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyrrrz committed Feb 13, 2025
1 parent 0842a1c commit 7676d77
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 128 deletions.
29 changes: 13 additions & 16 deletions CliWrap.Tests/CancellationSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,24 +64,21 @@ public async Task I_can_execute_a_command_and_cancel_it_gracefully_after_a_delay
{
// Arrange
using var cts = new CancellationTokenSource();

// We need to send the cancellation request right after the process has registered
// a handler for the interrupt signal, otherwise the default handler will trigger
// and just kill the process.
void HandleStdOut(string line)
{
if (line.Contains("Sleeping for", StringComparison.OrdinalIgnoreCase))
cts.CancelAfter(TimeSpan.FromSeconds(0.2));
}

var stdOutBuffer = new StringBuilder();

var target = PipeTarget.Merge(
PipeTarget.ToDelegate(HandleStdOut),
PipeTarget.ToStringBuilder(stdOutBuffer)
);

var cmd = Cli.Wrap(Dummy.Program.FilePath).WithArguments(["sleep", "00:00:20"]) | target;
var cmd =
Cli.Wrap(Dummy.Program.FilePath).WithArguments(["sleep", "00:00:20"])
| PipeTarget.Merge(
PipeTarget.ToDelegate(line =>
{
// We need to send the cancellation request right after the process has registered
// a handler for the interrupt signal, otherwise the default handler will trigger
// and just kill the process.
if (line.Contains("Sleeping for", StringComparison.OrdinalIgnoreCase))
cts.CancelAfter(TimeSpan.FromSeconds(0.2));
}),
PipeTarget.ToStringBuilder(stdOutBuffer)
);

// Act
var task = cmd.ExecuteAsync(CancellationToken.None, cts.Token);
Expand Down
203 changes: 91 additions & 112 deletions CliWrap.Tests/PipingSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ public class PipingSpecs
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_an_async_anonymous_source()
{
// Arrange
var source = PipeSource.Create(
async (destination, cancellationToken) =>
await destination.WriteAsync("Hello world!"u8.ToArray(), cancellationToken)
);

var cmd = source | Cli.Wrap(Dummy.Program.FilePath).WithArguments("echo stdin");
var cmd =
PipeSource.Create(
async (destination, cancellationToken) =>
await destination.WriteAsync("Hello world!"u8.ToArray(), cancellationToken)
) | Cli.Wrap(Dummy.Program.FilePath).WithArguments("echo stdin");

// Act
var result = await cmd.ExecuteBufferedAsync();
Expand All @@ -36,9 +35,9 @@ await destination.WriteAsync("Hello world!"u8.ToArray(), cancellationToken)
public async Task I_can_execute_a_command_and_pipe_the_stdin_from_a_sync_anonymous_source()
{
// Arrange
var source = PipeSource.Create(destination => destination.Write("Hello world!"u8));

var cmd = source | Cli.Wrap(Dummy.Program.FilePath).WithArguments("echo stdin");
var cmd =
PipeSource.Create(destination => destination.Write("Hello world!"u8))
| Cli.Wrap(Dummy.Program.FilePath).WithArguments("echo stdin");

// Act
var result = await cmd.ExecuteBufferedAsync();
Expand Down Expand Up @@ -186,15 +185,14 @@ public async Task I_can_execute_a_command_and_pipe_the_stdout_into_an_async_anon
// Arrange
using var stream = new MemoryStream();

var target = PipeTarget.Create(
async (origin, cancellationToken) =>
// ReSharper disable once AccessToDisposedClosure
await origin.CopyToAsync(stream, cancellationToken)
);

var cmd =
Cli.Wrap(Dummy.Program.FilePath)
.WithArguments(["generate binary", "--length", "100000"]) | target;
.WithArguments(["generate binary", "--length", "100000"])
| PipeTarget.Create(
async (origin, cancellationToken) =>
// ReSharper disable once AccessToDisposedClosure
await origin.CopyToAsync(stream, cancellationToken)
);

// Act
await cmd.ExecuteAsync();
Expand All @@ -209,14 +207,13 @@ public async Task I_can_execute_a_command_and_pipe_the_stdout_into_a_sync_anonym
// Arrange
using var stream = new MemoryStream();

var target = PipeTarget.Create(origin =>
// ReSharper disable once AccessToDisposedClosure
origin.CopyTo(stream)
);

var cmd =
Cli.Wrap(Dummy.Program.FilePath)
.WithArguments(["generate binary", "--length", "100000"]) | target;
.WithArguments(["generate binary", "--length", "100000"])
| PipeTarget.Create(origin =>
// ReSharper disable once AccessToDisposedClosure
origin.CopyTo(stream)
);

// Act
await cmd.ExecuteAsync();
Expand Down Expand Up @@ -282,15 +279,15 @@ public async Task I_can_execute_a_command_and_pipe_the_stdout_into_an_async_dele
// Arrange
var stdOutLinesCount = 0;

async Task HandleStdOutAsync(string line)
{
await Task.Yield();
stdOutLinesCount++;
}

var cmd =
Cli.Wrap(Dummy.Program.FilePath).WithArguments(["generate text", "--lines", "100"])
| HandleStdOutAsync;
| (
async line =>
{
await Task.Yield();
stdOutLinesCount++;
}
);

// Act
await cmd.ExecuteAsync();
Expand All @@ -305,15 +302,15 @@ public async Task I_can_execute_a_command_and_pipe_the_stdout_into_an_async_dele
// Arrange
var stdOutLinesCount = 0;

async Task HandleStdOutAsync(string line, CancellationToken cancellationToken = default)
{
await Task.Delay(1, cancellationToken);
stdOutLinesCount++;
}

var cmd =
Cli.Wrap(Dummy.Program.FilePath).WithArguments(["generate text", "--lines", "100"])
| HandleStdOutAsync;
| (
async (_, cancellationToken) =>
{
await Task.Delay(1, cancellationToken);
stdOutLinesCount++;
}
);

// Act
await cmd.ExecuteAsync();
Expand All @@ -328,11 +325,9 @@ public async Task I_can_execute_a_command_and_pipe_the_stdout_into_a_sync_delega
// Arrange
var stdOutLinesCount = 0;

void HandleStdOut(string line) => stdOutLinesCount++;

var cmd =
Cli.Wrap(Dummy.Program.FilePath).WithArguments(["generate text", "--lines", "100"])
| HandleStdOut;
| (_ => stdOutLinesCount++);

// Act
await cmd.ExecuteAsync();
Expand Down Expand Up @@ -452,13 +447,10 @@ public async Task I_can_execute_a_command_and_pipe_the_stdout_and_stderr_into_se
var stdOutLinesCount = 0;
var stdErrLinesCount = 0;

void HandleStdOut(string line) => stdOutLinesCount++;
void HandleStdErr(string line) => stdErrLinesCount++;

var cmd =
Cli.Wrap(Dummy.Program.FilePath)
.WithArguments(["generate text", "--target", "all", "--lines", "100"])
| (HandleStdOut, HandleStdErr);
| (_ => stdOutLinesCount++, _ => stdErrLinesCount++);

// Act
await cmd.ExecuteAsync();
Expand All @@ -476,15 +468,14 @@ public async Task I_can_execute_a_command_and_pipe_the_stdout_into_multiple_targ
using var stream2 = new MemoryStream();
using var stream3 = new MemoryStream();

var target = PipeTarget.Merge(
PipeTarget.ToStream(stream1),
PipeTarget.ToStream(stream2),
PipeTarget.ToStream(stream3)
);

var cmd =
Cli.Wrap(Dummy.Program.FilePath)
.WithArguments(["generate binary", "--length", "100000"]) | target;
.WithArguments(["generate binary", "--length", "100000"])
| PipeTarget.Merge(
PipeTarget.ToStream(stream1),
PipeTarget.ToStream(stream2),
PipeTarget.ToStream(stream3)
);

// Act
await cmd.ExecuteAsync();
Expand All @@ -503,14 +494,13 @@ public async Task I_can_execute_a_command_and_pipe_the_stdout_into_multiple_targ
// https://github.com/Tyrrrz/CliWrap/issues/212

// Arrange
var target = PipeTarget.Merge(
PipeTarget.ToStream(Stream.Null),
PipeTarget.ToDelegate(_ => throw new Exception("Expected exception."))
);

var cmd =
Cli.Wrap(Dummy.Program.FilePath)
.WithArguments(["generate binary", "--length", "100_000"]) | target;
.WithArguments(["generate binary", "--length", "100_000"])
| PipeTarget.Merge(
PipeTarget.ToStream(Stream.Null),
PipeTarget.ToDelegate(_ => throw new Exception("Expected exception."))
);

// Act & assert
var ex = await Assert.ThrowsAnyAsync<Exception>(async () => await cmd.ExecuteAsync());
Expand All @@ -526,17 +516,16 @@ public async Task I_can_execute_a_command_and_pipe_the_stdout_into_multiple_hier
using var stream3 = new MemoryStream();
using var stream4 = new MemoryStream();

var target = PipeTarget.Merge(
PipeTarget.ToStream(stream1),
PipeTarget.Merge(
PipeTarget.ToStream(stream2),
PipeTarget.Merge(PipeTarget.ToStream(stream3), PipeTarget.ToStream(stream4))
)
);

var cmd =
Cli.Wrap(Dummy.Program.FilePath)
.WithArguments(["generate binary", "--length", "100000"]) | target;
.WithArguments(["generate binary", "--length", "100000"])
| PipeTarget.Merge(
PipeTarget.ToStream(stream1),
PipeTarget.Merge(
PipeTarget.ToStream(stream2),
PipeTarget.Merge(PipeTarget.ToStream(stream3), PipeTarget.ToStream(stream4))
)
);

// Act
await cmd.ExecuteAsync();
Expand Down Expand Up @@ -619,11 +608,10 @@ public async Task I_can_execute_a_command_with_buffering_and_also_pipe_the_stdou

// Arrange
var delegateLines = new List<string>();
void HandleStdOut(string line) => delegateLines.Add(line);

var cmd =
Cli.Wrap(Dummy.Program.FilePath).WithArguments(["generate text", "--lines", "100"])
| HandleStdOut;
| delegateLines.Add;

// Act
var result = await cmd.ExecuteBufferedAsync();
Expand Down Expand Up @@ -693,22 +681,20 @@ public async Task I_can_execute_a_command_and_not_hang_if_the_process_only_parti
// Arrange
var random = new Random(1234567);

var source = PipeSource.Create(
async (destination, cancellationToken) =>
{
var buffer = new byte[256];
while (true)
var cmd =
PipeSource.Create(
async (destination, cancellationToken) =>
{
random.NextBytes(buffer);
await destination.WriteAsync(buffer, cancellationToken);
var buffer = new byte[256];
while (true)
{
random.NextBytes(buffer);
await destination.WriteAsync(buffer, cancellationToken);
}

// ReSharper disable once FunctionNeverReturns
}

// ReSharper disable once FunctionNeverReturns
}
);

var cmd =
source
)
| Cli.Wrap(Dummy.Program.FilePath).WithArguments(["echo stdin", "--length", "100000"]);

// Act & assert
Expand All @@ -721,17 +707,14 @@ public async Task I_can_execute_a_command_and_not_hang_if_the_process_does_not_c
// https://github.com/Tyrrrz/CliWrap/issues/74

// Arrange
var source = PipeSource.Create(
async (_, cancellationToken) =>
{
// Not infinite, but long enough
await Task.Delay(TimeSpan.FromSeconds(20), cancellationToken);
}
);

var cmd =
source
| Cli.Wrap(Dummy.Program.FilePath).WithArguments(["echo stdin", "--length", "0"]);
PipeSource.Create(
async (_, cancellationToken) =>
{
// Not infinite, but long enough
await Task.Delay(TimeSpan.FromSeconds(20), cancellationToken);
}
) | Cli.Wrap(Dummy.Program.FilePath).WithArguments(["echo stdin", "--length", "0"]);

// Act & assert
await cmd.ExecuteAsync();
Expand All @@ -743,15 +726,12 @@ public async Task I_can_execute_a_command_and_not_hang_if_the_process_does_not_c
// https://github.com/Tyrrrz/CliWrap/issues/74

// Arrange
var source = PipeSource.Create(
async (_, _) =>
// Not infinite, but long enough
await Task.Delay(TimeSpan.FromSeconds(20), CancellationToken.None)
);

var cmd =
source
| Cli.Wrap(Dummy.Program.FilePath).WithArguments(["echo stdin", "--length", "0"]);
PipeSource.Create(
async (_, _) =>
// Not infinite, but long enough
await Task.Delay(TimeSpan.FromSeconds(20), CancellationToken.None)
) | Cli.Wrap(Dummy.Program.FilePath).WithArguments(["echo stdin", "--length", "0"]);

// Act & assert
await cmd.ExecuteAsync();
Expand All @@ -766,23 +746,22 @@ public async Task I_can_execute_a_command_and_not_hang_on_large_stdin_while_also
var random = new Random(1234567);
var bytesRemaining = 100_000;

var source = PipeSource.Create(
async (destination, cancellationToken) =>
{
var buffer = new byte[256];
while (bytesRemaining > 0)
var cmd =
PipeSource.Create(
async (destination, cancellationToken) =>
{
random.NextBytes(buffer);
var buffer = new byte[256];
while (bytesRemaining > 0)
{
random.NextBytes(buffer);

var count = Math.Min(bytesRemaining, buffer.Length);
await destination.WriteAsync(buffer.AsMemory()[..count], cancellationToken);
var count = Math.Min(bytesRemaining, buffer.Length);
await destination.WriteAsync(buffer.AsMemory()[..count], cancellationToken);

bytesRemaining -= count;
bytesRemaining -= count;
}
}
}
);

var cmd = source | Cli.Wrap(Dummy.Program.FilePath).WithArguments("echo stdin");
) | Cli.Wrap(Dummy.Program.FilePath).WithArguments("echo stdin");

// Act & assert
await cmd.ExecuteAsync();
Expand Down

0 comments on commit 7676d77

Please sign in to comment.