/// <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(EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { bool expectationIsNotNull = AssertionScope.Current .ForCondition(!ReferenceEquals(context.Expectation, null)) .FailWith( "Expected {context:subject} to be <null>, but found {0}.", context.Subject); bool subjectIsNotNull = AssertionScope.Current.ForCondition( !ReferenceEquals(context.Subject, null)) .FailWith( "Expected {context:object} to be {0}{reason}, but found {1}.", context.Expectation, context.Subject); IEnumerable<PropertyInfo> selectedProperties = GetSelectedProperties(context, config).ToArray(); if (context.IsRoot && !selectedProperties.Any()) { throw new InvalidOperationException( "No properties were found for comparison. " + "Please specify some properties to include in the comparison or choose a more meaningful assertion."); } if (expectationIsNotNull && subjectIsNotNull) { foreach (PropertyInfo propertyInfo in selectedProperties) { AssertPropertyEquality(context, parent, propertyInfo, config); } } 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(EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { bool expectationIsNotNull = AssertionScope.Current .ForCondition(!ReferenceEquals(context.Expectation, null)) .FailWith( "Expected {context:subject} to be <null>, but found {0}.", context.Subject); bool subjectIsNotNull = AssertionScope.Current.ForCondition( !ReferenceEquals(context.Subject, null)) .FailWith( "Expected {context:object} to be {0}{reason}, but found {1}.", context.Expectation, context.Subject); IEnumerable <PropertyInfo> selectedProperties = GetSelectedProperties(context, config).ToArray(); if (context.IsRoot && !selectedProperties.Any()) { throw new InvalidOperationException( "No properties were found for comparison. " + "Please specify some properties to include in the comparison or choose a more meaningful assertion."); } if (expectationIsNotNull && subjectIsNotNull) { foreach (PropertyInfo propertyInfo in selectedProperties) { AssertPropertyEquality(context, parent, propertyInfo, config); } } return(true); }
public void AssertEqualityUsing(EquivalencyValidationContext context) { if (ContinueRecursion(context.PropertyPath)) { AssertionScope scope = AssertionScope.Current; scope.AddNonReportable("context", context.IsRoot ? "subject" : context.PropertyDescription); scope.AddNonReportable("subject", context.Subject); scope.AddNonReportable("expectation", context.Expectation); var objectTracker = scope.Get<ObjectTracker>("objects"); if (!objectTracker.IsCyclicReference(new ObjectReference(context.Subject, context.PropertyPath))) { bool wasHandled = false; foreach (var strategy in steps.Where(s => s.CanHandle(context, config))) { if (strategy.Handle(context, this, config)) { wasHandled = true; break; } } if (!wasHandled) { Execute.Assertion.FailWith( "No IEquivalencyStep was found to handle the context. " + "This is likely a bug in Fluent Assertions."); } } } }
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) { TSubjectValue subjectValue; if (subject.TryGetValue(key, out subjectValue)) { if (config.IsRecursive) { parent.AssertEqualityUsing(context.CreateForDictionaryItem(key, subject[key], expectation[key])); } else { subject[key].Should().Be(expectation[key], context.Because, context.BecauseArgs); } } else { AssertionScope.Current.FailWith("Expected {context:subject} to contain key {0}.", key); } } }
/// <summary> /// Gets a value indicating whether this step can handle the current subject and/or expectation. /// </summary> public bool CanHandle(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { Type type = context.RuntimeType; return (type != null) && (type != typeof (object)) && (type.Namespace == typeof (int).Namespace); }
private static void AssertExpectationIsCollection(EquivalencyValidationContext context) { context.Verification .ForCondition(IsCollection(context.Expectation)) .FailWith((context.IsRoot ? "Subject" : context.PropertyDescription) + " is a collection and cannot be compared with a non-collection type.", context.Subject, context.Subject.GetType().FullName); }
/// <summary> /// Gets a value indicating whether this step can handle the current subject and/or expectation. /// </summary> public bool CanHandle(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { Type type = context.RuntimeType; return((type != null) && (type != typeof(object)) && (type.Namespace == typeof(int).Namespace)); }
/// <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 virtual bool Handle(EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { if (context.PropertyInfo != null) { return(config.AssertionRules.Any(rule => rule.AssertEquality(context))); } return(false); }
/// <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(EquivalencyValidationContext context, IEquivalencyValidator parent) { if (context.PropertyInfo != null) { return context.Config.AssertionRules.Any(rule => rule.AssertEquality(context)); } return false; }
private void AssertPropertyEquality(EquivalencyValidationContext context, IEquivalencyValidator parent, PropertyInfo propertyInfo) { var nestedContext = context.CreateForNestedProperty(propertyInfo); if (nestedContext != null) { parent.AssertEqualityUsing(nestedContext); } }
private static void AssertCollectionsHaveEqualLength(EquivalencyValidationContext context, object[] subject, object[] expectation) { context.Verification .ForCondition(subject.Length == expectation.Length) .FailWith( "Expected " + (context.IsRoot ? "subject" : context.PropertyDescription) + " to be a collection with {0} item(s){reason}, but found {1}.", expectation.Length, subject.Length); }
private PropertyInfo FindMatchFor(PropertyInfo propertyInfo, EquivalencyValidationContext context, IEnumerable<IMatchingRule> matchingRules) { var query = from rule in matchingRules let match = rule.Match(propertyInfo, context.Expectation, context.PropertyDescription) where match != null select match; return query.FirstOrDefault(); }
private PropertyInfo FindMatchFor(PropertyInfo propertyInfo, EquivalencyValidationContext context, IEnumerable <IMatchingRule> matchingRules) { var query = from rule in matchingRules let match = rule.Match(propertyInfo, context.Expectation, context.PropertyDescription) where match != null select match; return(query.FirstOrDefault()); }
public void AssertEquality(EquivalencyValidationContext context) { try { AssertEqualityUsing(context); } catch (Exception exc) { Execute.Verification.FailWith(exc.Message + "\n" + context.Config); } }
private void EnumerateElements(EquivalencyValidationContext context, object[] subject, object[] expectation, IEquivalencyValidator parent) { if (!subject.SequenceEqual(expectation)) { for (int i = 0; i < subject.Length; i++) { parent.AssertEqualityUsing(context.CreateForCollectionItem(i, subject[i], expectation[i])); } } }
internal IEnumerable <PropertyInfo> GetSelectedProperties(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { IEnumerable <PropertyInfo> properties = Enumerable.Empty <PropertyInfo>(); foreach (ISelectionRule selectionRule in config.SelectionRules) { properties = selectionRule.SelectProperties(properties, context); } return(properties.Where(IsNotIndexer)); }
internal IEnumerable<PropertyInfo> GetSelectedProperties(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { IEnumerable<PropertyInfo> properties = new List<PropertyInfo>(); foreach (ISelectionRule selectionRule in config.SelectionRules) { properties = selectionRule.SelectProperties(properties, context); } return properties; }
private void AssertPropertyEquality(EquivalencyValidationContext context, IEquivalencyValidator parent, PropertyInfo propertyInfo, IEquivalencyAssertionOptions config) { var matchingProperty = FindMatchFor(propertyInfo, context, config.MatchingRules); if (matchingProperty != null) { EquivalencyValidationContext nestedContext = context.CreateForNestedProperty(propertyInfo, matchingProperty); if (nestedContext != null) { parent.AssertEqualityUsing(nestedContext); } } }
public void AssertEquality(EquivalencyValidationContext context) { using (var scope = new AssertionScope()) { scope.AddReportable("configuration", config.ToString()); scope.AddNonReportable("objects", new ObjectTracker(config.CyclicReferenceHandling)); scope.BecauseOf(context.Because, context.BecauseArgs); AssertEqualityUsing(context); } }
public void AssertEquality(EquivalencyValidationContext context) { using (var scope = new AssertionScope()) { scope.AddReportable("configuration", config.ToString()); scope.AddNonReportable("objects", new ObjectTracker(config.CyclicReferenceHandling)); scope.BecauseOf(context.Reason, context.ReasonArgs); AssertEqualityUsing(context); } }
internal IEnumerable <PropertyInfo> GetSelectedProperties(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { IEnumerable <PropertyInfo> properties = new List <PropertyInfo>(); foreach (ISelectionRule selectionRule in config.SelectionRules) { properties = selectionRule.SelectProperties(properties, context); } return(properties); }
/// <summary> /// Asserts that the previously selected properties of <typeparamref name="T"/> have the same value as the equally named /// properties of <paramref name="expectation"/>. /// </summary> /// <param name="expectation">The object to compare the current object with</param> /// <remarks> /// Property values are considered equal if, after converting them to the requested type, calling <see cref="EqualTo(object)"/> /// returns <c>true</c>. /// </remarks> /// <param name="reason"> /// 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="reasonArgs"> /// Zero or more objects to format using the placeholders in <see cref="reason"/>. /// </param> public void EqualTo(object expectation, string reason = "", params object[] reasonArgs) { var context = new EquivalencyValidationContext { Subject = subject, Expectation = expectation, CompileTimeType = typeof(T), Reason = reason, ReasonArgs = reasonArgs }; new EquivalencyValidator(config).AssertEquality(context); }
public void AssertEquality(EquivalencyValidationContext context) { using var scope = new AssertionScope(); scope.AddReportable("configuration", config.ToString()); scope.BecauseOf(context.Because, context.BecauseArgs); AssertEqualityUsing(context); if (context.Tracer != null) { scope.AddReportable("trace", context.Tracer.ToString()); } }
/// <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(EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { if (AssertExpectationIsCollection(context.Expectation)) { var validator = new EnumerableEquivalencyValidator(parent, context) { Recursive = context.IsRoot || config.IsRecursive, OrderingRules = config.OrderingRules }; validator.Execute(ToArray(context.Subject), ToArray(context.Expectation)); } return true; }
private static bool PreconditionsAreMet(EquivalencyValidationContext context, IDictionary expectation, IDictionary subject) { bool success = AssertionScope.Current .ForCondition(expectation != null) .FailWith("{context:subject} is a dictionary and cannot be compared with a non-dictionary type."); if (success) { success = AssertionScope.Current .ForCondition(subject.Keys.Count == expectation.Keys.Count) .FailWith("Expected {context:subject} to be a dictionary with {0} item(s), but it only contains {1} item(s).", expectation.Keys.Count, subject.Keys.Count); } return success; }
private static bool PreconditionsAreMet(EquivalencyValidationContext context, IDictionary expectation, IDictionary subject) { bool success = AssertionScope.Current .ForCondition(expectation != null) .FailWith("{context:subject} is a dictionary and cannot be compared with a non-dictionary type."); if (success) { success = AssertionScope.Current .ForCondition(subject.Keys.Count == expectation.Keys.Count) .FailWith("Expected {context:subject} to be a dictionary with {0} item(s), but it only contains {1} item(s).", expectation.Keys.Count, subject.Keys.Count); } return(success); }
/// <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(EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { if (AssertExpectationIsCollection(context.Expectation)) { var validator = new EnumerableEquivalencyValidator(parent, context) { Recursive = context.IsRoot || config.IsRecursive, OrderingRules = config.OrderingRules }; validator.Execute(ToArray(context.Subject), ToArray(context.Expectation)); } 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(EquivalencyValidationContext context, IEquivalencyValidator parent) { IEnumerable<PropertyInfo> selectedProperties = context.SelectedProperties.ToArray(); if (context.IsRoot && !selectedProperties.Any()) { throw new InvalidOperationException("Please specify some properties to include in the comparison."); } foreach (PropertyInfo propertyInfo in selectedProperties) { AssertPropertyEquality(context, parent, propertyInfo); } return true; }
public void AssertEquality(Comparands comparands, EquivalencyValidationContext context) { using var scope = new AssertionScope(); scope.AssumeSingleCaller(); scope.AddReportable("configuration", context.Options.ToString()); scope.BecauseOf(context.Reason); RecursivelyAssertEquality(comparands, context); if (context.TraceWriter is not null) { scope.AddReportable("trace", context.TraceWriter.ToString()); } }
/// <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 virtual bool Handle(EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { IEnumerable <PropertyInfo> selectedProperties = GetSelectedProperties(context, config).ToArray(); if (context.IsRoot && !selectedProperties.Any()) { throw new InvalidOperationException("Please specify some properties to include in the comparison."); } foreach (PropertyInfo propertyInfo in selectedProperties) { AssertPropertyEquality(context, parent, propertyInfo, config); } 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(EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { Type subjectType = EnumerableEquivalencyStep.GetSubjectType(context, config); Type[] interfaces = GetIEnumerableInterfaces(subjectType); bool multipleInterfaces = (interfaces.Count() > 1); if (multipleInterfaces) { IEnumerable<Type> enumerableTypes = interfaces.Select( type => type.GetGenericArguments().Single()); AssertionScope.Current.FailWith( String.Format( "{{context:Subject}} is enumerable for more than one type. " + "It is not known which type should be use for equivalence.{0}" + "IEnumerable is implemented for the following types: {1}", Environment.NewLine, String.Join(", ", enumerableTypes))); } if (AssertExpectationIsCollection(context.Expectation)) { var validator = new EnumerableEquivalencyValidator(parent, context) { Recursive = context.IsRoot || config.IsRecursive, OrderingRules = config.OrderingRules }; Type typeOfEnumeration = GetTypeOfEnumeration(subjectType); Expression subjectToArray = ToArray(context.Subject, typeOfEnumeration); Expression expectationToArray = Expression.Constant(EnumerableEquivalencyStep.ToArray(context.Expectation)); MethodCallExpression executeExpression = Expression.Call( Expression.Constant(validator), "Execute", new Type[] { typeOfEnumeration }, subjectToArray, expectationToArray); Expression.Lambda(executeExpression).Compile().DynamicInvoke(); } 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(EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { Type subjectType = EnumerableEquivalencyStep.GetSubjectType(context, config); Type[] interfaces = GetIEnumerableInterfaces(subjectType); bool multipleInterfaces = (interfaces.Count() > 1); if (multipleInterfaces) { IEnumerable <Type> enumerableTypes = interfaces.Select( type => type.GetGenericArguments().Single()); AssertionScope.Current.FailWith( String.Format( "{{context:Subject}} is enumerable for more than one type. " + "It is not known which type should be use for equivalence.{0}" + "IEnumerable is implemented for the following types: {1}", Environment.NewLine, String.Join(", ", enumerableTypes))); } if (AssertExpectationIsCollection(context.Expectation)) { var validator = new EnumerableEquivalencyValidator(parent, context) { Recursive = context.IsRoot || config.IsRecursive, OrderingRules = config.OrderingRules }; Type typeOfEnumeration = GetTypeOfEnumeration(subjectType); Expression subjectToArray = ToArray(context.Subject, typeOfEnumeration); Expression expectationToArray = Expression.Constant(EnumerableEquivalencyStep.ToArray(context.Expectation)); MethodCallExpression executeExpression = Expression.Call( Expression.Constant(validator), "Execute", new Type[] { typeOfEnumeration }, subjectToArray, expectationToArray); Expression.Lambda(executeExpression).Compile().DynamicInvoke(); } 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 virtual bool Handle(EquivalencyValidationContext context, IEquivalencyValidator structuralEqualityValidator, IEquivalencyAssertionOptions config) { if (ReferenceEquals(context.Subject, context.Expectation)) { return true; } if (ReferenceEquals(context.Expectation, null)) { AssertionScope.Current.FailWith( "Expected {context:subject} to be {0}{reason}, but found {1}.", context.Expectation, context.Subject); return true; } return !ReferenceEquals(context.Subject, null) && context.Subject.Equals(context.Expectation); }
/// <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 virtual bool Handle(EquivalencyValidationContext context, IEquivalencyValidator structuralEqualityValidator, IEquivalencyAssertionOptions config) { if (ReferenceEquals(context.Subject, context.Expectation)) { return(true); } if (ReferenceEquals(context.Expectation, null)) { AssertionScope.Current.FailWith( "Expected {context:subject} to be {0}{reason}, but found {1}.", context.Expectation, context.Subject); return(true); } return(!ReferenceEquals(context.Subject, null) && context.Subject.Equals(context.Expectation)); }
/// <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 virtual bool Handle(EquivalencyValidationContext context, IEquivalencyValidator structuralEqualityValidator, IEquivalencyAssertionOptions config) { if (!ReferenceEquals(context.Expectation, null) && !ReferenceEquals(context.Subject, null) && !context.Subject.GetType().IsSameOrInherits(context.Expectation.GetType())) { try { context.Subject = Convert.ChangeType(context.Subject, context.Expectation.GetType(), CultureInfo.CurrentCulture); } catch (FormatException) { } catch (InvalidCastException) { } } return(false); }
/// <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(EquivalencyValidationContext context, IEquivalencyValidator structuralEqualityValidator) { if (!ReferenceEquals(context.Expectation, null) && !ReferenceEquals(context.Subject, null) && !context.Subject.GetType().IsSameOrInherits(context.Expectation.GetType())) { try { context.Subject = Convert.ChangeType(context.Subject, context.Expectation.GetType(), CultureInfo.CurrentCulture); } catch (FormatException) { } catch (InvalidCastException) { } } return false; }
private static bool ValidateAgainstNulls(EquivalencyValidationContext context) { object expected = context.Expectation; object subject = context.Subject; string subjectDescription = GetSubjectDescription(context); bool onlyOneNull = ((expected == null) && (subject != null)) || ((expected != null) && (subject == null)); if (onlyOneNull) { AssertionScope.Current.FailWith( "Expected " + subjectDescription + " to be {0}{reason}, but found {1}.", expected, subject); return(false); } return(true); }
public void AssertEqualityUsing(EquivalencyValidationContext context) { AssertionScope scope = AssertionScope.Current; scope.AddNonReportable("context", context.IsRoot ? "subject" : context.PropertyDescription); scope.AddNonReportable("subject", context.Subject); scope.AddNonReportable("expectation", context.Expectation); var objectTracker = scope.Get<ObjectTracker>("objects"); if (!objectTracker.IsCyclicReference(new ObjectReference(context.Subject, context.PropertyPath))) { foreach (IEquivalencyStep strategy in steps.Where(s => s.CanHandle(context, config))) { if (strategy.Handle(context, this, config)) { break; } } } }
/// <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(EquivalencyValidationContext context, IEquivalencyValidator parent) { AssertExpectationIsCollection(context); var subject = ((IEnumerable)context.Subject).Cast<object>().ToArray(); var expectation = ((IEnumerable)context.Expectation).Cast<object>().ToArray(); AssertCollectionsHaveEqualLength(context, subject, expectation); if (context.IsRoot || context.Config.IsRecursive) { EnumerateElements(context, subject, expectation, parent); } else { subject.Should().Equal(expectation, context.Reason, context.ReasonArgs); } return true; }
private static bool ValidateAgainstType <T>(EquivalencyValidationContext context) { bool expectationisNull = ReferenceEquals(context.Expectation, null); if (expectationisNull) { // Do not know the declared type of the expectation. return(true); } return (AssertionScope.Current .ForCondition(context.Expectation.GetType() .IsSameOrInherits(typeof(T))) .FailWith( "Expected " + GetSubjectDescription(context) + " to be {0}, but found {1}", context.Expectation.GetType(), context.RuntimeType)); }
public void AssertEqualityUsing(EquivalencyValidationContext context) { ExecuteUsingSubjectName(context.PropertyDescription, () => { if (!context.ContainsCyclicReference) { foreach (IEquivalencyStep strategy in steps.Where(s => s.CanHandle(context))) { if (strategy.Handle(context, this)) { break; } } } else { context.HandleCyclicReference(); } }); }
public void AssertEqualityUsing(EquivalencyValidationContext context) { AssertionScope scope = AssertionScope.Current; scope.AddNonReportable("context", context.IsRoot ? "subject" : context.PropertyDescription); scope.AddNonReportable("subject", context.Subject); scope.AddNonReportable("expectation", context.Expectation); var objectTracker = scope.Get <ObjectTracker>("objects"); if (!objectTracker.IsCyclicReference(new ObjectReference(context.Subject, context.PropertyPath))) { foreach (IEquivalencyStep strategy in steps.Where(s => s.CanHandle(context, config))) { if (strategy.Handle(context, this, config)) { break; } } } }
/// <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 virtual bool Handle(EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { var subject = (IDictionary)context.Subject; var expectation = context.Expectation as IDictionary; if (PreconditionsAreMet(context, expectation, subject)) { foreach (object key in subject.Keys) { if (config.IsRecursive) { parent.AssertEqualityUsing(context.CreateForDictionaryItem(key, subject[key], expectation[key])); } else { subject[key].Should().Be(expectation[key], context.Reason, context.ReasonArgs); } } } 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 virtual bool Handle(EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { var subject = (IDictionary)context.Subject; var expectation = context.Expectation as IDictionary; if (PreconditionsAreMet(context, expectation, subject)) { foreach (object key in subject.Keys) { if (config.IsRecursive) { parent.AssertEqualityUsing(context.CreateForDictionaryItem(key, subject[key], expectation[key])); } else { subject[key].Should().Be(expectation[key], context.Reason, context.ReasonArgs); } } } 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(EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { if (!ValidateAgainstNulls(context)) { return(true); } bool expectationIsString = ValidateAgainstType <string>(context); if (expectationIsString) { string subject = (string)context.Subject; string expectation = (context.Expectation == null) ? null : (string)context.Expectation; subject.Should() .Be(expectation, context.Reason, context.ReasonArgs); } return(true); }
/// <summary> /// Gets a value indicating whether this step can handle the current subject and/or expectation. /// </summary> public bool CanHandle(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { return (context.PropertyInfo != null); }
/// <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 virtual bool Handle(EquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) { return config.AssertionRules.Any(rule => rule.AssertEquality(context)); }
/// <summary> /// Gets a value indicating whether this step can handle the current subject and/or expectation. /// </summary> public bool CanHandle(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { return(context.Subject is IDictionary); }
internal static Type GetSubjectType(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { bool useRuntimeType = ShouldUseRuntimeType(config); return useRuntimeType ? context.RuntimeType : context.CompileTimeType; }
/// <summary> /// Gets a value indicating whether this step can handle the current subject and/or expectation. /// </summary> public bool CanHandle(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { return(context.IsRoot || config.IsRecursive); }
/// <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(EquivalencyValidationContext context, IEquivalencyValidator structuralEqualityValidator, IEquivalencyAssertionOptions config) { context.Subject.Should().Be(context.Expectation, context.Reason, context.ReasonArgs); return(true); }
/// <summary> /// Gets a value indicating whether this step can handle the current subject and/or expectation. /// </summary> public bool CanHandle(EquivalencyValidationContext context) { return IsCollection(context.Subject); }
/// <summary> /// Gets a value indicating whether this step can handle the current subject and/or expectation. /// </summary> public bool CanHandle(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { return(true); }
public EnumerableEquivalencyValidator(IEquivalencyValidator parent, EquivalencyValidationContext context) { this.parent = parent; this.context = context; Recursive = false; }
/// <summary> /// Gets a value indicating whether this step can handle the verificationScope subject and/or expectation. /// </summary> public bool CanHandle(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { Type subjectType = GetSubjectType(context, config); return IsCollection(subjectType); }
/// <summary> /// Gets a value indicating whether this step can handle the current subject and/or expectation. /// </summary> public bool CanHandle(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { return((context.Subject != null) && context.Subject.GetType().IsComplexType() && (context.IsRoot || config.IsRecursive)); }
/// <summary> /// Gets a value indicating whether this step can handle the verificationScope subject and/or expectation. /// </summary> public bool CanHandle(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { return(IsCollection(context.Subject)); }
/// <summary> /// Gets a value indicating whether this step can handle the current subject and/or expectation. /// </summary> public bool CanHandle(EquivalencyValidationContext context, IEquivalencyAssertionOptions config) { return (context.Subject != null) && context.Subject.GetType().IsComplexType() && (context.IsRoot || config.IsRecursive); }