// Copyright (c) Microsoft. All rights reserved. #pragma warning disable CS0618 // Type or member is obsolete - Testing legacy reflection-based pattern using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Agents.AI.Workflows.Execution; using Microsoft.Agents.AI.Workflows.Reflection; using Moq; namespace Microsoft.Agents.AI.Workflows.UnitTests; public class BaseTestExecutor(string id) : ReflectingExecutor(id) where TActual : ReflectingExecutor { protected void OnInvokedHandler() => this.InvokedHandler = true; public bool InvokedHandler { get; private set; } } public class DefaultHandler() : BaseTestExecutor(nameof(DefaultHandler)), IMessageHandler { public ValueTask HandleAsync(object message, IWorkflowContext context, CancellationToken cancellationToken = default) { this.OnInvokedHandler(); return this.Handler(message, context); } public Func Handler { get; set; } = (message, context) => default; } public class TypedHandler() : BaseTestExecutor>(nameof(TypedHandler<>)), IMessageHandler { public ValueTask HandleAsync(TInput message, IWorkflowContext context, CancellationToken cancellationToken = default) { this.OnInvokedHandler(); return this.Handler(message, context); } public Func Handler { get; set; } = (message, context) => default; } public class TypedHandlerWithOutput() : BaseTestExecutor>(nameof(TypedHandlerWithOutput<,>)), IMessageHandler { public ValueTask HandleAsync(TInput message, IWorkflowContext context, CancellationToken cancellationToken) { this.OnInvokedHandler(); return this.Handler(message, context); } public Func> Handler { get; set; } = (message, context) => default; } public class RoutingReflectionTests { private static async ValueTask RunTestReflectAndRouteMessageAsync(BaseTestExecutor executor, TInput? input = default) where TInput : new() where TE : ReflectingExecutor { MessageRouter router = executor.Router; Assert.NotNull(router); input ??= new(); Assert.True(router.CanHandle(input.GetType())); Assert.True(router.CanHandle(input)); CallResult? result = await router.RouteMessageAsync(input, Mock.Of()); Assert.True(executor.InvokedHandler); return result; } [Fact] public async Task Test_ReflectAndExecute_DefaultHandlerAsync() { DefaultHandler executor = new(); CallResult? result = await RunTestReflectAndRouteMessageAsync(executor); Assert.NotNull(result); Assert.True(result.IsSuccess); Assert.True(result.IsVoid); } [Fact] public async Task Test_ReflectAndExecute_HandlerReturnsVoidAsync() { TypedHandler executor = new(); CallResult? result = await RunTestReflectAndRouteMessageAsync>(executor, 3); Assert.NotNull(result); Assert.True(result.IsSuccess); Assert.True(result.IsVoid); } [Fact] public async Task Test_ReflectAndExecute_HandlerReturnsValueAsync() { TypedHandlerWithOutput executor = new() { Handler = (message, context) => new ValueTask($"{message}") }; const string Expected = "3"; CallResult? result = await RunTestReflectAndRouteMessageAsync>(executor, int.Parse(Expected)); Assert.NotNull(result); Assert.True(result.IsSuccess); Assert.False(result.IsVoid); Assert.Equal(Expected, result.Result); } }