56 lines
2.2 KiB
C#
56 lines
2.2 KiB
C#
|
|
using System.Runtime.InteropServices;
|
||
|
|
using VoiceCat.Interop;
|
||
|
|
|
||
|
|
namespace VoiceCat.Interop.Tests;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// API-surface smoke tests for StreamFeedPcm / SetPcmSink through the P/Invoke layer.
|
||
|
|
/// These tests need voicecat.dll but NOT a running server — they verify the C# wrapper
|
||
|
|
/// compiles, is callable, and the error paths work at the C-ABI boundary. Full E2E relay
|
||
|
|
/// verification is handled by tests/test_external_pcm.cpp (C++ ctest).
|
||
|
|
/// </summary>
|
||
|
|
public sealed class ExternalPcmTests
|
||
|
|
{
|
||
|
|
[Fact]
|
||
|
|
public void StreamFeedPcm_NoActiveStream_ReturnsInvalidArg()
|
||
|
|
{
|
||
|
|
using var client = new VoiceCatClient("ext-pcm-test", "0.1", VcLogLevel.Off);
|
||
|
|
var pcm = new short[960];
|
||
|
|
// Stream 0 doesn't exist — core must return InvalidArg, not crash.
|
||
|
|
var result = client.StreamFeedPcm(0, pcm, 960, channels: 1);
|
||
|
|
Assert.Equal(VcResult.InvalidArg, result);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void StreamFeedPcm_InvalidChannels_ReturnsInvalidArg()
|
||
|
|
{
|
||
|
|
using var client = new VoiceCatClient("ext-pcm-test", "0.1", VcLogLevel.Off);
|
||
|
|
var pcm = new short[960 * 3];
|
||
|
|
// channels=3 is not supported — trampoline rejects before touching audio state.
|
||
|
|
var result = client.StreamFeedPcm(0, pcm, 960, channels: 3);
|
||
|
|
Assert.Equal(VcResult.InvalidArg, result);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void SetPcmSink_Zero_ReturnsOk()
|
||
|
|
{
|
||
|
|
using var client = new VoiceCatClient("ext-pcm-test", "0.1", VcLogLevel.Off);
|
||
|
|
// IntPtr.Zero = disable — default state, must be a no-op that returns Ok.
|
||
|
|
var result = client.SetPcmSink(IntPtr.Zero, IntPtr.Zero);
|
||
|
|
Assert.Equal(VcResult.Ok, result);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void SetPcmSink_EnableThenDisable_BothSucceed()
|
||
|
|
{
|
||
|
|
using var client = new VoiceCatClient("ext-pcm-test", "0.1", VcLogLevel.Off);
|
||
|
|
|
||
|
|
// Keep the delegate alive until after we unregister it (not just until the P/Invoke call).
|
||
|
|
NativeMethods.VcPcmSinkCallback sink = static (_, _, _, _, _, _, _) => { };
|
||
|
|
nint fp = Marshal.GetFunctionPointerForDelegate(sink);
|
||
|
|
Assert.Equal(VcResult.Ok, client.SetPcmSink(fp, IntPtr.Zero));
|
||
|
|
Assert.Equal(VcResult.Ok, client.SetPcmSink(IntPtr.Zero, IntPtr.Zero));
|
||
|
|
GC.KeepAlive(sink);
|
||
|
|
}
|
||
|
|
}
|