Skip to content

Commit e5d72ac

Browse files
author
David Obee
committed
Add test of external scope provider support
1 parent 2395852 commit e5d72ac

File tree

1 file changed

+72
-1
lines changed

1 file changed

+72
-1
lines changed

test/Serilog.Extensions.Logging.Tests/SerilogLoggerTests.cs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class SerilogLoggerTest
1717
const string Name = "test";
1818
const string TestMessage = "This is a test";
1919

20-
static Tuple<SerilogLogger, SerilogSink> SetUp(LogLevel logLevel)
20+
static Tuple<SerilogLogger, SerilogSink> SetUp(LogLevel logLevel, IExternalScopeProvider? externalScopeProvider = null)
2121
{
2222
var sink = new SerilogSink();
2323

@@ -29,6 +29,11 @@ static Tuple<SerilogLogger, SerilogSink> SetUp(LogLevel logLevel)
2929
var provider = new SerilogLoggerProvider(serilogLogger);
3030
var logger = (SerilogLogger)provider.CreateLogger(Name);
3131

32+
if (externalScopeProvider is not null)
33+
{
34+
provider.SetScopeProvider(externalScopeProvider);
35+
}
36+
3237
return new Tuple<SerilogLogger, SerilogSink>(logger, sink);
3338
}
3439

@@ -397,6 +402,35 @@ public void NamedScopesAreCaptured()
397402
Assert.Equal("Inner", items[1]);
398403
}
399404

405+
[Fact]
406+
public void ExternalScopesAreCaptured()
407+
{
408+
var externalScopeProvider = new FakeExternalScopeProvider();
409+
var (logger, sink) = SetUp(LogLevel.Trace, externalScopeProvider);
410+
411+
externalScopeProvider.Push(new Dictionary<string, int>()
412+
{
413+
{ "FirstKey", 1 },
414+
{ "SecondKey", 2 }
415+
});
416+
417+
var scopeObject = new { ObjectKey = "Some value" };
418+
externalScopeProvider.Push(scopeObject);
419+
420+
logger.Log(LogLevel.Information, 0, TestMessage, null!, null!);
421+
422+
Assert.Single(sink.Writes);
423+
Assert.True(sink.Writes[0].Properties.TryGetValue(SerilogLoggerProvider.ScopePropertyName, out var scopeValue));
424+
var sequence = Assert.IsType<SequenceValue>(scopeValue);
425+
426+
var objectScope = (ScalarValue) sequence.Elements.Single(e => e is ScalarValue);
427+
Assert.Equal(scopeObject.ToString(), (string?)objectScope.Value);
428+
429+
var dictionaryScope = (DictionaryValue) sequence.Elements.Single(e => e is DictionaryValue);
430+
Assert.Equal(1, ((ScalarValue)dictionaryScope.Elements.Single(pair => pair.Key.Value!.Equals("FirstKey")).Value).Value);
431+
Assert.Equal(2, ((ScalarValue)dictionaryScope.Elements.Single(pair => pair.Key.Value!.Equals("SecondKey")).Value).Value);
432+
}
433+
400434
class FoodScope : IEnumerable<KeyValuePair<string, object>>
401435
{
402436
readonly string _name;
@@ -446,6 +480,43 @@ class Person
446480
public string? LastName { get; set; }
447481
}
448482

483+
class FakeExternalScopeProvider : IExternalScopeProvider
484+
{
485+
private readonly List<Scope> _scopes = new List<Scope>();
486+
487+
public void ForEachScope<TState>(Action<object?, TState> callback, TState state)
488+
{
489+
foreach (var scope in _scopes)
490+
{
491+
if (scope.IsDisposed) continue;
492+
callback(scope.Value, state);
493+
}
494+
}
495+
496+
public IDisposable Push(object? state)
497+
{
498+
var scope = new Scope(state);
499+
_scopes.Add(scope);
500+
return scope;
501+
}
502+
503+
private class Scope : IDisposable
504+
{
505+
public bool IsDisposed { get; set; } = false;
506+
public object? Value { get; set; }
507+
508+
public Scope(object? value)
509+
{
510+
Value = value;
511+
}
512+
513+
public void Dispose()
514+
{
515+
IsDisposed = true;
516+
}
517+
}
518+
}
519+
449520
[Theory]
450521
[InlineData(1)]
451522
[InlineData(10)]

0 commit comments

Comments
 (0)