// 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 Compiler(Expression> expr); [Fact] public void Compiler_CompileFromConstLookup() { // Arrange Expression> expr = model => 42; var compiler = GetCompilerMethod("CompileFromConstLookup"); // Act var func = compiler(expr); int result = func("any model"); // Assert Assert.Equal(42, result); } [Fact] public void Compiler_CompileFromFingerprint() { // Arrange Expression> expr = s => 20 * s.Length; var compiler = GetCompilerMethod("CompileFromFingerprint"); // Act var func = compiler(expr); int result = func("hello"); // Assert Assert.Equal(100, result); } [Fact] public void Compiler_CompileFromIdentityFunc() { // Arrange Expression> expr = model => model; var compiler = GetCompilerMethod("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> expr = _ => capturedLocal; var compiler = GetCompilerMethod("CompileFromMemberAccess"); // Act var func = compiler(expr); string result = func("hello"); // Assert Assert.Equal("goodbye", result); } [Fact] public void Compiler_CompileFromMemberAccess_ParameterInstanceMember() { // Arrange Expression> expr = s => s.Length; var compiler = GetCompilerMethod("CompileFromMemberAccess"); // Act var func = compiler(expr); int result = func("hello"); // Assert Assert.Equal(5, result); } [Fact] public void Compiler_CompileFromMemberAccess_StaticMember() { // Arrange Expression> expr = _ => String.Empty; var compiler = GetCompilerMethod("CompileFromMemberAccess"); // Act var func = compiler(expr); string result = func("hello"); // Assert Assert.Equal("", result); } [Fact] public void Compiler_CompileSlow() { // Arrange Expression> expr = s => new StringBuilder(s).ToString(); var compiler = GetCompilerMethod("CompileSlow"); // Act var func = compiler(expr); string result = func("hello"); // Assert Assert.Equal("hello", result); } [Fact] public void Process() { // Arrange Expression> 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 GetCompilerMethod(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)Delegate.CreateDelegate(typeof(Compiler), targetMethod); } } }