104 lines
3.3 KiB
C#
104 lines
3.3 KiB
C#
using System.Collections.Concurrent;
|
|
using System.Runtime.InteropServices;
|
|
using MBN_STOCK_WEBVIEW.Playout.Interop;
|
|
|
|
namespace MBN_STOCK_WEBVIEW.Playout.Tests;
|
|
|
|
public sealed class DynamicK3dEventHandlerTests
|
|
{
|
|
[Fact]
|
|
public void GeneratedHandler_ImplementsImportedInterfaceAndForwardsOnlyLifecycleCallbacks()
|
|
{
|
|
var sink = new RecordingSink();
|
|
var value = DynamicK3dEventHandlerBuilder.Create(typeof(IFakeK3dEventHandler), sink);
|
|
var handler = Assert.IsAssignableFrom<IFakeK3dEventHandler>(value);
|
|
|
|
handler.OnHello();
|
|
handler.OnScenePlayed(1, 9, 10);
|
|
handler.OnCutOut(0, 9, 10);
|
|
handler.OnStopAll(1);
|
|
handler.OnIgnored("sensitive value");
|
|
|
|
Assert.Equal(
|
|
new[]
|
|
{
|
|
"OnHello:",
|
|
"OnScenePlayed:1,9,10",
|
|
"OnCutOut:0,9,10",
|
|
"OnStopAll:1"
|
|
},
|
|
sink.Calls);
|
|
Assert.Equal(
|
|
ClassInterfaceType.None,
|
|
value.GetType().GetCustomAttributes(typeof(ClassInterfaceAttribute), inherit: false)
|
|
.Cast<ClassInterfaceAttribute>()
|
|
.Single()
|
|
.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public void EventQueue_ParsesCallbacksWithoutThrowingAcrossNativeBoundary()
|
|
{
|
|
var queue = new K3dEventQueue(capacity: 4);
|
|
|
|
queue.OnCallback("OnHello", []);
|
|
queue.OnCallback("OnScenePlayed", [1, 9, 10]);
|
|
queue.OnCallback("OnCutOut", [0, 9, 10]);
|
|
queue.OnCallback("OnStopAll", [1]);
|
|
queue.OnCallback("OnScenePlayed", ["invalid"]);
|
|
|
|
Assert.True(queue.HelloObserved);
|
|
Assert.False(queue.HasOverflowed);
|
|
Assert.Equal(3, queue.PendingCount);
|
|
Assert.True(queue.TryDequeue(out var played));
|
|
Assert.Equal(
|
|
new K3dLifecycleCallback(K3dLifecycleCallbackKind.ScenePlayed, true, 9, 10),
|
|
played);
|
|
Assert.True(queue.TryDequeue(out var cut));
|
|
Assert.False(cut.IsSuccess);
|
|
Assert.True(queue.TryDequeue(out var stopped));
|
|
Assert.Equal(K3dLifecycleCallbackKind.StopAll, stopped.Kind);
|
|
Assert.False(queue.TryDequeue(out _));
|
|
}
|
|
|
|
[Fact]
|
|
public void EventQueue_OverflowLatchesAndNeverExceedsCapacity()
|
|
{
|
|
var queue = new K3dEventQueue(capacity: 1);
|
|
|
|
queue.OnCallback("OnStopAll", [1]);
|
|
queue.OnCallback("OnStopAll", [1]);
|
|
|
|
Assert.True(queue.HasOverflowed);
|
|
Assert.Equal(1, queue.PendingCount);
|
|
Assert.True(queue.TryDequeue(out _));
|
|
Assert.False(queue.TryDequeue(out _));
|
|
}
|
|
|
|
private sealed class RecordingSink : IK3dEventSink
|
|
{
|
|
private readonly ConcurrentQueue<string> _calls = new();
|
|
|
|
public string[] Calls => _calls.ToArray();
|
|
|
|
public void OnCallback(string methodName, object?[] arguments) =>
|
|
_calls.Enqueue($"{methodName}:{string.Join(',', arguments)}");
|
|
}
|
|
|
|
[ComImport]
|
|
[Guid("C21817DB-C0D3-4647-8D85-027338DCF832")]
|
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
public interface IFakeK3dEventHandler
|
|
{
|
|
void OnHello();
|
|
|
|
void OnScenePlayed(int success, int outputChannelIndex, int layerIndex);
|
|
|
|
void OnCutOut(int success, int outputChannelIndex, int layerIndex);
|
|
|
|
void OnStopAll(int success);
|
|
|
|
void OnIgnored(string value);
|
|
}
|
|
}
|