Auto: focas-f4b — cnc_wrmacro + cnc_wrparam writes

Closes #269
This commit is contained in:
Joseph Doherty
2026-04-26 04:54:28 -04:00
parent 71af554497
commit f48f31cfc7
15 changed files with 1066 additions and 36 deletions

View File

@@ -18,6 +18,20 @@ internal class FakeFocasClient : IFocasClient
public Dictionary<string, uint> WriteStatuses { get; } = new(StringComparer.OrdinalIgnoreCase);
public List<(FocasAddress addr, FocasDataType type, object? value)> WriteLog { get; } = new();
/// <summary>
/// Plan PR F4-b (issue #269) — separate log of <c>cnc_wrparam</c>-shaped calls
/// observed via <see cref="WriteParameterAsync"/>. Tests assert this list to
/// verify the driver routed PARAM writes through the typed entry point rather
/// than the generic <see cref="WriteAsync"/> dispatch.
/// </summary>
public List<(FocasAddress addr, FocasDataType type, object? value)> ParameterWriteLog { get; } = new();
/// <summary>
/// Plan PR F4-b (issue #269) — separate log of <c>cnc_wrmacro</c>-shaped calls
/// observed via <see cref="WriteMacroAsync"/>.
/// </summary>
public List<(FocasAddress addr, object? value)> MacroWriteLog { get; } = new();
public virtual Task ConnectAsync(FocasHostAddress address, TimeSpan timeout, CancellationToken ct)
{
ConnectCount++;
@@ -46,6 +60,37 @@ internal class FakeFocasClient : IFocasClient
return Task.FromResult(status);
}
/// <summary>
/// Plan PR F4-b (issue #269) — typed parameter-write entry point. Records the
/// call in <see cref="ParameterWriteLog"/>, persists the value into
/// <see cref="Values"/> at the canonical address (so a subsequent read returns
/// the written value), and resolves to <see cref="WriteStatuses"/> if seeded
/// (lets a test simulate <c>EW_PASSWD</c> -> <see cref="FocasStatusMapper.BadUserAccessDenied"/>).
/// </summary>
public virtual Task<uint> WriteParameterAsync(
FocasAddress address, FocasDataType type, object? value, CancellationToken ct)
{
if (ThrowOnWrite) throw Exception ?? new InvalidOperationException();
ParameterWriteLog.Add((address, type, value));
Values[address.Canonical] = value;
var status = WriteStatuses.TryGetValue(address.Canonical, out var s) ? s : FocasStatusMapper.Good;
return Task.FromResult(status);
}
/// <summary>
/// Plan PR F4-b (issue #269) — typed macro-write entry point. See
/// <see cref="WriteParameterAsync"/> for the per-canonical-address store / log shape.
/// </summary>
public virtual Task<uint> WriteMacroAsync(
FocasAddress address, object? value, CancellationToken ct)
{
if (ThrowOnWrite) throw Exception ?? new InvalidOperationException();
MacroWriteLog.Add((address, value));
Values[address.Canonical] = value;
var status = WriteStatuses.TryGetValue(address.Canonical, out var s) ? s : FocasStatusMapper.Good;
return Task.FromResult(status);
}
public List<(int number, int axis, FocasDataType type)> DiagnosticReads { get; } = new();
public virtual Task<(object? value, uint status)> ReadDiagnosticAsync(