diff --git a/TestStack.ConventionTests.Tests/ConventionAssertionClassTests.cs b/TestStack.ConventionTests.Tests/ConventionAssertionClassTests.cs index fe76a7b..d6b66ff 100644 --- a/TestStack.ConventionTests.Tests/ConventionAssertionClassTests.cs +++ b/TestStack.ConventionTests.Tests/ConventionAssertionClassTests.cs @@ -21,7 +21,7 @@ public void approval_mismatch() public class FakeData : IConventionData { - public void ThrowIfHasInvalidSource() + public void EnsureHasNonEmptySource() { } } diff --git a/TestStack.ConventionTests.Tests/ProjectBasedConventions.cs b/TestStack.ConventionTests.Tests/ProjectBasedConventions.cs index e1f4572..4722f9f 100644 --- a/TestStack.ConventionTests.Tests/ProjectBasedConventions.cs +++ b/TestStack.ConventionTests.Tests/ProjectBasedConventions.cs @@ -13,15 +13,12 @@ [UseReporter(typeof(DiffReporter))] public class ProjectBasedConventions { - Project project; IProjectProvider projectProvider; [SetUp] public void Setup() { projectProvider = Substitute.For(); - var projectLocator = Substitute.For(); - project = new Project(typeof(ProjectBasedConventions).Assembly, projectProvider, projectLocator); } [Test] @@ -31,6 +28,8 @@ public void assemblies_referencing_bin_obj() .LoadProjectDocument(Arg.Any()) .Returns(XDocument.Parse(Resources.ProjectFileWithBinReference)); + var projectLocator = Substitute.For(); + var project = new ProjectReferences(typeof(ProjectBasedConventions).Assembly, projectProvider, projectLocator); var ex = Assert.Throws(() => Convention.Is(new ProjectDoesNotReferenceDllsFromBinOrObjDirectories(), project)); Approvals.Verify(ex.Message); @@ -43,17 +42,24 @@ public void assemblies_referencing_bin_obj_with_approved_exceptions() .LoadProjectDocument(Arg.Any()) .Returns(XDocument.Parse(Resources.ProjectFileWithBinReference)); + + var projectLocator = Substitute.For(); + 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()) .Returns(XDocument.Parse(Resources.ProjectFileWithInvalidSqlScriptFile)); + var projectLocator = Substitute.For(); + var project = new ProjectFiles(typeof (ProjectBasedConventions).Assembly, projectProvider, projectLocator) + { + Items = i => i.FilePath.EndsWith(".sql") + }; var ex = Assert.Throws(() => Convention.Is(new FilesAreEmbeddedResources(), project)); Approvals.Verify(ex.Message); @@ -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(); + var project = new ProjectFiles(typeof(ProjectBasedConventions).Assembly, projectProvider, projectLocator) + { + Items = i => i.FilePath.EndsWith(".sql") + }; projectProvider .LoadProjectDocument(Arg.Any()) .Returns(XDocument.Parse(Resources.ProjectFileWithInvalidSqlScriptFile)); diff --git a/TestStack.ConventionTests/Convention.cs b/TestStack.ConventionTests/Convention.cs index b38f0b9..0d60479 100644 --- a/TestStack.ConventionTests/Convention.cs +++ b/TestStack.ConventionTests/Convention.cs @@ -8,7 +8,7 @@ public static class Convention { public static void Is(IConvention convention, TData data) where TData : IConventionData { - data.ThrowIfHasInvalidSource(); + data.EnsureHasNonEmptySource(); var result = convention.Execute(data); if (result.Failed) @@ -17,7 +17,7 @@ public static void Is(IConvention convention, TData data) where TD public static void IsWithApprovedExeptions(IConvention convention, TData data) where TData : IConventionData { - data.ThrowIfHasInvalidSource(); + data.EnsureHasNonEmptySource(); var result = convention.Execute(data); // should we encapsulate Approvals behind Settings? diff --git a/TestStack.ConventionTests/Conventions/Project.cs b/TestStack.ConventionTests/Conventions/AbstractProjectData.cs similarity index 69% rename from TestStack.ConventionTests/Conventions/Project.cs rename to TestStack.ConventionTests/Conventions/AbstractProjectData.cs index e265170..fe79b81 100644 --- a/TestStack.ConventionTests/Conventions/Project.cs +++ b/TestStack.ConventionTests/Conventions/AbstractProjectData.cs @@ -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 Includes; - - public Project(Assembly assembly, IProjectProvider projectProvider, IProjectLocator projectLocator) + protected AbstractProjectData(Assembly assembly, IProjectProvider projectProvider, IProjectLocator projectLocator) { Assembly = assembly; ProjectProvider = projectProvider; @@ -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); diff --git a/TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs b/TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs index 476520f..77d785d 100644 --- a/TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs +++ b/TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs @@ -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 + public class FilesAreEmbeddedResources : IConvention { - 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> 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)); } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs b/TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs index f773d95..7eadf6a 100644 --- a/TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs +++ b/TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs @@ -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 + public class ProjectDoesNotReferenceDllsFromBinOrObjDirectories : IConvention { const string AssemblyReferencingObjRegex = @"^(?.*?(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 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); } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/ProjectFile.cs b/TestStack.ConventionTests/Conventions/ProjectFile.cs new file mode 100644 index 0000000..f2a3563 --- /dev/null +++ b/TestStack.ConventionTests/Conventions/ProjectFile.cs @@ -0,0 +1,8 @@ +namespace TestStack.ConventionTests.Conventions +{ + public class ProjectFile + { + public string FilePath { get; set; } + public string ReferenceType { get; set; } + } +} \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/ProjectFiles.cs b/TestStack.ConventionTests/Conventions/ProjectFiles.cs new file mode 100644 index 0000000..e34ddbe --- /dev/null +++ b/TestStack.ConventionTests/Conventions/ProjectFiles.cs @@ -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(); + } + + + 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 Items { get; set; } + } +} \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/ProjectReference.cs b/TestStack.ConventionTests/Conventions/ProjectReference.cs new file mode 100644 index 0000000..a369e7a --- /dev/null +++ b/TestStack.ConventionTests/Conventions/ProjectReference.cs @@ -0,0 +1,7 @@ +namespace TestStack.ConventionTests.Conventions +{ + public class ProjectReference + { + public string ReferencedPath { get; set; } + } +} \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/ProjectReferences.cs b/TestStack.ConventionTests/Conventions/ProjectReferences.cs new file mode 100644 index 0000000..f72a747 --- /dev/null +++ b/TestStack.ConventionTests/Conventions/ProjectReferences.cs @@ -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(); + } + + public ProjectReference[] References + { + get + { + var project = GetProject(); + return AllProjectReferences(project) + .Select(r => new ProjectReference + { + ReferencedPath = r + }) + .Where(Items) + .ToArray(); + } + } + + static IEnumerable 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 Items { get; set; } + } +} \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/Types.cs b/TestStack.ConventionTests/Conventions/Types.cs index eca2dd8..0592c60 100644 --- a/TestStack.ConventionTests/Conventions/Types.cs +++ b/TestStack.ConventionTests/Conventions/Types.cs @@ -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"); diff --git a/TestStack.ConventionTests/IConventionData.cs b/TestStack.ConventionTests/IConventionData.cs index a289f10..26b0215 100644 --- a/TestStack.ConventionTests/IConventionData.cs +++ b/TestStack.ConventionTests/IConventionData.cs @@ -2,6 +2,6 @@ { public interface IConventionData { - void ThrowIfHasInvalidSource(); + void EnsureHasNonEmptySource(); } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Internal/PredicateHelpers.cs b/TestStack.ConventionTests/Internal/PredicateHelpers.cs new file mode 100644 index 0000000..5ab2fc3 --- /dev/null +++ b/TestStack.ConventionTests/Internal/PredicateHelpers.cs @@ -0,0 +1,17 @@ +namespace TestStack.ConventionTests.Internal +{ + using System; + + public static class PredicateHelpers + { + public static Func All() + { + return _ => true; + } + + public static Func None() + { + return _ => false; + } + } +} \ No newline at end of file diff --git a/TestStack.ConventionTests/TestStack.ConventionTests.csproj b/TestStack.ConventionTests/TestStack.ConventionTests.csproj index 0e9444d..6887bea 100644 --- a/TestStack.ConventionTests/TestStack.ConventionTests.csproj +++ b/TestStack.ConventionTests/TestStack.ConventionTests.csproj @@ -61,6 +61,10 @@ + + + + @@ -69,13 +73,14 @@ - + +