using Wiki.Core.Ports; namespace Wiki.Contracts; /// Every adapter derives from this. The adapter under test may talk to a fake server. public abstract class EmbeddingModelContract { protected abstract Task CreateModelAsync(); [Fact] public async Task VectorsHaveTheDeclaredDimensionAndUnitLength() { var model = await CreateModelAsync(); var vectors = await model.EmbedAsync(["alpha", "beta"], CancellationToken.None); Assert.Equal(2, vectors.Count); foreach (var v in vectors) { Assert.Equal(model.Dimension, v.Length); var norm = MathF.Sqrt(v.Sum(x => x * x)); Assert.InRange(norm, 0.99f, 1.01f); } } [Fact] public async Task SameTextSameVectorAndOrderPreserved() { var model = await CreateModelAsync(); var once = await model.EmbedAsync(["one", "two", "three"], CancellationToken.None); var again = await model.EmbedAsync(["three", "one"], CancellationToken.None); Assert.Equal(once[2], again[0]); Assert.Equal(once[0], again[1]); } [Fact] public async Task EmptyBatchIsEmpty() { var model = await CreateModelAsync(); Assert.Empty(await model.EmbedAsync([], CancellationToken.None)); } [Fact] public async Task ModelIdIsSet() { var model = await CreateModelAsync(); Assert.False(string.IsNullOrWhiteSpace(model.ModelId)); var health = await model.CheckAsync(CancellationToken.None); Assert.True(health.Ok, health.Detail); } }