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

MsgUtils

static class MsgUtils
Static methods used in creating messages
using NUnit.Framework.Internal; using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Reflection; using System.Text; namespace NUnit.Framework.Constraints { internal static class MsgUtils { private const string ELLIPSIS = "..."; private static readonly string Fmt_Null; private static readonly string Fmt_EmptyString; private static readonly string Fmt_EmptyCollection; private static readonly string Fmt_String; private static readonly string Fmt_Char; private static readonly string Fmt_DateTime; private static readonly string Fmt_DateTimeOffset; private static readonly string Fmt_ValueType; private static readonly string Fmt_Default; public static ValueFormatter DefaultValueFormatter { get; set; } static MsgUtils() { Fmt_Null = "null"; Fmt_EmptyString = "<string.Empty>"; Fmt_EmptyCollection = "<empty>"; Fmt_String = "\"{0}\""; Fmt_Char = "'{0}'"; Fmt_DateTime = "yyyy-MM-dd HH:mm:ss.FFFFFFF"; Fmt_DateTimeOffset = "yyyy-MM-dd HH:mm:ss.FFFFFFFzzz"; Fmt_ValueType = "{0}"; Fmt_Default = "<{0}>"; DefaultValueFormatter = ((object val) => string.Format(Fmt_Default, val)); AddFormatter((ValueFormatter next) => delegate(object val) { if (!(val is ValueType)) return next(val); return string.Format(Fmt_ValueType, val); }); AddFormatter((ValueFormatter next) => delegate(object val) { if (!(val is DateTime)) return next(val); return FormatDateTime((DateTime)val); }); AddFormatter((ValueFormatter next) => delegate(object val) { if (!(val is DateTimeOffset)) return next(val); return FormatDateTimeOffset((DateTimeOffset)val); }); AddFormatter((ValueFormatter next) => delegate(object val) { if (!(val is decimal)) return next(val); return FormatDecimal((decimal)val); }); AddFormatter((ValueFormatter next) => delegate(object val) { if (!(val is float)) return next(val); return FormatFloat((float)val); }); AddFormatter((ValueFormatter next) => delegate(object val) { if (!(val is double)) return next(val); return FormatDouble((double)val); }); AddFormatter((ValueFormatter next) => delegate(object val) { if (!(val is char)) return next(val); return string.Format(Fmt_Char, val); }); AddFormatter((ValueFormatter next) => delegate(object val) { if (!(val is IEnumerable)) return next(val); return FormatCollection((IEnumerable)val, 0, 10); }); AddFormatter((ValueFormatter next) => delegate(object val) { if (!(val is string)) return next(val); return FormatString((string)val); }); AddFormatter((ValueFormatter next) => delegate(object val) { if (!val.GetType().IsArray) return next(val); return FormatArray((Array)val); }); AddFormatter((ValueFormatter next) => (object val) => TryFormatKeyValuePair(val) ?? next(val)); AddFormatter((ValueFormatter next) => (object val) => TryFormatTuple(val, "System.Tuple", GetValueFromTuple) ?? next(val)); AddFormatter((ValueFormatter next) => (object val) => TryFormatTuple(val, "System.ValueTuple", GetValueFromValueTuple) ?? next(val)); } public static void AddFormatter(ValueFormatterFactory formatterFactory) { DefaultValueFormatter = formatterFactory(DefaultValueFormatter); } public static string FormatValue(object val) { if (val == null) return Fmt_Null; TestExecutionContext currentContext = TestExecutionContext.CurrentContext; if (currentContext != null) return currentContext.CurrentValueFormatter(val); return DefaultValueFormatter(val); } public static string FormatCollection(IEnumerable collection, long start, int max) { int num = 0; int num2 = 0; StringBuilder stringBuilder = new StringBuilder(); foreach (object item in collection) { if (num2++ >= start) { if (++num > max) break; stringBuilder.Append((num == 1) ? "< " : ", "); stringBuilder.Append(FormatValue(item)); } } if (num == 0) return Fmt_EmptyCollection; if (num > max) stringBuilder.Append("..."); stringBuilder.Append(" >"); return stringBuilder.ToString(); } private static string FormatArray(Array array) { if (array.Length == 0) return Fmt_EmptyCollection; int rank = array.Rank; int[] array2 = new int[rank]; int num = 1; int num2 = rank; while (--num2 >= 0) { num = (array2[num2] = num * array.GetLength(num2)); } int num3 = 0; StringBuilder stringBuilder = new StringBuilder(); foreach (object item in array) { if (num3 > 0) stringBuilder.Append(", "); bool flag = false; for (int i = 0; i < rank; i++) { flag = (flag || num3 % array2[i] == 0); if (flag) stringBuilder.Append("< "); } stringBuilder.Append(FormatValue(item)); num3++; bool flag2 = false; for (int j = 0; j < rank; j++) { flag2 = (flag2 || num3 % array2[j] == 0); if (flag2) stringBuilder.Append(" >"); } } return stringBuilder.ToString(); } private static string TryFormatKeyValuePair(object value) { if (value == null) return null; Type type = value.GetType(); if (!type.GetTypeInfo().IsGenericType) return null; if (type.GetGenericTypeDefinition() != typeof(KeyValuePair<, >)) return null; object value2 = type.GetProperty("Key").GetValue(value, null); object value3 = type.GetProperty("Value").GetValue(value, null); return FormatKeyValuePair(value2, value3); } private static string FormatKeyValuePair(object key, object value) { return $"""{FormatValue(key)}""{FormatValue(value)}"""; } private static object GetValueFromTuple(Type type, string propertyName, object obj) { return type.GetProperty(propertyName).GetValue(obj, null); } private static object GetValueFromValueTuple(Type type, string propertyName, object obj) { return type.GetField(propertyName).GetValue(obj); } private static string TryFormatTuple(object value, string tupleType, Func<Type, string, object, object> getValue) { if (value == null) return null; if (GetTypeNameWithoutGenerics(value.GetType().FullName) != tupleType) return null; return FormatTuple(value, true, getValue); } private static string FormatTuple(object value, bool printParentheses, Func<Type, string, object, object> getValue) { Type type = value.GetType(); int num = type.GetGenericArguments().Length; StringBuilder stringBuilder = new StringBuilder(); if (printParentheses) stringBuilder.Append("("); for (int i = 0; i < num; i++) { if (i > 0) stringBuilder.Append(", "); bool num2 = i < 7; string arg = num2 ? ("Item" + (i + 1)) : "Rest"; object obj = getValue(type, arg, value); string value2 = num2 ? FormatValue(obj) : FormatTuple(obj, false, getValue); stringBuilder.Append(value2); } if (printParentheses) stringBuilder.Append(")"); return stringBuilder.ToString(); } private static string GetTypeNameWithoutGenerics(string fullTypeName) { int num = fullTypeName.IndexOf('`'); if (num != -1) return fullTypeName.Substring(0, num); return fullTypeName; } private static string FormatString(string s) { if (!(s == string.Empty)) return string.Format(Fmt_String, s); return Fmt_EmptyString; } private static string FormatDouble(double d) { if (double.IsNaN(d) || double.IsInfinity(d)) return d.ToString(); string text = d.ToString("G17", CultureInfo.InvariantCulture); if (text.IndexOf('.') > 0) return text + "d"; return text + ".0d"; } private static string FormatFloat(float f) { if (float.IsNaN(f) || float.IsInfinity(f)) return f.ToString(); string text = f.ToString("G9", CultureInfo.InvariantCulture); if (text.IndexOf('.') > 0) return text + "f"; return text + ".0f"; } private static string FormatDecimal(decimal d) { return d.ToString("G29", CultureInfo.InvariantCulture) + "m"; } private static string FormatDateTime(DateTime dt) { return dt.ToString(Fmt_DateTime, CultureInfo.InvariantCulture); } private static string FormatDateTimeOffset(DateTimeOffset dto) { return dto.ToString(Fmt_DateTimeOffset, CultureInfo.InvariantCulture); } public static string GetTypeRepresentation(object obj) { Array array = obj as Array; if (array == null) return $"""{obj.GetType()}"""; StringBuilder stringBuilder = new StringBuilder(); Type type = array.GetType(); int num = 0; while (type.IsArray) { type = type.GetElementType(); num++; } stringBuilder.Append(type.ToString()); stringBuilder.Append('['); for (int i = 0; i < array.Rank; i++) { if (i > 0) stringBuilder.Append(','); stringBuilder.Append(array.GetLength(i)); } stringBuilder.Append(']'); while (--num > 0) { stringBuilder.Append("[]"); } return $"""{stringBuilder.ToString()}"""; } public static string EscapeControlChars(string s) { if (s != null) { StringBuilder stringBuilder = new StringBuilder(); string text = s; foreach (char c in text) { switch (c) { case '\\': stringBuilder.Append("\\\\"); break; case '': stringBuilder.Append("\\0"); break; case '': stringBuilder.Append("\\a"); break; case '\b': stringBuilder.Append("\\b"); break; case ' ': stringBuilder.Append("\\f"); break; case '\n': stringBuilder.Append("\\n"); break; case '\r': stringBuilder.Append("\\r"); break; case '\t': stringBuilder.Append("\\t"); break; case ' ': stringBuilder.Append("\\v"); break; case '…': case '
': case '
': stringBuilder.Append($"""{(int)c:""}"); break; default: stringBuilder.Append(c); break; } } s = stringBuilder.ToString(); } return s; } public static string EscapeNullCharacters(string s) { if (s != null) { StringBuilder stringBuilder = new StringBuilder(); string text = s; foreach (char c in text) { if (c == '') stringBuilder.Append("\\0"); else stringBuilder.Append(c); } s = stringBuilder.ToString(); } return s; } public static string GetArrayIndicesAsString(int[] indices) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append('['); for (int i = 0; i < indices.Length; i++) { if (i > 0) stringBuilder.Append(','); stringBuilder.Append(indices[i].ToString()); } stringBuilder.Append(']'); return stringBuilder.ToString(); } public static int[] GetArrayIndicesFromCollectionIndex(IEnumerable collection, long index) { Array array = collection as Array; int num = array?.Rank ?? 1; int[] array2 = new int[num]; int num2 = num; while (--num2 > 0) { int length = array.GetLength(num2); array2[num2] = (int)index % length; index /= length; } array2[0] = (int)index; return array2; } public static string ClipString(string s, int maxStringLength, int clipStart) { int num = maxStringLength; StringBuilder stringBuilder = new StringBuilder(); if (clipStart > 0) { num -= "...".Length; stringBuilder.Append("..."); } if (s.Length - clipStart > num) { num -= "...".Length; stringBuilder.Append(s.Substring(clipStart, num)); stringBuilder.Append("..."); } else if (clipStart > 0) { stringBuilder.Append(s.Substring(clipStart)); } else { stringBuilder.Append(s); } return stringBuilder.ToString(); } public static void ClipExpectedAndActual(ref string expected, ref string actual, int maxDisplayLength, int mismatch) { int num = Math.Max(expected.Length, actual.Length); if (num > maxDisplayLength) { int num2 = maxDisplayLength - "...".Length; int num3 = num - num2; if (num3 > mismatch) num3 = Math.Max(0, mismatch - num2 / 2); expected = ClipString(expected, maxDisplayLength, num3); actual = ClipString(actual, maxDisplayLength, num3); } } public static int FindMismatchPosition(string expected, string actual, int istart, bool ignoreCase) { int num = Math.Min(expected.Length, actual.Length); string text = ignoreCase ? expected.ToLower() : expected; string text2 = ignoreCase ? actual.ToLower() : actual; for (int i = istart; i < num; i++) { if (text[i] != text2[i]) return i; } if (expected.Length != actual.Length) return num; return -1; } } }