diff --git a/TestStack.ConventionTests.Tests/ProjectBasedConventions.cs b/TestStack.ConventionTests.Tests/ProjectBasedConventions.cs index 8ec4418..b84e12b 100644 --- a/TestStack.ConventionTests.Tests/ProjectBasedConventions.cs +++ b/TestStack.ConventionTests.Tests/ProjectBasedConventions.cs @@ -1,58 +1,50 @@ namespace TestStack.ConventionTests.Tests { using System.Xml.Linq; - using ApprovalTests; using ApprovalTests.Reporters; using NSubstitute; using NUnit.Framework; using TestStack.ConventionTests.Conventions; - using TestStack.ConventionTests.Helpers; + using TestStack.ConventionTests.Internal; using TestStack.ConventionTests.Tests.Properties; [TestFixture] - [UseReporter(typeof(DiffReporter))] + [UseReporter(typeof (DiffReporter))] public class ProjectBasedConventions { + public ProjectBasedConventions() + { + Convention.Settings.AssertInclunclusive = Assert.Inconclusive; + Convention.Settings.AssertZero = (v, m) => Assert.AreEqual(0, v, m); + } + [Test] public void ReferencingBinObj() { - // Actual syntax will be (when not testing): - // - // Convention.Is(new[] { typeof(ProjectBasedConventions).Assembly }); - // - var projectProvider = Substitute.For(); var projectLocator = Substitute.For(); projectProvider .LoadProjectDocument(Arg.Any()) .Returns(XDocument.Parse(Resources.ProjectFileWithBinReference)); - var convention = new ProjectDoesNotReferenceDllsFromBinOrObjDirectories(projectLocator, projectProvider); - - var exception = Assert.Throws(() => - Convention.Is(convention, new[] { typeof(ProjectBasedConventions).Assembly })); - Approvals.Verify(exception.Message); + Convention.Is(new ProjectDoesNotReferenceDllsFromBinOrObjDirectories(), + new Project(typeof (ProjectBasedConventions).Assembly, projectProvider, projectLocator)); } - + [Test] public void ScriptsNotEmbeddedResources() { - // Actual syntax will be (when not testing): - // - // Convention.Is(new[] { typeof(ProjectBasedConventions).Assembly }, i => i.EndsWith(".sql")); - // - var projectProvider = Substitute.For(); var projectLocator = Substitute.For(); projectProvider .LoadProjectDocument(Arg.Any()) .Returns(XDocument.Parse(Resources.ProjectFileWithInvalidSqlScriptFile)); - var convention = new FilesAreEmbeddedResources(projectLocator, projectProvider); - - var exception = Assert.Throws(() => - Convention.Is(convention, new[] { typeof(ProjectBasedConventions).Assembly }, i => i.EndsWith(".sql"))); - Approvals.Verify(exception.Message); + Convention.Is(new FilesAreEmbeddedResources(), + new Project(typeof (ProjectBasedConventions).Assembly, projectProvider, projectLocator) + { + Includes = i => i.EndsWith(".sql") + }); } } } \ No newline at end of file diff --git a/TestStack.ConventionTests.Tests/TypeBasedConventions.cs b/TestStack.ConventionTests.Tests/TypeBasedConventions.cs index d870e34..e5a2faa 100644 --- a/TestStack.ConventionTests.Tests/TypeBasedConventions.cs +++ b/TestStack.ConventionTests.Tests/TypeBasedConventions.cs @@ -1,37 +1,40 @@ namespace TestStack.ConventionTests.Tests { - using System; - using ApprovalTests; using ApprovalTests.Reporters; using NUnit.Framework; using TestAssembly; using TestStack.ConventionTests.Conventions; [TestFixture] - [UseReporter(typeof(DiffReporter))] + [UseReporter(typeof (DiffReporter))] public class TypeBasedConventions { - readonly Type[] itemsToVerify; + readonly Types nhibernateEntities; public TypeBasedConventions() { - itemsToVerify = typeof(SampleDomainClass).Assembly.GetTypes(); + // 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 + }; } [Test] - public void all_methods_are_virtual() + public void all_classes_have_default_constructor() { - var exception = Assert.Throws(() => Convention.Is(itemsToVerify)); - - Approvals.Verify(exception.Message); + Convention.Is(new AllClassesHaveDefaultConstructor(), nhibernateEntities); } [Test] - public void all_classes_have_default_constructor() + public void all_methods_are_virtual() { - var exception = Assert.Throws(() => Convention.Is(itemsToVerify)); - - Approvals.Verify(exception.Message); + Convention.Is(new AllMethodsAreVirtual(), nhibernateEntities); } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Convention.cs b/TestStack.ConventionTests/Convention.cs index 58ab14a..24107aa 100644 --- a/TestStack.ConventionTests/Convention.cs +++ b/TestStack.ConventionTests/Convention.cs @@ -1,98 +1,45 @@ namespace TestStack.ConventionTests { using System; - using System.Collections.Generic; - using System.Linq; - using System.Reflection; - using System.Text; + using ApprovalTests; public static class Convention { - public static void Is(IEnumerable itemsToVerify) where T : ConventionData, new() - { - Is(new T(), itemsToVerify); - } - public static void Is(IEnumerable itemsToVerify, Func filter) - where T : ConventionData, IRuntimeFilter, new() - { - Is(new T(), itemsToVerify); - } - public static void Is(IEnumerable itemsToVerify, Func filter) - where T : ConventionData, IRuntimeFilter, new() - { - Is(new T(), itemsToVerify); - } - - //Item.Is> - public static void Is(IEnumerable itemsToVerify) where T : ConventionData, new() - { - Is(new T(), itemsToVerify); - } - public static void Is(IEnumerable itemsToVerify, Func filter) where T : ConventionData, IRuntimeFilter, new() - { - Is(new T(), itemsToVerify, filter); - } - public static void Is(IEnumerable itemsToVerify, Func filter) where T : ConventionData, IRuntimeFilter, new() - { - Is(new T(), itemsToVerify, filter); - } + public static readonly ConventionSettings Settings = new ConventionSettings(); - //Item.Is> - public static void Is(IEnumerable itemsToVerify) where T : ConventionData, new() + public static void Is(IConvention convention, TData data) where TData : IConventionData { - Is(new T(), itemsToVerify); - } - public static void Is(IEnumerable itemsToVerify, Func filter) where T : ConventionData, IRuntimeFilter, new() - { - Is(new T(), itemsToVerify, filter); - } - public static void Is(IEnumerable itemsToVerify, Func filter) where T : ConventionData, IRuntimeFilter, new() - { - Is(new T(), itemsToVerify, filter); - } - - public static void Is(ConventionData convention, IEnumerable itemsToVerify) - { - var results = Result(convention, itemsToVerify); - if (!string.IsNullOrEmpty(results)) - throw new ConventionFailedException(results); - } - - public static void Is(TConvention convention, IEnumerable itemsToVerify, Func itemFilter) - where TConvention : ConventionData, IRuntimeFilter - { - Is(convention, itemsToVerify, itemFilter); + if (data.HasValidSource == false) + { + // TODO: this would have to have a more reasonable and helpful message... + Settings.AssertInclunclusive("No valid source in " + data); + return; + } + 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); } - public static void Is(TConvention convention, IEnumerable itemsToVerify, Func itemFilter) - where TConvention : ConventionData, IRuntimeFilter + public class ConventionSettings { - var results = Result(convention, itemsToVerify, itemFilter); - if (!string.IsNullOrEmpty(results)) - throw new ConventionFailedException(results); - } + public Action AssertInclunclusive; - public static string Result(ConventionData convention, IEnumerable itemsToVerify) - { - var message = new StringBuilder(); - var invalidItems = itemsToVerify.Where(i => !convention.Must(i)).ToArray(); - if (!invalidItems.Any()) return null; + public Action AssertZero; - message.AppendLine(convention.Description ?? "Convention has failing items"); - foreach (var invalidType in invalidItems) + public ConventionSettings() { - message.Append('\t'); - convention.ItemDescription(invalidType, message); + // TODO: initialize the type; } - - return message.ToString(); - } - - public static string Result(TConvention convention, IEnumerable itemsToVerify, Func itemFilter) - where TConvention : ConventionData, IRuntimeFilter - { - convention.SetFilter(itemFilter); - return Result(convention, itemsToVerify); } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/ConventionData.cs b/TestStack.ConventionTests/ConventionData.cs index 95e5aba..363e21b 100644 --- a/TestStack.ConventionTests/ConventionData.cs +++ b/TestStack.ConventionTests/ConventionData.cs @@ -1,11 +1,51 @@ namespace TestStack.ConventionTests { using System; + using System.Text; /// /// This is where we set what our convention is all about /// - public class ConventionData : ConventionData + public class ConventionData { + public static readonly Predicate None = _ => false; + readonly Action defaultItemDescription = DefaultItemDescriptionMethod; + + public ConventionData() + { + Must = None; + OrderBy = HashCode; + ItemDescription = defaultItemDescription; + } + + public Func OrderBy { get; set; } + + /// + /// Descriptive text used for failure message in test. Should explan what is wrong, and how to fix it (how to make + /// types that do not conform to the convention do so). + /// + public string Description { get; set; } + + /// + /// This is the convention. The predicate should return true for types that do conform to the convention, and + /// false otherwise + /// + public Predicate Must { get; set; } + + public Action ItemDescription { get; set; } + + static void DefaultItemDescriptionMethod(TItem item, StringBuilder message) + { + message.AppendLine(ReferenceEquals(item, null) ? "<>" : item.ToString()); + } + + object HashCode(TItem arg) + { + if (ReferenceEquals(arg, null)) + { + return 0; + } + return arg.GetHashCode(); + } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/ConventionData`1.cs b/TestStack.ConventionTests/ConventionData`1.cs deleted file mode 100644 index b7a5965..0000000 --- a/TestStack.ConventionTests/ConventionData`1.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace TestStack.ConventionTests -{ - using System; - using System.Text; - - /// - /// This is where we set what our convention is all about - /// - public class ConventionData - { - readonly Action defaultItemDescription = DefaultItemDescriptionMethod; - public static readonly Predicate None = _ => false; - - static void DefaultItemDescriptionMethod(TItem item, StringBuilder message) - { - message.AppendLine(ReferenceEquals(item, null) ? "<>" : item.ToString()); - } - - public ConventionData() - { - Must = None; - OrderBy = HashCode; - ItemDescription = defaultItemDescription; - } - - public Func OrderBy { get; set; } - - /// - /// Descriptive text used for failure message in test. Should explan what is wrong, and how to fix it (how to make types that do not conform to the convention do so). - /// - public string Description { get; set; } - - /// - /// This is the convention. The predicate should return true for types that do conform to the convention, and false otherwise - /// - public Predicate Must { get; set; } - - public Action ItemDescription { get; set; } - - object HashCode(TItem arg) - { - if (ReferenceEquals(arg, null)) - { - return 0; - } - return arg.GetHashCode(); - } - } -} \ No newline at end of file diff --git a/TestStack.ConventionTests/ConventionFailedException.cs b/TestStack.ConventionTests/ConventionFailedException.cs deleted file mode 100644 index 39b1104..0000000 --- a/TestStack.ConventionTests/ConventionFailedException.cs +++ /dev/null @@ -1,15 +0,0 @@ -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) { } - } -} \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/AllClassesHaveDefaultConstructor.cs b/TestStack.ConventionTests/Conventions/AllClassesHaveDefaultConstructor.cs index 4b754ac..7eef443 100644 --- a/TestStack.ConventionTests/Conventions/AllClassesHaveDefaultConstructor.cs +++ b/TestStack.ConventionTests/Conventions/AllClassesHaveDefaultConstructor.cs @@ -1,14 +1,21 @@ namespace TestStack.ConventionTests.Conventions { - using TestStack.ConventionTests.Helpers; + using System.Linq; + using TestStack.ConventionTests.Internal; - public class AllClassesHaveDefaultConstructor : ConventionData + public class AllClassesHaveDefaultConstructor : IConvention { public AllClassesHaveDefaultConstructor() { - Must = type => type.HasDefaultConstructor(); - ItemDescription = (type, builder) => - builder.AppendLine(string.Format("{0} does not have a default constructor", type.FullName)); + HeaderMessage = "The following types do not have default constructor"; + } + + public string HeaderMessage { get; set; } + + public ConventionResult Execute(Types data) + { + var invalid = data.ApplicableTypes.Where(t => t.HasDefaultConstructor() == false); + return ConventionResult.For(invalid, HeaderMessage, (t, m) => m.AppendLine("\t" + t)); } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/AllMethodsAreVirtual.cs b/TestStack.ConventionTests/Conventions/AllMethodsAreVirtual.cs index b1f2268..015ba8c 100644 --- a/TestStack.ConventionTests/Conventions/AllMethodsAreVirtual.cs +++ b/TestStack.ConventionTests/Conventions/AllMethodsAreVirtual.cs @@ -1,23 +1,37 @@ namespace TestStack.ConventionTests.Conventions { + using System; + using System.Collections.Generic; using System.Linq; - using TestStack.ConventionTests.Helpers; + using System.Reflection; + using System.Text; + using TestStack.ConventionTests.Internal; - public class AllMethodsAreVirtual : ConventionData + public class AllMethodsAreVirtual : IConvention { public AllMethodsAreVirtual() { - Must = t => t.NonVirtualMethods().None(); - ItemDescription = (type, builder) => + HeaderMessage = "The following methods are not virtual."; + } + + public string HeaderMessage { get; set; } + + 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); + } + + // I like how that's encapsulated in the reusable convention type, whereas previously it was part of the convention/test code + void DescribeTypeAndMethods(IGrouping> item, StringBuilder message) + { + message.AppendLine("\t" + item.Key); + foreach (var method in item) { - builder.Append(type.FullName); - builder.AppendLine(" has non virtual method(s):"); - foreach (var nonVirtual in type.NonVirtualMethods()) - { - builder.Append('\t'); - builder.AppendLine(nonVirtual.Name); - } - }; + message.AppendLine("\t\t" + method); + } } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs b/TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs index c018733..476520f 100644 --- a/TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs +++ b/TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs @@ -3,66 +3,33 @@ using System; using System.Collections.Generic; using System.Linq; - using System.Reflection; using System.Xml.Linq; - using TestStack.ConventionTests.Helpers; + using TestStack.ConventionTests.Internal; - public class FilesAreEmbeddedResources : ConventionData, IRuntimeFilter + public class FilesAreEmbeddedResources : IConvention { - readonly IProjectLocator projectLocator; - readonly IProjectProvider projectProvider; - Func itemFilter; - - public FilesAreEmbeddedResources() : this(new AssemblyProjectLocator(), new ProjectProvider()) { } - public FilesAreEmbeddedResources(IProjectLocator projectLocator, IProjectProvider projectProvider) + public ConventionResult Execute(Project data) { - this.projectLocator = projectLocator; - this.projectProvider = projectProvider; - - Must = assembly => - { - var references = GetProjectFiles(assembly); - - return references.All(s => s.Item1 == "EmbeddedResource"); - }; - ItemDescription = (assembly, builder) => - { - var filesNotEmbedded = GetProjectFiles(assembly) - .Where(r => r.Item1 != "EmbeddedResource"); - - - builder.AppendLine(string.Format("{0} has the following files which should be embedded resources:", - assembly.GetName().Name)); - foreach (var error in filesNotEmbedded.Select(m => m.Item2 + " which currently has a build action of '" + m.Item1 + "'")) - { - builder.Append('\t'); - builder.AppendLine(error); - } - }; + return ConventionResult.For(GetProjectFiles(data).Where(s => s.Item1 != "EmbeddedResource"), + "The following files which should be embedded resources:", + (t, m) => m.AppendLine("\t" + t.Item2)); } - IEnumerable> GetProjectFiles(Assembly assembly) + IEnumerable> GetProjectFiles(Project project) { - //TODO Not sure about filters, we can interate on this... - if (itemFilter == null) - throw new InvalidOperationException("This convention requires you to provide a filter, which is an overload on Convention.Is"); - + 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 resolveProjectFilePath = projectLocator.ResolveProjectFilePath(assembly); - XDocument projDefinition = projectProvider.LoadProjectDocument(resolveProjectFilePath); + 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 => itemFilter(i.Item2)); + .Where(i => project.Includes(i.Item2)); return references; } - - public void SetFilter(Func filter) - { - itemFilter = filter; - } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/Project.cs b/TestStack.ConventionTests/Conventions/Project.cs new file mode 100644 index 0000000..b0065d1 --- /dev/null +++ b/TestStack.ConventionTests/Conventions/Project.cs @@ -0,0 +1,39 @@ +namespace TestStack.ConventionTests.Conventions +{ + using System; + using System.Reflection; + using System.Xml.Linq; + using TestStack.ConventionTests.Internal; + + public class Project : IConventionData + { + public Func Includes; + + public Project(Assembly assembly, IProjectProvider projectProvider, IProjectLocator projectLocator) + { + Assembly = assembly; + ProjectProvider = projectProvider; + ProjectLocator = projectLocator; + } + + public Assembly Assembly { get; private set; } + + public IProjectLocator ProjectLocator { get; private set; } + + public IProjectProvider ProjectProvider { get; private set; } + + public bool HasValidSource + { + get { return ProjectLocator.ResolveProjectFilePath(Assembly) != null; } + } + + public bool HasApprovedExceptions { get; set; } + + public XDocument GetProject() + { + var location = ProjectLocator.ResolveProjectFilePath(Assembly); + var project = ProjectProvider.LoadProjectDocument(location); + return project; + } + } +} \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs b/TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs index d63528c..acfe31a 100644 --- a/TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs +++ b/TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs @@ -2,51 +2,30 @@ { using System.Collections.Generic; using System.Linq; - using System.Reflection; using System.Text.RegularExpressions; using System.Xml.Linq; - using TestStack.ConventionTests.Helpers; + using TestStack.ConventionTests.Internal; - public class ProjectDoesNotReferenceDllsFromBinOrObjDirectories : ConventionData + public class ProjectDoesNotReferenceDllsFromBinOrObjDirectories : IConvention { const string AssemblyReferencingObjRegex = @"^(?.*?(obj|bin).*?)$"; - public ProjectDoesNotReferenceDllsFromBinOrObjDirectories() - : this(new AssemblyProjectLocator(), new ProjectProvider()) + public ConventionResult Execute(Project data) { + var invalid = AllProjectReferences(data.GetProject()).Where(IsBinOrObjReference); + return ConventionResult.For(invalid, "Some invalid references found.", (r, m) => m.AppendLine("\t" + r)); } - public ProjectDoesNotReferenceDllsFromBinOrObjDirectories(IProjectLocator projectLocator, IProjectProvider projectProvider) - { - Must = assembly => - { - var references = GetProjectReferences(projectLocator, projectProvider, assembly); - - return references.All(s => !Regex.IsMatch(s, AssemblyReferencingObjRegex, RegexOptions.IgnoreCase)); - }; - ItemDescription = (assembly, builder) => - { - var matches = GetProjectReferences(projectLocator, projectProvider, assembly) - .Select(r => Regex.Match(r, AssemblyReferencingObjRegex, RegexOptions.IgnoreCase)) - .Where(r => r.Success); - builder.AppendLine(string.Format("{0} is referencing assemblies in the bin or obj folders:", - assembly.GetName().Name)); - foreach (var match in matches.Select(m=>m.Groups["assembly"].Value)) - { - builder.Append('\t'); - builder.AppendLine(match); - } - }; + static bool IsBinOrObjReference(string reference) + { + return Regex.IsMatch(reference, AssemblyReferencingObjRegex, RegexOptions.IgnoreCase); } - static IEnumerable GetProjectReferences(IProjectLocator projectLocator, IProjectProvider projectProvider, - Assembly assembly) + static IEnumerable AllProjectReferences(XDocument projDefinition) { XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003"; - var resolveProjectFilePath = projectLocator.ResolveProjectFilePath(assembly); - XDocument projDefinition = projectProvider.LoadProjectDocument(resolveProjectFilePath); - IEnumerable references = projDefinition + var references = projDefinition .Element(msbuild + "Project") .Elements(msbuild + "ItemGroup") .Elements(msbuild + "Reference") diff --git a/TestStack.ConventionTests/Conventions/Types.cs b/TestStack.ConventionTests/Conventions/Types.cs new file mode 100644 index 0000000..1ce6692 --- /dev/null +++ b/TestStack.ConventionTests/Conventions/Types.cs @@ -0,0 +1,21 @@ +namespace TestStack.ConventionTests.Conventions +{ + using System; + using System.Linq; + + /// + /// This is where we set what our convention is all about. + /// + public class Types : IConventionData + { + //NOTE: that's a terrible name + public Type[] ApplicableTypes { get; set; } + + public bool HasApprovedExceptions { get; set; } + + public bool HasValidSource + { + get { return ApplicableTypes.Any(); } + } + } +} \ No newline at end of file diff --git a/TestStack.ConventionTests/IConvention.cs b/TestStack.ConventionTests/IConvention.cs new file mode 100644 index 0000000..82a0908 --- /dev/null +++ b/TestStack.ConventionTests/IConvention.cs @@ -0,0 +1,9 @@ +namespace TestStack.ConventionTests +{ + using TestStack.ConventionTests.Internal; + + public interface IConvention where T : IConventionData + { + ConventionResult Execute(T data); + } +} \ No newline at end of file diff --git a/TestStack.ConventionTests/IConventionData.cs b/TestStack.ConventionTests/IConventionData.cs new file mode 100644 index 0000000..5d90db5 --- /dev/null +++ b/TestStack.ConventionTests/IConventionData.cs @@ -0,0 +1,8 @@ +namespace TestStack.ConventionTests +{ + public interface IConventionData + { + bool HasValidSource { get; } + bool HasApprovedExceptions { get; } + } +} \ No newline at end of file diff --git a/TestStack.ConventionTests/IRuntimeFilter.cs b/TestStack.ConventionTests/IRuntimeFilter.cs deleted file mode 100644 index 94c6778..0000000 --- a/TestStack.ConventionTests/IRuntimeFilter.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace TestStack.ConventionTests -{ - using System; - - public interface IRuntimeFilter - { - void SetFilter(Func predicate); - } -} \ No newline at end of file diff --git a/TestStack.ConventionTests/Helpers/AssemblyProjectLocator.cs b/TestStack.ConventionTests/Internal/AssemblyProjectLocator.cs similarity index 86% rename from TestStack.ConventionTests/Helpers/AssemblyProjectLocator.cs rename to TestStack.ConventionTests/Internal/AssemblyProjectLocator.cs index 174bf7d..2830ce7 100644 --- a/TestStack.ConventionTests/Helpers/AssemblyProjectLocator.cs +++ b/TestStack.ConventionTests/Internal/AssemblyProjectLocator.cs @@ -1,4 +1,4 @@ -namespace TestStack.ConventionTests.Helpers +namespace TestStack.ConventionTests.Internal { using System; using System.Reflection; @@ -9,7 +9,7 @@ public class AssemblyProjectLocator : IProjectLocator { public string ResolveProjectFilePath(Assembly assembly) { - var readerParameters = new ReaderParameters { ReadSymbols = true, ReadingMode = ReadingMode.Deferred }; + var readerParameters = new ReaderParameters {ReadSymbols = true, ReadingMode = ReadingMode.Deferred}; var definition = AssemblyDefinition.ReadAssembly(assembly.Location, readerParameters); var methodDefinition = GetMethodWithBody(definition); var document = GetMethodDocument(methodDefinition); diff --git a/TestStack.ConventionTests/Internal/ConventionResult.cs b/TestStack.ConventionTests/Internal/ConventionResult.cs new file mode 100644 index 0000000..96ac32c --- /dev/null +++ b/TestStack.ConventionTests/Internal/ConventionResult.cs @@ -0,0 +1,49 @@ +namespace TestStack.ConventionTests.Internal +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + public class ConventionResult + { + public string Message { get; set; } + public bool IsConclusive { get; set; } + // TODO: perhaps name it better so that it doesn't get confused with System.Exception and related concepts + public int InvalidResultsCount { get; set; } + + public static ConventionResult For(IEnumerable items, + string header, + Action itemDescriptor) + { + var array = items.ToArray(); + var result = new ConventionResult + { + InvalidResultsCount = array.Length, + IsConclusive = true + }; + if (array.None()) + { + return result; + } + // NOTE: we might possibly want to abstract the StringBuilder to have more high level construct that would allow us to plug rich reports here... + var message = new StringBuilder(header); + Array.ForEach(array, r => + { + message.AppendLine(); + itemDescriptor(r, message); + }); + result.Message = message.ToString(); + return result; + } + + public static ConventionResult Inconclusive(string message) + { + return new ConventionResult + { + Message = message, + IsConclusive = false + }; + } + } +} \ No newline at end of file diff --git a/TestStack.ConventionTests/Helpers/IProjectLocator.cs b/TestStack.ConventionTests/Internal/IProjectLocator.cs similarity index 71% rename from TestStack.ConventionTests/Helpers/IProjectLocator.cs rename to TestStack.ConventionTests/Internal/IProjectLocator.cs index 148bc17..12aaafc 100644 --- a/TestStack.ConventionTests/Helpers/IProjectLocator.cs +++ b/TestStack.ConventionTests/Internal/IProjectLocator.cs @@ -1,4 +1,4 @@ -namespace TestStack.ConventionTests.Helpers +namespace TestStack.ConventionTests.Internal { using System.Reflection; diff --git a/TestStack.ConventionTests/Helpers/IProjectProvider.cs b/TestStack.ConventionTests/Internal/IProjectProvider.cs similarity index 72% rename from TestStack.ConventionTests/Helpers/IProjectProvider.cs rename to TestStack.ConventionTests/Internal/IProjectProvider.cs index 1f8c52a..e09da1c 100644 --- a/TestStack.ConventionTests/Helpers/IProjectProvider.cs +++ b/TestStack.ConventionTests/Internal/IProjectProvider.cs @@ -1,9 +1,9 @@ -namespace TestStack.ConventionTests -{ - using System.Xml.Linq; - - public interface IProjectProvider - { - XDocument LoadProjectDocument(string resolveProjectFilePath); - } +namespace TestStack.ConventionTests.Internal +{ + using System.Xml.Linq; + + public interface IProjectProvider + { + XDocument LoadProjectDocument(string resolveProjectFilePath); + } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Helpers/LinqExtensions.cs b/TestStack.ConventionTests/Internal/LinqExtensions.cs similarity index 82% rename from TestStack.ConventionTests/Helpers/LinqExtensions.cs rename to TestStack.ConventionTests/Internal/LinqExtensions.cs index 72c391f..920e4e5 100644 --- a/TestStack.ConventionTests/Helpers/LinqExtensions.cs +++ b/TestStack.ConventionTests/Internal/LinqExtensions.cs @@ -1,8 +1,10 @@ // ReSharper disable once CheckNamespace -namespace System.Linq + +namespace TestStack.ConventionTests.Internal { using System; using System.Collections.Generic; + using System.Linq; public static class LinqExtensions { @@ -10,7 +12,7 @@ public static bool None(this IEnumerable enumerable) { return !enumerable.Any(); } - + public static bool None(this IEnumerable enumerable, Func predicate) { return !enumerable.Any(predicate); diff --git a/TestStack.ConventionTests/Helpers/ProjectProvider.cs b/TestStack.ConventionTests/Internal/ProjectProvider.cs similarity index 80% rename from TestStack.ConventionTests/Helpers/ProjectProvider.cs rename to TestStack.ConventionTests/Internal/ProjectProvider.cs index 3c6c662..994b44b 100644 --- a/TestStack.ConventionTests/Helpers/ProjectProvider.cs +++ b/TestStack.ConventionTests/Internal/ProjectProvider.cs @@ -1,12 +1,12 @@ -namespace TestStack.ConventionTests -{ - using System.Xml.Linq; - - public class ProjectProvider : IProjectProvider - { - public XDocument LoadProjectDocument(string resolveProjectFilePath) - { - return XDocument.Load(resolveProjectFilePath); - } - } +namespace TestStack.ConventionTests.Internal +{ + using System.Xml.Linq; + + public class ProjectProvider : IProjectProvider + { + public XDocument LoadProjectDocument(string resolveProjectFilePath) + { + return XDocument.Load(resolveProjectFilePath); + } + } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Helpers/ReflectionExtensions.cs b/TestStack.ConventionTests/Internal/ReflectionExtensions.cs similarity index 75% rename from TestStack.ConventionTests/Helpers/ReflectionExtensions.cs rename to TestStack.ConventionTests/Internal/ReflectionExtensions.cs index 76a17ac..11eaeb5 100644 --- a/TestStack.ConventionTests/Helpers/ReflectionExtensions.cs +++ b/TestStack.ConventionTests/Internal/ReflectionExtensions.cs @@ -1,4 +1,4 @@ -namespace TestStack.ConventionTests.Helpers +namespace TestStack.ConventionTests.Internal { using System; using System.Collections.Generic; @@ -46,12 +46,12 @@ public static Type[] SafeGetTypes(this Assembly assembly) public static bool IsEnum(this Type type) { - return typeof(Enum).IsAssignableFrom(type); + return typeof (Enum).IsAssignableFrom(type); } public static bool HasAttribute(this Type type, bool inherit = true) where TAttribute : Attribute { - return type.GetCustomAttributes(typeof(TAttribute), inherit).Length > 0; + return type.GetCustomAttributes(typeof (TAttribute), inherit).Length > 0; } public static bool IsStatic(this Type type) @@ -61,7 +61,8 @@ public static bool IsStatic(this Type type) public static bool HasDefaultConstructor(this Type type) { - return type.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly) + return type.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | + BindingFlags.DeclaredOnly) .Any(constructorInfo => constructorInfo.GetParameters().Length == 0 && !constructorInfo.IsPrivate); } @@ -73,7 +74,7 @@ public static bool HasPublicDefaultConstructor(this Type type) public static bool AssignableTo(this Type type) { - return typeof(TAssignableTo).IsAssignableFrom(type); + return typeof (TAssignableTo).IsAssignableFrom(type); } public static IEnumerable ConcreteTypes(this IEnumerable types) @@ -83,9 +84,13 @@ public static IEnumerable ConcreteTypes(this IEnumerable types) public static IEnumerable NonVirtualMethods(this Type type) { - var methodInfos = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); + var methodInfos = + type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | + BindingFlags.DeclaredOnly); return methodInfos - .Where(methodInfo => !methodInfo.IsPrivate && methodInfo.DeclaringType == type && !methodInfo.Name.StartsWith("<")) + .Where( + methodInfo => + !methodInfo.IsPrivate && methodInfo.DeclaringType == type && !methodInfo.Name.StartsWith("<")) .Where(methodInfo => methodInfo.Name != "Equals") .Where(methodInfo => !methodInfo.IsVirtual || methodInfo.IsFinal); } diff --git a/TestStack.ConventionTests/Properties/AssemblyInfo.cs b/TestStack.ConventionTests/Properties/AssemblyInfo.cs index 5f8fb14..74834b6 100644 --- a/TestStack.ConventionTests/Properties/AssemblyInfo.cs +++ b/TestStack.ConventionTests/Properties/AssemblyInfo.cs @@ -1,10 +1,9 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following +// 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 System.Reflection; +using System.Runtime.InteropServices; + [assembly: AssemblyTitle("TestStack.ConventionTests")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] @@ -17,9 +16,11 @@ // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. + [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM + [assembly: Guid("ae7bce97-3d40-4d7c-932f-37f1c7b041a2")] // Version information for an assembly consists of the following four values: @@ -32,5 +33,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] + [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/TestStack.ConventionTests/TestStack.ConventionTests.csproj b/TestStack.ConventionTests/TestStack.ConventionTests.csproj index 1929e87..1fed020 100644 --- a/TestStack.ConventionTests/TestStack.ConventionTests.csproj +++ b/TestStack.ConventionTests/TestStack.ConventionTests.csproj @@ -32,6 +32,12 @@ true + + ..\packages\ApprovalTests.3.0.01\lib\net40\ApprovalTests.dll + + + ..\packages\ApprovalUtilities.3.0.01\lib\net35\ApprovalUtilities.dll + ..\packages\Mono.Cecil.0.9.5.4\lib\net40\Mono.Cecil.dll @@ -53,22 +59,24 @@ + + - - + + + + - - - - + + + - - + - + diff --git a/TestStack.ConventionTests/packages.config b/TestStack.ConventionTests/packages.config index bd56ac0..d6f9755 100644 --- a/TestStack.ConventionTests/packages.config +++ b/TestStack.ConventionTests/packages.config @@ -1,4 +1,6 @@  + + \ No newline at end of file