/// <summary>
        /// Gets a value indicating whether this step can handle the current subject and/or expectation.
        /// </summary>
        public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
        {
            Type subjectType = config.GetSubjectType(context);

            return ((subjectType != null) && subjectType.IsEnum()) ||
                   ((context.Expectation != null) && context.Expectation.GetType().IsEnum());
        }
        public void AssertEqualityUsing(IEquivalencyValidationContext context)
        {
            if (ContinueRecursion(context.SelectedMemberPath))
            {
                AssertionScope scope = AssertionScope.Current;
                scope.AddNonReportable("context", context.IsRoot ? "subject" : context.SelectedMemberDescription);
                scope.AddNonReportable("subject", context.Subject);
                scope.AddNonReportable("expectation", context.Expectation);

                var objectTracker = scope.Get<ObjectTracker>("objects");

                if (!objectTracker.IsCyclicReference(new ObjectReference(context.Subject, context.SelectedMemberPath)))
                {
                    bool wasHandled = AssertionOptions.EquivalencySteps
                        .Where(s => s.CanHandle(context, config))
                        .Any(step => step.Handle(context, this, config));

                    if (!wasHandled)
                    {
                        Execute.Assertion.FailWith(
                            "No IEquivalencyStep was found to handle the context.  " +
                            "This is likely a bug in Fluent Assertions.");
                    }
                }
            }
        }
 public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent,
     IEquivalencyAssertionOptions config)
 {
     return config.UserEquivalencySteps
         .Where(s => s.CanHandle(context, config))
         .Any(step => step.Handle(context, parent, config));
 }
        public bool Handle(IEquivalencyValidationContext 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<SelectedMemberInfo> selectedMembers = GetSelectedMembers(context, config).ToArray();
            if (context.IsRoot && !selectedMembers.Any())
            {
                throw new InvalidOperationException(
                    "No members were found for comparison. " +
                    "Please specify some members to include in the comparison or choose a more meaningful assertion.");
            }

            if (expectationIsNotNull && subjectIsNotNull)
            {
                foreach (var selectedMemberInfo in selectedMembers)
                {
                    AssertMemberEquality(context, parent, selectedMemberInfo, config);
                }
            }
            return true;
        }
 private static bool AreComparable(IEquivalencyValidationContext context, Array subjectAsArray)
 {
     return
         IsArray(context.Expectation) &&
         HaveSameRank(context.Expectation, subjectAsArray) &&
         HaveSameDimensions(context.Expectation, subjectAsArray);
 }
        public bool Handle(
            IEquivalencyValidationContext context,
            IEquivalencyValidator parent,
            IEquivalencyAssertionOptions config)
        {
            var equivalencyValidationContext = CreateAdjustedCopy(context);

            return eqivalencyStep.Handle(equivalencyValidationContext, parent, config);
        }
        private static SelectedMemberInfo FindMatchFor(SelectedMemberInfo selectedMemberInfo, IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
        {
            var query =
                from rule in config.MatchingRules
                let match = rule.Match(selectedMemberInfo, context.Expectation, context.SelectedMemberDescription, config)
                where match != null
                select match;

            return query.FirstOrDefault();
        }
        /// <summary>
        /// Gets a value indicating whether this step can handle the current subject and/or expectation.
        /// </summary>
        public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
        {
            Type type = config.GetSubjectType(context);

            return 
                (type != null) && 
                (type != typeof (object)) && 
                config.IsValueType(type) && 
                !type.IsArray;
        }
        private void CompareByValue(IEquivalencyValidationContext context)
        {
            var subjectType = Enum.GetUnderlyingType(context.Subject.GetType());
            var subjectUnderlyingValue = Convert.ChangeType(context.Subject, subjectType, CultureInfo.InvariantCulture);

            var expectationType = Enum.GetUnderlyingType(context.Expectation.GetType());
            var expectationUnderlyingValue = Convert.ChangeType(context.Expectation, expectationType,
                CultureInfo.InvariantCulture);

            subjectUnderlyingValue.Should().Be(expectationUnderlyingValue, context.Reason, context.ReasonArgs);
        }
 private static void AssertMemberEquality(IEquivalencyValidationContext context, IEquivalencyValidator parent, SelectedMemberInfo selectedMemberInfo, IEquivalencyAssertionOptions config)
 {
     var matchingMember = FindMatchFor(selectedMemberInfo, context, config);
     if (matchingMember != null)
     {
         var nestedContext = context.CreateForNestedMember(selectedMemberInfo, matchingMember);
         if (nestedContext != null)
         {
             parent.AssertEqualityUsing(nestedContext);
         }
     }
 }
        internal IEnumerable<SelectedMemberInfo> GetSelectedMembers(IEquivalencyValidationContext context, 
            IEquivalencyAssertionOptions config)
        {
            IEnumerable<SelectedMemberInfo> members = Enumerable.Empty<SelectedMemberInfo>();

            foreach (var selectionRule in config.SelectionRules)
            {
                members = selectionRule.SelectMembers(members, context, config);
            }

            return members;
        }
 private static EquivalencyValidationContext CreateAdjustedCopy(IEquivalencyValidationContext context)
 {
     return new EquivalencyValidationContext
     {
         CompileTimeType = context.CompileTimeType,
         Expectation = context.Expectation,
         SelectedMemberDescription = context.SelectedMemberDescription,
         SelectedMemberInfo = context.SelectedMemberInfo,
         SelectedMemberPath = CollectionMemberSubjectInfo.GetAdjustedPropertyPath(context.SelectedMemberPath),
         Because = context.Because,
         BecauseArgs = context.BecauseArgs,
         Subject = context.Subject
     };
 }
        /// <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 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(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config)
        {
            Type subjectType = config.GetSubjectType(context);

            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),
                    ExpressionExtensions.GetMethodName(() => validator.Execute<object>(null,null)),
                    new Type[] { typeOfEnumeration },
                    subjectToArray,
                    expectationToArray);

                Expression.Lambda(executeExpression).Compile().DynamicInvoke();
            }

            return true;
        }
        public bool AssertEquality(IEquivalencyValidationContext context)
        {
            if (context.RuntimeType != typeof (double))
            {
                return false;
            }
            var expectation = context.Expectation.As<double>();
            var actual      = context.Subject.As<double>();
            var delta       = actual - expectation;

            Execute.Assertion.ForCondition(Math.Abs(delta) <= TOLERANCE)
                .BecauseOf(string.Empty)
                .FailWith(string.Format(
                    "Expected property {0} to be {1} (+/- {2}), but found {3}. Differed by {4}.",
                    context.PropertyInfo.Name, expectation, TOLERANCE, actual, delta
                ));

            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 (!ReferenceEquals(context.Expectation, null) && !ReferenceEquals(context.Subject, null)
                && !context.Subject.GetType().IsSameOrInherits(context.Expectation.GetType()))
            {
                Type expectationType = context.Expectation.GetType();

                object convertedSubject;
                if (TryChangeType(context.Subject, expectationType, out convertedSubject))
                {
                    var newContext = context.CreateWithDifferentSubject(convertedSubject, expectationType);

                    structuralEqualityValidator.AssertEqualityUsing(newContext);
                    return true;
                }
            }

            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(IEquivalencyValidationContext context, IEquivalencyValidator parent,
            IEquivalencyAssertionOptions config)
        {
            switch (config.EnumEquivalencyHandling)
            {
                case EnumEquivalencyHandling.ByValue:
                    CompareByValue(context);
                    break;
                case EnumEquivalencyHandling.ByName:
                    context.Subject.ToString()
                        .Should()
                        .Be(context.Expectation.ToString(), context.Reason, context.ReasonArgs);
                    break;
                default:
                    throw new InvalidOperationException(string.Format("Don't know how to handle {0}",
                        config.EnumEquivalencyHandling));
            }

            return true;
        }
        internal static IEquivalencyValidationContext CreateForCollectionItem <T>(this IEquivalencyValidationContext context,
                                                                                  string index, object subject, T expectation)
        {
            string memberDescription = "[" + index + "]";
            string propertyPath      = (context.SelectedMemberDescription.Length == 0) ? "item" : context.SelectedMemberDescription + String.Empty;

            return(new EquivalencyValidationContext
            {
                SelectedMemberInfo = context.SelectedMemberInfo,
                Subject = subject,
                Expectation = expectation,
                SelectedMemberPath = context.SelectedMemberPath.Combine(memberDescription, String.Empty),
                SelectedMemberDescription = propertyPath + memberDescription,
                Because = context.Because,
                BecauseArgs = context.BecauseArgs,
                CompileTimeType = typeof(T),
                RootIsCollection = context.RootIsCollection,
                Tracer = context.Tracer
            });
        }
        internal static IEquivalencyValidationContext CreateForNestedMember(this IEquivalencyValidationContext context,
                                                                            SelectedMemberInfo nestedMember, SelectedMemberInfo matchingProperty)
        {
            string memberDescription = nestedMember.Name;
            string propertyPath      = (context.SelectedMemberDescription.Length == 0) ? "member " : context.SelectedMemberDescription + ".";

            return(new EquivalencyValidationContext
            {
                SelectedMemberInfo = nestedMember,
                Subject = matchingProperty.GetValue(context.Subject, null),
                Expectation = nestedMember.GetValue(context.Expectation, null),
                SelectedMemberPath = context.SelectedMemberPath.Combine(memberDescription, "."),
                SelectedMemberDescription = propertyPath + memberDescription,
                Because = context.Because,
                BecauseArgs = context.BecauseArgs,
                CompileTimeType = nestedMember.MemberType,
                RootIsCollection = context.RootIsCollection,
                Tracer = context.Tracer
            });
        }
        public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator)
        {
            if (!IsCollection(comparands.GetExpectedType(context.Options)))
            {
                return(EquivalencyResult.ContinueWithNext);
            }

            if (AssertSubjectIsCollection(comparands.Subject))
            {
                var validator = new EnumerableEquivalencyValidator(nestedValidator, context)
                {
                    Recursive     = context.CurrentNode.IsRoot || context.Options.IsRecursive,
                    OrderingRules = context.Options.OrderingRules
                };

                validator.Execute(ToArray(comparands.Subject), ToArray(comparands.Expectation));
            }

            return(EquivalencyResult.AssertionCompleted);
        }
        /// <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 parent,
                           IEquivalencyAssertionOptions config)
        {
            switch (config.EnumEquivalencyHandling)
            {
            case EnumEquivalencyHandling.ByValue:
                HandleByValue(context);
                break;

            case EnumEquivalencyHandling.ByName:
                HandleByName(context);
                break;

            default:
                throw new InvalidOperationException(string.Format("Do not know how to handle {0}",
                                                                  config.EnumEquivalencyHandling));
            }

            return(true);
        }
Example #22
0
#pragma warning restore SA1110

        public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator)
        {
            Type expectedType = comparands.GetExpectedType(context.Options);

            if (comparands.Expectation is null || !IsGenericCollection(expectedType))
            {
                return(EquivalencyResult.ContinueWithNext);
            }

            Type[] interfaceTypes = GetIEnumerableInterfaces(expectedType);

            AssertionScope.Current
            .ForCondition(interfaceTypes.Length == 1)
            .FailWith(() => new FailReason("{context:Expectation} implements {0}, so cannot determine which one " +
                                           "to use for asserting the equivalency of the collection. ",
                                           interfaceTypes.Select(type => "IEnumerable<" + type.GetGenericArguments().Single() + ">")));

            if (AssertSubjectIsCollection(comparands.Subject))
            {
                var validator = new EnumerableEquivalencyValidator(nestedValidator, context)
                {
                    Recursive     = context.CurrentNode.IsRoot || context.Options.IsRecursive,
                    OrderingRules = context.Options.OrderingRules
                };

                Type typeOfEnumeration = GetTypeOfEnumeration(expectedType);

                var subjectAsArray = EnumerableEquivalencyStep.ToArray(comparands.Subject);

                try
                {
                    HandleMethod.MakeGenericMethod(typeOfEnumeration).Invoke(null, new[] { validator, subjectAsArray, comparands.Expectation });
                }
                catch (TargetInvocationException e)
                {
                    e.Unwrap().Throw();
                }
            }

            return(EquivalencyResult.AssertionCompleted);
        }
        public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context,
                                        IEquivalencyValidator nestedValidator)
        {
            if (!context.CurrentNode.IsRoot && !context.Options.IsRecursive)
            {
                return(EquivalencyResult.ContinueWithNext);
            }

            bool expectationIsNotNull = AssertionScope.Current
                                        .ForCondition(comparands.Expectation is not null)
                                        .BecauseOf(context.Reason)
                                        .FailWith(
                "Expected {context:subject} to be <null>{reason}, but found {0}.",
                comparands.Subject);

            bool subjectIsNotNull = AssertionScope.Current
                                    .ForCondition(comparands.Subject is not null)
                                    .BecauseOf(context.Reason)
                                    .FailWith(
                "Expected {context:object} to be {0}{reason}, but found {1}.",
                comparands.Expectation,
                comparands.Subject);

            if (expectationIsNotNull && subjectIsNotNull)
            {
                IMember[] selectedMembers = GetMembersFromExpectation(context.CurrentNode, comparands, context.Options).ToArray();
                if (context.CurrentNode.IsRoot && !selectedMembers.Any())
                {
                    throw new InvalidOperationException(
                              "No members were found for comparison. " +
                              "Please specify some members to include in the comparison or choose a more meaningful assertion.");
                }

                foreach (IMember selectedMember in selectedMembers)
                {
                    AssertMemberEquality(comparands, context, nestedValidator, selectedMember, context.Options);
                }
            }

            return(EquivalencyResult.AssertionCompleted);
        }
        protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator)
        {
            var subject     = comparands.Subject as DataRelation;
            var expectation = comparands.Expectation as DataRelation;

            if (expectation is null)
            {
                if (subject is not null)
                {
                    AssertionScope.Current.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");
                    }
                    else
                    {
                        AssertionScope.Current.FailWith("Expected {context:DataRelation} of type {0}, but found {1} instead",
                                                        expectation.GetType(), comparands.Subject.GetType());
                    }
                }
                else
                {
                    var selectedMembers = GetMembersFromExpectation(context.CurrentNode, comparands, context.Options)
                                          .ToDictionary(member => member.Name);

                    CompareScalarProperties(subject, expectation, selectedMembers);

                    CompareCollections(context, comparands, nestedValidator, context.Options, selectedMembers);

                    CompareRelationConstraints(context, nestedValidator, subject, expectation, selectedMembers);
                }
            }

            return(EquivalencyResult.AssertionCompleted);
        }
        /// <summary>
        /// Defines how a subject's property is compared for equality with the same property of the expectation.
        /// </summary>
        /// <param name="subjectProperty">
        /// Provides details about the subject's property.
        /// </param>
        /// <param name="subject">
        /// The value of the subject's property.
        /// </param>
        /// <param name="expectation">
        /// The value of a property on expectation object that was identified
        /// </param>
        /// <returns>
        /// Returns <c>true</c> if the rule was applied correctly and the assertion didn't cause any exceptions.
        /// Returns <c>false</c> if this rule doesn't support the subject's type.
        /// Throws if the rule did support the data type but assertion fails.
        /// </returns>
        public bool AssertEquality(IEquivalencyValidationContext context)
        {
            if (predicate(context))
            {
                bool succeeded =
                    AssertionScope.Current
                    .ForCondition(ReferenceEquals(context.Expectation, null) || context.Expectation.GetType().IsSameOrInherits(typeof(TSubject)))
                    .FailWith("Expected " + context.PropertyDescription + " to be a {0}{reason}, but found a {1}",
                              context.Expectation.GetType(), context.PropertyInfo.PropertyType);

                if (succeeded)
                {
                    action(new AssertionContext(context.PropertyInfo,
                                                (TSubject)context.Subject, (TSubject)context.Expectation, context.Reason, context.ReasonArgs));
                }

                return(true);
            }

            return(false);
        }
        public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config)
        {
            if (ReferenceEquals(context.Subject, context.Expectation))
            {
                return(true);
            }

            FieldInfo[] fieldInfos = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public);
            if (!fieldInfos.All(fi => fi.FieldType == typeof(float) || fi.FieldType == typeof(double)))
            {
                throw new InvalidOperationException("Cannot compare vectors. One or more fields is not a float or double.");
            }

            List <T> vectors         = ((IEnumerable <T>)context.Subject).ToList();
            List <T> expectedVectors = ((IEnumerable <T>)context.Expectation).ToList();

            if (vectors.Count != expectedVectors.Count)
            {
                return(false);
            }

            for (int i = 0; i < vectors.Count; i++)
            {
                T left  = vectors[i];
                T right = expectedVectors[i];

                foreach (FieldInfo fieldInfo in fieldInfos)
                {
                    double leftValue  = Convert.ToDouble(fieldInfo.GetValue(left));
                    double rightValue = Convert.ToDouble(fieldInfo.GetValue(right));

                    if (!NearlyEqual(leftValue, rightValue, _epsilon))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Example #27
0
        /// <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 parent,
                           IEquivalencyAssertionOptions config)
        {
            Type subjectType = config.GetSubjectType(context);

            var interfaceTypes = GetIEnumerableInterfaces(subjectType)
                                 .Select(type => "IEnumerable<" + type.GetGenericArguments().Single() + ">")
                                 .ToList();

            AssertionScope.Current
            .ForCondition(interfaceTypes.Count() == 1)
            .FailWith("{context:Subject} implements {0}, so cannot determine which one " +
                      "to use for asserting the equivalency of the collection. ", interfaceTypes);

            if (AssertExpectationIsCollection(context.Expectation, context.Subject))
            {
                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),
                    ExpressionExtensions.GetMethodName(() => validator.Execute <object>(null, null)),
                    new[] { 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(IEquivalencyValidationContext context, IEquivalencyValidator parent,
            IEquivalencyAssertionOptions config)
        {
            Type subjectType = config.GetSubjectType(context);

            var interfaceTypes = GetIEnumerableInterfaces(subjectType)
                .Select(type => "IEnumerable<" + type.GetGenericArguments().Single() + ">")
                .ToList();

            AssertionScope.Current
                .ForCondition(interfaceTypes.Count() == 1)
                .FailWith("{context:Subject} implements {0}, so cannot determine which one " +
                          "to use for asserting the equivalency of the collection. ", interfaceTypes);

            if (AssertExpectationIsCollection(context.Expectation, context.Subject))
            {
                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),
                    ExpressionExtensions.GetMethodName(() => validator.Execute<object>(null, null)),
                    new[] {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(IEquivalencyValidationContext 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);
        }
Example #30
0
        /// <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 parent,
                           IEquivalencyAssertionOptions config)
        {
            switch (config.EnumEquivalencyHandling)
            {
            case EnumEquivalencyHandling.ByValue:
                CompareByValue(context);
                break;

            case EnumEquivalencyHandling.ByName:
                context.Subject.ToString()
                .Should()
                .Be(context.Expectation.ToString(), context.Reason, context.ReasonArgs);
                break;

            default:
                throw new InvalidOperationException(string.Format("Don't know how to handle {0}",
                                                                  config.EnumEquivalencyHandling));
            }

            return(true);
        }
        protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator)
        {
            if (comparands.Subject is not Constraint)
            {
                AssertionScope.Current
                .FailWith("Expected {context:constraint} to be a value of type Constraint, but found {0}",
                          comparands.Subject.GetType());
            }
            else
            {
                var subject     = (Constraint)comparands.Subject;
                var expectation = (Constraint)comparands.Expectation;

                var selectedMembers = GetMembersFromExpectation(comparands, context.CurrentNode, context.Options)
                                      .ToDictionary(member => member.Name);

                CompareCommonProperties(context, nestedValidator, context.Options, subject, expectation, selectedMembers);

                bool matchingType = subject.GetType() == expectation.GetType();

                AssertionScope.Current
                .ForCondition(matchingType)
                .FailWith("Expected {context:constraint} to be of type {0}, but found {1}", expectation.GetType(),
                          subject.GetType());

                if (matchingType)
                {
                    if ((subject is UniqueConstraint subjectUniqueConstraint) &&
                        (expectation is UniqueConstraint expectationUniqueConstraint))
                    {
                        CompareConstraints(nestedValidator, context, subjectUniqueConstraint, expectationUniqueConstraint,
                                           selectedMembers);
                    }
                    else if ((subject is ForeignKeyConstraint subjectForeignKeyConstraint) &&
                             (expectation is ForeignKeyConstraint expectationForeignKeyConstraint))
                    {
                        CompareConstraints(nestedValidator, context, subjectForeignKeyConstraint, expectationForeignKeyConstraint,
                                           selectedMembers);
                    }
Example #32
0
        internal static IEquivalencyValidationContext CreateForDictionaryItem <TKey, TValue>(
            this IEquivalencyValidationContext context,
            TKey key,
            TValue subject,
            object expectation)
        {
            string memberDescription = "[" + key + "]";
            string propertyPath      = (context.SelectedMemberDescription.Length == 0) ? "pair" : context.SelectedMemberDescription + String.Empty;

            return(new EquivalencyValidationContext
            {
                SelectedMemberInfo = context.SelectedMemberInfo,
                Subject = subject,
                Expectation = expectation,
                SelectedMemberPath = context.SelectedMemberPath.Combine(memberDescription, String.Empty),
                SelectedMemberDescription = propertyPath + memberDescription,
                Because = context.Because,
                BecauseArgs = context.BecauseArgs,
                CompileTimeType = typeof(TValue),
                RootIsCollection = context.RootIsCollection
            });
        }
        private static void CompareExtendedProperties(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config, Dictionary <string, IMember> selectedMembers)
        {
            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);
                    if (matchingMember is not null)
                    {
                        var nestedComparands = new Comparands
                        {
                            Subject         = matchingMember.GetValue(comparands.Subject),
                            Expectation     = expectationMember.GetValue(comparands.Expectation),
                            CompileTimeType = expectationMember.Type
                        };

                        IEquivalencyValidationContext nestedContext = context.AsNestedMember(expectationMember);
                        parent.RecursivelyAssertEquality(nestedComparands, nestedContext);
                    }
                }
            }
        }
Example #34
0
        /// <summary>
        /// Defines how a subject's property is compared for equality with the same property of the expectation.
        /// </summary>
        /// <param name="subjectProperty">
        /// Provides details about the subject's property.
        /// </param>
        /// <param name="subject">
        /// The value of the subject's property.
        /// </param>
        /// <param name="expectation">
        /// The value of a property on expectation object that was identified
        /// </param>
        /// <returns>
        /// Returns <c>true</c> if the rule was applied correctly and the assertion didn't cause any exceptions.
        /// Returns <c>false</c> if this rule doesn't support the subject's type.
        /// Throws if the rule did support the data type but assertion fails.
        /// </returns>
        public bool AssertEquality(IEquivalencyValidationContext context)
        {
            if (predicate(context))
            {
                bool expectationisNull = ReferenceEquals(context.Expectation, null);

                bool succeeded =
                    AssertionScope.Current
                    .ForCondition(expectationisNull || context.Expectation.GetType().IsSameOrInherits(typeof(TSubject)))
                    .FailWith("Expected " + context.SelectedMemberDescription + " to be a {0}{reason}, but found a {1}",
                              !expectationisNull ? context.Expectation.GetType() : null, context.SelectedMemberInfo.MemberType);

                if (succeeded)
                {
                    action(AssertionContext <TSubject> .CreateFromEquivalencyValidationContext(context));
                }

                return(true);
            }

            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 virtual bool Handle(IEquivalencyValidationContext 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.Because, context.BecauseArgs);
                    }
                }
            }

            return(true);
        }
        public void AssertEqualityUsing(IEquivalencyValidationContext context)
        {
            if (ContinueRecursion(context.SelectedMemberPath))
            {
                AssertionScope scope = AssertionScope.Current;
                scope.Context = (context.SelectedMemberDescription.Length == 0) ? scope.Context : context.SelectedMemberDescription;
                scope.AddNonReportable("subject", context.Subject);
                scope.AddNonReportable("expectation", context.Expectation);

                var objectTracker = scope.Get <CyclicReferenceDetector>("objects");

                bool isComplexType   = IsComplexType(context.Expectation);
                var  objectReference = new ObjectReference(context.Expectation, context.SelectedMemberPath, isComplexType);

                if (!objectTracker.IsCyclicReference(objectReference))
                {
                    bool wasHandled = false;

                    foreach (var step in AssertionOptions.EquivalencySteps)
                    {
                        if (step.CanHandle(context, config))
                        {
                            if (step.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 CompareRelationConstraints(IEquivalencyValidationContext context, IEquivalencyValidator parent,
                                                       DataRelation subject, DataRelation expectation,
                                                       Dictionary <string, IMember> selectedMembers)
        {
            CompareDataRelationConstraints(
                parent, context, subject, expectation, selectedMembers,
                "Child",
                selectedMembers.ContainsKey(nameof(DataRelation.ChildTable)),
                selectedMembers.ContainsKey(nameof(DataRelation.ChildColumns)),
                selectedMembers.ContainsKey(nameof(DataRelation.ChildKeyConstraint)),
                r => r.ChildColumns,
                r => r.ChildTable);

            CompareDataRelationConstraints(
                parent, context, subject, expectation, selectedMembers,
                "Parent",
                selectedMembers.ContainsKey(nameof(DataRelation.ParentTable)),
                selectedMembers.ContainsKey(nameof(DataRelation.ParentColumns)),
                selectedMembers.ContainsKey(nameof(DataRelation.ParentKeyConstraint)),
                r => r.ParentColumns,
                r => r.ParentTable);
        }
        /// <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(IEquivalencyValidationContext 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(IEquivalencyValidationContext context, IEquivalencyValidator parent,
            IEquivalencyAssertionOptions config)
        {
            switch (config.EnumEquivalencyHandling)
            {
                case EnumEquivalencyHandling.ByValue:
                    long subjectsUnderlyingValue = Convert.ToInt64(context.Subject);
                    long expectationsUnderlyingValue = Convert.ToInt64(context.Expectation);

                    subjectsUnderlyingValue.Should().Be(expectationsUnderlyingValue, context.Because, context.BecauseArgs);
                    break;

                case EnumEquivalencyHandling.ByName:
                    context.Subject.ToString().Should().Be(context.Expectation.ToString(), context.Because, context.BecauseArgs);
                    break;

                default:
                    throw new InvalidOperationException(string.Format("Don't know how to handle {0}",
                        config.EnumEquivalencyHandling));
            }

            return true;
        }
        private static void CompareDataRelationConstraints(
            IEquivalencyValidator parent, IEquivalencyValidationContext context,
            DataRelation subject, DataRelation expectation, Dictionary <string, IMember> selectedMembers,
            string relationDirection,
            bool compareTable, bool compareColumns, bool compareKeyConstraint,
            Func <DataRelation, DataColumn[]> getColumns,
            Func <DataRelation, DataTable> getOtherTable)
        {
            if (compareColumns)
            {
                CompareDataRelationColumns(subject, expectation, getColumns);
            }

            if (compareTable)
            {
                CompareDataRelationTable(subject, expectation, getOtherTable);
            }

            if (compareKeyConstraint)
            {
                CompareDataRelationKeyConstraint(subject, expectation, parent, context, selectedMembers, relationDirection);
            }
        }
Example #41
0
        /// <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 (!ReferenceEquals(context.Expectation, null) && !ReferenceEquals(context.Subject, null) &&
                !context.Subject.GetType().IsSameOrInherits(context.Expectation.GetType()))
            {
                Type expectationType = context.Expectation.GetType();

                object convertedSubject;
                if (TryChangeType(context.Subject, expectationType, out convertedSubject))
                {
                    context.TraceSingle(path => $"Converted subject {context.Subject} at {path} to {expectationType}");

                    var newContext = context.CreateWithDifferentSubject(convertedSubject, expectationType);

                    structuralEqualityValidator.AssertEqualityUsing(newContext);
                    return(true);
                }

                context.TraceSingle(path => $"Subject {context.Subject} at {path} could not be converted to {expectationType}");
            }

            return(false);
        }
        private static void AssertDictionaryEquivalence(IEquivalencyValidationContext context,
                                                        IEquivalencyValidator parent, IEquivalencyAssertionOptions config)
        {
            Type expectationType = config.GetExpectationType(context);

            string methodName =
                ExpressionExtensions.GetMethodName(
                    () => AssertDictionaryEquivalence <object, object, object, object>(null, null, null, null, null));

            MethodCallExpression assertDictionaryEquivalence = Expression.Call(
                typeof(GenericDictionaryEquivalencyStep),
                methodName,
                GetDictionaryTypeArguments(context.Subject.GetType())
                .Concat(GetDictionaryTypeArguments(expectationType))
                .ToArray(),
                Expression.Constant(context),
                Expression.Constant(parent),
                Expression.Constant(config),
                Expression.Constant(context.Subject, GetIDictionaryInterface(context.Subject.GetType())),
                Expression.Constant(context.Expectation, GetIDictionaryInterface(expectationType)));

            Expression.Lambda(assertDictionaryEquivalence).Compile().DynamicInvoke();
        }
        public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent,
                           IEquivalencyAssertionOptions config)
        {
            Array expectationAsArray = (Array)context.Expectation;

            if (AreComparable(context, expectationAsArray))
            {
                Digit digit = BuildDigitsRepresentingAllIndices(expectationAsArray);

                do
                {
                    var subject = ((Array)context.Subject).GetValue(digit.Indices);
                    IEquivalencyValidationContext itemContext = context.CreateForCollectionItem(
                        string.Join(",", digit.Indices),
                        subject,
                        expectationAsArray.GetValue(digit.Indices));

                    parent.AssertEqualityUsing(itemContext);
                }while (digit.Increment());
            }

            return(true);
        }
Example #44
0
        /// <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 parent,
                           IEquivalencyAssertionOptions config)
        {
            switch (config.EnumEquivalencyHandling)
            {
            case EnumEquivalencyHandling.ByValue:
                decimal?subjectsUnderlyingValue     = (context.Subject != null) ? Convert.ToDecimal(context.Subject) : (decimal?)null;
                decimal?expectationsUnderlyingValue = (context.Expectation != null) ? Convert.ToDecimal(context.Expectation) : (decimal?)null;

                subjectsUnderlyingValue.Should().Be(expectationsUnderlyingValue, context.Because, context.BecauseArgs);
                break;

            case EnumEquivalencyHandling.ByName:
                context.Subject.ToString().Should().Be(context.Expectation.ToString(), context.Because, context.BecauseArgs);
                break;

            default:
                throw new InvalidOperationException(string.Format("Don't know how to handle {0}",
                                                                  config.EnumEquivalencyHandling));
            }

            return(true);
        }
Example #45
0
        /// <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 parent,
                           IEquivalencyAssertionOptions config)
        {
            Type expectedType = config.GetExpectationType(context);

            Type[] interfaceTypes = GetIEnumerableInterfaces(expectedType);

            AssertionScope.Current
            .ForCondition(interfaceTypes.Length == 1)
            .FailWith(() => new FailReason("{context:Expectation} implements {0}, so cannot determine which one " +
                                           "to use for asserting the equivalency of the collection. ",
                                           interfaceTypes.Select(type => "IEnumerable<" + type.GetGenericArguments().Single() + ">")));

            if (AssertSubjectIsCollection(context.Subject))
            {
                var validator = new EnumerableEquivalencyValidator(parent, context)
                {
                    Recursive     = context.IsRoot || config.IsRecursive,
                    OrderingRules = config.OrderingRules
                };

                Type typeOfEnumeration = GetTypeOfEnumeration(expectedType);

                var subjectAsArray = EnumerableEquivalencyStep.ToArray(context.Subject);

                try
                {
                    HandleMethod.MakeGenericMethod(typeOfEnumeration).Invoke(null, new[] { validator, subjectAsArray, context.Expectation });
                }
                catch (TargetInvocationException e)
                {
                    throw e.Unwrap();
                }
            }

            return(true);
        }
Example #46
0
        public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent,
                           IEquivalencyAssertionOptions config)
        {
            bool success = false;

            using (var scope = new AssertionScope())
            {
                // Try without conversion
                if (AppliesTo(context))
                {
                    success = ExecuteAssertion(context);
                }

                bool converted = false;
                if (!success && converter.CanHandle(context, config))
                {
                    // Convert into a child context
                    context = context.Clone();
                    converter.Handle(context, parent, config);
                    converted = true;
                }

                if (converted && AppliesTo(context))
                {
                    // Try again after conversion
                    success = ExecuteAssertion(context);
                    if (success)
                    {
                        // If the assertion succeeded after conversion, discard the failures from
                        // the previous attempt. If it didn't, let the scope throw with those failures.
                        scope.Discard();
                    }
                }
            }

            return(success);
        }
Example #47
0
        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));
            }
        }
Example #48
0
        public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator)
        {
            if (!comparands.GetExpectedType(context.Options).IsEnum)
            {
                return(EquivalencyResult.ContinueWithNext);
            }

            bool succeeded = Execute.Assertion
                             .ForCondition(comparands.Subject?.GetType().IsEnum == true)
                             .FailWith(() =>
            {
                decimal?expectationsUnderlyingValue = ExtractDecimal(comparands.Expectation);
                string expectationName = GetDisplayNameForEnumComparison(comparands.Expectation, expectationsUnderlyingValue);

                return(new FailReason($"Expected {{context:enum}} to be equivalent to {expectationName}{{reason}}, but found {{0}}.", comparands.Subject));
            });

            if (succeeded)
            {
                switch (context.Options.EnumEquivalencyHandling)
                {
                case EnumEquivalencyHandling.ByValue:
                    HandleByValue(comparands);
                    break;

                case EnumEquivalencyHandling.ByName:
                    HandleByName(comparands);
                    break;

                default:
                    throw new InvalidOperationException($"Do not know how to handle {context.Options.EnumEquivalencyHandling}");
                }
            }

            return(EquivalencyResult.AssertionCompleted);
        }
Example #49
0
        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);
                    }
                }
            }
        }
        public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent,
            IEquivalencyAssertionOptions config)
        {
            Array subjectAsArray = (Array) context.Subject;

            if (AreComparable(context, subjectAsArray))
            {
                Digit digit = BuildDigitsRepresentingAllIndices(subjectAsArray);

                do
                {
                    var expectation = ((Array) context.Expectation).GetValue(digit.Indices);
                    IEquivalencyValidationContext itemContext = context.CreateForCollectionItem(
                        string.Join(",", digit.Indices),
                        subjectAsArray.GetValue(digit.Indices),
                        expectation);

                    parent.AssertEqualityUsing(itemContext);
                }
                while (digit.Increment());
            }

            return true;
        }
        /// <summary>
        /// Gets a value indicating whether this step can handle the verificationScope subject and/or expectation.
        /// </summary>
        public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
        {
            var subjectType = config.GetSubjectType(context);

            return (context.Subject != null) && IsGenericCollection(subjectType);
        }
 /// <summary>
 /// Gets a value indicating whether this step can handle the current subject and/or expectation.
 /// </summary>
 public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
 {
     return !config.IsRecursive && !context.IsRoot;
 }
 public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
 {
     return eqivalencyStep.CanHandle(CreateAdjustedCopy(context), config);
 }
 public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
 {
     return (context.SelectedMemberInfo != null);
 }
 private static bool PreconditionsAreMet(IEquivalencyValidationContext context, IDictionary expectation, IDictionary subject)
 {
     return (AssertIsDictionary(expectation) && AssertSameLength(expectation, subject));
 }
 public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config)
 {
     return assertionRule.AssertEquality(context);
 }
        /// <summary>
        /// Gets a value indicating whether this step can handle the current subject and/or expectation.
        /// </summary>
        public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
        {
            Type subjectType = config.GetSubjectType(context);

            return typeof(IDictionary).IsAssignableFrom(subjectType);
        }
        /// <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)
        {
            context.Subject.Should().Be(context.Expectation, context.Because, context.BecauseArgs);

            return true;
        }
Example #59
0
 public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
 {
     return(true);
 }
        /// <summary>
        /// Gets a value indicating whether this step can handle the verificationScope subject and/or expectation.
        /// </summary>
        public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
        {
            Type subjectType = config.GetSubjectType(context);

            return IsCollection(subjectType);
        }