Permalink
Browse files

Issue #21 - ShouldBeEmpty/ShouldNotBeEmpty

Implemented ShouldBeEmpty/ShouldNotBeEmpty

Started refactor of ShouldlyMessage to split the
  message generation into a chain of responsibility of generators
  based on the "Should" method.
  This structure will give us flexibility in providing more customised
    error messages for each "should" method
  • Loading branch information...
xerxesb committed Sep 23, 2011
1 parent 9548682 commit 08c4ebfa2908dd25c9343b5d3d2363bc11605a22
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using NUnit.Framework;
namespace Shouldly.Tests
@@ -104,5 +105,52 @@ public void ShouldContain_WithNumbersWhenFalse_ShouldErrorWithMessage()
"new[] { 1.0f, 2.1f, (float)Math.PI, 4.321f, 5.4321f } should contain 3.14 but was [1, 2.1, 3.141593, 4.321, 5.4321]");
}
+ [Test]
+ public void ShouldBeEmpty_WhenEmpty_ShouldNotError()
+ {
+ Should.NotError(() => new object[0].ShouldBeEmpty());
+ }
+
+ [Test]
+ public void ShouldBeEmpty_WhenNull_ShouldError()
+ {
+ IEnumerable<object> objects = null;
+ Should.Error(() =>
+ objects.ShouldBeEmpty(),
+ "objects should be empty but was null");
+ }
+
+ [Test]
+ public void ShouldBeEmpty_WhenNotEmpty_ShouldError()
+ {
+ var objects = (new[] { new object(), new object() });
+ Should.Error(() =>
+ objects.ShouldBeEmpty(),
+ "objects should be empty but was [System.Object, System.Object]");
+ }
+
+ [Test]
+ public void ShouldNotBeEmpty_WhenNotEmpty_ShouldNotError()
+ {
+ Should.NotError(() => new[] { new object() }.ShouldNotBeEmpty());
+ }
+
+ [Test]
+ public void ShouldNotBeEmpty_WhenNull_ShouldError()
+ {
+ IEnumerable<object> objects = null;
+ Should.Error(() =>
+ objects.ShouldNotBeEmpty(),
+ "objects should not be empty but was null");
+ }
+
+ [Test]
+ public void ShouldNotBeEmpty_WhenEmpty_ShouldError()
+ {
+ var objects = new object[0];
+ Should.Error(() =>
+ objects.ShouldNotBeEmpty(),
+ "objects should not be empty but was");
+ }
}
}
@@ -36,6 +36,18 @@ public static void ShouldNotContain<T>(this IEnumerable<T> actual, Expression<Fu
throw new ChuckedAWobbly(new ShouldlyMessage(elementPredicate.Body).ToString());
}
+ public static void ShouldBeEmpty<T>(this IEnumerable<T> actual)
+ {
+ if (actual == null || (actual != null && actual.Count() != 0))
+ throw new ChuckedAWobbly(new ShouldlyMessage(actual).ToString());
+ }
+
+ public static void ShouldNotBeEmpty<T>(this IEnumerable<T> actual)
+ {
+ if (actual == null || actual != null && actual.Count() == 0)
+ throw new ChuckedAWobbly(new ShouldlyMessage(actual).ToString());
+ }
+
public static void ShouldContain(this IEnumerable<float> actual, float expected, double tolerance)
{
if (actual.Where(a => Math.Abs(expected - a) < tolerance).Count() < 1)
@@ -67,6 +67,7 @@
<Compile Include="ShouldBeTestExtensions.cs" />
<Compile Include="ShouldlyCoreExtensions.cs" />
<Compile Include="ShouldlyMessage.cs" />
+ <Compile Include="ShouldlyMessageGenerators.cs" />
<Compile Include="ShouldlyMethodsAttribute.cs" />
<Compile Include="ShouldlyRhinoExtensions.cs" />
<Compile Include="ShouldThrowTestExtensions.cs" />
@@ -1,8 +1,8 @@
using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Linq.Expressions;
using Shouldly.DifferenceHighlighting;
using System.Reflection;
@@ -18,27 +18,28 @@ internal class TestEnvironment
internal class ShouldlyMessage
{
- private readonly object expected;
- private readonly object actual;
- private readonly bool hasActual;
+ private readonly object _expected;
+ private readonly object _actual;
+ private readonly bool _hasActual;
+ private static readonly IEnumerable<ShouldlyMessageGenerator> ShouldlyMessageGenerators = new ShouldlyMessageGenerator[] { new ShouldBeEmptyMessageGenerator(), new DefaultMessageGenerator() };
public ShouldlyMessage(object expected)
{
- this.expected = expected;
+ _expected = expected;
}
public ShouldlyMessage(object expected, object actual)
{
- this.actual = actual;
- this.expected = expected;
- hasActual = true;
+ _actual = actual;
+ _expected = expected;
+ _hasActual = true;
}
public override string ToString()
{
- return hasActual ?
- GenerateShouldMessage(actual, expected) :
- GenerateShouldMessage(expected);
+ return _hasActual ?
+ GenerateShouldMessage(_actual, _expected) :
+ GenerateShouldMessage(_expected);
}
private static string GenerateShouldMessage(object actual, object expected)
@@ -61,7 +62,15 @@ private static string GenerateShouldMessage(object actual, object expected)
return CreateActualVsExpectedMessage(actual, expected, environment, codePart);
}
- private static string CreateActualVsExpectedMessage(object actual, object expected, TestEnvironment environment, string codePart)
+ private static string GenerateShouldMessage(object expected)
+ {
+ var environment = GetStackFrameForOriginatingTestMethod();
+ var message = ShouldlyMessageGenerators.First(x => x.CanProcess(environment)).GenerateErrorMessage(environment, expected);
+
+ return message;
+ }
+
+ private static string CreateActualVsExpectedMessage(object actual, object expected, TestEnvironment environment, string codePart)
{
string message = string.Format(@"{0}
{1}
@@ -70,7 +79,8 @@ but was
{3}",
codePart, environment.ShouldMethod.PascalToSpaced(), expected.Inspect(), actual.Inspect());
- if (actual.CanGenerateDifferencesBetween(expected)) {
+ if (actual.CanGenerateDifferencesBetween(expected))
+ {
message += string.Format(@"
difference
{0}",
@@ -79,31 +89,6 @@ but was
return message;
}
- private static string GenerateShouldMessage(object expected)
- {
- var environment = GetStackFrameForOriginatingTestMethod();
- var codePart = "The provided expression";
-
- if (environment.DeterminedOriginatingFrame)
- {
- var codeLines = string.Join("\n",
- File.ReadAllLines(environment.FileName)
- .Skip(environment.LineNumber).ToArray());
-
- codePart = codeLines.Substring(0, codeLines.IndexOf(environment.ShouldMethod) - 1).Trim();
- }
-
- var isNegatedAssertion = environment.ShouldMethod.Contains("Not");
-
- const string elementSatifyingTheConditionString = "an element satisfying the condition";
- return string.Format(
- @"{0}
- {1} {2}
- {3}
- but does {4}",
- codePart, environment.ShouldMethod.PascalToSpaced(), expected is BinaryExpression ? elementSatifyingTheConditionString : "", expected.Inspect(), isNegatedAssertion ? "" : "not");
- }
-
private static TestEnvironment GetStackFrameForOriginatingTestMethod()
{
var stackTrace = new StackTrace(true);
@@ -137,7 +122,7 @@ private static bool IsShouldlyMethod(MethodBase method)
if (method.DeclaringType == null)
return false;
- return method.DeclaringType.GetCustomAttributes(typeof (ShouldlyMethodsAttribute), true).Any();
+ return method.DeclaringType.GetCustomAttributes(typeof(ShouldlyMethodsAttribute), true).Any();
}
}
}
@@ -0,0 +1,78 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text.RegularExpressions;
+
+namespace Shouldly
+{
+ internal class ShouldBeEmptyMessageGenerator : ShouldlyMessageGenerator
+ {
+ private static readonly Regex Validator = new Regex("Should(Not)?BeEmpty", RegexOptions.Compiled);
+
+ public override bool CanProcess(TestEnvironment environment)
+ {
+ return Validator.IsMatch(environment.ShouldMethod);
+ }
+
+ public override string GenerateErrorMessage(TestEnvironment environment, object actual)
+ {
+ const string format = @"{0}
+ {1}
+ but was {2}";
+
+ var codePart = GetCodePart(environment);
+ var actualValue = actual.Inspect();
+
+ var isNegatedAssertion = environment.ShouldMethod.Contains("Not");
+ if (isNegatedAssertion)
+ return String.Format(format, codePart, environment.ShouldMethod.PascalToSpaced(), actual == null ? "null" : "");
+
+ return String.Format(format, codePart, environment.ShouldMethod.PascalToSpaced(), actualValue);
+ }
+ }
+
+ internal class DefaultMessageGenerator : ShouldlyMessageGenerator
+ {
+ public override bool CanProcess(TestEnvironment environment)
+ {
+ return true;
+ }
+
+ public override string GenerateErrorMessage(TestEnvironment environment, object expected)
+ {
+ var format = @"{0}
+ {1} {2}
+ {3}
+ but does {4}";
+
+ var codePart = GetCodePart(environment);
+ var isNegatedAssertion = environment.ShouldMethod.Contains("Not");
+
+ const string elementSatifyingTheConditionString = "an element satisfying the condition";
+ return String.Format(format, codePart, environment.ShouldMethod.PascalToSpaced(), expected is BinaryExpression ? elementSatifyingTheConditionString : "", expected.Inspect(), isNegatedAssertion ? "" : "not");
+ }
+ }
+
+ internal abstract class ShouldlyMessageGenerator
+ {
+ public abstract bool CanProcess(TestEnvironment environment);
+ public abstract string GenerateErrorMessage(TestEnvironment environment, object expected);
+
+
+ protected static string GetCodePart(TestEnvironment environment)
+ {
+ var codePart = "The provided expression";
+
+ if (environment.DeterminedOriginatingFrame)
+ {
+ var codeLines = String.Join("\n",
+ File.ReadAllLines(environment.FileName)
+ .Skip(environment.LineNumber).ToArray());
+
+ codePart = codeLines.Substring(0, codeLines.IndexOf(environment.ShouldMethod) - 1).Trim();
+ }
+ return codePart;
+ }
+ }
+}

0 comments on commit 08c4ebf

Please sign in to comment.