using System.Globalization; using System.Runtime.CompilerServices; namespace AcDream.Tests; /// /// Lets a test run pin the ambient culture, so a locale-dependent failure can /// be reproduced on any machine instead of only on one with the right Windows /// locale. /// /// Why this exists. On 2026-08-19 the Windows CI runner went red on /// 37 tests across four assemblies with failures like /// Expected: "You have 1 500p" / Actual: "You have 1,500p". The /// production code was right — it formats retail text with /// , so every player sees retail's /// comma. The TESTS were wrong: they built their expected strings with /// $"{value:N0}", which uses the machine's current culture, so they only /// passed on a machine that happens to format like the invariant culture. The /// runner is Swedish (space as the group separator), and the tests had been /// passing there only because its registry locale had been pinned by hand — /// a machine-state fix that silently came undone. /// /// The expectations are fixed to be invariant. This knob is the /// apparatus that makes such a break reproducible next time: /// ACDREAM_TEST_CULTURE=sv-SE dotnet test ... runs the suite as the /// Swedish runner sees it. Unset (the default, and what CI runs) changes /// nothing at all. /// internal static class TestCultureInitializer { internal const string CultureVariable = "ACDREAM_TEST_CULTURE"; [ModuleInitializer] internal static void Initialize() { string? requested = Environment.GetEnvironmentVariable(CultureVariable); if (string.IsNullOrWhiteSpace(requested)) { return; } try { var culture = CultureInfo.GetCultureInfo(requested); CultureInfo.DefaultThreadCurrentCulture = culture; CultureInfo.DefaultThreadCurrentUICulture = culture; } catch (CultureNotFoundException) { // A typo in an opt-in diagnostic must not fail an unrelated suite; // the run simply keeps the machine's own culture. } } }