<PackageReference Include="NUnit" Version="4.3.1" />

TextMessageWriter

TextMessageWriter writes constraint descriptions and messages in displayable form as a text stream. It tailors the display of individual message components to form the standard message format of NUnit assertion failure messages.
using NUnit.Framework.Constraints; using System; using System.Collections; using System.Runtime.CompilerServices; namespace NUnit.Framework.Internal { [NullableContext(1)] [Nullable(0)] public class TextMessageWriter : MessageWriter { private static readonly int DEFAULT_LINE_LENGTH = 78; public static readonly string Pfx_Expected = " Expected: "; public static readonly string Pfx_Actual = " But was: "; public static readonly string Pfx_Difference = " Off by: "; public static readonly int PrefixLength = Pfx_Expected.Length; private int _maxLineLength = DEFAULT_LINE_LENGTH; private bool _sameValDiffTypes; [Nullable(2)] private string _expectedType; [Nullable(2)] private string _actualType; public override int MaxLineLength { get { return _maxLineLength; } set { _maxLineLength = value; } } public TextMessageWriter() { } [NullableContext(2)] public TextMessageWriter(string userMessage, params object[] args) { if (!string.IsNullOrEmpty(userMessage)) WriteMessageLine(userMessage, args); } public override void WriteMessageLine(int level, string message, [Nullable(2)] params object[] args) { if (message != null) { while (level-- >= 0) { Write(" "); } if (args != null && args.Length != 0) message = string.Format(message, args); WriteLine(MsgUtils.EscapeNullCharacters(message)); } } public override void DisplayDifferences(ConstraintResult result) { WriteExpectedLine(result); WriteActualLine(result); WriteAdditionalLine(result); } private void ResolveTypeNameDifference(object expected, object actual, out string expectedType, out string actualType) { TypeNameDifferenceResolver typeNameDifferenceResolver = new TypeNameDifferenceResolver(); typeNameDifferenceResolver.ResolveTypeNameDifference(expected, actual, out expectedType, out actualType); expectedType = " (" + expectedType + ")"; actualType = " (" + actualType + ")"; } [NullableContext(2)] public override void DisplayDifferences(object expected, object actual) { DisplayDifferences(expected, actual, null); } [NullableContext(2)] public override void DisplayDifferences(object expected, object actual, Tolerance tolerance) { if (expected != null && actual != null && expected.GetType() != actual.GetType() && MsgUtils.FormatValue(expected) == MsgUtils.FormatValue(actual)) { _sameValDiffTypes = true; ResolveTypeNameDifference(expected, actual, out _expectedType, out _actualType); } WriteExpectedLine(expected, tolerance); WriteActualLine(actual); if (tolerance != null && expected != null && actual != null) WriteDifferenceLine(expected, actual, tolerance); } public override void DisplayStringDifferences(string expected, string actual, int mismatch, bool ignoreCase, bool clipping) { DisplayStringDifferences(expected, actual, mismatch, mismatch, ignoreCase, false, clipping); } public override void DisplayStringDifferences(string expected, string actual, int mismatchExpected, int mismatchActual, bool ignoreCase, bool ignoreWhiteSpace, bool clipping) { int maxDisplayLength = MaxLineLength - PrefixLength - 2; if (clipping) { if (ignoreWhiteSpace) { expected = MsgUtils.ClipWhenNeeded(expected, expected.Length, maxDisplayLength, ref mismatchExpected); actual = MsgUtils.ClipWhenNeeded(actual, actual.Length, maxDisplayLength, ref mismatchActual); } else MsgUtils.ClipExpectedAndActual(ref expected, ref actual, maxDisplayLength, ref mismatchExpected, ref mismatchActual); } expected = MsgUtils.EscapeControlChars(expected, ref mismatchExpected); actual = MsgUtils.EscapeControlChars(actual, ref mismatchActual); Write(Pfx_Expected); Write(MsgUtils.FormatValue(expected)); if (ignoreCase) Write(", ignoring case"); if (ignoreWhiteSpace) Write(", ignoring white-space"); WriteLine(); if (mismatchExpected >= 0 && mismatchExpected != mismatchActual) WriteCaretLine(mismatchExpected); WriteActualLine(actual); if (mismatchActual >= 0) WriteCaretLine(mismatchActual); } [NullableContext(2)] public override void WriteActualValue(object actual) { WriteValue(actual); } [NullableContext(2)] public override void WriteValue(object val) { Write(MsgUtils.FormatValue(val)); } public override void WriteCollectionElements(IEnumerable collection, long start, int max) { Write(MsgUtils.FormatCollection(collection, start, max)); } private void WriteExpectedLine(ConstraintResult result) { Write(Pfx_Expected); WriteLine(result.Description); } [NullableContext(2)] private void WriteExpectedLine(object expected, Tolerance tolerance) { Write(Pfx_Expected); Write(MsgUtils.FormatValue(expected)); if (_sameValDiffTypes) Write(_expectedType); if (tolerance != null && tolerance.HasVariance) { Write(" +/- "); Write(MsgUtils.FormatValue(tolerance.Amount)); if (tolerance.Mode != ToleranceMode.Linear) Write(" {0}", tolerance.Mode); } WriteLine(); } private void WriteActualLine(ConstraintResult result) { Write(Pfx_Actual); result.WriteActualValueTo(this); WriteLine(); } private void WriteAdditionalLine(ConstraintResult result) { result.WriteAdditionalLinesTo(this); } [NullableContext(2)] private void WriteActualLine(object actual) { Write(Pfx_Actual); WriteActualValue(actual); if (_sameValDiffTypes) Write(_actualType); WriteLine(); } [NullableContext(2)] private void WriteDifferenceLine(object expected, object actual, [Nullable(1)] Tolerance tolerance) { if (tolerance.Mode == ToleranceMode.Linear || tolerance.Mode == ToleranceMode.Percent) { string text = (tolerance.Amount is TimeSpan) ? MsgUtils.FormatValue(DateTimes.Difference(expected, actual)) : MsgUtils.FormatValue(Numerics.Difference(expected, actual, tolerance.Mode)); if (text != NaN.ToString()) { Write(Pfx_Difference); Write(text); if (tolerance.Mode != ToleranceMode.Linear) Write(" {0}", tolerance.Mode); WriteLine(); } } } private void WriteCaretLine(int mismatch) { WriteLine(" {0}^", new string('-', PrefixLength + mismatch - 2 + 1)); } } }