From 95b3ec4fa5ca6dbee1d3d7d18cea8d203bc3131e Mon Sep 17 00:00:00 2001
From: Timothy Nunnink <46979634+tnunnink@users.noreply.github.com>
Date: Sat, 3 Feb 2024 14:20:36 -0600
Subject: [PATCH] Added IsEquivalent method to both LogixElement.cs and
LogixType.cs to allow check of the underlying XML structure between two
objects. Also some other clean up, documenting, and testing
---
src/.idea/.idea.L5Sharp/.idea/workspace.xml | 18 ++-
.../Components/AddOnInstruction.cs | 2 +
src/L5Sharp.Core/Components/Controller.cs | 2 +
src/L5Sharp.Core/Components/DataType.cs | 2 +
src/L5Sharp.Core/Components/Module.cs | 1 +
src/L5Sharp.Core/Components/Program.cs | 2 +
src/L5Sharp.Core/Components/Routine.cs | 2 +
src/L5Sharp.Core/Components/Tag.cs | 8 +-
src/L5Sharp.Core/L5Sharp.Core.csproj | 18 +--
src/L5Sharp.Core/LogixElement.cs | 16 +++
src/L5Sharp.Core/LogixParser.cs | 4 -
src/L5Sharp.Core/LogixType.cs | 24 +++-
tests/L5Sharp.Tests/Elements/RungTests.cs | 22 ++++
tests/L5Sharp.Tests/LogixElementTests.cs | 111 ++++++++++++++++--
.../L5Sharp.Tests/Types/Atomics/BoolTests.cs | 22 ++++
.../L5Sharp.Tests/Types/Atomics/DintTests.cs | 22 ++++
tests/L5Sharp.Tests/Types/Atomics/IntTests.cs | 22 ++++
.../L5Sharp.Tests/Types/Atomics/LintTests.cs | 22 ++++
.../L5Sharp.Tests/Types/Atomics/LrealTests.cs | 22 ++++
.../L5Sharp.Tests/Types/Atomics/RealTests.cs | 22 ++++
.../L5Sharp.Tests/Types/Atomics/SintTests.cs | 22 ++++
.../L5Sharp.Tests/Types/Atomics/UDintTests.cs | 22 ++++
.../L5Sharp.Tests/Types/Atomics/UIntTests.cs | 22 ++++
.../L5Sharp.Tests/Types/Atomics/ULintTests.cs | 22 ++++
.../L5Sharp.Tests/Types/Atomics/USintTests.cs | 22 ++++
tests/L5Sharp.Tests/Types/ComplexTypeTests.cs | 84 ++++++++++++-
26 files changed, 522 insertions(+), 36 deletions(-)
diff --git a/src/.idea/.idea.L5Sharp/.idea/workspace.xml b/src/.idea/.idea.L5Sharp/.idea/workspace.xml
index 32618e6f..c2361e9b 100644
--- a/src/.idea/.idea.L5Sharp/.idea/workspace.xml
+++ b/src/.idea/.idea.L5Sharp/.idea/workspace.xml
@@ -10,9 +10,15 @@
+
+
+
+
+
+
+
+
-
-
@@ -374,7 +380,7 @@
-
+ 1677621948966
@@ -719,7 +725,7 @@
1687451515386
-
+
@@ -755,7 +761,6 @@
-
@@ -780,7 +785,8 @@
-
+
+
diff --git a/src/L5Sharp.Core/Components/AddOnInstruction.cs b/src/L5Sharp.Core/Components/AddOnInstruction.cs
index 7768b1bc..0f41d70c 100644
--- a/src/L5Sharp.Core/Components/AddOnInstruction.cs
+++ b/src/L5Sharp.Core/Components/AddOnInstruction.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;
+using JetBrains.Annotations;
namespace L5Sharp.Core;
@@ -14,6 +15,7 @@ namespace L5Sharp.Core;
/// See
/// `Logix 5000 Controllers Import/Export` for more information.
///
+[PublicAPI]
[L5XType(L5XName.AddOnInstructionDefinition)]
public class AddOnInstruction : LogixComponent
{
diff --git a/src/L5Sharp.Core/Components/Controller.cs b/src/L5Sharp.Core/Components/Controller.cs
index 86d51b24..93ae8fb5 100644
--- a/src/L5Sharp.Core/Components/Controller.cs
+++ b/src/L5Sharp.Core/Components/Controller.cs
@@ -1,5 +1,6 @@
using System;
using System.Xml.Linq;
+using JetBrains.Annotations;
namespace L5Sharp.Core;
@@ -26,6 +27,7 @@ namespace L5Sharp.Core;
/// See
/// `Logix 5000 Controllers Import/Export` for more information.
///
+[PublicAPI]
public class Controller : LogixComponent
{
private const string DateTimeFormat = "ddd MMM d HH:mm:ss yyyy";
diff --git a/src/L5Sharp.Core/Components/DataType.cs b/src/L5Sharp.Core/Components/DataType.cs
index f4ae11b7..ce404f2c 100644
--- a/src/L5Sharp.Core/Components/DataType.cs
+++ b/src/L5Sharp.Core/Components/DataType.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
+using JetBrains.Annotations;
namespace L5Sharp.Core;
@@ -23,6 +24,7 @@ namespace L5Sharp.Core;
/// See
/// `Logix 5000 Controllers Import/Export` for more information.
///
+[PublicAPI]
public class DataType : LogixComponent
{
///
diff --git a/src/L5Sharp.Core/Components/Module.cs b/src/L5Sharp.Core/Components/Module.cs
index c6b74035..125a1dd5 100644
--- a/src/L5Sharp.Core/Components/Module.cs
+++ b/src/L5Sharp.Core/Components/Module.cs
@@ -14,6 +14,7 @@ namespace L5Sharp.Core;
/// See
/// `Logix 5000 Controllers Import/Export` for more information.
///
+[PublicAPI]
public class Module : LogixComponent
{
///
diff --git a/src/L5Sharp.Core/Components/Program.cs b/src/L5Sharp.Core/Components/Program.cs
index 3688428d..282eb003 100644
--- a/src/L5Sharp.Core/Components/Program.cs
+++ b/src/L5Sharp.Core/Components/Program.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
+using JetBrains.Annotations;
namespace L5Sharp.Core;
@@ -12,6 +13,7 @@ namespace L5Sharp.Core;
/// See
/// `Logix 5000 Controllers Import/Export` for more information.
///
+[PublicAPI]
public class Program : LogixComponent
{
///
diff --git a/src/L5Sharp.Core/Components/Routine.cs b/src/L5Sharp.Core/Components/Routine.cs
index eed62049..ce762e42 100644
--- a/src/L5Sharp.Core/Components/Routine.cs
+++ b/src/L5Sharp.Core/Components/Routine.cs
@@ -1,5 +1,6 @@
using System;
using System.Xml.Linq;
+using JetBrains.Annotations;
namespace L5Sharp.Core;
@@ -11,6 +12,7 @@ namespace L5Sharp.Core;
/// See
/// `Logix 5000 Controllers Import/Export` for more information.
///
+[PublicAPI]
public class Routine : LogixComponent
{
///
diff --git a/src/L5Sharp.Core/Components/Tag.cs b/src/L5Sharp.Core/Components/Tag.cs
index 2ec12ed8..a3fc71e6 100644
--- a/src/L5Sharp.Core/Components/Tag.cs
+++ b/src/L5Sharp.Core/Components/Tag.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
+using JetBrains.Annotations;
namespace L5Sharp.Core;
@@ -12,6 +13,7 @@ namespace L5Sharp.Core;
/// See
/// `Logix 5000 Controllers Import/Export` for more information.
///
+[PublicAPI]
[L5XType(L5XName.Tag)]
[L5XType(L5XName.LocalTag)]
[L5XType(L5XName.ConfigTag)]
@@ -384,7 +386,7 @@ public void Add(string name, LogixType value)
///
public IEnumerable Members()
{
- var members = Parent is null ? new List {this} : new List();
+ var members = Parent is null ? [this] : new List();
foreach (var member in Value.Members)
{
@@ -409,7 +411,7 @@ public IEnumerable Members(Predicate predicate)
{
if (predicate is null) throw new ArgumentNullException(nameof(predicate));
- var members = Parent is null && predicate.Invoke(TagName) ? new List {this} : new List();
+ var members = Parent is null && predicate.Invoke(TagName) ? [this] : new List();
foreach (var member in Value.Members)
{
@@ -437,7 +439,7 @@ public IEnumerable Members(Predicate predicate)
{
if (predicate is null) throw new ArgumentNullException(nameof(predicate));
- var members = Parent is null && predicate.Invoke(this) ? new List {this} : new List();
+ var members = Parent is null && predicate.Invoke(this) ? [this] : new List();
foreach (var member in Value.Members)
{
diff --git a/src/L5Sharp.Core/L5Sharp.Core.csproj b/src/L5Sharp.Core/L5Sharp.Core.csproj
index bdedbe4f..7372643d 100644
--- a/src/L5Sharp.Core/L5Sharp.Core.csproj
+++ b/src/L5Sharp.Core/L5Sharp.Core.csproj
@@ -7,9 +7,9 @@
trueL5SharpTimothy Nunnink
- 0.19.1
- 0.19.1
- 0.19.1.0
+ 0.19.2
+ 0.19.3
+ 0.19.3.0A library for intuitively interacting with Rockwell's L5X import/export files.https://github.com/tnunnink/L5Sharpcsharp allen-bradely l5x logix plc-programming rockwell-automation logix5000
@@ -17,7 +17,7 @@
MITgit
- Upgraded to .NET7. Reworked LogixParser.cs. Added new ILogixParsable.cs. Fixed tests and documentation.
+ Added some equivalency methods to the LogixElement.cs and LogixType.cs to allow checks against entire XML structure..Copyright (c) Timothy Nunnink 2022README.mdL5Sharp
@@ -27,16 +27,16 @@
-
-
-
+
+
+
-
+
-
+
diff --git a/src/L5Sharp.Core/LogixElement.cs b/src/L5Sharp.Core/LogixElement.cs
index 9e831d6f..e0fb9e6d 100644
--- a/src/L5Sharp.Core/LogixElement.cs
+++ b/src/L5Sharp.Core/LogixElement.cs
@@ -332,6 +332,22 @@ public void Replace(LogixElement element)
///
public virtual XElement Serialize() => Element;
+ ///
+ /// Determines if the provided is equivalent to this element in terms of both type and
+ /// state, including all child elements and values.
+ ///
+ /// The to compare.
+ /// ture if the elements are equivalent; Otherwise, false.
+ ///
+ /// This internally compares the underlying XML nodes of the two elements to determine if all their
+ /// elements, attributes, and values are equal. This includes all nested or descendant elements (i.e. it
+ /// compares the entire XML structure).
+ ///
+ public bool IsEquivalent(LogixElement other)
+ {
+ return XNode.DeepEquals(Element, other.Element);
+ }
+
///
/// Gets the value of the specified attribute name from the element parsed as the specified generic type parameter if it exists.
/// If the attribute does not exist, returns default value of the generic type parameter.
diff --git a/src/L5Sharp.Core/LogixParser.cs b/src/L5Sharp.Core/LogixParser.cs
index 070b1478..0d04ffe4 100644
--- a/src/L5Sharp.Core/LogixParser.cs
+++ b/src/L5Sharp.Core/LogixParser.cs
@@ -141,10 +141,6 @@ private static IEnumerable> GetParsers()
foreach (var type in types)
{
- if (!type.IsPublic)
- {
- Console.WriteLine(type.Name);
- }
var parse = BuildParseFunction(type);
var tryParse = BuildTryParseFunction(type);
var parsers = new Parsers(parse, tryParse);
diff --git a/src/L5Sharp.Core/LogixType.cs b/src/L5Sharp.Core/LogixType.cs
index 55004c97..e00ff2fc 100644
--- a/src/L5Sharp.Core/LogixType.cs
+++ b/src/L5Sharp.Core/LogixType.cs
@@ -92,6 +92,22 @@ public override bool Equals(object? obj)
///
public override int GetHashCode() => Name.GetHashCode();
+
+ ///
+ /// Determines if the provided is equivalent to this type in terms of the underlying XML
+ /// data that comprise the complex object.
+ ///
+ /// The to compare.
+ /// ture if the types are equivalent; Otherwise, false.
+ ///
+ /// This internally compares the underlying XML nodes of the two types to determine if all their
+ /// elements, attributes, and values are equal. This includes all nested or descendant elements (i.e. it
+ /// compares the entire XML structure).
+ ///
+ public bool IsEquivalent(LogixType other)
+ {
+ return XNode.DeepEquals(Serialize(), other.Serialize());
+ }
///
/// Gets a with the specified name if it exists for the ;
@@ -284,7 +300,7 @@ public override bool Equals(object? obj)
///
/// The value to convert.
/// A representing the converted value.
- public static implicit operator LogixType(LogixType[,] value) =>ToArrayType(value);
+ public static implicit operator LogixType(LogixType[,] value) => ToArrayType(value);
///
/// Converts the provided to a .
@@ -300,7 +316,7 @@ public override bool Equals(object? obj)
/// A representing the converted value.
public static implicit operator LogixType(Dictionary value) =>
new ComplexType(nameof(ComplexType), value.Select(m => new LogixMember(m.Key, m.Value)));
-
+
///
/// Converts the current array object to a of the concrete logix type by
/// inspecting the first element's type in the array.
@@ -321,7 +337,7 @@ private static ArrayType ToArrayType(Array array)
var type = array.Cast().First().GetType();
var arrayType = typeof(ArrayType<>).MakeGenericType(type);
var parameterType = typeof(Array);
- var constructor = arrayType.GetConstructor(new[] { parameterType })!;
+ var constructor = arrayType.GetConstructor([parameterType])!;
var parameter = Expression.Parameter(parameterType, "array");
var creator = Expression.New(constructor, parameter);
var lambda = Expression.Lambda>(creator, parameter);
@@ -360,4 +376,4 @@ public static ArrayType ToArrayType(this IEnumerable
{
- new() { SomeValue = "Child_1"},
- new() { SomeValue = "Child_2"},
- new() { SomeValue = "Child_3"}
+ new() { SomeValue = "Child_1" },
+ new() { SomeValue = "Child_2" },
+ new() { SomeValue = "Child_3" }
};
return Verify(element.Serialize().ToString());
@@ -550,9 +550,9 @@ public Task SetContainer_HasValueDifferentValue_ShouldBeVerified()
element.ChildElements = new LogixContainer
{
- new() { SomeValue = "Child_3"},
- new() { SomeValue = "Child_2"},
- new() { SomeValue = "Child_1"}
+ new() { SomeValue = "Child_3" },
+ new() { SomeValue = "Child_2" },
+ new() { SomeValue = "Child_1" }
};
return Verify(element.Serialize().ToString());
@@ -573,7 +573,7 @@ public Task SetContainer_HasValueToNull_ShouldBeVerified()
return Verify(element.Serialize().ToString());
}
-
+
[Test]
public void GetDateTime_HasValue_ShouldBeExpectedValue()
{
@@ -628,7 +628,7 @@ public Task SetDateTime_HasValueToNull_ShouldBeVerified()
return Verify(element.Serialize().ToString());
}
-
+
[Test]
public Task SetDescription_NoValueToValue_ShouldBeVerified()
{
@@ -955,6 +955,99 @@ public void Convert_AsTypeDefaultType_ShouldHaveExpectedTypeAndBeSameInstance()
converted.Should().BeOfType();
converted.Should().BeSameAs(element);
}
+
+ [Test]
+ public void IsEquivalent_AreEquivalent_ShouldBeTrue()
+ {
+ var first = new TestElement();
+ var second = new TestElement();
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreEquivalentWithSetProperties_ShouldBeTrue()
+ {
+ var first = new TestElement
+ {
+ OptionalValue = "Testing",
+ Property = "SomeValue",
+ Description = "This is a test",
+ Date = new DateTime(2024, 1, 1)
+ };
+
+ var second = new TestElement
+ {
+ OptionalValue = "Testing",
+ Property = "SomeValue",
+ Description = "This is a test",
+ Date = new DateTime(2024, 1, 1)
+ };
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEquivalentWithOneDifferent_ShouldBeFalse()
+ {
+ var first = new TestElement
+ {
+ OptionalValue = "Testing",
+ Property = "SomeValue",
+ Description = "This is a test",
+ Date = new DateTime(2024, 1, 1)
+ };
+
+ var second = new TestElement
+ {
+ OptionalValue = "Testing",
+ Property = "SomeValue",
+ Description = "This is a test",
+ Date = new DateTime(2024, 1, 1)
+ };
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEquivalentOneUnsetProperty_ShouldBeFalse()
+ {
+ var first = new TestElement
+ {
+ Property = "SomeValue",
+ Description = "This is a test",
+ Date = new DateTime(2024, 1, 1)
+ };
+
+ var second = new TestElement
+ {
+ OptionalValue = "Testing",
+ Property = "SomeValue",
+ Description = "This is a test",
+ Date = new DateTime(2024, 1, 1)
+ };
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
+
+ [Test]
+ public void IsEquivalent_DifferentType_ShouldBeFalse()
+ {
+ var first = new TestElement();
+ var second = new ChildElement();
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
}
[L5XType("Test", "Container")]
diff --git a/tests/L5Sharp.Tests/Types/Atomics/BoolTests.cs b/tests/L5Sharp.Tests/Types/Atomics/BoolTests.cs
index bd119a81..3266aa57 100644
--- a/tests/L5Sharp.Tests/Types/Atomics/BoolTests.cs
+++ b/tests/L5Sharp.Tests/Types/Atomics/BoolTests.cs
@@ -796,6 +796,28 @@ public void Equals_OverLargeCollection_ShouldWorkFairlyFast(int capacity)
result.Count.Should().Be(capacity);
}
+ [Test]
+ public void IsEquivalent_AreEqual_ShouldBeTrue()
+ {
+ var first = new BOOL(1);
+ var second = new BOOL(1);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqual_ShouldBeFalse()
+ {
+ var first = new BOOL(1);
+ var second = new BOOL(0);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
+
[Test]
public void GetHashCode_RandomValue_ShouldBeHashOfValue()
{
diff --git a/tests/L5Sharp.Tests/Types/Atomics/DintTests.cs b/tests/L5Sharp.Tests/Types/Atomics/DintTests.cs
index d6d92662..998b9b7e 100644
--- a/tests/L5Sharp.Tests/Types/Atomics/DintTests.cs
+++ b/tests/L5Sharp.Tests/Types/Atomics/DintTests.cs
@@ -882,6 +882,28 @@ public void Equals_OverLargeCollection_ShouldWorkFairlyFast(int capacity)
result.Count.Should().Be(capacity);
}
+
+ [Test]
+ public void IsEquivalent_AreEqual_ShouldBeTrue()
+ {
+ var first = new DINT(1);
+ var second = new DINT(1);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqual_ShouldBeFalse()
+ {
+ var first = new DINT(1);
+ var second = new DINT(0);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
[Test]
public void GetHashCode_RandomValue_ShouldBeHashOfValue()
diff --git a/tests/L5Sharp.Tests/Types/Atomics/IntTests.cs b/tests/L5Sharp.Tests/Types/Atomics/IntTests.cs
index a3999ec7..a057d1e0 100644
--- a/tests/L5Sharp.Tests/Types/Atomics/IntTests.cs
+++ b/tests/L5Sharp.Tests/Types/Atomics/IntTests.cs
@@ -869,6 +869,28 @@ public void Equals_OverLargeCollection_ShouldWorkFairlyFast(int capacity)
result.Count.Should().Be(capacity);
}
+
+ [Test]
+ public void IsEquivalent_AreEqual_ShouldBeTrue()
+ {
+ var first = new INT(1);
+ var second = new INT(1);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqual_ShouldBeFalse()
+ {
+ var first = new INT(1);
+ var second = new INT(0);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
[Test]
public void GetHashCode_RandomValue_ShouldBeHashOfValue()
diff --git a/tests/L5Sharp.Tests/Types/Atomics/LintTests.cs b/tests/L5Sharp.Tests/Types/Atomics/LintTests.cs
index 1b058078..4e0379a1 100644
--- a/tests/L5Sharp.Tests/Types/Atomics/LintTests.cs
+++ b/tests/L5Sharp.Tests/Types/Atomics/LintTests.cs
@@ -875,6 +875,28 @@ public void Equals_OverLargeCollection_ShouldWorkFairlyFast(int capacity)
result.Count.Should().Be(capacity);
}
+
+ [Test]
+ public void IsEquivalent_AreEqual_ShouldBeTrue()
+ {
+ var first = new LINT(1);
+ var second = new LINT(1);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqual_ShouldBeFalse()
+ {
+ var first = new LINT(1);
+ var second = new LINT(0);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
[Test]
public void GetHashCode_RandomValue_ShouldBeHashOfValue()
diff --git a/tests/L5Sharp.Tests/Types/Atomics/LrealTests.cs b/tests/L5Sharp.Tests/Types/Atomics/LrealTests.cs
index d3bad282..4725c8cb 100644
--- a/tests/L5Sharp.Tests/Types/Atomics/LrealTests.cs
+++ b/tests/L5Sharp.Tests/Types/Atomics/LrealTests.cs
@@ -806,6 +806,28 @@ public void Equals_OverLargeCollection_ShouldWorkFairlyFast(int capacity)
result.Count.Should().Be(capacity);
}
+
+ [Test]
+ public void IsEquivalent_AreEqual_ShouldBeTrue()
+ {
+ var first = new LREAL(1.23);
+ var second = new LREAL(1.23);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqual_ShouldBeFalse()
+ {
+ var first = new LREAL(1.23);
+ var second = new LREAL(1.32);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
[Test]
public void GetHashCode_RandomValue_ShouldBeHashOfValue()
diff --git a/tests/L5Sharp.Tests/Types/Atomics/RealTests.cs b/tests/L5Sharp.Tests/Types/Atomics/RealTests.cs
index c1f911a9..8315f31c 100644
--- a/tests/L5Sharp.Tests/Types/Atomics/RealTests.cs
+++ b/tests/L5Sharp.Tests/Types/Atomics/RealTests.cs
@@ -806,6 +806,28 @@ public void Equals_OverLargeCollection_ShouldWorkFairlyFast(int capacity)
result.Count.Should().Be(capacity);
}
+
+ [Test]
+ public void IsEquivalent_AreEqual_ShouldBeTrue()
+ {
+ var first = new REAL(1.23f);
+ var second = new REAL(1.23f);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqual_ShouldBeFalse()
+ {
+ var first = new REAL(1.23f);
+ var second = new REAL(1.32f);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
[Test]
public void GetHashCode_RandomValue_ShouldBeHashOfValue()
diff --git a/tests/L5Sharp.Tests/Types/Atomics/SintTests.cs b/tests/L5Sharp.Tests/Types/Atomics/SintTests.cs
index 51ab7276..d477c571 100644
--- a/tests/L5Sharp.Tests/Types/Atomics/SintTests.cs
+++ b/tests/L5Sharp.Tests/Types/Atomics/SintTests.cs
@@ -568,6 +568,28 @@ public void Equals_OverLargeCollection_ShouldWorkFairlyFast(int capacity)
result.Count.Should().Be(capacity);
}
+
+ [Test]
+ public void IsEquivalent_AreEqual_ShouldBeTrue()
+ {
+ var first = new SINT(1);
+ var second = new SINT(1);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqual_ShouldBeFalse()
+ {
+ var first = new SINT(1);
+ var second = new SINT(0);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
[Test]
public void GetHashCode_RandomValue_ShouldBeHashOfValue()
diff --git a/tests/L5Sharp.Tests/Types/Atomics/UDintTests.cs b/tests/L5Sharp.Tests/Types/Atomics/UDintTests.cs
index 7bbf1bdb..2219db51 100644
--- a/tests/L5Sharp.Tests/Types/Atomics/UDintTests.cs
+++ b/tests/L5Sharp.Tests/Types/Atomics/UDintTests.cs
@@ -867,6 +867,28 @@ public void Equals_OverLargeCollection_ShouldWorkFairlyFast(int capacity)
result.Count.Should().Be(capacity);
}
+
+ [Test]
+ public void IsEquivalent_AreEqual_ShouldBeTrue()
+ {
+ var first = new UDINT(1);
+ var second = new UDINT(1);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqual_ShouldBeFalse()
+ {
+ var first = new UDINT(1);
+ var second = new UDINT(0);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
[Test]
public void GetHashCode_RandomValue_ShouldBeHashOfValue()
diff --git a/tests/L5Sharp.Tests/Types/Atomics/UIntTests.cs b/tests/L5Sharp.Tests/Types/Atomics/UIntTests.cs
index 1bb050f5..8a7015ad 100644
--- a/tests/L5Sharp.Tests/Types/Atomics/UIntTests.cs
+++ b/tests/L5Sharp.Tests/Types/Atomics/UIntTests.cs
@@ -267,6 +267,28 @@ public void Equals_InvalidType_ShouldBeFalse()
result.Should().BeFalse();
}
+
+ [Test]
+ public void IsEquivalent_AreEqual_ShouldBeTrue()
+ {
+ var first = new UINT(1);
+ var second = new UINT(1);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqual_ShouldBeFalse()
+ {
+ var first = new UINT(1);
+ var second = new UINT(0);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
[Test]
public void OperatorEquals_AreEqual_ShouldBeTrue()
diff --git a/tests/L5Sharp.Tests/Types/Atomics/ULintTests.cs b/tests/L5Sharp.Tests/Types/Atomics/ULintTests.cs
index 14b23b8e..81e61a4a 100644
--- a/tests/L5Sharp.Tests/Types/Atomics/ULintTests.cs
+++ b/tests/L5Sharp.Tests/Types/Atomics/ULintTests.cs
@@ -867,6 +867,28 @@ public void Equals_OverLargeCollection_ShouldWorkFairlyFast(int capacity)
result.Count.Should().Be(capacity);
}
+
+ [Test]
+ public void IsEquivalent_AreEqual_ShouldBeTrue()
+ {
+ var first = new ULINT(1);
+ var second = new ULINT(1);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqual_ShouldBeFalse()
+ {
+ var first = new ULINT(1);
+ var second = new ULINT(0);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
[Test]
public void GetHashCode_RandomValue_ShouldBeHashOfValue()
diff --git a/tests/L5Sharp.Tests/Types/Atomics/USintTests.cs b/tests/L5Sharp.Tests/Types/Atomics/USintTests.cs
index 73592e87..9a941007 100644
--- a/tests/L5Sharp.Tests/Types/Atomics/USintTests.cs
+++ b/tests/L5Sharp.Tests/Types/Atomics/USintTests.cs
@@ -868,6 +868,28 @@ public void Equals_OverLargeCollection_ShouldWorkFairlyFast(int capacity)
result.Count.Should().Be(capacity);
}
+
+ [Test]
+ public void IsEquivalent_AreEqual_ShouldBeTrue()
+ {
+ var first = new USINT(1);
+ var second = new USINT(1);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqual_ShouldBeFalse()
+ {
+ var first = new USINT(1);
+ var second = new USINT(0);
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
[Test]
public void GetHashCode_RandomValue_ShouldBeHashOfValue()
diff --git a/tests/L5Sharp.Tests/Types/ComplexTypeTests.cs b/tests/L5Sharp.Tests/Types/ComplexTypeTests.cs
index 3e6ea0c3..9c7b61a1 100644
--- a/tests/L5Sharp.Tests/Types/ComplexTypeTests.cs
+++ b/tests/L5Sharp.Tests/Types/ComplexTypeTests.cs
@@ -1,4 +1,5 @@
-using System.Xml.Linq;
+using System.Runtime.InteropServices;
+using System.Xml.Linq;
using FluentAssertions;
namespace L5Sharp.Tests.Types;
@@ -573,4 +574,85 @@ public Task Serialize_Test_ShouldBeVerified()
return Verify(xml);
}
+
+ [Test]
+ public void IsEquivalent_AreEqual_ShouldBeTrue()
+ {
+ var first = new ComplexType("Test", new List
+ {
+ new("Member1", true),
+ new("Member2", (byte)255),
+ new("Member3", 1000),
+ new("Member4", 4.5f),
+ new("Member5", new TIMER())
+ });
+
+ var second = new ComplexType("Test", new List
+ {
+ new("Member1", true),
+ new("Member2", (byte)255),
+ new("Member3", 1000),
+ new("Member4", 4.5f),
+ new("Member5", new TIMER())
+ });
+
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeTrue();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqualByValue_ShouldBeFalse()
+ {
+ var first = new ComplexType("Test", new List
+ {
+ new("Member1", true),
+ new("Member2", (byte)255),
+ new("Member3", 1000),
+ new("Member4", 4.5f),
+ new("Member5", new TIMER())
+ });
+
+ var second = new ComplexType("Test", new List
+ {
+ new("Member1", true),
+ new("Member2", (byte)255),
+ new("Member3", 1000),
+ new("Member4", 4.45f),
+ new("Member5", new TIMER())
+ });
+
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
+
+ [Test]
+ public void IsEquivalent_AreNotEqualByName_ShouldBeFalse()
+ {
+ var first = new ComplexType("Test", new List
+ {
+ new("Member1", true),
+ new("Member2", (byte)255),
+ new("Member3", 1000),
+ new("Member4", 4.5f),
+ new("Member5", new TIMER())
+ });
+
+ var second = new ComplexType("Test", new List
+ {
+ new("Member1", true),
+ new("Member2", (byte)255),
+ new("Member3", 1000),
+ new("Member4", 4.5f),
+ new("Member6", new TIMER())
+ });
+
+
+ var result = first.IsEquivalent(second);
+
+ result.Should().BeFalse();
+ }
}
\ No newline at end of file