diff options
Diffstat (limited to '')
| -rw-r--r-- | src/internal/WixInternal.TestSupport/WixAssert.cs | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/internal/WixInternal.TestSupport/WixAssert.cs b/src/internal/WixInternal.TestSupport/WixAssert.cs new file mode 100644 index 00000000..40355131 --- /dev/null +++ b/src/internal/WixInternal.TestSupport/WixAssert.cs | |||
| @@ -0,0 +1,143 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixInternal.MSTestSupport | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using System.Collections.Generic; | ||
| 7 | using System.Linq; | ||
| 8 | using System.Text; | ||
| 9 | using System.Xml.Linq; | ||
| 10 | using Xunit; | ||
| 11 | using Xunit.Sdk; | ||
| 12 | |||
| 13 | public class WixAssert | ||
| 14 | { | ||
| 15 | public static void CompareLineByLine(string[] expectedLines, string[] actualLines) | ||
| 16 | { | ||
| 17 | var lineNumber = 0; | ||
| 18 | |||
| 19 | for (; lineNumber < expectedLines.Length && lineNumber < actualLines.Length; ++lineNumber) | ||
| 20 | { | ||
| 21 | StringEqual($"{lineNumber}: {expectedLines[lineNumber]}", $"{lineNumber}: {actualLines[lineNumber]}"); | ||
| 22 | } | ||
| 23 | |||
| 24 | var additionalExpectedLines = expectedLines.Length > lineNumber ? String.Join(Environment.NewLine, expectedLines.Skip(lineNumber).Select((s, i) => $"{lineNumber + i}: {s}")) : $"Missing {actualLines.Length - lineNumber} lines"; | ||
| 25 | var additionalActualLines = actualLines.Length > lineNumber ? String.Join(Environment.NewLine, actualLines.Skip(lineNumber).Select((s, i) => $"{lineNumber + i}: {s}")) : $"Missing {expectedLines.Length - lineNumber} lines"; | ||
| 26 | |||
| 27 | Assert.Equal<object>(additionalExpectedLines, additionalActualLines, StringObjectEqualityComparer.InvariantCulture); | ||
| 28 | } | ||
| 29 | |||
| 30 | public static void CompareXml(XContainer xExpected, XContainer xActual) | ||
| 31 | { | ||
| 32 | var expecteds = ComparableElements(xExpected); | ||
| 33 | var actuals = ComparableElements(xActual); | ||
| 34 | |||
| 35 | CompareLineByLine(expecteds.OrderBy(s => s).ToArray(), actuals.OrderBy(s => s).ToArray()); | ||
| 36 | } | ||
| 37 | |||
| 38 | public static void CompareXml(string expectedPath, string actualPath) | ||
| 39 | { | ||
| 40 | var expectedDoc = XDocument.Load(expectedPath, LoadOptions.PreserveWhitespace | LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); | ||
| 41 | var actualDoc = XDocument.Load(actualPath, LoadOptions.PreserveWhitespace | LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); | ||
| 42 | |||
| 43 | CompareXml(expectedDoc, actualDoc); | ||
| 44 | } | ||
| 45 | |||
| 46 | private static IEnumerable<string> ComparableElements(XContainer container) | ||
| 47 | { | ||
| 48 | return container.Descendants().Select(x => $"{x.Name.LocalName}:{String.Join(",", x.Attributes().OrderBy(a => a.Name.LocalName).Select(a => $"{a.Name.LocalName}={ComparableAttribute(a)}"))}"); | ||
| 49 | } | ||
| 50 | |||
| 51 | private static string ComparableAttribute(XAttribute attribute) | ||
| 52 | { | ||
| 53 | switch (attribute.Name.LocalName) | ||
| 54 | { | ||
| 55 | case "SourceFile": | ||
| 56 | return "<SourceFile>"; | ||
| 57 | default: | ||
| 58 | return attribute.Value; | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | public static void StringCollectionEmpty(IList<string> collection) | ||
| 63 | { | ||
| 64 | if (collection.Count > 0) | ||
| 65 | { | ||
| 66 | Assert.Fail($"The collection was expected to be empty, but instead was [{Environment.NewLine}\"{String.Join($"\", {Environment.NewLine}\"", collection)}\"{Environment.NewLine}]"); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | public static void StringEqual(string expected, string actual, bool ignoreCase = false) | ||
| 71 | { | ||
| 72 | WixStringEqualException.ThrowIfNotEqual(expected, actual, ignoreCase); | ||
| 73 | } | ||
| 74 | |||
| 75 | public static void NotStringEqual(string expected, string actual, bool ignoreCase = false) | ||
| 76 | { | ||
| 77 | var comparer = ignoreCase ? StringObjectEqualityComparer.InvariantCultureIgnoreCase : StringObjectEqualityComparer.InvariantCulture; | ||
| 78 | Assert.NotEqual(expected, actual, comparer); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | internal class StringObjectEqualityComparer : IEqualityComparer<object> | ||
| 83 | { | ||
| 84 | public static readonly StringObjectEqualityComparer InvariantCultureIgnoreCase = new StringObjectEqualityComparer(true); | ||
| 85 | public static readonly StringObjectEqualityComparer InvariantCulture = new StringObjectEqualityComparer(false); | ||
| 86 | |||
| 87 | private readonly StringComparer stringComparer; | ||
| 88 | |||
| 89 | public StringObjectEqualityComparer(bool ignoreCase) | ||
| 90 | { | ||
| 91 | this.stringComparer = ignoreCase ? StringComparer.InvariantCultureIgnoreCase : StringComparer.InvariantCulture; | ||
| 92 | } | ||
| 93 | |||
| 94 | public new bool Equals(object x, object y) | ||
| 95 | { | ||
| 96 | return this.stringComparer.Equals((string)x, (string)y); | ||
| 97 | } | ||
| 98 | |||
| 99 | public int GetHashCode(object obj) | ||
| 100 | { | ||
| 101 | return this.stringComparer.GetHashCode((string)obj); | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | public class WixStringEqualException : XunitException | ||
| 106 | { | ||
| 107 | public WixStringEqualException(string userMessage) : base(userMessage) { } | ||
| 108 | |||
| 109 | public static void ThrowIfNotEqual(string expected, string actual, bool ignoreCase) | ||
| 110 | { | ||
| 111 | var comparer = ignoreCase ? StringObjectEqualityComparer.InvariantCultureIgnoreCase : StringObjectEqualityComparer.InvariantCulture; | ||
| 112 | if (comparer.Equals(expected, actual)) | ||
| 113 | { | ||
| 114 | return; | ||
| 115 | } | ||
| 116 | |||
| 117 | var sbMessage = new StringBuilder(); | ||
| 118 | |||
| 119 | try | ||
| 120 | { | ||
| 121 | Assert.Equal(expected, actual, ignoreCase); | ||
| 122 | } | ||
| 123 | catch (XunitException xe) | ||
| 124 | { | ||
| 125 | // If either string is not completely in the message, then make sure it gets in there. | ||
| 126 | if (!xe.Message.Contains(expected) || !xe.Message.Contains(actual)) | ||
| 127 | { | ||
| 128 | sbMessage.AppendLine(xe.Message); | ||
| 129 | sbMessage.AppendLine(); | ||
| 130 | sbMessage.AppendFormat("Expected: {0}", expected); | ||
| 131 | sbMessage.AppendLine(); | ||
| 132 | sbMessage.AppendFormat("Actual: {0}", actual); | ||
| 133 | } | ||
| 134 | else | ||
| 135 | { | ||
| 136 | throw; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | |||
| 140 | throw new WixStringEqualException(sbMessage.ToString()); | ||
| 141 | } | ||
| 142 | } | ||
| 143 | } | ||
