-
-
Save haacked/1610603 to your computer and use it in GitHub Desktop.
public static class TestHelpers | |
{ | |
public static void ShouldEqualWithDiff(this string actualValue, string expectedValue) | |
{ | |
ShouldEqualWithDiff(actualValue, expectedValue, DiffStyle.Full, Console.Out); | |
} | |
public static void ShouldEqualWithDiff(this string actualValue, string expectedValue, DiffStyle diffStyle) | |
{ | |
ShouldEqualWithDiff(actualValue, expectedValue, diffStyle, Console.Out); | |
} | |
public static void ShouldEqualWithDiff(this string actualValue, string expectedValue, DiffStyle diffStyle, TextWriter output) | |
{ | |
if(actualValue == null || expectedValue == null) | |
{ | |
//Assert.AreEqual(expectedValue, actualValue); | |
Assert.Equal(expectedValue, actualValue); | |
return; | |
} | |
if (actualValue.Equals(expectedValue, StringComparison.Ordinal)) return; | |
output.WriteLine(" Idx Expected Actual"); | |
output.WriteLine("-------------------------"); | |
int maxLen = Math.Max(actualValue.Length, expectedValue.Length); | |
int minLen = Math.Min(actualValue.Length, expectedValue.Length); | |
for (int i = 0; i < maxLen; i++) | |
{ | |
if (diffStyle != DiffStyle.Minimal || i >= minLen || actualValue[i] != expectedValue[i]) | |
{ | |
output.WriteLine("{0} {1,-3} {2,-4} {3,-3} {4,-4} {5,-3}", | |
i < minLen && actualValue[i] == expectedValue[i] ? " " : "*", // put a mark beside a differing row | |
i, // the index | |
i < expectedValue.Length ? ((int)expectedValue[i]).ToString() : "", // character decimal value | |
i < expectedValue.Length ? expectedValue[i].ToSafeString() : "", // character safe string | |
i < actualValue.Length ? ((int)actualValue[i]).ToString() : "", // character decimal value | |
i < actualValue.Length ? actualValue[i].ToSafeString() : "" // character safe string | |
); | |
} | |
} | |
output.WriteLine(); | |
//Assert.AreEqual(expectedValue, actualValue); | |
Assert.Equal(expectedValue, actualValue); | |
} | |
private static string ToSafeString(this char c) | |
{ | |
if (Char.IsControl(c) || Char.IsWhiteSpace(c)) | |
{ | |
switch (c) | |
{ | |
case '\r': | |
return @"\r"; | |
case '\n': | |
return @"\n"; | |
case '\t': | |
return @"\t"; | |
case '\a': | |
return @"\a"; | |
case '\v': | |
return @"\v"; | |
case '\f': | |
return @"\f"; | |
default: | |
return String.Format("\\u{0:X};", (int)c); | |
} | |
} | |
return c.ToString(CultureInfo.InvariantCulture); | |
} | |
} | |
public enum DiffStyle | |
{ | |
Full, | |
Minimal | |
} |
Not knowing C#, I learned with your example the meaning of the prefix @ before a string literal in C# = no escaped char sequences.
@jarshwah Thanks! Are you sure that makes a difference? There are many cases where the C# compiler can optimize calls like this. For example, since it knows that actualValue and expectedValue don't change, it can evaluate the length and max once. I don't know if it does it in this particular case, but would be interesting to check the IL and measure it to see if it really does make a difference. :)
I forked and made some modifications to your snippet, here it is: https://gist.github.com/1615334
- Extended the list of safe strings according to: http://sinairv.wordpress.com/2010/08/08/code-snippet-representing-strings-with-all-their-characters-visible/
- Moved all tabular formatting to the main method using String.Format
- added support for minimal diff representation
- checked for null input strings
- and a little more
PS. how can I send a pull request for a gist?
@sinairv thanks! I'll take a look at it. Unfortunately, gistts don't support pull requests.
@haacked & @sinairv, for readability, I would suggest removing the call to string.Format & using the overload output.WriteLine(string format, params object[] args)
output.WriteLine("{0} {1,-3} {2,-4} {3,-3} {4,-4} {5,-3}",
i < minLen && actual[i] == expected[i] ? " " : "*", // put a mark beside a differing row
i, // the index
i < expected.Length ? ((int)expected[i]).ToString() : "", // character decimal value
i < expected.Length ? expected[i].ToSafeString() : "", // character safe string
i < actual.Length ? ((int)actual[i]).ToString() : "", // character decimal value
i < actual.Length ? actual[i].ToSafeString() : "" // character safe string
);
@dotnetzebra good suggestion. I made the change.
Thx man.
This helper class help me A LOT with some tricky tests.
I like this. Helped me out a lot.
Maybe consider creating a NuGet package just for this source file. You can create NuGet packages for source pretty easily. I am doing just that now with common files I used to drag around.
http://www.rhyous.com/2016/03/03/nuget-for-source-using-add-as-link-1
Moved the Math.Max() outside the loop declaration: https://gist.github.com/1610860