From c1514c8c753b42e8be277f65bfe12394133867ba Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 11 Aug 2013 20:54:25 +0100 Subject: [PATCH 1/3] Introduced a IConventionResult to clean things up --- .../ConventionAssertionClassTests.cs | 6 +- TestStack.ConventionTests/Convention.cs | 64 ++----------------- .../AllClassesHaveDefaultConstructor.cs | 8 +-- .../Conventions/AllMethodsAreVirtual.cs | 8 +-- .../ClassTypeHasSpecificNamespace.cs | 35 +++------- .../Conventions/FilesAreEmbeddedResources.cs | 17 ++--- .../Conventions/ISymmetricConvention.cs | 12 ---- ...NotReferenceDllsFromBinOrObjDirectories.cs | 12 ++-- TestStack.ConventionTests/IConvention.cs | 5 +- .../IConventionResult.cs | 13 ++++ .../Internal/ConventionResult.cs | 59 +++++++++++++++++ .../Internal/Executor.cs | 42 ++++++------ .../TestStack.ConventionTests.csproj | 3 +- 13 files changed, 125 insertions(+), 159 deletions(-) delete mode 100644 TestStack.ConventionTests/Conventions/ISymmetricConvention.cs create mode 100644 TestStack.ConventionTests/IConventionResult.cs create mode 100644 TestStack.ConventionTests/Internal/ConventionResult.cs diff --git a/TestStack.ConventionTests.Tests/ConventionAssertionClassTests.cs b/TestStack.ConventionTests.Tests/ConventionAssertionClassTests.cs index 6fd3730..a72203d 100644 --- a/TestStack.ConventionTests.Tests/ConventionAssertionClassTests.cs +++ b/TestStack.ConventionTests.Tests/ConventionAssertionClassTests.cs @@ -1,6 +1,5 @@ namespace TestStack.ConventionTests.Tests { - using System.Collections.Generic; using ApprovalTests.Reporters; using NUnit.Framework; using TestStack.ConventionTests.Internal; @@ -34,10 +33,9 @@ public ConventionReportFailure Format(string failingData) public class FailingConvention : IConvention { - public string ConventionTitle { get { return "Header"; } } - public IEnumerable GetFailingData(FakeData data) + public void Execute(FakeData data, IConventionResult result) { - return new[] { "Different" }; + result.Is("Header", new[] {"Different"}); } } } diff --git a/TestStack.ConventionTests/Convention.cs b/TestStack.ConventionTests/Convention.cs index 606d671..f4439af 100644 --- a/TestStack.ConventionTests/Convention.cs +++ b/TestStack.ConventionTests/Convention.cs @@ -3,11 +3,9 @@ using System; using System.Collections.Generic; using System.IO; - using System.Linq; using System.Reflection; using ApprovalTests; using ApprovalTests.Core.Exceptions; - using TestStack.ConventionTests.Conventions; using TestStack.ConventionTests.Internal; using TestStack.ConventionTests.Reporting; @@ -42,8 +40,8 @@ public static void Is(IConvention convention, TDataSou { try { - var conventionResult = Executor.GetConventionReport(convention.ConventionTitle, convention.GetFailingData(data).ToArray(), data); - Reports.Add(conventionResult); + var conventionResult = Executor.GetConventionResults(convention, data); + Reports.AddRange(conventionResult); new ConventionReportTraceRenderer().Render(conventionResult); reporter.Render(conventionResult); @@ -57,8 +55,8 @@ public static void Is(IConvention convention, TDataSou public static void IsWithApprovedExeptions(IConvention convention, TDataSource data) where TDataSource : IConventionData { - var conventionResult = Executor.GetConventionReportWithApprovedExeptions(convention.ConventionTitle, convention.GetFailingData(data).ToArray(), data); - Reports.Add(conventionResult); + var conventionResult = Executor.GetConventionResultsWithApprovedExeptions(convention, data); + Reports.AddRange(conventionResult); try { @@ -78,60 +76,6 @@ public static void IsWithApprovedExeptions(IConvention } } - public static void Is(ISymmetricConvention convention, TDataSource data) - where TDataSource : IConventionData - { - Is(convention, data, new ConventionResultExceptionReporter()); - } - - public static void Is(ISymmetricConvention convention, TDataSource data, IConventionReportRenderer reporter) - where TDataSource : IConventionData - { - try - { - var conventionResult = Executor.GetConventionReport(convention.ConventionTitle, convention.GetFailingData(data).ToArray(), data); - var inverseConventionResult = Executor.GetConventionReport(convention.InverseTitle, convention.GetFailingInverseData(data).ToArray(), data); - - Reports.Add(conventionResult); - Reports.Add(inverseConventionResult); - - new ConventionReportTraceRenderer().Render(conventionResult, inverseConventionResult); - reporter.Render(conventionResult, inverseConventionResult); - } - finally - { - HtmlRenderer.Render(Reports.ToArray()); - } - } - - public static void IsWithApprovedExeptions(ISymmetricConvention convention, TDataSource data) - where TDataSource : IConventionData - { - var conventionResult = Executor.GetConventionReportWithApprovedExeptions(convention.ConventionTitle, convention.GetFailingData(data).ToArray(), data); - var inverseConventionResult = Executor.GetConventionReportWithApprovedExeptions(convention.InverseTitle, convention.GetFailingInverseData(data).ToArray(), data); - Reports.Add(conventionResult); - Reports.Add(inverseConventionResult); - - try - { - //Render both, with approved exceptions included - var conventionReportTextRenderer = new ConventionReportTextRenderer(); - conventionReportTextRenderer.Render(conventionResult, inverseConventionResult); - Approvals.Verify(conventionReportTextRenderer.Output); - - // Trace on success - new ConventionReportTraceRenderer().Render(conventionResult, inverseConventionResult); - } - catch (ApprovalException ex) - { - throw new ConventionFailedException("Approved exceptions for convention differs\r\n\r\n" + ex.Message, ex); - } - finally - { - HtmlRenderer.Render(Reports.ToArray()); - } - } - // http://stackoverflow.com/questions/52797/c-how-do-i-get-the-path-of-the-assembly-the-code-is-in#answer-283917 static string AssemblyDirectory { diff --git a/TestStack.ConventionTests/Conventions/AllClassesHaveDefaultConstructor.cs b/TestStack.ConventionTests/Conventions/AllClassesHaveDefaultConstructor.cs index 63ee4f8..ed8647f 100644 --- a/TestStack.ConventionTests/Conventions/AllClassesHaveDefaultConstructor.cs +++ b/TestStack.ConventionTests/Conventions/AllClassesHaveDefaultConstructor.cs @@ -1,17 +1,15 @@ namespace TestStack.ConventionTests.Conventions { - using System.Collections.Generic; using System.Linq; using TestStack.ConventionTests.ConventionData; using TestStack.ConventionTests.Internal; public class AllClassesHaveDefaultConstructor : IConvention { - public string ConventionTitle { get { return "Types must have a default constructor"; } } - - public IEnumerable GetFailingData(Types data) + public void Execute(Types data, IConventionResult result) { - return data.TypesToVerify.Where(t => t.HasDefaultConstructor() == false); + result.Is("Types must have a default constructor", + data.TypesToVerify.Where(t => t.HasDefaultConstructor() == false)); } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/AllMethodsAreVirtual.cs b/TestStack.ConventionTests/Conventions/AllMethodsAreVirtual.cs index dcf659e..b6d7d1e 100644 --- a/TestStack.ConventionTests/Conventions/AllMethodsAreVirtual.cs +++ b/TestStack.ConventionTests/Conventions/AllMethodsAreVirtual.cs @@ -1,18 +1,14 @@ namespace TestStack.ConventionTests.Conventions { - using System.Collections.Generic; using System.Linq; - using System.Reflection; using TestStack.ConventionTests.ConventionData; using TestStack.ConventionTests.Internal; public class AllMethodsAreVirtual : IConvention { - public string ConventionTitle { get { return "Methods must be virtual"; } } - - public IEnumerable GetFailingData(Types data) + public void Execute(Types data, IConventionResult result) { - return data.TypesToVerify.SelectMany(t => t.NonVirtualMethods()); + result.Is("Methods must be virtual", data.TypesToVerify.SelectMany(t => t.NonVirtualMethods())); } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/ClassTypeHasSpecificNamespace.cs b/TestStack.ConventionTests/Conventions/ClassTypeHasSpecificNamespace.cs index d109d37..893a836 100644 --- a/TestStack.ConventionTests/Conventions/ClassTypeHasSpecificNamespace.cs +++ b/TestStack.ConventionTests/Conventions/ClassTypeHasSpecificNamespace.cs @@ -1,7 +1,6 @@ namespace TestStack.ConventionTests.Conventions { using System; - using System.Collections.Generic; using System.Linq; using TestStack.ConventionTests.ConventionData; @@ -14,7 +13,7 @@ /// /// This is a Symmetric convention, and will verify all of a Class Type lives in the namespace, but also that only that class type is in that namespace /// - public class ClassTypeHasSpecificNamespace : ISymmetricConvention + public class ClassTypeHasSpecificNamespace : IConvention { readonly Func classIsApplicable; readonly string namespaceToCheck; @@ -33,34 +32,20 @@ public ClassTypeHasSpecificNamespace(Func classIsApplicable, string this.classType = classType; } - public string ConventionTitle + public void Execute(Types data, IConventionResult result) { - get - { - return string.Format("{0}s must be under the '{1}' namespace", classType, namespaceToCheck); - } - } - - public string InverseTitle - { - get - { - return string.Format("Non-{0}s must not be under the '{1}' namespace", classType, namespaceToCheck); - } - } - - public IEnumerable GetFailingData(Types data) - { - return data.TypesToVerify + var failingData = data.TypesToVerify .Where(classIsApplicable) .Where(t => t.Namespace == null || !t.Namespace.StartsWith(namespaceToCheck)); - } - - public IEnumerable GetFailingInverseData(Types data) - { - return data.TypesToVerify + var inverseFailingData = data.TypesToVerify .Where(t => !classIsApplicable(t)) .Where(t => t.Namespace != null && t.Namespace.StartsWith(namespaceToCheck)); + + result.IsSymmetric( + string.Format("{0}s must be under the '{1}' namespace", classType, namespaceToCheck), + failingData, + string.Format("Non-{0}s must not be under the '{1}' namespace", classType, namespaceToCheck), + inverseFailingData); } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs b/TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs index 88fc915..53f83af 100644 --- a/TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs +++ b/TestStack.ConventionTests/Conventions/FilesAreEmbeddedResources.cs @@ -1,6 +1,5 @@ namespace TestStack.ConventionTests.Conventions { - using System.Collections.Generic; using System.Linq; using TestStack.ConventionTests.ConventionData; @@ -11,19 +10,13 @@ public FilesAreEmbeddedResources(string fileExtension) FileExtension = fileExtension; } - public string ConventionTitle - { - get - { - return string.Format("{0} Files must be embedded resources", FileExtension); - } - } - - public string FileExtension { get; set; } + public string FileExtension { get; private set; } - public IEnumerable GetFailingData(ProjectFiles data) + public void Execute(ProjectFiles data, IConventionResult result) { - return data.Files.Where(s => s.FilePath.EndsWith(FileExtension) && s.ReferenceType != "EmbeddedResource"); + result.Is( + string.Format("{0} Files must be embedded resources", FileExtension), + data.Files.Where(s => s.FilePath.EndsWith(FileExtension) && s.ReferenceType != "EmbeddedResource")); } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/ISymmetricConvention.cs b/TestStack.ConventionTests/Conventions/ISymmetricConvention.cs deleted file mode 100644 index e7454bf..0000000 --- a/TestStack.ConventionTests/Conventions/ISymmetricConvention.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace TestStack.ConventionTests.Conventions -{ - using System.Collections.Generic; - - public interface ISymmetricConvention where T : IConventionData - { - string ConventionTitle { get; } - string InverseTitle { get; } - IEnumerable GetFailingData(T data); - IEnumerable GetFailingInverseData(T data); - } -} \ No newline at end of file diff --git a/TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs b/TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs index 04d9fdb..29eab34 100644 --- a/TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs +++ b/TestStack.ConventionTests/Conventions/ProjectDoesNotReferenceDllsFromBinOrObjDirectories.cs @@ -1,6 +1,5 @@ namespace TestStack.ConventionTests.Conventions { - using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using TestStack.ConventionTests.ConventionData; @@ -9,16 +8,15 @@ public class ProjectDoesNotReferenceDllsFromBinOrObjDirectories : IConvention.*?(obj|bin).*?)$"; - static bool IsBinOrObjReference(ProjectReference reference) + public void Execute(ProjectReferences data, IConventionResult result) { - return Regex.IsMatch(reference.ReferencedPath, AssemblyReferencingObjRegex, RegexOptions.IgnoreCase); + result.Is("Project must not reference dlls from bin or obj directories", + data.References.Where(IsBinOrObjReference)); } - public string ConventionTitle { get { return "Project must not reference dlls from bin or obj directories"; } } - - public IEnumerable GetFailingData(ProjectReferences data) + static bool IsBinOrObjReference(ProjectReference reference) { - return data.References.Where(IsBinOrObjReference); + return Regex.IsMatch(reference.ReferencedPath, AssemblyReferencingObjRegex, RegexOptions.IgnoreCase); } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/IConvention.cs b/TestStack.ConventionTests/IConvention.cs index 468fdf6..641dc53 100644 --- a/TestStack.ConventionTests/IConvention.cs +++ b/TestStack.ConventionTests/IConvention.cs @@ -1,10 +1,7 @@ namespace TestStack.ConventionTests { - using System.Collections.Generic; - public interface IConvention where T : IConventionData { - string ConventionTitle { get; } - IEnumerable GetFailingData(T data); + void Execute(T data, IConventionResult result); } } \ No newline at end of file diff --git a/TestStack.ConventionTests/IConventionResult.cs b/TestStack.ConventionTests/IConventionResult.cs new file mode 100644 index 0000000..b01edb4 --- /dev/null +++ b/TestStack.ConventionTests/IConventionResult.cs @@ -0,0 +1,13 @@ +namespace TestStack.ConventionTests +{ + using System; + using System.Collections.Generic; + + public interface IConventionResult + { + void Is(string resultTitle, IEnumerable failingData); + void IsSymmetric( + string firstResultTitle, IEnumerable firstFailingData, + string secondResultTitle, IEnumerable secondFailingData); + } +} \ No newline at end of file diff --git a/TestStack.ConventionTests/Internal/ConventionResult.cs b/TestStack.ConventionTests/Internal/ConventionResult.cs new file mode 100644 index 0000000..8db4c8d --- /dev/null +++ b/TestStack.ConventionTests/Internal/ConventionResult.cs @@ -0,0 +1,59 @@ +namespace TestStack.ConventionTests.Internal +{ + using System.Collections.Generic; + using System.Linq; + using TestStack.ConventionTests.Reporting; + + public class ConventionResult : IConventionResult + { + readonly string dataDescription; + readonly List conventionResults; + + public ConventionResult(string dataDescription) + { + this.dataDescription = dataDescription; + conventionResults = new List(); + } + + public ResultInfo[] ConventionResults + { + get { return conventionResults.ToArray(); } + } + + public void Is(string resultTitle, IEnumerable failingData) + { + // ReSharper disable PossibleMultipleEnumeration + conventionResults.Add(new ResultInfo( + failingData.None() ? TestResult.Passed : TestResult.Failed, + resultTitle, + dataDescription, + failingData.Select(FormatData).ToArray())); + } + + public void IsSymmetric( + string firstResultTitle, IEnumerable firstFailingData, + string secondResultTitle, IEnumerable secondFailingData) + { + conventionResults.Add(new ResultInfo( + firstFailingData.None() ? TestResult.Passed : TestResult.Failed, + firstResultTitle, + dataDescription, + firstFailingData.Select(FormatData).ToArray())); + conventionResults.Add(new ResultInfo( + secondFailingData.None() ? TestResult.Passed : TestResult.Failed, + secondResultTitle, + dataDescription, + secondFailingData.Select(FormatData).ToArray())); + } + + static ConventionReportFailure FormatData(T failingData) + { + var formatter = Convention.Formatters.FirstOrDefault(f => f.CanFormat(failingData)); + + if (formatter == null) + throw new NoDataFormatterFoundException(typeof(T).Name + " has no formatter, add one with `Convention.Formatters.Add(new MyDataFormatter());`"); + + return formatter.Format(failingData); + } + } +} \ No newline at end of file diff --git a/TestStack.ConventionTests/Internal/Executor.cs b/TestStack.ConventionTests/Internal/Executor.cs index c054e29..a39c3cf 100644 --- a/TestStack.ConventionTests/Internal/Executor.cs +++ b/TestStack.ConventionTests/Internal/Executor.cs @@ -1,45 +1,41 @@ namespace TestStack.ConventionTests.Internal { - using System.Linq; + using System; using TestStack.ConventionTests.Conventions; using TestStack.ConventionTests.Reporting; public static class Executor { - public static ResultInfo GetConventionReport(string conventionTitle, object[] failingData, IConventionData data) + public static ResultInfo[] GetConventionResults(IConvention convention, TDataSource data) + where TDataSource : IConventionData { if (!data.HasData) throw new ConventionSourceInvalidException(string.Format("{0} has no data", data.Description)); - var passed = failingData.None(); + var resultGatherer = new ConventionResult(data.Description); + convention.Execute(data, resultGatherer); - var conventionResult = new ResultInfo( - passed ? TestResult.Passed : TestResult.Failed, - conventionTitle, - data.Description, - failingData.Select(FormatData).ToArray()); - return conventionResult; + return resultGatherer.ConventionResults; } - public static ResultInfo GetConventionReportWithApprovedExeptions(string conventionTitle, object[] failingData, IConventionData data) + public static ResultInfo[] GetConventionResultsWithApprovedExeptions( + IConvention convention, TDataSource data) + where TDataSource : IConventionData { - var conventionResult = Executor.GetConventionReport(conventionTitle, failingData, data); var conventionReportTextRenderer = new ConventionReportTextRenderer(); // Add approved exceptions to report - conventionReportTextRenderer.RenderItems(conventionResult); - conventionResult.WithApprovedException(conventionReportTextRenderer.Output); - - return conventionResult; - } - - static ConventionReportFailure FormatData(T failingData) - { - var formatter = Convention.Formatters.FirstOrDefault(f => f.CanFormat(failingData)); + if (!data.HasData) + throw new ConventionSourceInvalidException(string.Format("{0} has no data", data.Description)); - if (formatter == null) - throw new NoDataFormatterFoundException(typeof(T).Name + " has no formatter, add one with `Convention.Formatters.Add(new MyDataFormatter());`"); + var resultGatherer = new ConventionResult(data.Description); + convention.Execute(data, resultGatherer); + foreach (var conventionResult in resultGatherer.ConventionResults) + { + conventionReportTextRenderer.RenderItems(conventionResult); + conventionResult.WithApprovedException(conventionReportTextRenderer.Output); + } - return formatter.Format(failingData); + return resultGatherer.ConventionResults; } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/TestStack.ConventionTests.csproj b/TestStack.ConventionTests/TestStack.ConventionTests.csproj index 8235b14..3e8b083 100644 --- a/TestStack.ConventionTests/TestStack.ConventionTests.csproj +++ b/TestStack.ConventionTests/TestStack.ConventionTests.csproj @@ -61,7 +61,9 @@ + + @@ -75,7 +77,6 @@ - From 14f1a6e219281da3c93d24d85c4a197c295959e8 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Mon, 12 Aug 2013 08:35:17 +0100 Subject: [PATCH 2/3] Added better IsSymmetric overload thanks to @kkozmic --- .../ClassTypeHasSpecificNamespace.cs | 18 ++++----- .../IConventionResult.cs | 35 +++++++++++++++-- .../Internal/ConventionResult.cs | 39 +++++++++++++------ 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/TestStack.ConventionTests/Conventions/ClassTypeHasSpecificNamespace.cs b/TestStack.ConventionTests/Conventions/ClassTypeHasSpecificNamespace.cs index 893a836..25da3af 100644 --- a/TestStack.ConventionTests/Conventions/ClassTypeHasSpecificNamespace.cs +++ b/TestStack.ConventionTests/Conventions/ClassTypeHasSpecificNamespace.cs @@ -1,7 +1,6 @@ namespace TestStack.ConventionTests.Conventions { using System; - using System.Linq; using TestStack.ConventionTests.ConventionData; /// @@ -34,18 +33,17 @@ public ClassTypeHasSpecificNamespace(Func classIsApplicable, string public void Execute(Types data, IConventionResult result) { - var failingData = data.TypesToVerify - .Where(classIsApplicable) - .Where(t => t.Namespace == null || !t.Namespace.StartsWith(namespaceToCheck)); - var inverseFailingData = data.TypesToVerify - .Where(t => !classIsApplicable(t)) - .Where(t => t.Namespace != null && t.Namespace.StartsWith(namespaceToCheck)); - result.IsSymmetric( string.Format("{0}s must be under the '{1}' namespace", classType, namespaceToCheck), - failingData, string.Format("Non-{0}s must not be under the '{1}' namespace", classType, namespaceToCheck), - inverseFailingData); + classIsApplicable, + TypeLivesInSpecifiedNamespace, + data.TypesToVerify); + } + + bool TypeLivesInSpecifiedNamespace(Type t) + { + return t.Namespace == null || t.Namespace.StartsWith(namespaceToCheck); } } } \ No newline at end of file diff --git a/TestStack.ConventionTests/IConventionResult.cs b/TestStack.ConventionTests/IConventionResult.cs index b01edb4..d305ebb 100644 --- a/TestStack.ConventionTests/IConventionResult.cs +++ b/TestStack.ConventionTests/IConventionResult.cs @@ -6,8 +6,37 @@ public interface IConventionResult { void Is(string resultTitle, IEnumerable failingData); - void IsSymmetric( - string firstResultTitle, IEnumerable firstFailingData, - string secondResultTitle, IEnumerable secondFailingData); + + /// + /// A symmetric convention is a convention which also can be applied in reverse. For example + /// All dto's live in Project.Dto namespace AND Only dto's live in Project.Dto + /// This means if a DTO is outside of Project.Dto, the test will fail, + /// and if a non-dto is in Project.Dto the test will also fail + /// + /// The data type the convention is applied to + /// Title of the convention, i.e Dto's must live in Project.Dto namespace + /// Data failing to conform to the convention + /// The inverse scenario title, i.e Non-dtos must not live inside Project.Dto namespace + /// Data failing to conform to the inverse of the convention + void IsSymmetric( + string conventionResultTitle, IEnumerable conventionFailingData, + string inverseResultTitle, IEnumerable inverseFailingData); + + /// + /// A symmetric convention is a convention which also can be applied in reverse. For example + /// All dto's live in Project.Dto namespace AND Only dto's live in Project.Dto + /// This means if a DTO is outside of Project.Dto, the test will fail, + /// and if a non-dto is in Project.Dto the test will also fail + /// + /// The data type the convention is applied to + /// Title of the convention, i.e Dto's must live in Project.Dto namespace + /// The inverse scenario title, i.e Non-dtos must not live inside Project.Dto namespace + /// Predicate describing if the data is included, for example, t => t.Name.EndsWith("Dto") + /// + /// Predicate describing the convention, for example, t => + /// t.NameSpace.StartsWith("Project.Dto") + /// + /// All data, for dto example, all types in the project, not just dto's + void IsSymmetric(string conventionResultTitle, string inverseResultTitle, Func isInclusiveData, Func dataConformsToConvention, IEnumerable allData); } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Internal/ConventionResult.cs b/TestStack.ConventionTests/Internal/ConventionResult.cs index 8db4c8d..10b3b78 100644 --- a/TestStack.ConventionTests/Internal/ConventionResult.cs +++ b/TestStack.ConventionTests/Internal/ConventionResult.cs @@ -1,13 +1,14 @@ namespace TestStack.ConventionTests.Internal { + using System; using System.Collections.Generic; using System.Linq; using TestStack.ConventionTests.Reporting; public class ConventionResult : IConventionResult { - readonly string dataDescription; readonly List conventionResults; + readonly string dataDescription; public ConventionResult(string dataDescription) { @@ -30,20 +31,32 @@ public void Is(string resultTitle, IEnumerable failingData) failingData.Select(FormatData).ToArray())); } - public void IsSymmetric( - string firstResultTitle, IEnumerable firstFailingData, - string secondResultTitle, IEnumerable secondFailingData) + public void IsSymmetric( + string conventionResultTitle, IEnumerable conventionFailingData, + string inverseResultTitle, IEnumerable inverseFailingData) { conventionResults.Add(new ResultInfo( - firstFailingData.None() ? TestResult.Passed : TestResult.Failed, - firstResultTitle, + conventionFailingData.None() ? TestResult.Passed : TestResult.Failed, + conventionResultTitle, dataDescription, - firstFailingData.Select(FormatData).ToArray())); + conventionFailingData.Select(FormatData).ToArray())); conventionResults.Add(new ResultInfo( - secondFailingData.None() ? TestResult.Passed : TestResult.Failed, - secondResultTitle, + inverseFailingData.None() ? TestResult.Passed : TestResult.Failed, + inverseResultTitle, dataDescription, - secondFailingData.Select(FormatData).ToArray())); + inverseFailingData.Select(FormatData).ToArray())); + } + + public void IsSymmetric(string conventionResultTitle, string inverseResultTitle, + Func isInclusiveData, Func dataConformsToConvention, + IEnumerable allData) + { + var conventionFailingData = allData.Where(isInclusiveData).Where(d => !dataConformsToConvention(d)); + var inverseFailingData = allData.Where(d => !isInclusiveData(d)).Where(dataConformsToConvention); + + IsSymmetric( + conventionResultTitle, conventionFailingData, + inverseResultTitle, inverseFailingData); } static ConventionReportFailure FormatData(T failingData) @@ -51,7 +64,11 @@ static ConventionReportFailure FormatData(T failingData) var formatter = Convention.Formatters.FirstOrDefault(f => f.CanFormat(failingData)); if (formatter == null) - throw new NoDataFormatterFoundException(typeof(T).Name + " has no formatter, add one with `Convention.Formatters.Add(new MyDataFormatter());`"); + { + throw new NoDataFormatterFoundException( + typeof (T).Name + + " has no formatter, add one with `Convention.Formatters.Add(new MyDataFormatter());`"); + } return formatter.Format(failingData); } From 7e89f5275473b4cc1c0363939254fa0aa229cbe8 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Tue, 13 Aug 2013 17:13:34 +0100 Subject: [PATCH 3/3] Renamed to follow sets idea --- .../IConventionResult.cs | 20 +++++++++++-------- .../Internal/ConventionResult.cs | 15 ++++++++------ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/TestStack.ConventionTests/IConventionResult.cs b/TestStack.ConventionTests/IConventionResult.cs index d305ebb..9442528 100644 --- a/TestStack.ConventionTests/IConventionResult.cs +++ b/TestStack.ConventionTests/IConventionResult.cs @@ -27,16 +27,20 @@ void IsSymmetric( /// All dto's live in Project.Dto namespace AND Only dto's live in Project.Dto /// This means if a DTO is outside of Project.Dto, the test will fail, /// and if a non-dto is in Project.Dto the test will also fail + /// + /// This overload allows you to work with sets, see .... /// /// The data type the convention is applied to - /// Title of the convention, i.e Dto's must live in Project.Dto namespace - /// The inverse scenario title, i.e Non-dtos must not live inside Project.Dto namespace - /// Predicate describing if the data is included, for example, t => t.Name.EndsWith("Dto") - /// - /// Predicate describing the convention, for example, t => - /// t.NameSpace.StartsWith("Project.Dto") - /// + /// Title of the convention, i.e Dto's must live in Project.Dto namespace + /// The inverse scenario title, i.e Non-dtos must not live inside Project.Dto namespace /// All data, for dto example, all types in the project, not just dto's - void IsSymmetric(string conventionResultTitle, string inverseResultTitle, Func isInclusiveData, Func dataConformsToConvention, IEnumerable allData); + /// Predicate defining data which is in the first set + /// Predicate defining data which is in the second set + void IsSymmetric( + string firstSetFailureTitle, + string secondSetFailureTitle, + Func isPartOfFirstSet, + Func isPartOfSecondSet, + IEnumerable allData); } } \ No newline at end of file diff --git a/TestStack.ConventionTests/Internal/ConventionResult.cs b/TestStack.ConventionTests/Internal/ConventionResult.cs index 10b3b78..53d1112 100644 --- a/TestStack.ConventionTests/Internal/ConventionResult.cs +++ b/TestStack.ConventionTests/Internal/ConventionResult.cs @@ -47,16 +47,19 @@ public void IsSymmetric( inverseFailingData.Select(FormatData).ToArray())); } - public void IsSymmetric(string conventionResultTitle, string inverseResultTitle, - Func isInclusiveData, Func dataConformsToConvention, + public void IsSymmetric( + string firstSetFailureTitle, + string secondSetFailureTitle, + Func isPartOfFirstSet, + Func isPartOfSecondSet, IEnumerable allData) { - var conventionFailingData = allData.Where(isInclusiveData).Where(d => !dataConformsToConvention(d)); - var inverseFailingData = allData.Where(d => !isInclusiveData(d)).Where(dataConformsToConvention); + var firstSetFailingData = allData.Where(isPartOfFirstSet).Where(d => !isPartOfSecondSet(d)); + var secondSetFailingData = allData.Where(d => !isPartOfFirstSet(d)).Where(isPartOfSecondSet); IsSymmetric( - conventionResultTitle, conventionFailingData, - inverseResultTitle, inverseFailingData); + firstSetFailureTitle, firstSetFailingData, + secondSetFailureTitle, secondSetFailingData); } static ConventionReportFailure FormatData(T failingData)