Description
Problem
PropertyConstraint keeps the base constraint description but throws away the actual comparison message and just prints the actual value.
Starting with a familiar example, Is.EquivalentTo
:
var actual = new SomeClass { SomeProperty = { 2, 3, 5, 7 } };
Assert.That(actual.SomeProperty, Is.EquivalentTo(new List<int> { 2, 3, 5, 8 }));
Expected: equivalent to < 2, 3, 5, 8 >
But was: < 2, 3, 5, 7 >
Missing (1): < 8 >
Extra (1): < 7 >
But as soon as you compose it with PropertyConstraint
:
var actual = new SomeClass { SomeProperty = { 2, 3, 5, 7 } };
Assert.That(actual, Has.Property("SomeProperty").EquivalentTo(new List<int> { 2, 3, 5, 8 }));
Expected: equivalent to < 2, 3, 5, 8 >
But was: < 2, 3, 5, 7 >
In that example, just printing the actual value is still pretty okay.
But when the value is a complex object that doesn't .ToString()
to something you care about, you get something like this:
Expected: property SomeProperty [long description from custom constraint]
But was: <Appearance>
Assert.That(new SomeClass(), Has.Property("SomeComplexThing")
.SomeCustomConstraint(expectedComplexThing));
Proposal
Here you can see the constraint, which understands the semantics of the actual value, getting thrown away. Only the actual value and success bool are retained:
nunit/src/NUnitFramework/framework/Constraints/PropertyConstraint.cs
Lines 73 to 74 in bf8f2dc
Rather than the existing code below, I think we should have an internal-for-now ChainedConstraintResult
class which delegates all its writing to the base constraint result:
internal class ChainedConstraintResult : ConstraintResult
{
private readonly ConstraintResult _baseResult;
public ChainedConstraintResult(IConstraint constraint, ConstraintResult baseResult) : base(constraint, baseResult.ActualValue, baseResult.Status)
{
_baseResult = baseResult;
}
public override void WriteActualValueTo(MessageWriter writer)
{
_baseResult.WriteActualValueTo(writer);
}
}
PropertyConstraint would then do this:
var baseResult = BaseConstraint.ApplyTo(propValue);
return new ChainedConstraintResult(this, baseResult);