From ea626f9e1427863380c7de54b156fa8c643ac5f4 Mon Sep 17 00:00:00 2001 From: Yaakov Date: Sun, 26 Nov 2017 19:48:59 +1100 Subject: [PATCH] Implement ServerRecord equality and hashing. Fixes #476. --- .../SteamKit2/Steam/Discovery/ServerRecord.cs | 52 ++++++++++- SteamKit2/Tests/ServerRecordFacts.cs | 88 +++++++++++++++++++ 2 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 SteamKit2/Tests/ServerRecordFacts.cs diff --git a/SteamKit2/SteamKit2/Steam/Discovery/ServerRecord.cs b/SteamKit2/SteamKit2/Steam/Discovery/ServerRecord.cs index 71ce294de..3d9ce0918 100644 --- a/SteamKit2/SteamKit2/Steam/Discovery/ServerRecord.cs +++ b/SteamKit2/SteamKit2/Steam/Discovery/ServerRecord.cs @@ -1,4 +1,4 @@ - using System; +using System; using System.Net; namespace SteamKit2.Discovery @@ -122,5 +122,55 @@ public static ServerRecord CreateWebSocketServer(string address) return new ServerRecord(endPoint, ProtocolTypes.WebSocket); } + + #region Equality and Hashing + + /// + /// Determines whether two objects are equal. + /// + /// The object on the left-hand side of the equality operator. + /// The object on the right-hand side of the equality operator. + /// true if the specified object is equal to the current object; otherwise, false. + public static bool operator ==(ServerRecord left, ServerRecord right) + { + if (ReferenceEquals(left, right)) + { + return true; + } + + return !ReferenceEquals(left, null) && left.Equals(right); + } + + /// + /// Determines whether two objects are not equal. + /// + /// The object on the left-hand side of the inequality operator. + /// The object on the right-hand side of the inequality operator. + /// true if the specified object is not equal to the current object; otherwise, false. + public static bool operator !=(ServerRecord left, ServerRecord right) + { + return !(left == right); + } + + /// + /// Determines whether the specified object is equal to the current object. + /// + /// + /// true if the specified object is equal to the current object; otherwise, false. + public override bool Equals(object obj) + => obj is ServerRecord other && + EndPoint.Equals(other.EndPoint) && + ProtocolTypes == other.ProtocolTypes; + + /// + /// Hash function + /// + /// A hash code for the current object. + public override int GetHashCode() + { + return EndPoint.GetHashCode() ^ ProtocolTypes.GetHashCode(); + } + + #endregion } } diff --git a/SteamKit2/Tests/ServerRecordFacts.cs b/SteamKit2/Tests/ServerRecordFacts.cs new file mode 100644 index 000000000..3c2d73c8f --- /dev/null +++ b/SteamKit2/Tests/ServerRecordFacts.cs @@ -0,0 +1,88 @@ +using SteamKit2; +using SteamKit2.Discovery; +using Xunit; + +namespace Tests +{ + public class ServerRecordFacts + { + [Fact] + public void NullsAreEqualOperator() + { + ServerRecord l = null; + ServerRecord r = null; + + Assert.True(l == r); + } + + [Fact] + public void NullIsNotEqual() + { + var s = ServerRecord.CreateWebSocketServer("host:1"); + + Assert.True(s != null); + Assert.True(null != s); + Assert.False(s.Equals(null)); + Assert.False(s == null); + Assert.False(null == s); + } + + [Fact] + public void DifferentProtocolsAreNotEqual() + { + var l = ServerRecord.CreateServer("host", 1, ProtocolTypes.Tcp); + var r = ServerRecord.CreateServer("host", 1, ProtocolTypes.WebSocket); + + Assert.True(l != r); + Assert.True(r != l); + Assert.False(l == r); + Assert.False(r == l); + Assert.False(l.Equals(r)); + Assert.False(r.Equals(l)); + } + + [Fact] + public void DifferentEndPointsAreNotEqual() + { + var l = ServerRecord.CreateServer("host", 1, ProtocolTypes.Tcp); + var r = ServerRecord.CreateServer("host", 2, ProtocolTypes.Tcp); + + Assert.True(l != r); + Assert.True(r != l); + Assert.False(l == r); + Assert.False(r == l); + Assert.False(l.Equals(r)); + Assert.False(r.Equals(l)); + } + + [Fact] + public void DifferentEndPointsAndProtocolsAreNotEqual() + { + var l = ServerRecord.CreateServer("host", 1, ProtocolTypes.Tcp); + var r = ServerRecord.CreateServer("host", 2, ProtocolTypes.WebSocket); + + Assert.True(l != r); + Assert.True(r != l); + Assert.False(l == r); + Assert.False(r == l); + Assert.False(l.Equals(r)); + Assert.False(r.Equals(l)); + } + + [Fact] + public void SameEndPointsAndProtocolsAreEqual() + { + var l = ServerRecord.CreateServer("host", 1, ProtocolTypes.Tcp); + var r = ServerRecord.CreateServer("host", 1, ProtocolTypes.Tcp); + + Assert.False(l != r); + Assert.False(r != l); + Assert.True(l == r); + Assert.True(r == l); + Assert.True(l.Equals(r)); + Assert.True(r.Equals(l)); + + Assert.Equal(l.GetHashCode(), r.GetHashCode()); + } + } +}