forked from serilog/serilog
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add basic support for LogEventProperty structural equality,
The 'LogEventPropertyStructuralEqualityComparer` and `LogEventPropertyValueComparer` currently only support `ScalarValue` and `SequenceValue`. If the comparer encounters a `StructureValue` or `DictionaryValue` it throws `NotImplementedException`.
- Loading branch information
1 parent
4d15d2c
commit e0a08ec
Showing
3 changed files
with
173 additions
and
0 deletions.
There are no files selected for viewing
32 changes: 32 additions & 0 deletions
32
test/Serilog.Tests/Support/LogEventPropertyStructuralEqualityComparer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Serilog.Events; | ||
|
||
namespace Serilog.Tests.Support | ||
{ | ||
class LogEventPropertyStructuralEqualityComparer : IEqualityComparer<LogEventProperty> | ||
{ | ||
readonly IEqualityComparer<LogEventPropertyValue> _valueEqualityComparer; | ||
|
||
public LogEventPropertyStructuralEqualityComparer( | ||
IEqualityComparer<LogEventPropertyValue> valueEqualityComparer = null) | ||
{ | ||
this._valueEqualityComparer = | ||
valueEqualityComparer ?? new LogEventPropertyValueComparer(EqualityComparer<object>.Default); | ||
} | ||
|
||
public bool Equals(LogEventProperty x, LogEventProperty y) | ||
{ | ||
if (x == null || y == null) | ||
return false; // throw new Exception($"the comparer doesn't support nulls, x={x}, y={y}"); | ||
|
||
return x.Name == y.Name | ||
&& _valueEqualityComparer.Equals(x.Value, y.Value); | ||
} | ||
|
||
public int GetHashCode(LogEventProperty obj) | ||
{ | ||
return 0; | ||
} | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
test/Serilog.Tests/Support/LogEventPropertyStructuralEqualityComparerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
using System; | ||
using Serilog.Events; | ||
using Xunit; | ||
|
||
namespace Serilog.Tests.Support | ||
{ | ||
public class LogEventPropertyStructuralEqualityComparerTests | ||
{ | ||
[Fact] | ||
public void HandlesNullAsNotEqual() | ||
{ | ||
var sut = new LogEventPropertyStructuralEqualityComparer(); | ||
Assert.False(sut.Equals(null, new LogEventProperty("a", new ScalarValue(null)))); | ||
Assert.False(sut.Equals(new LogEventProperty("a", new ScalarValue(null)), null)); | ||
Assert.False(sut.Equals(null, null)); | ||
} | ||
|
||
[Fact] | ||
public void LogEventPropertyStructuralEqualityComparerWorksForSequences() | ||
{ | ||
var intStringDoubleScalarArray = | ||
new[] { new ScalarValue(1), new ScalarValue("2"), new ScalarValue(3.0), }; | ||
|
||
var intStringFloatScalarArray = | ||
new[] { new ScalarValue("1"), new ScalarValue(2), new ScalarValue(3.0f), }; | ||
|
||
var sequenceOfScalarsIntStringDoubleA = new LogEventProperty("a", new SequenceValue(intStringDoubleScalarArray)); | ||
|
||
var sequenceOfScalarsIntStringDoubleAStructurallyEqual = new LogEventProperty("a", | ||
new SequenceValue(new[] { new ScalarValue(1), new ScalarValue("2"), new ScalarValue(3.0), })); | ||
|
||
var sequenceOfScalarsIntStringDoubleAStructurallyNotEqual = new LogEventProperty("a", | ||
new SequenceValue(new [] { new ScalarValue(1), new ScalarValue("2"), new ScalarValue(3.1), })); | ||
|
||
var sequenceOfScalarsIntStringFloatA = new LogEventProperty("a", new ScalarValue(intStringFloatScalarArray)); | ||
|
||
var sequenceOfScalarsIntStringDoubleB = new LogEventProperty("b", new SequenceValue(intStringDoubleScalarArray)); | ||
|
||
var sut = new LogEventPropertyStructuralEqualityComparer(); | ||
|
||
// Structurally equal | ||
Assert.True(sut.Equals(sequenceOfScalarsIntStringDoubleA, sequenceOfScalarsIntStringDoubleAStructurallyEqual)); | ||
|
||
// Not equal due to having a different property name (but otherwise structurally equal) | ||
Assert.False(sut.Equals(sequenceOfScalarsIntStringDoubleA, sequenceOfScalarsIntStringDoubleB)); | ||
|
||
// Structurally not equal because element 3 has a different value | ||
Assert.False(sut.Equals(sequenceOfScalarsIntStringDoubleA, sequenceOfScalarsIntStringDoubleAStructurallyNotEqual)); | ||
|
||
// Strucrtually not equal because element 3 has a different underlying value and type | ||
Assert.False(sut.Equals(sequenceOfScalarsIntStringDoubleA, sequenceOfScalarsIntStringFloatA)); | ||
} | ||
|
||
[Fact] | ||
public void LogEventPropertyStructuralEqualityComparerWorksForScalars() | ||
{ | ||
var scalarStringA = new LogEventProperty("a", new ScalarValue("a")); | ||
var scalarStringAStructurallyEqual = new LogEventProperty("a", new ScalarValue("a")); | ||
|
||
var scalarStringB = new LogEventProperty("b", new ScalarValue("b")); | ||
var scalarStringBStructurallyNotEqual = new LogEventProperty("b", new ScalarValue("notEqual")); | ||
|
||
var scalarIntA1 = new LogEventProperty("a", new ScalarValue(1)); | ||
var scalarIntA1StructurallyEqual = new LogEventProperty("a", new ScalarValue(1)); | ||
var scalarIntA1DiffValueSameType = new LogEventProperty("a", new ScalarValue(0)); | ||
var scalarIntB1 = new LogEventProperty("b", new ScalarValue(1)); | ||
|
||
var guid1 = Guid.NewGuid(); | ||
var guid2 = Guid.NewGuid(); | ||
var scalarGuid1 = new LogEventProperty("1", new ScalarValue(guid1)); | ||
var scalarGuid1StructurallyEqual = new LogEventProperty("1", new ScalarValue(guid1)); | ||
var scalarGuid1StructurallyNotEqual = new LogEventProperty("1", new ScalarValue("notEqual")); | ||
var scalarGuid2 = new LogEventProperty("2", new ScalarValue(guid2)); | ||
|
||
var sut = new LogEventPropertyStructuralEqualityComparer(); | ||
|
||
Assert.True(sut.Equals(scalarStringA, scalarStringAStructurallyEqual)); | ||
Assert.True(sut.Equals(scalarIntA1, scalarIntA1StructurallyEqual)); | ||
Assert.True(sut.Equals(scalarGuid1, scalarGuid1StructurallyEqual)); | ||
|
||
Assert.False(sut.Equals(scalarStringB, scalarStringBStructurallyNotEqual)); | ||
Assert.False(sut.Equals(scalarIntA1, scalarIntB1)); | ||
Assert.False(sut.Equals(scalarIntA1, scalarIntA1DiffValueSameType)); | ||
|
||
Assert.False(sut.Equals(scalarGuid1, scalarGuid2)); | ||
Assert.False(sut.Equals(scalarGuid1, scalarGuid1StructurallyNotEqual)); | ||
} | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
test/Serilog.Tests/Support/LogEventPropertyValueComparer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Serilog.Events; | ||
|
||
namespace Serilog.Tests.Support | ||
{ | ||
class LogEventPropertyValueComparer : IEqualityComparer<LogEventPropertyValue> | ||
{ | ||
readonly IEqualityComparer<object> _objectEqualityComparer; | ||
|
||
public LogEventPropertyValueComparer(IEqualityComparer<object> objectEqualityComparer = null) | ||
{ | ||
this._objectEqualityComparer = objectEqualityComparer ?? EqualityComparer<object>.Default; | ||
} | ||
|
||
public bool Equals(LogEventPropertyValue x, LogEventPropertyValue y) | ||
{ | ||
var scalarX = x as ScalarValue; | ||
var scalarY = y as ScalarValue; | ||
if (scalarX != null && scalarY != null) | ||
{ | ||
return _objectEqualityComparer.Equals(scalarX.Value, scalarY.Value); | ||
} | ||
|
||
var sequenceX = x as SequenceValue; | ||
var sequenceY = y as SequenceValue; | ||
if (sequenceX != null && sequenceY != null) | ||
{ | ||
return sequenceX.Elements | ||
.SequenceEqual(sequenceY.Elements, this); | ||
} | ||
|
||
if (x is StructureValue || y is StructureValue) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
if (x is DictionaryValue || y is DictionaryValue) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
public int GetHashCode(LogEventPropertyValue obj) | ||
{ | ||
return 0; | ||
} | ||
} | ||
} |