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 131 132 133 134 135 136 137 138 139 140 141 142 143
|
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using Xunit;
namespace System.Web.Mvc.ExpressionUtil.Test
{
public class CachedExpressionCompilerTest
{
private delegate Func<TIn, TOut> Compiler<TIn, TOut>(Expression<Func<TIn, TOut>> expr);
[Fact]
public void Compiler_CompileFromConstLookup()
{
// Arrange
Expression<Func<string, int>> expr = model => 42;
var compiler = GetCompilerMethod<string, int>("CompileFromConstLookup");
// Act
var func = compiler(expr);
int result = func("any model");
// Assert
Assert.Equal(42, result);
}
[Fact]
public void Compiler_CompileFromFingerprint()
{
// Arrange
Expression<Func<string, int>> expr = s => 20 * s.Length;
var compiler = GetCompilerMethod<string, int>("CompileFromFingerprint");
// Act
var func = compiler(expr);
int result = func("hello");
// Assert
Assert.Equal(100, result);
}
[Fact]
public void Compiler_CompileFromIdentityFunc()
{
// Arrange
Expression<Func<string, string>> expr = model => model;
var compiler = GetCompilerMethod<string, string>("CompileFromIdentityFunc");
// Act
var func = compiler(expr);
string result = func("hello");
// Assert
Assert.Equal("hello", result);
}
[Fact]
public void Compiler_CompileFromMemberAccess_CapturedLocal()
{
// Arrange
string capturedLocal = "goodbye";
Expression<Func<string, string>> expr = _ => capturedLocal;
var compiler = GetCompilerMethod<string, string>("CompileFromMemberAccess");
// Act
var func = compiler(expr);
string result = func("hello");
// Assert
Assert.Equal("goodbye", result);
}
[Fact]
public void Compiler_CompileFromMemberAccess_ParameterInstanceMember()
{
// Arrange
Expression<Func<string, int>> expr = s => s.Length;
var compiler = GetCompilerMethod<string, int>("CompileFromMemberAccess");
// Act
var func = compiler(expr);
int result = func("hello");
// Assert
Assert.Equal(5, result);
}
[Fact]
public void Compiler_CompileFromMemberAccess_StaticMember()
{
// Arrange
Expression<Func<string, string>> expr = _ => String.Empty;
var compiler = GetCompilerMethod<string, string>("CompileFromMemberAccess");
// Act
var func = compiler(expr);
string result = func("hello");
// Assert
Assert.Equal("", result);
}
[Fact]
public void Compiler_CompileSlow()
{
// Arrange
Expression<Func<string, string>> expr = s => new StringBuilder(s).ToString();
var compiler = GetCompilerMethod<string, string>("CompileSlow");
// Act
var func = compiler(expr);
string result = func("hello");
// Assert
Assert.Equal("hello", result);
}
[Fact]
public void Process()
{
// Arrange
Expression<Func<string, string>> expr = s => new StringBuilder(s).ToString();
// Act
var func = CachedExpressionCompiler.Process(expr);
string result = func("hello");
// Assert
Assert.Equal("hello", result);
}
// helper to create a delegate to a private method on the compiler
private static Compiler<TIn, TOut> GetCompilerMethod<TIn, TOut>(string methodName)
{
Type openCompilerType = typeof(CachedExpressionCompiler).GetNestedType("Compiler`2", BindingFlags.NonPublic);
Type closedCompilerType = openCompilerType.MakeGenericType(typeof(TIn), typeof(TOut));
MethodInfo targetMethod = closedCompilerType.GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic);
return (Compiler<TIn, TOut>)Delegate.CreateDelegate(typeof(Compiler<TIn, TOut>), targetMethod);
}
}
}
|