aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/src/Godosa.Core.Tests/SettingsFileTests.cs
blob: 7308c2bba39d8ae5d9c0b97c5b7b11de4875d11e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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<string> _reports = new();

    private SettingsFile<string> Store(string path, Func<string, string>? 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<string>.DefaultPath(variable, "some-game"));
        Environment.SetEnvironmentVariable(variable, "/tmp/x.json");
        try
        {
            Assert.Equal("/tmp/x.json", SettingsFile<string>.DefaultPath(variable, "some-game"));
        }
        finally
        {
            Environment.SetEnvironmentVariable(variable, null);
        }
    }
}