Add ScriptedRealtimeUpstream + FakeDeviceChannel test doubles
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text.Json;
|
||||
using backend.Tools;
|
||||
|
||||
namespace backend.tests;
|
||||
|
||||
// Slim version for Tasks 9-15. Task 16 reopens this file to add IDeviceClient + envelope sending.
|
||||
public class FakeDeviceChannel : IDeviceChannel
|
||||
{
|
||||
public ConcurrentQueue<JsonElement> PiToolReplies { get; } = new();
|
||||
|
||||
public Task<JsonElement> CallPiToolAsync(string name, JsonElement args, CancellationToken ct)
|
||||
{
|
||||
if (PiToolReplies.TryDequeue(out var reply))
|
||||
return Task.FromResult(reply);
|
||||
return Task.FromResult(JsonDocument.Parse("""{"ok":true}""").RootElement);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Threading.Channels;
|
||||
using backend.Realtime;
|
||||
|
||||
namespace backend.tests;
|
||||
|
||||
public class ScriptedRealtimeUpstream : IRealtimeUpstream
|
||||
{
|
||||
private readonly Channel<JsonObject> _toRelay =
|
||||
Channel.CreateUnbounded<JsonObject>(new UnboundedChannelOptions { SingleReader = true });
|
||||
|
||||
private readonly Channel<JsonObject> _fromRelay =
|
||||
Channel.CreateUnbounded<JsonObject>(new UnboundedChannelOptions { SingleWriter = true });
|
||||
|
||||
public IList<JsonObject> Sent { get; } = new List<JsonObject>();
|
||||
|
||||
public Task SendJsonAsync(JsonObject envelope, CancellationToken ct)
|
||||
{
|
||||
Sent.Add(envelope);
|
||||
return _fromRelay.Writer.WriteAsync(envelope, ct).AsTask();
|
||||
}
|
||||
|
||||
public async Task<JsonObject?> ReceiveJsonAsync(CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _toRelay.Reader.ReadAsync(ct);
|
||||
}
|
||||
catch (ChannelClosedException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Push(JsonObject evt) => _toRelay.Writer.TryWrite(evt);
|
||||
public void CloseUpstream() => _toRelay.Writer.TryComplete();
|
||||
|
||||
public async Task<JsonObject> WaitForSentAsync(string type, CancellationToken ct)
|
||||
{
|
||||
await foreach (var item in _fromRelay.Reader.ReadAllAsync(ct))
|
||||
{
|
||||
if ((string?)item["type"] == type) return item;
|
||||
}
|
||||
throw new TimeoutException($"never saw outbound {type}");
|
||||
}
|
||||
|
||||
public ValueTask DisposeAsync()
|
||||
{
|
||||
_toRelay.Writer.TryComplete();
|
||||
_fromRelay.Writer.TryComplete();
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user