/// <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);
         }
     }
 }
Example #19
0
        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);
        }
Example #22
0
        /// <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);
        }
        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.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;
        }
Example #30
0
        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;
        }
Example #33
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(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);
        }
Example #35
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 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));
        }
Example #36
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 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;
        }
Example #38
0
        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;
        }
Example #41
0
        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();
         }
     });
 }
Example #43
0
        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);
        }
Example #46
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(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;
 }
 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);
 }