Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Header

Approved Exception
37 changes: 37 additions & 0 deletions TestStack.ConventionTests.Tests/ConventionAssertionClassTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
namespace TestStack.ConventionTests.Tests
{
using ApprovalTests.Reporters;
using NUnit.Framework;
using TestStack.ConventionTests.Internal;

[TestFixture]
[UseReporter(typeof(DiffReporter))] //NOTE: Can we take care of this in IsWithApprovedExceptions?
public class ConventionAssertionClassTests
{
[Test]
public void approval_mismatch()
{
//NOTE Do not approve any changes to this test
var ex = Assert.Throws<ConventionFailedException>(() => Convention.IsWithApprovedExeptions(new FailingConvention(), new FakeData()));

StringAssert.Contains("Approved exceptions for convention differs", ex.Message);
StringAssert.Contains("Failed Approval: Received file ", ex.Message);
StringAssert.Contains("does not match approved file", ex.Message);
}

public class FakeData : IConventionData
{
public void ThrowIfHasInvalidSource()
{
}
}

public class FailingConvention : IConvention<FakeData>
{
public ConventionResult Execute(FakeData data)
{
return ConventionResult.For(new[] { "" }, "Header", (s, builder) => builder.AppendLine("Different"));
}
}
}
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Some invalid assembly references found in TestStack.ConventionTests.Tests

bin\Debug\ApprovalTests.dll
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Some invalid assembly references found in TestStack.ConventionTests.Tests

bin\Debug\ApprovalTests.dll
59 changes: 41 additions & 18 deletions TestStack.ConventionTests.Tests/ProjectBasedConventions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace TestStack.ConventionTests.Tests
{
using System.Xml.Linq;
using ApprovalTests;
using ApprovalTests.Reporters;
using NSubstitute;
using NUnit.Framework;
Expand All @@ -9,42 +10,64 @@
using TestStack.ConventionTests.Tests.Properties;

[TestFixture]
[UseReporter(typeof (DiffReporter))]
[UseReporter(typeof(DiffReporter))]
public class ProjectBasedConventions
{
public ProjectBasedConventions()
Project project;
IProjectProvider projectProvider;

[SetUp]
public void Setup()
{
Convention.Settings.AssertInclunclusive = Assert.Inconclusive;
Convention.Settings.AssertZero = (v, m) => Assert.AreEqual(0, v, m);
projectProvider = Substitute.For<IProjectProvider>();
var projectLocator = Substitute.For<IProjectLocator>();
project = new Project(typeof(ProjectBasedConventions).Assembly, projectProvider, projectLocator);
}

[Test]
public void ReferencingBinObj()
public void assemblies_referencing_bin_obj()
{
var projectProvider = Substitute.For<IProjectProvider>();
var projectLocator = Substitute.For<IProjectLocator>();
projectProvider
.LoadProjectDocument(Arg.Any<string>())
.Returns(XDocument.Parse(Resources.ProjectFileWithBinReference));

Convention.Is(new ProjectDoesNotReferenceDllsFromBinOrObjDirectories(),
new Project(typeof (ProjectBasedConventions).Assembly, projectProvider, projectLocator));
var ex = Assert.Throws<ConventionFailedException>(() => Convention.Is(new ProjectDoesNotReferenceDllsFromBinOrObjDirectories(), project));

Approvals.Verify(ex.Message);
}

[Test]
public void ScriptsNotEmbeddedResources()
public void assemblies_referencing_bin_obj_with_approved_exceptions()
{
var projectProvider = Substitute.For<IProjectProvider>();
var projectLocator = Substitute.For<IProjectLocator>();
projectProvider
.LoadProjectDocument(Arg.Any<string>())
.Returns(XDocument.Parse(Resources.ProjectFileWithBinReference));

Convention.IsWithApprovedExeptions(new ProjectDoesNotReferenceDllsFromBinOrObjDirectories(), project);
}

[Test]
public void scripts_not_embedded_resources()
{
project.Includes = i => i.EndsWith(".sql");
projectProvider
.LoadProjectDocument(Arg.Any<string>())
.Returns(XDocument.Parse(Resources.ProjectFileWithInvalidSqlScriptFile));

var ex = Assert.Throws<ConventionFailedException>(() => Convention.Is(new FilesAreEmbeddedResources(), project));

Approvals.Verify(ex.Message);
}

[Test]
public void scripts_not_embedded_resources_with_approved_exceptions()
{
project.Includes = i => i.EndsWith(".sql");
projectProvider
.LoadProjectDocument(Arg.Any<string>())
.Returns(XDocument.Parse(Resources.ProjectFileWithInvalidSqlScriptFile));

Convention.Is(new FilesAreEmbeddedResources(),
new Project(typeof (ProjectBasedConventions).Assembly, projectProvider, projectLocator)
{
Includes = i => i.EndsWith(".sql")
});
Convention.IsWithApprovedExeptions(new FilesAreEmbeddedResources(), project);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
The following files which should be embedded resources:

Scripts\Script2.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
The following files which should be embedded resources:

Scripts\Script2.sql
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ConventionAssertionClassTests.cs" />
<Compile Include="ProjectBasedConventions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Convention has failing items
TestAssembly.ClassWithNoDefaultCtor does not have a default constructor
TestAssembly.ClassWithPrivateDefaultCtor does not have a default constructor
The following types do not have default constructor

TestAssembly.ClassWithNoDefaultCtor
TestAssembly.ClassWithPrivateDefaultCtor
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
The following types do not have default constructor

TestAssembly.ClassWithNoDefaultCtor
TestAssembly.ClassWithPrivateDefaultCtor
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Convention has failing items
TestAssembly.SampleDomainClass has non virtual method(s):
TestNonVirtual
The following methods are not virtual.

TestAssembly.SampleDomainClass.TestNonVirtual
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
The following methods are not virtual.

TestAssembly.SampleDomainClass.TestNonVirtual
28 changes: 20 additions & 8 deletions TestStack.ConventionTests.Tests/TypeBasedConventions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace TestStack.ConventionTests.Tests
{
using ApprovalTests;
using ApprovalTests.Reporters;
using NUnit.Framework;
using TestAssembly;
Expand All @@ -13,28 +14,39 @@ public class TypeBasedConventions

public TypeBasedConventions()
{
// TODO: This should go to some sort of autodiscovery mechanism so users don't have to see this shit
Convention.Settings.AssertInclunclusive = Assert.Inconclusive;
Convention.Settings.AssertZero = (v, m) => Assert.AreEqual(0, v, m);

var itemsToVerify = typeof (SampleDomainClass).Assembly.GetTypes();
nhibernateEntities = new Types
{
ApplicableTypes = itemsToVerify,
HasApprovedExceptions = false
ApplicableTypes = itemsToVerify
};
}

[Test]
public void all_classes_have_default_constructor()
{
Convention.Is(new AllClassesHaveDefaultConstructor(), nhibernateEntities);
var ex = Assert.Throws<ConventionFailedException>(()=>Convention.Is(new AllClassesHaveDefaultConstructor(), nhibernateEntities));

Approvals.Verify(ex.Message);
}

[Test]
public void all_classes_have_default_constructor_wth_approved_exceptions()
{
Convention.IsWithApprovedExeptions(new AllClassesHaveDefaultConstructor(), nhibernateEntities);
}

[Test]
public void all_methods_are_virtual()
{
Convention.Is(new AllMethodsAreVirtual(), nhibernateEntities);
var ex = Assert.Throws<ConventionFailedException>(()=>Convention.Is(new AllMethodsAreVirtual(), nhibernateEntities));

Approvals.Verify(ex.Message);
}

[Test]
public void all_methods_are_virtual_wth_approved_exceptions()
{
Convention.IsWithApprovedExeptions(new AllMethodsAreVirtual(), nhibernateEntities);
}
}
}
43 changes: 17 additions & 26 deletions TestStack.ConventionTests/Convention.cs
Original file line number Diff line number Diff line change
@@ -1,44 +1,35 @@
namespace TestStack.ConventionTests
{
using System;
using System.Diagnostics;
using ApprovalTests;
using ApprovalTests.Core.Exceptions;

public static class Convention
{
public static readonly ConventionSettings Settings = new ConventionSettings();

public static void Is<TData>(IConvention<TData> convention, TData data) where TData : IConventionData
{
if (data.HasValidSource == false)
{
// TODO: this would have to have a more reasonable and helpful message...
Settings.AssertInclunclusive("No valid source in " + data);
return;
}
data.ThrowIfHasInvalidSource();
var result = convention.Execute(data);
if (result.IsConclusive == false)
{
Settings.AssertInclunclusive(result.Message);
return;
}
if (data.HasApprovedExceptions)
{
// should we encapsulate Approvals behind Settings?
Approvals.Verify(result.Message);
return;
}
Settings.AssertZero(result.InvalidResultsCount, result.Message);

if (result.Failed)
throw new ConventionFailedException(result.Message);
}

public class ConventionSettings
public static void IsWithApprovedExeptions<TData>(IConvention<TData> convention, TData data) where TData : IConventionData
{
public Action<String> AssertInclunclusive;
data.ThrowIfHasInvalidSource();
var result = convention.Execute(data);

public Action<int, string> AssertZero;
// should we encapsulate Approvals behind Settings?
try
{
Approvals.Verify(result.Message);

public ConventionSettings()
Trace.WriteLine(string.Format("{0} has approved exceptions:\r\n\r\n{1}", convention.GetType().Name, result.Message));
}
catch (ApprovalException ex)
{
// TODO: initialize the type;
throw new ConventionFailedException("Approved exceptions for convention differs\r\n\r\n"+ex.Message, ex);
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions TestStack.ConventionTests/ConventionFailedException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace TestStack.ConventionTests
{
using System;
using System.Runtime.Serialization;

[Serializable]
public class ConventionFailedException : Exception
{
public ConventionFailedException() { }
public ConventionFailedException(string message) : base(message) { }
public ConventionFailedException(string message, Exception inner) : base(message, inner) { }
protected ConventionFailedException(SerializationInfo info, StreamingContext context)
: base(info, context) { }
}
}
18 changes: 12 additions & 6 deletions TestStack.ConventionTests/Conventions/AllMethodsAreVirtual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,23 @@ public ConventionResult Execute(Types data)
{
// do we want to encapsulate that in some way?
// also notice how data gives us types, yet the convention acts upon methods.
var invalid = data.ApplicableTypes.ToLookup(t => t, t => t.NonVirtualMethods()).Where(l => l.Any());
return ConventionResult.For(invalid, HeaderMessage, DescribeTypeAndMethods);
var items = from applicableType in data.ApplicableTypes
let nonVirtuals = applicableType.NonVirtualMethods()
where nonVirtuals.Any()
select Tuple.Create(applicableType, nonVirtuals);
return ConventionResult.For(items, HeaderMessage, DescribeTypeAndMethods);
}

// I like how that's encapsulated in the reusable convention type, whereas previously it was part of the convention/test code
void DescribeTypeAndMethods(IGrouping<Type, IEnumerable<MethodInfo>> item, StringBuilder message)
void DescribeTypeAndMethods(Tuple<Type, IEnumerable<MethodInfo>> item, StringBuilder message)
{
message.AppendLine("\t" + item.Key);
foreach (var method in item)
foreach (var method in item.Item2)
{
message.AppendLine("\t\t" + method);
message.Append("\t");
message.Append(item.Item1);
message.Append(".");
message.Append(method.Name);
message.AppendLine();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace TestStack.ConventionTests.Conventions
{
using System;
using System.Runtime.Serialization;

[Serializable]
public class ConventionSourceInvalidException : Exception
{
public ConventionSourceInvalidException() { }
public ConventionSourceInvalidException(string message) : base(message) { }
public ConventionSourceInvalidException(string message, Exception inner) : base(message, inner) { }
protected ConventionSourceInvalidException(
SerializationInfo info,
StreamingContext context)
: base(info, context) { }
}
}
5 changes: 3 additions & 2 deletions TestStack.ConventionTests/Conventions/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ public Project(Assembly assembly, IProjectProvider projectProvider, IProjectLoca

public IProjectProvider ProjectProvider { get; private set; }

public bool HasValidSource
public void ThrowIfHasInvalidSource()
{
get { return ProjectLocator.ResolveProjectFilePath(Assembly) != null; }
if (ProjectLocator.ResolveProjectFilePath(Assembly) == null)
throw new ConventionSourceInvalidException("Cannot resolve project file for assembly {0}");
}

public bool HasApprovedExceptions { get; set; }
Expand Down
Loading