-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathExpressionConstraint.cs
130 lines (116 loc) · 5.04 KB
/
ExpressionConstraint.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using System;
namespace Moryx.AbstractionLayer
{
/// <summary>
/// Constraint that evalutes an expression and compares it to an expected value
/// </summary>
public static class ExpressionConstraint
{
/// <summary>
/// Create a constraint that checks if an expression equals the compare value
/// </summary>
public static IConstraint Equals<TContext>(Func<TContext, object> expression, object compareValue)
where TContext : class, IConstraintContext
{
return new ExpressionEqualsConstraint<TContext>(expression, compareValue);
}
/// <summary>
/// Create a constraint, that checks if an expression is less or equal to the return value
/// </summary>
public static IConstraint LessOrEqual<TContext>(Func<TContext, IComparable> expression, IComparable compareValue)
where TContext : class, IConstraintContext
{
return new ExpressionLessConstraint<TContext>(expression, compareValue);
}
/// <summary>
/// Create a constraint, that checks if an expression is greater or equal to the return value
/// </summary>
public static IConstraint GreaterOrEqual<TContext>(Func<TContext, IComparable> expression, IComparable compareValue)
where TContext : class, IConstraintContext
{
return new ExpressionGreaterConstraint<TContext>(expression, compareValue);
}
/// <summary>
/// Nested generic base class for the differen types of expression constraints
/// </summary>
/// <typeparam name="TContext"></typeparam>
private abstract class ExpressionConstraintBase<TContext> : IConstraint
where TContext : class, IConstraintContext
{
/// <summary>
/// Value the expressions return value is compared to
/// </summary>
protected object Value { get; }
/// <summary>
/// Expression to retrieve the value
/// </summary>
protected Func<TContext, object> Expression { get; }
/// <summary>
/// Create a new expression constraint
/// </summary>
protected ExpressionConstraintBase(Func<TContext, object> expression, object value)
{
Expression = expression;
Value = value;
}
/// <summary>
/// Delegate constraint comparison to the derived type
/// </summary>
public bool Check(IConstraintContext context)
{
var typedContext = context as TContext;
return typedContext != null && CheckConstraint(typedContext);
}
/// <summary>
/// Typed constraint check
/// </summary>
protected abstract bool CheckConstraint(TContext context);
}
/// <summary>
/// Check if the expressions return value equals the <see cref="ExpressionConstraintBase{TContext}.Value"/>
/// </summary>
private class ExpressionEqualsConstraint<TContext> : ExpressionConstraintBase<TContext>
where TContext : class, IConstraintContext
{
public ExpressionEqualsConstraint(Func<TContext, object> expression, object value) : base(expression, value)
{
}
protected override bool CheckConstraint(TContext context)
{
return Expression(context).Equals(Value);
}
}
/// <summary>
/// Check if the expression return value is less or equal to <see cref="ExpressionConstraintBase{TContext}.Value"/>
/// </summary>
private class ExpressionLessConstraint<TContext> : ExpressionConstraintBase<TContext>
where TContext : class, IConstraintContext
{
public ExpressionLessConstraint(Func<TContext, object> expression, object value) : base(expression, value)
{
}
protected override bool CheckConstraint(TContext context)
{
var compareValue = (IComparable)Value;
var returnValue = (IComparable)Expression(context);
return returnValue.CompareTo(compareValue) <= 0;
}
}
/// <summary>
/// Check if the expression return value is greater or equal to <see cref="ExpressionConstraintBase{TContext}.Value"/>
/// </summary>
private class ExpressionGreaterConstraint<TContext> : ExpressionConstraintBase<TContext>
where TContext : class, IConstraintContext
{
public ExpressionGreaterConstraint(Func<TContext, object> expression, object value) : base(expression, value)
{
}
protected override bool CheckConstraint(TContext context)
{
var compareValue = (IComparable)Value;
var returnValue = (IComparable)Expression(context);
return returnValue.CompareTo(compareValue) >= 0;
}
}
}
}