Fix and tests for invoking static methods
This commit is contained in:
parent
871072d9c3
commit
b2ec59a3f3
@ -12,12 +12,19 @@ namespace Tapeti.Tests.Config
|
|||||||
public void RegisterController()
|
public void RegisterController()
|
||||||
{
|
{
|
||||||
var bindings = GetControllerBindings<TestController>();
|
var bindings = GetControllerBindings<TestController>();
|
||||||
bindings.Should().HaveCount(1);
|
bindings.Should().HaveCount(2);
|
||||||
|
|
||||||
var handleSimpleMessageBinding = bindings.Single(b => b is IControllerMethodBinding cmb &&
|
var handleSimpleMessageBinding = bindings.Single(b => b is IControllerMethodBinding cmb &&
|
||||||
cmb.Controller == typeof(TestController) &&
|
cmb.Controller == typeof(TestController) &&
|
||||||
cmb.Method.Name == "HandleSimpleMessage");
|
cmb.Method.Name == "HandleSimpleMessage");
|
||||||
handleSimpleMessageBinding.QueueType.Should().Be(QueueType.Dynamic);
|
handleSimpleMessageBinding.QueueType.Should().Be(QueueType.Dynamic);
|
||||||
|
|
||||||
|
|
||||||
|
var handleSimpleMessageStaticBinding = bindings.Single(b => b is IControllerMethodBinding cmb &&
|
||||||
|
cmb.Controller == typeof(TestController) &&
|
||||||
|
cmb.Method.Name == "HandleSimpleMessageStatic");
|
||||||
|
handleSimpleMessageStaticBinding.QueueType.Should().Be(QueueType.Dynamic);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -35,6 +42,10 @@ namespace Tapeti.Tests.Config
|
|||||||
public void HandleSimpleMessage(TestMessage message)
|
public void HandleSimpleMessage(TestMessage message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void HandleSimpleMessageStatic(TestMessage message)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning restore
|
#pragma warning restore
|
||||||
|
227
Tapeti.Tests/Helpers/ExpressionInvokerTest.cs
Normal file
227
Tapeti.Tests/Helpers/ExpressionInvokerTest.cs
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Tapeti.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Tapeti.Tests.Helpers
|
||||||
|
{
|
||||||
|
public class ExpressionInvokerTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void InstanceMethodVoidNoParameters()
|
||||||
|
{
|
||||||
|
const string methodName = nameof(InvokeTarget.InstanceMethodVoidNoParameters);
|
||||||
|
var invoker = InvokerFor(methodName);
|
||||||
|
|
||||||
|
var target = new InvokeTarget();
|
||||||
|
invoker.Invoke(target);
|
||||||
|
|
||||||
|
target.Verify(methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InstanceMethodReturnValueNoParameters()
|
||||||
|
{
|
||||||
|
const string methodName = nameof(InvokeTarget.InstanceMethodReturnValueNoParameters);
|
||||||
|
var invoker = InvokerFor(methodName);
|
||||||
|
|
||||||
|
var target = new InvokeTarget();
|
||||||
|
var returnValue = invoker.Invoke(target);
|
||||||
|
|
||||||
|
target.Verify(methodName);
|
||||||
|
returnValue.Should().Be("Hello world!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InstanceMethodVoidParameters()
|
||||||
|
{
|
||||||
|
const string methodName = nameof(InvokeTarget.InstanceMethodVoidParameters);
|
||||||
|
var invoker = InvokerFor(methodName);
|
||||||
|
|
||||||
|
var target = new InvokeTarget();
|
||||||
|
invoker.Invoke(target, 42);
|
||||||
|
|
||||||
|
target.Verify(methodName, "42");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InstanceMethodReturnValueParameters()
|
||||||
|
{
|
||||||
|
const string methodName = nameof(InvokeTarget.InstanceMethodReturnValueParameters);
|
||||||
|
var invoker = InvokerFor(methodName);
|
||||||
|
|
||||||
|
var target = new InvokeTarget();
|
||||||
|
var returnValue = invoker.Invoke(target, new byte[] { 42, 69 });
|
||||||
|
|
||||||
|
target.Verify(methodName, "42,69");
|
||||||
|
returnValue.Should().Be(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void StaticMethodVoidNoParameters()
|
||||||
|
{
|
||||||
|
InvokeTarget.ResetStatic();
|
||||||
|
|
||||||
|
const string methodName = nameof(InvokeTarget.StaticMethodVoidNoParameters);
|
||||||
|
var invoker = InvokerFor(methodName);
|
||||||
|
|
||||||
|
invoker.Invoke(null);
|
||||||
|
|
||||||
|
InvokeTarget.VerifyStatic(methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void StaticMethodReturnValueNoParameters()
|
||||||
|
{
|
||||||
|
InvokeTarget.ResetStatic();
|
||||||
|
|
||||||
|
const string methodName = nameof(InvokeTarget.StaticMethodReturnValueNoParameters);
|
||||||
|
var invoker = InvokerFor(methodName);
|
||||||
|
|
||||||
|
var returnValue = invoker.Invoke(null);
|
||||||
|
|
||||||
|
InvokeTarget.VerifyStatic(methodName);
|
||||||
|
returnValue.Should().Be("Hello world!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void StaticMethodVoidParameters()
|
||||||
|
{
|
||||||
|
InvokeTarget.ResetStatic();
|
||||||
|
|
||||||
|
const string methodName = nameof(InvokeTarget.StaticMethodVoidParameters);
|
||||||
|
var invoker = InvokerFor(methodName);
|
||||||
|
|
||||||
|
invoker.Invoke(null, 42);
|
||||||
|
|
||||||
|
InvokeTarget.VerifyStatic(methodName, "42");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void StaticMethodReturnValueParameters()
|
||||||
|
{
|
||||||
|
InvokeTarget.ResetStatic();
|
||||||
|
|
||||||
|
const string methodName = nameof(InvokeTarget.StaticMethodReturnValueParameters);
|
||||||
|
var invoker = InvokerFor(methodName);
|
||||||
|
|
||||||
|
var returnValue = invoker.Invoke(null, new byte[] { 42, 69 });
|
||||||
|
|
||||||
|
InvokeTarget.VerifyStatic(methodName, "42,69");
|
||||||
|
returnValue.Should().Be(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static ExpressionInvoke InvokerFor(string invokeTargetMethodName)
|
||||||
|
{
|
||||||
|
var method = typeof(InvokeTarget).GetMethod(invokeTargetMethodName);
|
||||||
|
return method!.CreateExpressionInvoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ReSharper disable ParameterHidesMember
|
||||||
|
private class InvokeTarget
|
||||||
|
{
|
||||||
|
private static string? staticMethodName;
|
||||||
|
private static string? staticParameters;
|
||||||
|
|
||||||
|
private string? methodName;
|
||||||
|
private string? parameters;
|
||||||
|
|
||||||
|
|
||||||
|
public void InstanceMethodVoidNoParameters()
|
||||||
|
{
|
||||||
|
MethodCalled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string InstanceMethodReturnValueNoParameters()
|
||||||
|
{
|
||||||
|
MethodCalled();
|
||||||
|
return "Hello world!";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InstanceMethodVoidParameters(int answer)
|
||||||
|
{
|
||||||
|
MethodCalled(answer.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool InstanceMethodReturnValueParameters(IEnumerable<byte> values)
|
||||||
|
{
|
||||||
|
MethodCalled(string.Join(',', values.Select(v => v.ToString())));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void StaticMethodVoidNoParameters()
|
||||||
|
{
|
||||||
|
StaticMethodCalled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string StaticMethodReturnValueNoParameters()
|
||||||
|
{
|
||||||
|
StaticMethodCalled();
|
||||||
|
return "Hello world!";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StaticMethodVoidParameters(int answer)
|
||||||
|
{
|
||||||
|
StaticMethodCalled(answer.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool StaticMethodReturnValueParameters(IEnumerable<byte> values)
|
||||||
|
{
|
||||||
|
StaticMethodCalled(string.Join(',', values.Select(v => v.ToString())));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void MethodCalled(string parameters = "", [CallerMemberName]string methodName = "")
|
||||||
|
{
|
||||||
|
this.methodName.Should().BeNull();
|
||||||
|
this.methodName = methodName;
|
||||||
|
this.parameters = parameters;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void ResetStatic()
|
||||||
|
{
|
||||||
|
staticMethodName = null;
|
||||||
|
staticParameters = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void StaticMethodCalled(string parameters = "", [CallerMemberName] string methodName = "")
|
||||||
|
{
|
||||||
|
staticMethodName.Should().BeNull();
|
||||||
|
staticMethodName = methodName;
|
||||||
|
staticParameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void Verify(string methodName, string parameters = "")
|
||||||
|
{
|
||||||
|
this.methodName.Should().Be(methodName);
|
||||||
|
this.parameters.Should().Be(parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void VerifyStatic(string methodName, string parameters = "")
|
||||||
|
{
|
||||||
|
staticMethodName.Should().Be(methodName);
|
||||||
|
staticParameters.Should().Be(parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -44,22 +44,25 @@ namespace Tapeti.Helpers
|
|||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
|
|
||||||
var target = Expression.Parameter(typeof(object), "target");
|
var instanceParameter = Expression.Parameter(typeof(object), "target");
|
||||||
var castTarget = Expression.Convert(target, method.DeclaringType);
|
Expression? instance = method.IsStatic
|
||||||
var invoke = Expression.Call(castTarget, method, parameters);
|
? null
|
||||||
|
: Expression.Convert(instanceParameter, method.DeclaringType);
|
||||||
|
|
||||||
|
var invoke = Expression.Call(instance, method, parameters);
|
||||||
|
|
||||||
Expression<ExpressionInvoke> lambda;
|
Expression<ExpressionInvoke> lambda;
|
||||||
|
|
||||||
if (method.ReturnType != typeof(void))
|
if (method.ReturnType != typeof(void))
|
||||||
{
|
{
|
||||||
var result = Expression.Convert(invoke, typeof(object));
|
var result = Expression.Convert(invoke, typeof(object));
|
||||||
lambda = Expression.Lambda<ExpressionInvoke>(result, target, argsParameter);
|
lambda = Expression.Lambda<ExpressionInvoke>(result, instanceParameter, argsParameter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var nullResult = Expression.Constant(null, typeof(object));
|
var nullResult = Expression.Constant(null, typeof(object));
|
||||||
var body = Expression.Block(invoke, nullResult);
|
var body = Expression.Block(invoke, nullResult);
|
||||||
lambda = Expression.Lambda<ExpressionInvoke>(body, target, argsParameter);
|
lambda = Expression.Lambda<ExpressionInvoke>(body, instanceParameter, argsParameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return lambda.Compile();
|
return lambda.Compile();
|
||||||
|
Loading…
Reference in New Issue
Block a user