diff --git a/tests/GameCult.Caching.Tests/StoreRoutingTests.cs b/tests/GameCult.Caching.Tests/StoreRoutingTests.cs index 9a65dc89..fc99f01f 100644 --- a/tests/GameCult.Caching.Tests/StoreRoutingTests.cs +++ b/tests/GameCult.Caching.Tests/StoreRoutingTests.cs @@ -410,6 +410,22 @@ namespace GameCult.Caching.Tests Assert.That(reader.AllEntries, Is.Empty); } + [Test] + public async Task GetByIndexMatchesAssignableTypes() + { + using var cache = new CultCache(CultDocumentRegistry.ForTypes(new[] { typeof(RoutingIndexedLeaf), typeof(RoutingIndexedTwin) })); + var leaf = await cache.UpsertAsync(typeof(RoutingIndexedLeaf), new RoutingIndexedLeaf { Code = "alpha" }); + + Assert.That(cache.GetByIndex("code", "alpha"), Is.InstanceOf(), + "an index declared on a base member resolves through the base type"); + + var twin = await cache.UpsertAsync(typeof(RoutingIndexedTwin), new RoutingIndexedTwin { Code = "alpha" }); + + Assert.That(() => cache.GetByIndex("code", "alpha"), + Throws.InvalidOperationException.With.Message.Contains(leaf.Value).And.Message.Contains(twin.Value)); + Assert.That(cache.GetByIndex("code", "alpha"), Is.InstanceOf()); + } + [Test] public async Task AmbiguousAssignableLookupThrows() { @@ -768,6 +784,25 @@ namespace GameCult.Caching.Tests public string Name = string.Empty; } + internal abstract class RoutingIndexedBase + { + [Key(0)] + [CultIndex("code")] + public string Code = string.Empty; + } + + [CultDocument("tests.routing_indexed_leaf", "tests.routing_indexed_leaf.v1")] + [MessagePackObject(AllowPrivate = true)] + internal sealed class RoutingIndexedLeaf : RoutingIndexedBase + { + } + + [CultDocument("tests.routing_indexed_twin", "tests.routing_indexed_twin.v1")] + [MessagePackObject(AllowPrivate = true)] + internal sealed class RoutingIndexedTwin : RoutingIndexedBase + { + } + internal abstract class RoutingGlobalBase { }