private string[] TryToMatch <T>(object subject, T expectation, int expectationIndex) { using var scope = new AssertionScope(); parent.RecursivelyAssertEquality(new Comparands(subject, expectation, typeof(T)), context.AsCollectionItem <T>(expectationIndex)); return(scope.Discard()); }
private string[] TryToMatch <T>(object subject, T expectation, int expectationIndex) { using (var scope = new AssertionScope()) { parent.RecursivelyAssertEquality(context.CreateForCollectionItem(expectationIndex.ToString(), subject, expectation)); return(scope.Discard()); } }
public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) { Array expectationAsArray = comparands.Expectation as Array; if (expectationAsArray is null || expectationAsArray?.Rank == 1) { return(EquivalencyResult.ContinueWithNext); } if (AreComparable(comparands, expectationAsArray)) { if (expectationAsArray.Length == 0) { return(EquivalencyResult.AssertionCompleted); } Digit digit = BuildDigitsRepresentingAllIndices(expectationAsArray); do { int[] indices = digit.GetIndices(); object subject = ((Array)comparands.Subject).GetValue(indices); string listOfIndices = string.Join(",", indices); object expectation = expectationAsArray.GetValue(indices); IEquivalencyValidationContext itemContext = context.AsCollectionItem <object>(listOfIndices); nestedValidator.RecursivelyAssertEquality(new Comparands(subject, expectation, typeof(object)), itemContext); }while (digit.Increment()); } return(EquivalencyResult.AssertionCompleted); }
protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) { var subject = comparands.Subject as IDictionary; var expectation = comparands.Expectation as IDictionary; if (PreconditionsAreMet(expectation, subject)) { if (expectation is not null) { foreach (object key in expectation.Keys) { if (context.Options.IsRecursive) { context.Tracer.WriteLine(member => Invariant($"Recursing into dictionary item {key} at {member.Description}")); nestedValidator.RecursivelyAssertEquality(new Comparands(subject[key], expectation[key], typeof(object)), context.AsDictionaryItem <object, IDictionary>(key)); } else { context.Tracer.WriteLine(member => Invariant($"Comparing dictionary item {key} at {member.Description} between subject and expectation")); subject[key].Should().Be(expectation[key], context.Reason.FormattedMessage, context.Reason.Arguments); } } } } return(EquivalencyResult.AssertionCompleted); }
public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { Array expectationAsArray = (Array)context.Expectation; if (AreComparable(context, expectationAsArray)) { Digit digit = BuildDigitsRepresentingAllIndices(expectationAsArray); do { int[] indices = digit.GetIndices(); object subject = ((Array)context.Subject).GetValue(indices); string listOfIndices = string.Join(",", indices); object expectation = expectationAsArray.GetValue(indices); IEquivalencyValidationContext itemContext = context.CreateForCollectionItem( listOfIndices, subject, expectation); parent.RecursivelyAssertEquality(itemContext); }while (digit.Increment()); } return(true); }
public virtual bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { var subject = context.Subject as IDictionary; var expectation = context.Expectation as IDictionary; if (PreconditionsAreMet(expectation, subject)) { if (expectation != null) { foreach (object key in expectation.Keys) { if (config.IsRecursive) { context.TraceSingle(path => $"Recursing into dictionary item {key} at {path}"); parent.RecursivelyAssertEquality(context.CreateForDictionaryItem(key, subject[key], expectation[key])); } else { context.TraceSingle(path => $"Comparing dictionary item {key} at {path} between subject and expectation"); subject[key].Should().Be(expectation[key], context.Because, context.BecauseArgs); } } } } return(true); }
/// <summary> /// Applies a step as part of the task to compare two objects for structural equality. /// </summary> /// <value> /// Should return <c>true</c> if the subject matches the expectation or if no additional assertions /// have to be executed. Should return <c>false</c> otherwise. /// </value> /// <remarks> /// May throw when preconditions are not met or if it detects mismatching data. /// </remarks> public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator structuralEqualityValidator, IEquivalencyAssertionOptions config) { if ((context.Expectation is null) || (context.Subject is null)) { return(false); } Type subjectType = context.Subject.GetType(); Type expectationType = context.Expectation.GetType(); if (subjectType.IsSameOrInherits(expectationType)) { return(false); } if (TryChangeType(context.Subject, expectationType, out object convertedSubject)) { context.TraceSingle(path => $"Converted subject {context.Subject} at {path} to {expectationType}"); var newContext = context.CreateWithDifferentSubject(convertedSubject, expectationType); structuralEqualityValidator.RecursivelyAssertEquality(newContext); return(true); } context.TraceSingle(path => $"Subject {context.Subject} at {path} could not be converted to {expectationType}"); return(false); }
private static void AssertDictionaryEquivalence <TSubjectKey, TSubjectValue, TExpectedKey, TExpectedValue>( EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config, IDictionary <TSubjectKey, TSubjectValue> subject, IDictionary <TExpectedKey, TExpectedValue> expectation) where TExpectedKey : TSubjectKey { foreach (TExpectedKey key in expectation.Keys) { if (subject.TryGetValue(key, out TSubjectValue subjectValue)) { if (config.IsRecursive) { parent.RecursivelyAssertEquality(context.CreateForDictionaryItem(key, subjectValue, expectation[key])); } else { subjectValue.Should().Be(expectation[key], context.Because, context.BecauseArgs); } } else { AssertionScope.Current.FailWith("Expected {context:subject} to contain key {0}.", key); } } }
private static void MatchRowsByIndexAndCompare(IEquivalencyValidationContext context, IEquivalencyValidator parent, DataRowCollection subject, DataRowCollection expectation) { for (int index = 0; index < expectation.Count; index++) { IEquivalencyValidationContext nestedContext = context.AsCollectionItem <DataRow>(index); parent.RecursivelyAssertEquality(new Comparands(subject[index], expectation[index], typeof(DataRow)), nestedContext); } }
private static void AssertMemberEquality(IEquivalencyValidationContext context, IEquivalencyValidator parent, SelectedMemberInfo selectedMemberInfo, IEquivalencyAssertionOptions config) { SelectedMemberInfo matchingMember = FindMatchFor(selectedMemberInfo, context, config); if (matchingMember != null) { IEquivalencyValidationContext nestedContext = context.CreateForNestedMember(selectedMemberInfo, matchingMember); if (nestedContext != null) { parent.RecursivelyAssertEquality(nestedContext); } } }
private static void CompareFieldValue(IEquivalencyValidationContext context, IEquivalencyValidator parent, DataRow subject, DataRow expectation, DataColumn subjectColumn, DataRowVersion subjectVersion, DataColumn expectationColumn, DataRowVersion expectationVersion) { IEquivalencyValidationContext nestedContext = context.AsCollectionItem <object>( subjectVersion == DataRowVersion.Current ? subjectColumn.ColumnName : $"{subjectColumn.ColumnName}, DataRowVersion.Original"); if (nestedContext is not null) { parent.RecursivelyAssertEquality( new Comparands(subject[subjectColumn, subjectVersion], expectation[expectationColumn, expectationVersion], typeof(object)), nestedContext); } }
private static void AssertMemberEquality(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator parent, IMember selectedMember, IEquivalencyAssertionOptions options) { IMember matchingMember = FindMatchFor(selectedMember, context.CurrentNode, comparands.Subject, options); if (matchingMember is not null) { var nestedComparands = new Comparands { Subject = matchingMember.GetValue(comparands.Subject), Expectation = selectedMember.GetValue(comparands.Expectation), CompileTimeType = selectedMember.Type }; parent.RecursivelyAssertEquality(nestedComparands, context.AsNestedMember(selectedMember)); } }
protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) { if (comparands.Subject is not ConstraintCollection) { AssertionScope.Current .FailWith("Expected a value of type ConstraintCollection at {context:Constraints}, but found {0}", comparands.Subject.GetType()); } else { var subject = (ConstraintCollection)comparands.Subject; var expectation = (ConstraintCollection)comparands.Expectation; var subjectConstraints = subject.Cast <Constraint>().ToDictionary(constraint => constraint.ConstraintName); var expectationConstraints = expectation.Cast <Constraint>().ToDictionary(constraint => constraint.ConstraintName); IEnumerable <string> constraintNames = subjectConstraints.Keys.Union(expectationConstraints.Keys); foreach (var constraintName in constraintNames) { AssertionScope.Current .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 .ForCondition(expectationConstraints.TryGetValue(constraintName, out Constraint expectationConstraint)) .FailWith("Found unexpected constraint named {0} in {context:Constraints collection}", constraintName); if ((subjectConstraint is not null) && (expectationConstraint is not null)) { Comparands newComparands = new() { Subject = subjectConstraint, Expectation = expectationConstraint, CompileTimeType = typeof(Constraint) }; IEquivalencyValidationContext nestedContext = context.AsCollectionItem <Constraint>(constraintName); nestedValidator.RecursivelyAssertEquality(newComparands, nestedContext); } } } return(EquivalencyResult.AssertionCompleted); } }
private static void CompareDataRelationKeyConstraint(DataRelation subject, DataRelation expectation, IEquivalencyValidator parent, IEquivalencyValidationContext context, Dictionary <string, IMember> selectedMembers, string relationDirection) { if (selectedMembers.TryGetValue(relationDirection + "KeyConstraint", out IMember expectationMember)) { IMember subjectMember = FindMatchFor(expectationMember, context.CurrentNode, subject, context.Options); var newComparands = new Comparands { Subject = subjectMember.GetValue(subject), Expectation = expectationMember.GetValue(expectation), CompileTimeType = expectationMember.Type }; parent.RecursivelyAssertEquality(newComparands, context.AsNestedMember(expectationMember)); } }
private static void CompareTable(IEquivalencyValidationContext context, IEquivalencyValidator parent, DataSet subject, DataSet expectation, string tableName) { DataTable expectationTable = expectation.Tables[tableName]; DataTable subjectTable = subject.Tables[tableName]; bool success = AssertionScope.Current .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) { IEquivalencyValidationContext nestedContext = context.AsCollectionItem <DataTable>(tableName); parent.RecursivelyAssertEquality(new Comparands(subjectTable, expectationTable, typeof(DataTable)), nestedContext); } }
private static void CompareCollections(IEquivalencyValidationContext context, Comparands comparands, IEquivalencyValidator parent, IEquivalencyAssertionOptions config, Dictionary <string, IMember> selectedMembers) { if (selectedMembers.TryGetValue(nameof(DataRelation.ExtendedProperties), out IMember expectationMember)) { IMember matchingMember = FindMatchFor(expectationMember, context.CurrentNode, comparands.Subject, config); if (matchingMember is not null) { var nestedComparands = new Comparands { Subject = matchingMember.GetValue(comparands.Subject), Expectation = expectationMember.GetValue(comparands.Expectation), CompileTimeType = expectationMember.Type }; parent.RecursivelyAssertEquality(nestedComparands, context.AsNestedMember(expectationMember)); } } }
private static void CompareMember(IMember expectationMember, Comparands comparands, IEquivalencyValidator parent, IEquivalencyValidationContext context) { IMember matchingMember = FindMatchFor(expectationMember, comparands.Subject, context); if (matchingMember is not null) { var nestedComparands = new Comparands { Subject = matchingMember.GetValue(comparands.Subject), Expectation = expectationMember.GetValue(comparands.Expectation), CompileTimeType = expectationMember.Type }; if (context.AsNestedMember(expectationMember) is not null) { parent.RecursivelyAssertEquality(nestedComparands, context.AsNestedMember(expectationMember)); } } }
private static void AssertMemberEquality(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator parent, IMember selectedMember, IEquivalencyAssertionOptions options) { IMember matchingMember = FindMatchFor(selectedMember, context.CurrentNode, comparands.Subject, options); if (matchingMember is not null) { var nestedComparands = new Comparands { Subject = matchingMember.GetValue(comparands.Subject), Expectation = selectedMember.GetValue(comparands.Expectation), CompileTimeType = selectedMember.Type }; if (selectedMember.Name != matchingMember.Name) { // In case the matching process selected a different member on the subject, // adjust the current member so that assertion failures report the proper name. selectedMember.Name = matchingMember.Name; } parent.RecursivelyAssertEquality(nestedComparands, context.AsNestedMember(selectedMember)); } }
private static void CompareCollections(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config, Dictionary <string, IMember> selectedMembers) { // 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. var collectionNames = new[] { nameof(DataTable.ChildRelations), nameof(DataTable.Columns), nameof(DataTable.Constraints), nameof(DataTable.ExtendedProperties), nameof(DataTable.ParentRelations), nameof(DataTable.PrimaryKey), nameof(DataTable.Rows), }; foreach (var collectionName in collectionNames) { if (selectedMembers.TryGetValue(collectionName, out IMember expectationMember)) { IMember matchingMember = FindMatchFor(expectationMember, comparands.Subject, context.CurrentNode, config); if (matchingMember is not null) { IEquivalencyValidationContext nestedContext = context.AsNestedMember(expectationMember); var nestedComparands = new Comparands { Subject = matchingMember.GetValue(comparands.Subject), Expectation = expectationMember.GetValue(comparands.Expectation), CompileTimeType = expectationMember.Type }; parent.RecursivelyAssertEquality(nestedComparands, nestedContext); } } } }
private static void AssertDictionaryEquivalence <TSubjectKey, TSubjectValue, TExpectedKey, TExpectedValue>( EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions options, IDictionary <TSubjectKey, TSubjectValue> subject, IDictionary <TExpectedKey, TExpectedValue> expectation) where TExpectedKey : TSubjectKey { foreach (TExpectedKey key in expectation.Keys) { if (subject.TryGetValue(key, out TSubjectValue subjectValue)) { if (options.IsRecursive) { // Run the child assertion without affecting the current context using (new AssertionScope()) { var nestedComparands = new Comparands(subject[key], expectation[key], typeof(TExpectedValue)); parent.RecursivelyAssertEquality(nestedComparands, context.AsDictionaryItem <TExpectedKey, TExpectedValue>(key)); } } else { subjectValue.Should().Be(expectation[key], context.Reason.FormattedMessage, context.Reason.Arguments); } } else { AssertionScope.Current .BecauseOf(context.Reason) .FailWith("Expected {context:subject} to contain key {0}{reason}.", key); } } }