diff --git a/app/Tests/Provider/ModelListMetadataTests.cs b/app/Tests/Provider/ModelListMetadataTests.cs index b87f2e372..96ba3d273 100644 --- a/app/Tests/Provider/ModelListMetadataTests.cs +++ b/app/Tests/Provider/ModelListMetadataTests.cs @@ -1,5 +1,6 @@ using System.Text.Json; +using AIStudio.Provider; using AIStudio.Provider.Groq; using AIStudio.Provider.OpenRouter; using AIStudio.Provider.Requesty; @@ -19,17 +20,12 @@ namespace AIStudio.Tests.Provider; /// below are shortened answers of the real routes, so that a rename is caught here rather than by /// somebody wondering why their window never shows up. /// -/// The options mirror what the providers deserialize with: names in snake case, which is what makes -/// the renaming attributes necessary in the first place. +/// The answers are read with the options of the providers themselves: names in snake case, which is +/// what makes the renaming attributes necessary in the first place. /// [TestFixture] public sealed class ModelListMetadataTests { - private static readonly JsonSerializerOptions AS_THE_PROVIDERS_READ_IT = new() - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, - }; - [Test] // ReSharper disable once InconsistentNaming public void VLLMStatesTheWindowItWasStartedWith() @@ -41,7 +37,7 @@ public sealed class ModelListMetadataTests { "id": "Qwen/Qwen3-32B", "object": "model", "owned_by": "vllm", "max_model_len": 32768 } ] } - """, AS_THE_PROVIDERS_READ_IT); + """, ProviderJsonOptions.OPTIONS); Assert.That(response.Data, Is.Not.Null); using (Assert.EnterMultipleScope()) @@ -63,7 +59,7 @@ public sealed class ModelListMetadataTests "object": "list", "data": [ { "id": "gemma3:1b", "object": "model" } ] } - """, AS_THE_PROVIDERS_READ_IT); + """, ProviderJsonOptions.OPTIONS); Assert.That(response.Data, Is.Not.Null); Assert.That(response.Data![0].ContextWindowTokens, Is.Null); @@ -84,7 +80,7 @@ public sealed class ModelListMetadataTests } ] } - """, AS_THE_PROVIDERS_READ_IT); + """, ProviderJsonOptions.OPTIONS); using (Assert.EnterMultipleScope()) { @@ -101,7 +97,7 @@ public sealed class ModelListMetadataTests "object": "list", "data": [ { "id": "llama-3.3-70b-versatile", "object": "model", "context_window": 131072 } ] } - """, AS_THE_PROVIDERS_READ_IT); + """, ProviderJsonOptions.OPTIONS); Assert.That(response.Data[0].ContextWindowTokens, Is.EqualTo(131_072)); } @@ -114,7 +110,7 @@ public sealed class ModelListMetadataTests "object": "list", "data": [ { "id": "openai/gpt-4o-mini", "object": "model", "api": "chat", "context_window": 128000, "max_output_tokens": 16384 } ] } - """, AS_THE_PROVIDERS_READ_IT); + """, ProviderJsonOptions.OPTIONS); Assert.That(response.Data[0].ContextWindowTokens, Is.EqualTo(128_000)); } @@ -127,7 +123,7 @@ public sealed class ModelListMetadataTests "object": "list", "data": [ { "id": "mistral-large-latest", "object": "model", "created": 1700000000, "owned_by": "mistralai", "max_context_length": 131072 } ] } - """, AS_THE_PROVIDERS_READ_IT); + """, ProviderJsonOptions.OPTIONS); Assert.That(response.Data[0].ContextWindowTokens, Is.EqualTo(131_072)); } @@ -147,7 +143,7 @@ public sealed class ModelListMetadataTests } ] } - """, AS_THE_PROVIDERS_READ_IT); + """, ProviderJsonOptions.OPTIONS); Assert.That(response.Data[0].Providers, Is.Not.Null); Assert.That(response.Data[0].Providers![0].ContextWindowTokens, Is.EqualTo(64_000)); diff --git a/app/Tests/Provider/SelfHostedModelListTests.cs b/app/Tests/Provider/SelfHostedModelListTests.cs index 466f48e3b..ab29225e7 100644 --- a/app/Tests/Provider/SelfHostedModelListTests.cs +++ b/app/Tests/Provider/SelfHostedModelListTests.cs @@ -25,11 +25,6 @@ namespace AIStudio.Tests.Provider; [TestFixture] public sealed class SelfHostedModelListTests { - private static readonly JsonSerializerOptions AS_THE_PROVIDERS_READ_IT = new() - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, - }; - /// /// What "GET /v1/models" answers on a local Ollama, shortened to the fields it sends. /// @@ -51,7 +46,7 @@ public sealed class SelfHostedModelListTests private static IReadOnlyList TheModelsTheEngineListed() { - var response = JsonSerializer.Deserialize(WHAT_A_LOCAL_OLLAMA_ANSWERS, AS_THE_PROVIDERS_READ_IT); + var response = JsonSerializer.Deserialize(WHAT_A_LOCAL_OLLAMA_ANSWERS, ProviderJsonOptions.OPTIONS); Assert.That(response.Data, Is.Not.Null, "The answer has to be readable before anything can be sorted out of it."); return response.Data! diff --git a/app/Tests/Tools/FileTypesTests.cs b/app/Tests/Tools/FileTypesTests.cs index 478e00b4e..50e66a4eb 100644 --- a/app/Tests/Tools/FileTypesTests.cs +++ b/app/Tests/Tools/FileTypesTests.cs @@ -3,6 +3,7 @@ using System.Text; using System.Text.Json; using AIStudio.Tools.Rust; +using AIStudio.Tools.Services; using AIStudio.Tools.Validation; namespace AIStudio.Tests.Tools; @@ -122,7 +123,7 @@ public class FileTypesTests public void DialogFilterMatchesTheRuntimeContract() { // The struct FileTypeFilter in runtime/src/file_actions.rs knows exactly these two fields: - var json = JsonSerializer.Serialize(FileTypes.ToFileDialogFilter(FileTypes.JSON), new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower }); + var json = JsonSerializer.Serialize(FileTypes.ToFileDialogFilter(FileTypes.JSON), RustService.JSON_OPTIONS); Assert.That(json, Is.EqualTo("""{"filter_name":"JSON","filter_extensions":["json"]}""")); } diff --git a/app/Tests/Tools/ShareFileResponseTests.cs b/app/Tests/Tools/ShareFileResponseTests.cs index f90f15201..fddde6370 100644 --- a/app/Tests/Tools/ShareFileResponseTests.cs +++ b/app/Tests/Tools/ShareFileResponseTests.cs @@ -11,27 +11,18 @@ namespace AIStudio.Tests.Tools; /// /// ShareFileResponse in runtime/src/share_sheet.rs names the outcome in snake case. A name which the /// app does not know would not fail anywhere: the enum converter falls back to the first member, and -/// a share sheet which did not respond would go unnoticed again. The options mirror what RustService -/// deserializes with. +/// a share sheet which did not respond would go unnoticed again. The answers are read with the options +/// of RustService itself. /// [TestFixture] public sealed class ShareFileResponseTests { - private static readonly JsonSerializerOptions AS_THE_RUST_SERVICE_READS_IT = new() - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, - Converters = - { - new RustEnumConverter(), - }, - }; - [TestCase("opened", ShareSheetOutcome.OPENED)] [TestCase("failed", ShareSheetOutcome.FAILED)] [TestCase("unresponsive", ShareSheetOutcome.UNRESPONSIVE)] public void TheAppReadsEveryOutcomeOfTheRuntime(string outcome, ShareSheetOutcome expectedOutcome) { - var response = JsonSerializer.Deserialize($$"""{"outcome":"{{outcome}}","issue":"The main window is not available."}""", AS_THE_RUST_SERVICE_READS_IT); + var response = JsonSerializer.Deserialize($$"""{"outcome":"{{outcome}}","issue":"The main window is not available."}""", RustService.JSON_OPTIONS); Assert.That(response, Is.Not.Null); using (Assert.EnterMultipleScope()) @@ -44,7 +35,7 @@ public sealed class ShareFileResponseTests [Test] public void AnUnknownOutcomeNeverCountsAsAnOpenedShareSheet() { - var response = JsonSerializer.Deserialize("""{"outcome":"vanished","issue":""}""", AS_THE_RUST_SERVICE_READS_IT); + var response = JsonSerializer.Deserialize("""{"outcome":"vanished","issue":""}""", RustService.JSON_OPTIONS); Assert.That(response?.Outcome, Is.EqualTo(ShareSheetOutcome.UNKNOWN)); }