Implementation of the basic functionallity

This commit is contained in:
2024-02-06 19:47:06 +01:00
parent a6c7828fbe
commit f31f6f94ff
42 changed files with 6875 additions and 11 deletions

View File

@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>12.0</LangVersion>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<CollectCoverage>true</CollectCoverage>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.msbuild" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="MSTest.TestAdapter" Version="3.2.0" />
<PackageReference Include="MSTest.TestFramework" Version="3.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AMWD.Protocols.Modbus.Common\AMWD.Protocols.Modbus.Common.csproj" />
<ProjectReference Include="..\AMWD.Protocols.Modbus.Tcp\AMWD.Protocols.Modbus.Tcp.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,742 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using AMWD.Protocols.Modbus.Common.Contracts;
using Moq;
namespace AMWD.Protocols.Modbus.Tests.Common.Contracts
{
[TestClass]
public class ModbusClientBaseTest
{
// Consts
private const byte UNIT_ID = 42;
private const ushort START_ADDRESS = 123;
private const ushort READ_COUNT = 12;
// Mocks
private Mock<IModbusConnection> _connection;
private Mock<IModbusProtocol> _protocol;
// Responses
private bool _connectionIsConnectecd;
private List<Coil> _readCoilsResponse;
private List<DiscreteInput> _readDiscreteInputsResponse;
private List<HoldingRegister> _readHoldingRegistersResponse;
private List<InputRegister> _readInputRegistersResponse;
private Coil _writeSingleCoilResponse;
private HoldingRegister _writeSingleHoldingRegisterResponse;
private (ushort startAddress, ushort count) _writeMultipleCoilsResponse;
private (ushort startAddress, ushort count) _writeMultipleHoldingRegistersResponse;
[TestInitialize]
public void Initialize()
{
_connectionIsConnectecd = true;
_readCoilsResponse = new List<Coil>();
_readDiscreteInputsResponse = new List<DiscreteInput>();
_readHoldingRegistersResponse = new List<HoldingRegister>();
_readInputRegistersResponse = new List<InputRegister>();
for (int i = 0; i < READ_COUNT; i++)
{
_readCoilsResponse.Add(new Coil
{
Address = (ushort)i,
HighByte = (byte)((i % 2 == 0) ? 0xFF : 0x00)
});
_readDiscreteInputsResponse.Add(new DiscreteInput
{
Address = (ushort)i,
HighByte = (byte)((i % 2 == 1) ? 0xFF : 0x00)
});
_readHoldingRegistersResponse.Add(new HoldingRegister
{
Address = (ushort)i,
HighByte = 0x00,
LowByte = (byte)(i + 10)
});
_readInputRegistersResponse.Add(new InputRegister
{
Address = (ushort)i,
HighByte = 0x00,
LowByte = (byte)(i + 15)
});
}
_writeSingleCoilResponse = new Coil { Address = START_ADDRESS };
_writeSingleHoldingRegisterResponse = new HoldingRegister { Address = START_ADDRESS, Value = 0x1234 };
_writeMultipleCoilsResponse = (START_ADDRESS, READ_COUNT);
_writeMultipleHoldingRegistersResponse = (START_ADDRESS, READ_COUNT);
}
[TestMethod]
public void ShouldPrettyPrint()
{
// Arrange
var client = GetClient();
// Act
string str = client.ToString();
// Assert
Assert.AreEqual("Modbus client using Moq protocol to connect via Mock", str);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowExceptionOnNullConnection()
{
// Arrange
IModbusConnection connection = null;
// Act
new ModbusClientBaseWrapper(connection);
// Assert - ArgumentNullException
}
[TestMethod]
public async Task ShouldConnectSuccessfully()
{
// Arrange
var client = GetClient();
// Act
await client.ConnectAsync();
// Assert
_connection.Verify(c => c.ConnectAsync(It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldDisconnectSuccessfully()
{
// Arrange
var client = GetClient();
// Act
await client.DisconnectAsync();
// Assert
_connection.Verify(c => c.DisconnectAsync(It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.VerifyNoOtherCalls();
}
[DataTestMethod]
[DataRow(true)]
[DataRow(false)]
public void ShouldAlsoDisposeConnection(bool disposeConnection)
{
// Arrange
var client = GetClient(disposeConnection);
// Act
client.Dispose();
// Assert
if (disposeConnection)
_connection.Verify(c => c.Dispose(), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public void ShouldAllowDisposeMultipleTimes()
{
// Arrange
var client = GetClient();
// Act
client.Dispose();
client.Dispose();
// Assert
_connection.Verify(c => c.Dispose(), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
[ExpectedException(typeof(ObjectDisposedException))]
public async Task ShouldAssertDisposed()
{
// Arrange
var client = GetClient();
client.Dispose();
// Act
await client.ReadCoilsAsync(UNIT_ID, START_ADDRESS, READ_COUNT);
// Assert - ObjectDisposedException
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public async Task ShouldAssertProtocolSet()
{
// Arrange
var client = GetClient();
client.Protocol = null;
// Act
await client.ReadCoilsAsync(UNIT_ID, START_ADDRESS, READ_COUNT);
// Assert - ArgumentNullException
}
[TestMethod]
[ExpectedException(typeof(ApplicationException))]
public async Task ShouldAssertConnected()
{
// Arrange
_connectionIsConnectecd = false;
var client = GetClient();
// Act
await client.ReadCoilsAsync(UNIT_ID, START_ADDRESS, READ_COUNT);
// Assert - ApplicationException
}
[TestMethod]
public async Task ShouldReadCoils()
{
// Arrange
_readCoilsResponse.Add(new Coil());
var client = GetClient();
// Act
var result = await client.ReadCoilsAsync(UNIT_ID, START_ADDRESS, READ_COUNT);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(READ_COUNT, result.Count);
for (int i = 0; i < READ_COUNT; i++)
{
Assert.AreEqual(START_ADDRESS + i, result[i].Address);
Assert.AreEqual(i % 2 == 0, result[i].Value);
}
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeReadCoils(UNIT_ID, START_ADDRESS, READ_COUNT), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeReadCoils(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldReadDiscreteInputs()
{
// Arrange
_readDiscreteInputsResponse.Add(new DiscreteInput());
var client = GetClient();
// Act
var result = await client.ReadDiscreteInputsAsync(UNIT_ID, START_ADDRESS, READ_COUNT);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(READ_COUNT, result.Count);
for (int i = 0; i < READ_COUNT; i++)
{
Assert.AreEqual(START_ADDRESS + i, result[i].Address);
Assert.AreEqual(i % 2 == 1, result[i].Value);
}
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeReadDiscreteInputs(UNIT_ID, START_ADDRESS, READ_COUNT), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeReadDiscreteInputs(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldReadHoldingRegisters()
{
// Arrange
var client = GetClient();
// Act
var result = await client.ReadHoldingRegistersAsync(UNIT_ID, START_ADDRESS, READ_COUNT);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(READ_COUNT, result.Count);
for (int i = 0; i < READ_COUNT; i++)
{
Assert.AreEqual(START_ADDRESS + i, result[i].Address);
Assert.AreEqual(i + 10, result[i].Value);
}
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeReadHoldingRegisters(UNIT_ID, START_ADDRESS, READ_COUNT), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeReadHoldingRegisters(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldReadInputRegisters()
{
// Arrange
var client = GetClient();
// Act
var result = await client.ReadInputRegistersAsync(UNIT_ID, START_ADDRESS, READ_COUNT);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(READ_COUNT, result.Count);
for (int i = 0; i < READ_COUNT; i++)
{
Assert.AreEqual(START_ADDRESS + i, result[i].Address);
Assert.AreEqual(i + 15, result[i].Value);
}
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeReadInputRegisters(UNIT_ID, START_ADDRESS, READ_COUNT), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeReadInputRegisters(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldWriteSingleCoil()
{
// Arrange
var coil = new Coil
{
Address = START_ADDRESS,
Value = false
};
var client = GetClient();
// Act
bool result = await client.WriteSingleCoilAsync(UNIT_ID, coil);
// Assert
Assert.IsTrue(result);
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeWriteSingleCoil(UNIT_ID, coil), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeWriteSingleCoil(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldFailWriteSingleCoilOnAddress()
{
// Arrange
var coil = new Coil
{
Address = START_ADDRESS + 1,
Value = false
};
var client = GetClient();
// Act
bool result = await client.WriteSingleCoilAsync(UNIT_ID, coil);
// Assert
Assert.IsFalse(result);
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeWriteSingleCoil(UNIT_ID, coil), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeWriteSingleCoil(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldFailWriteSingleCoilOnValue()
{
// Arrange
var coil = new Coil
{
Address = START_ADDRESS,
Value = true
};
var client = GetClient();
// Act
bool result = await client.WriteSingleCoilAsync(UNIT_ID, coil);
// Assert
Assert.IsFalse(result);
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeWriteSingleCoil(UNIT_ID, coil), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeWriteSingleCoil(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldWriteSingleHoldingRegister()
{
// Arrange
var register = new HoldingRegister
{
Address = START_ADDRESS,
Value = 0x1234
};
var client = GetClient();
// Act
bool result = await client.WriteSingleHoldingRegisterAsync(UNIT_ID, register);
// Assert
Assert.IsTrue(result);
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeWriteSingleHoldingRegister(UNIT_ID, register), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeWriteSingleHoldingRegister(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldFailWriteSingleHoldingRegisterOnAddress()
{
// Arrange
var register = new HoldingRegister
{
Address = START_ADDRESS + 1,
Value = 0x1234
};
var client = GetClient();
// Act
bool result = await client.WriteSingleHoldingRegisterAsync(UNIT_ID, register);
// Assert
Assert.IsFalse(result);
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeWriteSingleHoldingRegister(UNIT_ID, register), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeWriteSingleHoldingRegister(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldFailWriteSingleHoldingRegisterOnValue()
{
// Arrange
var register = new HoldingRegister
{
Address = START_ADDRESS,
Value = 0x1233
};
var client = GetClient();
// Act
bool result = await client.WriteSingleHoldingRegisterAsync(UNIT_ID, register);
// Assert
Assert.IsFalse(result);
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeWriteSingleHoldingRegister(UNIT_ID, register), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeWriteSingleHoldingRegister(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldWriteMultipleCoils()
{
// Arrange
var coils = new List<Coil>();
for (int i = 0; i < READ_COUNT; i++)
{
coils.Add(new Coil
{
Address = (ushort)(START_ADDRESS + i),
Value = i % 2 == 0
});
}
var client = GetClient();
// Act
bool result = await client.WriteMultipleCoilsAsync(UNIT_ID, coils);
// Assert
Assert.IsTrue(result);
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeWriteMultipleCoils(UNIT_ID, coils), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeWriteMultipleCoils(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldFailWriteMultipleCoilsOnAddress()
{
// Arrange
_writeMultipleCoilsResponse.startAddress = START_ADDRESS + 1;
var coils = new List<Coil>();
for (int i = 0; i < READ_COUNT; i++)
{
coils.Add(new Coil
{
Address = (ushort)(START_ADDRESS + i),
Value = i % 2 == 0
});
}
var client = GetClient();
// Act
bool result = await client.WriteMultipleCoilsAsync(UNIT_ID, coils);
// Assert
Assert.IsFalse(result);
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeWriteMultipleCoils(UNIT_ID, coils), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeWriteMultipleCoils(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldFailWriteMultipleCoilsOnCount()
{
// Arrange
_writeMultipleCoilsResponse.count = READ_COUNT + 1;
var coils = new List<Coil>();
for (int i = 0; i < READ_COUNT; i++)
{
coils.Add(new Coil
{
Address = (ushort)(START_ADDRESS + i),
Value = i % 2 == 0
});
}
var client = GetClient();
// Act
bool result = await client.WriteMultipleCoilsAsync(UNIT_ID, coils);
// Assert
Assert.IsFalse(result);
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeWriteMultipleCoils(UNIT_ID, coils), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeWriteMultipleCoils(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldWriteMultipleRegisters()
{
// Arrange
var registers = new List<HoldingRegister>();
for (int i = 0; i < READ_COUNT; i++)
{
registers.Add(new HoldingRegister
{
Address = (ushort)(START_ADDRESS + i),
Value = (ushort)i
});
}
var client = GetClient();
// Act
bool result = await client.WriteMultipleHoldingRegistersAsync(UNIT_ID, registers);
// Assert
Assert.IsTrue(result);
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeWriteMultipleHoldingRegisters(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldFailWriteMultiplRegistersOnAddress()
{
// Arrange
_writeMultipleHoldingRegistersResponse.startAddress = START_ADDRESS + 1;
var registers = new List<HoldingRegister>();
for (int i = 0; i < READ_COUNT; i++)
{
registers.Add(new HoldingRegister
{
Address = (ushort)(START_ADDRESS + i),
Value = (ushort)i
});
}
var client = GetClient();
// Act
bool result = await client.WriteMultipleHoldingRegistersAsync(UNIT_ID, registers);
// Assert
Assert.IsFalse(result);
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeWriteMultipleHoldingRegisters(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
[TestMethod]
public async Task ShouldFailWriteMultipleRegistersOnCount()
{
// Arrange
_writeMultipleHoldingRegistersResponse.count = READ_COUNT + 1;
var registers = new List<HoldingRegister>();
for (int i = 0; i < READ_COUNT; i++)
{
registers.Add(new HoldingRegister
{
Address = (ushort)(START_ADDRESS + i),
Value = (ushort)i
});
}
var client = GetClient();
// Act
bool result = await client.WriteMultipleHoldingRegistersAsync(UNIT_ID, registers);
// Assert
Assert.IsFalse(result);
_connection.VerifyGet(c => c.IsConnected, Times.Once);
_connection.Verify(c => c.InvokeAsync(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<Func<IReadOnlyList<byte>, bool>>(), It.IsAny<CancellationToken>()), Times.Once);
_connection.VerifyNoOtherCalls();
_protocol.Verify(p => p.SerializeWriteMultipleHoldingRegisters(UNIT_ID, registers), Times.Once);
_protocol.Verify(p => p.ValidateResponse(It.IsAny<IReadOnlyList<byte>>(), It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.Verify(p => p.DeserializeWriteMultipleHoldingRegisters(It.IsAny<IReadOnlyList<byte>>()), Times.Once);
_protocol.VerifyNoOtherCalls();
}
private ModbusClientBase GetClient(bool disposeConnection = true)
{
_connection = new Mock<IModbusConnection>();
_connection
.SetupGet(c => c.Name)
.Returns("Mock");
_connection
.SetupGet(c => c.IsConnected)
.Returns(() => _connectionIsConnectecd);
_protocol = new Mock<IModbusProtocol>();
_protocol
.SetupGet(p => p.Name)
.Returns("Moq");
_protocol
.Setup(p => p.DeserializeReadCoils(It.IsAny<IReadOnlyList<byte>>()))
.Returns(() => _readCoilsResponse);
_protocol
.Setup(p => p.DeserializeReadDiscreteInputs(It.IsAny<IReadOnlyList<byte>>()))
.Returns(() => _readDiscreteInputsResponse);
_protocol
.Setup(p => p.DeserializeReadHoldingRegisters(It.IsAny<IReadOnlyList<byte>>()))
.Returns(() => _readHoldingRegistersResponse);
_protocol
.Setup(p => p.DeserializeReadInputRegisters(It.IsAny<IReadOnlyList<byte>>()))
.Returns(() => _readInputRegistersResponse);
_protocol
.Setup(p => p.DeserializeWriteSingleCoil(It.IsAny<IReadOnlyList<byte>>()))
.Returns(() => _writeSingleCoilResponse);
_protocol
.Setup(p => p.DeserializeWriteSingleHoldingRegister(It.IsAny<IReadOnlyList<byte>>()))
.Returns(() => _writeSingleHoldingRegisterResponse);
_protocol
.Setup(p => p.DeserializeWriteMultipleCoils(It.IsAny<IReadOnlyList<byte>>()))
.Returns(() => _writeMultipleCoilsResponse);
_protocol
.Setup(p => p.DeserializeWriteMultipleHoldingRegisters(It.IsAny<IReadOnlyList<byte>>()))
.Returns(() => _writeMultipleHoldingRegistersResponse);
return new ModbusClientBaseWrapper(_connection.Object, disposeConnection)
{
Protocol = _protocol.Object,
};
}
internal class ModbusClientBaseWrapper : ModbusClientBase
{
public ModbusClientBaseWrapper(IModbusConnection connection)
: base(connection)
{ }
public ModbusClientBaseWrapper(IModbusConnection connection, bool disposeConnection)
: base(connection, disposeConnection)
{ }
public override IModbusProtocol Protocol { get; set; }
}
}
}

View File

@@ -0,0 +1,330 @@
using AMWD.Protocols.Modbus.Common;
namespace AMWD.Protocols.Modbus.Tests.Common.Extensions
{
[TestClass]
public class ModbusDecimalExtensionsTest
{
#region Modbus to value
[TestMethod]
public void ShouldGetSingle()
{
// Arrange
var registers = new HoldingRegister[]
{
new(),
new() { Address = 100, HighByte = 0x41, LowByte = 0x45 },
new() { Address = 101, HighByte = 0x70, LowByte = 0xA4 }
};
// Act
float f = registers.GetSingle(1);
// Assert
Assert.AreEqual(12.34f, f);
}
[TestMethod]
public void ShouldGetSingleReversedRegisters()
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 101, HighByte = 0x41, LowByte = 0x45 },
new() { Address = 100, HighByte = 0x70, LowByte = 0xA4 }
};
// Act
float f = registers.GetSingle(0, reverseRegisterOrder: true);
// Assert
Assert.AreEqual(12.34f, f);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullOnGetSingle()
{
// Arrange
HoldingRegister[] registers = null;
// Act
registers.GetSingle(0);
// Assert - ArgumentNullException
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnGetSingleForLength()
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 101, HighByte = 0x01, LowByte = 0x02 }
};
// Act
registers.GetSingle(0);
// Assert - ArgumentException
}
[DataTestMethod]
[DataRow(1)]
[DataRow(-1)]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void ShouldThrowArgumentOutOfRangeOnGetSingle(int startIndex)
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 101, HighByte = 0x01, LowByte = 0x02 },
new() { Address = 100, HighByte = 0x03, LowByte = 0x04 }
};
// Act
registers.GetSingle(startIndex);
// Assert - ArgumentOutOfRangeException
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnGetSingleForType()
{
// Arrange
var registers = new ModbusObject[]
{
new HoldingRegister { Address = 100, HighByte = 0x01, LowByte = 0x02 },
new InputRegister { Address = 101, HighByte = 0x03, LowByte = 0x04 }
};
// Act
registers.GetSingle(0);
// Assert - ArgumentException
}
[TestMethod]
public void ShouldGetDouble()
{
// Arrange
var registers = new HoldingRegister[]
{
new(),
new() { Address = 100, HighByte = 0x40, LowByte = 0x28 },
new() { Address = 101, HighByte = 0xAE, LowByte = 0x14 },
new() { Address = 102, HighByte = 0x7A, LowByte = 0xE1 },
new() { Address = 103, HighByte = 0x47, LowByte = 0xAE }
};
// Act
double d = registers.GetDouble(1);
// Assert
Assert.AreEqual(12.34, d);
}
[TestMethod]
public void ShouldGetDoubleReversedRegisters()
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 103, HighByte = 0x40, LowByte = 0x28 },
new() { Address = 102, HighByte = 0xAE, LowByte = 0x14 },
new() { Address = 101, HighByte = 0x7A, LowByte = 0xE1 },
new() { Address = 100, HighByte = 0x47, LowByte = 0xAE }
};
// Act
double d = registers.GetDouble(0, reverseRegisterOrder: true);
// Assert
Assert.AreEqual(12.34, d);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullOnGetDouble()
{
// Arrange
HoldingRegister[] registers = null;
// Act
registers.GetDouble(0);
// Assert - ArgumentNullException
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnGetDoubleForLength()
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 100, HighByte = 0x40, LowByte = 0x28 },
new() { Address = 101, HighByte = 0xAE, LowByte = 0x14 },
new() { Address = 102, HighByte = 0x7A, LowByte = 0xE1 }
};
// Act
registers.GetDouble(0);
// Assert - ArgumentException
}
[DataTestMethod]
[DataRow(1)]
[DataRow(-1)]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void ShouldThrowArgumentOutOfRangeOnGetDouble(int startIndex)
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 100, HighByte = 0x40, LowByte = 0x28 },
new() { Address = 101, HighByte = 0xAE, LowByte = 0x14 },
new() { Address = 102, HighByte = 0x7A, LowByte = 0xE1 },
new() { Address = 103, HighByte = 0x47, LowByte = 0xAE }
};
// Act
registers.GetDouble(startIndex);
// Assert - ArgumentOutOfRangeException
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnGetDoubleForType()
{
// Arrange
var registers = new ModbusObject[]
{
new HoldingRegister { Address = 100, HighByte = 0x40, LowByte = 0x28 },
new InputRegister { Address = 101, HighByte = 0xAE, LowByte = 0x14 },
new HoldingRegister { Address = 102, HighByte = 0x7A, LowByte = 0xE1 },
new InputRegister { Address = 103, HighByte = 0x47, LowByte = 0xAE }
};
// Act
registers.GetDouble(0);
// Assert - ArgumentException
}
#endregion Modbus to value
#region Value to Modbus
[TestMethod]
public void ShouldConvertSingle()
{
// Arrange
float f = 12.34f;
// Act
var registers = f.ToRegister(5).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(2, registers.Count);
Assert.AreEqual(5, registers[0].Address);
Assert.AreEqual(0x41, registers[0].HighByte);
Assert.AreEqual(0x45, registers[0].LowByte);
Assert.AreEqual(6, registers[1].Address);
Assert.AreEqual(0x70, registers[1].HighByte);
Assert.AreEqual(0xA4, registers[1].LowByte);
}
[TestMethod]
public void ShouldConvertSingleReversed()
{
// Arrange
float f = 12.34f;
// Act
var registers = f.ToRegister(5, reverseRegisterOrder: true).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(2, registers.Count);
Assert.AreEqual(6, registers[0].Address);
Assert.AreEqual(0x41, registers[0].HighByte);
Assert.AreEqual(0x45, registers[0].LowByte);
Assert.AreEqual(5, registers[1].Address);
Assert.AreEqual(0x70, registers[1].HighByte);
Assert.AreEqual(0xA4, registers[1].LowByte);
}
[TestMethod]
public void ShouldConvertDouble()
{
// Arrange
double d = 12.34;
// Act
var registers = d.ToRegister(5).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(4, registers.Count);
Assert.AreEqual(5, registers[0].Address);
Assert.AreEqual(0x40, registers[0].HighByte);
Assert.AreEqual(0x28, registers[0].LowByte);
Assert.AreEqual(6, registers[1].Address);
Assert.AreEqual(0xAE, registers[1].HighByte);
Assert.AreEqual(0x14, registers[1].LowByte);
Assert.AreEqual(7, registers[2].Address);
Assert.AreEqual(0x7A, registers[2].HighByte);
Assert.AreEqual(0xE1, registers[2].LowByte);
Assert.AreEqual(8, registers[3].Address);
Assert.AreEqual(0x47, registers[3].HighByte);
Assert.AreEqual(0xAE, registers[3].LowByte);
}
[TestMethod]
public void ShouldConvertDoubleReversed()
{
// Arrange
double d = 12.34;
// Act
var registers = d.ToRegister(5, reverseRegisterOrder: true).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(4, registers.Count);
Assert.AreEqual(8, registers[0].Address);
Assert.AreEqual(0x40, registers[0].HighByte);
Assert.AreEqual(0x28, registers[0].LowByte);
Assert.AreEqual(7, registers[1].Address);
Assert.AreEqual(0xAE, registers[1].HighByte);
Assert.AreEqual(0x14, registers[1].LowByte);
Assert.AreEqual(6, registers[2].Address);
Assert.AreEqual(0x7A, registers[2].HighByte);
Assert.AreEqual(0xE1, registers[2].LowByte);
Assert.AreEqual(5, registers[3].Address);
Assert.AreEqual(0x47, registers[3].HighByte);
Assert.AreEqual(0xAE, registers[3].LowByte);
}
#endregion Value to Modbus
}
}

View File

@@ -0,0 +1,289 @@
using System.Text;
namespace AMWD.Protocols.Modbus.Tests.Common.Extensions
{
[TestClass]
public class ModbusExtensionsTest
{
#region Modbus to value
[TestMethod]
public void ShouldConvertToBoolean()
{
// Arrange
var coil = new Coil { HighByte = 0x00 };
var discreteInput = new DiscreteInput { HighByte = 0xFF };
var holdingRegister = new HoldingRegister { HighByte = 0x01 };
var inputRegister = new InputRegister { LowByte = 0x10 };
// Act
bool coilResult = coil.GetBoolean();
bool discreteInputResult = discreteInput.GetBoolean();
bool holdingRegisterResult = holdingRegister.GetBoolean();
bool inputRegisterResult = inputRegister.GetBoolean();
// Assert
Assert.IsFalse(coilResult);
Assert.IsTrue(discreteInputResult);
Assert.IsTrue(holdingRegisterResult);
Assert.IsTrue(inputRegisterResult);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullOnGetBoolean()
{
// Arrange
Coil coil = null;
// Act
coil.GetBoolean();
// Assert - ArgumentNullException
}
[TestMethod]
public void ShouldConvertToString()
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 1, HighByte = 65, LowByte = 66 },
new() { Address = 2, HighByte = 67, LowByte = 0 },
new() { Address = 3, HighByte = 95, LowByte = 96 }
};
// Act
string text = registers.GetString(3);
// Assert
Assert.AreEqual("ABC", text);
}
[TestMethod]
public void ShouldConvertToStringReversedBytes()
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 1, HighByte = 66, LowByte = 65 },
new() { Address = 2, HighByte = 0, LowByte = 67 }
};
// Act
string text = registers.GetString(2, reverseByteOrderPerRegister: true);
// Assert
Assert.AreEqual("ABC", text);
}
[TestMethod]
public void ShouldConvertToStringReversedRegisters()
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 2, HighByte = 65, LowByte = 66 },
new() { Address = 1, HighByte = 67, LowByte = 0 },
};
// Act
string text = registers.GetString(2, reverseRegisterOrder: true);
// Assert
Assert.AreEqual("ABC", text);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullOnString()
{
// Arrange
HoldingRegister[] list = null;
// Act
list.GetString(2);
// Assert - ArgumentNullException
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnStringForEmptyList()
{
// Arrange
var registers = Array.Empty<HoldingRegister>();
// Act
registers.GetString(2);
// Assert - ArgumentException
}
[DataTestMethod]
[DataRow(1)]
[DataRow(-1)]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void ShouldThrowArgumentOutOfRangeOnString(int startIndex)
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 1, HighByte = 65, LowByte = 66 },
new() { Address = 2, HighByte = 67, LowByte = 0 }
};
// Act
registers.GetString(2, startIndex);
// Assert - ArgumentOutOfRangeException
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnStringForMixedTypes()
{
// Arrange
var registers = new ModbusObject[]
{
new HoldingRegister { Address = 1, HighByte = 65, LowByte = 66 },
new InputRegister { Address = 2, HighByte = 67, LowByte = 0 }
};
// Act
registers.GetString(2);
// Assert - ArgumentException
}
#endregion Modbus to value
#region Value to Modbus
[TestMethod]
public void ShouldGetBooleanCoil()
{
// Arrange
bool value = false;
// Act
var coil = value.ToCoil(123);
// Assert
Assert.IsNotNull(coil);
Assert.AreEqual(123, coil.Address);
Assert.IsFalse(coil.Value);
}
[TestMethod]
public void ShouldGetBooleanRegisterTrue()
{
// Arrange
bool value = true;
// Act
var register = value.ToRegister(321);
// Assert
Assert.IsNotNull(register);
Assert.AreEqual(321, register.Address);
Assert.IsTrue(register.Value > 0);
}
[TestMethod]
public void ShouldGetBooleanRegisterFalse()
{
// Arrange
bool value = false;
// Act
var register = value.ToRegister(321);
// Assert
Assert.IsNotNull(register);
Assert.AreEqual(321, register.Address);
Assert.IsTrue(register.Value == 0);
}
[TestMethod]
public void ShouldGetString()
{
// Arrange
string str = "abc";
// Act
var registers = str.ToRegisters(100).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(2, registers.Count);
Assert.AreEqual(100, registers[0].Address);
Assert.AreEqual(97, registers[0].HighByte);
Assert.AreEqual(98, registers[0].LowByte);
Assert.AreEqual(101, registers[1].Address);
Assert.AreEqual(99, registers[1].HighByte);
Assert.AreEqual(0, registers[1].LowByte);
}
[TestMethod]
public void ShouldGetStringReversedRegisters()
{
// Arrange
string str = "abc";
// Act
var registers = str.ToRegisters(100, reverseRegisterOrder: true).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(2, registers.Count);
Assert.AreEqual(101, registers[0].Address);
Assert.AreEqual(97, registers[0].HighByte);
Assert.AreEqual(98, registers[0].LowByte);
Assert.AreEqual(100, registers[1].Address);
Assert.AreEqual(99, registers[1].HighByte);
Assert.AreEqual(0, registers[1].LowByte);
}
[TestMethod]
public void ShouldGetStringReversedBytes()
{
// Arrange
string str = "abc";
// Act
var registers = str.ToRegisters(100, reverseByteOrderPerRegister: true).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(2, registers.Count);
Assert.AreEqual(100, registers[0].Address);
Assert.AreEqual(97, registers[0].LowByte);
Assert.AreEqual(98, registers[0].HighByte);
Assert.AreEqual(101, registers[1].Address);
Assert.AreEqual(99, registers[1].LowByte);
Assert.AreEqual(0, registers[1].HighByte);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullOnGetString()
{
// Arrange
string str = null;
// Act
_ = str.ToRegisters(100).ToArray();
// Assert - ArgumentNullException
}
#endregion Value to Modbus
}
}

View File

@@ -0,0 +1,476 @@
namespace AMWD.Protocols.Modbus.Tests.Common.Extensions
{
[TestClass]
public class ModbusSignedExtensionsTest
{
#region Modbus to value
[TestMethod]
public void ShouldGetSByteOnHoldingRegister()
{
// Arrange
var register = new HoldingRegister { Address = 1, HighByte = 0x02, LowByte = 0xFE };
// Act
sbyte sb = register.GetSByte();
// Assert
Assert.AreEqual(-2, sb);
}
[TestMethod]
public void ShouldGetSByteOnInputRegister()
{
// Arrange
var register = new InputRegister { Address = 1, HighByte = 0x02, LowByte = 0xFE };
// Act
sbyte sb = register.GetSByte();
// Assert
Assert.AreEqual(-2, sb);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullForGetSByte()
{
// Arrange
HoldingRegister register = null;
// Act
register.GetSByte();
// Assert - ArgumentNullException
Assert.Fail();
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentForGetSByte()
{
// Arrange
var obj = new Coil();
// Act
obj.GetSByte();
// Assert - ArgumentException
Assert.Fail();
}
[TestMethod]
public void ShouldGetInt16OnHoldingRegister()
{
// Arrange
var register = new HoldingRegister { Address = 1, HighByte = 0x02, LowByte = 0x10 };
// Act
short s = register.GetInt16();
// Assert
Assert.AreEqual(528, s);
}
[TestMethod]
public void ShouldGetInt16OnInputRegister()
{
// Arrange
var register = new InputRegister { Address = 1, HighByte = 0x02, LowByte = 0x10 };
// Act
short s = register.GetInt16();
// Assert
Assert.AreEqual(528, s);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullForGetInt16()
{
// Arrange
HoldingRegister register = null;
// Act
register.GetInt16();
// Assert - ArgumentNullException
Assert.Fail();
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentForGetInt16()
{
// Arrange
var obj = new Coil();
// Act
obj.GetInt16();
// Assert - ArgumentException
Assert.Fail();
}
[TestMethod]
public void ShouldGetInt32()
{
// Arrange
var registers = new HoldingRegister[]
{
new HoldingRegister(),
new HoldingRegister { Address = 100, HighByte = 0x01, LowByte = 0x02 },
new HoldingRegister { Address = 101, HighByte = 0x03, LowByte = 0x04 }
};
// Act
int i = registers.GetInt32(1);
// Assert
Assert.AreEqual(16909060, i);
}
[TestMethod]
public void ShouldGetInt32ReversedRegisters()
{
// Arrange
var registers = new HoldingRegister[]
{
new HoldingRegister { Address = 101, HighByte = 0x01, LowByte = 0x02 },
new HoldingRegister { Address = 100, HighByte = 0x03, LowByte = 0x04 }
};
// Act
int i = registers.GetInt32(0, reverseRegisterOrder: true);
// Assert
Assert.AreEqual(16909060, i);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullOnGetInt32()
{
// Arrange
HoldingRegister[] registers = null;
// Act
registers.GetInt32(0);
// Assert - ArgumentNullException
Assert.Fail();
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnGetInt32ForLength()
{
// Arrange
var registers = new HoldingRegister[]
{
new HoldingRegister { Address = 101, HighByte = 0x01, LowByte = 0x02 }
};
// Act
registers.GetInt32(0);
// Assert - ArgumentException
Assert.Fail();
}
[DataTestMethod]
[DataRow(1)]
[DataRow(-1)]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void ShouldThrowArgumentOutOfRangeOnGetInt32(int startIndex)
{
// Arrange
var registers = new HoldingRegister[]
{
new HoldingRegister { Address = 101, HighByte = 0x01, LowByte = 0x02 },
new HoldingRegister { Address = 100, HighByte = 0x03, LowByte = 0x04 }
};
// Act
registers.GetInt32(startIndex);
// Assert - ArgumentOutOfRangeException
Assert.Fail();
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnGetInt32ForType()
{
// Arrange
var registers = new ModbusObject[]
{
new HoldingRegister { Address = 100, HighByte = 0x01, LowByte = 0x02 },
new InputRegister { Address = 101, HighByte = 0x03, LowByte = 0x04 }
};
// Act
registers.GetInt32(0);
// Assert - ArgumentException
Assert.Fail();
}
[TestMethod]
public void ShouldGetInt64()
{
// Arrange
var registers = new HoldingRegister[]
{
new HoldingRegister(),
new HoldingRegister { Address = 100, HighByte = 0x00, LowByte = 0x00 },
new HoldingRegister { Address = 101, HighByte = 0x00, LowByte = 0x00 },
new HoldingRegister { Address = 102, HighByte = 0x01, LowByte = 0x02 },
new HoldingRegister { Address = 103, HighByte = 0x03, LowByte = 0x04 }
};
// Act
long l = registers.GetInt64(1);
// Assert
Assert.AreEqual(16909060L, l);
}
[TestMethod]
public void ShouldGetInt64ReversedRegisters()
{
// Arrange
var registers = new HoldingRegister[]
{
new HoldingRegister { Address = 103, HighByte = 0x00, LowByte = 0x00 },
new HoldingRegister { Address = 102, HighByte = 0x00, LowByte = 0x00 },
new HoldingRegister { Address = 101, HighByte = 0x01, LowByte = 0x02 },
new HoldingRegister { Address = 100, HighByte = 0x03, LowByte = 0x04 }
};
// Act
long l = registers.GetInt64(0, reverseRegisterOrder: true);
// Assert
Assert.AreEqual(16909060L, l);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullOnGetInt64()
{
// Arrange
HoldingRegister[] registers = null;
// Act
registers.GetInt64(0);
// Assert - ArgumentNullException
Assert.Fail();
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnGetInt64ForLength()
{
// Arrange
var registers = new HoldingRegister[]
{
new HoldingRegister { Address = 101, HighByte = 0x00, LowByte = 0x00 },
new HoldingRegister { Address = 102, HighByte = 0x01, LowByte = 0x02 },
new HoldingRegister { Address = 103, HighByte = 0x03, LowByte = 0x04 }
};
// Act
registers.GetInt64(0);
// Assert - ArgumentException
Assert.Fail();
}
[DataTestMethod]
[DataRow(1)]
[DataRow(-1)]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void ShouldThrowArgumentOutOfRangeOnGetInt64(int startIndex)
{
// Arrange
var registers = new HoldingRegister[]
{
new HoldingRegister { Address = 100, HighByte = 0x00, LowByte = 0x00 },
new HoldingRegister { Address = 101, HighByte = 0x00, LowByte = 0x00 },
new HoldingRegister { Address = 102, HighByte = 0x01, LowByte = 0x02 },
new HoldingRegister { Address = 103, HighByte = 0x03, LowByte = 0x04 }
};
// Act
registers.GetInt64(startIndex);
// Assert - ArgumentOutOfRangeException
Assert.Fail();
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnGetInt64ForType()
{
// Arrange
var registers = new ModbusObject[]
{
new HoldingRegister { Address = 100, HighByte = 0x00, LowByte = 0x00 },
new InputRegister { Address = 101, HighByte = 0x00, LowByte = 0x00 },
new HoldingRegister { Address = 102, HighByte = 0x01, LowByte = 0x02 },
new InputRegister { Address = 103, HighByte = 0x03, LowByte = 0x04 }
};
// Act
registers.GetInt64(0);
// Assert - ArgumentException
Assert.Fail();
}
#endregion Modbus to value
#region Value to Modbus
[TestMethod]
public void ShouldConvertSByte()
{
// Arrange
sbyte sb = -2;
// Act
var register = sb.ToRegister(24);
// Assert
Assert.IsNotNull(register);
Assert.AreEqual(24, register.Address);
Assert.AreEqual(0x00, register.HighByte);
Assert.AreEqual(0xFE, register.LowByte);
}
[TestMethod]
public void ShouldConvertInt16()
{
// Arrange
short s = 1000;
// Act
var register = s.ToRegister(123);
// Assert
Assert.IsNotNull(register);
Assert.AreEqual(123, register.Address);
Assert.AreEqual(0x03, register.HighByte);
Assert.AreEqual(0xE8, register.LowByte);
}
[TestMethod]
public void ShouldConvertInt32()
{
// Arrange
int i = 75000;
// Act
var registers = i.ToRegister(5).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(2, registers.Count);
Assert.AreEqual(5, registers[0].Address);
Assert.AreEqual(0x00, registers[0].HighByte);
Assert.AreEqual(0x01, registers[0].LowByte);
Assert.AreEqual(6, registers[1].Address);
Assert.AreEqual(0x24, registers[1].HighByte);
Assert.AreEqual(0xF8, registers[1].LowByte);
}
[TestMethod]
public void ShouldConvertInt32Reversed()
{
// Arrange
int i = 75000;
// Act
var registers = i.ToRegister(5, reverseRegisterOrder: true).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(2, registers.Count);
Assert.AreEqual(6, registers[0].Address);
Assert.AreEqual(0x00, registers[0].HighByte);
Assert.AreEqual(0x01, registers[0].LowByte);
Assert.AreEqual(5, registers[1].Address);
Assert.AreEqual(0x24, registers[1].HighByte);
Assert.AreEqual(0xF8, registers[1].LowByte);
}
[TestMethod]
public void ShouldConvertInt64()
{
// Arrange
long l = 75000;
// Act
var registers = l.ToRegister(10).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(4, registers.Count);
Assert.AreEqual(10, registers[0].Address);
Assert.AreEqual(0x00, registers[0].HighByte);
Assert.AreEqual(0x00, registers[0].LowByte);
Assert.AreEqual(11, registers[1].Address);
Assert.AreEqual(0x00, registers[1].HighByte);
Assert.AreEqual(0x00, registers[1].LowByte);
Assert.AreEqual(12, registers[2].Address);
Assert.AreEqual(0x00, registers[2].HighByte);
Assert.AreEqual(0x01, registers[2].LowByte);
Assert.AreEqual(13, registers[3].Address);
Assert.AreEqual(0x24, registers[3].HighByte);
Assert.AreEqual(0xF8, registers[3].LowByte);
}
[TestMethod]
public void ShouldConvertInt64Reversed()
{
// Arrange
long l = 75000;
// Act
var registers = l.ToRegister(10, reverseRegisterOrder: true).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(4, registers.Count);
Assert.AreEqual(13, registers[0].Address);
Assert.AreEqual(0x00, registers[0].HighByte);
Assert.AreEqual(0x00, registers[0].LowByte);
Assert.AreEqual(12, registers[1].Address);
Assert.AreEqual(0x00, registers[1].HighByte);
Assert.AreEqual(0x00, registers[1].LowByte);
Assert.AreEqual(11, registers[2].Address);
Assert.AreEqual(0x00, registers[2].HighByte);
Assert.AreEqual(0x01, registers[2].LowByte);
Assert.AreEqual(10, registers[3].Address);
Assert.AreEqual(0x24, registers[3].HighByte);
Assert.AreEqual(0xF8, registers[3].LowByte);
}
#endregion Value to Modbus
}
}

View File

@@ -0,0 +1,466 @@
namespace AMWD.Protocols.Modbus.Tests.Common.Extensions
{
[TestClass]
public class ModbusUnsignedExtensionsTest
{
#region Modbus to value
[TestMethod]
public void ShouldGetByteOnHoldingRegister()
{
// Arrange
var register = new HoldingRegister { Address = 1, HighByte = 0x02, LowByte = 0x10 };
// Act
byte b = register.GetByte();
// Assert
Assert.AreEqual(16, b);
}
[TestMethod]
public void ShouldGetByteOnInputRegister()
{
// Arrange
var register = new InputRegister { Address = 1, HighByte = 0x02, LowByte = 0x10 };
// Act
byte b = register.GetByte();
// Assert
Assert.AreEqual(16, b);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullForGetByte()
{
// Arrange
HoldingRegister register = null;
// Act
register.GetByte();
// Assert - ArgumentNullException
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentForGetByte()
{
// Arrange
var obj = new Coil();
// Act
obj.GetByte();
// Assert - ArgumentException
}
[TestMethod]
public void ShouldGetUInt16OnHoldingRegister()
{
// Arrange
var register = new HoldingRegister { Address = 1, HighByte = 0x02, LowByte = 0x10 };
// Act
ushort us = register.GetUInt16();
// Assert
Assert.AreEqual(528, us);
}
[TestMethod]
public void ShouldGetUInt16OnInputRegister()
{
// Arrange
var register = new InputRegister { Address = 1, HighByte = 0x02, LowByte = 0x10 };
// Act
ushort us = register.GetUInt16();
// Assert
Assert.AreEqual(528, us);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullForGetUInt16()
{
// Arrange
HoldingRegister register = null;
// Act
register.GetUInt16();
// Assert - ArgumentNullException
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentForGetUInt16()
{
// Arrange
var obj = new Coil();
// Act
obj.GetUInt16();
// Assert - ArgumentException
}
[TestMethod]
public void ShouldGetUInt32()
{
// Arrange
var registers = new HoldingRegister[]
{
new(),
new() { Address = 100, HighByte = 0x01, LowByte = 0x02 },
new() { Address = 101, HighByte = 0x03, LowByte = 0x04 }
};
// Act
uint ui = registers.GetUInt32(1);
// Assert
Assert.AreEqual(16909060u, ui);
}
[TestMethod]
public void ShouldGetUInt32ReversedRegisters()
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 101, HighByte = 0x01, LowByte = 0x02 },
new() { Address = 100, HighByte = 0x03, LowByte = 0x04 }
};
// Act
uint ui = registers.GetUInt32(0, reverseRegisterOrder: true);
// Assert
Assert.AreEqual(16909060u, ui);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullOnGetUInt32()
{
// Arrange
HoldingRegister[] registers = null;
// Act
registers.GetUInt32(0);
// Assert - ArgumentNullException
Assert.Fail();
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnGetUInt32ForLength()
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 101, HighByte = 0x01, LowByte = 0x02 }
};
// Act
registers.GetUInt32(0);
// Assert - ArgumentException
}
[DataTestMethod]
[DataRow(1)]
[DataRow(-1)]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void ShouldThrowArgumentOutOfRangeOnGetUInt32(int startIndex)
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 101, HighByte = 0x01, LowByte = 0x02 },
new() { Address = 100, HighByte = 0x03, LowByte = 0x04 }
};
// Act
registers.GetUInt32(startIndex);
// Assert - ArgumentOutOfRangeException
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnGetUInt32ForType()
{
// Arrange
var registers = new ModbusObject[]
{
new HoldingRegister { Address = 100, HighByte = 0x01, LowByte = 0x02 },
new InputRegister { Address = 101, HighByte = 0x03, LowByte = 0x04 }
};
// Act
registers.GetUInt32(0);
// Assert - ArgumentException
}
[TestMethod]
public void ShouldGetUInt64()
{
// Arrange
var registers = new HoldingRegister[]
{
new(),
new() { Address = 100, HighByte = 0x00, LowByte = 0x00 },
new() { Address = 101, HighByte = 0x00, LowByte = 0x00 },
new() { Address = 102, HighByte = 0x01, LowByte = 0x02 },
new() { Address = 103, HighByte = 0x03, LowByte = 0x04 }
};
// Act
ulong ul = registers.GetUInt64(1);
// Assert
Assert.AreEqual(16909060ul, ul);
}
[TestMethod]
public void ShouldGetUInt64ReversedRegisters()
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 103, HighByte = 0x00, LowByte = 0x00 },
new() { Address = 102, HighByte = 0x00, LowByte = 0x00 },
new() { Address = 101, HighByte = 0x01, LowByte = 0x02 },
new() { Address = 100, HighByte = 0x03, LowByte = 0x04 }
};
// Act
ulong ul = registers.GetUInt64(0, reverseRegisterOrder: true);
// Assert
Assert.AreEqual(16909060ul, ul);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ShouldThrowNullOnGetUInt64()
{
// Arrange
HoldingRegister[] registers = null;
// Act
registers.GetUInt64(0);
// Assert - ArgumentNullException
Assert.Fail();
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnGetUInt64ForLength()
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 101, HighByte = 0x00, LowByte = 0x00 },
new() { Address = 102, HighByte = 0x01, LowByte = 0x02 },
new() { Address = 103, HighByte = 0x03, LowByte = 0x04 }
};
// Act
registers.GetUInt64(0);
// Assert - ArgumentException
}
[DataTestMethod]
[DataRow(1)]
[DataRow(-1)]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void ShouldThrowArgumentOutOfRangeOnGetUInt64(int startIndex)
{
// Arrange
var registers = new HoldingRegister[]
{
new() { Address = 100, HighByte = 0x00, LowByte = 0x00 },
new() { Address = 101, HighByte = 0x00, LowByte = 0x00 },
new() { Address = 102, HighByte = 0x01, LowByte = 0x02 },
new() { Address = 103, HighByte = 0x03, LowByte = 0x04 }
};
// Act
registers.GetUInt64(startIndex);
// Assert - ArgumentOutOfRangeException
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentOnGetUInt64ForType()
{
// Arrange
var registers = new ModbusObject[]
{
new HoldingRegister { Address = 100, HighByte = 0x00, LowByte = 0x00 },
new InputRegister { Address = 101, HighByte = 0x00, LowByte = 0x00 },
new HoldingRegister { Address = 102, HighByte = 0x01, LowByte = 0x02 },
new InputRegister { Address = 103, HighByte = 0x03, LowByte = 0x04 }
};
// Act
registers.GetUInt64(0);
// Assert - ArgumentException
}
#endregion Modbus to value
#region Value to Modbus
[TestMethod]
public void ShouldConvertByte()
{
// Arrange
byte b = 123;
// Act
var register = b.ToRegister(321);
// Assert
Assert.IsNotNull(register);
Assert.AreEqual(321, register.Address);
Assert.AreEqual(0, register.HighByte);
Assert.AreEqual(123, register.LowByte);
}
[TestMethod]
public void ShouldConvertUInt16()
{
// Arrange
ushort us = 1000;
// Act
var register = us.ToRegister(123);
// Assert
Assert.IsNotNull(register);
Assert.AreEqual(123, register.Address);
Assert.AreEqual(0x03, register.HighByte);
Assert.AreEqual(0xE8, register.LowByte);
}
[TestMethod]
public void ShouldConvertUInt32()
{
// Arrange
uint ui = 75000;
// Act
var registers = ui.ToRegister(5).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(2, registers.Count);
Assert.AreEqual(5, registers[0].Address);
Assert.AreEqual(0x00, registers[0].HighByte);
Assert.AreEqual(0x01, registers[0].LowByte);
Assert.AreEqual(6, registers[1].Address);
Assert.AreEqual(0x24, registers[1].HighByte);
Assert.AreEqual(0xF8, registers[1].LowByte);
}
[TestMethod]
public void ShouldConvertUInt32Reversed()
{
// Arrange
uint ui = 75000;
// Act
var registers = ui.ToRegister(5, reverseRegisterOrder: true).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(2, registers.Count);
Assert.AreEqual(6, registers[0].Address);
Assert.AreEqual(0x00, registers[0].HighByte);
Assert.AreEqual(0x01, registers[0].LowByte);
Assert.AreEqual(5, registers[1].Address);
Assert.AreEqual(0x24, registers[1].HighByte);
Assert.AreEqual(0xF8, registers[1].LowByte);
}
[TestMethod]
public void ShouldConvertUInt64()
{
// Arrange
ulong ul = 75000;
// Act
var registers = ul.ToRegister(10).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(4, registers.Count);
Assert.AreEqual(10, registers[0].Address);
Assert.AreEqual(0x00, registers[0].HighByte);
Assert.AreEqual(0x00, registers[0].LowByte);
Assert.AreEqual(11, registers[1].Address);
Assert.AreEqual(0x00, registers[1].HighByte);
Assert.AreEqual(0x00, registers[1].LowByte);
Assert.AreEqual(12, registers[2].Address);
Assert.AreEqual(0x00, registers[2].HighByte);
Assert.AreEqual(0x01, registers[2].LowByte);
Assert.AreEqual(13, registers[3].Address);
Assert.AreEqual(0x24, registers[3].HighByte);
Assert.AreEqual(0xF8, registers[3].LowByte);
}
[TestMethod]
public void ShouldConvertUInt64Reversed()
{
// Arrange
ulong ul = 75000;
// Act
var registers = ul.ToRegister(10, reverseRegisterOrder: true).ToList();
// Assert
Assert.IsNotNull(registers);
Assert.AreEqual(4, registers.Count);
Assert.AreEqual(13, registers[0].Address);
Assert.AreEqual(0x00, registers[0].HighByte);
Assert.AreEqual(0x00, registers[0].LowByte);
Assert.AreEqual(12, registers[1].Address);
Assert.AreEqual(0x00, registers[1].HighByte);
Assert.AreEqual(0x00, registers[1].LowByte);
Assert.AreEqual(11, registers[2].Address);
Assert.AreEqual(0x00, registers[2].HighByte);
Assert.AreEqual(0x01, registers[2].LowByte);
Assert.AreEqual(10, registers[3].Address);
Assert.AreEqual(0x24, registers[3].HighByte);
Assert.AreEqual(0xF8, registers[3].LowByte);
}
#endregion Value to Modbus
}
}

View File

@@ -0,0 +1,108 @@
namespace AMWD.Protocols.Modbus.Tests.Common.Models
{
[TestClass]
public class CoilTest
{
[TestMethod]
public void ShouldSuccessfulCompare()
{
// Arrange
var coil1 = new Coil { Address = 123, Value = true };
var coil2 = new Coil { Address = 123, Value = true };
// Act
bool success = coil1.Equals(coil2);
// Assert
Assert.IsTrue(success);
}
[TestMethod]
public void ShouldFailOnInstanceComparing()
{
// Arrange
var coil1 = new Coil { Address = 123, Value = true };
var coil2 = new { Address = 123, HighByte = 0xFF };
// Act
bool success = coil1.Equals(coil2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnTypeComparing()
{
// Arrange
var coil1 = new Coil { Address = 123, Value = true };
var coil2 = new DiscreteInput { Address = 123, HighByte = 0xFF };
// Act
bool success = coil1.Equals(coil2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnAddressComparing()
{
// Arrange
var coil1 = new Coil { Address = 123, Value = true };
var coil2 = new Coil { Address = 321, HighByte = 0xFF };
// Act
bool success = coil1.Equals(coil2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnHighByteComparing()
{
// Arrange
var coil1 = new Coil { Address = 123, Value = true };
var coil2 = new Coil { Address = 123, HighByte = 0x00 };
// Act
bool success = coil1.Equals(coil2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnLowByteComparing()
{
// Arrange
var coil1 = new Coil { Address = 123, Value = true };
var coil2 = new Coil { Address = 123, HighByte = 0xFF, LowByte = 0xFF };
// Act
bool success = coil1.Equals(coil2);
// Assert
Assert.IsFalse(success);
}
[DataTestMethod]
[DataRow(0xFF)]
[DataRow(0x00)]
public void ShouldPrintPrettyString(int highByte)
{
// Arrange
var coil = new Coil { Address = 123, HighByte = (byte)highByte, LowByte = 0x00 };
// Act
string str = coil.ToString();
// Assert
if (highByte > 0)
Assert.AreEqual("Coil #123 | ON", str);
else
Assert.AreEqual("Coil #123 | OFF", str);
}
}
}

View File

@@ -0,0 +1,108 @@
namespace AMWD.Protocols.Modbus.Tests.Common.Models
{
[TestClass]
public class DiscreteInputTest
{
[TestMethod]
public void ShouldSuccessfulCompare()
{
// Arrange
var input1 = new DiscreteInput { Address = 123, HighByte = 0xFF, LowByte = 0x00 };
var input2 = new DiscreteInput { Address = 123, HighByte = 0xFF, LowByte = 0x00 };
// Act
bool success = input1.Equals(input2);
// Assert
Assert.IsTrue(success);
}
[TestMethod]
public void ShouldFailOnInstanceComparing()
{
// Arrange
var coil1 = new Coil { Address = 123, Value = true };
var coil2 = new { Address = 123, HighByte = 0xFF };
// Act
bool success = coil1.Equals(coil2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnTypeComparing()
{
// Arrange
var input1 = new DiscreteInput { Address = 123, HighByte = 0xFF, LowByte = 0x00 };
var input2 = new Coil { Address = 123, HighByte = 0xFF, LowByte = 0x00 };
// Act
bool success = input1.Equals(input2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnAddressComparing()
{
// Arrange
var input1 = new DiscreteInput { Address = 123, HighByte = 0xFF, LowByte = 0x00 };
var input2 = new DiscreteInput { Address = 321, HighByte = 0xFF, LowByte = 0x00 };
// Act
bool success = input1.Equals(input2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnHighByteComparing()
{
// Arrange
var input1 = new DiscreteInput { Address = 123, HighByte = 0xFF, LowByte = 0x00 };
var input2 = new DiscreteInput { Address = 123, HighByte = 0x00, LowByte = 0x00 };
// Act
bool success = input1.Equals(input2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnLowByteComparing()
{
// Arrange
var input1 = new DiscreteInput { Address = 123, HighByte = 0xFF, LowByte = 0x00 };
var input2 = new DiscreteInput { Address = 123, HighByte = 0xFF, LowByte = 0xFF };
// Act
bool success = input1.Equals(input2);
// Assert
Assert.IsFalse(success);
}
[DataTestMethod]
[DataRow(0xFF)]
[DataRow(0x00)]
public void ShouldPrintPrettyString(int highByte)
{
// Arrange
var input = new DiscreteInput { Address = 123, HighByte = (byte)highByte, LowByte = 0x00 };
// Act
string str = input.ToString();
// Assert
if (highByte > 0)
Assert.AreEqual("Discrete Input #123 | ON", str);
else
Assert.AreEqual("Discrete Input #123 | OFF", str);
}
}
}

View File

@@ -0,0 +1,117 @@
namespace AMWD.Protocols.Modbus.Tests.Common.Models
{
[TestClass]
public class HoldingRegisterTests
{
[TestMethod]
public void ShouldSuccessfulCompare()
{
// Arrange
var register1 = new HoldingRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
var register2 = new HoldingRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
// Act
bool success = register1.Equals(register2);
// Assert
Assert.IsTrue(success);
}
[TestMethod]
public void ShouldFailOnInstanceComparing()
{
// Arrange
var register1 = new HoldingRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
var register2 = new { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
// Act
bool success = register1.Equals(register2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnTypeComparing()
{
// Arrange
var register1 = new HoldingRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
var register2 = new InputRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
// Act
bool success = register1.Equals(register2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnAddressComparing()
{
// Arrange
var register1 = new HoldingRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
var register2 = new HoldingRegister { Address = 321, HighByte = 0xBE, LowByte = 0xEF };
// Act
bool success = register1.Equals(register2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnHighByteComparing()
{
// Arrange
var register1 = new HoldingRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
var register2 = new HoldingRegister { Address = 123, HighByte = 0xBD, LowByte = 0xEF };
// Act
bool success = register1.Equals(register2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnLowByteComparing()
{
// Arrange
var register1 = new HoldingRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
var register2 = new HoldingRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEE };
// Act
bool success = register1.Equals(register2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldPrintPrettyString()
{
// Arrange
var register = new HoldingRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
// Act
string str = register.ToString();
// Assert
Assert.AreEqual("Holding Register #123 | 48879 | HI: BE, LO: EF", str);
}
[TestMethod]
public void ShouldSetByValue()
{
// Arrange
var register = new HoldingRegister { Address = 123 };
// Act
register.Value = 48879;
// Assert
Assert.AreEqual(0xBE, register.HighByte);
Assert.AreEqual(0xEF, register.LowByte);
}
}
}

View File

@@ -0,0 +1,103 @@
namespace AMWD.Protocols.Modbus.Tests.Common.Models
{
[TestClass]
public class InputRegisterTests
{
[TestMethod]
public void ShouldSuccessfulCompare()
{
// Arrange
var register1 = new InputRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
var register2 = new InputRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
// Act
bool success = register1.Equals(register2);
// Assert
Assert.IsTrue(success);
}
[TestMethod]
public void ShouldFailOnInstanceComparing()
{
// Arrange
var register1 = new InputRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
var register2 = new { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
// Act
bool success = register1.Equals(register2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnTypeComparing()
{
// Arrange
var register1 = new InputRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
var register2 = new HoldingRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
// Act
bool success = register1.Equals(register2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnAddressComparing()
{
// Arrange
var register1 = new InputRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
var register2 = new InputRegister { Address = 321, HighByte = 0xBE, LowByte = 0xEF };
// Act
bool success = register1.Equals(register2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnHighByteComparing()
{
// Arrange
var register1 = new InputRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
var register2 = new InputRegister { Address = 123, HighByte = 0xBD, LowByte = 0xEF };
// Act
bool success = register1.Equals(register2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldFailOnLowByteComparing()
{
// Arrange
var register1 = new InputRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
var register2 = new InputRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEE };
// Act
bool success = register1.Equals(register2);
// Assert
Assert.IsFalse(success);
}
[TestMethod]
public void ShouldPrintPrettyString()
{
// Arrange
var register = new InputRegister { Address = 123, HighByte = 0xBE, LowByte = 0xEF };
// Act
string str = register.ToString();
// Assert
Assert.AreEqual("Input Register #123 | 48879 | HI: BE, LO: EF", str);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
global using AMWD.Protocols.Modbus.Common;
global using Microsoft.VisualStudio.TestTools.UnitTesting;
global using System;
global using System.Linq;