using System.Runtime.CompilerServices; using ClaudeDo.Localization; using ClaudeDo.Ui.Localization; using ClaudeDo.Ui.Services; using Xunit; // Loc.Current (src/ClaudeDo.Ui/Localization/Loc.cs) is a process-wide mutable static that many // ViewModel test constructors assign — parallel collections race on which localizer is active. [assembly: CollectionBehavior(DisableTestParallelization = true)] namespace ClaudeDo.Ui.Tests; internal static class TestSetup { // Runs once when this test assembly loads, before any test executes. Without it, every test // that constructs a real DetailsIslandViewModel/TasksIslandViewModel/WorkerClient and calls a // method instrumented with OperationTiming.Shared.Record writes straight into the live app's // ~/.todo-app/logs/operation-timing.ndjson — a single Ui.Tests run added 50-100 cancelled // "DetailsIsland.BindAsync:?" lines to that file, dwarfing real usage and making the churn // look like a UI bug. [ModuleInitializer] internal static void RedirectOperationTimingAwayFromRealAppData() { var path = Path.Combine(Path.GetTempPath(), "claudedo-ui-tests", $"operation-timing-{Environment.ProcessId}.ndjson"); OperationTiming.Shared = new OperationTiming(path); } // Installs the real localizer before any test runs, so a class that reads Loc.T/Loc.Current // without setting it up itself (e.g. via a ViewModel error message) doesn't fall back to // Loc's key-echo default depending on which test class happens to run first. [ModuleInitializer] internal static void InstallRealLocalizer() { var dir = AppContext.BaseDirectory; while (dir is not null && !Directory.Exists(Path.Combine(dir, "src", "ClaudeDo.Localization", "locales"))) dir = Path.GetDirectoryName(dir); Loc.Current = new Localizer( LocaleStore.Load(Path.Combine(dir!, "src", "ClaudeDo.Localization", "locales")), "en"); } }