Skip to content

Commit bf3343f

Browse files
Support AwesomeAssertions version 8
1 parent 4f0939b commit bf3343f

15 files changed

+603
-11
lines changed

Changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## 0.13.0.0
4+
5+
- Support FluentAssertions version 5, 6, 7 and 8
6+
- Support AwesomeAssertions version 8
7+
38
## 0.11.0.0
49

510
- Add assertions for verifying properties on messages that have a property that contains a destructured object

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>0.12.1.0</Version>
3+
<Version>0.13.0.0</Version>
44
<Authors>Sander van Vliet</Authors>
55
<Company>Codenizer BV</Company>
66
<Copyright>2025 Sander van Vliet</Copyright>

SerilogSinksInMemory.sln

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
2929
EndProject
3030
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions6", "test\Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions6\Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions6.csproj", "{F65ECEEE-4461-48EE-98BE-003BBC716FC5}"
3131
EndProject
32-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions8", "test\Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions8\Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions8.csproj", "{F759DDF5-0852-4D3E-965C-13F5DDD6DA0B}"
32+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions8", "test\Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions8\Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions8.csproj", "{F759DDF5-0852-4D3E-965C-13F5DDD6DA0B}"
3333
EndProject
34-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Sinks.InMemory.FluentAssertions6", "src\Serilog.Sinks.InMemory.FluentAssertions6\Serilog.Sinks.InMemory.FluentAssertions6.csproj", "{0092D58A-402D-43F5-A20C-B5BADE049CE8}"
34+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Sinks.InMemory.FluentAssertions6", "src\Serilog.Sinks.InMemory.FluentAssertions6\Serilog.Sinks.InMemory.FluentAssertions6.csproj", "{0092D58A-402D-43F5-A20C-B5BADE049CE8}"
3535
EndProject
36-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Sinks.InMemory.FluentAssertions8", "src\Serilog.Sinks.InMemory.FluentAssertions8\Serilog.Sinks.InMemory.FluentAssertions8.csproj", "{610ADB4E-1975-44CF-A30B-53F96DF35704}"
36+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Sinks.InMemory.FluentAssertions8", "src\Serilog.Sinks.InMemory.FluentAssertions8\Serilog.Sinks.InMemory.FluentAssertions8.csproj", "{610ADB4E-1975-44CF-A30B-53F96DF35704}"
3737
EndProject
38-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Sinks.InMemory.Assertions.Abstractions", "src\Serilog.Sinks.InMemory.Assertions.Abstractions\Serilog.Sinks.InMemory.Assertions.Abstractions.csproj", "{6718197F-6C67-4534-9296-36E0F120EB47}"
38+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Sinks.InMemory.Assertions.Abstractions", "src\Serilog.Sinks.InMemory.Assertions.Abstractions\Serilog.Sinks.InMemory.Assertions.Abstractions.csproj", "{6718197F-6C67-4534-9296-36E0F120EB47}"
3939
EndProject
40-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Sinks.InMemory.FluentAssertions5", "src\Serilog.Sinks.InMemory.FluentAssertions5\Serilog.Sinks.InMemory.FluentAssertions5.csproj", "{9E980ECF-E1CF-4121-83D2-800441F98EF7}"
40+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Sinks.InMemory.FluentAssertions5", "src\Serilog.Sinks.InMemory.FluentAssertions5\Serilog.Sinks.InMemory.FluentAssertions5.csproj", "{9E980ECF-E1CF-4121-83D2-800441F98EF7}"
4141
EndProject
4242
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Serilog.Sinks.InMemory.Assertions.Tests.Unit", "Serilog.Sinks.InMemory.Assertions.Tests.Unit", "{95F4D271-188F-48F9-BDB8-FD59BE4BFB30}"
4343
ProjectSection(SolutionItems) = preProject
@@ -51,9 +51,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Serilog.Sinks.InMemory.Asse
5151
test\Serilog.Sinks.InMemory.Assertions.Tests.Unit\WhenAssertingStructuredLogPropertyExists.cs = test\Serilog.Sinks.InMemory.Assertions.Tests.Unit\WhenAssertingStructuredLogPropertyExists.cs
5252
EndProjectSection
5353
EndProject
54-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Sinks.InMemory.FluentAssertions7", "src\Serilog.Sinks.InMemory.FluentAssertions7\Serilog.Sinks.InMemory.FluentAssertions7.csproj", "{3EDF7A6B-C2D5-462C-898A-4293B3BE45D3}"
54+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Sinks.InMemory.FluentAssertions7", "src\Serilog.Sinks.InMemory.FluentAssertions7\Serilog.Sinks.InMemory.FluentAssertions7.csproj", "{3EDF7A6B-C2D5-462C-898A-4293B3BE45D3}"
5555
EndProject
56-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions7", "test\Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions7\Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions7.csproj", "{63DF819E-0BF0-40EE-B94B-515BCF8041B9}"
56+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions7", "test\Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions7\Serilog.Sinks.InMemory.Assertions.Tests.Unit.FluentAssertions7.csproj", "{63DF819E-0BF0-40EE-B94B-515BCF8041B9}"
57+
EndProject
58+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Sinks.InMemory.AwesomeAssertions8", "src\Serilog.Sinks.InMemory.AwesomeAssertions8\Serilog.Sinks.InMemory.AwesomeAssertions8.csproj", "{5136DCA2-E485-4EB1-961C-AD3CC9593946}"
59+
EndProject
60+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Sinks.InMemory.Assertions.Tests.Unit.AwesomeAssertions8", "test\Serilog.Sinks.InMemory.Assertions.Tests.Unit.AwesomeAssertions8\Serilog.Sinks.InMemory.Assertions.Tests.Unit.AwesomeAssertions8.csproj", "{251A7F28-0166-49BB-AC4C-F72004FE14CC}"
5761
EndProject
5862
Global
5963
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -209,6 +213,30 @@ Global
209213
{63DF819E-0BF0-40EE-B94B-515BCF8041B9}.Release|x64.Build.0 = Release|Any CPU
210214
{63DF819E-0BF0-40EE-B94B-515BCF8041B9}.Release|x86.ActiveCfg = Release|Any CPU
211215
{63DF819E-0BF0-40EE-B94B-515BCF8041B9}.Release|x86.Build.0 = Release|Any CPU
216+
{5136DCA2-E485-4EB1-961C-AD3CC9593946}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
217+
{5136DCA2-E485-4EB1-961C-AD3CC9593946}.Debug|Any CPU.Build.0 = Debug|Any CPU
218+
{5136DCA2-E485-4EB1-961C-AD3CC9593946}.Debug|x64.ActiveCfg = Debug|Any CPU
219+
{5136DCA2-E485-4EB1-961C-AD3CC9593946}.Debug|x64.Build.0 = Debug|Any CPU
220+
{5136DCA2-E485-4EB1-961C-AD3CC9593946}.Debug|x86.ActiveCfg = Debug|Any CPU
221+
{5136DCA2-E485-4EB1-961C-AD3CC9593946}.Debug|x86.Build.0 = Debug|Any CPU
222+
{5136DCA2-E485-4EB1-961C-AD3CC9593946}.Release|Any CPU.ActiveCfg = Release|Any CPU
223+
{5136DCA2-E485-4EB1-961C-AD3CC9593946}.Release|Any CPU.Build.0 = Release|Any CPU
224+
{5136DCA2-E485-4EB1-961C-AD3CC9593946}.Release|x64.ActiveCfg = Release|Any CPU
225+
{5136DCA2-E485-4EB1-961C-AD3CC9593946}.Release|x64.Build.0 = Release|Any CPU
226+
{5136DCA2-E485-4EB1-961C-AD3CC9593946}.Release|x86.ActiveCfg = Release|Any CPU
227+
{5136DCA2-E485-4EB1-961C-AD3CC9593946}.Release|x86.Build.0 = Release|Any CPU
228+
{251A7F28-0166-49BB-AC4C-F72004FE14CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
229+
{251A7F28-0166-49BB-AC4C-F72004FE14CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
230+
{251A7F28-0166-49BB-AC4C-F72004FE14CC}.Debug|x64.ActiveCfg = Debug|Any CPU
231+
{251A7F28-0166-49BB-AC4C-F72004FE14CC}.Debug|x64.Build.0 = Debug|Any CPU
232+
{251A7F28-0166-49BB-AC4C-F72004FE14CC}.Debug|x86.ActiveCfg = Debug|Any CPU
233+
{251A7F28-0166-49BB-AC4C-F72004FE14CC}.Debug|x86.Build.0 = Debug|Any CPU
234+
{251A7F28-0166-49BB-AC4C-F72004FE14CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
235+
{251A7F28-0166-49BB-AC4C-F72004FE14CC}.Release|Any CPU.Build.0 = Release|Any CPU
236+
{251A7F28-0166-49BB-AC4C-F72004FE14CC}.Release|x64.ActiveCfg = Release|Any CPU
237+
{251A7F28-0166-49BB-AC4C-F72004FE14CC}.Release|x64.Build.0 = Release|Any CPU
238+
{251A7F28-0166-49BB-AC4C-F72004FE14CC}.Release|x86.ActiveCfg = Release|Any CPU
239+
{251A7F28-0166-49BB-AC4C-F72004FE14CC}.Release|x86.Build.0 = Release|Any CPU
212240
EndGlobalSection
213241
GlobalSection(SolutionProperties) = preSolution
214242
HideSolutionNode = FALSE
@@ -227,6 +255,8 @@ Global
227255
{95F4D271-188F-48F9-BDB8-FD59BE4BFB30} = {056C07B9-CAD5-4F92-8A24-FBDFDCBA0DDD}
228256
{3EDF7A6B-C2D5-462C-898A-4293B3BE45D3} = {B73801C2-972F-48CD-A47A-87A4544953E2}
229257
{63DF819E-0BF0-40EE-B94B-515BCF8041B9} = {056C07B9-CAD5-4F92-8A24-FBDFDCBA0DDD}
258+
{5136DCA2-E485-4EB1-961C-AD3CC9593946} = {B73801C2-972F-48CD-A47A-87A4544953E2}
259+
{251A7F28-0166-49BB-AC4C-F72004FE14CC} = {056C07B9-CAD5-4F92-8A24-FBDFDCBA0DDD}
230260
EndGlobalSection
231261
GlobalSection(ExtensibilityGlobals) = postSolution
232262
SolutionGuid = {7573ED42-AA91-4C5A-8355-F60D23EC57B1}

src/Serilog.Sinks.InMemory.Assertions/InMemorySinkExtensions.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#nullable enable
22
using System;
3-
using System.Diagnostics;
43
using System.IO;
54
using System.Linq;
65
using System.Reflection;
@@ -45,11 +44,15 @@ public static InMemorySinkAssertions Should(this InMemorySink instance)
4544
}
4645
}
4746

47+
var assertionLibrary = IsAwesomeAssertions(fluentAssertionsAssembly)
48+
? "AwesomeAssertions"
49+
: "FluentAssertions";
50+
4851
var fluentAssertionsMajorVersion = fluentAssertionsAssembly.GetName().Version.Major;
4952

5053
var versionedLocation = Path.Combine(
5154
assemblyLocation,
52-
$"Serilog.Sinks.InMemory.FluentAssertions{fluentAssertionsMajorVersion}.dll");
55+
$"Serilog.Sinks.InMemory.{assertionLibrary}{fluentAssertionsMajorVersion}.dll");
5356

5457
var versionedAssembly = Assembly.LoadFile(versionedLocation);
5558

@@ -70,6 +73,14 @@ public static InMemorySinkAssertions Should(this InMemorySink instance)
7073
_assertionsType, snapshotInstance);
7174
}
7275

76+
private static bool IsAwesomeAssertions(Assembly fluentAssertionsAssembly)
77+
{
78+
var assemblyMetadata = fluentAssertionsAssembly.GetCustomAttributes<AssemblyMetadataAttribute>();
79+
80+
// Yuck yuck yuck
81+
return assemblyMetadata.Any(metadata => metadata.Value.Contains("AwesomeAssertions"));
82+
}
83+
7384
/*
7485
* Hack attack.
7586
*

src/Serilog.Sinks.InMemory.Assertions/Serilog.Sinks.InMemory.Assertions.csproj

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<IsPackable>true</IsPackable>
99
<Title>Serilog in-memory sink assertion extensions</Title>
1010
<Description>FluentAssertions extensions to use with the Serilog.Sinks.InMemory package</Description>
11-
<Copyright>2021 Sander van Vliet</Copyright>
11+
<Copyright>2025 Sander van Vliet</Copyright>
1212
<Authors>Sander van Vliet</Authors>
1313
<PackageProjectUrl>https://github.com/sandermvanvliet/SerilogSinksInMemory/</PackageProjectUrl>
1414
<PackageLicenseExpression>MIT</PackageLicenseExpression>
@@ -81,5 +81,12 @@
8181
<OutputItemType>Content</OutputItemType>
8282
<PackagePath>lib/netstandard2.0</PackagePath>
8383
</ProjectReference>
84+
<ProjectReference Include="..\Serilog.Sinks.InMemory.AwesomeAssertions8\Serilog.Sinks.InMemory.AwesomeAssertions8.csproj">
85+
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
86+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
87+
<Package>true</Package>
88+
<OutputItemType>Content</OutputItemType>
89+
<PackagePath>lib/netstandard2.0</PackagePath>
90+
</ProjectReference>
8491
</ItemGroup>
8592
</Project>
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using System.Linq;
2+
using FluentAssertions.Execution;
3+
using FluentAssertions.Primitives;
4+
using Serilog.Sinks.InMemory.Assertions;
5+
6+
namespace Serilog.Sinks.InMemory.AwesomeAssertions8
7+
{
8+
public class InMemorySinkAssertionsImpl : ReferenceTypeAssertions<InMemorySink, InMemorySinkAssertionsImpl>, InMemorySinkAssertions
9+
{
10+
public InMemorySinkAssertionsImpl(InMemorySink snapshotInstance) : base(snapshotInstance, AssertionChain.GetOrCreate())
11+
{
12+
}
13+
14+
/*
15+
* Hack attack.
16+
*
17+
* This is a bit of a dirty way to work around snapshotting the InMemorySink instance
18+
* to ensure that you won't get hit by an InvalidOperationException when calling
19+
* HaveMessage() and the logger gets called from somewhere else and adds a new
20+
* LogEvent to the collection while that method is invoked.
21+
*
22+
* For now we copy the LogEvents from the current sink and use reflection to assign
23+
* it to a new instance of InMemorySink that will be used by the assertions,
24+
* effectively creating a snapshot of the InMemorySink that was used by the tests.
25+
*/
26+
private static InMemorySink SnapshotOf(InMemorySink instance)
27+
{
28+
return instance.Snapshot();
29+
}
30+
31+
protected override string Identifier => nameof(InMemorySink);
32+
33+
public LogEventsAssertions HaveMessage(
34+
string messageTemplate,
35+
string because = "",
36+
params object[] becauseArgs)
37+
{
38+
var matches = Subject
39+
.LogEvents
40+
.Where(logEvent => logEvent.MessageTemplate.Text == messageTemplate)
41+
.ToList();
42+
43+
CurrentAssertionChain
44+
.BecauseOf(because, becauseArgs)
45+
.ForCondition(matches.Any())
46+
.FailWith(
47+
"Expected message {0} to be logged",
48+
messageTemplate);
49+
50+
return new LogEventsAssertionsImpl(messageTemplate, matches, CurrentAssertionChain);
51+
}
52+
53+
public PatternLogEventsAssertions HaveMessage()
54+
{
55+
return new PatternLogEventsAssertionsImpl(Subject.LogEvents, CurrentAssertionChain);
56+
}
57+
58+
public void NotHaveMessage(
59+
string messageTemplate = null,
60+
string because = "",
61+
params object[] becauseArgs)
62+
{
63+
int count;
64+
string failureMessage;
65+
66+
if (messageTemplate != null)
67+
{
68+
count = Subject
69+
.LogEvents
70+
.Count(logEvent => logEvent.MessageTemplate.Text == messageTemplate);
71+
72+
failureMessage = $"Expected message \"{messageTemplate}\" not to be logged, but it was found {(count > 1 ? $"{count} times" : "once")}";
73+
}
74+
else
75+
{
76+
count = Subject
77+
.LogEvents
78+
.Count();
79+
80+
failureMessage = $"Expected no messages to be logged, but found {(count > 1 ? $"{count} messages" : "message")}";
81+
}
82+
83+
CurrentAssertionChain
84+
.BecauseOf(because, becauseArgs)
85+
.ForCondition(count == 0)
86+
.FailWith(failureMessage);
87+
}
88+
}
89+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System;
2+
using FluentAssertions;
3+
using FluentAssertions.Execution;
4+
using FluentAssertions.Primitives;
5+
using Serilog.Events;
6+
using Serilog.Sinks.InMemory.Assertions;
7+
8+
namespace Serilog.Sinks.InMemory.AwesomeAssertions8
9+
{
10+
public class LogEventAssertionImpl : ReferenceTypeAssertions<LogEvent, LogEventAssertionImpl>, LogEventAssertion
11+
{
12+
private readonly string _messageTemplate;
13+
14+
public LogEventAssertionImpl(string messageTemplate, LogEvent subject, AssertionChain assertionChain) : base(subject, assertionChain)
15+
{
16+
_messageTemplate = messageTemplate;
17+
}
18+
19+
protected override string Identifier => "log event";
20+
21+
public LogEventPropertyValueAssertions WithProperty(string name, string because = "", params object[] becauseArgs)
22+
{
23+
if (name.StartsWith("@"))
24+
{
25+
name = name.Substring(1);
26+
}
27+
28+
CurrentAssertionChain
29+
.BecauseOf(because, becauseArgs)
30+
.ForCondition(Subject.Properties.ContainsKey(name))
31+
.FailWith("Expected message {0} to have a property {1} but it wasn't found",
32+
_messageTemplate,
33+
name);
34+
35+
return new LogEventPropertyValueAssertionsImpl(
36+
this,
37+
Subject.Properties[name],
38+
name);
39+
}
40+
41+
public LogEventAssertion WithLevel(LogEventLevel level, string because = "", params object[] becauseArgs)
42+
{
43+
CurrentAssertionChain
44+
.BecauseOf(because, becauseArgs)
45+
.ForCondition(Subject.Level == level)
46+
.FailWith("Expected message {0} to have level {1}, but it is {2}",
47+
_messageTemplate,
48+
level.ToString(),
49+
Subject.Level.ToString());
50+
51+
return this;
52+
}
53+
54+
public void Match(Func<LogEvent, bool> predicate)
55+
{
56+
Subject.Should().Match<LogEvent>(o => predicate(o));
57+
}
58+
}
59+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
using FluentAssertions;
3+
using FluentAssertions.Primitives;
4+
using Serilog.Events;
5+
using Serilog.Sinks.InMemory.Assertions;
6+
7+
namespace Serilog.Sinks.InMemory.AwesomeAssertions8
8+
{
9+
public class LogEventPropertyValueAssertionsImpl : ReferenceTypeAssertions<LogEventPropertyValue, LogEventPropertyValueAssertionsImpl>, LogEventPropertyValueAssertions
10+
{
11+
private readonly LogEventAssertionImpl _logEventAssertion;
12+
13+
public LogEventPropertyValueAssertionsImpl(LogEventAssertionImpl logEventAssertion, LogEventPropertyValue instance, string propertyName)
14+
: base(instance, logEventAssertion.CurrentAssertionChain)
15+
{
16+
_logEventAssertion = logEventAssertion;
17+
Identifier = propertyName;
18+
}
19+
20+
protected override string Identifier { get; }
21+
22+
public TValue WhichValue<TValue>()
23+
{
24+
if (Subject is ScalarValue scalarValue)
25+
{
26+
CurrentAssertionChain
27+
.ForCondition(scalarValue.Value is TValue)
28+
.FailWith("Expected property value to be of type {0} but found {1}",
29+
typeof(TValue).Name,
30+
scalarValue.Value.GetType().Name);
31+
32+
return (TValue)scalarValue.Value;
33+
}
34+
35+
throw new Exception($"Expected property value to be of type {typeof(TValue).Name} but the property value is not a scalar and I don't know how to handle that");
36+
}
37+
38+
public AndConstraint<LogEventAssertion> WithValue(object value, string because = "", params object[] becauseArgs)
39+
{
40+
var actualValue = GetValueFromProperty(Subject);
41+
42+
CurrentAssertionChain
43+
.BecauseOf(because, becauseArgs)
44+
.ForCondition(Equals(actualValue, value))
45+
.FailWith("Expected property {0} to have value {1} but found {2}",
46+
Identifier,
47+
value,
48+
actualValue);
49+
50+
return new AndConstraint<LogEventAssertion>(_logEventAssertion);
51+
}
52+
53+
private object GetValueFromProperty(LogEventPropertyValue instance)
54+
{
55+
switch(instance)
56+
{
57+
case ScalarValue scalarValue:
58+
return scalarValue.Value;
59+
default:
60+
return Subject.ToString();
61+
}
62+
}
63+
64+
public StructuredValueAssertions HavingADestructuredObject(string because = "", params object[] becauseArgs)
65+
{
66+
CurrentAssertionChain
67+
.BecauseOf(because, becauseArgs)
68+
.ForCondition(Subject is StructureValue)
69+
.FailWith("Expected message \"{0}\" to have a property {1} that holds a destructured object but found a scalar value",
70+
_logEventAssertion.Subject.MessageTemplate,
71+
Identifier);
72+
73+
return new StructuredValueAssertionsImpl(Subject as StructureValue, Identifier, _logEventAssertion);
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)