aboutsummaryrefslogtreecommitdiff
path: root/src/internal/WixInternal.TestSupport/WixAssert.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/WixInternal.TestSupport/WixAssert.cs')
-rw-r--r--src/internal/WixInternal.TestSupport/WixAssert.cs143
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
3namespace 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}