Skip to content

Commit dfcec58

Browse files
committed
Merge pull request #46 from JakeGinnivan/AddedConventionReason
Adds convention reason to conventions, useful for the living documentati...
2 parents 1caea05 + d6ecde1 commit dfcec58

18 files changed

+77
-11
lines changed

TestStack.ConventionTests.Autofac/CanResolveAllRegisteredServices.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
namespace TestStack.ConventionTests.Autofac
22
{
3+
using global::Autofac;
4+
using global::Autofac.Core;
35
using System;
46
using System.Collections.Generic;
57
using System.Linq;
6-
using global::Autofac;
7-
using global::Autofac.Core;
88

99
public class CanResolveAllRegisteredServices : IConvention<AutofacRegistrations>
1010
{
@@ -37,6 +37,14 @@ public void Execute(AutofacRegistrations data, IConventionResultContext result)
3737
result.Is("Can resolve all types registered with Autofac", failingTypes);
3838
}
3939

40+
public string ConventionReason
41+
{
42+
get
43+
{
44+
return "Container resolution failings are runtime exceptions, this convention allows you to detect missing registrations faster!";
45+
}
46+
}
47+
4048
private IEnumerable<Type> GetGenericFactoryTypes(AutofacRegistrations data, IComponentRegistration componentRegistration)
4149
{
4250
return from ctorParameter in data.GetRegistrationCtorParameters(componentRegistration)

TestStack.ConventionTests.Autofac/ServicesShouldOnlyHaveDependenciesWithLesserLifetime.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
namespace TestStack.ConventionTests.Autofac
22
{
3-
using System.Collections.Generic;
43
using global::Autofac.Core;
4+
using System.Collections.Generic;
55
using TestStack.ConventionTests.ConventionData;
66

77
public class ServicesShouldOnlyHaveDependenciesWithLesserLifetime : IConvention<AutofacRegistrations>
@@ -37,5 +37,10 @@ public void Execute(AutofacRegistrations data, IConventionResultContext result)
3737

3838
result.Is("Components should not depend on with greater lifetimes", exceptions);
3939
}
40+
41+
public string ConventionReason
42+
{
43+
get { return @"When classes with larger lifetimes depend on classes with smaller lifetimes this often indicates an error and can lead to subtle bugs"; }
44+
}
4045
}
4146
}

TestStack.ConventionTests.Tests/ConventionAssertionClassTests.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ public void Execute(FakeData data, IConventionResultContext result)
3131
{
3232
result.Is("Header", new[] {"Different"});
3333
}
34+
35+
public string ConventionReason
36+
{
37+
get { return "Because fail.."; }
38+
}
3439
}
3540
}
3641
}

TestStack.ConventionTests.Tests/ConventionFixture.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public void Execute(Types data, IConventionResultContext result)
2525
// Oops, I forgot to set the result
2626
}
2727

28+
public string ConventionReason { get { return "Convention does not set result for testing"; } }
29+
2830
bool IsBroken(Type type)
2931
{
3032
return true;

TestStack.ConventionTests.Tests/TestConventions/CollectionsRelationsConvention.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ from item in GetItemTypes(collection)
2929
result.Is("Some title", collectionToItemLookup);
3030
}
3131

32+
public string ConventionReason
33+
{
34+
get { return "Test convention"; }
35+
}
36+
3237
IEnumerable<Type> GetItemTypes(Type type)
3338
{
3439
return from @interface in type.GetInterfaces()

TestStack.ConventionTests/Convention.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System;
44
using System.Collections.Generic;
55
using System.Reflection;
6-
using System.Text.RegularExpressions;
76
using TestStack.ConventionTests.ConventionData;
87
using TestStack.ConventionTests.Internal;
98
using TestStack.ConventionTests.Reporting;

TestStack.ConventionTests/Conventions/AllClassesHaveDefaultConstructor.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,10 @@ public void Execute(Types data, IConventionResultContext result)
1010
result.Is("Types must have a default constructor",
1111
data.TypesToVerify.Where(t => t.HasDefaultConstructor() == false));
1212
}
13+
14+
public string ConventionReason
15+
{
16+
get { return "This convention is useful when classes need to be proxied (nHibernate/Entity Framework entities), which need a public or protected constructor"; }
17+
}
1318
}
1419
}

TestStack.ConventionTests/Conventions/AllMethodsAreVirtual.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,10 @@ public void Execute(Types data, IConventionResultContext result)
99
{
1010
result.Is("Methods must be virtual", data.TypesToVerify.SelectMany(t => t.NonVirtualMethods()));
1111
}
12+
13+
public string ConventionReason
14+
{
15+
get { return "This convention is useful when classes need to be proxied (nHibernate entities), which need members to be virtual"; }
16+
}
1217
}
1318
}

TestStack.ConventionTests/Conventions/ClassTypeHasSpecificNamespace.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ public void Execute(Types data, IConventionResultContext result)
4141
data.TypesToVerify);
4242
}
4343

44+
public string ConventionReason
45+
{
46+
get { return "To simplify project structure and allow developers to know where this type of class should live in the project"; }
47+
}
48+
4449
bool TypeLivesInSpecifiedNamespace(Type t)
4550
{
4651
return t.Namespace == null || t.Namespace.StartsWith(namespaceToCheck);

TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,7 @@ public void Execute(ProjectFileItems data, IConventionResultContext result)
1818
string.Format("{0} Files must be embedded resources", FileExtension),
1919
data.Items.Where(s => s.FilePath.EndsWith(FileExtension) && s.ReferenceType != "EmbeddedResource"));
2020
}
21+
22+
public string ConventionReason { get { return "Many files are added as 'Content' to visual studio projects, this convention enforces files with an extension are correctly set as Embedded Resources"; } }
2123
}
2224
}

TestStack.ConventionTests/Conventions/MvcControllerNameAndBaseClassConvention.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ public void Execute(Types data, IConventionResultContext result)
2020
GetControllerTypeName() + "s must be suffixed with Controller", typesWhichDoNotEndInController,
2121
"Types named *Controller must inherit from ApiController or Controller",
2222
controllersWhichDoNotInheritFromController);
23-
}
24-
23+
}
24+
25+
public string ConventionReason { get { return "This convention detects when Mvc Controllers are likely misconfigured and do not follow Mvc conventions"; } }
26+
2527
protected virtual string GetControllerTypeName()
2628
{
2729
return "Mvc Controller";

TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public void Execute(ProjectReferences data, IConventionResultContext result)
1414
data.References.Where(IsBinOrObjReference));
1515
}
1616

17+
public string ConventionReason { get { return "Referencing assemblies from the bin/obj folder is normally due to a broken reference, this convention detects these issues"; } }
18+
1719
static bool IsBinOrObjReference(ProjectReference reference)
1820
{
1921
return Regex.IsMatch(reference.ReferencedPath, AssemblyReferencingObjRegex, RegexOptions.IgnoreCase);

TestStack.ConventionTests/Conventions/ViewModelShouldInheritFromINotifyPropertyChanged.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,13 @@ public void Execute(Types data, IConventionResultContext result)
2323
result.Is("ViewModels (types named *{0}) should inherit from INotifyPropertyChanged",
2424
failingData);
2525
}
26+
27+
public string ConventionReason
28+
{
29+
get
30+
{
31+
return "In different scenarios, WPF can hold onto ViewModels if they do not inherit from INotifyPropertyChanged";
32+
}
33+
}
2634
}
2735
}

TestStack.ConventionTests/IConvention.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
public interface IConvention<in T> where T : IConventionData
44
{
55
void Execute(T data, IConventionResultContext result);
6+
string ConventionReason { get; }
67
}
78
}

TestStack.ConventionTests/Internal/ConventionContext.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class ConventionContext : IConventionResultContext, IConventionFormatCont
1313
readonly IList<IResultsProcessor> processors;
1414
readonly ITestResultProcessor testResultProcessor;
1515
readonly IList<ConventionResult> results = new List<ConventionResult>();
16+
string conventionReason;
1617
bool resultSet;
1718

1819
public ConventionContext(string dataDescription, IList<IReportDataFormatter> formatters,
@@ -65,6 +66,7 @@ void IConventionResultContext.Is<TResult>(string resultTitle, IEnumerable<TResul
6566
results.Add(new ConventionResult(
6667
typeof (TResult),
6768
resultTitle,
69+
conventionReason,
6870
dataDescription,
6971
failingData.ToObjectArray()));
7072
}
@@ -76,11 +78,11 @@ void IConventionResultContext.IsSymmetric<TResult>(
7678
resultSet = true;
7779
results.Add(new ConventionResult(
7880
typeof (TResult), firstSetFailureTitle,
79-
dataDescription,
81+
conventionReason, dataDescription,
8082
firstSetFailureData.ToObjectArray()));
8183
results.Add(new ConventionResult(
8284
typeof (TResult), secondSetFailureTitle,
83-
dataDescription,
85+
conventionReason, dataDescription,
8486
secondSetFailureData.ToObjectArray()));
8587
}
8688

@@ -102,6 +104,7 @@ void IConventionResultContext.IsSymmetric<TResult>(
102104
public void Execute<TDataSource>(IConvention<TDataSource> convention, TDataSource data)
103105
where TDataSource : IConventionData
104106
{
107+
conventionReason = convention.ConventionReason;
105108
if (!data.HasData)
106109
throw new ConventionSourceInvalidException(String.Format("{0} has no data", data.Description));
107110
convention.Execute(data, this);

TestStack.ConventionTests/Internal/ConventionResult.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
public class ConventionResult
77
{
8-
public ConventionResult(Type dataType, string conventionTitle, string dataDescription, object[] data)
8+
public ConventionResult(Type dataType, string conventionTitle, string conventionReason, string dataDescription, object[] data)
99
{
10+
ConventionReason = conventionReason;
1011
DataType = dataType;
1112
ConventionTitle = conventionTitle;
1213
DataDescription = dataDescription;
@@ -15,6 +16,7 @@ public ConventionResult(Type dataType, string conventionTitle, string dataDescri
1516

1617
public Type DataType { get; private set; }
1718
public string ConventionTitle { get; private set; }
19+
public string ConventionReason { get; private set; }
1820
public string DataDescription { get; private set; }
1921
public object[] Data { get; private set; }
2022

@@ -23,6 +25,7 @@ public bool HasData
2325
get { return Data.Any(); }
2426
}
2527

28+
2629
protected bool Equals(ConventionResult other)
2730
{
2831
return DataType == other.DataType && string.Equals(ConventionTitle, other.ConventionTitle) && string.Equals(DataDescription, other.DataDescription);

TestStack.ConventionTests/Reporting/HtmlConventionResultsReporter.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ protected override string Process(IConventionFormatContext context, IEnumerable<
6666
html.RenderBeginTag(HtmlTextWriterTag.H4);
6767
html.Write(conventionResult.ConventionTitle);
6868
html.RenderEndTag();
69+
html.AddAttribute("style", "margin-left:20px;");
70+
html.RenderBeginTag(HtmlTextWriterTag.Div);
71+
html.Write(conventionResult.ConventionReason);
72+
html.RenderEndTag();
6973
if (conventionResult.Data.Any())
7074
{
7175
html.AddAttribute("style", "margin-left:20px;");

TestStack.ConventionTests/Reporting/MarkdownConventionResultsReporter.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ protected override string Process(IConventionFormatContext context, IEnumerable<
2222

2323
foreach (var conventionResult in conventionReport)
2424
{
25-
sb.Append(" - ");
26-
sb.AppendLine(conventionResult.ConventionTitle);
25+
sb.Append(" - **");
26+
sb.Append(conventionResult.ConventionTitle);
27+
sb.AppendLine("** ");
28+
sb.AppendLine(conventionResult.ConventionReason);
2729
}
2830
}
2931

0 commit comments

Comments
 (0)