Skip to content

Instantly share code, notes, and snippets.

@whatupdave
Created December 8, 2009 23:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whatupdave/252084 to your computer and use it in GitHub Desktop.
Save whatupdave/252084 to your computer and use it in GitHub Desktop.
Assert Awesomely
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Linq;
using NUnit.Framework.Constraints;
namespace NUnit.Framework
{
public static class AwesomeTestExtensions
{
[DebuggerStepThrough]
public static void ShouldBe<T>(this T actual, T expected)
{
actual.AssertAwesomely(Is.EqualTo(expected), expected);
}
[DebuggerStepThrough]
public static void ShouldContain(this string actual, string expected)
{
actual.AssertAwesomely(Is.StringContaining(expected).IgnoreCase, expected);
}
[DebuggerStepThrough]
public static void ShouldNotContain(this string actual, string expected)
{
actual.AssertAwesomely(Is.Not.StringContaining(expected).IgnoreCase, expected);
}
[DebuggerStepThrough]
public static void ShouldBeGreaterThan(this int actual, int expected)
{
actual.AssertAwesomely(Is.GreaterThan(expected), expected);
}
[DebuggerStepThrough]
private static string GenerateShouldBeMessage<T>(T expected, T actual)
{
var thisClassName = typeof (AwesomeTestExtensions).Name;
var stackTrace = new StackTrace(true);
var i = 0;
var frame = stackTrace.GetFrame(i);
var shouldMethod = "";
while (frame.GetMethod().DeclaringType.Name == thisClassName)
{
shouldMethod = frame.GetMethod().Name;
frame = stackTrace.GetFrame(++i);
}
var lineNumber = frame.GetFileLineNumber() - 1;
var fileName = frame.GetFileName();
var codeLines = string.Join("\n", File.ReadAllLines(fileName).Skip(lineNumber).ToArray());
var codePart = codeLines.Substring(0, codeLines.IndexOf(shouldMethod) - 1).Trim();
return string.Format(
@"{0}
{1}
{2}
but was
{3}",
codePart, shouldMethod.FromPascal(), VariableToString(expected), VariableToString(actual));
}
private static void AssertAwesomely<T>(this T actual, IResolveConstraint specifiedConstraint, object expected)
{
AssertAwesomely(actual, specifiedConstraint, expected, null);
}
private static void AssertAwesomely<T>(this T actual, IResolveConstraint specifiedConstraint, object expected, string message)
{
var constraint = specifiedConstraint.Resolve();
if (constraint.Matches(actual)) return;
var writer = new TextMessageWriter(GenerateShouldBeMessage(expected, actual));
if (message != null) writer.WriteMessageLine(message);
throw new AssertionException(writer.ToString());
}
private static string VariableToString<T>(T value)
{
if (value is string)
return "\"" + value + "\"";
if (value is IEnumerable)
{
var objects = ((IEnumerable)value).Cast<object>();
return "[" + string.Join(", ", objects.Select(o => VariableToString(o)).ToArray()) + "]";
}
if (value == null)
return "null";
return string.Format(@"{0}", value);
}
private static string FromPascal(this string pascal)
{
return Regex.Replace(pascal, @"([A-Z])", match => " " + match.Value.ToLower()).Trim();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment