using Xunit; namespace Godosa.Core.Tests; public sealed class SettingsFileTests : IDisposable { private readonly string _dir = Path.Combine(Path.GetTempPath(), "godosa-settings-" + Guid.NewGuid().ToString("N")); public void Dispose() { if (Directory.Exists(_dir)) Directory.Delete(_dir, recursive: true); } private readonly List _reports = new(); private SettingsFile Store(string path, Func? parse = null) => new(path, parse ?? (text => "parsed:" + text), value => value, () => "defaults", _reports.Add); [Fact] public void Missing_GivesDefaults() { var file = Store(Path.Combine(_dir, "settings.json"), _ => throw new InvalidOperationException("parsed")); Assert.Equal("defaults", file.Load()); Assert.Empty(_reports); // a first run is not a problem } [Fact] public void Save_CreatesFolder_ThenLoadParsesWhatWasWritten_NoTempLeft() { string path = Path.Combine(_dir, "sub", "settings.json"); var file = Store(path); file.Save("{\"a\":1}"); Assert.Equal("{\"a\":1}", System.IO.File.ReadAllText(path)); Assert.Equal("parsed:{\"a\":1}", file.Load()); Assert.False(System.IO.File.Exists(path + ".tmp")); } [Fact] public void ParseFailure_FallsBackToDefaults() { string path = Path.Combine(_dir, "settings.json"); Directory.CreateDirectory(_dir); System.IO.File.WriteAllText(path, "\u0000junk"); var file = Store(path, _ => throw new FormatException("bad")); Assert.Equal("defaults", file.Load()); Assert.Contains("load failed", Assert.Single(_reports)); } [Fact] public void SaveFailure_DoesNotThrow() { Directory.CreateDirectory(Path.Combine(_dir, "settings.json")); // a folder where the file should go Store(Path.Combine(_dir, "settings.json")).Save("x"); Assert.Contains("save failed", Assert.Single(_reports)); Assert.False(System.IO.File.Exists(Path.Combine(_dir, "settings.json.tmp")), "temp file cleaned up"); } [Fact] public void BareRelativePath_SavesInTheWorkingFolder() { string name = "godosa-settings-" + Guid.NewGuid().ToString("N") + ".json"; try { Store(name).Save("x"); Assert.Empty(_reports); Assert.Equal("x", System.IO.File.ReadAllText(Path.GetFullPath(name))); } finally { System.IO.File.Delete(Path.GetFullPath(name)); } } [Fact] public void DefaultPath_UsesOverrideWhenSet_ElseAppDataFolder() { string variable = "GODOSA_TEST_SETTINGS_" + Guid.NewGuid().ToString("N"); string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); Assert.Equal(Path.Combine(appData, "some-game", "settings.json"), SettingsFile.DefaultPath(variable, "some-game")); Environment.SetEnvironmentVariable(variable, "/tmp/x.json"); try { Assert.Equal("/tmp/x.json", SettingsFile.DefaultPath(variable, "some-game")); } finally { Environment.SetEnvironmentVariable(variable, null); } } }