/// <summary> /// Asserts that an instance of <see cref="DataSet"/> is equivalent to another. /// </summary> /// <remarks> /// Data sets are equivalent when their <see cref="DataSet.Tables"/> and <see cref="DataSet.ExtendedProperties"/> /// collections are equivalent and the following members have the same values: /// /// <list type="bullet"> /// <item><description>DataSetName</description></item> /// <item><description>CaseSensitive</description></item> /// <item><description>EnforceConstraints</description></item> /// <item><description>HasErrors</description></item> /// <item><description>Locale</description></item> /// <item><description>Namespace</description></item> /// <item><description>Prefix</description></item> /// <item><description>RemotingFormat</description></item> /// <item><description>SchemaSerializationMode</description></item> /// </list> /// /// The <see cref="DataSet"/> objects must be of the same type; if two <see cref="DataSet"/> objects /// are equivalent in all ways, except that one is a custom subclass of <see cref="DataSet"/> (e.g. to provide /// typed accessors for <see cref="DataTable"/> values contained by the <see cref="DataSet"/>), then by default, /// they will not be considered equivalent. /// /// This, as well as testing of any property can be overridden using the <paramref name="config"/> callback. /// By calling <see cref="IDataEquivalencyAssertionOptions{T}.AllowingMismatchedTypes"/>, two <see cref="DataSet"/> /// objects of differing types can be considered equivalent. This setting applies to all types recursively tested /// as part of the <see cref="DataSet"/>. /// /// Exclude specific properties using <see cref="IDataEquivalencyAssertionOptions{T}.Excluding(System.Linq.Expressions.Expression{Func{T, object}})"/>. /// Exclude specific tables within the data set using <see cref="IDataEquivalencyAssertionOptions{T}.ExcludingTable(string)"/> /// or a related function. You can also indicate that columns should be excluded within the <see cref="DataTable"/> /// objects recursively tested as part of the <see cref="DataSet"/> using <see cref="IDataEquivalencyAssertionOptions{T}.ExcludingColumn(DataColumn)"/> /// or a related function. The <see cref="IDataEquivalencyAssertionOptions{T}.ExcludingColumnInAllTables(string)"/> method /// can be used to exclude columns across all <see cref="DataTable"/> objects in the <see cref="DataSet"/> that share /// the same name. /// /// You can use <see cref="IDataEquivalencyAssertionOptions{T}.ExcludingRelated(System.Linq.Expressions.Expression{Func{DataTable, object}})"/> /// and related functions to exclude properties on other related System.Data types. /// </remarks> /// <param name="expectation">A <see cref="DataColumn"/> with the expected configuration.</param> /// <param name="config"> /// A reference to the <see cref="IDataEquivalencyAssertionOptions{DataSet}"/> configuration object that can be used /// to influence the way the object graphs are compared. You can also provide an alternative instance of the /// <see cref="IDataEquivalencyAssertionOptions{DataSet}"/> class. The global defaults are determined by the /// <see cref="AssertionOptions"/> class. /// </param> /// <param name="because"> /// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion /// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. /// </param> /// <param name="becauseArgs"> /// Zero or more objects to format using the placeholders in <paramref name="because"/>. /// </param> public AndConstraint <DataSetAssertions <TDataSet> > BeEquivalentTo(DataSet expectation, Func <IDataEquivalencyAssertionOptions <DataSet>, IDataEquivalencyAssertionOptions <DataSet> > config, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(config, nameof(config)); IDataEquivalencyAssertionOptions <DataSet> options = config(AssertionOptions.CloneDefaults <DataSet, DataEquivalencyAssertionOptions <DataSet> >(e => new(e))); var comparands = new Comparands { Subject = Subject, Expectation = expectation, CompileTimeType = typeof(TDataSet) }; var context = new EquivalencyValidationContext(Node.From <DataSet>(() => AssertionScope.Current.CallerIdentity), options) { Reason = new Reason(because, becauseArgs), TraceWriter = options.TraceWriter, }; var equivalencyValidator = new EquivalencyValidator(); equivalencyValidator.AssertEquality(comparands, context); return(new AndConstraint <DataSetAssertions <TDataSet> >(this)); }
/// <summary> /// Asserts that a collection of objects is equivalent to another collection of objects. /// </summary> /// <remarks> /// The two collections are equivalent when they both contain the same strings in any order. /// </remarks> /// <param name="config"> /// A reference to the <see cref="EquivalencyAssertionOptions{String}"/> configuration object that can be used /// to influence the way the object graphs are compared. You can also provide an alternative instance of the /// <see cref="EquivalencyAssertionOptions{String}"/> class. The global defaults are determined by the /// <see cref="AssertionOptions"/> class. /// </param> /// <param name="because"> /// An optional formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the /// assertion is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. /// </param> /// <param name="becauseArgs"> /// Zero or more objects to format using the placeholders in <see cref="because" />. /// </param> public AndConstraint <StringCollectionAssertions> BeEquivalentTo(IEnumerable <string> expectation, Func <EquivalencyAssertionOptions <string>, EquivalencyAssertionOptions <string> > config, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(config, nameof(config)); EquivalencyAssertionOptions <IEnumerable <string> > options = config(AssertionOptions.CloneDefaults <string>()).AsCollection(); var context = new EquivalencyValidationContext { Subject = Subject, Expectation = expectation, RootIsCollection = true, CompileTimeType = typeof(IEnumerable <string>), Because = because, BecauseArgs = becauseArgs, Tracer = options.TraceWriter }; var equivalencyValidator = new EquivalencyValidator(options); equivalencyValidator.AssertEquality(context); return(new AndConstraint <StringCollectionAssertions>(this)); }
public static AndConstraint <GenericCollectionAssertions <T> > NotContainEquivalentOf <T>( this GenericCollectionAssertions <T> assert, T expectation, Func <EquivalencyAssertionOptions <T>, EquivalencyAssertionOptions <T> > config, string because = "", params object[] becauseArgs) { if (ReferenceEquals(assert.Subject, null)) { return(new AndConstraint <GenericCollectionAssertions <T> >(assert)); } IEquivalencyAssertionOptions options = config(AssertionOptions.CloneDefaults <T>()); IEnumerable <object> actualItems = assert.Subject.Cast <object>(); using (var scope = new AssertionScope()) { scope.AddReportable("configuration", options.ToString()); foreach (var actualItem in actualItems) { var context = new EquivalencyValidationContext { Subject = actualItem, Expectation = expectation, CompileTimeType = typeof(T), Because = because, BecauseArgs = becauseArgs, Tracer = options.TraceWriter, }; var equivalencyValidator = new EquivalencyValidator(options); equivalencyValidator.AssertEquality(context); var failures = scope.Discard(); if (!failures.Any()) { Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {context:collection} {0} to not contain equivalent of {1}.", assert.Subject, expectation); break; } } } return(new AndConstraint <GenericCollectionAssertions <T> >(assert)); }
/// <summary> /// Asserts that an object is equivalent to another object. /// </summary> /// <remarks> /// Objects are equivalent when both object graphs have equally named properties with the same value, /// irrespective of the type of those objects. Two properties are also equal if one type can be converted to another and the result is equal. /// The type of a collection property is ignored as long as the collection implements <see cref="IEnumerable{T}"/> and all /// items in the collection are structurally equal. /// </remarks> /// <param name="config"> /// A reference to the <see cref="EquivalencyAssertionOptions{TSubject}"/> configuration object that can be used /// to influence the way the object graphs are compared. You can also provide an alternative instance of the /// <see cref="EquivalencyAssertionOptions{TSubject}"/> class. The global defaults are determined by the /// <see cref="AssertionOptions"/> class. /// </param> /// <param name="because"> /// An optional formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the /// assertion is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. /// </param> /// <param name="becauseArgs"> /// Zero or more objects to format using the placeholders in <see cref="because" />. /// </param> public void BeEquivalentTo <TExpectation>(TExpectation expectation, Func <EquivalencyAssertionOptions <TExpectation>, EquivalencyAssertionOptions <TExpectation> > config, string because = "", params object[] becauseArgs) { IEquivalencyAssertionOptions options = config(AssertionOptions.CloneDefaults <TExpectation>()); var context = new EquivalencyValidationContext { Subject = Subject, Expectation = expectation, CompileTimeType = typeof(TExpectation), Because = because, BecauseArgs = becauseArgs, Tracer = options.TraceWriter }; var equivalencyValidator = new EquivalencyValidator(options); equivalencyValidator.AssertEquality(context); }
/// <summary> /// Asserts that a collection of objects is equivalent to another collection of objects. /// </summary> /// <remarks> /// Objects within the collections are equivalent when both object graphs have equally named properties with the same /// value, irrespective of the type of those objects. Two properties are also equal if one type can be converted to another /// and the result is equal. /// The type of a collection property is ignored as long as the collection implements <see cref="IEnumerable"/> and all /// items in the collection are structurally equal. /// </remarks> /// <param name="config"> /// A reference to the <see cref="EquivalencyAssertionOptions{TSubject}"/> configuration object that can be used /// to influence the way the object graphs are compared. You can also provide an alternative instance of the /// <see cref="EquivalencyAssertionOptions{TSubject}"/> class. The global defaults are determined by the /// <see cref="AssertionOptions"/> class. /// </param> /// <param name="because"> /// An optional formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the /// assertion is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. /// </param> /// <param name="becauseArgs"> /// Zero or more objects to format using the placeholders in <see cref="because" />. /// </param> public void BeEquivalentTo(IEnumerable expectation, Func <EquivalencyAssertionOptions <IEnumerable>, EquivalencyAssertionOptions <IEnumerable> > config, string because = "", params object[] becauseArgs) { EquivalencyAssertionOptions <IEnumerable> options = config(AssertionOptions.CloneDefaults <IEnumerable>()); var context = new EquivalencyValidationContext { Subject = Subject, Expectation = expectation, RootIsCollection = true, CompileTimeType = typeof(IEnumerable), Because = because, BecauseArgs = becauseArgs, Tracer = options.TraceWriter }; var equivalencyValidator = new EquivalencyValidator(options); equivalencyValidator.AssertEquality(context); }
public static void ShouldNotBeEquivalentToDefault<T>( this T subject, Func<EquivalencyAssertionOptions<T>, EquivalencyAssertionOptions<T>> config, string because = "", params object[] reasonArgs ) { var context = new EquivalencyValidationContext { Subject = subject, Expectation = subject, CompileTimeType = typeof( T ), Reason = because, ReasonArgs = reasonArgs }; var validator = new EquivalencyValidator( config( EquivalencyAssertionOptions<T>.Default() .Using<string>( ctx => ctx.Subject.Should().NotBeDefault() ).WhenTypeIs<string>() ) .WithStrictOrdering() ); validator.Steps.Remove( validator.Steps.Single( _ => typeof( TryConversionEquivalencyStep ) == _.GetType() ) ); validator.Steps.Remove( validator.Steps.Single( _ => typeof( ReferenceEqualityEquivalencyStep ) == _.GetType() ) ); validator.Steps.Remove( validator.Steps.Single( _ => typeof( SimpleEqualityEquivalencyStep ) == _.GetType() ) ); validator.Steps.Add( new SimpleIsNotDefaultEquivalencyStep() ); validator.AssertEquality( context ); }