using System; using System.Threading; using System.Threading.Tasks; using FluentAssertions; using Xunit; using ZB.MOM.WW.LmxProxy.Host.MxAccess; namespace ZB.MOM.WW.LmxProxy.Host.Tests.MxAccess { public class StaDispatchThreadTests { [Fact] public async Task DispatchAsync_ExecutesOnStaThread() { using var sta = new StaDispatchThread("Test-STA"); var threadId = await sta.DispatchAsync(() => Thread.CurrentThread.ManagedThreadId); threadId.Should().NotBe(Thread.CurrentThread.ManagedThreadId); } [Fact] public async Task DispatchAsync_ReturnsResult() { using var sta = new StaDispatchThread("Test-STA"); var result = await sta.DispatchAsync(() => 42); result.Should().Be(42); } [Fact] public async Task DispatchAsync_PropagatesException() { using var sta = new StaDispatchThread("Test-STA"); Func act = () => sta.DispatchAsync(() => throw new InvalidOperationException("test error")); await act.Should().ThrowAsync().WithMessage("test error"); } [Fact] public async Task DispatchAsync_Action_Completes() { using var sta = new StaDispatchThread("Test-STA"); int value = 0; await sta.DispatchAsync(() => { value = 99; }); value.Should().Be(99); } [Fact] public void Dispose_CompletesGracefully() { var sta = new StaDispatchThread("Test-STA"); sta.Dispose(); // Should not throw } [Fact] public void DispatchAfterDispose_ThrowsObjectDisposedException() { var sta = new StaDispatchThread("Test-STA"); sta.Dispose(); Func act = () => sta.DispatchAsync(() => 42); act.Should().ThrowAsync(); } [Fact] public async Task MultipleDispatches_ExecuteInOrder() { using var sta = new StaDispatchThread("Test-STA"); var results = new System.Collections.Concurrent.ConcurrentBag(); var tasks = new Task[10]; for (int i = 0; i < 10; i++) { int idx = i; tasks[i] = sta.DispatchAsync(() => { results.Add(idx); }); } await Task.WhenAll(tasks); results.Count.Should().Be(10); } [Fact] public async Task StaThread_HasStaApartmentState() { using var sta = new StaDispatchThread("Test-STA"); var apartmentState = await sta.DispatchAsync(() => Thread.CurrentThread.GetApartmentState()); apartmentState.Should().Be(ApartmentState.STA); } } }