using System.Text.Json; using FrameProcessor.Domain; namespace FrameProcessor.Tests; public class MacAddressTests { private static readonly byte[] ExpectedBytes = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF]; private const string Canonical = "aabbccddeeff"; [Theory] [InlineData("AA:BB:CC:DD:EE:FF")] [InlineData("aa:bb:cc:dd:ee:ff")] [InlineData("AA-BB-CC-DD-EE-FF")] [InlineData("aa-bb-cc-dd-ee-ff")] [InlineData("AABBCCDDEEFF")] [InlineData("aabbccddeeff")] [InlineData(" AA:BB:CC:DD:EE:FF ")] [InlineData("\tAA-bb-CC-dd-EE-ff\n")] public void TryParse_AcceptedForms_ProduceCanonicalString(string input) { Assert.True(MacAddress.TryParse(input, out var mac)); Assert.Equal(Canonical, mac.ToString()); } [Fact] public void Equality_IsByteWise_AcrossInputForms() { Assert.True(MacAddress.TryParse("AA:BB:CC:DD:EE:FF", out var a)); Assert.True(MacAddress.TryParse("aa-bb-cc-dd-ee-ff", out var b)); Assert.True(MacAddress.TryParse("AABBCCDDEEFF", out var c)); Assert.Equal(a, b); Assert.Equal(b, c); Assert.Equal(a.GetHashCode(), b.GetHashCode()); } [Fact] public void Equality_DiffersOnAnySingleByte() { Assert.True(MacAddress.TryParse("aabbccddeeff", out var a)); Assert.True(MacAddress.TryParse("aabbccddeefe", out var b)); Assert.NotEqual(a, b); } [Theory] [InlineData("")] [InlineData(" ")] [InlineData("not-a-mac")] [InlineData("AA:BB:CC:DD:EE")] // too short [InlineData("AA:BB:CC:DD:EE:FF:00")] // too long [InlineData("ZZ:BB:CC:DD:EE:FF")] // non-hex digit [InlineData("AA:BB:CC:DD:EE:F")] // odd hex count [InlineData("AA BB CC DD EE FF")] // unsupported space separator public void TryParse_RejectsBadInput(string input) { Assert.False(MacAddress.TryParse(input, out _)); } [Fact] public void TryParse_Null_ReturnsFalse() { Assert.False(MacAddress.TryParse((string?)null, out _)); } [Fact] public void Parse_Throws_OnBadInput() { Assert.Throws(() => MacAddress.Parse("nope")); } [Fact] public void Constructor_FromBytes_RoundTripsThroughToString() { var mac = new MacAddress(ExpectedBytes); Assert.Equal(Canonical, mac.ToString()); } [Fact] public void Constructor_FromWrongLength_Throws() { Assert.Throws(() => new MacAddress(new byte[] { 0x00 })); Assert.Throws(() => new MacAddress(new byte[7])); } [Fact] public void JsonRoundTrip_NormalizesToCanonicalForm() { var json = "\"AA:BB:CC:DD:EE:FF\""; var mac = JsonSerializer.Deserialize(json); var written = JsonSerializer.Serialize(mac); Assert.Equal($"\"{Canonical}\"", written); } [Fact] public void JsonDeserialize_BadInput_Throws() { Assert.Throws(() => JsonSerializer.Deserialize("\"not-a-mac\"")); } [Fact] public void IParsable_Hookup_Works() { var mac = MacAddress.Parse("AA:BB:CC:DD:EE:FF", provider: null); Assert.Equal(Canonical, mac.ToString()); Assert.True(MacAddress.TryParse("AA:BB:CC:DD:EE:FF", provider: null, out var mac2)); Assert.Equal(mac, mac2); } }