Skip to content
Merged
12 changes: 3 additions & 9 deletions TestStack.ConventionTests.Tests/ConventionAssertionClassTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
{
using ApprovalTests.Reporters;
using NUnit.Framework;
using TestStack.ConventionTests.Internal;

[TestFixture]
[UseReporter(typeof(DiffReporter))] //NOTE: Can we take care of this in IsWithApprovedExceptions?
[UseReporter(typeof(QuietReporter))] //NOTE: Can we take care of this in IsWithApprovedExceptions?
public class ConventionAssertionClassTests
{
[Test]
Expand All @@ -19,19 +18,14 @@ public void approval_mismatch()
StringAssert.Contains("does not match approved file", ex.Message);
}

public class FakeData : IConventionData
class FakeData : IConventionData
{
public string Description { get { return "Fake data"; } }

public bool HasData { get { return true; } }

public ConventionReportFailure Format(string failingData)
{
return new ConventionReportFailure(failingData);
}
}

public class FailingConvention : IConvention<FakeData>
class FailingConvention : IConvention<FakeData>
{
public void Execute(FakeData data, IConventionResultContext result)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
'Api Controllers must be suffixed with Controller' for 'TestAssembly'
---------------------------------------------------------------------
'Api Controllers must be suffixed with Controller' for 'Types in TestAssembly'
------------------------------------------------------------------------------

TestAssembly.Controllers.BarApiControler

'Types named *Controller must inherit from ApiController or Controller' for 'TestAssembly'
------------------------------------------------------------------------------------------
'Types named *Controller must inherit from ApiController or Controller' for 'Types in TestAssembly'
---------------------------------------------------------------------------------------------------

TestAssembly.Controllers.TestApiController
TestAssembly.Controllers.TestController
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
'Mvc Controllers must be suffixed with Controller' for 'TestAssembly'
---------------------------------------------------------------------
'Mvc Controllers must be suffixed with Controller' for 'Types in TestAssembly'
------------------------------------------------------------------------------

TestAssembly.Controllers.FooControler

'Types named *Controller must inherit from ApiController or Controller' for 'TestAssembly'
------------------------------------------------------------------------------------------
'Types named *Controller must inherit from ApiController or Controller' for 'Types in TestAssembly'
---------------------------------------------------------------------------------------------------

TestAssembly.Controllers.TestApiController
TestAssembly.Controllers.TestController
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'Project must not reference dlls from bin or obj directories' for 'TestStack.ConventionTests.Tests'
---------------------------------------------------------------------------------------------------
'Project must not reference dlls from bin or obj directories' for 'Project references in TestStack.ConventionTests.Tests'
-------------------------------------------------------------------------------------------------------------------------

bin\Debug\ApprovalTests.dll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'Project must not reference dlls from bin or obj directories' for 'TestStack.ConventionTests.Tests'
---------------------------------------------------------------------------------------------------
'Project must not reference dlls from bin or obj directories' for 'Project references in TestStack.ConventionTests.Tests'
-------------------------------------------------------------------------------------------------------------------------

bin\Debug\ApprovalTests.dll
4 changes: 2 additions & 2 deletions TestStack.ConventionTests.Tests/ProjectBasedConventions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public void scripts_not_embedded_resources()
.Returns(XDocument.Parse(Resources.ProjectFileWithInvalidSqlScriptFile));

var projectLocator = Substitute.For<IProjectLocator>();
var project = new ProjectFiles(typeof (ProjectBasedConventions).Assembly, projectProvider, projectLocator);
var project = new ProjectFileItems(typeof (ProjectBasedConventions).Assembly, projectProvider, projectLocator);
var ex = Assert.Throws<ConventionFailedException>(() => Convention.Is(new FilesAreEmbeddedResources(".sql"), project));

Approvals.Verify(ex.Message);
Expand All @@ -67,7 +67,7 @@ public void scripts_not_embedded_resources()
public void scripts_not_embedded_resources_with_approved_exceptions()
{
var projectLocator = Substitute.For<IProjectLocator>();
var project = new ProjectFiles(typeof (ProjectBasedConventions).Assembly, projectProvider, projectLocator);
var project = new ProjectFileItems(typeof (ProjectBasedConventions).Assembly, projectProvider, projectLocator);
projectProvider
.LoadProjectDocument(Arg.Any<string>())
.Returns(XDocument.Parse(Resources.ProjectFileWithInvalidSqlScriptFile));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'.sql Files must be embedded resources' for 'TestStack.ConventionTests.Tests'
-----------------------------------------------------------------------------
'.sql Files must be embedded resources' for 'Project file items in TestStack.ConventionTests.Tests'
---------------------------------------------------------------------------------------------------

Scripts\Script2.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'.sql Files must be embedded resources' for 'TestStack.ConventionTests.Tests'
-----------------------------------------------------------------------------
'.sql Files must be embedded resources' for 'Project file items in TestStack.ConventionTests.Tests'
---------------------------------------------------------------------------------------------------

Scripts\Script2.sql
7 changes: 6 additions & 1 deletion TestStack.ConventionTests.Tests/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System.Reflection;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
using TestStack.ConventionTests;
using TestStack.ConventionTests.Reporting;

[assembly: AssemblyTitle("TestStack.ConventionTests.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
Expand Down Expand Up @@ -33,3 +35,6 @@
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

[assembly: ConventionReporter(typeof(HtmlConventionResultsReporter))]
[assembly: ConventionReporter(typeof(MarkdownConventionResultsReporter))]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'Types must have a default constructor' for 'nHibernate Entitites'
------------------------------------------------------------------
'Types must have a default constructor' for 'Types in nHibernate Entitites'
---------------------------------------------------------------------------

TestAssembly.ClassWithNoDefaultCtor
TestAssembly.ClassWithPrivateDefaultCtor
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'Types must have a default constructor' for 'nHibernate Entitites'
------------------------------------------------------------------
'Types must have a default constructor' for 'Types in nHibernate Entitites'
---------------------------------------------------------------------------

TestAssembly.ClassWithNoDefaultCtor
TestAssembly.ClassWithPrivateDefaultCtor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'Methods must be virtual' for 'nHibernate Entitites'
----------------------------------------------------
'Methods must be virtual' for 'Types in nHibernate Entitites'
-------------------------------------------------------------

TestAssembly.SampleDomainClass.TestNonVirtual
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'Methods must be virtual' for 'nHibernate Entitites'
----------------------------------------------------
'Methods must be virtual' for 'Types in nHibernate Entitites'
-------------------------------------------------------------

TestAssembly.SampleDomainClass.TestNonVirtual
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'Dtos must be under the 'TestAssembly.Dtos' namespace' for 'TestAssembly'
-------------------------------------------------------------------------
'Dtos must be under the 'TestAssembly.Dtos' namespace' for 'Types in TestAssembly'
----------------------------------------------------------------------------------

TestAssembly.SomeDto

'Non-Dtos must not be under the 'TestAssembly.Dtos' namespace' for 'TestAssembly'
---------------------------------------------------------------------------------
'Non-Dtos must not be under the 'TestAssembly.Dtos' namespace' for 'Types in TestAssembly'
------------------------------------------------------------------------------------------

TestAssembly.Dtos.AnotherClass
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'Dtos must be under the 'TestAssembly.Dtos' namespace' for 'TestAssembly'
-------------------------------------------------------------------------
'Dtos must be under the 'TestAssembly.Dtos' namespace' for 'Types in TestAssembly'
----------------------------------------------------------------------------------

TestAssembly.SomeDto
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'Non-Dtos must not be under the 'TestAssembly.Dtos' namespace' for 'TestAssembly'
---------------------------------------------------------------------------------
'Non-Dtos must not be under the 'TestAssembly.Dtos' namespace' for 'Types in TestAssembly'
------------------------------------------------------------------------------------------

TestAssembly.Dtos.AnotherClass
69 changes: 36 additions & 33 deletions TestStack.ConventionTests/Convention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using TestStack.ConventionTests.ConventionData;
using TestStack.ConventionTests.Internal;
using TestStack.ConventionTests.Reporting;

public static class Convention
{
static readonly HtmlReportRenderer HtmlRenderer = new HtmlReportRenderer(AssemblyDirectory);
static IResultsProcessor[] defaultProcessors;
static IResultsProcessor[] defaultApprovalProcessors;

static Convention()
{
Expand All @@ -27,52 +29,53 @@ static Convention()

public static IList<IReportDataFormatter> Formatters { get; set; }

static string AssemblyDirectory
public static void Is<TDataSource>(IConvention<TDataSource> convention, TDataSource data,
ITestResultProcessor resultProcessor = null)
where TDataSource : IConventionData
{
get
{
// http://stackoverflow.com/questions/52797/c-how-do-i-get-the-path-of-the-assembly-the-code-is-in#answer-283917
var codeBase = Assembly.GetExecutingAssembly().CodeBase;
var uri = new UriBuilder(codeBase);
var path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
}
if (defaultProcessors == null || defaultApprovalProcessors == null)
Init(Assembly.GetCallingAssembly());
Execute(convention, data, defaultProcessors, resultProcessor ?? new ConventionReportTextRenderer());
}

public static void Is<TDataSource>(IConvention<TDataSource> convention, TDataSource data,
params IResultsProcessor[] extraResultProcessors)
public static void IsWithApprovedExeptions<TDataSource>(IConvention<TDataSource> convention, TDataSource data,
ITestResultProcessor resultProcessor = null)
where TDataSource : IConventionData
{
var processors = new List<IResultsProcessor>(extraResultProcessors)
{
new ConventionReportTextRenderer(),
HtmlRenderer,
new ConventionReportTraceRenderer(),
new ThrowOnFailureResultsProcessor()
};
Execute(convention, data, processors.ToArray());
if (defaultProcessors == null || defaultApprovalProcessors == null)
Init(Assembly.GetCallingAssembly());
Execute(convention, data, defaultApprovalProcessors, resultProcessor ?? new ConventionReportTextRenderer());
}

static void Execute<TDataSource>(IConvention<TDataSource> convention, TDataSource data,
IResultsProcessor[] processors)
IResultsProcessor[] processors, ITestResultProcessor resultProcessor)
where TDataSource : IConventionData
{
var context = new ConventionContext(data.Description, Formatters, processors);
var dataDescription = string.Format("{0} in {1}", data.GetType().GetSentenceCaseName(), data.Description);
var context = new ConventionContext(dataDescription, Formatters, processors, resultProcessor);
context.Execute(convention, data);
}

public static void IsWithApprovedExeptions<TDataSource>(IConvention<TDataSource> convention, TDataSource data,
params IResultsProcessor[] extraResultProcessors)
where TDataSource : IConventionData
static void Init(Assembly assembly)
{
var processors = new List<IResultsProcessor>(extraResultProcessors)
var customReporters = assembly.GetCustomAttributes(typeof(ConventionReporterAttribute), false);

defaultProcessors = new IResultsProcessor[customReporters.Length + 2];
defaultApprovalProcessors = new IResultsProcessor[customReporters.Length + 2];

for (var index = 0; index < customReporters.Length; index++)
{
new ConventionReportTextRenderer(),
HtmlRenderer,
new ConventionReportTraceRenderer(),
new ApproveResultsProcessor()
};
Execute(convention, data, processors.ToArray());
var customReporter = (ConventionReporterAttribute)customReporters[index];
var resultsProcessor = (IResultsProcessor)Activator.CreateInstance(customReporter.ReporterType);
defaultProcessors[index] = resultsProcessor;
defaultApprovalProcessors[index] = resultsProcessor;
}

var conventionReportTraceRenderer = new ConventionReportTraceRenderer();
defaultProcessors[defaultProcessors.Length - 2] = conventionReportTraceRenderer;
defaultApprovalProcessors[defaultProcessors.Length - 2] = conventionReportTraceRenderer;
defaultProcessors[defaultProcessors.Length - 1] = new ThrowOnFailureResultsProcessor();
defaultApprovalProcessors[defaultProcessors.Length - 1] = new ApproveResultsProcessor();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
{
using System.Reflection;
using System.Xml.Linq;
using TestStack.ConventionTests.Conventions;
using TestStack.ConventionTests.Internal;

public abstract class AbstractProjectData : IConventionData
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace TestStack.ConventionTests.ConventionData
{
public class ProjectFile
public class ProjectFileItem
{
public string FilePath { get; set; }
public string ReferenceType { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@
using System.Xml.Linq;
using TestStack.ConventionTests.Internal;

public class ProjectFiles : AbstractProjectData
/// <summary>
/// Items/Files in a .*proj project file
/// </summary>
public class ProjectFileItems : AbstractProjectData
{
public ProjectFiles(Assembly assembly, IProjectProvider projectProvider = null, IProjectLocator projectLocator = null)
public ProjectFileItems(Assembly assembly, IProjectProvider projectProvider = null, IProjectLocator projectLocator = null)
: base(assembly, projectProvider, projectLocator)
{
}

public ProjectFile[] Files
public ProjectFileItem[] Items
{
get
{
Expand All @@ -23,7 +26,7 @@ public ProjectFile[] Files
.Elements(XName.Get("ItemGroup", msbuild))
.Elements()
.Select(refElem =>
new ProjectFile
new ProjectFileItem
{
ReferenceType = refElem.Name.LocalName,
FilePath = refElem.Attribute("Include").Value
Expand Down
6 changes: 6 additions & 0 deletions TestStack.ConventionTests/ConventionData/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;

public static class TypeExtensions
{
Expand Down Expand Up @@ -66,5 +67,10 @@ public static bool ClosesInterface(this Type t, Type openGeneric)
{
return t.GetClosedInterfacesOf(openGeneric).Any();
}

internal static string GetSentenceCaseName(this Type type)
{
return Regex.Replace(type.Name, "[a-z][A-Z]", m => m.Value[0] + " " + char.ToLower(m.Value[1]));
}
}
}
18 changes: 18 additions & 0 deletions TestStack.ConventionTests/ConventionReporterAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace TestStack.ConventionTests
{
using System;
using TestStack.ConventionTests.Reporting;

[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class ConventionReporterAttribute : Attribute
{
public ConventionReporterAttribute(Type reporterType)
{
ReporterType = reporterType;
if (!typeof(IResultsProcessor).IsAssignableFrom(reporterType))
throw new ArgumentException("Reporters must inherit from IResultsProcessor", "reporterType");
}

public Type ReporterType { get; private set; }
}
}
Loading