diff --git a/Sharp7.Rx.Tests/S7ValueConverterTests/ConverterTestBase.cs b/Sharp7.Rx.Tests/S7ValueConverterTests/ConverterTestBase.cs index a4fb1b4..f344256 100644 --- a/Sharp7.Rx.Tests/S7ValueConverterTests/ConverterTestBase.cs +++ b/Sharp7.Rx.Tests/S7ValueConverterTests/ConverterTestBase.cs @@ -59,8 +59,6 @@ internal abstract class ConverterTestBase yield return new ConverterTestCase((short) -3532, "DB99.INT0", [0xF2, 0x34]); yield return new ConverterTestCase(305419879, "DB99.DINT0", [0x12, 0x34, 0x56, 0x67]); yield return new ConverterTestCase(-231451033, "DB99.DINT0", [0xF2, 0x34, 0x56, 0x67]); - yield return new ConverterTestCase(1311768394163015151L, "DB99.dul0", [0x12, 0x34, 0x56, 0x67, 0x89, 0xAB, 0xCD, 0xEF]); - yield return new ConverterTestCase(-994074615050678801L, "DB99.dul0", [0xF2, 0x34, 0x56, 0x67, 0x89, 0xAB, 0xCD, 0xEF]); yield return new ConverterTestCase(1311768394163015151uL, "DB99.dul0", [0x12, 0x34, 0x56, 0x67, 0x89, 0xAB, 0xCD, 0xEF]); yield return new ConverterTestCase(17452669458658872815uL, "DB99.dul0", [0xF2, 0x34, 0x56, 0x67, 0x89, 0xAB, 0xCD, 0xEF]); yield return new ConverterTestCase(new byte[] {0x12, 0x34, 0x56, 0x67}, "DB99.DBB0.4", [0x12, 0x34, 0x56, 0x67]); diff --git a/Sharp7.Rx.Tests/S7VariableAddressTests/MatchesType.cs b/Sharp7.Rx.Tests/S7VariableAddressTests/MatchesType.cs index d3d428a..458c17d 100644 --- a/Sharp7.Rx.Tests/S7VariableAddressTests/MatchesType.cs +++ b/Sharp7.Rx.Tests/S7VariableAddressTests/MatchesType.cs @@ -1,7 +1,7 @@ -using System.Reflection; -using NUnit.Framework; +using NUnit.Framework; using Sharp7.Rx.Extensions; using Sharp7.Rx.Interfaces; +using Sharp7.Rx.Tests.S7ValueConverterTests; using Shouldly; namespace Sharp7.Rx.Tests.S7VariableAddressTests; @@ -11,19 +11,61 @@ public class MatchesType { static readonly IS7VariableNameParser parser = new S7VariableNameParser(); - - public void Supported(Type type, string address) + private static readonly IReadOnlyList typeList = new[] { - Check(type, address, true); + typeof(byte), + typeof(byte[]), + + typeof(bool), + typeof(short), + typeof(ushort), + typeof(int), + typeof(uint), + typeof(long), + typeof(ulong), + + typeof(float), + typeof(double), + + typeof(string), + + typeof(int[]), + typeof(float[]), + typeof(DateTime[]), + typeof(object), + }; + + [TestCaseSource(nameof(GetValid))] + public void Supported(TestCase tc) => Check(tc.Type, tc.Address, true); + + [TestCaseSource(nameof(GetInvalid))] + public void Unsupported(TestCase tc) => Check(tc.Type, tc.Address, false); + + + public static IEnumerable GetValid() + { + return + ConverterTestBase.GetValidTestCases() + .Select(tc => new TestCase(tc.Value.GetType(), tc.Address)); } - public IEnumerable GetValid() + public static IEnumerable GetInvalid() { - yield return new TestCase(typeof(bool), "DB0.DBx0.0"); - yield return new TestCase(typeof(short), "DB0.INT0"); - yield return new TestCase(typeof(int), "DB0.DINT0"); - yield return new TestCase(typeof(long), "DB0.DUL0"); - yield return new TestCase(typeof(ulong), "DB0.DUL0"); + return + ConverterTestBase.GetValidTestCases() + .DistinctBy(tc => tc.Value.GetType()) + .SelectMany(tc => + typeList.Where(type => type != tc.Value.GetType()) + .Select(type => new TestCase(type, tc.Address)) + ) + + // Explicitly remove some valid combinations + .Where(tc => !( + (tc.Type == typeof(string) && tc.Address == "DB99.Byte5") || + (tc.Type == typeof(string) && tc.Address == "DB99.Byte5.4") || + (tc.Type == typeof(byte[]) && tc.Address == "DB99.Byte5") + )) + ; } @@ -36,5 +78,8 @@ public class MatchesType variableAddress.MatchesType(type).ShouldBe(expected); } - public record TestCase(Type Type, string Address); + public record TestCase(Type Type, string Address) + { + public override string ToString() => $"{Type.Name} {Address}"; + } } diff --git a/Sharp7.Rx/Extensions/S7VariableExtensions.cs b/Sharp7.Rx/Extensions/S7VariableExtensions.cs index a2b0a39..40c8eed 100644 --- a/Sharp7.Rx/Extensions/S7VariableExtensions.cs +++ b/Sharp7.Rx/Extensions/S7VariableExtensions.cs @@ -1,9 +1,25 @@ -namespace Sharp7.Rx.Extensions; +using Sharp7.Rx.Enums; + +namespace Sharp7.Rx.Extensions; internal static class S7VariableAddressExtensions { - public static bool MatchesType(this S7VariableAddress address, Type type) + private static readonly Dictionary> supportedTypeMap = new() { - return false; - } + {typeof(bool), a => a.Type == DbType.Bit}, + {typeof(string), a => a.Type is DbType.String or DbType.WString or DbType.Byte }, + {typeof(byte), a => a.Type==DbType.Byte && a.Length == 1}, + {typeof(short), a => a.Type==DbType.Int}, + {typeof(ushort), a => a.Type==DbType.UInt}, + {typeof(int), a => a.Type==DbType.DInt}, + {typeof(uint), a => a.Type==DbType.UDInt}, + {typeof(long), a => a.Type==DbType.LInt}, + {typeof(ulong), a => a.Type==DbType.ULInt}, + {typeof(float), a => a.Type==DbType.Single}, + {typeof(double), a => a.Type==DbType.Double}, + {typeof(byte[]), a => a.Type==DbType.Byte}, + }; + + public static bool MatchesType(this S7VariableAddress address, Type type) => + supportedTypeMap.TryGetValue(type, out var map) && map(address); } diff --git a/Sharp7.Rx/S7VariableNameParser.cs b/Sharp7.Rx/S7VariableNameParser.cs index a7029a1..38cecc3 100644 --- a/Sharp7.Rx/S7VariableNameParser.cs +++ b/Sharp7.Rx/S7VariableNameParser.cs @@ -148,8 +148,6 @@ internal class S7VariableNameParser : IS7VariableNameParser if (result > 7) throw new InvalidS7AddressException($"Bit must be between 0 and 7 but is {result} in \"{input}\"", input); - - return result; } }