Example #1
0
        private Result CreateResult(Rule rule, ResultStatus status, FailureReason reason,
                                    object left, RuleComparisonOperatorParameter.Operator op, object right,
                                    params ResultDetail[] details)
        {
            Result result = new Result(this, rule, status, reason,
                                       String.Format(CultureInfo.CurrentCulture, rule.ErrorInfoTemplate, left,
                                                     RuleComparisonOperatorParameter.StringForOperator(op), right));

            foreach (ResultDetail detail in details)
            {
                result.Details.Add(detail);
            }
            return(result);
        }
Example #2
0
        protected override IEnumerable <Result> CheckInternal(object checkable, Rule rule)
        {
            object leftValue = GetValue(checkable, (rule.Parameters["LeftValueFieldName"] as RuleStringParameter).Value);

            RuleComparisonOperatorParameter.Operator comparisonOperator = (rule.Parameters["ComparisonOperator"] as RuleComparisonOperatorParameter).Value;

            var extractionClassParameter    = rule.Parameters["ExtractionFunctionClass"] as RuleStringParameter;
            var extractionFunctionParameter = rule.Parameters["ExtractionFunctionName"] as RuleStringParameter;

            MethodInfo extractionFunction = null;

            // simple check here, more elaborate check is being done in IsCompatibleParameterSet
            if (extractionClassParameter != null)
            {
                var extractionClassType = Type.GetType(extractionClassParameter.Value);
                if (extractionClassType == null)
                {
                    yield return(new Result(this, rule, ResultStatus.Fail, FailureReason.CheckNotPerformed, "Extraction class not found"));

                    yield break;
                }
                extractionFunction = extractionClassType.GetMethod(extractionFunctionParameter.Value);
                if (extractionFunction == null)
                {
                    yield return(new Result(this, rule, ResultStatus.Fail, FailureReason.CheckNotPerformed, "Extraction function not found"));

                    yield break;
                }

                // No yield returning in the body of a catch clause. Great.
                // I'll just do it myself then.
                Exception leftValueException = null;
                try {
                    leftValue = extractionFunction.Invoke(null, new object[] { leftValue });
                }
                catch (Exception ex) {
                    leftValueException = ex;
                }

                if (leftValueException != null)
                {
                    yield return(new Result(this, rule, ResultStatus.Fail, FailureReason.CheckNotPerformed, "Extraction function call failed for left value: " + leftValueException.Message));

                    yield break;
                }
            }

            object rightValue;
            var    rightValueParameter = rule.Parameters["RightValue"];

            if (rightValueParameter != null)
            {
                rightValue = rightValueParameter.Value;
            }
            else
            {
                rightValue = GetValue(checkable, (rule.Parameters["RightValueFieldName"] as RuleStringParameter).Value);
                Exception rightValueException = null;
                if (extractionFunction != null)
                {
                    try {
                        rightValue = extractionFunction.Invoke(null, new object[] { rightValue });
                    }
                    catch (Exception ex) {
                        rightValueException = ex;
                    }
                    if (rightValueException != null)
                    {
                        yield return(new Result(this, rule, ResultStatus.Fail, FailureReason.CheckNotPerformed, "Extraction function call failed for right value: " + rightValueException.Message));

                        yield break;
                    }
                }
            }

            if (rightValue == null)
            {
                if (leftValue == null)
                {
                    yield return(new Result(this, rule, ResultStatus.Pass, FailureReason.None, String.Empty));
                }
                else
                {
                    yield return(CreateResult(rule, ResultStatus.Fail, FailureReason.CheckFailed, leftValue, comparisonOperator, rightValue));
                }
                yield break;
            }

            // I wouldn't initialize this at all, because the following lines
            // of code ensure that compResult is initialized before it reaches
            // the switch block below, or otherwise the method quits.
            // But the compiler doesn't understand this due to the added
            // complexity with the exception handling.
            int       compResult          = 0;
            Exception comparisonException = null;

            try {
                compResult = Comparer.Default.Compare(leftValue, rightValue);
            }
            catch (Exception ex) {
                comparisonException = ex;
            }
            if (comparisonException != null)
            {
                yield return(CreateResult(rule, ResultStatus.Fail, FailureReason.CheckNotPerformed, leftValue,
                                          comparisonOperator, rightValue, new ResultDetail("ExceptionMessage", comparisonException.Message)));

                yield break;
            }

            bool compResultB = false;

            switch (comparisonOperator)
            {
            case RuleComparisonOperatorParameter.Operator.Smaller:
                compResultB = compResult < 0;
                break;

            case RuleComparisonOperatorParameter.Operator.SmallerOrEqual:
                compResultB = compResult <= 0;
                break;

            case RuleComparisonOperatorParameter.Operator.Equal:
                compResultB = compResult == 0;
                break;

            case RuleComparisonOperatorParameter.Operator.NotEqual:
                compResultB = compResult != 0;
                break;

            case RuleComparisonOperatorParameter.Operator.GreaterOrEqual:
                compResultB = compResult >= 0;
                break;

            case RuleComparisonOperatorParameter.Operator.Greater:
                compResultB = compResult > 0;
                break;
            }

            if (compResultB)
            {
                yield return(new Result(this, rule, ResultStatus.Pass, FailureReason.None, null));
            }
            else
            {
                yield return(CreateResult(rule, ResultStatus.Fail, FailureReason.CheckFailed,
                                          leftValue, comparisonOperator, rightValue));
            }
        }