Files

127 lines
4.4 KiB
C#

using System.Runtime.InteropServices;
using NucleicProtocol.Interop;
namespace NucleicApp.Tests;
internal sealed class FakeNativeProtocol : INativeProtocol
{
private NativeProtocolCallback? eventCallback;
private NativeProtocolCallback? stateCallback;
private nint context;
public string? ConfigurationJson { get; private set; }
public string? RendezvousJson { get; private set; }
public List<string> Intents { get; } = [];
public bool Closed { get; private set; }
public string ProjectionResult { get; set; } = "{\"splices\":[],\"version\":1}";
public nint ClientCreate(string configurationJson)
{
ConfigurationJson = configurationJson;
return 11;
}
public void ClientSetCallbacks(
nint handle, NativeProtocolCallback? eventCallback,
NativeProtocolCallback? stateCallback, nint context)
{
this.eventCallback = eventCallback;
this.stateCallback = stateCallback;
this.context = context;
}
public int ClientConnectLocal(nint handle, string rendezvousJson)
{
RendezvousJson = rendezvousJson;
return 0;
}
public int ClientConnectRemote(nint handle, string endpointJson) => 0;
public int ClientPair(nint handle, string pairingCode) => 0;
public int ClientSendIntent(nint handle, string clientMessageJson)
{
Intents.Add(clientMessageJson);
return 0;
}
public void ClientClose(nint handle) => Closed = true;
public nint ProjectionCreate() => 22;
public nint ProjectionApply(nint projection, string hostMessageJson) =>
Marshal.StringToCoTaskMemUTF8(ProjectionResult);
public void ProjectionFree(nint projection) { }
public string CopyAndFreeString(nint value)
{
try { return Marshal.PtrToStringUTF8(value)!; }
finally { Marshal.FreeCoTaskMem(value); }
}
public void EmitEvent(string json) => Emit(eventCallback, json);
public void EmitState(string json) => Emit(stateCallback, json);
private void Emit(NativeProtocolCallback? callback, string json)
{
var pointer = Marshal.StringToCoTaskMemUTF8(json);
try { callback?.Invoke(context, pointer); }
finally { Marshal.FreeCoTaskMem(pointer); }
}
}
internal sealed class FakeProtocolClient : IProtocolClient
{
public event Action<string>? MessageJsonReceived;
public event Action<string>? StateJsonReceived;
public HostdRendezvous? Rendezvous { get; private set; }
public List<string> Intents { get; } = [];
public Queue<ProtocolResult> ConnectLocalResults { get; } = [];
public int ConnectLocalCount { get; private set; }
public bool Disposed { get; private set; }
public ProtocolResult ConnectLocal(HostdRendezvous rendezvous)
{
ConnectLocalCount++;
Rendezvous = rendezvous;
return ConnectLocalResults.TryDequeue(out var result) ? result : ProtocolResult.Ok;
}
public ProtocolResult ConnectRemote(string endpointJson) => ProtocolResult.Ok;
public ProtocolResult Pair(string pairingCode) => ProtocolResult.Ok;
public ProtocolResult SendIntent(string clientMessageJson)
{
Intents.Add(clientMessageJson);
return ProtocolResult.Ok;
}
public void Dispose() => Disposed = true;
public void EmitMessage(string json) => MessageJsonReceived?.Invoke(json);
public void EmitState(string json) => StateJsonReceived?.Invoke(json);
}
internal sealed class FakeProtocolClientFactory(FakeProtocolClient client) : IProtocolClientFactory
{
public ProtocolClientConfiguration? Configuration { get; private set; }
public IProtocolClient Create(ProtocolClientConfiguration configuration)
{
Configuration = configuration;
return client;
}
}
internal static class TestRepository
{
public static string Root
{
get
{
var current = new DirectoryInfo(AppContext.BaseDirectory);
while (current is not null)
{
if (Directory.Exists(Path.Combine(current.FullName, "fixtures", "protocol-abi")))
return current.FullName;
current = current.Parent;
}
throw new DirectoryNotFoundException("could not locate repository fixtures");
}
}
public static string Fixture(string side, string name) => File.ReadAllText(
Path.Combine(Root, "fixtures", "protocol-abi", "v1", side, name + ".json"));
}