Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Generic Test passes under NUnity but not NCrunch
bjjenson
#1 Posted : Friday, August 30, 2013 4:05:04 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 8/30/2013(UTC)
Posts: 3
Location: United States of America

Was thanked: 1 time(s) in 1 post(s)
The following test passes fine under NUnit but does not pass under NCrunch.

[TestCase((int)5, (int)6)]
[TestCase((long)5, (long)6)]
[TestCase((short)5, (short)6)]
[TestCase((double)5.6, (double)6.5)]
[TestCase((float)5.6, (float)6.5)]
[TestCase((bool)true, (bool)false)]
public void CreateFilterExpression_value_equalsOperator<T>(T equalValue, T otherValue)
{
var data = new GenericTestModel<T>[] {
new GenericTestModel<T>{ Value = equalValue},
new GenericTestModel<T> { Value = otherValue},
};
Expression<Func<GenericTestModel<T>, object>> expression = t => t.Value;
T value = equalValue;

var filterExpression = ExpressionBuilder.CreateFilterExpression<GenericTestModel<T>>(expression, value.ToString());

Assert.AreEqual(1, data.Count(filterExpression.Compile()));
}

I would rather not have to write and maintain 6 different tests but will have to do so for the time being. Any suggestions?
Remco
#2 Posted : Friday, August 30, 2013 11:21:42 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,144

Thanks: 959 times
Was thanked: 1290 time(s) in 1196 post(s)
Hi, thanks for sharing this issue.

Is there any chance you could share the code for the ExpressionBuilder and GenericTestModel classes? If you like, you can submit this privately using the contact form. With these components I may be able to reproduce the behaviour you're seeing.

If you haven't already, I recommend reading up on the test troubleshooting page, as this page contains many useful suggestions for troubleshooting issues such as this. NCrunch itself uses NUnit to run your test, so this problem is likely to be caused by a difference between NCrunch's test environment and the test environment the test was designed in. Usually such issues can be resolved with minor modifications to the test or introducing additional NCrunch configuration.


Cheers,

Remco
bjjenson
#3 Posted : Tuesday, September 3, 2013 3:39:35 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 8/30/2013(UTC)
Posts: 3
Location: United States of America

Was thanked: 1 time(s) in 1 post(s)
Here is the code for ExpressionBuilder.

Code:

    public static class ExpressionBuilder
    {
        public static Expression<Func<TModel, bool>> CreateFilterExpression<TModel>(LambdaExpression parameterExpression, string value)
        {
            Type propertyType = GetPropertyType(parameterExpression);
            Func<Expression, Expression, Expression> operatorExpression = null;

            if (propertyType == typeof(string))
            {
                var containsMethod = typeof(string).GetMethod("Contains");
                operatorExpression = (left, target) => Expression.Call(left, containsMethod, target);
            }
            else if (propertyType == typeof(int) ||
                propertyType == typeof(long) ||
                propertyType == typeof(short) ||
                propertyType == typeof(double) ||
                propertyType == typeof(float) ||
                propertyType == typeof(bool))
            {
                operatorExpression = (left, target) => Expression.Equal(left, target);
            }
            else
            {
                throw new NotImplementedException("GetType is not imlemented yet for " + propertyType.ToString());
            }

            return CreateFilterExpression<TModel>(parameterExpression, value, operatorExpression);
        }

        public static Expression<Func<TModel, bool>> CreateFilterExpression<TModel>(LambdaExpression parameterExpression, string value, Func<Expression, Expression, Expression> createOperator)
        {
            var expressions = new List<Expression>();

            ParameterExpression argParam = parameterExpression.Parameters.First();
            var nameMember = GetExpressionMember(parameterExpression);

            var prop = (PropertyInfo)nameMember;
            object typedValue = Convert.ChangeType(value, prop.PropertyType, null);

            Expression equalTarget = Expression.Constant(typedValue, prop.PropertyType);
            Expression left = Expression.PropertyOrField(argParam, nameMember.Name);
            Expression equals = createOperator(left, equalTarget);

            return Expression.Lambda<Func<TModel, bool>>(equals, argParam);
        }

        public static Expression<Func<TModel, bool>> CombineFilters<TModel>(Expression<Func<TModel, bool>> left, Expression<Func<TModel, bool>> right)
        {
            var expressionArg = left.Parameters.First();
            BinaryExpression andedExpression = Expression.AndAlso(left.Body, Expression.Invoke(right, expressionArg));

            return Expression.Lambda<Func<TModel, bool>>(andedExpression, expressionArg);
        }

        private static Type GetPropertyType(LambdaExpression parameterExpression)
        {
            var propertyInfo = (PropertyInfo)GetExpressionMember(parameterExpression);
            return propertyInfo.PropertyType;
        }

        public static MemberInfo GetExpressionMember(LambdaExpression lambda)
        {
            var property = lambda.Body as MemberExpression;
            if (property != null)
            {
                return property.Member;
            }

            var unary = lambda.Body as UnaryExpression;
            if (unary != null)
            {
                return ((MemberExpression)unary.Operand).Member;
            }

            throw new NotImplementedException(lambda.Body.GetType().ToString() + " is not implemented");
        }
    }


And GenericTestModel

Code:

public class GenericTestModel<TValue>
{
    public TValue Value { get; set; }
}
Remco
#4 Posted : Wednesday, September 4, 2013 12:21:58 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,144

Thanks: 959 times
Was thanked: 1290 time(s) in 1196 post(s)
Can you confirm whether you have your Framework utilisation type for NUnit set to StaticAnalysis? If so, this test will cause you problems.

StaticAnalysis is slightly faster than DynamicAnalysis with NUnit, but it does not provide full support for all niche NUnit features (such as complex TestCases). In order to run this test with NCrunch in its current structure, you must use DynamicAnalysis.


Cheers,

Remco
bjjenson
#5 Posted : Wednesday, September 4, 2013 7:25:29 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 8/30/2013(UTC)
Posts: 3
Location: United States of America

Was thanked: 1 time(s) in 1 post(s)
Yes it is set to use StaticAnalysis.

Thanks
1 user thanked bjjenson for this useful post.
Remco on 9/5/2013(UTC)
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

YAF | YAF © 2003-2011, Yet Another Forum.NET
This page was generated in 0.222 seconds.
Trial NCrunch
Take NCrunch for a spin
Do your fingers a favour and supercharge your testing workflow
Free Download