127 lines
4.4 KiB
C#
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"));
|
|
}
|