Skip to content

Commit a830076

Browse files
committed
feat: add StatusAsync method for logging status with cancellation support and implement tests
1 parent ed8f8e5 commit a830076

3 files changed

Lines changed: 77 additions & 0 deletions

File tree

src/Extensions/ILoggerExtensions.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,37 @@ public static async Task ProgressAsync(this ILogger @this, Func<Progress, Task>
106106

107107
await finishedPayload.WaitForFinishedAsync().ConfigureAwait(false);
108108
}
109+
110+
/// <summary>
111+
/// Logs a <see cref="Status"/> to the console.
112+
/// </summary>
113+
/// <param name="this">The <see cref="ILogger"/> instance to log the status to.</param>
114+
/// <param name="action">An action that receives the <see cref="Status"/> instance to configure it and add tasks to it.</param>
115+
/// <param name="cancellationToken">A cancellation token that can be used to cancel the status operation.</param>
116+
/// <returns>A <see cref="Task"/> that represents the asynchronous status operation.</returns>
117+
public static async Task StatusAsync(this ILogger @this, Func<Status, Task> action, CancellationToken cancellationToken = default)
118+
{
119+
ArgumentNullException.ThrowIfNull(@this);
120+
ArgumentNullException.ThrowIfNull(action);
121+
122+
StatusStartPayload startPayload = new()
123+
{
124+
CancellationToken = cancellationToken,
125+
};
126+
127+
@this.Log(null, startPayload);
128+
129+
Status status = await startPayload.WaitForStatusAsync().ConfigureAwait(false);
130+
131+
await action(status).ConfigureAwait(false);
132+
133+
StatusFinishedPayload finishedPayload = new()
134+
{
135+
CancellationToken = cancellationToken,
136+
};
137+
138+
@this.Log(null, finishedPayload);
139+
140+
await finishedPayload.WaitForFinishedAsync().ConfigureAwait(false);
141+
}
109142
}

src/SpectreConsoleLogSink.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public sealed class SpectreConsoleLogSink : AsyncLogSinkBase<IAnsiConsole>
1212
{
1313
private readonly ProgressConsoleMessageWriter progressConsoleMessageWriter = new();
1414

15+
private readonly StatusConsoleMessageWriter statusConsoleMessageWriter = new();
16+
1517
// ┌─────────────────────────────────────────────────────────────────────────────┐
1618
// │ Public Constructors │
1719
// └─────────────────────────────────────────────────────────────────────────────┘
@@ -24,5 +26,7 @@ public SpectreConsoleLogSink() : base(new SpectreConsoleLogMessageWriter<object>
2426
RegisterLogMessageWriter(new PayloadLogMessageWriter());
2527
RegisterLogMessageWriter<ProgressStartPayload>(progressConsoleMessageWriter);
2628
RegisterLogMessageWriter<ProgressFinishedPayload>(progressConsoleMessageWriter);
29+
RegisterLogMessageWriter<StatusStartPayload>(statusConsoleMessageWriter);
30+
RegisterLogMessageWriter<StatusFinishedPayload>(statusConsoleMessageWriter);
2731
}
2832
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System.Threading.Tasks;
2+
using AwesomeAssertions;
3+
using Spectre.Console;
4+
using Spectre.Console.Testing;
5+
using WB.Logging;
6+
using WB.Logging.LogSinks.Console.Spectre;
7+
8+
namespace ExtensionsTests.ILoggerExtensionsTests.StatusAsyncMethodTests;
9+
10+
public sealed class TheStatusAsyncMethod
11+
{
12+
[Test]
13+
public async Task ShouldRunAStatus()
14+
{
15+
// Arrange
16+
TestConsole testConsole = new();
17+
ILogger logger = new Logger("test");
18+
logger.AttachSpectreConsole(logSink =>
19+
{
20+
logSink.Writer = testConsole;
21+
});
22+
23+
// Act
24+
await logger.StatusAsync(async status =>
25+
{
26+
await status.StartAsync("status", async context =>
27+
{
28+
for (int i = 0; i < 100; i++)
29+
{
30+
context.Status($"Processing... {i}%");
31+
await Task.Delay(10);
32+
}
33+
}).ConfigureAwait(false);
34+
});
35+
await logger.FlushAsync();
36+
37+
// Assert
38+
testConsole.Output.Should().Contain("Processing...");
39+
}
40+
}

0 commit comments

Comments
 (0)