Upgraded to .NET 10 (#1147)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-11-01 20:32:16 +01:00
1 parent faae2951f7
commit fc7399e81b
327 files changed
+3059 -3049

No files matched your search

+2 -2
View File
@@ -37,7 +37,7 @@ public sealed class CapabilityTests
{
var bits = new Dictionary<ulong, Capability>();
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
foreach (var capability in Enum.GetValues<Capability>())
{
@@ -52,7 +52,7 @@ public sealed class CapabilityTests
bits[value] = capability;
}
});
}
}
[Test]
+6 -6
View File
@@ -53,11 +53,11 @@ public sealed class ContextWindowRuleTests
{
var window = provider.GetModelProfile(new Model(modelId, null)).Context;
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(window.IsKnown, Is.True);
Assert.That(window.DefaultTokens, Is.EqualTo(tokens));
});
}
}
[Test]
@@ -70,11 +70,11 @@ public sealed class ContextWindowRuleTests
//
var profile = ModelRegistry.Shared.Profile(LLMProviders.OPEN_AI, "gpt-5.3");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Context.IsKnown, Is.False);
Assert.That(profile.Has(Capability.FUNCTION_CALLING), Is.True, "Everything else it does inherit.");
});
}
}
[Test]
@@ -100,10 +100,10 @@ public sealed class ContextWindowRuleTests
//
var profile = ModelRegistry.Shared.Profile(LLMProviders.SELF_HOSTED, "some-model-nobody-wrote-a-rule-for");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Context.IsKnown, Is.False);
Assert.That(profile.Context.DefaultTokens, Is.Zero, "And the number next to it is meaningless, which is why nothing may read it without asking first.");
});
}
}
}
+2 -2
View File
@@ -41,7 +41,7 @@ public sealed class CorpusTests
[Test]
public void EveryKnownWrongAnswerSaysWhyAndWhereThatCanBeChecked()
{
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
foreach (var change in ExpectedChanges.ENTRIES)
{
@@ -49,7 +49,7 @@ public sealed class CorpusTests
Assert.That(change.Source, Is.Not.Empty, $"{change.Provider} {change.ModelId} does not say where that can be checked.");
Assert.That(change.AnswerWanted, Is.Not.Empty, $"{change.Provider} {change.ModelId} does not say what the answer should be.");
}
});
}
}
[Test]
@@ -51,12 +51,12 @@ public sealed class ModelPatternLiteralAnalyzerTests
{
var reported = await AnalyzeAsync(statements);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(reported, Has.Count.EqualTo(1));
Assert.That(reported.FirstOrDefault()?.Id, Is.EqualTo("MWAIS0013"));
Assert.That(reported.FirstOrDefault()?.GetMessage(), Does.Contain($"write it as \"{expectedSpelling}\""));
});
}
}
[Test]
@@ -64,11 +64,11 @@ public sealed class ModelPatternLiteralAnalyzerTests
{
var reported = await AnalyzeAsync("""builder.Rule("___");""");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(reported, Has.Count.EqualTo(1));
Assert.That(reported.FirstOrDefault()?.GetMessage(), Does.Contain("nothing of it survives"));
});
}
}
[Test]
@@ -97,12 +97,12 @@ public sealed class ModelRegistryGeneratorTests
{
var generated = Generate(TWO_FAMILIES_AND_A_HOST, out _, out _);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(generated, Does.Contain("new global::Sample.FirstFamily()"));
Assert.That(generated, Does.Contain("new global::Sample.SecondFamily()"), "A family which inherits through another class is still a family.");
Assert.That(generated, Does.Contain("new global::Sample.SampleHost()"));
});
}
}
[Test]
@@ -142,11 +142,11 @@ public sealed class ModelRegistryGeneratorTests
//
var generated = Generate("namespace Sample;\n\npublic sealed class NothingToDoWithModels;", out var updated, out _);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(generated, Does.Contain("public static class ModelRegistrations"));
Assert.That(CompilationHarness.ErrorsOf(updated), Is.Empty);
});
}
}
[Test]
@@ -155,12 +155,12 @@ public sealed class ModelRegistryGeneratorTests
var generated = Generate(A_FAMILY_NEEDING_AN_ARGUMENT, out _, out var diagnostics);
var reported = diagnostics.Where(diagnostic => diagnostic.Id is "MDR001").ToList();
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(reported, Has.Count.EqualTo(1));
Assert.That(reported.FirstOrDefault()?.GetMessage(), Does.Contain("DemandingFamily"));
Assert.That(generated, Does.Not.Contain("DemandingFamily"));
});
}
}
[Test]
@@ -170,11 +170,11 @@ public sealed class ModelRegistryGeneratorTests
// The tests above run the generator by hand. This one asks whether it also ran while the app
// was built, which is a different question and the one that actually matters.
//
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(ModelRegistrations.CreateFamilies(), Is.Not.Null);
Assert.That(ModelRegistrations.CreateHosts(), Is.Not.Null);
});
}
}
private static string Generate(string source, out Compilation updated, out IReadOnlyList<Diagnostic> diagnostics)
+22 -22
View File
@@ -20,12 +20,12 @@ public sealed class HostNamingTests
{
var taken = HostNaming.TrySplitOrganization(new ModelId("anthropic/claude-opus-5"), out var inner, out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(taken, Is.True);
Assert.That(inner.Original, Is.EqualTo("claude-opus-5"));
Assert.That(vendor, Is.EqualTo(ModelVendor.ANTHROPIC));
});
}
}
[Test]
@@ -37,18 +37,18 @@ public sealed class HostNamingTests
//
var taken = HostNaming.TrySplitOrganization(new ModelId("azure/gpt-5.6"), out var inner, out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(taken, Is.True);
Assert.That(inner.Original, Is.EqualTo("gpt-5.6"));
Assert.That(vendor, Is.Null);
});
}
}
[Test]
public void AnOrganizationIsRecognizedWhicheverWayTheHostSpellsIt()
{
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(HostNaming.VendorOfOrganization("meta-llama"), Is.EqualTo(ModelVendor.META));
Assert.That(HostNaming.VendorOfOrganization("Qwen"), Is.EqualTo(ModelVendor.ALIBABA));
@@ -57,7 +57,7 @@ public sealed class HostNamingTests
Assert.That(HostNaming.VendorOfOrganization("zai"), Is.EqualTo(ModelVendor.Z_AI));
Assert.That(HostNaming.VendorOfOrganization("minimaxi"), Is.EqualTo(ModelVendor.MINIMAX));
Assert.That(HostNaming.VendorOfOrganization("somebody-else"), Is.EqualTo(ModelVendor.UNKNOWN));
});
}
}
[Test]
@@ -65,12 +65,12 @@ public sealed class HostNamingTests
{
var taken = HostNaming.TrySplitOrganization(new ModelId("llama-3.3-70b-versatile"), out var inner, out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(taken, Is.False);
Assert.That(inner.Original, Is.EqualTo("llama-3.3-70b-versatile"));
Assert.That(vendor, Is.Null);
});
}
}
[Test]
@@ -82,11 +82,11 @@ public sealed class HostNamingTests
//
var taken = HostNaming.TrySplitOrganization(new ModelId("accounts/fireworks/models/llama-v3p1-405b-instruct"), out var inner, out _);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(taken, Is.True);
Assert.That(inner.Original, Is.EqualTo("fireworks/models/llama-v3p1-405b-instruct"));
});
}
}
[Test]
@@ -94,11 +94,11 @@ public sealed class HostNamingTests
{
var taken = HostNaming.TrySplitOrganization(new ModelId("openai/"), out var inner, out _);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(taken, Is.False);
Assert.That(inner.Original, Is.EqualTo("openai/"));
});
}
}
[Test]
@@ -106,11 +106,11 @@ public sealed class HostNamingTests
{
var taken = HostNaming.TryStripRoutingSuffix(new ModelId("google/gemma-4-31B-it:novita"), out var inner);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(taken, Is.True);
Assert.That(inner.Original, Is.EqualTo("google/gemma-4-31B-it"));
});
}
}
[Test]
@@ -118,11 +118,11 @@ public sealed class HostNamingTests
{
var taken = HostNaming.TryStripRegionSuffix(new ModelId("bedrock/claude-opus-5@eu-central-1"), out var inner);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(taken, Is.True);
Assert.That(inner.Original, Is.EqualTo("bedrock/claude-opus-5"));
});
}
}
[TestCase("bedrock/claude-opus-5", TestName = "A name without an at sign has no region to take off")]
@@ -131,11 +131,11 @@ public sealed class HostNamingTests
{
var taken = HostNaming.TryStripRegionSuffix(new ModelId(modelId), out var inner);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(taken, Is.False);
Assert.That(inner.Original, Is.EqualTo(modelId));
});
}
}
[Test]
@@ -143,11 +143,11 @@ public sealed class HostNamingTests
{
var taken = HostNaming.TryStripMenuPosition(new ModelId("10 - Muse Glimmer 30b - the newest META model"), out var inner);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(taken, Is.True);
Assert.That(inner.Original, Is.EqualTo("Muse Glimmer 30b - the newest META model"));
});
}
}
[TestCase("70b-instruct", TestName = "A number the model is named after is not a menu position")]
@@ -158,10 +158,10 @@ public sealed class HostNamingTests
{
var taken = HostNaming.TryStripMenuPosition(new ModelId(modelId), out var inner);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(taken, Is.False);
Assert.That(inner.Original, Is.EqualTo(modelId));
});
}
}
}
@@ -49,12 +49,12 @@ public sealed class ModelHostIndexTests
{
var index = ModelHostIndex.Build([new SplittingHost()]);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(index.ProvidersWithoutAHost, Does.Contain(LLMProviders.ANTHROPIC));
Assert.That(index.ProvidersWithoutAHost, Does.Not.Contain(LLMProviders.OPEN_ROUTER));
Assert.That(index.ProvidersWithoutAHost, Does.Not.Contain(LLMProviders.NONE), "Nobody can configure it, so nobody has to write a host for it.");
});
}
}
[Test]
@@ -63,12 +63,12 @@ public sealed class ModelHostIndexTests
var index = ModelHostIndex.Build([new SplittingHost()]);
var unwrapped = index.Unwrap(new ModelId("anthropic/claude-opus-5"), LLMProviders.ANTHROPIC, out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(index.Of(LLMProviders.ANTHROPIC), Is.Null);
Assert.That(unwrapped.Original, Is.EqualTo("anthropic/claude-opus-5"));
Assert.That(vendor, Is.Null);
});
}
}
[Test]
@@ -82,11 +82,11 @@ public sealed class ModelHostIndexTests
var profile = new ModelProfile { Capabilities = Capability.TEXT_INPUT | Capability.RESPONSES_API };
var throughTheProvider = index.ApplyTransport(profile, LLMProviders.ANTHROPIC);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(throughTheProvider.Has(Capability.RESPONSES_API), Is.False);
Assert.That(throughTheProvider.Has(Capability.CHAT_COMPLETION_API), Is.True);
});
}
}
[Test]
+28 -28
View File
@@ -47,11 +47,11 @@ public sealed class ModelHostTests
{
var unwrapped = Unwrap(LLMProviders.OPEN_ROUTER, "anthropic/claude-opus-5", out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(unwrapped.Original, Is.EqualTo("claude-opus-5"));
Assert.That(vendor, Is.EqualTo(ModelVendor.ANTHROPIC));
});
}
}
[Test]
@@ -59,11 +59,11 @@ public sealed class ModelHostTests
{
var unwrapped = Unwrap(LLMProviders.HUGGINGFACE, "openai/gpt-oss-120b:fireworks-ai", out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(unwrapped.Original, Is.EqualTo("gpt-oss-120b"));
Assert.That(vendor, Is.EqualTo(ModelVendor.OPEN_AI), "OpenAI published the weights, whoever is serving them today.");
});
}
}
[Test]
@@ -71,11 +71,11 @@ public sealed class ModelHostTests
{
var unwrapped = Unwrap(LLMProviders.HUGGINGFACE, "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(unwrapped.Original, Is.EqualTo("DeepSeek-R1-Distill-Qwen-32B"));
Assert.That(vendor, Is.EqualTo(ModelVendor.DEEP_SEEK));
});
}
}
[Test]
@@ -83,11 +83,11 @@ public sealed class ModelHostTests
{
var unwrapped = Unwrap(LLMProviders.REQUESTY, "bedrock/claude-opus-5@eu-central-1", out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(unwrapped.Original, Is.EqualTo("claude-opus-5"));
Assert.That(vendor, Is.Null, "Bedrock runs the model; it did not build it.");
});
}
}
[Test]
@@ -95,11 +95,11 @@ public sealed class ModelHostTests
{
var unwrapped = Unwrap(LLMProviders.REQUESTY, "claude-opus-5@eu", out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(unwrapped.Original, Is.EqualTo("claude-opus-5"));
Assert.That(vendor, Is.Null);
});
}
}
[Test]
@@ -107,11 +107,11 @@ public sealed class ModelHostTests
{
var unwrapped = Unwrap(LLMProviders.REQUESTY, "openai/gpt-6-sol:flex", out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(unwrapped.Original, Is.EqualTo("gpt-6-sol"));
Assert.That(vendor, Is.EqualTo(ModelVendor.OPEN_AI));
});
}
}
[TestCase("novita/qwen/qwen3.8-max", "qwen3.8-max", ModelVendor.ALIBABA, TestName = "Behind the cloud, the organization from the hub names the vendor")]
@@ -120,11 +120,11 @@ public sealed class ModelHostTests
{
var unwrapped = Unwrap(LLMProviders.REQUESTY, modelId, out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(unwrapped.Original, Is.EqualTo(expectedModel));
Assert.That(vendor, Is.EqualTo(expectedVendor));
});
}
}
[Test]
@@ -132,11 +132,11 @@ public sealed class ModelHostTests
{
var unwrapped = Unwrap(LLMProviders.FIREWORKS, "accounts/fireworks/models/llama-v3p1-405b-instruct", out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(unwrapped.Original, Is.EqualTo("llama-v3p1-405b-instruct"));
Assert.That(vendor, Is.Null, "None of the three path segments names a vendor.");
});
}
}
[Test]
@@ -152,11 +152,11 @@ public sealed class ModelHostTests
{
var unwrapped = Unwrap(LLMProviders.SELF_HOSTED, "meta-llama/Llama-3.3-70B-Instruct", out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(unwrapped.Original, Is.EqualTo("Llama-3.3-70B-Instruct"));
Assert.That(vendor, Is.EqualTo(ModelVendor.META));
});
}
}
[Test]
@@ -184,11 +184,11 @@ public sealed class ModelHostTests
//
var unwrapped = Unwrap(LLMProviders.SELF_HOSTED, modelId, out var vendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(unwrapped.Original, Is.EqualTo(expectedModel));
Assert.That(vendor, Is.EqualTo(expectedVendor));
});
}
}
[Test]
@@ -203,13 +203,13 @@ public sealed class ModelHostTests
var atItsVendor = new ModelProfile { Capabilities = Capability.TEXT_INPUT | Capability.FUNCTION_CALLING | Capability.RESPONSES_API };
var throughTheReseller = Transport(LLMProviders.GWDG, atItsVendor);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(Unwrap(LLMProviders.GWDG, "claude-sonnet-5", out _).Original, Is.EqualTo("claude-sonnet-5"));
Assert.That(throughTheReseller.Has(Capability.FUNCTION_CALLING), Is.True);
Assert.That(throughTheReseller.Has(Capability.RESPONSES_API), Is.False);
Assert.That(throughTheReseller.Has(Capability.CHAT_COMPLETION_API), Is.True);
});
}
}
[Test]
@@ -221,11 +221,11 @@ public sealed class ModelHostTests
.Where(host => host.ApplyTransport(withBothApis).Has(Capability.RESPONSES_API))
.Select(host => host.GetType().Name);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(Transport(LLMProviders.OPEN_AI, withBothApis).Has(Capability.RESPONSES_API), Is.True);
Assert.That(elsewhere, Is.Empty, "The app sends a Responses API request from exactly one place.");
});
}
}
[Test]
@@ -238,22 +238,22 @@ public sealed class ModelHostTests
var embedding = new ModelProfile { Capabilities = Capability.EMBEDDING };
var throughAGateway = Transport(LLMProviders.OPEN_ROUTER, embedding);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(throughAGateway.Has(Capability.EMBEDDING), Is.True);
Assert.That(throughAGateway.HasAny(Capability.CHAT_COMPLETION_API | Capability.RESPONSES_API), Is.False);
});
}
}
[Test]
public void ANameWithoutAWrappingComesBackAsItWas()
{
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(Unwrap(LLMProviders.OPEN_AI, "gpt-5.6", out _).Original, Is.EqualTo("gpt-5.6"));
Assert.That(Unwrap(LLMProviders.GROQ, "llama-3.3-70b-versatile", out _).Original, Is.EqualTo("llama-3.3-70b-versatile"));
Assert.That(Unwrap(LLMProviders.LITE_LLM, "the-fast-one", out _).Original, Is.EqualTo("the-fast-one"));
});
}
}
private static ModelId Unwrap(LLMProviders provider, string modelId, out ModelVendor? declaredVendor) => INDEX.Unwrap(new ModelId(modelId), provider, out declaredVendor);
+8 -8
View File
@@ -37,12 +37,12 @@ public sealed class ImageLimitRuleTests
{
var limits = provider.GetModelProfile(new Model(modelId, null)).Images;
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(limits.IsKnown, Is.True);
Assert.That(limits.MaxPerRequest, Is.EqualTo(perRequest));
Assert.That(limits.MaxPerMessage, Is.Null, "Neither vendor states a per-message limit, and inventing one would be a ceiling nobody wrote.");
});
}
}
[Test]
@@ -57,13 +57,13 @@ public sealed class ImageLimitRuleTests
var smallWindow = ModelRegistry.Shared.Profile(LLMProviders.ANTHROPIC, "claude-opus-4-1");
var largeWindow = ModelRegistry.Shared.Profile(LLMProviders.ANTHROPIC, "claude-opus-4-6");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(smallWindow.Context.DefaultTokens, Is.EqualTo(200_000));
Assert.That(smallWindow.Images.MaxPerRequest, Is.EqualTo(100));
Assert.That(largeWindow.Context.DefaultTokens, Is.EqualTo(1_000_000));
Assert.That(largeWindow.Images.MaxPerRequest, Is.EqualTo(600));
});
}
}
[Test]
@@ -76,11 +76,11 @@ public sealed class ImageLimitRuleTests
//
var profile = ModelRegistry.Shared.Profile(LLMProviders.SELF_HOSTED, "some-model-nobody-wrote-a-rule-for");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Images.IsKnown, Is.False);
Assert.That(profile.Images.MaxInOneMessage, Is.Null);
});
}
}
[Test]
@@ -93,11 +93,11 @@ public sealed class ImageLimitRuleTests
//
var profile = ModelRegistry.Shared.Profile(LLMProviders.OPEN_AI, "gpt-5.1");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Has(Capability.MULTIPLE_IMAGE_INPUT), Is.True, "It does read several images.");
Assert.That(profile.Images.IsKnown, Is.False, "How many, nobody said.");
});
}
}
[Test]
+12 -12
View File
@@ -35,11 +35,11 @@ public sealed class ListedModelsTests
{
var listed = new ListedModels();
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(listed.Of(ONE_MACHINE, MODEL), Is.EqualTo(ModelListing.NOTHING));
Assert.That(listed.Of(ONE_MACHINE, MODEL).IsKnown, Is.False);
});
}
}
[Test]
@@ -53,11 +53,11 @@ public sealed class ListedModelsTests
listed.Report(ONE_MACHINE, [new(MODEL, ContextWindow.Of(32_768))]);
listed.Report(ANOTHER_MACHINE, [new(MODEL, ContextWindow.Of(8_192))]);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(listed.Of(ONE_MACHINE, MODEL).Context.DefaultTokens, Is.EqualTo(32_768));
Assert.That(listed.Of(ANOTHER_MACHINE, MODEL).Context.DefaultTokens, Is.EqualTo(8_192));
});
}
}
[Test]
@@ -67,11 +67,11 @@ public sealed class ListedModelsTests
listed.Report(ONE_MACHINE, [new(MODEL, ContextWindow.Of(32_768)), new("gemma3-27b", ContextWindow.Of(16_384))]);
listed.Report(ONE_MACHINE, [new("gemma3-27b", ContextWindow.Of(16_384))]);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(listed.Of(ONE_MACHINE, MODEL), Is.EqualTo(ModelListing.NOTHING), "The engine was restarted without it, so nothing is known about it any more.");
Assert.That(listed.Of(ONE_MACHINE, "gemma3-27b").Context.DefaultTokens, Is.EqualTo(16_384));
});
}
}
[Test]
@@ -105,11 +105,11 @@ public sealed class ListedModelsTests
var listed = new ListedModels();
listed.Report(string.Empty, [new(MODEL, ContextWindow.Of(32_768))]);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(listed.Of(string.Empty, MODEL), Is.EqualTo(ModelListing.NOTHING));
Assert.That(listed.Of(ONE_MACHINE, MODEL), Is.EqualTo(ModelListing.NOTHING), "One nameless report does not become every machine's answer.");
});
}
}
[Test]
@@ -126,11 +126,11 @@ public sealed class ListedModelsTests
{
var after = new ModelListing(MODEL, ContextWindow.Of(32_768)).ApplyTo(WHAT_THE_RULES_SAY);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(after.Context.DefaultTokens, Is.EqualTo(32_768));
Assert.That(after.Context.RaisableToTokens, Is.Null, "What the weights could be raised to is not a number anybody reaches without restarting this engine.");
});
}
}
[Test]
@@ -138,12 +138,12 @@ public sealed class ListedModelsTests
{
var after = new ModelListing(MODEL, ContextWindow.Of(32_768)).ApplyTo(WHAT_THE_RULES_SAY);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(after.Capabilities, Is.EqualTo(WHAT_THE_RULES_SAY.Capabilities));
Assert.That(after.Images, Is.EqualTo(WHAT_THE_RULES_SAY.Images));
Assert.That(after.Kind, Is.EqualTo(WHAT_THE_RULES_SAY.Kind));
});
}
}
[Test]
@@ -21,11 +21,11 @@ public sealed class MatchPatternTests
var onAlibaba = new MatchPattern { Kind = MatchKind.SEGMENT, Text = "qwq", OnlyOn = LLMProviders.ALIBABA_CLOUD };
var name = new ModelId("qwq-32b");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(onAlibaba.Matches(name, LLMProviders.ALIBABA_CLOUD, ModelVendor.UNKNOWN), Is.True);
Assert.That(onAlibaba.Matches(name, LLMProviders.SELF_HOSTED, ModelVendor.UNKNOWN), Is.False);
});
}
}
[Test]
@@ -34,11 +34,11 @@ public sealed class MatchPatternTests
var fromAnthropic = new MatchPattern { Kind = MatchKind.SEGMENT, Text = "claude", OnlyFrom = ModelVendor.ANTHROPIC };
var name = new ModelId("claude-sonnet-4-0");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(fromAnthropic.Matches(name, LLMProviders.LITE_LLM, ModelVendor.ANTHROPIC), Is.True);
Assert.That(fromAnthropic.Matches(name, LLMProviders.LITE_LLM, ModelVendor.UNKNOWN), Is.False);
});
}
}
[Test]
@@ -46,12 +46,12 @@ public sealed class MatchPatternTests
{
var withVision = new MatchPattern { Kind = MatchKind.SEGMENT, Text = "qwen3.8", AlsoContains = ["vl"] };
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(withVision.Matches(new ModelId("qwen3.8-27b-vl"), LLMProviders.SELF_HOSTED, ModelVendor.UNKNOWN), Is.True);
Assert.That(withVision.Matches(new ModelId("qwen3.8-27b"), LLMProviders.SELF_HOSTED, ModelVendor.UNKNOWN), Is.False);
Assert.That(withVision.Matches(new ModelId("qwen3.8-27b-vllm"), LLMProviders.SELF_HOSTED, ModelVendor.UNKNOWN), Is.False, "\"vl\" inside another name part is not the vision variant.");
});
}
}
[Test]
@@ -62,11 +62,11 @@ public sealed class MatchPatternTests
//
var withoutTools = new MatchPattern { Kind = MatchKind.SEGMENT, Text = "salamandra", NotContains = ["tools"] };
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(withoutTools.Matches(new ModelId("salamandra-7b-instruct"), LLMProviders.SELF_HOSTED, ModelVendor.UNKNOWN), Is.True);
Assert.That(withoutTools.Matches(new ModelId("salamandra-7b-instruct-tools"), LLMProviders.SELF_HOSTED, ModelVendor.UNKNOWN), Is.False);
});
}
}
[TestCase("gpt-5.1", true)]
@@ -29,11 +29,11 @@ public sealed class ModelFamilyIndexTests
var distill = Selector("deepseek-r1", MatchKind.SEGMENT, new() { Adds = Capability.TEXT_INPUT | Capability.FUNCTION_CALLING, Reasoning = ReasoningSupport.ALWAYS });
var name = new ModelId("deepseek-r1-distill-llama-70b");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(ModelFamilyIndex.Build([llama, distill]).Explain(name, ANY_PROVIDER, ModelVendor.UNKNOWN).Selector, Is.SameAs(distill));
Assert.That(ModelFamilyIndex.Build([distill, llama]).Explain(name, ANY_PROVIDER, ModelVendor.UNKNOWN).Selector, Is.SameAs(distill), "The order the rules arrive in must not change the answer.");
});
}
}
[Test]
@@ -47,11 +47,11 @@ public sealed class ModelFamilyIndexTests
var chat = Selector("gpt-5-chat", MatchKind.PREFIX, new() { Adds = Capability.TEXT_INPUT, Reasoning = ReasoningSupport.NONE });
var index = ModelFamilyIndex.Build([reasoning, chat]);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(index.Resolve(new ModelId("gpt-5-chat-latest"), ANY_PROVIDER, ModelVendor.UNKNOWN).Reasoning, Is.EqualTo(ReasoningSupport.NONE));
Assert.That(index.Resolve(new ModelId("gpt-5-pro"), ANY_PROVIDER, ModelVendor.UNKNOWN).Reasoning, Is.EqualTo(ReasoningSupport.ALWAYS));
});
}
}
[Test]
@@ -79,11 +79,11 @@ public sealed class ModelFamilyIndexTests
var index = ModelFamilyIndex.Build([openWeights, commercial]);
var name = new ModelId("qwq-32b");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(index.Explain(name, LLMProviders.ALIBABA_CLOUD, ModelVendor.UNKNOWN).Selector, Is.SameAs(commercial));
Assert.That(index.Explain(name, LLMProviders.SELF_HOSTED, ModelVendor.UNKNOWN).Selector, Is.SameAs(openWeights));
});
}
}
[Test]
@@ -98,11 +98,11 @@ public sealed class ModelFamilyIndexTests
var baseCheckpoint = Modifier("base", MatchKind.SEGMENT, new() { Removes = Capability.FUNCTION_CALLING });
var index = ModelFamilyIndex.Build([family, baseCheckpoint]);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(index.Resolve(new ModelId("llama-3.3-70b"), ANY_PROVIDER, ModelVendor.UNKNOWN).Has(Capability.FUNCTION_CALLING), Is.True);
Assert.That(index.Resolve(new ModelId("llama-3.3-70b-base"), ANY_PROVIDER, ModelVendor.UNKNOWN).Has(Capability.FUNCTION_CALLING), Is.False);
});
}
}
[Test]
@@ -113,11 +113,11 @@ public sealed class ModelFamilyIndexTests
var narrow = Modifier("instruct-nano", MatchKind.SEGMENT, new() { Removes = Capability.FUNCTION_CALLING });
var resolution = ModelFamilyIndex.Build([narrow, broad, family]).Explain(new ModelId("llama-3.3-instruct-nano"), ANY_PROVIDER, ModelVendor.UNKNOWN);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(resolution.Modifiers.Select(modifier => modifier.Pattern.Text), Is.EqualTo(new[] { "instruct", "instruct-nano" }));
Assert.That(resolution.Profile.Has(Capability.FUNCTION_CALLING), Is.False);
});
}
}
[Test]
@@ -154,12 +154,12 @@ public sealed class ModelFamilyIndexTests
var oneWay = ModelFamilyIndex.Build([one, other]).Explain(name, ANY_PROVIDER, ModelVendor.UNKNOWN);
var otherWay = ModelFamilyIndex.Build([other, one]).Explain(name, ANY_PROVIDER, ModelVendor.UNKNOWN);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(oneWay.IsAmbiguous, Is.True);
Assert.That(otherWay.IsAmbiguous, Is.True);
Assert.That(oneWay.Selector, Is.SameAs(otherWay.Selector), "Which of the two answers must not depend on the order they arrived in.");
});
}
}
[Test]
@@ -190,11 +190,11 @@ public sealed class ModelFamilyIndexTests
var index = ModelFamilyIndex.Build([Selector("llama", MatchKind.SEGMENT, new() { Adds = Capability.TEXT_INPUT })]);
var resolution = index.Explain(new ModelId("something-nobody-wrote-a-rule-for"), ANY_PROVIDER, ModelVendor.UNKNOWN);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(resolution.IsKnown, Is.False);
Assert.That(resolution.Profile, Is.EqualTo(ModelProfile.UNKNOWN));
});
}
}
[Test]
@@ -227,11 +227,11 @@ public sealed class ModelFamilyIndexTests
//
var index = ModelFamilyIndex.Build([Selector("GPT-5", MatchKind.PREFIX, new() { Adds = Capability.TEXT_INPUT })]);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(index.Rules.Where(rule => !rule.Pattern.IsWellFormed), Is.Not.Empty);
Assert.That(index.Explain(new ModelId("gpt-5.1"), ANY_PROVIDER, ModelVendor.UNKNOWN).IsKnown, Is.False);
});
}
}
private static ModelRule Selector(string text, MatchKind kind, ModelProfileChange change, string origin = "test") => new(new() { Kind = kind, Text = text }, ModelRuleKind.SELECTOR, change, origin);
+8 -8
View File
@@ -30,11 +30,11 @@ public sealed class ModelIdTests
{
var id = new ModelId(reported);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(id.IsEmpty, Is.True);
Assert.That(id.Normalized, Is.Empty);
});
}
}
[Test]
@@ -42,11 +42,11 @@ public sealed class ModelIdTests
{
var id = new ModelId("Qwen3.8:27B-MLX");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(id.Original, Is.EqualTo("Qwen3.8:27B-MLX"));
Assert.That(id.ToString(), Is.EqualTo("Qwen3.8:27B-MLX"));
});
}
}
[Test]
@@ -54,13 +54,13 @@ public sealed class ModelIdTests
{
ModelId untouched = default;
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(untouched.IsEmpty, Is.True);
Assert.That(untouched.Original, Is.Empty);
Assert.That(untouched.Normalized, Is.Empty);
Assert.That(untouched.Segments.GetEnumerator().MoveNext(), Is.False);
});
}
}
[Test]
@@ -69,11 +69,11 @@ public sealed class ModelIdTests
var fromOllama = new ModelId("Qwen3.8:27b");
var fromHub = new ModelId("qwen3.8-27b");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(fromOllama, Is.EqualTo(fromHub));
Assert.That(fromOllama.GetHashCode(), Is.EqualTo(fromHub.GetHashCode()));
});
}
}
[Test]
@@ -82,10 +82,10 @@ public sealed class RuleSpecificityTests
var winner = RuleSpecificity.Of(expectedWinner);
var loser = RuleSpecificity.Of(expectedLoser);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(winner.CompareTo(loser), Is.GreaterThan(0));
Assert.That(loser.CompareTo(winner), Is.LessThan(0), "The comparison has to say the same thing in both directions.");
});
}
}
}
@@ -53,14 +53,14 @@ public sealed class MistralReleasesTests
// for "mistral-medium-3" would otherwise answer for "mistral-medium-3.5" as well and place
// it eleven months too early, before the release which gave it reasoning.
//
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(MistralReleases.Of(new ModelId("mistral-medium-3"), SOME_LATEST_RELEASE), Is.EqualTo(2505));
Assert.That(MistralReleases.Of(new ModelId("mistral-medium-3.5"), SOME_LATEST_RELEASE), Is.EqualTo(2604));
Assert.That(MistralReleases.Of(new ModelId("mistral-medium-3-5"), SOME_LATEST_RELEASE), Is.EqualTo(2604), "Mistral writes the version separator both ways for the same model.");
Assert.That(MistralReleases.Of(new ModelId("mistral-large-4"), SOME_LATEST_RELEASE), Is.EqualTo(2610));
Assert.That(MistralReleases.Of(new ModelId("mistral-large-4-0"), SOME_LATEST_RELEASE), Is.EqualTo(2610), "The model card names it with a minor version, which changes nothing about the release.");
});
}
}
[Test]
@@ -73,14 +73,14 @@ public sealed class MistralReleasesTests
var beforeItCouldSee = ModelRegistry.Shared.Profile(LLMProviders.MISTRAL, "mistral-large-2411");
var afterwards = ModelRegistry.Shared.Profile(LLMProviders.MISTRAL, "mistral-large-2512");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(beforeItCouldSee.Has(Capability.MULTIPLE_IMAGE_INPUT), Is.False);
Assert.That(beforeItCouldSee.Reasoning, Is.EqualTo(ReasoningSupport.NONE));
Assert.That(afterwards.Has(Capability.MULTIPLE_IMAGE_INPUT), Is.True);
Assert.That(afterwards.Reasoning, Is.EqualTo(ReasoningSupport.OPTIONAL));
});
}
}
[TestCase("mistral-large-4", TestName = "Mistral Large 4 under the name of Mistral's changelog")]
@@ -93,12 +93,12 @@ public sealed class MistralReleasesTests
//
var profile = ModelRegistry.Shared.Profile(LLMProviders.MISTRAL, modelId);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Has(Capability.MULTIPLE_IMAGE_INPUT), Is.True);
Assert.That(profile.Reasoning, Is.EqualTo(ReasoningSupport.OPTIONAL));
Assert.That(profile.Context.DefaultTokens, Is.EqualTo(1_000_000));
});
}
}
[TestCase("mistral-large-2512", TestName = "Mistral Large 3 keeps its own window")]
@@ -119,12 +119,12 @@ public sealed class MistralReleasesTests
//
var profile = ModelRegistry.Shared.Profile(LLMProviders.MISTRAL, "mistral-large-whenever");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Has(Capability.FUNCTION_CALLING), Is.True, "What the family could always do is still stated.");
Assert.That(profile.Has(Capability.MULTIPLE_IMAGE_INPUT), Is.False);
Assert.That(profile.Reasoning, Is.EqualTo(ReasoningSupport.NONE));
});
}
}
[Test]
@@ -132,10 +132,10 @@ public sealed class MistralReleasesTests
{
var newest = ModelRegistry.Shared.Profile(LLMProviders.MISTRAL, "ministral-3b-latest");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(newest.Has(Capability.MULTIPLE_IMAGE_INPUT), Is.True, "Ministral 3 reads images.");
Assert.That(newest.Reasoning, Is.EqualTo(ReasoningSupport.NONE), "No Ministral reasons, whatever its release.");
});
}
}
}
+10 -10
View File
@@ -20,11 +20,11 @@ public sealed class ModelFactsTests
{
ContextWindow untouched = default;
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(untouched.IsKnown, Is.False);
Assert.That(untouched, Is.EqualTo(ContextWindow.UNKNOWN));
});
}
}
[Test]
@@ -32,12 +32,12 @@ public sealed class ModelFactsTests
{
var window = ContextWindow.Of(128_000, 1_000_000);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(window.IsKnown, Is.True);
Assert.That(window.DefaultTokens, Is.EqualTo(128_000));
Assert.That(window.RaisableToTokens, Is.EqualTo(1_000_000));
});
}
}
[Test]
@@ -59,11 +59,11 @@ public sealed class ModelFactsTests
{
TokenizerRef untouched = default;
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(untouched.IsKnown, Is.False);
Assert.That(untouched.Kind, Is.EqualTo(TokenizerKind.UNKNOWN));
});
}
}
[Test]
@@ -79,12 +79,12 @@ public sealed class ModelFactsTests
{
ImageLimits untouched = default;
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(untouched.IsKnown, Is.False);
Assert.That(untouched.MaxPerMessage, Is.Null);
Assert.That(untouched.MaxPerRequest, Is.Null);
});
}
}
[Test]
@@ -92,11 +92,11 @@ public sealed class ModelFactsTests
{
var noImages = new ImageLimits(MaxPerMessage: 0, MaxPerRequest: null);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(noImages.IsKnown, Is.True, "Zero images is a statement an operator can make.");
Assert.That(noImages.MaxPerMessage, Is.EqualTo(0));
});
}
}
[Test]
+10 -10
View File
@@ -21,11 +21,11 @@ public sealed class ModelFamilyTests
{
var family = new SampleFamily();
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(family.Name, Is.EqualTo(nameof(SampleFamily)));
Assert.That(family.Rules.Select(rule => rule.Origin), Is.All.EqualTo(nameof(SampleFamily)));
});
}
}
[Test]
@@ -52,7 +52,7 @@ public sealed class ModelFamilyTests
var index = ModelFamilyIndex.Build(new SampleFamily().Rules);
var codex = index.Resolve(new ModelId("gpt-5.1-codex-max"), LLMProviders.OPEN_AI, ModelVendor.OPEN_AI);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(codex.Has(Capability.WEB_SEARCH), Is.False, "This is the one thing the variant takes away.");
Assert.That(codex.Has(Capability.TEXT_INPUT | Capability.MULTIPLE_IMAGE_INPUT | Capability.FUNCTION_CALLING), Is.True);
@@ -60,7 +60,7 @@ public sealed class ModelFamilyTests
Assert.That(codex.Context.DefaultTokens, Is.EqualTo(400_000));
Assert.That(codex.Tokenizer.Id, Is.EqualTo("o200k_base"));
Assert.That(codex.SystemPromptRole, Is.EqualTo(SystemPromptRole.DEVELOPER));
});
}
}
[Test]
@@ -69,11 +69,11 @@ public sealed class ModelFamilyTests
var index = ModelFamilyIndex.Build(new SampleFamily().Rules.Concat(new FamilyWithAModifier().Rules));
var adjusted = index.Resolve(new ModelId("gpt-5.1-base"), LLMProviders.OPEN_AI, ModelVendor.OPEN_AI);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(adjusted.Has(Capability.FUNCTION_CALLING), Is.False, "The modifier did apply.");
Assert.That(adjusted.SystemPromptRole, Is.EqualTo(SystemPromptRole.DEVELOPER));
});
}
}
[Test]
@@ -99,11 +99,11 @@ public sealed class ModelFamilyTests
{
var index = ModelFamilyIndex.Build(new FamilyWithTwoGenerations().Rules);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(index.Resolve(new ModelId("thing3-mini"), LLMProviders.SELF_HOSTED, ModelVendor.UNKNOWN).Reasoning, Is.EqualTo(ReasoningSupport.ALWAYS));
Assert.That(index.Resolve(new ModelId("thing4"), LLMProviders.SELF_HOSTED, ModelVendor.UNKNOWN).Reasoning, Is.EqualTo(ReasoningSupport.NONE));
});
}
}
[Test]
@@ -174,12 +174,12 @@ public sealed class ModelFamilyTests
[Test]
public void ASourceWithoutAPageOrADayIsNotAStatement()
{
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(new SampleFamily().Source.IsStated, Is.True);
Assert.That(new ModelSource(string.Empty, new DateOnly(2026, 9, 11), "a note").IsStated, Is.False);
Assert.That(new ModelSource("https://example.invalid", default, "a note").IsStated, Is.False);
});
}
}
/// <summary>
+6 -6
View File
@@ -24,7 +24,7 @@ public sealed class ModelKindTests
[Test]
public void EveryExampleIsRecognizedAsWhatItIsMadeFor()
{
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
foreach (var example in ModelKindCorpus.ENTRIES)
{
@@ -32,7 +32,7 @@ public sealed class ModelKindTests
Assert.That(profile.Kind, Is.EqualTo(example.Kind), $"{example.Provider} \"{example.ModelId}\"");
}
});
}
}
[Test]
@@ -59,11 +59,11 @@ public sealed class ModelKindTests
//
var profile = ModelRegistry.Shared.Profile(LLMProviders.SELF_HOSTED, "llama-guard-3-8b");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Kind, Is.EqualTo(ModelKind.MODERATION));
Assert.That(profile.Has(Capability.TEXT_INPUT), Is.True, "The family which chose the model still speaks for it.");
});
}
}
[Test]
@@ -71,10 +71,10 @@ public sealed class ModelKindTests
{
var resolution = ModelRegistry.Shared.Explain(LLMProviders.SELF_HOSTED, "bge-reranker-v2-m3");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(resolution.Profile.Kind, Is.EqualTo(ModelKind.RERANKING));
Assert.That(resolution.Modifiers.Select(modifier => modifier.Pattern.Text), Does.Contain("bge"), "Both words match; the ranked one has to be the one which gets the last word.");
});
}
}
}
+8 -8
View File
@@ -14,7 +14,7 @@ public sealed class ModelProfileTests
{
var untouched = ModelProfile.UNKNOWN;
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(untouched.Capabilities, Is.EqualTo(Capability.NONE));
Assert.That(untouched.Reasoning, Is.EqualTo(ReasoningSupport.NONE));
@@ -27,7 +27,7 @@ public sealed class ModelProfileTests
// meaning "no idea".
//
Assert.That(untouched.Kind, Is.EqualTo(ModelKind.CHAT));
});
}
}
[Test]
@@ -35,13 +35,13 @@ public sealed class ModelProfileTests
{
var profile = new ModelProfile { Capabilities = Capability.TEXT_INPUT | Capability.TEXT_OUTPUT };
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Has(Capability.TEXT_INPUT | Capability.TEXT_OUTPUT), Is.True);
Assert.That(profile.Has(Capability.TEXT_INPUT | Capability.WEB_SEARCH), Is.False);
Assert.That(profile.HasAny(Capability.TEXT_INPUT | Capability.WEB_SEARCH), Is.True);
Assert.That(profile.HasAny(Capability.WEB_SEARCH | Capability.EMBEDDING), Is.False);
});
}
}
[Test]
@@ -69,13 +69,13 @@ public sealed class ModelProfileTests
var after = new ModelProfileChange { Removes = Capability.WEB_SEARCH }.ApplyTo(before);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(after.Capabilities, Is.EqualTo(Capability.TEXT_INPUT));
Assert.That(after.Reasoning, Is.EqualTo(ReasoningSupport.OPTIONAL), "A change saying nothing about reasoning must not reset it.");
Assert.That(after.Context, Is.EqualTo(before.Context), "A change saying nothing about the context window must not reset it.");
Assert.That(after.SystemPromptRole, Is.EqualTo(SystemPromptRole.DEVELOPER), "A change saying nothing about the system prompt role must not reset it.");
});
}
}
[Test]
@@ -106,11 +106,11 @@ public sealed class ModelProfileTests
var profile = change.ApplyTo(ModelProfile.UNKNOWN);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Capabilities, Is.EqualTo(Capability.TEXT_INPUT));
Assert.That(profile.Has(Capability.ALWAYS_REASONING), Is.False);
Assert.That(profile.Reasoning, Is.EqualTo(ReasoningSupport.ALWAYS));
});
}
}
}
+2 -2
View File
@@ -27,7 +27,7 @@ public sealed class Gpt6FamilyTests
{
var profile = LLMProviders.OPEN_AI.GetModelProfile(new Model(modelId, null));
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Has(Capability.RESPONSES_API), Is.True);
Assert.That(profile.Has(Capability.MULTIPLE_IMAGE_INPUT), Is.True);
@@ -35,7 +35,7 @@ public sealed class Gpt6FamilyTests
Assert.That(profile.Has(Capability.WEB_SEARCH), Is.True);
Assert.That(profile.Context.IsKnown, Is.True);
Assert.That(profile.Context.DefaultTokens, Is.EqualTo(1_050_000));
});
}
}
[TestCase("gpt-6-astra", ReasoningSupport.ALWAYS, TestName = "Astra reasons on every request")]
@@ -27,13 +27,13 @@ public sealed class NewOpenAIModelTests
{
var profile = LLMProviders.OPEN_AI.GetModelProfile(new Model(modelId, null));
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Has(Capability.RESPONSES_API), Is.True);
Assert.That(profile.Has(Capability.FUNCTION_CALLING), Is.True);
Assert.That(profile.Has(Capability.MULTIPLE_IMAGE_INPUT), Is.True);
Assert.That(profile.Reasoning, Is.Not.EqualTo(ReasoningSupport.NONE));
});
}
}
[Test]
@@ -46,12 +46,12 @@ public sealed class NewOpenAIModelTests
//
var profile = LLMProviders.OPEN_AI.GetModelProfile(new Model("gpt-oss-120b", null));
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Has(Capability.RESPONSES_API), Is.False);
Assert.That(profile.Reasoning, Is.EqualTo(ReasoningSupport.NONE));
Assert.That(profile.Context.DefaultTokens, Is.EqualTo(131_072));
});
}
}
[Test]
@@ -59,11 +59,11 @@ public sealed class NewOpenAIModelTests
{
var profile = LLMProviders.SELF_HOSTED.GetModelProfile(new Model("gpt-j-6b", null));
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Has(Capability.RESPONSES_API), Is.False);
Assert.That(profile.Has(Capability.MULTIPLE_IMAGE_INPUT), Is.False);
Assert.That(profile.Reasoning, Is.EqualTo(ReasoningSupport.NONE));
});
}
}
}
@@ -49,11 +49,11 @@ public sealed class DeclaredModelsTests
var profile = registry.Profile(LLMProviders.SELF_HOSTED, "acme-assistant-7b");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(profile.Has(Capability.FUNCTION_CALLING), Is.False, "The built-in rule grants this one, and the declaration does not.");
Assert.That(profile.Reasoning, Is.EqualTo(ReasoningSupport.NONE), "Nor does it reason, whatever the built-in rule says.");
});
}
}
[Test]
@@ -83,11 +83,11 @@ public sealed class DeclaredModelsTests
registry.Declare([]);
var afterwards = registry.Profile(LLMProviders.SELF_HOSTED, "acme-assistant-7b");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(whileDeclared.Has(Capability.FUNCTION_CALLING), Is.False);
Assert.That(afterwards.Has(Capability.FUNCTION_CALLING), Is.True);
});
}
}
[Test]
@@ -105,11 +105,11 @@ public sealed class DeclaredModelsTests
Declaring("acme-assistant-7b", MatchKind.EXACT, Capability.TEXT_INPUT | Capability.TEXT_OUTPUT | Capability.MULTIPLE_IMAGE_INPUT),
]);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(registry.Profile(LLMProviders.SELF_HOSTED, "acme-assistant-7b").Has(Capability.MULTIPLE_IMAGE_INPUT), Is.True);
Assert.That(registry.Profile(LLMProviders.SELF_HOSTED, "acme-assistant-3b").Has(Capability.MULTIPLE_IMAGE_INPUT), Is.False);
});
}
}
[Test]
@@ -127,11 +127,11 @@ public sealed class DeclaredModelsTests
{
registry.Declare([declaration]);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(registry.Profile(LLMProviders.OPEN_AI, "gpt-5.1").Has(Capability.VIDEO_INPUT), Is.True);
Assert.That(registry.Profile(LLMProviders.OPEN_ROUTER, "openai/gpt-5.1").Has(Capability.VIDEO_INPUT), Is.True, "The same model, reached through a gateway which wraps the name.");
});
}
}
finally
{
@@ -56,7 +56,7 @@ public sealed class ModelDeclarationTests
var declaration = await ReadAsync(A_COMPLETE_DECLARATION);
Assert.That(declaration, Is.Not.Null);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(declaration!.Pattern.Text, Is.EqualTo("acme-assistant"));
Assert.That(declaration.Pattern.Kind, Is.EqualTo(MatchKind.PREFIX));
@@ -68,7 +68,7 @@ public sealed class ModelDeclarationTests
Assert.That(declaration.Change.Images, Is.EqualTo(new ImageLimits(1, 8)));
Assert.That(declaration.Source.CheckedOn, Is.EqualTo(new DateOnly(2026, 9, 12)));
Assert.That(declaration.EnterpriseConfigurationPluginId, Is.EqualTo(PLUGIN_ID));
});
}
}
[Test]
@@ -77,7 +77,7 @@ public sealed class ModelDeclarationTests
var declaration = await ReadAsync(THE_LEAST_A_DECLARATION_CAN_SAY);
Assert.That(declaration, Is.Not.Null);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(declaration!.Pattern.Kind, Is.EqualTo(MatchKind.SEGMENT), "The kind to reach for by default, here as everywhere else.");
Assert.That(declaration.Change.Reasoning, Is.EqualTo(ReasoningSupport.NONE));
@@ -85,7 +85,7 @@ public sealed class ModelDeclarationTests
Assert.That(declaration.Change.Context, Is.Null);
Assert.That(declaration.Change.Tokenizer, Is.Null);
Assert.That(declaration.Change.Images, Is.Null);
});
}
}
[Test]
@@ -199,11 +199,11 @@ public sealed class ModelDeclarationTests
var theSameNames = await ReadAsync(A_COMPLETE_DECLARATION.Replace("""["CONTEXT_WINDOW"] = 131072,""", """["CONTEXT_WINDOW"] = 65536,""", StringComparison.Ordinal));
var otherNames = await ReadAsync(A_COMPLETE_DECLARATION.Replace("""["MATCH"] = "PREFIX",""", """["MATCH"] = "SEGMENT",""", StringComparison.Ordinal));
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(theSameNames?.Id, Is.EqualTo(declaration?.Id), "The same pattern, so one of the two has to win.");
Assert.That(otherNames?.Id, Is.Not.EqualTo(declaration?.Id), "Bound to the name differently, so they claim different sets of names.");
});
}
}
private static async Task<ModelDeclaration?> ReadAsync(string entry)
+4 -4
View File
@@ -27,7 +27,7 @@ public sealed class PortingDifferenceTests
{
var corrected = ExpectedChanges.ENTRIES.Where(change => IsAnswered(change.Provider, change.ModelId)).ToList();
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(corrected, Is.Not.Empty, "Nothing the audit found wrong is answered by a rule at all, which would make this test green for the wrong reason.");
@@ -38,7 +38,7 @@ public sealed class PortingDifferenceTests
Assert.That(rebuilt, Is.EqualTo(CapabilitySnapshot.Describe(change.AnswerWanted)), $"{change.Provider} \"{change.ModelId}\": {change.Reason}");
}
});
}
}
[Test]
@@ -80,7 +80,7 @@ public sealed class PortingDifferenceTests
// toss. Reading the rules alone cannot find it -- the two patterns are written differently
// and only meet on a real name, which is what the corpus is full of.
//
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
foreach (var entry in ModelCorpus.ENTRIES)
{
@@ -88,7 +88,7 @@ public sealed class PortingDifferenceTests
Assert.That(resolution.IsAmbiguous, Is.False, $"{entry.Provider} \"{entry.ModelId}\" is claimed by {resolution.Selector} and, just as strongly, by {string.Join(", ", resolution.TiedSelectors)}.");
}
});
}
}
/// <summary>
@@ -114,12 +114,12 @@ public sealed class ModelRegistryTests
var atOpenAI = ModelRegistry.Shared.Profile(LLMProviders.OPEN_AI, "gpt-5.1");
var throughAGateway = ModelRegistry.Shared.Profile(LLMProviders.OPEN_ROUTER, "openai/gpt-5.1");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(atOpenAI.Has(Capability.RESPONSES_API), Is.True);
Assert.That(throughAGateway.Has(Capability.RESPONSES_API), Is.False);
Assert.That(throughAGateway.Has(Capability.FUNCTION_CALLING), Is.True, "Everything but the API survives the trip through a gateway.");
});
}
}
[Test]
+8 -8
View File
@@ -40,11 +40,11 @@ public sealed class TokenizerRuleTests
{
var tokenizer = provider.GetModelProfile(new Model(modelId, null)).Tokenizer;
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(tokenizer.Kind, Is.EqualTo(TokenizerKind.TIKTOKEN));
Assert.That(tokenizer.Id, Is.EqualTo(encoding));
});
}
}
[TestCase(LLMProviders.ANTHROPIC, "claude-opus-5", "/v1/messages/count_tokens")]
@@ -55,11 +55,11 @@ public sealed class TokenizerRuleTests
{
var tokenizer = provider.GetModelProfile(new Model(modelId, null)).Tokenizer;
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(tokenizer.Kind, Is.EqualTo(TokenizerKind.PROVIDER_API));
Assert.That(tokenizer.Id, Is.EqualTo(endpoint));
});
}
}
[TestCase(LLMProviders.OPEN_AI, "gpt-6-astra", Description = "Newer than the mapping OpenAI publishes, so nothing is claimed for it.")]
@@ -70,11 +70,11 @@ public sealed class TokenizerRuleTests
{
var tokenizer = provider.GetModelProfile(new Model(modelId, null)).Tokenizer;
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(tokenizer.IsKnown, Is.False);
Assert.That(tokenizer.Kind, Is.EqualTo(TokenizerKind.UNKNOWN), "Which means the built-in tokenizer, the same as today.");
});
}
}
[Test]
@@ -98,12 +98,12 @@ public sealed class TokenizerRuleTests
// without a kind cannot be told apart from any other string -- whether it is a repository,
// an encoding or an endpoint decides what a person can do with it.
//
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(new TokenizerRef(TokenizerKind.HUGGING_FACE, string.Empty).IsKnown, Is.False);
Assert.That(new TokenizerRef(TokenizerKind.UNKNOWN, "o200k_base").IsKnown, Is.False);
Assert.That(TokenizerRef.UNKNOWN.IsKnown, Is.False);
Assert.That(new TokenizerRef(TokenizerKind.TIKTOKEN, "o200k_base").IsKnown, Is.True);
});
}
}
}