Cover GetByIndex resolving through assignable types
GetByIndexMatchesAssignableTypes: a [CultIndex] on a base member of two derived documents resolves GetByIndex<Base> to the derived record, throws naming both keys once the value is ambiguous across the two types, and still resolves by the concrete type. GetByIndex<T> already filtered assignable types; no CultCache change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
debe616716
commit
b6ed9e5f83
1 changed files with 35 additions and 0 deletions
|
|
@ -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<RoutingIndexedBase>("code", "alpha"), Is.InstanceOf<RoutingIndexedLeaf>(),
|
||||
"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<RoutingIndexedBase>("code", "alpha"),
|
||||
Throws.InvalidOperationException.With.Message.Contains(leaf.Value).And.Message.Contains(twin.Value));
|
||||
Assert.That(cache.GetByIndex<RoutingIndexedLeaf>("code", "alpha"), Is.InstanceOf<RoutingIndexedLeaf>());
|
||||
}
|
||||
|
||||
[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
|
||||
{
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue