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);
}
}
}
|