diff --git a/csharp/Platform.Data.Tests/ILinksExtensionsTests.cs b/csharp/Platform.Data.Tests/ILinksExtensionsTests.cs new file mode 100644 index 0000000..51d55a4 --- /dev/null +++ b/csharp/Platform.Data.Tests/ILinksExtensionsTests.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Numerics; +using Xunit; +using Platform.Data.Exceptions; +using Platform.Delegates; + +namespace Platform.Data.Tests +{ + /// + /// Tests for ILinksExtensions methods + /// + public static class ILinksExtensionsTests + { + private class MockLinks : ILinks> + { + private readonly LinksConstants _constants; + + public MockLinks() + { + _constants = new LinksConstants(enableExternalReferencesSupport: true); + } + + public LinksConstants Constants => _constants; + + public ulong Count(IList? restriction) => 0; + + public ulong Each(IList? restriction, ReadHandler? handler) + { + // Return Constants.Break to simulate no matching links found + return _constants.Break; + } + + public ulong Create(IList? substitution, WriteHandler? handler) => 0; + + public ulong Update(IList? restriction, IList? substitution, WriteHandler? handler) => 0; + + public ulong Delete(IList? restriction, WriteHandler? handler) => 0; + } + + /// + /// Tests that GetLink throws ArgumentLinkDoesNotExistsException when link doesn't exist + /// + [Fact] + public static void GetLinkThrowsExceptionWhenLinkDoesNotExist() + { + var links = new MockLinks(); + var nonExistentLinkId = 999UL; + + // The mock implementation returns Constants.Break from Each, which means no link was found + // and the Setter.Result remains null, so GetLink should throw ArgumentLinkDoesNotExistsException + var exception = Assert.Throws>(() => + links.GetLink(nonExistentLinkId)); + + // Verify the exception contains the correct link id (checking if it's in the message) + Assert.Contains(nonExistentLinkId.ToString(), exception.Message); + } + + /// + /// Tests that GetLink works correctly for external references + /// + [Fact] + public static void GetLinkWorksForExternalReferences() + { + var links = new MockLinks(); + var externalReference = new Hybrid(0, true); // External reference + + // For external references, GetLink should return a Point without calling Each + var result = links.GetLink(externalReference); + + Assert.NotNull(result); + // The Point should contain the external reference value + Assert.Equal(externalReference.Value, result[0]); + } + } +} \ No newline at end of file diff --git a/csharp/Platform.Data/ILinksExtensions.cs b/csharp/Platform.Data/ILinksExtensions.cs index 4fcf77a..303d138 100644 --- a/csharp/Platform.Data/ILinksExtensions.cs +++ b/csharp/Platform.Data/ILinksExtensions.cs @@ -148,7 +148,12 @@ public static TLinkAddress Each(this ILinks?, TLinkAddress>(constants.Continue, constants.Break); links.Each(linkPartsSetter.SetAndReturnTrue, link); - return linkPartsSetter.Result; + var result = linkPartsSetter.Result; + if (result == null) + { + throw new ArgumentLinkDoesNotExistsException(link); + } + return result; } #region Points