Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions Stack/Opc.Ua.Types/Utils/NumericRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,22 @@ public override readonly bool Equals(object obj)
/// <param name="other">The NumericRange to test against this</param>
public readonly bool Equals(NumericRange other)
{
return (other.m_begin == m_begin) && (other.m_end == m_end);
if (other.m_begin != m_begin || other.m_end != m_end)
{
return false;
}

if (SubRanges == null && other.SubRanges == null)
{
return true;
}

if (SubRanges == null ^ other.SubRanges == null)
{
return false;
}

return other.SubRanges.SequenceEqual(SubRanges);
}

/// <summary>
Expand Down Expand Up @@ -317,7 +332,19 @@ public readonly bool Equals(NumericRange other)
/// </remarks>
public override readonly int GetHashCode()
{
return HashCode.Combine(m_begin, m_end);
int hashCode = HashCode.Combine(m_begin, m_end);

if (SubRanges == null)
{
return hashCode;
}

foreach (NumericRange subRange in SubRanges)
{
hashCode = HashCode.Combine(hashCode, subRange);
}

return hashCode;
}

/// <summary>
Expand Down
68 changes: 68 additions & 0 deletions Tests/Opc.Ua.Types.Tests/Utils/NumericRangeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System.Collections.Generic;
using NUnit.Framework;

namespace Opc.Ua.Types.Tests.Utils
{
[TestFixture]
[Category("Utils")]
[SetCulture("en-us")]
[SetUICulture("en-us")]
[Parallelizable]
public class NumericRangeTests
{
private static IEnumerable<TestCaseData> SubRangesCombinations
{
get
{
NumericRange[] range1 = [new(1, 3)];
NumericRange[] range2 = [new(2, 4)];
NumericRange[] empty = [];
NumericRange[] nullValue = null;

yield return new TestCaseData(range1, range2).Returns(false);
yield return new TestCaseData(empty, range1).Returns(false);
yield return new TestCaseData(range1, empty).Returns(false);
yield return new TestCaseData(nullValue, range1).Returns(false);
yield return new TestCaseData(range1, nullValue).Returns(false);

yield return new TestCaseData(range1, range1).Returns(true);
yield return new TestCaseData(nullValue, nullValue).Returns(true);
}
}

[TestCaseSource(nameof(SubRangesCombinations))]
public bool Equals_ForSubRanges(NumericRange[] subRanges1, NumericRange[] subRanges2)
{
var range1 = new NumericRange(1, 5)
{
SubRanges = subRanges1
};

var range2 = new NumericRange(1, 5)
{
SubRanges = subRanges2
};

return range1.Equals(range2);
}

/// <remarks>
/// NOTE: Could theoretically fail for hash collisions
/// </remarks>
[TestCaseSource(nameof(SubRangesCombinations))]
public bool GetHashCode_ForSubRanges(NumericRange[] subRanges1, NumericRange[] subRanges2)
{
var range1 = new NumericRange(1, 5)
{
SubRanges = subRanges1
};

var range2 = new NumericRange(1, 5)
{
SubRanges = subRanges2
};

return range1.GetHashCode() == range2.GetHashCode();
}
}
}
Loading