Skip to content

Commit 3ba784c

Browse files
committed
moved some common logic out of Convention classes
so ConventionData now has an interface, not so POCO anymore, but we get to have 2LOC conventions
1 parent 5843c80 commit 3ba784c

File tree

8 files changed

+38
-43
lines changed

8 files changed

+38
-43
lines changed

TestStack.ConventionTests/Convention.cs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,27 @@ public static class Convention
1111
{
1212
public static readonly ConventionSettings Settings = new ConventionSettings();
1313

14-
public static void Is<TData>(IConvention<TData> convention, TData data)
14+
public static void Is<TData>(IConvention<TData> convention, TData data) where TData : IConventionData
1515
{
16+
if (data.HasValidSource == false)
17+
{
18+
// TODO: this would have to have a more reasonable and helpful message...
19+
Settings.AssertInclunclusive("No valid source in " + data);
20+
return;
21+
}
1622
var result = convention.Execute(data);
1723
if (result.IsConclusive == false)
1824
{
1925
Settings.AssertInclunclusive(result.Message);
26+
return;
2027
}
21-
else
28+
if (data.HasApprovedExceptions)
2229
{
23-
if (result.HasExceptions)
24-
{
25-
// should we encapsulate Approvals behind Settings?
26-
Approvals.Verify(result.Message);
27-
}
28-
else
29-
{
30-
Settings.AssertZero(result.InvalidResultsCount, result.Message);
31-
}
30+
// should we encapsulate Approvals behind Settings?
31+
Approvals.Verify(result.Message);
32+
return;
3233
}
34+
Settings.AssertZero(result.InvalidResultsCount, result.Message);
3335
}
3436

3537
public static void Is<T, T2>(IEnumerable<T2> itemsToVerify) where T : ConventionData<T2>, new()

TestStack.ConventionTests/Conventions/AllClassesHaveDefaultConstructor.cs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,17 @@
66

77
public class AllClassesHaveDefaultConstructor : IConvention<Types>
88
{
9-
public string HeaderMessage { get; set; }
10-
119
public AllClassesHaveDefaultConstructor()
1210
{
1311
HeaderMessage = "The following types do not have default constructor";
1412
}
1513

14+
public string HeaderMessage { get; set; }
15+
1616
public ConventionResult Execute(Types data)
1717
{
18-
var types = data.ApplicableTypes;
19-
if (types.None())
20-
{
21-
return ConventionResult.Inconclusive("Put sensible 'inconclusive' message here");
22-
}
23-
// NOTE: thie bit above is duplicated in both conventions we have, and will likely be duplicated in any other.
24-
// we likely will want to pull that out, leaving perhaps a property like InconclusiveMessage
25-
26-
var invalid = types.Where(t => t.HasDefaultConstructor() == false);
27-
var result = ConventionResult.For(invalid, HeaderMessage, (t, m) => m.AppendLine("\t" + t));
28-
29-
//if we switch conventionData to have an interface and put HasApprovedExceptions on it, we'll be able to pull this out as well.
30-
result.HasExceptions = data.HasApprovedExceptions;
31-
return result;
18+
var invalid = data.ApplicableTypes.Where(t => t.HasDefaultConstructor() == false);
19+
return ConventionResult.For(invalid, HeaderMessage, (t, m) => m.AppendLine("\t" + t));
3220
}
3321
}
3422
}

TestStack.ConventionTests/Conventions/AllMethodsAreVirtual.cs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,14 @@ public AllMethodsAreVirtual()
1515
HeaderMessage = "The following methods are not virtual.";
1616
}
1717

18+
public string HeaderMessage { get; set; }
19+
1820
public ConventionResult Execute(Types data)
1921
{
20-
var types = data.ApplicableTypes;
21-
if (types.None())
22-
{
23-
return ConventionResult.Inconclusive("Put sensible 'inconclusive' message here");
24-
}
25-
2622
// do we want to encapsulate that in some way?
2723
// also notice how data gives us types, yet the convention acts upon methods.
28-
var invalid = types.ToLookup(t => t, t => t.NonVirtualMethods()).Where(l => l.Any());
29-
var result = ConventionResult.For(invalid, HeaderMessage, DescribeTypeAndMethods);
30-
result.HasExceptions = data.HasApprovedExceptions;
31-
return result;
24+
var invalid = data.ApplicableTypes.ToLookup(t => t, t => t.NonVirtualMethods()).Where(l => l.Any());
25+
return ConventionResult.For(invalid, HeaderMessage, DescribeTypeAndMethods);
3226
}
3327

3428
// I like how that's encapsulated in the reusable convention type, whereas previously it was part of the convention/test code
@@ -40,7 +34,5 @@ void DescribeTypeAndMethods(IGrouping<Type, IEnumerable<MethodInfo>> item, Strin
4034
message.AppendLine("\t\t" + method);
4135
}
4236
}
43-
44-
public string HeaderMessage { get; set; }
4537
}
4638
}

TestStack.ConventionTests/IConvention.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{
33
using TestStack.ConventionTests.Internal;
44

5-
public interface IConvention<T>
5+
public interface IConvention<T> where T : IConventionData
66
{
77
ConventionResult Execute(T data);
88
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace TestStack.ConventionTests
2+
{
3+
public interface IConventionData
4+
{
5+
bool HasValidSource { get; }
6+
bool HasApprovedExceptions { get; }
7+
}
8+
}

TestStack.ConventionTests/Internal/ConventionResult.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ public class ConventionResult
1010
public string Message { get; set; }
1111
public bool IsConclusive { get; set; }
1212
// TODO: perhaps name it better so that it doesn't get confused with System.Exception and related concepts
13-
public bool HasExceptions { get; set; }
1413
public int InvalidResultsCount { get; set; }
1514

1615
public static ConventionResult For<TResult>(IEnumerable<TResult> items,

TestStack.ConventionTests/TestStack.ConventionTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
<Reference Include="System.Xml" />
6060
</ItemGroup>
6161
<ItemGroup>
62+
<Compile Include="IConventionData.cs" />
6263
<Compile Include="Internal\ConventionResult.cs" />
6364
<Compile Include="Conventions\AllMethodsAreVirtual.cs" />
6465
<Compile Include="ConventionFailedException.cs" />

TestStack.ConventionTests/Types.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
namespace TestStack.ConventionTests
22
{
33
using System;
4+
using System.Linq;
45

56
/// <summary>
67
/// This is where we set what our convention is all about.
78
/// </summary>
8-
// NOTE: notice no base type, no interface. Just a POCO DTO
9-
public class Types
9+
public class Types : IConventionData
1010
{
1111
//NOTE: that's a terrible name
1212
public Type[] ApplicableTypes { get; set; }
1313

1414
public bool HasApprovedExceptions { get; set; }
15+
16+
public bool HasValidSource
17+
{
18+
get { return ApplicableTypes.Any(); }
19+
}
1520
}
1621
}

0 commit comments

Comments
 (0)