using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using StellaOps.Concelier.Models; using Xunit; using StellaOps.TestKit; namespace StellaOps.Concelier.Models.Tests; public sealed class SerializationDeterminismTests { private static readonly string[] Cultures = { "en-US", "fr-FR", "tr-TR", "ja-JP", "ar-SA" }; [Trait("Category", TestCategories.Unit)] [Fact] public void CanonicalSerializer_ProducesStableJsonAcrossCultures() { var examples = CanonicalExampleFactory.GetExamples().ToArray(); var baseline = SerializeUnderCulture(CultureInfo.InvariantCulture, examples); foreach (var cultureName in Cultures) { var culture = CultureInfo.GetCultureInfo(cultureName); var serialized = SerializeUnderCulture(culture, examples); Assert.Equal(baseline.Count, serialized.Count); for (var i = 0; i < baseline.Count; i++) { Assert.Equal(baseline[i].Compact, serialized[i].Compact); Assert.Equal(baseline[i].Indented, serialized[i].Indented); } } } private static List<(string Name, string Compact, string Indented)> SerializeUnderCulture( CultureInfo culture, IReadOnlyList<(string Name, Advisory Advisory)> examples) { var originalCulture = CultureInfo.CurrentCulture; var originalUiCulture = CultureInfo.CurrentUICulture; try { CultureInfo.CurrentCulture = culture; CultureInfo.CurrentUICulture = culture; var results = new List<(string Name, string Compact, string Indented)>(examples.Count); foreach (var (name, advisory) in examples) { var compact = CanonicalJsonSerializer.Serialize(advisory); var indented = CanonicalJsonSerializer.SerializeIndented(advisory); results.Add((name, compact, indented)); } return results; } finally { CultureInfo.CurrentCulture = originalCulture; CultureInfo.CurrentUICulture = originalUiCulture; } } }