Skip to content

Commit

Permalink
Merge pull request #402 from JakeGinnivan/ConventionTestImprovements
Browse files Browse the repository at this point in the history
Fixed some issues with the shouldly convention tests
  • Loading branch information
josephwoodward committed Oct 9, 2016
2 parents 1e4043d + 9e9b1be commit f5bf810
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ public void Execute(Types data, IConventionResultContext result)
{
var shouldThrowMethods = data
.SelectMany(t => t.GetMethods())
.Where(method => method.Name.StartsWith("Throw") || method.Name.StartsWith("ShouldThrow"))
.Where(method =>
method.Name.StartsWith("Throw") || method.Name.StartsWith("ShouldThrow") ||
method.Name.StartsWith("NotThrow") || method.Name.StartsWith("ShouldNotThrow"))
.Select(throwMethod => new ShouldThrowMethod(throwMethod))
.ToList();

var extensionMethods = shouldThrowMethods.Where(m => m.IsShouldlyExtension).ToList();
var staticMethods = shouldThrowMethods.Where(m => !m.IsShouldlyExtension).ToList();

var firstSetFailureData = staticMethods.Where(e => !extensionMethods.Any(e.Equals));
var secondSetFailureData = extensionMethods.Where(e => !staticMethods.Any(e.Equals));
var firstSetFailureData = staticMethods.Where(e => !extensionMethods.Any(e.Equals)).ToList();
var secondSetFailureData = extensionMethods.Where(e => !staticMethods.Any(e.Equals)).ToList();
result.IsSymmetric(
"Should.Throw method without corresponding ShouldThrow extension method",
firstSetFailureData,
Expand Down
8 changes: 7 additions & 1 deletion src/Shouldly.Tests/ConventionTests/ShouldThrowMethod.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Linq;
using System.Reflection;

Expand All @@ -21,7 +22,12 @@ public ShouldThrowMethod(MethodInfo throwMethod)

protected bool Equals(ShouldThrowMethod other)
{
return string.Equals(Name, other.Name) && Parameters.All(p => other.Parameters.Any(op => p.Name == op.Name && p.ParameterType == op.ParameterType));
return string.Equals(Name, other.Name) && Parameters.All(p => other.Parameters.Any(op => p.Name == op.Name && TypeEqual(p.ParameterType, op.ParameterType)));
}

private static bool TypeEqual(Type pt1, Type pt2)
{
return pt1.FormatType() == pt2.FormatType();
}

public override bool Equals(object obj)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'The following shouldly methods are missing one or more of the custom message overloads' for 'Types in Shouldly extension classes'
----------------------------------------------------------------------------------------------------------------------------------

ShouldMatchApproved(this System.String actual)
ShouldBe(this System.String actual, System.String expected, Shouldly.StringCompareShould options)
ShouldBe(this System.String actual, System.String expected, Shouldly.StringCompareShould option)
ShouldStartWith(this System.String actual, System.String expected)
ShouldEndWith(this System.String actual, System.String expected)
ShouldNotStartWith(this System.String actual, System.String expected)
ShouldNotEndWith(this System.String actual, System.String expected)
28 changes: 27 additions & 1 deletion src/Shouldly.Tests/ConventionTests/ShouldlyConventions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using TestStack.ConventionTests;
using TestStack.ConventionTests.ConventionData;
using Xunit;
Expand All @@ -18,7 +19,21 @@ public ShouldlyConventions()
[Fact]
public void ShouldHaveCustomMessageOverloads()
{
Convention.Is(new ShouldlyMethodsShouldHaveCustomMessageOverload(), _shouldlyMethodClasses);
Convention.GetFailures(new ShouldlyMethodsShouldHaveCustomMessageOverload(), _shouldlyMethodClasses)
.ShouldMatchApproved();
}

[Fact]
public void VerifyItWorks()
{
var ex = Should.Throw<ConventionFailedException>(() =>
{
var convention = new ShouldlyMethodsShouldHaveCustomMessageOverload();
var types = Types.InCollection(new[] { typeof(TestWithMissingOverloads) }, "Sample");
Convention.Is(convention, types);
});

ex.Message.ShouldContain("ShouldAlsoFail");
}

[Fact]
Expand All @@ -27,4 +42,15 @@ public void ShouldThrowMethodsShouldHaveExtensions()
Convention.Is(new ShouldThrowMatchesExtensionsConvention(), _shouldlyMethodClasses);
}
}

public static class TestWithMissingOverloads
{
public static void ShouldTest(this object foo) { }

public static void ShouldAlsoFail(this object foo) { }
public static void ShouldAlsoFail(this object foo, string customMessage) { }
public static void ShouldAlsoFail(this object foo, Func<string> customMessage) { }
public static void ShouldAlsoFail(this object foo, int param) { }
public static void ShouldAlsoFail(this object foo, int param, Func<string> customMessage) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ private bool HasNoCustomMessageOverload(IGrouping<string, MethodInfo> shouldlyMe
var hasFuncStringOverload = shouldlyMethod.Any(m => m.GetParameters().Any(IsCustomMessageParameter<Func<string>>));
var hasStringOverload = shouldlyMethod.Any(m => m.GetParameters().Any(IsCustomMessageParameter<string>));

return !hasFuncStringOverload && !hasStringOverload;
return !hasFuncStringOverload || !hasStringOverload;
}

private static bool IsCustomMessageParameter<T>(ParameterInfo p)
Expand Down
28 changes: 16 additions & 12 deletions src/Shouldly.Tests/ConventionTests/TypeExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace Shouldly.Tests.ConventionTests
{
Expand All @@ -16,20 +18,20 @@ public static bool HasAttribute(this Type type, string attributeName)
return type.GetCustomAttributes(true).Cast<Attribute>().Any(a => a.GetType().FullName == attributeName);
}

public static string FormatMethod(this MethodInfo shouldlyMethods, bool onlyIncludeFirstParam = false)
public static string FormatMethod(this MethodInfo shouldlyMethod, bool removeCustomMessage = false)
{
var parameters = shouldlyMethods.GetParameters();
var parameterType = FormatType(parameters[0].ParameterType);
if (shouldlyMethods.IsGenericMethod)
var parameters = shouldlyMethod.GetParameters();
var maybeFilteredParameters = removeCustomMessage ? parameters.Where(p => p.Name != "customMessage") : parameters;
var argList = string.Join(", ", maybeFilteredParameters.Select(p => string.Format("{0} {1}", p.ParameterType.FormatType(), p.Name)));
var extensionMethodText = shouldlyMethod.IsDefined(typeof (ExtensionAttribute), true)
? "this "
: string.Empty;
if (shouldlyMethod.IsGenericMethod)
{
string otherArgs = string.Empty;
if (!onlyIncludeFirstParam)
otherArgs = string.Join(", ", parameters.Skip(1).Select(p => string.Format("{0} {1}", p.ParameterType.FormatType(), p.Name)));
if (!string.IsNullOrEmpty(otherArgs))
otherArgs = ", " + otherArgs;
return string.Format("{0}(this {1} {2}{3})", shouldlyMethods.Name, parameterType, parameters[0].Name, otherArgs);
var genericArgs = string.Join(", ", shouldlyMethod.GetGenericArguments().Select(a => a.FormatType()));
return string.Format("{0}<{1}>({2}{3})", shouldlyMethod.Name, genericArgs, extensionMethodText, argList);
}
return string.Format("{0}(this {1})", shouldlyMethods.Name, parameterType);
return string.Format("{0}({1}{2})", shouldlyMethod.Name, extensionMethodText, argList);
}

public static string FormatType(this Type type)
Expand All @@ -43,7 +45,9 @@ public static string FormatType(this Type type)
string.Join("", genericTypeParams.Select(FormatType)));
}

return type.ToString();
return type.ToString()
.Replace("System.Object", "object")
.Replace("System.Int32", "int");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Shouldly
public static partial class ShouldBeStringTestExtensions
{
/// <summary>
/// Perform a case sensitive string comparison
/// Perform a string comparison, specifying the desired case sensitivity
/// </summary>
[Obsolete("Use the StringCompareShould enum instead of the Case enum")]
public static void ShouldBe(this string actual, string expected, Case caseSensitivity)
Expand Down Expand Up @@ -95,6 +95,7 @@ public static void ShouldBe(this string actual, string expected, Case caseSensit
var assertion = StringShouldBeAssertionFactory.Create(expected, actual, options);
ExecuteAssertion(assertion, customMessage);
}

static void ExecuteAssertion(Internals.Assertions.IAssertion assertion, Func<string> customMessage)
{
try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public static void ShouldStartWith(this string actual, string expected)
{
ShouldStartWith(actual, expected, () => null);
}

public static void ShouldStartWith(this string actual, string expected, Case caseSensitivity)
{
ShouldStartWith(actual, expected, () => null, caseSensitivity);
Expand Down

0 comments on commit f5bf810

Please sign in to comment.