interoptopus_csharp 0.16.0

The C# backend for Interoptopus.
Documentation
using My.Company;
using My.Company.Common;
using System.Threading.Tasks;
using Xunit;

public class TestPatternServicesAsyncPanic
{
    [Fact]
    public async void PanickingThrowsException()
    {
        using var s = ServiceAsyncPanic.Create();

        // A panic inside an async method aborts the future; the cancellation
        // guard then signals `AsyncOutcome::Cancelled`, which the trampoline
        // turns into a TaskCanceledException on the .NET side.
        await Assert.ThrowsAsync<TaskCanceledException>(async () =>
        {
            await s.Panicking();
        });
    }

    [Fact]
    public async void NotPanickingSucceeds()
    {
        using var s = ServiceAsyncPanic.Create();
        await s.NotPanicking();
    }

    [Fact]
    public async void ServiceWorksAfterPanic()
    {
        using var s = ServiceAsyncPanic.Create();

        // First call panics
        await Assert.ThrowsAsync<TaskCanceledException>(async () =>
        {
            await s.Panicking();
        });

        // Service is still functional after the panic
        await s.NotPanicking();
    }

    [Fact]
    public async void ServiceWorksAfterRepeatedPanics()
    {
        using var s = ServiceAsyncPanic.Create();

        for (int i = 0; i < 10; i++)
        {
            await Assert.ThrowsAsync<TaskCanceledException>(async () =>
            {
                await s.Panicking();
            });
        }

        // Service is still functional after repeated panics
        await s.NotPanicking();
    }
}