using CliFx.Infrastructure;
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Driver.Modbus.Cli.Commands;
namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.Cli.Tests;
///
/// Covers Driver.Modbus.Cli-005: probe / read / write must swallow
/// so a Ctrl+C during InitializeAsync exits
/// cleanly instead of dumping a full stack trace through CliFx. SubscribeCommand
/// already handles this around its Task.Delay; these tests pin the same behaviour
/// to the connect/read/write commands.
/// The test pre-cancels the CliFx ; the driver's
/// ConnectAsync observes the token via Dns.GetHostAddressesAsync and throws
/// OCE before any socket I/O happens, so the test is hermetic — no real PLC needed.
///
[Trait("Category", "Unit")]
public sealed class CommandCancellationTests
{
/// Verifies that probe command gracefully handles cancellation during initialization.
[Fact]
public async Task ProbeCommand_swallows_cancellation_during_initialize()
{
using var console = new FakeInMemoryConsole();
console.RequestCancellation(); // simulate Ctrl+C before ExecuteAsync runs
var sut = new ProbeCommand { Host = "127.0.0.1" };
await Should.NotThrowAsync(async () => await sut.ExecuteAsync(console));
}
/// Verifies that read command gracefully handles cancellation during initialization.
[Fact]
public async Task ReadCommand_swallows_cancellation_during_initialize()
{
using var console = new FakeInMemoryConsole();
console.RequestCancellation();
var sut = new ReadCommand
{
Host = "127.0.0.1",
Region = ModbusRegion.HoldingRegisters,
Address = 0,
DataType = ModbusDataType.UInt16,
};
await Should.NotThrowAsync(async () => await sut.ExecuteAsync(console));
}
/// Verifies that write command gracefully handles cancellation during initialization.
[Fact]
public async Task WriteCommand_swallows_cancellation_during_initialize()
{
using var console = new FakeInMemoryConsole();
console.RequestCancellation();
var sut = new WriteCommand
{
Host = "127.0.0.1",
Region = ModbusRegion.HoldingRegisters,
Address = 0,
DataType = ModbusDataType.UInt16,
Value = "42",
};
await Should.NotThrowAsync(async () => await sut.ExecuteAsync(console));
}
}