diff --git a/Build/_build.csproj.DotSettings b/Build/_build.csproj.DotSettings index 9aac7d8..28494fb 100644 --- a/Build/_build.csproj.DotSettings +++ b/Build/_build.csproj.DotSettings @@ -13,6 +13,8 @@ False <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></Policy> True True True @@ -21,4 +23,5 @@ True True True - True + True + True diff --git a/Directory.Build.props b/Directory.Build.props index ad74a50..2117787 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -3,6 +3,7 @@ 11.0 false true + NU1901; NU1902; NU1903; NU1904 @@ -30,11 +31,11 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/FluentAssertions.DataSets.sln.DotSettings b/FluentAssertions.DataSets.sln.DotSettings index 692c8c6..8e755b4 100644 --- a/FluentAssertions.DataSets.sln.DotSettings +++ b/FluentAssertions.DataSets.sln.DotSettings @@ -104,6 +104,8 @@ UseExplicitType <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /></Policy> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> @@ -154,6 +156,7 @@ True True True + True D:\Workspaces\FluentAssertions\Default.testsettings 4 False diff --git a/Src/FluentAssertions.DataSets/AssertionExtensions.cs b/Src/FluentAssertions.DataSets/AssertionExtensions.cs index 895a7e8..aa7ccf8 100644 --- a/Src/FluentAssertions.DataSets/AssertionExtensions.cs +++ b/Src/FluentAssertions.DataSets/AssertionExtensions.cs @@ -3,6 +3,7 @@ using FluentAssertions.Collections; using FluentAssertions.DataSets; using FluentAssertions.DataSets.Common; +using FluentAssertions.Execution; using JetBrains.Annotations; // ReSharper disable once CheckNamespace @@ -21,7 +22,7 @@ public static class AssertionExtensions public static GenericCollectionAssertions Should(this DataTableCollection actualValue) { return new GenericCollectionAssertions( - ReadOnlyNonGenericCollectionWrapper.Create(actualValue)); + ReadOnlyNonGenericCollectionWrapper.Create(actualValue), AssertionChain.GetOrCreate()); } /// @@ -31,7 +32,7 @@ public static GenericCollectionAssertions Should(this DataTableCollec public static GenericCollectionAssertions Should(this DataColumnCollection actualValue) { return new GenericCollectionAssertions( - ReadOnlyNonGenericCollectionWrapper.Create(actualValue)); + ReadOnlyNonGenericCollectionWrapper.Create(actualValue), AssertionChain.GetOrCreate()); } /// @@ -41,7 +42,7 @@ public static GenericCollectionAssertions Should(this DataColumnColl public static GenericCollectionAssertions Should(this DataRowCollection actualValue) { return new GenericCollectionAssertions( - ReadOnlyNonGenericCollectionWrapper.Create(actualValue)); + ReadOnlyNonGenericCollectionWrapper.Create(actualValue), AssertionChain.GetOrCreate()); } /// @@ -51,6 +52,6 @@ public static GenericCollectionAssertions Should(this DataRowCollection [Pure] public static DataColumnAssertions Should(this DataColumn actualValue) { - return new DataColumnAssertions(actualValue); + return new DataColumnAssertions(actualValue, AssertionChain.GetOrCreate()); } } diff --git a/Src/FluentAssertions.DataSets/Common/AssertionChainExtensions.cs b/Src/FluentAssertions.DataSets/Common/AssertionChainExtensions.cs new file mode 100644 index 0000000..97b756d --- /dev/null +++ b/Src/FluentAssertions.DataSets/Common/AssertionChainExtensions.cs @@ -0,0 +1,20 @@ +using FluentAssertions.Equivalency; +using FluentAssertions.Execution; + +namespace FluentAssertions.DataSets.Common; + +internal static class AssertionChainExtensions +{ + /// + /// Updates the with the relevant information from the current , including the correct + /// caller identification path. + /// + public static AssertionChain For(this AssertionChain chain, IEquivalencyValidationContext context) + { + chain.OverrideCallerIdentifier(() => context.CurrentNode.Description); + + return chain + .WithReportable("configuration", () => context.Options.ToString()) + .BecauseOf(context.Reason); + } +} diff --git a/Src/FluentAssertions.DataSets/DataColumnAssertions.cs b/Src/FluentAssertions.DataSets/DataColumnAssertions.cs index 42eea7d..4658faf 100644 --- a/Src/FluentAssertions.DataSets/DataColumnAssertions.cs +++ b/Src/FluentAssertions.DataSets/DataColumnAssertions.cs @@ -2,7 +2,6 @@ using System.Data; using System.Diagnostics; using FluentAssertions.DataSets.Common; -using FluentAssertions.Equivalency; using FluentAssertions.Execution; using FluentAssertions.Primitives; @@ -15,8 +14,8 @@ namespace FluentAssertions.DataSets; [DebuggerNonUserCode] public class DataColumnAssertions : ReferenceTypeAssertions { - public DataColumnAssertions(DataColumn dataColumn) - : base(dataColumn) + public DataColumnAssertions(DataColumn dataColumn, AssertionChain assertionChain) + : base(dataColumn, assertionChain) { } @@ -120,23 +119,9 @@ public AndConstraint BeEquivalentTo(DataColumn expectation Guard.ThrowIfArgumentIsNull(config); var defaults = new DataEquivalencyAssertionOptions(AssertionOptions.CloneDefaults()); - IDataEquivalencyAssertionOptions options = config(defaults); + config(defaults); - var context = - new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), options) - { - Reason = new Reason(because, becauseArgs), - TraceWriter = options.TraceWriter - }; - - var comparands = new Comparands - { - Subject = Subject, - Expectation = expectation, - CompileTimeType = typeof(DataColumn) - }; - - new EquivalencyValidator().AssertEquality(comparands, context); + ((object)Subject).Should().BeEquivalentTo(expectation, _ => defaults, because, becauseArgs); return new AndConstraint(this); } diff --git a/Src/FluentAssertions.DataSets/DataColumnCollectionAssertionExtensions.cs b/Src/FluentAssertions.DataSets/DataColumnCollectionAssertionExtensions.cs index dfa7439..c49a5c9 100644 --- a/Src/FluentAssertions.DataSets/DataColumnCollectionAssertionExtensions.cs +++ b/Src/FluentAssertions.DataSets/DataColumnCollectionAssertionExtensions.cs @@ -4,7 +4,6 @@ using FluentAssertions.Collections; using FluentAssertions.DataSets; using FluentAssertions.DataSets.Common; -using FluentAssertions.Execution; // ReSharper disable once CheckNamespace namespace FluentAssertions; @@ -35,7 +34,7 @@ public static AndConstraint> BeSameAs( { var actualSubject = wrapper.UnderlyingCollection; - Execute.Assertion + assertion.CurrentAssertionChain .UsingLineBreaks .ForCondition(ReferenceEquals(actualSubject, expected)) .BecauseOf(because, becauseArgs) @@ -45,7 +44,7 @@ public static AndConstraint> BeSameAs( } else { - Execute.Assertion + assertion.CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith( "Invalid expectation: Expected {context:column collection} to refer to an instance of " + @@ -80,7 +79,7 @@ public static AndConstraint> NotBeSameAs { var actualSubject = wrapper.UnderlyingCollection; - Execute.Assertion + assertion.CurrentAssertionChain .UsingLineBreaks .ForCondition(!ReferenceEquals(actualSubject, unexpected)) .BecauseOf(because, becauseArgs) @@ -88,7 +87,7 @@ public static AndConstraint> NotBeSameAs } else { - Execute.Assertion + assertion.CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith( "Invalid expectation: Expected {context:column collection} to refer to a different instance of " + @@ -119,18 +118,16 @@ public static AndConstraint> HaveSameCou Guard.ThrowIfArgumentIsNull( otherCollection, nameof(otherCollection), "Cannot verify count against a collection."); - Execute.Assertion + assertion.CurrentAssertionChain .BecauseOf(because, becauseArgs) - .WithExpectation("Expected {context:collection} to have ") - .Given(() => assertion.Subject) - .ForCondition(subject => subject is not null) - .FailWith("the same count as {0}{reason}, but found .", otherCollection) - .Then - .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) - .ForCondition(count => count.actual == count.expected) - .FailWith("{0} column(s){reason}, but found {1}.", count => count.expected, count => count.actual) - .Then - .ClearExpectation(); + .WithExpectation("Expected {context:collection} to have ", chain => chain + .Given(() => assertion.Subject) + .ForCondition(subject => subject is not null) + .FailWith("the same count as {0}{reason}, but found .", otherCollection) + .Then + .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) + .ForCondition(count => count.actual == count.expected) + .FailWith("{0} column(s){reason}, but found {1}.", count => count.expected, count => count.actual)); return new AndConstraint>(assertion); } @@ -157,18 +154,16 @@ public static AndConstraint> NotHaveSame Guard.ThrowIfArgumentIsNull( otherCollection, nameof(otherCollection), "Cannot verify count against a collection."); - Execute.Assertion + assertion.CurrentAssertionChain .BecauseOf(because, becauseArgs) - .WithExpectation("Expected {context:collection} to not have ") - .Given(() => assertion.Subject) - .ForCondition(subject => subject is not null) - .FailWith("the same count as {0}{reason}, but found .", otherCollection) - .Then - .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) - .ForCondition(count => count.actual != count.expected) - .FailWith("{0} column(s){reason}, but found {1}.", count => count.expected, count => count.actual) - .Then - .ClearExpectation(); + .WithExpectation("Expected {context:collection} to not have ", chain => chain + .Given(() => assertion.Subject) + .ForCondition(subject => subject is not null) + .FailWith("the same count as {0}{reason}, but found .", otherCollection) + .Then + .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) + .ForCondition(count => count.actual != count.expected) + .FailWith("{0} column(s){reason}, but found {1}.", count => count.expected, count => count.actual)); return new AndConstraint>(assertion); } diff --git a/Src/FluentAssertions.DataSets/DataEquivalencyAssertionOptions.cs b/Src/FluentAssertions.DataSets/DataEquivalencyAssertionOptions.cs index 4eb482f..9ecf95f 100644 --- a/Src/FluentAssertions.DataSets/DataEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions.DataSets/DataEquivalencyAssertionOptions.cs @@ -7,7 +7,7 @@ namespace FluentAssertions.DataSets; -internal class DataEquivalencyAssertionOptions : EquivalencyAssertionOptions, IDataEquivalencyAssertionOptions +internal class DataEquivalencyAssertionOptions : EquivalencyOptions, IDataEquivalencyAssertionOptions { private readonly HashSet excludeTableNames = new(); private readonly HashSet excludeColumnNames = new(); @@ -25,7 +25,7 @@ internal class DataEquivalencyAssertionOptions : EquivalencyAssertionOptions< public ISet ExcludeColumnNames => excludeColumnNames; - public DataEquivalencyAssertionOptions(EquivalencyAssertionOptions defaults) + public DataEquivalencyAssertionOptions(EquivalencyOptions defaults) : base(defaults) { } diff --git a/Src/FluentAssertions.DataSets/DataRowAssertionExtensions.cs b/Src/FluentAssertions.DataSets/DataRowAssertionExtensions.cs index af98bd3..fe073ad 100644 --- a/Src/FluentAssertions.DataSets/DataRowAssertionExtensions.cs +++ b/Src/FluentAssertions.DataSets/DataRowAssertionExtensions.cs @@ -1,6 +1,7 @@ using System.Data; using System.Diagnostics; using FluentAssertions.DataSets; +using FluentAssertions.Execution; using JetBrains.Annotations; // ReSharper disable once CheckNamespace @@ -20,6 +21,6 @@ public static class DataRowAssertionExtensions public static DataRowAssertions Should(this TDataRow actualValue) where TDataRow : DataRow { - return new DataRowAssertions(actualValue); + return new DataRowAssertions(actualValue, AssertionChain.GetOrCreate()); } } diff --git a/Src/FluentAssertions.DataSets/DataRowAssertions.cs b/Src/FluentAssertions.DataSets/DataRowAssertions.cs index 09b3dd7..94e49ae 100644 --- a/Src/FluentAssertions.DataSets/DataRowAssertions.cs +++ b/Src/FluentAssertions.DataSets/DataRowAssertions.cs @@ -18,8 +18,8 @@ namespace FluentAssertions.DataSets; public class DataRowAssertions : ReferenceTypeAssertions> where TDataRow : DataRow { - public DataRowAssertions(TDataRow dataRow) - : base(dataRow) + public DataRowAssertions(TDataRow dataRow, AssertionChain assertionChain) + : base(dataRow, assertionChain) { } @@ -41,14 +41,14 @@ public AndWhichConstraint, DataColumn> HaveColumn(st if (Subject is null) { - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataRow} to contain a column named {0}{reason}, but found .", expectedColumnName); } else if (!Subject.Table.Columns.Contains(expectedColumnName)) { - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataRow} to contain a column named {0}{reason}, but it does not.", expectedColumnName); @@ -84,18 +84,18 @@ public AndConstraint> HaveColumns(params string[] ex public AndConstraint> HaveColumns(IEnumerable expectedColumnNames, string because = "", params object[] becauseArgs) { - bool success = Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith( "Expected {context:DataRow} to be in a table containing {0} column(s) with specific names{reason}, but found .", () => expectedColumnNames.Count()); - if (success) + if (CurrentAssertionChain.Succeeded) { foreach (var expectedColumnName in expectedColumnNames) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject.Table.Columns.Contains(expectedColumnName)) .BecauseOf(because, becauseArgs) .FailWith("Expected table containing {context:DataRow} to contain a column named {0}{reason}, but it does not.", @@ -192,22 +192,9 @@ public AndConstraint> BeEquivalentTo(DataRow expecta Guard.ThrowIfArgumentIsNull(config); var defaults = new DataEquivalencyAssertionOptions(AssertionOptions.CloneDefaults()); - IDataEquivalencyAssertionOptions options = config(defaults); + config(defaults); - var context = new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), options) - { - Reason = new Reason(because, becauseArgs), - TraceWriter = options.TraceWriter - }; - - var comparands = new Comparands - { - Subject = Subject, - Expectation = expectation, - CompileTimeType = typeof(TDataRow), - }; - - new EquivalencyValidator().AssertEquality(comparands, context); + ((object)Subject).Should().BeEquivalentTo(expectation, _ => defaults, because, becauseArgs); return new AndConstraint>(this); } diff --git a/Src/FluentAssertions.DataSets/DataRowCollectionAssertionExtensions.cs b/Src/FluentAssertions.DataSets/DataRowCollectionAssertionExtensions.cs index c25bf84..8c4a67d 100644 --- a/Src/FluentAssertions.DataSets/DataRowCollectionAssertionExtensions.cs +++ b/Src/FluentAssertions.DataSets/DataRowCollectionAssertionExtensions.cs @@ -4,7 +4,6 @@ using FluentAssertions.Collections; using FluentAssertions.DataSets; using FluentAssertions.DataSets.Common; -using FluentAssertions.Execution; // ReSharper disable once CheckNamespace namespace FluentAssertions; @@ -30,7 +29,7 @@ public static AndConstraint> BeSameAs( { var actualSubject = wrapper.UnderlyingCollection; - Execute.Assertion + assertion.CurrentAssertionChain .UsingLineBreaks .ForCondition(ReferenceEquals(actualSubject, expected)) .BecauseOf(because, becauseArgs) @@ -40,7 +39,7 @@ public static AndConstraint> BeSameAs( } else { - Execute.Assertion + assertion.CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith( "Invalid expectation: Expected {context:column collection} to refer to an instance of " + @@ -70,7 +69,7 @@ public static AndConstraint> NotBeSameAs( { var actualSubject = wrapper.UnderlyingCollection; - Execute.Assertion + assertion.CurrentAssertionChain .UsingLineBreaks .ForCondition(!ReferenceEquals(actualSubject, unexpected)) .BecauseOf(because, becauseArgs) @@ -78,7 +77,7 @@ public static AndConstraint> NotBeSameAs( } else { - Execute.Assertion + assertion.CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith( "Invalid expectation: Expected {context:column collection} to refer to a different instance of " + @@ -109,18 +108,16 @@ public static AndConstraint> HaveSameCount( Guard.ThrowIfArgumentIsNull( otherCollection, nameof(otherCollection), "Cannot verify count against a collection."); - Execute.Assertion + assertion.CurrentAssertionChain .BecauseOf(because, becauseArgs) - .WithExpectation("Expected {context:collection} to have ") - .Given(() => assertion.Subject) - .ForCondition(subject => subject is not null) - .FailWith("the same count as {0}{reason}, but found .", otherCollection) - .Then - .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) - .ForCondition(count => count.actual == count.expected) - .FailWith("{0} row(s){reason}, but found {1}.", count => count.expected, count => count.actual) - .Then - .ClearExpectation(); + .WithExpectation("Expected {context:collection} to have ", chain => chain + .Given(() => assertion.Subject) + .ForCondition(subject => subject is not null) + .FailWith("the same count as {0}{reason}, but found .", otherCollection) + .Then + .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) + .ForCondition(count => count.actual == count.expected) + .FailWith("{0} row(s){reason}, but found {1}.", count => count.expected, count => count.actual)); return new AndConstraint>(assertion); } @@ -145,18 +142,16 @@ public static AndConstraint> NotHaveSameCou Guard.ThrowIfArgumentIsNull( otherCollection, nameof(otherCollection), "Cannot verify count against a collection."); - Execute.Assertion + assertion.CurrentAssertionChain .BecauseOf(because, becauseArgs) - .WithExpectation("Expected {context:collection} to not have ") - .Given(() => assertion.Subject) - .ForCondition(subject => subject is not null) - .FailWith("the same count as {0}{reason}, but found .", otherCollection) - .Then - .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) - .ForCondition(count => count.actual != count.expected) - .FailWith("{0} row(s){reason}, but found {1}.", count => count.expected, count => count.actual) - .Then - .ClearExpectation(); + .WithExpectation("Expected {context:collection} to not have ", chain => chain + .Given(() => assertion.Subject) + .ForCondition(subject => subject is not null) + .FailWith("the same count as {0}{reason}, but found .", otherCollection) + .Then + .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) + .ForCondition(count => count.actual != count.expected) + .FailWith("{0} row(s){reason}, but found {1}.", count => count.expected, count => count.actual)); return new AndConstraint>(assertion); } diff --git a/Src/FluentAssertions.DataSets/DataSetAssertionExtensions.cs b/Src/FluentAssertions.DataSets/DataSetAssertionExtensions.cs index db38a35..c474005 100644 --- a/Src/FluentAssertions.DataSets/DataSetAssertionExtensions.cs +++ b/Src/FluentAssertions.DataSets/DataSetAssertionExtensions.cs @@ -1,6 +1,7 @@ using System.Data; using System.Diagnostics; using FluentAssertions.DataSets; +using FluentAssertions.Execution; using JetBrains.Annotations; namespace FluentAssertions; @@ -19,6 +20,6 @@ public static class DataSetAssertionExtensions public static DataSetAssertions Should(this TDataSet actualValue) where TDataSet : DataSet { - return new DataSetAssertions(actualValue); + return new DataSetAssertions(actualValue, AssertionChain.GetOrCreate()); } } diff --git a/Src/FluentAssertions.DataSets/DataSetAssertions.cs b/Src/FluentAssertions.DataSets/DataSetAssertions.cs index 0aa44f1..31ba8fd 100644 --- a/Src/FluentAssertions.DataSets/DataSetAssertions.cs +++ b/Src/FluentAssertions.DataSets/DataSetAssertions.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using System.Linq; using FluentAssertions.DataSets.Common; -using FluentAssertions.Equivalency; using FluentAssertions.Execution; using FluentAssertions.Primitives; @@ -18,8 +17,8 @@ namespace FluentAssertions.DataSets; public class DataSetAssertions : ReferenceTypeAssertions> where TDataSet : DataSet { - public DataSetAssertions(TDataSet dataSet) - : base(dataSet) + public DataSetAssertions(TDataSet dataSet, AssertionChain assertionChain) + : base(dataSet, assertionChain) { } @@ -37,16 +36,16 @@ public DataSetAssertions(TDataSet dataSet) public AndConstraint> HaveTableCount(int expected, string because = "", params object[] becauseArgs) { - bool success = Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataSet} to contain exactly {0} table(s){reason}, but found .", expected); - if (success) + if (CurrentAssertionChain.Succeeded) { int actualCount = Subject.Tables.Count; - Execute.Assertion + CurrentAssertionChain .ForCondition(actualCount == expected) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataSet} to contain exactly {0} table(s){reason}, but found {1}.", expected, @@ -74,14 +73,14 @@ public AndWhichConstraint, DataTable> HaveTable(stri if (Subject is null) { - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataSet} to contain a table named {0}{reason}, but found .", expectedTableName); } else if (!Subject.Tables.Contains(expectedTableName)) { - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataSet} to contain a table named {0}{reason}, but it does not.", expectedTableName); } @@ -116,17 +115,17 @@ public AndConstraint> HaveTables(params string[] exp public AndConstraint> HaveTables(IEnumerable expectedTableNames, string because = "", params object[] becauseArgs) { - bool success = Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataSet} to contain {0} table(s) with specific names{reason}, but found .", () => expectedTableNames.Count()); - if (success) + if (CurrentAssertionChain.Succeeded) { foreach (var expectedTableName in expectedTableNames) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject.Tables.Contains(expectedTableName)) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataSet} to contain a table named {0}{reason}, but it does not.", expectedTableName); @@ -246,23 +245,9 @@ public AndConstraint> BeEquivalentTo(DataSet expecta Guard.ThrowIfArgumentIsNull(config); var defaults = new DataEquivalencyAssertionOptions(AssertionOptions.CloneDefaults()); - IDataEquivalencyAssertionOptions options = config(defaults); + config(defaults); - var comparands = new Comparands - { - Subject = Subject, - Expectation = expectation, - CompileTimeType = typeof(TDataSet) - }; - - var context = new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), options) - { - Reason = new Reason(because, becauseArgs), - TraceWriter = options.TraceWriter, - }; - - var equivalencyValidator = new EquivalencyValidator(); - equivalencyValidator.AssertEquality(comparands, context); + ((object)Subject).Should().BeEquivalentTo(expectation, _ => defaults, because, becauseArgs); return new AndConstraint>(this); } diff --git a/Src/FluentAssertions.DataSets/DataTableAssertionExtensions.cs b/Src/FluentAssertions.DataSets/DataTableAssertionExtensions.cs index b4e080c..93efbf7 100644 --- a/Src/FluentAssertions.DataSets/DataTableAssertionExtensions.cs +++ b/Src/FluentAssertions.DataSets/DataTableAssertionExtensions.cs @@ -1,6 +1,7 @@ using System.Data; using System.Diagnostics; using FluentAssertions.DataSets; +using FluentAssertions.Execution; using JetBrains.Annotations; // ReSharper disable once CheckNamespace @@ -20,6 +21,6 @@ public static class DataTableAssertionExtensions public static DataTableAssertions Should(this TDataTable actualValue) where TDataTable : DataTable { - return new DataTableAssertions(actualValue); + return new DataTableAssertions(actualValue, AssertionChain.GetOrCreate()); } } diff --git a/Src/FluentAssertions.DataSets/DataTableAssertions.cs b/Src/FluentAssertions.DataSets/DataTableAssertions.cs index 80a8fda..134e979 100644 --- a/Src/FluentAssertions.DataSets/DataTableAssertions.cs +++ b/Src/FluentAssertions.DataSets/DataTableAssertions.cs @@ -18,8 +18,8 @@ namespace FluentAssertions.DataSets; public class DataTableAssertions : ReferenceTypeAssertions> where TDataTable : DataTable { - public DataTableAssertions(TDataTable dataTable) - : base(dataTable) + public DataTableAssertions(TDataTable dataTable, AssertionChain assertionChain) + : base(dataTable, assertionChain) { } @@ -37,16 +37,16 @@ public DataTableAssertions(TDataTable dataTable) public AndConstraint> HaveRowCount(int expected, string because = "", params object[] becauseArgs) { - bool success = Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataTable} to contain exactly {0} row(s){reason}, but found .", expected); - if (success) + if (CurrentAssertionChain.Succeeded) { int actualCount = Subject.Rows.Count; - Execute.Assertion + CurrentAssertionChain .ForCondition(actualCount == expected) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataTable} to contain exactly {0} row(s){reason}, but found {1}.", expected, @@ -74,14 +74,14 @@ public AndWhichConstraint, DataColumn> HaveColum if (Subject is null) { - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataTable} to contain a column named {0}{reason}, but found .", expectedColumnName); } else if (!Subject.Columns.Contains(expectedColumnName)) { - Execute.Assertion + CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataTable} to contain a column named {0}{reason}, but it does not.", expectedColumnName); @@ -117,17 +117,17 @@ public AndConstraint> HaveColumns(params string[ public AndConstraint> HaveColumns(IEnumerable expectedColumnNames, string because = "", params object[] becauseArgs) { - bool success = Execute.Assertion + CurrentAssertionChain .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataTable} to contain {0} column(s) with specific names{reason}, but found .", () => expectedColumnNames.Count()); - if (success) + if (CurrentAssertionChain.Succeeded) { foreach (var expectedColumnName in expectedColumnNames) { - Execute.Assertion + CurrentAssertionChain .ForCondition(Subject.Columns.Contains(expectedColumnName)) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:DataTable} to contain a column named {0}{reason}, but it does not.", @@ -259,22 +259,9 @@ public AndConstraint> BeEquivalentTo(DataTable e Guard.ThrowIfArgumentIsNull(config); var defaults = new DataEquivalencyAssertionOptions(AssertionOptions.CloneDefaults()); - IDataEquivalencyAssertionOptions options = config(defaults); + config(defaults); - var context = new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), options) - { - Reason = new Reason(because, becauseArgs), - TraceWriter = options.TraceWriter - }; - - var comparands = new Comparands - { - Subject = Subject, - Expectation = expectation, - CompileTimeType = typeof(TDataTable), - }; - - new EquivalencyValidator().AssertEquality(comparands, context); + ((object)Subject).Should().BeEquivalentTo(expectation, _ => defaults, because, becauseArgs); return new AndConstraint>(this); } diff --git a/Src/FluentAssertions.DataSets/DataTableCollectionAssertionExtensions.cs b/Src/FluentAssertions.DataSets/DataTableCollectionAssertionExtensions.cs index 95fb273..ccaaad5 100644 --- a/Src/FluentAssertions.DataSets/DataTableCollectionAssertionExtensions.cs +++ b/Src/FluentAssertions.DataSets/DataTableCollectionAssertionExtensions.cs @@ -30,7 +30,7 @@ public static AndConstraint> BeSameAs( { var actualSubject = wrapper.UnderlyingCollection; - Execute.Assertion + assertion.CurrentAssertionChain .UsingLineBreaks .ForCondition(ReferenceEquals(actualSubject, expected)) .BecauseOf(because, becauseArgs) @@ -40,7 +40,7 @@ public static AndConstraint> BeSameAs( } else { - Execute.Assertion + assertion.CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith( "Invalid expectation: Expected {context:column collection} to refer to an instance of " + @@ -70,7 +70,7 @@ public static AndConstraint> NotBeSameAs( { var actualSubject = wrapper.UnderlyingCollection; - Execute.Assertion + assertion.CurrentAssertionChain .UsingLineBreaks .ForCondition(!ReferenceEquals(actualSubject, unexpected)) .BecauseOf(because, becauseArgs) @@ -78,7 +78,7 @@ public static AndConstraint> NotBeSameAs( } else { - Execute.Assertion + assertion.CurrentAssertionChain .BecauseOf(because, becauseArgs) .FailWith( "Invalid expectation: Expected {context:column collection} to refer to a different instance of " + @@ -147,18 +147,16 @@ public static AndConstraint> HaveSameCoun Guard.ThrowIfArgumentIsNull( otherCollection, nameof(otherCollection), "Cannot verify count against a collection."); - Execute.Assertion + assertion.CurrentAssertionChain .BecauseOf(because, becauseArgs) - .WithExpectation("Expected {context:collection} to have ") + .WithExpectation("Expected {context:collection} to have ", chain => chain .Given(() => assertion.Subject) .ForCondition(subject => subject is not null) .FailWith("the same count as {0}{reason}, but found .", otherCollection) .Then .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) .ForCondition(count => count.actual == count.expected) - .FailWith("{0} table(s){reason}, but found {1}.", count => count.expected, count => count.actual) - .Then - .ClearExpectation(); + .FailWith("{0} table(s){reason}, but found {1}.", count => count.expected, count => count.actual)); return new AndConstraint>(assertion); } @@ -183,18 +181,16 @@ public static AndConstraint> NotHaveSameC Guard.ThrowIfArgumentIsNull( otherCollection, nameof(otherCollection), "Cannot verify count against a collection."); - Execute.Assertion + assertion.CurrentAssertionChain .BecauseOf(because, becauseArgs) - .WithExpectation("Expected {context:collection} to not have ") + .WithExpectation("Expected {context:collection} to not have ", chain => chain .Given(() => assertion.Subject) .ForCondition(subject => subject is not null) .FailWith("the same count as {0}{reason}, but found .", otherCollection) .Then .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) .ForCondition(count => count.actual != count.expected) - .FailWith("{0} table(s){reason}, but found {1}.", count => count.expected, count => count.actual) - .Then - .ClearExpectation(); + .FailWith("{0} table(s){reason}, but found {1}.", count => count.expected, count => count.actual)); return new AndConstraint>(assertion); } diff --git a/Src/FluentAssertions.DataSets/Equivalency/ConstraintCollectionEquivalencyStep.cs b/Src/FluentAssertions.DataSets/Equivalency/ConstraintCollectionEquivalencyStep.cs index 01308de..f817575 100644 --- a/Src/FluentAssertions.DataSets/Equivalency/ConstraintCollectionEquivalencyStep.cs +++ b/Src/FluentAssertions.DataSets/Equivalency/ConstraintCollectionEquivalencyStep.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; +using FluentAssertions.DataSets.Common; using FluentAssertions.Equivalency; using FluentAssertions.Execution; @@ -9,11 +10,13 @@ namespace FluentAssertions.DataSets.Equivalency; public class ConstraintCollectionEquivalencyStep : EquivalencyStep { protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, - IEquivalencyValidator nestedValidator) + IValidateChildNodeEquivalency nestedValidator) { + var assertionChain = AssertionChain.GetOrCreate().For(context); + if (comparands.Subject is not ConstraintCollection) { - AssertionScope.Current + assertionChain .FailWith("Expected a value of type ConstraintCollection at {context:Constraints}, but found {0}", comparands.Subject.GetType()); } @@ -29,12 +32,12 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc foreach (var constraintName in constraintNames) { - AssertionScope.Current + assertionChain .ForCondition(subjectConstraints.TryGetValue(constraintName, out Constraint subjectConstraint)) .FailWith("Expected constraint named {0} in {context:Constraints collection}{reason}, but did not find one", constraintName); - AssertionScope.Current + assertionChain .ForCondition(expectationConstraints.TryGetValue(constraintName, out Constraint expectationConstraint)) .FailWith("Found unexpected constraint named {0} in {context:Constraints collection}", constraintName); @@ -48,11 +51,11 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc }; IEquivalencyValidationContext nestedContext = context.AsCollectionItem(constraintName); - nestedValidator.RecursivelyAssertEquality(newComparands, nestedContext); + nestedValidator.AssertEquivalencyOf(newComparands, nestedContext); } } } - return EquivalencyResult.AssertionCompleted; + return EquivalencyResult.EquivalencyProven; } } diff --git a/Src/FluentAssertions.DataSets/Equivalency/ConstraintEquivalencyStep.cs b/Src/FluentAssertions.DataSets/Equivalency/ConstraintEquivalencyStep.cs index ec08234..c86df19 100644 --- a/Src/FluentAssertions.DataSets/Equivalency/ConstraintEquivalencyStep.cs +++ b/Src/FluentAssertions.DataSets/Equivalency/ConstraintEquivalencyStep.cs @@ -12,11 +12,13 @@ namespace FluentAssertions.DataSets.Equivalency; public class ConstraintEquivalencyStep : EquivalencyStep { protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, - IEquivalencyValidator nestedValidator) + IValidateChildNodeEquivalency nestedValidator) { + var assertionChain = AssertionChain.GetOrCreate().For(context); + if (comparands.Subject is not Constraint) { - AssertionScope.Current + assertionChain .FailWith("Expected {context:constraint} to be a value of type Constraint, but found {0}", comparands.Subject.GetType()); } @@ -28,11 +30,11 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc var selectedMembers = GetMembersFromExpectation(comparands, context.CurrentNode, context.Options) .ToDictionary(member => member.Name); - CompareCommonProperties(context, nestedValidator, context.Options, subject, expectation, selectedMembers); + CompareCommonProperties(context, nestedValidator, context.Options, subject, expectation, selectedMembers, assertionChain); bool matchingType = subject.GetType() == expectation.GetType(); - AssertionScope.Current + assertionChain .ForCondition(matchingType) .FailWith("Expected {context:constraint} to be of type {0}, but found {1}", expectation.GetType(), subject.GetType()); @@ -43,32 +45,32 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc && expectation is UniqueConstraint expectationUniqueConstraint) { CompareConstraints(nestedValidator, context, subjectUniqueConstraint, expectationUniqueConstraint, - selectedMembers); + selectedMembers, assertionChain); } else if (subject is ForeignKeyConstraint subjectForeignKeyConstraint && expectation is ForeignKeyConstraint expectationForeignKeyConstraint) { CompareConstraints(nestedValidator, context, subjectForeignKeyConstraint, expectationForeignKeyConstraint, - selectedMembers); + selectedMembers, assertionChain); } else { - AssertionScope.Current + assertionChain .FailWith("Don't know how to handle {constraint:a Constraint} of type {0}", subject.GetType()); } } } - return EquivalencyResult.AssertionCompleted; + return EquivalencyResult.EquivalencyProven; } - private static void CompareCommonProperties(IEquivalencyValidationContext context, IEquivalencyValidator parent, - IEquivalencyAssertionOptions options, Constraint subject, Constraint expectation, - Dictionary selectedMembers) + private static void CompareCommonProperties(IEquivalencyValidationContext context, IValidateChildNodeEquivalency parent, + IEquivalencyOptions options, Constraint subject, Constraint expectation, + Dictionary selectedMembers, AssertionChain assertionChain) { if (selectedMembers.ContainsKey("ConstraintName")) { - AssertionScope.Current + assertionChain .ForCondition(subject.ConstraintName == expectation.ConstraintName) .FailWith("Expected {context:constraint} to have a ConstraintName of {0}{reason}, but found {1}", expectation.ConstraintName, subject.ConstraintName); @@ -76,7 +78,7 @@ private static void CompareCommonProperties(IEquivalencyValidationContext contex if (selectedMembers.ContainsKey("Table")) { - AssertionScope.Current + assertionChain .ForCondition(subject.Table.TableName == expectation.Table.TableName) .FailWith( "Expected {context:constraint} to be associated with a Table with TableName of {0}{reason}, but found {1}", @@ -85,7 +87,7 @@ private static void CompareCommonProperties(IEquivalencyValidationContext contex if (selectedMembers.TryGetValue("ExtendedProperties", out IMember expectationMember)) { - IMember matchingMember = FindMatchFor(expectationMember, context.CurrentNode, subject, options); + IMember matchingMember = FindMatchFor(expectationMember, context.CurrentNode, subject, options, assertionChain); if (matchingMember is not null) { @@ -96,20 +98,20 @@ private static void CompareCommonProperties(IEquivalencyValidationContext contex CompileTimeType = expectationMember.Type }; - parent.RecursivelyAssertEquality(nestedComparands, context.AsNestedMember(expectationMember)); + parent.AssertEquivalencyOf(nestedComparands, context.AsNestedMember(expectationMember)); } } } - private static void CompareConstraints(IEquivalencyValidator parent, IEquivalencyValidationContext context, - UniqueConstraint subject, UniqueConstraint expectation, Dictionary selectedMembers) + private static void CompareConstraints(IValidateChildNodeEquivalency parent, IEquivalencyValidationContext context, + UniqueConstraint subject, UniqueConstraint expectation, Dictionary selectedMembers, AssertionChain assertionChain) { - AssertionScope.Current + assertionChain .ForCondition(subject.ConstraintName == expectation.ConstraintName) .FailWith("Expected {context:constraint} to be named {0}{reason}, but found {1}", expectation.ConstraintName, subject.ConstraintName); - var nestedMember = new Property( + var nestedMember = MemberFactory.Create( typeof(Constraint).GetProperty(nameof(subject.ExtendedProperties)), context.CurrentNode); @@ -120,11 +122,11 @@ private static void CompareConstraints(IEquivalencyValidator parent, IEquivalenc CompileTimeType = nestedMember.Type }; - parent.RecursivelyAssertEquality(nestedComparands, context.AsNestedMember(nestedMember)); + parent.AssertEquivalencyOf(nestedComparands, context.AsNestedMember(nestedMember)); if (selectedMembers.ContainsKey(nameof(expectation.IsPrimaryKey))) { - AssertionScope.Current + assertionChain .ForCondition(subject.IsPrimaryKey == expectation.IsPrimaryKey) .FailWith("Expected {context:constraint} to be a {0} constraint{reason}, but found a {1} constraint", expectation.IsPrimaryKey ? "Primary Key" : "Foreign Key", @@ -133,20 +135,20 @@ private static void CompareConstraints(IEquivalencyValidator parent, IEquivalenc if (selectedMembers.ContainsKey(nameof(expectation.Columns))) { - CompareConstraintColumns(subject.Columns, expectation.Columns); + CompareConstraintColumns(subject.Columns, expectation.Columns, assertionChain); } } [SuppressMessage("Design", "MA0051:Method is too long", Justification = "Needs to be refactored")] - private static void CompareConstraints(IEquivalencyValidator parent, IEquivalencyValidationContext context, - ForeignKeyConstraint subject, ForeignKeyConstraint expectation, Dictionary selectedMembers) + private static void CompareConstraints(IValidateChildNodeEquivalency parent, IEquivalencyValidationContext context, + ForeignKeyConstraint subject, ForeignKeyConstraint expectation, Dictionary selectedMembers, AssertionChain assertionChain) { - AssertionScope.Current + assertionChain .ForCondition(subject.ConstraintName == expectation.ConstraintName) .FailWith("Expected {context:constraint} to be named {0}{reason}, but found {1}", expectation.ConstraintName, subject.ConstraintName); - var nestedMember = new Property( + var nestedMember = MemberFactory.Create( typeof(Constraint).GetProperty(nameof(subject.ExtendedProperties)), context.CurrentNode); @@ -157,11 +159,11 @@ private static void CompareConstraints(IEquivalencyValidator parent, IEquivalenc CompileTimeType = nestedMember.Type }; - parent.RecursivelyAssertEquality(nestedComparands, context.AsNestedMember(nestedMember)); + parent.AssertEquivalencyOf(nestedComparands, context.AsNestedMember(nestedMember)); if (selectedMembers.ContainsKey(nameof(expectation.RelatedTable))) { - AssertionScope.Current + assertionChain .ForCondition(subject.RelatedTable.TableName == expectation.RelatedTable.TableName) .FailWith("Expected {context:constraint} to have a related table named {0}{reason}, but found {1}", expectation.RelatedTable.TableName, subject.RelatedTable.TableName); @@ -169,7 +171,7 @@ private static void CompareConstraints(IEquivalencyValidator parent, IEquivalenc if (selectedMembers.ContainsKey(nameof(expectation.AcceptRejectRule))) { - AssertionScope.Current + assertionChain .ForCondition(subject.AcceptRejectRule == expectation.AcceptRejectRule) .FailWith( "Expected {context:constraint} to have AcceptRejectRule.{0}{reason}, but found AcceptRejectRule.{1}", @@ -178,7 +180,7 @@ private static void CompareConstraints(IEquivalencyValidator parent, IEquivalenc if (selectedMembers.ContainsKey(nameof(expectation.DeleteRule))) { - AssertionScope.Current + assertionChain .ForCondition(subject.DeleteRule == expectation.DeleteRule) .FailWith("Expected {context:constraint} to have DeleteRule Rule.{0}{reason}, but found Rule.{1}", expectation.DeleteRule, subject.DeleteRule); @@ -186,7 +188,7 @@ private static void CompareConstraints(IEquivalencyValidator parent, IEquivalenc if (selectedMembers.ContainsKey(nameof(expectation.UpdateRule))) { - AssertionScope.Current + assertionChain .ForCondition(subject.UpdateRule == expectation.UpdateRule) .FailWith("Expected {context:constraint} to have UpdateRule Rule.{0}{reason}, but found Rule.{1}", expectation.UpdateRule, subject.UpdateRule); @@ -194,16 +196,16 @@ private static void CompareConstraints(IEquivalencyValidator parent, IEquivalenc if (selectedMembers.ContainsKey(nameof(expectation.Columns))) { - CompareConstraintColumns(subject.Columns, expectation.Columns); + CompareConstraintColumns(subject.Columns, expectation.Columns, assertionChain); } if (selectedMembers.ContainsKey(nameof(expectation.RelatedColumns))) { - CompareConstraintColumns(subject.RelatedColumns, expectation.RelatedColumns); + CompareConstraintColumns(subject.RelatedColumns, expectation.RelatedColumns, assertionChain); } } - private static void CompareConstraintColumns(DataColumn[] subjectColumns, DataColumn[] expectationColumns) + private static void CompareConstraintColumns(DataColumn[] subjectColumns, DataColumn[] expectationColumns, AssertionChain assertionChain) { var subjectColumnNames = new HashSet(subjectColumns.Select(col => col.ColumnName)); var expectationColumnNames = new HashSet(expectationColumns.Select(col => col.ColumnName)); @@ -251,17 +253,17 @@ private static void CompareConstraintColumns(DataColumn[] subjectColumns, DataCo bool successful = failureMessage.Length == 0; - AssertionScope.Current + assertionChain .ForCondition(successful) .FailWith(failureMessage.ToString()); } private static IMember FindMatchFor(IMember selectedMemberInfo, INode currentNode, object subject, - IEquivalencyAssertionOptions config) + IEquivalencyOptions config, AssertionChain assertionChain) { IEnumerable query = from rule in config.MatchingRules - let match = rule.Match(selectedMemberInfo, subject, currentNode, config) + let match = rule.Match(selectedMemberInfo, subject, currentNode, config, assertionChain) where match is not null select match; @@ -269,7 +271,7 @@ where match is not null } private static IEnumerable GetMembersFromExpectation(Comparands comparands, INode currentNode, - IEquivalencyAssertionOptions options) + IEquivalencyOptions options) { IEnumerable members = Enumerable.Empty(); diff --git a/Src/FluentAssertions.DataSets/Equivalency/DataColumnEquivalencyStep.cs b/Src/FluentAssertions.DataSets/Equivalency/DataColumnEquivalencyStep.cs index b19366d..aa2942b 100644 --- a/Src/FluentAssertions.DataSets/Equivalency/DataColumnEquivalencyStep.cs +++ b/Src/FluentAssertions.DataSets/Equivalency/DataColumnEquivalencyStep.cs @@ -2,6 +2,7 @@ using System.Data; using System.Diagnostics.CodeAnalysis; using System.Linq; +using FluentAssertions.DataSets.Common; using FluentAssertions.Equivalency; using FluentAssertions.Execution; @@ -11,39 +12,40 @@ public class DataColumnEquivalencyStep : EquivalencyStep { [SuppressMessage("Style", "IDE0019:Use pattern matching", Justification = "The code is easier to read without it.")] protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, - IEquivalencyValidator nestedValidator) + IValidateChildNodeEquivalency nestedValidator) { + var assertionChain = AssertionChain.GetOrCreate().For(context); var subject = comparands.Subject as DataColumn; if (comparands.Expectation is not DataColumn expectation) { if (subject is not null) { - AssertionScope.Current.FailWith("Expected {context:DataColumn} value to be null, but found {0}", subject); + assertionChain.FailWith("Expected {context:DataColumn} value to be null, but found {0}", subject); } } else if (subject is null) { if (comparands.Subject is null) { - AssertionScope.Current.FailWith("Expected {context:DataColumn} to be non-null, but found null"); + assertionChain.FailWith("Expected {context:DataColumn} to be non-null, but found null"); } else { - AssertionScope.Current.FailWith("Expected {context:DataColumn} to be of type {0}, but found {1} instead", + assertionChain.FailWith("Expected {context:DataColumn} to be of type {0}, but found {1} instead", expectation.GetType(), comparands.Subject.GetType()); } } else { - CompareSubjectAndExpectationOfTypeDataColumn(comparands, context, nestedValidator, subject); + CompareSubjectAndExpectationOfTypeDataColumn(comparands, context, nestedValidator, subject, assertionChain); } - return EquivalencyResult.AssertionCompleted; + return EquivalencyResult.EquivalencyProven; } private static void CompareSubjectAndExpectationOfTypeDataColumn(Comparands comparands, - IEquivalencyValidationContext context, IEquivalencyValidator parent, DataColumn subject) + IEquivalencyValidationContext context, IValidateChildNodeEquivalency parent, DataColumn subject, AssertionChain assertionChain) { bool compareColumn = true; @@ -64,16 +66,16 @@ private static void CompareSubjectAndExpectationOfTypeDataColumn(Comparands comp { if (expectationMember.Name != nameof(subject.Table)) { - CompareMember(expectationMember, comparands, parent, context); + CompareMember(expectationMember, comparands, parent, context, assertionChain); } } } } - private static void CompareMember(IMember expectationMember, Comparands comparands, IEquivalencyValidator parent, - IEquivalencyValidationContext context) + private static void CompareMember(IMember expectationMember, Comparands comparands, IValidateChildNodeEquivalency parent, + IEquivalencyValidationContext context, AssertionChain assertionChain) { - IMember matchingMember = FindMatchFor(expectationMember, comparands.Subject, context); + IMember matchingMember = FindMatchFor(expectationMember, comparands.Subject, context, assertionChain); if (matchingMember is not null) { @@ -86,16 +88,17 @@ private static void CompareMember(IMember expectationMember, Comparands comparan if (context.AsNestedMember(expectationMember) is not null) { - parent.RecursivelyAssertEquality(nestedComparands, context.AsNestedMember(expectationMember)); + parent.AssertEquivalencyOf(nestedComparands, context.AsNestedMember(expectationMember)); } } } - private static IMember FindMatchFor(IMember selectedMemberInfo, object subject, IEquivalencyValidationContext context) + private static IMember FindMatchFor(IMember selectedMemberInfo, object subject, IEquivalencyValidationContext context, + AssertionChain assertionChain) { IEnumerable query = from rule in context.Options.MatchingRules - let match = rule.Match(selectedMemberInfo, subject, context.CurrentNode, context.Options) + let match = rule.Match(selectedMemberInfo, subject, context.CurrentNode, context.Options, assertionChain) where match is not null select match; @@ -126,7 +129,7 @@ where match is not null }; private static IEnumerable GetMembersFromExpectation(INode currentNode, Comparands comparands, - IEquivalencyAssertionOptions config) + IEquivalencyOptions config) { IEnumerable members = Enumerable.Empty(); diff --git a/Src/FluentAssertions.DataSets/Equivalency/DataRelationEquivalencyStep.cs b/Src/FluentAssertions.DataSets/Equivalency/DataRelationEquivalencyStep.cs index 8d1e2a7..d8d4bb1 100644 --- a/Src/FluentAssertions.DataSets/Equivalency/DataRelationEquivalencyStep.cs +++ b/Src/FluentAssertions.DataSets/Equivalency/DataRelationEquivalencyStep.cs @@ -3,6 +3,7 @@ using System.Data; using System.Diagnostics.CodeAnalysis; using System.Linq; +using FluentAssertions.DataSets.Common; using FluentAssertions.Equivalency; using FluentAssertions.Execution; @@ -12,26 +13,27 @@ public class DataRelationEquivalencyStep : EquivalencyStep { [SuppressMessage("Style", "IDE0019:Use pattern matching", Justification = "The code is easier to read without it.")] protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, - IEquivalencyValidator nestedValidator) + IValidateChildNodeEquivalency nestedValidator) { + var assertionChain = AssertionChain.GetOrCreate().For(context); var subject = comparands.Subject as DataRelation; if (comparands.Expectation is not DataRelation expectation) { if (subject is not null) { - AssertionScope.Current.FailWith("Expected {context:DataRelation} to be null, but found {0}", subject); + assertionChain.FailWith("Expected {context:DataRelation} to be null, but found {0}", subject); } } else if (subject is null) { if (comparands.Subject is null) { - AssertionScope.Current.FailWith("Expected {context:DataRelation} value to be non-null, but found null"); + assertionChain.FailWith("Expected {context:DataRelation} value to be non-null, but found null"); } else { - AssertionScope.Current.FailWith("Expected {context:DataRelation} of type {0}, but found {1} instead", + assertionChain.FailWith("Expected {context:DataRelation} of type {0}, but found {1} instead", expectation.GetType(), comparands.Subject.GetType()); } } @@ -40,22 +42,22 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc var selectedMembers = GetMembersFromExpectation(context.CurrentNode, comparands, context.Options) .ToDictionary(member => member.Name); - CompareScalarProperties(subject, expectation, selectedMembers); + CompareScalarProperties(subject, expectation, selectedMembers, assertionChain); - CompareCollections(context, comparands, nestedValidator, context.Options, selectedMembers); + CompareCollections(context, comparands, nestedValidator, context.Options, selectedMembers, assertionChain); - CompareRelationConstraints(context, nestedValidator, subject, expectation, selectedMembers); + CompareRelationConstraints(context, nestedValidator, subject, expectation, selectedMembers, assertionChain); } - return EquivalencyResult.AssertionCompleted; + return EquivalencyResult.EquivalencyProven; } private static void CompareScalarProperties(DataRelation subject, DataRelation expectation, - Dictionary selectedMembers) + Dictionary selectedMembers, AssertionChain assertionChain) { if (selectedMembers.ContainsKey(nameof(expectation.RelationName))) { - AssertionScope.Current + assertionChain .ForCondition(subject.RelationName == expectation.RelationName) .FailWith("Expected {context:DataRelation} to have RelationName of {0}{reason}, but found {1}", expectation.RelationName, subject.RelationName); @@ -63,7 +65,7 @@ private static void CompareScalarProperties(DataRelation subject, DataRelation e if (selectedMembers.ContainsKey(nameof(expectation.Nested))) { - AssertionScope.Current + assertionChain .ForCondition(subject.Nested == expectation.Nested) .FailWith("Expected {context:DataRelation} to have Nested value of {0}{reason}, but found {1}", expectation.Nested, subject.Nested); @@ -72,7 +74,7 @@ private static void CompareScalarProperties(DataRelation subject, DataRelation e // Special case: Compare name only if (selectedMembers.ContainsKey(nameof(expectation.DataSet))) { - AssertionScope.Current + assertionChain .ForCondition(subject.DataSet?.DataSetName == expectation.DataSet?.DataSetName) .FailWith("Expected containing DataSet of {context:DataRelation} to be {0}{reason}, but found {1}", expectation.DataSet?.DataSetName ?? "", @@ -81,12 +83,12 @@ private static void CompareScalarProperties(DataRelation subject, DataRelation e } private static void CompareCollections(IEquivalencyValidationContext context, Comparands comparands, - IEquivalencyValidator parent, - IEquivalencyAssertionOptions config, Dictionary selectedMembers) + IValidateChildNodeEquivalency parent, + IEquivalencyOptions config, Dictionary selectedMembers, AssertionChain assertionChain) { if (selectedMembers.TryGetValue(nameof(DataRelation.ExtendedProperties), out IMember expectationMember)) { - IMember matchingMember = FindMatchFor(expectationMember, context.CurrentNode, comparands.Subject, config); + IMember matchingMember = FindMatchFor(expectationMember, context.CurrentNode, comparands.Subject, config, assertionChain); if (matchingMember is not null) { @@ -97,14 +99,15 @@ private static void CompareCollections(IEquivalencyValidationContext context, Co CompileTimeType = expectationMember.Type }; - parent.RecursivelyAssertEquality(nestedComparands, context.AsNestedMember(expectationMember)); + parent.AssertEquivalencyOf(nestedComparands, context.AsNestedMember(expectationMember)); } } } - private static void CompareRelationConstraints(IEquivalencyValidationContext context, IEquivalencyValidator parent, + private static void CompareRelationConstraints(IEquivalencyValidationContext context, IValidateChildNodeEquivalency parent, DataRelation subject, DataRelation expectation, - Dictionary selectedMembers) + Dictionary selectedMembers, + AssertionChain assertionChain) { CompareDataRelationConstraints( parent, context, subject, expectation, selectedMembers, @@ -113,7 +116,7 @@ private static void CompareRelationConstraints(IEquivalencyValidationContext con selectedMembers.ContainsKey(nameof(DataRelation.ChildColumns)), selectedMembers.ContainsKey(nameof(DataRelation.ChildKeyConstraint)), r => r.ChildColumns, - r => r.ChildTable); + r => r.ChildTable, assertionChain); CompareDataRelationConstraints( parent, context, subject, expectation, selectedMembers, @@ -122,47 +125,48 @@ private static void CompareRelationConstraints(IEquivalencyValidationContext con selectedMembers.ContainsKey(nameof(DataRelation.ParentColumns)), selectedMembers.ContainsKey(nameof(DataRelation.ParentKeyConstraint)), r => r.ParentColumns, - r => r.ParentTable); + r => r.ParentTable, assertionChain); } private static void CompareDataRelationConstraints( - IEquivalencyValidator parent, IEquivalencyValidationContext context, + IValidateChildNodeEquivalency parent, IEquivalencyValidationContext context, DataRelation subject, DataRelation expectation, Dictionary selectedMembers, string relationDirection, bool compareTable, bool compareColumns, bool compareKeyConstraint, Func getColumns, - Func getOtherTable) + Func getOtherTable, + AssertionChain assertionChain) { if (compareColumns) { - CompareDataRelationColumns(subject, expectation, getColumns); + CompareDataRelationColumns(subject, expectation, getColumns, assertionChain); } if (compareTable) { - CompareDataRelationTable(subject, expectation, getOtherTable); + CompareDataRelationTable(subject, expectation, getOtherTable, assertionChain); } if (compareKeyConstraint) { - CompareDataRelationKeyConstraint(subject, expectation, parent, context, selectedMembers, relationDirection); + CompareDataRelationKeyConstraint(subject, expectation, parent, context, selectedMembers, relationDirection, assertionChain); } } private static void CompareDataRelationColumns(DataRelation subject, DataRelation expectation, - Func getColumns) + Func getColumns, AssertionChain assertionChain) { DataColumn[] subjectColumns = getColumns(subject); DataColumn[] expectationColumns = getColumns(expectation); // These column references are in different tables in different data sets that _should_ be equivalent // to one another. - bool success = AssertionScope.Current + assertionChain .ForCondition(subjectColumns.Length == expectationColumns.Length) .FailWith("Expected {context:DataRelation} to reference {0} column(s){reason}, but found {subjectColumns.Length}", expectationColumns.Length, subjectColumns.Length); - if (success) + if (assertionChain.Succeeded) { for (int i = 0; i < expectationColumns.Length; i++) { @@ -173,7 +177,7 @@ private static void CompareDataRelationColumns(DataRelation subject, DataRelatio subjectColumn.Table.TableName == expectationColumn.Table.TableName && subjectColumn.ColumnName == expectationColumn.ColumnName; - AssertionScope.Current + assertionChain .ForCondition(columnsAreEquivalent) .FailWith( "Expected {context:DataRelation} to reference column {0} in table {1}{reason}, but found a reference to {2} in table {3} instead", @@ -186,24 +190,24 @@ private static void CompareDataRelationColumns(DataRelation subject, DataRelatio } private static void CompareDataRelationTable(DataRelation subject, DataRelation expectation, - Func getOtherTable) + Func getOtherTable, AssertionChain assertionChain) { DataTable subjectTable = getOtherTable(subject); DataTable expectationTable = getOtherTable(expectation); - AssertionScope.Current + assertionChain .ForCondition(subjectTable.TableName == expectationTable.TableName) .FailWith("Expected {context:DataRelation} to reference a table named {0}{reason}, but found {1} instead", expectationTable.TableName, subjectTable.TableName); } private static void CompareDataRelationKeyConstraint(DataRelation subject, DataRelation expectation, - IEquivalencyValidator parent, IEquivalencyValidationContext context, Dictionary selectedMembers, - string relationDirection) + IValidateChildNodeEquivalency parent, IEquivalencyValidationContext context, Dictionary selectedMembers, + string relationDirection, AssertionChain assertionChain) { if (selectedMembers.TryGetValue(relationDirection + "KeyConstraint", out IMember expectationMember)) { - IMember subjectMember = FindMatchFor(expectationMember, context.CurrentNode, subject, context.Options); + IMember subjectMember = FindMatchFor(expectationMember, context.CurrentNode, subject, context.Options, assertionChain); var newComparands = new Comparands { @@ -212,16 +216,16 @@ private static void CompareDataRelationKeyConstraint(DataRelation subject, DataR CompileTimeType = expectationMember.Type }; - parent.RecursivelyAssertEquality(newComparands, context.AsNestedMember(expectationMember)); + parent.AssertEquivalencyOf(newComparands, context.AsNestedMember(expectationMember)); } } private static IMember FindMatchFor(IMember selectedMemberInfo, INode currentNode, object subject, - IEquivalencyAssertionOptions config) + IEquivalencyOptions config, AssertionChain assertionChain) { IEnumerable query = from rule in config.MatchingRules - let match = rule.Match(selectedMemberInfo, subject, currentNode, config) + let match = rule.Match(selectedMemberInfo, subject, currentNode, config, assertionChain) where match is not null select match; @@ -229,7 +233,7 @@ where match is not null } private static IEnumerable GetMembersFromExpectation(INode currentNode, Comparands comparands, - IEquivalencyAssertionOptions config) + IEquivalencyOptions config) { IEnumerable members = Enumerable.Empty(); diff --git a/Src/FluentAssertions.DataSets/Equivalency/DataRowCollectionEquivalencyStep.cs b/Src/FluentAssertions.DataSets/Equivalency/DataRowCollectionEquivalencyStep.cs index d9701bc..3d0e07c 100644 --- a/Src/FluentAssertions.DataSets/Equivalency/DataRowCollectionEquivalencyStep.cs +++ b/Src/FluentAssertions.DataSets/Equivalency/DataRowCollectionEquivalencyStep.cs @@ -10,11 +10,13 @@ namespace FluentAssertions.DataSets.Equivalency; public class DataRowCollectionEquivalencyStep : EquivalencyStep { protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, - IEquivalencyValidator nestedValidator) + IValidateChildNodeEquivalency nestedValidator) { + var assertionChain = AssertionChain.GetOrCreate().For(context); + if (comparands.Subject is not DataRowCollection) { - AssertionScope.Current + assertionChain .FailWith("Expected {context:value} to be of type DataRowCollection, but found {0}", comparands.Subject.GetType()); } @@ -30,12 +32,12 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc var subject = (DataRowCollection)comparands.Subject; var expectation = (DataRowCollection)comparands.Expectation; - bool success = AssertionScope.Current + assertionChain .ForCondition(subject.Count == expectation.Count) .FailWith("Expected {context:DataRowCollection} to contain {0} row(s){reason}, but found {1}", expectation.Count, subject.Count); - if (success) + if (assertionChain.Succeeded) { switch (rowMatchMode) { @@ -44,11 +46,11 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc break; case RowMatchMode.PrimaryKey: - MatchRowsByPrimaryKeyAndCompare(nestedValidator, context, subject, expectation); + MatchRowsByPrimaryKeyAndCompare(nestedValidator, context, subject, expectation, assertionChain); break; default: - AssertionScope.Current.FailWith( + assertionChain.FailWith( "Unknown RowMatchMode {0} when trying to compare {context:DataRowCollection}", rowMatchMode); break; @@ -56,50 +58,51 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc } } - return EquivalencyResult.AssertionCompleted; + return EquivalencyResult.EquivalencyProven; } - private static void MatchRowsByIndexAndCompare(IEquivalencyValidationContext context, IEquivalencyValidator parent, + private static void MatchRowsByIndexAndCompare(IEquivalencyValidationContext context, IValidateChildNodeEquivalency parent, DataRowCollection subject, DataRowCollection expectation) { for (int index = 0; index < expectation.Count; index++) { IEquivalencyValidationContext nestedContext = context.AsCollectionItem(index); - parent.RecursivelyAssertEquality(new Comparands(subject[index], expectation[index], typeof(DataRow)), nestedContext); + parent.AssertEquivalencyOf(new Comparands(subject[index], expectation[index], typeof(DataRow)), nestedContext); } } - private static void MatchRowsByPrimaryKeyAndCompare(IEquivalencyValidator parent, IEquivalencyValidationContext context, - DataRowCollection subject, DataRowCollection expectation) + private static void MatchRowsByPrimaryKeyAndCompare(IValidateChildNodeEquivalency parent, + IEquivalencyValidationContext context, + DataRowCollection subject, DataRowCollection expectation, AssertionChain assertionChain) { Type[] subjectPrimaryKeyTypes = null; Type[] expectationPrimaryKeyTypes = null; if (subject.Count > 0) { - subjectPrimaryKeyTypes = GatherPrimaryKeyColumnTypes(subject[0].Table, "subject"); + subjectPrimaryKeyTypes = GatherPrimaryKeyColumnTypes(subject[0].Table, "subject", assertionChain); } if (expectation.Count > 0) { - expectationPrimaryKeyTypes = GatherPrimaryKeyColumnTypes(expectation[0].Table, "expectation"); + expectationPrimaryKeyTypes = GatherPrimaryKeyColumnTypes(expectation[0].Table, "expectation", assertionChain); } - bool matchingTypes = ComparePrimaryKeyTypes(subjectPrimaryKeyTypes, expectationPrimaryKeyTypes); + bool matchingTypes = ComparePrimaryKeyTypes(subjectPrimaryKeyTypes, expectationPrimaryKeyTypes, assertionChain); if (matchingTypes) { - GatherRowsByPrimaryKeyAndCompareData(parent, context, subject, expectation); + GatherRowsByPrimaryKeyAndCompareData(parent, context, subject, expectation, assertionChain); } } - private static Type[] GatherPrimaryKeyColumnTypes(DataTable table, string comparisonTerm) + private static Type[] GatherPrimaryKeyColumnTypes(DataTable table, string comparisonTerm, AssertionChain assertionChain) { Type[] primaryKeyTypes = null; if (table.PrimaryKey is null or { Length: 0 }) { - AssertionScope.Current + assertionChain .FailWith( "Table {0} containing {1} {context:DataRowCollection} does not have a primary key. RowMatchMode.PrimaryKey cannot be applied.", table.TableName, comparisonTerm); @@ -117,7 +120,7 @@ private static Type[] GatherPrimaryKeyColumnTypes(DataTable table, string compar return primaryKeyTypes; } - private static bool ComparePrimaryKeyTypes(Type[] subjectPrimaryKeyTypes, Type[] expectationPrimaryKeyTypes) + private static bool ComparePrimaryKeyTypes(Type[] subjectPrimaryKeyTypes, Type[] expectationPrimaryKeyTypes, AssertionChain assertionChain) { bool matchingTypes = false; @@ -135,7 +138,7 @@ private static bool ComparePrimaryKeyTypes(Type[] subjectPrimaryKeyTypes, Type[] if (!matchingTypes) { - AssertionScope.Current + assertionChain .FailWith( "Subject and expectation primary keys of table containing {context:DataRowCollection} do not have the same schema and cannot be compared. RowMatchMode.PrimaryKey cannot be applied."); } @@ -144,8 +147,8 @@ private static bool ComparePrimaryKeyTypes(Type[] subjectPrimaryKeyTypes, Type[] return matchingTypes; } - private static void GatherRowsByPrimaryKeyAndCompareData(IEquivalencyValidator parent, IEquivalencyValidationContext context, - DataRowCollection subject, DataRowCollection expectation) + private static void GatherRowsByPrimaryKeyAndCompareData(IValidateChildNodeEquivalency parent, IEquivalencyValidationContext context, + DataRowCollection subject, DataRowCollection expectation, AssertionChain assertionChain) { var expectationRowByKey = expectation.Cast() .ToDictionary(row => ExtractPrimaryKey(row)); @@ -156,7 +159,7 @@ private static void GatherRowsByPrimaryKeyAndCompareData(IEquivalencyValidator p if (!expectationRowByKey.TryGetValue(key, out DataRow expectationRow)) { - AssertionScope.Current + assertionChain .FailWith("Found unexpected row in {context:DataRowCollection} with key {0}", key); } else @@ -164,7 +167,7 @@ private static void GatherRowsByPrimaryKeyAndCompareData(IEquivalencyValidator p expectationRowByKey.Remove(key); IEquivalencyValidationContext nestedContext = context.AsCollectionItem(key.ToString()); - parent.RecursivelyAssertEquality(new Comparands(subjectRow, expectationRow, typeof(DataRow)), nestedContext); + parent.AssertEquivalencyOf(new Comparands(subjectRow, expectationRow, typeof(DataRow)), nestedContext); } } @@ -172,12 +175,12 @@ private static void GatherRowsByPrimaryKeyAndCompareData(IEquivalencyValidator p { if (expectationRowByKey.Count > 1) { - AssertionScope.Current + assertionChain .FailWith("{0} rows were expected in {context:DataRowCollection} and not found", expectationRowByKey.Count); } else { - AssertionScope.Current + assertionChain .FailWith( "Expected to find a row with key {0} in {context:DataRowCollection}{reason}, but no such row was found", expectationRowByKey.Keys.Single()); diff --git a/Src/FluentAssertions.DataSets/Equivalency/DataRowEquivalencyStep.cs b/Src/FluentAssertions.DataSets/Equivalency/DataRowEquivalencyStep.cs index 8c20727..b03d1f4 100644 --- a/Src/FluentAssertions.DataSets/Equivalency/DataRowEquivalencyStep.cs +++ b/Src/FluentAssertions.DataSets/Equivalency/DataRowEquivalencyStep.cs @@ -4,6 +4,7 @@ using System.Data; using System.Diagnostics.CodeAnalysis; using System.Linq; +using FluentAssertions.DataSets.Common; using FluentAssertions.Equivalency; using FluentAssertions.Execution; @@ -13,26 +14,27 @@ public class DataRowEquivalencyStep : EquivalencyStep { [SuppressMessage("Style", "IDE0019:Use pattern matching", Justification = "The code is easier to read without it.")] protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, - IEquivalencyValidator nestedValidator) + IValidateChildNodeEquivalency nestedValidator) { + var assertionChain = AssertionChain.GetOrCreate().For(context); var subject = comparands.Subject as DataRow; if (comparands.Expectation is not DataRow expectation) { if (subject is not null) { - AssertionScope.Current.FailWith("Expected {context:DataRow} value to be null, but found {0}", subject); + assertionChain.FailWith("Expected {context:DataRow} value to be null, but found {0}", subject); } } else if (subject is null) { if (comparands.Subject is null) { - AssertionScope.Current.FailWith("Expected {context:DataRow} to be non-null, but found null"); + assertionChain.FailWith("Expected {context:DataRow} to be non-null, but found null"); } else { - AssertionScope.Current.FailWith("Expected {context:DataRow} to be of type {0}, but found {1} instead", + assertionChain.FailWith("Expected {context:DataRow} to be of type {0}, but found {1} instead", expectation.GetType(), comparands.Subject.GetType()); } } @@ -46,7 +48,7 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc && dataTableConfig?.AllowMismatchedTypes != true && dataRowConfig?.AllowMismatchedTypes != true) { - AssertionScope.Current + assertionChain .ForCondition(subject.GetType() == expectation.GetType()) .FailWith("Expected {context:DataRow} to be of type {0}{reason}, but found {1}", expectation.GetType(), subject.GetType()); @@ -55,22 +57,22 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc SelectedDataRowMembers selectedMembers = GetMembersFromExpectation(comparands, context.CurrentNode, context.Options); - CompareScalarProperties(subject, expectation, selectedMembers); + CompareScalarProperties(subject, expectation, selectedMembers, assertionChain); CompareFieldValues(context, nestedValidator, subject, expectation, dataSetConfig, dataTableConfig, - dataRowConfig); + dataRowConfig, assertionChain); } - return EquivalencyResult.AssertionCompleted; + return EquivalencyResult.EquivalencyProven; } - private static void CompareScalarProperties(DataRow subject, DataRow expectation, SelectedDataRowMembers selectedMembers) + private static void CompareScalarProperties(DataRow subject, DataRow expectation, SelectedDataRowMembers selectedMembers, AssertionChain assertionChain) { // Note: The members here are listed in the XML documentation for the DataRow.BeEquivalentTo extension // method in DataRowAssertions.cs. If this ever needs to change, keep them in sync. if (selectedMembers.HasErrors) { - AssertionScope.Current + assertionChain .ForCondition(subject.HasErrors == expectation.HasErrors) .FailWith("Expected {context:DataRow} to have HasErrors value of {0}{reason}, but found {1} instead", expectation.HasErrors, subject.HasErrors); @@ -78,7 +80,7 @@ private static void CompareScalarProperties(DataRow subject, DataRow expectation if (selectedMembers.RowState) { - AssertionScope.Current + assertionChain .ForCondition(subject.RowState == expectation.RowState) .FailWith("Expected {context:DataRow} to have RowState value of {0}{reason}, but found {1} instead", expectation.RowState, subject.RowState); @@ -87,9 +89,10 @@ private static void CompareScalarProperties(DataRow subject, DataRow expectation [SuppressMessage("Maintainability", "AV1561:Signature contains too many parameters", Justification = "Needs to be refactored")] [SuppressMessage("Design", "MA0051:Method is too long", Justification = "Needs to be refactored")] - private static void CompareFieldValues(IEquivalencyValidationContext context, IEquivalencyValidator parent, + private static void CompareFieldValues(IEquivalencyValidationContext context, IValidateChildNodeEquivalency parent, DataRow subject, DataRow expectation, DataEquivalencyAssertionOptions dataSetConfig, - DataEquivalencyAssertionOptions dataTableConfig, DataEquivalencyAssertionOptions dataRowConfig) + DataEquivalencyAssertionOptions dataTableConfig, DataEquivalencyAssertionOptions dataRowConfig, + AssertionChain assertionChain) { IEnumerable expectationColumnNames = expectation.Table.Columns.Cast() .Select(col => col.ColumnName); @@ -137,11 +140,11 @@ private static void CompareFieldValues(IEquivalencyValidationContext context, IE if (!ignoreUnmatchedColumns) { - AssertionScope.Current + assertionChain .ForCondition(subjectColumn is not null) .FailWith("Expected {context:DataRow} to have column {0}{reason}, but found none", columnName); - AssertionScope.Current + assertionChain .ForCondition(expectationColumn is not null) .FailWith("Found unexpected column {0} in {context:DataRow}", columnName); } @@ -160,7 +163,7 @@ private static void CompareFieldValues(IEquivalencyValidationContext context, IE } } - private static void CompareFieldValue(IEquivalencyValidationContext context, IEquivalencyValidator parent, DataRow subject, + private static void CompareFieldValue(IEquivalencyValidationContext context, IValidateChildNodeEquivalency parent, DataRow subject, DataRow expectation, DataColumn subjectColumn, DataRowVersion subjectVersion, DataColumn expectationColumn, DataRowVersion expectationVersion) { @@ -171,7 +174,7 @@ private static void CompareFieldValue(IEquivalencyValidationContext context, IEq if (nestedContext is not null) { - parent.RecursivelyAssertEquality( + parent.AssertEquivalencyOf( new Comparands(subject[subjectColumn, subjectVersion], expectation[expectationColumn, expectationVersion], typeof(object)), nestedContext); @@ -185,11 +188,11 @@ private sealed class SelectedDataRowMembers public bool RowState { get; init; } } - private static readonly ConcurrentDictionary<(Type CompileTimeType, Type RuntimeType, IEquivalencyAssertionOptions Config), + private static readonly ConcurrentDictionary<(Type CompileTimeType, Type RuntimeType, IEquivalencyOptions Config), SelectedDataRowMembers> SelectedMembersCache = new(); private static SelectedDataRowMembers GetMembersFromExpectation(Comparands comparands, INode currentNode, - IEquivalencyAssertionOptions config) + IEquivalencyOptions config) { var cacheKey = (comparands.CompileTimeType, comparands.RuntimeType, config); diff --git a/Src/FluentAssertions.DataSets/Equivalency/DataSetEquivalencyStep.cs b/Src/FluentAssertions.DataSets/Equivalency/DataSetEquivalencyStep.cs index 03d42bb..65ddc3e 100644 --- a/Src/FluentAssertions.DataSets/Equivalency/DataSetEquivalencyStep.cs +++ b/Src/FluentAssertions.DataSets/Equivalency/DataSetEquivalencyStep.cs @@ -2,6 +2,7 @@ using System.Data; using System.Diagnostics.CodeAnalysis; using System.Linq; +using FluentAssertions.DataSets.Common; using FluentAssertions.Equivalency; using FluentAssertions.Execution; @@ -10,26 +11,27 @@ namespace FluentAssertions.DataSets.Equivalency; public class DataSetEquivalencyStep : EquivalencyStep { protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, - IEquivalencyValidator nestedValidator) + IValidateChildNodeEquivalency nestedValidator) { + var assertionChain = AssertionChain.GetOrCreate().For(context); var subject = comparands.Subject as DataSet; if (comparands.Expectation is not DataSet expectation) { if (subject is not null) { - AssertionScope.Current.FailWith("Expected {context:DataSet} value to be null, but found {0}", subject); + assertionChain.FailWith("Expected {context:DataSet} value to be null, but found {0}", subject); } } else if (subject is null) { if (comparands.Subject is null) { - AssertionScope.Current.FailWith("Expected {context:DataSet} to be non-null, but found null"); + assertionChain.FailWith("Expected {context:DataSet} to be non-null, but found null"); } else { - AssertionScope.Current.FailWith("Expected {context:DataSet} to be of type {0}, but found {1} instead", + assertionChain.FailWith("Expected {context:DataSet} to be of type {0}, but found {1} instead", expectation.GetType(), comparands.Subject.GetType()); } } @@ -39,7 +41,7 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc if (dataConfig?.AllowMismatchedTypes != true) { - AssertionScope.Current + assertionChain .ForCondition(subject.GetType() == expectation.GetType()) .FailWith("Expected {context:DataSet} to be of type {0}{reason}, but found {1}", expectation.GetType(), subject.GetType()); @@ -48,22 +50,22 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc var selectedMembers = GetMembersFromExpectation(comparands, context.CurrentNode, context.Options) .ToDictionary(member => member.Name); - CompareScalarProperties(subject, expectation, selectedMembers); + CompareScalarProperties(subject, expectation, selectedMembers, assertionChain); - CompareCollections(context, nestedValidator, context.Options, subject, expectation, dataConfig, selectedMembers); + CompareCollections(context, nestedValidator, context.Options, subject, expectation, dataConfig, selectedMembers, assertionChain); } - return EquivalencyResult.AssertionCompleted; + return EquivalencyResult.EquivalencyProven; } [SuppressMessage("Design", "MA0051:Method is too long")] - private static void CompareScalarProperties(DataSet subject, DataSet expectation, Dictionary selectedMembers) + private static void CompareScalarProperties(DataSet subject, DataSet expectation, Dictionary selectedMembers, AssertionChain assertionChain) { // Note: The members here are listed in the XML documentation for the DataSet.BeEquivalentTo extension // method in DataSetAssertions.cs. If this ever needs to change, keep them in sync. if (selectedMembers.ContainsKey(nameof(expectation.DataSetName))) { - AssertionScope.Current + assertionChain .ForCondition(subject.DataSetName == expectation.DataSetName) .FailWith("Expected {context:DataSet} to have DataSetName {0}{reason}, but found {1} instead", expectation.DataSetName, subject.DataSetName); @@ -71,7 +73,7 @@ private static void CompareScalarProperties(DataSet subject, DataSet expectation if (selectedMembers.ContainsKey(nameof(expectation.CaseSensitive))) { - AssertionScope.Current + assertionChain .ForCondition(subject.CaseSensitive == expectation.CaseSensitive) .FailWith("Expected {context:DataSet} to have CaseSensitive value of {0}{reason}, but found {1} instead", expectation.CaseSensitive, subject.CaseSensitive); @@ -79,7 +81,7 @@ private static void CompareScalarProperties(DataSet subject, DataSet expectation if (selectedMembers.ContainsKey(nameof(expectation.EnforceConstraints))) { - AssertionScope.Current + assertionChain .ForCondition(subject.EnforceConstraints == expectation.EnforceConstraints) .FailWith("Expected {context:DataSet} to have EnforceConstraints value of {0}{reason}, but found {1} instead", expectation.EnforceConstraints, subject.EnforceConstraints); @@ -87,7 +89,7 @@ private static void CompareScalarProperties(DataSet subject, DataSet expectation if (selectedMembers.ContainsKey(nameof(expectation.HasErrors))) { - AssertionScope.Current + assertionChain .ForCondition(subject.HasErrors == expectation.HasErrors) .FailWith("Expected {context:DataSet} to have HasErrors value of {0}{reason}, but found {1} instead", expectation.HasErrors, subject.HasErrors); @@ -95,7 +97,7 @@ private static void CompareScalarProperties(DataSet subject, DataSet expectation if (selectedMembers.ContainsKey(nameof(expectation.Locale))) { - AssertionScope.Current + assertionChain .ForCondition(Equals(subject.Locale, expectation.Locale)) .FailWith("Expected {context:DataSet} to have Locale value of {0}{reason}, but found {1} instead", expectation.Locale, subject.Locale); @@ -103,7 +105,7 @@ private static void CompareScalarProperties(DataSet subject, DataSet expectation if (selectedMembers.ContainsKey(nameof(expectation.Namespace))) { - AssertionScope.Current + assertionChain .ForCondition(subject.Namespace == expectation.Namespace) .FailWith("Expected {context:DataSet} to have Namespace value of {0}{reason}, but found {1} instead", expectation.Namespace, subject.Namespace); @@ -111,7 +113,7 @@ private static void CompareScalarProperties(DataSet subject, DataSet expectation if (selectedMembers.ContainsKey(nameof(expectation.Prefix))) { - AssertionScope.Current + assertionChain .ForCondition(subject.Prefix == expectation.Prefix) .FailWith("Expected {context:DataSet} to have Prefix value of {0}{reason}, but found {1} instead", expectation.Prefix, subject.Prefix); @@ -119,7 +121,7 @@ private static void CompareScalarProperties(DataSet subject, DataSet expectation if (selectedMembers.ContainsKey(nameof(expectation.RemotingFormat))) { - AssertionScope.Current + assertionChain .ForCondition(subject.RemotingFormat == expectation.RemotingFormat) .FailWith("Expected {context:DataSet} to have RemotingFormat value of {0}{reason}, but found {1} instead", expectation.RemotingFormat, subject.RemotingFormat); @@ -127,7 +129,7 @@ private static void CompareScalarProperties(DataSet subject, DataSet expectation if (selectedMembers.ContainsKey(nameof(expectation.SchemaSerializationMode))) { - AssertionScope.Current + assertionChain .ForCondition(subject.SchemaSerializationMode == expectation.SchemaSerializationMode) .FailWith( "Expected {context:DataSet} to have SchemaSerializationMode value of {0}{reason}, but found {1} instead", @@ -135,26 +137,26 @@ private static void CompareScalarProperties(DataSet subject, DataSet expectation } } - private static void CompareCollections(IEquivalencyValidationContext context, IEquivalencyValidator parent, - IEquivalencyAssertionOptions config, DataSet subject, DataSet expectation, - DataEquivalencyAssertionOptions dataConfig, Dictionary selectedMembers) + private static void CompareCollections(IEquivalencyValidationContext context, IValidateChildNodeEquivalency parent, + IEquivalencyOptions config, DataSet subject, DataSet expectation, + DataEquivalencyAssertionOptions dataConfig, Dictionary selectedMembers, AssertionChain assertionChain) { // Note: The collections here are listed in the XML documentation for the DataSet.BeEquivalentTo extension // method in DataSetAssertions.cs. If this ever needs to change, keep them in sync. CompareExtendedProperties(new Comparands(subject, expectation, typeof(DataSet)), context, parent, config, - selectedMembers); + selectedMembers, assertionChain); - CompareTables(context, parent, subject, expectation, dataConfig, selectedMembers); + CompareTables(context, parent, subject, expectation, dataConfig, selectedMembers, assertionChain); } private static void CompareExtendedProperties(Comparands comparands, IEquivalencyValidationContext context, - IEquivalencyValidator parent, IEquivalencyAssertionOptions config, Dictionary selectedMembers) + IValidateChildNodeEquivalency parent, IEquivalencyOptions config, Dictionary selectedMembers, AssertionChain assertionChain) { foreach (var collectionName in new[] { nameof(DataSet.ExtendedProperties), nameof(DataSet.Relations) }) { if (selectedMembers.TryGetValue(collectionName, out IMember expectationMember)) { - IMember matchingMember = FindMatchFor(expectationMember, comparands.Subject, context.CurrentNode, config); + IMember matchingMember = FindMatchFor(expectationMember, comparands.Subject, context.CurrentNode, config, assertionChain); if (matchingMember is not null) { @@ -166,23 +168,24 @@ private static void CompareExtendedProperties(Comparands comparands, IEquivalenc }; IEquivalencyValidationContext nestedContext = context.AsNestedMember(expectationMember); - parent.RecursivelyAssertEquality(nestedComparands, nestedContext); + parent.AssertEquivalencyOf(nestedComparands, nestedContext); } } } } - private static void CompareTables(IEquivalencyValidationContext context, IEquivalencyValidator parent, DataSet subject, - DataSet expectation, DataEquivalencyAssertionOptions dataConfig, Dictionary selectedMembers) + private static void CompareTables(IEquivalencyValidationContext context, IValidateChildNodeEquivalency parent, DataSet subject, + DataSet expectation, DataEquivalencyAssertionOptions dataConfig, Dictionary selectedMembers, + AssertionChain assertionChain) { if (selectedMembers.ContainsKey(nameof(expectation.Tables))) { - bool success = AssertionScope.Current + assertionChain .ForCondition(subject.Tables.Count == expectation.Tables.Count) .FailWith("Expected {context:DataSet} to contain {0}, but found {1} table(s)", expectation.Tables.Count, subject.Tables.Count); - if (!success) + if (!assertionChain.Succeeded) { return; } @@ -216,37 +219,37 @@ private static void CompareTables(IEquivalencyValidationContext context, IEquiva continue; } - CompareTable(context, parent, subject, expectation, tableName); + CompareTable(context, parent, subject, expectation, tableName, assertionChain); } } } - private static void CompareTable(IEquivalencyValidationContext context, IEquivalencyValidator parent, DataSet subject, - DataSet expectation, string tableName) + private static void CompareTable(IEquivalencyValidationContext context, IValidateChildNodeEquivalency parent, DataSet subject, + DataSet expectation, string tableName, AssertionChain assertionChain) { DataTable expectationTable = expectation.Tables[tableName]; DataTable subjectTable = subject.Tables[tableName]; - bool success = AssertionScope.Current + assertionChain .ForCondition(subjectTable is not null) .FailWith("Expected {context:DataSet} to contain table {0}{reason}, but did not find it", tableName) .Then .ForCondition(expectationTable is not null) .FailWith("Found unexpected table {0} in DataSet", tableName); - if (success) + if (assertionChain.Succeeded) { IEquivalencyValidationContext nestedContext = context.AsCollectionItem(tableName); - parent.RecursivelyAssertEquality(new Comparands(subjectTable, expectationTable, typeof(DataTable)), nestedContext); + parent.AssertEquivalencyOf(new Comparands(subjectTable, expectationTable, typeof(DataTable)), nestedContext); } } private static IMember FindMatchFor(IMember selectedMemberInfo, object subject, INode currentNode, - IEquivalencyAssertionOptions options) + IEquivalencyOptions options, AssertionChain assertionChain) { IEnumerable query = from rule in options.MatchingRules - let match = rule.Match(selectedMemberInfo, subject, currentNode, options) + let match = rule.Match(selectedMemberInfo, subject, currentNode, options, assertionChain) where match is not null select match; @@ -255,7 +258,7 @@ where match is not null private static IEnumerable GetMembersFromExpectation(Comparands comparands, INode contextCurrentNode, - IEquivalencyAssertionOptions options) + IEquivalencyOptions options) { IEnumerable members = Enumerable.Empty(); diff --git a/Src/FluentAssertions.DataSets/Equivalency/DataTableEquivalencyStep.cs b/Src/FluentAssertions.DataSets/Equivalency/DataTableEquivalencyStep.cs index 5087ea4..c656dde 100644 --- a/Src/FluentAssertions.DataSets/Equivalency/DataTableEquivalencyStep.cs +++ b/Src/FluentAssertions.DataSets/Equivalency/DataTableEquivalencyStep.cs @@ -2,6 +2,7 @@ using System.Data; using System.Diagnostics.CodeAnalysis; using System.Linq; +using FluentAssertions.DataSets.Common; using FluentAssertions.Equivalency; using FluentAssertions.Execution; @@ -11,26 +12,28 @@ public class DataTableEquivalencyStep : EquivalencyStep { [SuppressMessage("Style", "IDE0019:Use pattern matching", Justification = "The code is easier to read without it.")] protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, - IEquivalencyValidator nestedValidator) + IValidateChildNodeEquivalency nestedValidator) { + var assertionChain = AssertionChain.GetOrCreate().For(context); + var subject = comparands.Subject as DataTable; if (comparands.Expectation is not DataTable expectation) { if (subject is not null) { - AssertionScope.Current.FailWith("Expected {context:DataTable} value to be null, but found {0}", subject); + assertionChain.FailWith("Expected {context:DataTable} value to be null, but found {0}", subject); } } else if (subject is null) { if (comparands.Subject is null) { - AssertionScope.Current.FailWith("Expected {context:DataTable} to be non-null, but found null"); + assertionChain.FailWith("Expected {context:DataTable} to be non-null, but found null"); } else { - AssertionScope.Current.FailWith("Expected {context:DataTable} to be of type {0}, but found {1} instead", + assertionChain.FailWith("Expected {context:DataTable} to be of type {0}, but found {1} instead", expectation.GetType(), comparands.Subject.GetType()); } } @@ -42,7 +45,7 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc if (dataSetConfig?.AllowMismatchedTypes != true && dataTableConfig?.AllowMismatchedTypes != true) { - AssertionScope.Current + assertionChain .ForCondition(subject.GetType() == expectation.GetType()) .FailWith("Expected {context:DataTable} to be of type {0}{reason}, but found {1}", expectation.GetType(), subject.GetType()); @@ -51,23 +54,23 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc var selectedMembers = GetMembersFromExpectation(context.CurrentNode, comparands, context.Options) .ToDictionary(member => member.Name); - CompareScalarProperties(subject, expectation, selectedMembers); + CompareScalarProperties(subject, expectation, selectedMembers, assertionChain); - CompareCollections(comparands, context, nestedValidator, context.Options, selectedMembers); + CompareCollections(comparands, context, nestedValidator, context.Options, selectedMembers, assertionChain); } - return EquivalencyResult.AssertionCompleted; + return EquivalencyResult.EquivalencyProven; } [SuppressMessage("Design", "MA0051:Method is too long")] private static void CompareScalarProperties(DataTable subject, DataTable expectation, - Dictionary selectedMembers) + Dictionary selectedMembers, AssertionChain assertionChain) { // Note: The members here are listed in the XML documentation for the DataTable.BeEquivalentTo extension // method in DataTableAssertions.cs. If this ever needs to change, keep them in sync. if (selectedMembers.ContainsKey(nameof(expectation.TableName))) { - AssertionScope.Current + assertionChain .ForCondition(subject.TableName == expectation.TableName) .FailWith("Expected {context:DataTable} to have TableName {0}{reason}, but found {1} instead", expectation.TableName, subject.TableName); @@ -75,7 +78,7 @@ private static void CompareScalarProperties(DataTable subject, DataTable expecta if (selectedMembers.ContainsKey(nameof(expectation.CaseSensitive))) { - AssertionScope.Current + assertionChain .ForCondition(subject.CaseSensitive == expectation.CaseSensitive) .FailWith("Expected {context:DataTable} to have CaseSensitive value of {0}{reason}, but found {1} instead", expectation.CaseSensitive, subject.CaseSensitive); @@ -83,7 +86,7 @@ private static void CompareScalarProperties(DataTable subject, DataTable expecta if (selectedMembers.ContainsKey(nameof(expectation.DisplayExpression))) { - AssertionScope.Current + assertionChain .ForCondition(subject.DisplayExpression == expectation.DisplayExpression) .FailWith("Expected {context:DataTable} to have DisplayExpression value of {0}{reason}, but found {1} instead", expectation.DisplayExpression, subject.DisplayExpression); @@ -91,7 +94,7 @@ private static void CompareScalarProperties(DataTable subject, DataTable expecta if (selectedMembers.ContainsKey(nameof(expectation.HasErrors))) { - AssertionScope.Current + assertionChain .ForCondition(subject.HasErrors == expectation.HasErrors) .FailWith("Expected {context:DataTable} to have HasErrors value of {0}{reason}, but found {1} instead", expectation.HasErrors, subject.HasErrors); @@ -99,7 +102,7 @@ private static void CompareScalarProperties(DataTable subject, DataTable expecta if (selectedMembers.ContainsKey(nameof(expectation.Locale))) { - AssertionScope.Current + assertionChain .ForCondition(Equals(subject.Locale, expectation.Locale)) .FailWith("Expected {context:DataTable} to have Locale value of {0}{reason}, but found {1} instead", expectation.Locale, subject.Locale); @@ -107,7 +110,7 @@ private static void CompareScalarProperties(DataTable subject, DataTable expecta if (selectedMembers.ContainsKey(nameof(expectation.Namespace))) { - AssertionScope.Current + assertionChain .ForCondition(subject.Namespace == expectation.Namespace) .FailWith("Expected {context:DataTable} to have Namespace value of {0}{reason}, but found {1} instead", expectation.Namespace, subject.Namespace); @@ -115,7 +118,7 @@ private static void CompareScalarProperties(DataTable subject, DataTable expecta if (selectedMembers.ContainsKey(nameof(expectation.Prefix))) { - AssertionScope.Current + assertionChain .ForCondition(subject.Prefix == expectation.Prefix) .FailWith("Expected {context:DataTable} to have Prefix value of {0}{reason}, but found {1} instead", expectation.Prefix, subject.Prefix); @@ -123,7 +126,7 @@ private static void CompareScalarProperties(DataTable subject, DataTable expecta if (selectedMembers.ContainsKey(nameof(expectation.RemotingFormat))) { - AssertionScope.Current + assertionChain .ForCondition(subject.RemotingFormat == expectation.RemotingFormat) .FailWith("Expected {context:DataTable} to have RemotingFormat value of {0}{reason}, but found {1} instead", expectation.RemotingFormat, subject.RemotingFormat); @@ -131,7 +134,8 @@ private static void CompareScalarProperties(DataTable subject, DataTable expecta } private static void CompareCollections(Comparands comparands, IEquivalencyValidationContext context, - IEquivalencyValidator parent, IEquivalencyAssertionOptions config, Dictionary selectedMembers) + IValidateChildNodeEquivalency parent, IEquivalencyOptions config, Dictionary selectedMembers, + AssertionChain assertionChain) { // Note: The collections here are listed in the XML documentation for the DataTable.BeEquivalentTo extension // method in DataTableAssertions.cs. If this ever needs to change, keep them in sync. @@ -150,7 +154,8 @@ private static void CompareCollections(Comparands comparands, IEquivalencyValida { if (selectedMembers.TryGetValue(collectionName, out IMember expectationMember)) { - IMember matchingMember = FindMatchFor(expectationMember, comparands.Subject, context.CurrentNode, config); + IMember matchingMember = FindMatchFor(expectationMember, comparands.Subject, context.CurrentNode, config, + assertionChain); if (matchingMember is not null) { @@ -163,18 +168,18 @@ private static void CompareCollections(Comparands comparands, IEquivalencyValida CompileTimeType = expectationMember.Type }; - parent.RecursivelyAssertEquality(nestedComparands, nestedContext); + parent.AssertEquivalencyOf(nestedComparands, nestedContext); } } } } private static IMember FindMatchFor(IMember selectedMemberInfo, object subject, INode currentNode, - IEquivalencyAssertionOptions config) + IEquivalencyOptions config, AssertionChain assertionChain) { IEnumerable query = from rule in config.MatchingRules - let match = rule.Match(selectedMemberInfo, subject, currentNode, config) + let match = rule.Match(selectedMemberInfo, subject, currentNode, config, assertionChain) where match is not null select match; @@ -182,7 +187,7 @@ where match is not null } private static IEnumerable GetMembersFromExpectation(INode currentNode, Comparands comparands, - IEquivalencyAssertionOptions config) + IEquivalencyOptions config) { IEnumerable members = Enumerable.Empty(); diff --git a/Src/FluentAssertions.DataSets/FluentAssertions.DataSets.csproj b/Src/FluentAssertions.DataSets/FluentAssertions.DataSets.csproj index 606ef1d..50bb0d2 100644 --- a/Src/FluentAssertions.DataSets/FluentAssertions.DataSets.csproj +++ b/Src/FluentAssertions.DataSets/FluentAssertions.DataSets.csproj @@ -39,10 +39,10 @@ - + - + diff --git a/Src/FluentAssertions.DataSets/IDataEquivalencyAssertionOptions.cs b/Src/FluentAssertions.DataSets/IDataEquivalencyAssertionOptions.cs index c43ad30..48f31bb 100644 --- a/Src/FluentAssertions.DataSets/IDataEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions.DataSets/IDataEquivalencyAssertionOptions.cs @@ -12,7 +12,7 @@ namespace FluentAssertions.DataSets; /// ). /// /// The System.Data type being tested for equivalency. -public interface IDataEquivalencyAssertionOptions : IEquivalencyAssertionOptions +public interface IDataEquivalencyAssertionOptions : IEquivalencyOptions { /// /// Specifies that the subject and the expectation should not be considered non-equivalent if their exact data types do not match. diff --git a/Src/FluentAssertions.DataSets/InitializeDataSetSupport.cs b/Src/FluentAssertions.DataSets/InitializeDataSetSupport.cs index dc0e3fa..250e52c 100644 --- a/Src/FluentAssertions.DataSets/InitializeDataSetSupport.cs +++ b/Src/FluentAssertions.DataSets/InitializeDataSetSupport.cs @@ -12,11 +12,16 @@ namespace FluentAssertions.DataSets; public static class InitializeDataSetSupport { + private static readonly object SyncObject = new(); + // ReSharper disable once UnusedMember.Global #pragma warning disable CA1822 public static void Initialize() #pragma warning restore CA1822 { - AssertionOptions.EquivalencyPlan.AddDataSetSupport(); + lock (SyncObject) + { + AssertionOptions.EquivalencyPlan.AddDataSetSupport(); + } } } diff --git a/Tests/Approval.Tests/ApiApproval.cs b/Tests/Approval.Tests/ApiApproval.cs index 005ce05..2bed357 100644 --- a/Tests/Approval.Tests/ApiApproval.cs +++ b/Tests/Approval.Tests/ApiApproval.cs @@ -1,97 +1,53 @@ -using System; -using System.Collections.Generic; -using System.IO; +using System.IO; +using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; -using System.Text; using System.Threading.Tasks; using System.Xml.Linq; using System.Xml.XPath; -using DiffPlex.DiffBuilder; -using DiffPlex.DiffBuilder.Model; using PublicApiGenerator; using VerifyTests; +using VerifyTests.DiffPlex; using VerifyXunit; using Xunit; namespace Approval.Tests; -[UsesVerify] public class ApiApproval { + static ApiApproval() => VerifyDiffPlex.Initialize(OutputType.Minimal); + [Theory] [ClassData(typeof(TargetFrameworksTheoryData))] - public Task ApproveApi(string frameworkVersion) + public Task ApproveApi(string framework) { - string codeBase = Assembly.GetExecutingAssembly().Location; - var uri = new UriBuilder(new Uri(codeBase)); - string assemblyPath = Uri.UnescapeDataString(uri.Path); - var containingDirectory = Path.GetDirectoryName(assemblyPath); - var configurationName = new DirectoryInfo(containingDirectory).Parent.Name; - - var assemblyFile = Path.GetFullPath( - Path.Combine( - GetSourceDirectory(), - Path.Combine("..", "..", "Src", "FluentAssertions.DataSets", "bin", configurationName, frameworkVersion, - "FluentAssertions.DataSets.dll"))); - - var assembly = Assembly.LoadFile(Path.GetFullPath(assemblyFile)); + var configuration = typeof(ApiApproval).Assembly.GetCustomAttribute()!.Configuration; + var assemblyFile = CombinedPaths("Src", "FluentAssertions.DataSets", "bin", configuration, framework, "FluentAssertions.DataSets.dll"); + var assembly = Assembly.LoadFile(assemblyFile); var publicApi = assembly.GeneratePublicApi(options: null); return Verifier .Verify(publicApi) .ScrubLinesContaining("FrameworkDisplayName") .UseDirectory(Path.Combine("ApprovedApi", "FluentAssertions.DataSets")) - .UseStringComparer(OnlyIncludeChanges) - .UseFileName(frameworkVersion) + .UseFileName(framework) .DisableDiff(); } - private static string GetSourceDirectory([CallerFilePath] string path = "") => Path.GetDirectoryName(path); - - // Copied from https://github.com/VerifyTests/Verify.DiffPlex/blob/master/src/Verify.DiffPlex/VerifyDiffPlex.cs - private static Task OnlyIncludeChanges(string received, string verified, IReadOnlyDictionary _) - { - var diff = InlineDiffBuilder.Diff(verified, received); - - var builder = new StringBuilder(); - - foreach (var line in diff.Lines) - { - switch (line.Type) - { - case ChangeType.Inserted: - builder.Append("+ "); - break; - case ChangeType.Deleted: - builder.Append("- "); - break; - default: - // omit unchanged files - continue; - } - - builder.AppendLine(line.Text); - } - - var compareResult = CompareResult.NotEqual(builder.ToString()); - return Task.FromResult(compareResult); - } - private class TargetFrameworksTheoryData : TheoryData { public TargetFrameworksTheoryData() { - var csproj = Path.Combine(GetSourceDirectory(), - Path.Combine("..", "..", "Src", "FluentAssertions.DataSets", "FluentAssertions.DataSets.csproj")); - + var csproj = CombinedPaths("Src", "FluentAssertions.DataSets", "FluentAssertions.DataSets.csproj"); var project = XDocument.Load(csproj); var targetFrameworks = project.XPathSelectElement("/Project/PropertyGroup/TargetFrameworks"); - - foreach (string targetFramework in targetFrameworks!.Value.Split(';')) - { - Add(targetFramework); - } + AddRange(targetFrameworks!.Value.Split(';')); } } + + private static string GetSolutionDirectory([CallerFilePath] string path = "") => + Path.Combine(Path.GetDirectoryName(path)!, "..", ".."); + + private static string CombinedPaths(params string[] paths) => + Path.GetFullPath(Path.Combine(paths.Prepend(GetSolutionDirectory()).ToArray())); } diff --git a/Tests/Approval.Tests/Approval.Tests.csproj b/Tests/Approval.Tests/Approval.Tests.csproj index 54639d6..f6953c3 100644 --- a/Tests/Approval.Tests/Approval.Tests.csproj +++ b/Tests/Approval.Tests/Approval.Tests.csproj @@ -5,16 +5,28 @@ - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions.DataSets/net47.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions.DataSets/net47.verified.txt index aa50a25..226e715 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions.DataSets/net47.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions.DataSets/net47.verified.txt @@ -54,7 +54,7 @@ namespace FluentAssertions.DataSets { public class DataColumnAssertions : FluentAssertions.Primitives.ReferenceTypeAssertions { - public DataColumnAssertions(System.Data.DataColumn dataColumn) { } + public DataColumnAssertions(System.Data.DataColumn dataColumn, FluentAssertions.Execution.AssertionChain assertionChain) { } protected override string Identifier { get; } public FluentAssertions.AndConstraint BeEquivalentTo(System.Data.DataColumn expectation, string because = "", params object[] becauseArgs) { } public FluentAssertions.AndConstraint BeEquivalentTo(System.Data.DataColumn expectation, System.Func, FluentAssertions.DataSets.IDataEquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) { } @@ -62,7 +62,7 @@ namespace FluentAssertions.DataSets public class DataRowAssertions : FluentAssertions.Primitives.ReferenceTypeAssertions> where TDataRow : System.Data.DataRow { - public DataRowAssertions(TDataRow dataRow) { } + public DataRowAssertions(TDataRow dataRow, FluentAssertions.Execution.AssertionChain assertionChain) { } protected override string Identifier { get; } public FluentAssertions.AndConstraint> BeEquivalentTo(System.Data.DataRow expectation, string because = "", params object[] becauseArgs) { } public FluentAssertions.AndConstraint> BeEquivalentTo(System.Data.DataRow expectation, System.Func, FluentAssertions.DataSets.IDataEquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) { } @@ -73,7 +73,7 @@ namespace FluentAssertions.DataSets public class DataSetAssertions : FluentAssertions.Primitives.ReferenceTypeAssertions> where TDataSet : System.Data.DataSet { - public DataSetAssertions(TDataSet dataSet) { } + public DataSetAssertions(TDataSet dataSet, FluentAssertions.Execution.AssertionChain assertionChain) { } protected override string Identifier { get; } public FluentAssertions.AndConstraint> BeEquivalentTo(System.Data.DataSet expectation, string because = "", params object[] becauseArgs) { } public FluentAssertions.AndConstraint> BeEquivalentTo(System.Data.DataSet expectation, System.Func, FluentAssertions.DataSets.IDataEquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) { } @@ -85,7 +85,7 @@ namespace FluentAssertions.DataSets public class DataTableAssertions : FluentAssertions.Primitives.ReferenceTypeAssertions> where TDataTable : System.Data.DataTable { - public DataTableAssertions(TDataTable dataTable) { } + public DataTableAssertions(TDataTable dataTable, FluentAssertions.Execution.AssertionChain assertionChain) { } protected override string Identifier { get; } public FluentAssertions.AndConstraint> BeEquivalentTo(System.Data.DataTable expectation, string because = "", params object[] becauseArgs) { } public FluentAssertions.AndConstraint> BeEquivalentTo(System.Data.DataTable expectation, System.Func, FluentAssertions.DataSets.IDataEquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) { } @@ -98,7 +98,7 @@ namespace FluentAssertions.DataSets { public static void AddDataSetSupport(this FluentAssertions.EquivalencyPlan plan) { } } - public interface IDataEquivalencyAssertionOptions : FluentAssertions.Equivalency.IEquivalencyAssertionOptions + public interface IDataEquivalencyAssertionOptions : FluentAssertions.Equivalency.IEquivalencyOptions { FluentAssertions.DataSets.IDataEquivalencyAssertionOptions AllowingMismatchedTypes(); FluentAssertions.DataSets.IDataEquivalencyAssertionOptions Excluding(System.Linq.Expressions.Expression> predicate); @@ -141,41 +141,41 @@ namespace FluentAssertions.DataSets.Equivalency public class ConstraintCollectionEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public ConstraintCollectionEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class ConstraintEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public ConstraintEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class DataColumnEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public DataColumnEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class DataRelationEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public DataRelationEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class DataRowCollectionEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public DataRowCollectionEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class DataRowEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public DataRowEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class DataSetEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public DataSetEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class DataTableEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public DataTableEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } } \ No newline at end of file diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions.DataSets/net6.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions.DataSets/net6.0.verified.txt index aa50a25..226e715 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions.DataSets/net6.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions.DataSets/net6.0.verified.txt @@ -54,7 +54,7 @@ namespace FluentAssertions.DataSets { public class DataColumnAssertions : FluentAssertions.Primitives.ReferenceTypeAssertions { - public DataColumnAssertions(System.Data.DataColumn dataColumn) { } + public DataColumnAssertions(System.Data.DataColumn dataColumn, FluentAssertions.Execution.AssertionChain assertionChain) { } protected override string Identifier { get; } public FluentAssertions.AndConstraint BeEquivalentTo(System.Data.DataColumn expectation, string because = "", params object[] becauseArgs) { } public FluentAssertions.AndConstraint BeEquivalentTo(System.Data.DataColumn expectation, System.Func, FluentAssertions.DataSets.IDataEquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) { } @@ -62,7 +62,7 @@ namespace FluentAssertions.DataSets public class DataRowAssertions : FluentAssertions.Primitives.ReferenceTypeAssertions> where TDataRow : System.Data.DataRow { - public DataRowAssertions(TDataRow dataRow) { } + public DataRowAssertions(TDataRow dataRow, FluentAssertions.Execution.AssertionChain assertionChain) { } protected override string Identifier { get; } public FluentAssertions.AndConstraint> BeEquivalentTo(System.Data.DataRow expectation, string because = "", params object[] becauseArgs) { } public FluentAssertions.AndConstraint> BeEquivalentTo(System.Data.DataRow expectation, System.Func, FluentAssertions.DataSets.IDataEquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) { } @@ -73,7 +73,7 @@ namespace FluentAssertions.DataSets public class DataSetAssertions : FluentAssertions.Primitives.ReferenceTypeAssertions> where TDataSet : System.Data.DataSet { - public DataSetAssertions(TDataSet dataSet) { } + public DataSetAssertions(TDataSet dataSet, FluentAssertions.Execution.AssertionChain assertionChain) { } protected override string Identifier { get; } public FluentAssertions.AndConstraint> BeEquivalentTo(System.Data.DataSet expectation, string because = "", params object[] becauseArgs) { } public FluentAssertions.AndConstraint> BeEquivalentTo(System.Data.DataSet expectation, System.Func, FluentAssertions.DataSets.IDataEquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) { } @@ -85,7 +85,7 @@ namespace FluentAssertions.DataSets public class DataTableAssertions : FluentAssertions.Primitives.ReferenceTypeAssertions> where TDataTable : System.Data.DataTable { - public DataTableAssertions(TDataTable dataTable) { } + public DataTableAssertions(TDataTable dataTable, FluentAssertions.Execution.AssertionChain assertionChain) { } protected override string Identifier { get; } public FluentAssertions.AndConstraint> BeEquivalentTo(System.Data.DataTable expectation, string because = "", params object[] becauseArgs) { } public FluentAssertions.AndConstraint> BeEquivalentTo(System.Data.DataTable expectation, System.Func, FluentAssertions.DataSets.IDataEquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) { } @@ -98,7 +98,7 @@ namespace FluentAssertions.DataSets { public static void AddDataSetSupport(this FluentAssertions.EquivalencyPlan plan) { } } - public interface IDataEquivalencyAssertionOptions : FluentAssertions.Equivalency.IEquivalencyAssertionOptions + public interface IDataEquivalencyAssertionOptions : FluentAssertions.Equivalency.IEquivalencyOptions { FluentAssertions.DataSets.IDataEquivalencyAssertionOptions AllowingMismatchedTypes(); FluentAssertions.DataSets.IDataEquivalencyAssertionOptions Excluding(System.Linq.Expressions.Expression> predicate); @@ -141,41 +141,41 @@ namespace FluentAssertions.DataSets.Equivalency public class ConstraintCollectionEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public ConstraintCollectionEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class ConstraintEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public ConstraintEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class DataColumnEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public DataColumnEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class DataRelationEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public DataRelationEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class DataRowCollectionEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public DataRowCollectionEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class DataRowEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public DataRowEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class DataSetEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public DataSetEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } public class DataTableEquivalencyStep : FluentAssertions.Equivalency.EquivalencyStep { public DataTableEquivalencyStep() { } - protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IEquivalencyValidator nestedValidator) { } + protected override FluentAssertions.Equivalency.EquivalencyResult OnHandle(FluentAssertions.Equivalency.Comparands comparands, FluentAssertions.Equivalency.IEquivalencyValidationContext context, FluentAssertions.Equivalency.IValidateChildNodeEquivalency nestedValidator) { } } } \ No newline at end of file diff --git a/Tests/Benchmarks/Benchmarks.csproj b/Tests/Benchmarks/Benchmarks.csproj index e3c4975..0d45d72 100644 --- a/Tests/Benchmarks/Benchmarks.csproj +++ b/Tests/Benchmarks/Benchmarks.csproj @@ -6,9 +6,8 @@ Exe - - - + + diff --git a/Tests/Benchmarks/Program.cs b/Tests/Benchmarks/Program.cs index ac922b0..8c7a7cb 100644 --- a/Tests/Benchmarks/Program.cs +++ b/Tests/Benchmarks/Program.cs @@ -1,10 +1,10 @@ using System.Globalization; -using BenchmarkDotNet.Columns; using BenchmarkDotNet.Configs; using BenchmarkDotNet.Exporters.Csv; using BenchmarkDotNet.Reports; using BenchmarkDotNet.Running; using Perfolizer.Horology; +using Perfolizer.Metrology; namespace Benchmarks; diff --git a/Tests/FluentAssertions.DataSets.Specs/DataRowCollectionAssertionSpecs.cs b/Tests/FluentAssertions.DataSets.Specs/DataRowCollectionAssertionSpecs.cs index b244288..2dea83b 100644 --- a/Tests/FluentAssertions.DataSets.Specs/DataRowCollectionAssertionSpecs.cs +++ b/Tests/FluentAssertions.DataSets.Specs/DataRowCollectionAssertionSpecs.cs @@ -367,7 +367,7 @@ public void When_collection_is_compared_with_null_it_should_fail() // Assert action.Should().Throw().WithMessage( - "Expected nullDataRows to not have the same count as * because we care, but found ."); + "Expected nullDataRows to not have the same count as*because we care, but found ."); } [Fact] @@ -516,7 +516,7 @@ public void When_collection_does_not_contain_equivalent_row_it_should_fail() // Assert action.Should().Throw().WithMessage( - "Expected dataTable.Rows * to contain equivalent of System.Data.DataRow* because we care.*"); + "Expected dataTable.Rows*to contain equivalent of System.Data.DataRow*because we care.*"); } } @@ -580,7 +580,7 @@ public void When_collection_contains_equivalent_row_it_should_fail() // Assert action.Should().Throw() - .WithMessage("Expected dataTable.Rows * not to contain equivalent of System.Data.DataRow* because we " + + .WithMessage("Expected dataTable.Rows*not to contain equivalent of System.Data.DataRow*because we " + "care, but found one at index 1.*"); } diff --git a/Tests/FluentAssertions.DataSets.Specs/DataSetSpecs.cs b/Tests/FluentAssertions.DataSets.Specs/DataSetSpecs.cs index 7d0855f..1d33d9d 100644 --- a/Tests/FluentAssertions.DataSets.Specs/DataSetSpecs.cs +++ b/Tests/FluentAssertions.DataSets.Specs/DataSetSpecs.cs @@ -617,7 +617,7 @@ public void When_data_set_table_count_matches_but_tables_are_different_equivalen // Assert action.Should().Throw() .WithMessage( - "Expected dataSet1.Relations[0].ExtendedProperties* to reference column *ForeignRowID* in table *Different*, but found a reference to *ForeignRowID* in table *TypedDataTable2* instead*"); + "Expected dataSet1.Relations[0]*to reference column*ForeignRowID*in table*Different*, but found a reference to*ForeignRowID*in table*TypedDataTable2*instead*"); } [Fact] diff --git a/Tests/FluentAssertions.DataSets.Specs/DataTableSpecs.cs b/Tests/FluentAssertions.DataSets.Specs/DataTableSpecs.cs index d339c19..eed892a 100644 --- a/Tests/FluentAssertions.DataSets.Specs/DataTableSpecs.cs +++ b/Tests/FluentAssertions.DataSets.Specs/DataTableSpecs.cs @@ -121,7 +121,7 @@ public void When_primary_key_of_one_rows_differ_it_should_fail() // Assert action.Should().Throw().WithMessage( - "Found unexpected row in *with key *Expected to find a row with key *in *, but no such row was found*"); + "Found unexpected row in*with key*"); } [Fact] @@ -147,7 +147,7 @@ public void When_primary_key_of_multiple_rows_differ_it_should_fail() // Assert action.Should().Throw().WithMessage( - "Found unexpected row in *with key * rows were expected in *and not found*"); + "Found unexpected row in*with key*"); } [Fact] diff --git a/Tests/FluentAssertions.DataSets.Specs/FluentAssertions.DataSets.Specs.csproj b/Tests/FluentAssertions.DataSets.Specs/FluentAssertions.DataSets.Specs.csproj index 2a76aad..988cb2d 100644 --- a/Tests/FluentAssertions.DataSets.Specs/FluentAssertions.DataSets.Specs.csproj +++ b/Tests/FluentAssertions.DataSets.Specs/FluentAssertions.DataSets.Specs.csproj @@ -20,7 +20,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive