/// <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, 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 expectedType = config.GetExpectationType(context); var interfaceTypes = GetIEnumerableInterfaces(expectedType) .Select(type => "IEnumerable<" + type.GetGenericArguments().Single() + ">") .ToList(); AssertionScope.Current .ForCondition(interfaceTypes.Count == 1) .FailWith("{context:Expectation} implements {0}, so cannot determine which one " + "to use for asserting the equivalency of the collection. ", interfaceTypes); if (AssertSubjectIsCollection(context.Expectation, context.Subject)) { var validator = new EnumerableEquivalencyValidator(parent, context) { Recursive = context.IsRoot || config.IsRecursive, OrderingRules = config.OrderingRules }; Type typeOfEnumeration = GetTypeOfEnumeration(expectedType); MethodCallExpression expectationAsArray = ToArray(context.Expectation, typeOfEnumeration); ConstantExpression subjectAsArray = Expression.Constant(EnumerableEquivalencyStep.ToArray(context.Subject)); MethodCallExpression executeExpression = Expression.Call( Expression.Constant(validator), ExpressionExtensions.GetMethodName(() => validator.Execute <object>(null, null)), new[] { typeOfEnumeration }, subjectAsArray, expectationAsArray); try { Expression.Lambda(executeExpression).Compile().DynamicInvoke(); } catch (TargetInvocationException e) { throw e.Unwrap(); } } 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); }
/// <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; }
/// <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; }
private static void HandleImpl <T>(EnumerableEquivalencyValidator validator, object[] subject, IEnumerable <T> expectation) => validator.Execute(subject, expectation?.ToArray());