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