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
Expand Up @@ -21,7 +21,7 @@ public void approval_mismatch()

public class FakeData : IConventionData
{
public void ThrowIfHasInvalidSource()
public void EnsureHasNonEmptySource()
{
}
}
Expand Down
20 changes: 15 additions & 5 deletions TestStack.ConventionTests.Tests/ProjectBasedConventions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,12 @@
[UseReporter(typeof(DiffReporter))]
public class ProjectBasedConventions
{
Project project;
IProjectProvider projectProvider;

[SetUp]
public void Setup()
{
projectProvider = Substitute.For<IProjectProvider>();
var projectLocator = Substitute.For<IProjectLocator>();
project = new Project(typeof(ProjectBasedConventions).Assembly, projectProvider, projectLocator);
}

[Test]
Expand All @@ -31,6 +28,8 @@ public void assemblies_referencing_bin_obj()
.LoadProjectDocument(Arg.Any<string>())
.Returns(XDocument.Parse(Resources.ProjectFileWithBinReference));

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

Approvals.Verify(ex.Message);
Expand All @@ -43,17 +42,24 @@ public void assemblies_referencing_bin_obj_with_approved_exceptions()
.LoadProjectDocument(Arg.Any<string>())
.Returns(XDocument.Parse(Resources.ProjectFileWithBinReference));


var projectLocator = Substitute.For<IProjectLocator>();
var project = new ProjectReferences(typeof(ProjectBasedConventions).Assembly, projectProvider, projectLocator);
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 projectLocator = Substitute.For<IProjectLocator>();
var project = new ProjectFiles(typeof (ProjectBasedConventions).Assembly, projectProvider, projectLocator)
{
Items = i => i.FilePath.EndsWith(".sql")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe ItemFilter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more like ItemsWhere...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or perhaps just .Where...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the last one would probably resonate with anyone who has ever written a LINQ query...

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

Approvals.Verify(ex.Message);
Expand All @@ -62,7 +68,11 @@ public void scripts_not_embedded_resources()
[Test]
public void scripts_not_embedded_resources_with_approved_exceptions()
{
project.Includes = i => i.EndsWith(".sql");
var projectLocator = Substitute.For<IProjectLocator>();
var project = new ProjectFiles(typeof(ProjectBasedConventions).Assembly, projectProvider, projectLocator)
{
Items = i => i.FilePath.EndsWith(".sql")
};
projectProvider
.LoadProjectDocument(Arg.Any<string>())
.Returns(XDocument.Parse(Resources.ProjectFileWithInvalidSqlScriptFile));
Expand Down
4 changes: 2 additions & 2 deletions TestStack.ConventionTests/Convention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public static class Convention
{
public static void Is<TData>(IConvention<TData> convention, TData data) where TData : IConventionData
{
data.ThrowIfHasInvalidSource();
data.EnsureHasNonEmptySource();
var result = convention.Execute(data);

if (result.Failed)
Expand All @@ -17,7 +17,7 @@ public static void Is<TData>(IConvention<TData> convention, TData data) where TD

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

// should we encapsulate Approvals behind Settings?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
namespace TestStack.ConventionTests.Conventions
{
using System;
using System.Reflection;
using System.Xml.Linq;
using TestStack.ConventionTests.Internal;

public class Project : IConventionData
public abstract class AbstractProjectData : IConventionData
{
public Func<string, bool> Includes;

public Project(Assembly assembly, IProjectProvider projectProvider, IProjectLocator projectLocator)
protected AbstractProjectData(Assembly assembly, IProjectProvider projectProvider, IProjectLocator projectLocator)
{
Assembly = assembly;
ProjectProvider = projectProvider;
Expand All @@ -22,15 +19,13 @@ public Project(Assembly assembly, IProjectProvider projectProvider, IProjectLoca

public IProjectProvider ProjectProvider { get; private set; }

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

public bool HasApprovedExceptions { get; set; }

public XDocument GetProject()
protected XDocument GetProject()
{
var location = ProjectLocator.ResolveProjectFilePath(Assembly);
var project = ProjectProvider.LoadProjectDocument(location);
Expand Down
28 changes: 4 additions & 24 deletions TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,15 @@
namespace TestStack.ConventionTests.Conventions
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using TestStack.ConventionTests.Internal;

public class FilesAreEmbeddedResources : IConvention<Project>
public class FilesAreEmbeddedResources : IConvention<ProjectFiles>
{
public ConventionResult Execute(Project data)
public ConventionResult Execute(ProjectFiles data)
{
return ConventionResult.For(GetProjectFiles(data).Where(s => s.Item1 != "EmbeddedResource"),
return ConventionResult.For(data.Files.Where(s => s.ReferenceType != "EmbeddedResource"),
"The following files which should be embedded resources:",
(t, m) => m.AppendLine("\t" + t.Item2));
}

IEnumerable<Tuple<string, string>> GetProjectFiles(Project project)
{
if (project.Includes == null)
throw new InvalidOperationException(
"This convention requires you to provide a filter on the convention data");
const string msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
var projDefinition = project.GetProject();
var references = projDefinition
.Element(XName.Get("Project", msbuild))
.Elements(XName.Get("ItemGroup", msbuild))
.Elements()
.Select(refElem => Tuple.Create(refElem.Name.LocalName, refElem.Attribute("Include").Value))
.Where(i => project.Includes(i.Item2));

return references;
(t, m) => m.AppendLine("\t" + t.FilePath));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,44 +1,29 @@
namespace TestStack.ConventionTests.Conventions
{
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using TestStack.ConventionTests.Internal;

public class ProjectDoesNotReferenceDllsFromBinOrObjDirectories : IConvention<Project>
public class ProjectDoesNotReferenceDllsFromBinOrObjDirectories : IConvention<ProjectReferences>
{
const string AssemblyReferencingObjRegex = @"^(?<assembly>.*?(obj|bin).*?)$";

public ConventionResult Execute(Project data)
public ConventionResult Execute(ProjectReferences data)
{
var projDefinition = data.GetProject();
var invalid = AllProjectReferences(projDefinition).Where(IsBinOrObjReference);
var invalid = data.References.Where(IsBinOrObjReference);
var header = string.Format("Some invalid assembly references found in {0}", data.Assembly.GetName().Name);
return ConventionResult.For(invalid, header, FormatLine);
}

void FormatLine(string assemblyReference, StringBuilder m)
void FormatLine(ProjectReference assemblyReference, StringBuilder m)
{
m.AppendLine("\t" + assemblyReference);
m.AppendLine("\t" + assemblyReference.ReferencedPath);
}

static bool IsBinOrObjReference(string reference)
static bool IsBinOrObjReference(ProjectReference reference)
{
return Regex.IsMatch(reference, AssemblyReferencingObjRegex, RegexOptions.IgnoreCase);
}

static IEnumerable<string> AllProjectReferences(XDocument projDefinition)
{
XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
var references = projDefinition
.Element(msbuild + "Project")
.Elements(msbuild + "ItemGroup")
.Elements(msbuild + "Reference")
.Elements(msbuild + "HintPath")
.Select(refElem => refElem.Value);
return references;
return Regex.IsMatch(reference.ReferencedPath, AssemblyReferencingObjRegex, RegexOptions.IgnoreCase);
}
}
}
8 changes: 8 additions & 0 deletions TestStack.ConventionTests/Conventions/ProjectFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace TestStack.ConventionTests.Conventions
{
public class ProjectFile
{
public string FilePath { get; set; }
public string ReferenceType { get; set; }
}
}
41 changes: 41 additions & 0 deletions TestStack.ConventionTests/Conventions/ProjectFiles.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace TestStack.ConventionTests.Conventions
{
using System;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
using TestStack.ConventionTests.Internal;

public class ProjectFiles : AbstractProjectData
{
public ProjectFiles(Assembly assembly, IProjectProvider projectProvider, IProjectLocator projectLocator)
: base(assembly, projectProvider, projectLocator)
{
Items = PredicateHelpers.All<ProjectFile>();
}


public ProjectFile[] Files
{
get
{
var project = GetProject();
const string msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
return project
.Element(XName.Get("Project", msbuild))
.Elements(XName.Get("ItemGroup", msbuild))
.Elements()
.Select(refElem =>
new ProjectFile
{
ReferenceType = refElem.Name.LocalName,
FilePath = refElem.Attribute("Include").Value
})
.Where(Items)
.ToArray();
}
}

public Func<ProjectFile, bool> Items { get; set; }
}
}
7 changes: 7 additions & 0 deletions TestStack.ConventionTests/Conventions/ProjectReference.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace TestStack.ConventionTests.Conventions
{
public class ProjectReference
{
public string ReferencedPath { get; set; }
}
}
47 changes: 47 additions & 0 deletions TestStack.ConventionTests/Conventions/ProjectReferences.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
namespace TestStack.ConventionTests.Conventions
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
using TestStack.ConventionTests.Internal;

public class ProjectReferences : AbstractProjectData
{
public ProjectReferences(Assembly assembly, IProjectProvider projectProvider, IProjectLocator projectLocator)
: base(assembly, projectProvider, projectLocator)
{
Items = PredicateHelpers.All<ProjectReference>();
}

public ProjectReference[] References
{
get
{
var project = GetProject();
return AllProjectReferences(project)
.Select(r => new ProjectReference
{
ReferencedPath = r
})
.Where(Items)
.ToArray();
}
}

static IEnumerable<string> AllProjectReferences(XDocument projDefinition)
{
XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
var references = projDefinition
.Element(msbuild + "Project")
.Elements(msbuild + "ItemGroup")
.Elements(msbuild + "Reference")
.Elements(msbuild + "HintPath")
.Select(refElem => refElem.Value);
return references;
}

public Func<ProjectReference, bool> Items { get; set; }
}
}
2 changes: 1 addition & 1 deletion TestStack.ConventionTests/Conventions/Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class Types : IConventionData

public bool HasApprovedExceptions { get; set; }

public void ThrowIfHasInvalidSource()
public void EnsureHasNonEmptySource()
{
if (ApplicableTypes.None())
throw new ConventionSourceInvalidException("You must supply types to verify");
Expand Down
2 changes: 1 addition & 1 deletion TestStack.ConventionTests/IConventionData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
{
public interface IConventionData
{
void ThrowIfHasInvalidSource();
void EnsureHasNonEmptySource();
}
}
17 changes: 17 additions & 0 deletions TestStack.ConventionTests/Internal/PredicateHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace TestStack.ConventionTests.Internal
{
using System;

public static class PredicateHelpers
{
public static Func<T, bool> All<T>()
{
return _ => true;
}

public static Func<T, bool> None<T>()
{
return _ => false;
}
}
}
7 changes: 6 additions & 1 deletion TestStack.ConventionTests/TestStack.ConventionTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
<ItemGroup>
<Compile Include="ConventionFailedException.cs" />
<Compile Include="Conventions\ConventionSourceInvalidException.cs" />
<Compile Include="Conventions\ProjectFile.cs" />
<Compile Include="Conventions\ProjectFiles.cs" />
<Compile Include="Conventions\ProjectReference.cs" />
<Compile Include="Conventions\ProjectReferences.cs" />
<Compile Include="IConventionData.cs" />
<Compile Include="Internal\ConventionResult.cs" />
<Compile Include="Conventions\AllMethodsAreVirtual.cs" />
Expand All @@ -69,13 +73,14 @@
<Compile Include="Internal\AssemblyProjectLocator.cs" />
<Compile Include="Convention.cs" />
<Compile Include="IConvention.cs" />
<Compile Include="Conventions\Project.cs" />
<Compile Include="Conventions\AbstractProjectData.cs" />
<Compile Include="Conventions\Types.cs" />
<Compile Include="ConventionData.cs" />
<Compile Include="Internal\IProjectLocator.cs" />
<Compile Include="Internal\IProjectProvider.cs" />
<Compile Include="Internal\LinqExtensions.cs" />
<Compile Include="Conventions\ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs" />
<Compile Include="Internal\PredicateHelpers.cs" />
<Compile Include="Internal\ProjectProvider.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Internal\ReflectionExtensions.cs" />
Expand Down