SettingsTests.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. using System;
  2. using System.IO;
  3. using System.Reflection;
  4. using DesktopClock.Properties;
  5. namespace DesktopClock.Tests;
  6. public class SettingsPersistenceTests
  7. {
  8. [Fact]
  9. public void Save_ThenPopulate_ShouldRoundTripKeyProperties()
  10. {
  11. using var _ = new TempSettingsFileScope();
  12. var original = CreateSettingsInstance();
  13. original.FontFamily = "My custom font";
  14. original.Height = 72;
  15. original.Topmost = false;
  16. original.Format = "{HH:mm:ss}";
  17. original.RunOnStartup = true;
  18. original.ClickThrough = true;
  19. var saved = original.Save();
  20. Assert.True(saved);
  21. Assert.True(File.Exists(Settings.FilePath));
  22. var loaded = CreateSettingsInstance();
  23. PopulateFromFile(loaded);
  24. Assert.Equal(original.FontFamily, loaded.FontFamily);
  25. Assert.Equal(original.Height, loaded.Height);
  26. Assert.Equal(original.Topmost, loaded.Topmost);
  27. Assert.Equal(original.Format, loaded.Format);
  28. Assert.Equal(original.RunOnStartup, loaded.RunOnStartup);
  29. Assert.Equal(original.ClickThrough, loaded.ClickThrough);
  30. }
  31. [Fact]
  32. public void ScaleHeight_ShouldAdjustAndClamp()
  33. {
  34. var settings = CreateSettingsInstance();
  35. settings.Height = 48;
  36. settings.ScaleHeight(2);
  37. Assert.Equal(64, settings.Height);
  38. settings.ScaleHeight(-2);
  39. Assert.Equal(47, settings.Height);
  40. var minHeight = (int)Math.Exp(Settings.MinSizeLog);
  41. var maxHeight = (int)Math.Exp(Settings.MaxSizeLog);
  42. settings.Height = 48;
  43. settings.ScaleHeight(10_000);
  44. Assert.Equal(maxHeight, settings.Height);
  45. settings.Height = 48;
  46. settings.ScaleHeight(-10_000);
  47. Assert.Equal(minHeight, settings.Height);
  48. }
  49. private static Settings CreateSettingsInstance() =>
  50. (Settings)Activator.CreateInstance(typeof(Settings), nonPublic: true)!;
  51. private static void PopulateFromFile(Settings settings)
  52. {
  53. var populateMethod = typeof(Settings).GetMethod(
  54. "Populate",
  55. BindingFlags.NonPublic | BindingFlags.Static);
  56. Assert.NotNull(populateMethod);
  57. populateMethod.Invoke(null, new object[] { settings });
  58. }
  59. private sealed class TempSettingsFileScope : IDisposable
  60. {
  61. private readonly string _originalFilePath;
  62. public TempSettingsFileScope()
  63. {
  64. _originalFilePath = Settings.FilePath;
  65. var tempDir = Path.Combine(Path.GetTempPath(), "DesktopClock.Tests");
  66. Directory.CreateDirectory(tempDir);
  67. var tempFilePath = Path.Combine(tempDir, $"{Guid.NewGuid():N}.settings");
  68. SetSettingsFilePath(tempFilePath);
  69. if (File.Exists(Settings.FilePath))
  70. File.Delete(Settings.FilePath);
  71. }
  72. public void Dispose()
  73. {
  74. try
  75. {
  76. if (File.Exists(Settings.FilePath))
  77. File.Delete(Settings.FilePath);
  78. }
  79. finally
  80. {
  81. SetSettingsFilePath(_originalFilePath);
  82. }
  83. }
  84. private static void SetSettingsFilePath(string filePath)
  85. {
  86. var filePathProperty = typeof(Settings).GetProperty(
  87. nameof(Settings.FilePath),
  88. BindingFlags.Public | BindingFlags.Static);
  89. Assert.NotNull(filePathProperty);
  90. var setMethod = filePathProperty.GetSetMethod(nonPublic: true);
  91. Assert.NotNull(setMethod);
  92. setMethod.Invoke(null, new object[] { filePath });
  93. }
  94. }
  95. }