-
Couldn't load subscription status.
- Fork 354
Description
The Matches method is asymmetrical, that is, the following can be true: encounter1.Matches(encounter2) && !encounter2.Matches(encounter1). Here is an example of a passing test that exhibits this behavior:
[Test]
public void MatchesAsymmetric_IsExactlySymmetric()
{
var enc1 = new Encounter {Id = "a"};
var enc2 = new Encounter();
// Matches return value depends on which direction you call it in
Assert.IsTrue(enc1.Matches(enc2));
Assert.IsFalse(enc2.Matches(enc1));
// IsExactly value is the same in both directions
Assert.IsFalse(enc1.IsExactly(enc2));
Assert.IsFalse(enc2.IsExactly(enc1));
}
This seems only to happen when one object has one or more values set which are null in the other object. If each object has a value set which is null in the other, Matches is false in both directions:
[Test]
public void MatchesAsymmetric_IsExactlySymmetric()
{
var enc1 = new Encounter { Id = "a" };
var enc2 = new Encounter { Period = new Period(new FhirDateTime(1994), new FhirDateTime(1995)) };
// Matches is false in both directions: each encounter has a value set which is null in the other
Assert.IsFalse(enc1.Matches(enc2));
Assert.IsFalse(enc2.Matches(enc1));
// IsExactly value is the same in both directions
Assert.IsFalse(enc1.IsExactly(enc2));
Assert.IsFalse(enc2.IsExactly(enc1));
}
This behavior is unexpected and difficult to rely on, as it is hard to constantly remember which direction to call the method from in order to ensure consistent behavior.
I believe the following method is the source of the behavior (from Hl7.Fhir.Model.DeepComparable.Matches(IDeepComparable a, IDeepComparable pattern)):
public static bool Matches(IDeepComparable a, IDeepComparable pattern)
{
if (pattern == null) return true;
if (a != null && pattern != null)
{
return a.Matches(pattern);
}
else
return false;
}
I would think the first line of the method should instead be:
if (pattern == null || a == null) return true;
so that the method returns true for both directions in the above test. This would mean that the Matches call only checks the match for values which are set for both compared objects, and ignores any value which is null in either object.