Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#nullable enable
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#nullable enable
MartinCostello.Logging.XUnit.XUnitLoggerOptions.TimeProvider.get -> System.TimeProvider!
MartinCostello.Logging.XUnit.XUnitLoggerOptions.TimeProvider.set -> void
1 change: 1 addition & 0 deletions src/Logging.XUnit/PublicAPI/net8.0/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#nullable enable
3 changes: 3 additions & 0 deletions src/Logging.XUnit/PublicAPI/net8.0/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#nullable enable
MartinCostello.Logging.XUnit.XUnitLoggerOptions.TimeProvider.get -> System.TimeProvider!
MartinCostello.Logging.XUnit.XUnitLoggerOptions.TimeProvider.set -> void
17 changes: 16 additions & 1 deletion src/Shared/XUnitLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ public partial class XUnitLogger : ILogger
/// </summary>
private readonly string _timestampFormat;

#if NET8_0_OR_GREATER

/// <summary>
/// The time provider used in log messages.
/// </summary>
private readonly TimeProvider _timeProvider;

#endif

/// <summary>
/// Gets or sets the filter to use.
/// </summary>
Expand All @@ -57,6 +66,12 @@ private XUnitLogger(string name, XUnitLoggerOptions? options)
_messageSinkMessageFactory = options?.MessageSinkMessageFactory ?? (static (message) => new DiagnosticMessage(message));
_timestampFormat = options?.TimestampFormat ?? "u";
IncludeScopes = options?.IncludeScopes ?? false;
#if NET8_0_OR_GREATER
_timeProvider = options?.TimeProvider ?? TimeProvider.System;
Clock = () => _timeProvider.GetLocalNow();
#else
Clock = static () => DateTimeOffset.Now;
#endif
}

/// <summary>
Expand Down Expand Up @@ -84,7 +99,7 @@ private XUnitLogger(string name, XUnitLoggerOptions? options)
/// <summary>
/// Gets or sets a delegate representing the system clock.
/// </summary>
internal Func<DateTimeOffset> Clock { get; set; } = static () => DateTimeOffset.Now;
internal Func<DateTimeOffset> Clock { get; set; }

/// <inheritdoc />
public IDisposable? BeginScope<TState>(TState state)
Expand Down
9 changes: 9 additions & 0 deletions src/Shared/XUnitLoggerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,13 @@ public XUnitLoggerOptions()
/// </summary>
[StringSyntax(StringSyntaxAttribute.DateTimeFormat)]
public string? TimestampFormat { get; set; }

#if NET8_0_OR_GREATER

/// <summary>
/// Gets or sets the time provider used in log messages. Defaults to <see cref="TimeProvider.System"/>.
/// </summary>
public TimeProvider TimeProvider { get; set; } = TimeProvider.System;

#endif
}
35 changes: 35 additions & 0 deletions tests/Shared/XUnitLoggerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,41 @@ public static void XUnitLogger_Log_Logs_Message_If_Scopes_Included_And_There_Is_
outputHelper.Received(1).WriteLine(expected);
}

#if NET8_0_OR_GREATER

[Fact]
public static void XUnitLogger_Log_Logs_Message_With_TimeProvider()
{
// Arrange
var outputHelper = Substitute.For<ITestOutputHelper>();
string name = "MyName";

var timeProvider = Substitute.For<TimeProvider>();
timeProvider.LocalTimeZone.Returns(TimeZoneInfo.FindSystemTimeZoneById("Europe/London"));
timeProvider.GetUtcNow().Returns(new DateTimeOffset(2019, 05, 12, 13, 47, 41, 123, 456, TimeSpan.Zero));

var options = new XUnitLoggerOptions()
{
Filter = FilterTrue,
TimeProvider = timeProvider,
};

var logger = new XUnitLogger(name, outputHelper, options);

string expected = string.Join(
Environment.NewLine,
"[2019-05-12 13:47:41Z] info: MyName[85]",
" Message|True|False");

// Act
logger.Log(LogLevel.Information, new EventId(85), "Martin", null, Formatter);

// Assert
outputHelper.Received(1).WriteLine(expected);
}

#endif

private static DateTimeOffset StaticClock() => new(2018, 08, 19, 17, 12, 16, TimeSpan.FromHours(1));

private static DiagnosticMessage DiagnosticMessageFactory(string message) => new(message);
Expand Down