更新框架
This commit is contained in:
1 parent
ef50fa0620
commit
84b28f9672
72 files changed
+2222
-282
No files matched your search
@@ -0,0 +1,113 @@
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using Newtonsoft.Json;
|
||||
using Store.Management.Framework.Controls;
|
||||
using Store.Management.Framework.Converters;
|
||||
using Store.Management.Framework.Services;
|
||||
using Store.Management.Framework.Utilities;
|
||||
using Store.Management.Framework.Configs;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
[STAThread]
|
||||
private static void Main()
|
||||
{
|
||||
int count = 0;
|
||||
var cleanup = new DisposeAction(() => Interlocked.Increment(ref count));
|
||||
Parallel.For(0, 100, _ => cleanup.Dispose());
|
||||
Check(count == 1, "Concurrent cleanup");
|
||||
VerifyEvents().GetAwaiter().GetResult();
|
||||
string? crashPath = ApplicationLogService.WriteFatal(new InvalidOperationException("smoke-crash-marker"), "SmokeTest");
|
||||
Check(crashPath != null && File.ReadAllText(crashPath).Contains("smoke-crash-marker"), "Crash report without logger initialization");
|
||||
File.Delete(crashPath!);
|
||||
|
||||
Check(Path.IsPathFullyQualified(FolderConfig.ConfigFolder), "Absolute config directory");
|
||||
Check(FolderConfig.AppSettingsFilePath == Path.Combine(FolderConfig.ConfigFolder, "AppSettings.json"), "Settings location");
|
||||
Check(new DefaultPathSettings().FilePath == Path.Combine(FolderConfig.ConfigFolder, "SettingsModel.json"), "Default model location");
|
||||
foreach (string invalid in new[] { "../escape.json", "D:\\escape.json", "..", "config.json." })
|
||||
{
|
||||
try { FolderConfig.GetSettingsFilePath(invalid); throw new Exception("Expected invalid filename error"); }
|
||||
catch (ArgumentException) { }
|
||||
}
|
||||
|
||||
string directory = Path.Combine(Path.GetTempPath(), "StoreFramework-" + Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(directory);
|
||||
try
|
||||
{
|
||||
string file = Path.Combine(directory, "settings.JSON");
|
||||
var settings = new TestSettings(file);
|
||||
settings.LoadSettings();
|
||||
Check(settings.Model.Value == 7, "Missing settings defaults");
|
||||
settings.Model.Value = 42;
|
||||
settings.SaveSettings();
|
||||
var reloaded = new TestSettings(file);
|
||||
reloaded.LoadSettingsAsync().GetAwaiter().GetResult();
|
||||
Check(reloaded.Model.Value == 42, "Settings roundtrip");
|
||||
Task.WhenAll(Enumerable.Range(0, 10).Select(_ => settings.SaveSettingsAsync())).GetAwaiter().GetResult();
|
||||
Check(Directory.GetFiles(directory, "*.tmp").Length == 0, "Temporary file cleanup");
|
||||
File.WriteAllText(file, "{broken");
|
||||
try { reloaded.LoadSettings(); throw new Exception("Expected JSON error"); }
|
||||
catch (JsonException) { }
|
||||
Check(reloaded.Model.Value == 42, "Corrupt settings preserve model");
|
||||
File.WriteAllText(file, "null");
|
||||
try { reloaded.LoadSettings(); throw new Exception("Expected null error"); }
|
||||
catch (JsonException) { }
|
||||
string[] args = [file];
|
||||
AppArgsService.Initialize(args);
|
||||
args[0] = "changed";
|
||||
Check(AppArgsService.GetArgs()[0] == file, "Arguments snapshot");
|
||||
Check(AppArgsService.GetFilePaths("json").Single() == file, "Extension case");
|
||||
Check(AppArgsService.GetFilePaths(".JSON").Single() == file, "Dotted extension");
|
||||
try { AppArgsService.GetFilePaths("."); throw new Exception("Expected invalid extension error"); }
|
||||
catch (ArgumentException) { }
|
||||
}
|
||||
finally { Directory.Delete(directory, recursive: true); }
|
||||
|
||||
var grid = new AutoColumnsUniformGrid { CellMinWidth = 200, MinColumns = 2, MaxColumns = 4 };
|
||||
grid.Measure(new Size(1000, 500));
|
||||
Check(grid.Columns == 4, "Maximum columns");
|
||||
grid.Measure(new Size(100, 500));
|
||||
Check(grid.Columns == 2, "Minimum columns");
|
||||
grid.MaxColumns = 1;
|
||||
grid.Measure(new Size(1000, 500));
|
||||
Check(grid.Columns == 2, "Conflicting bounds");
|
||||
try { grid.CellMinWidth = double.NaN; throw new Exception("Expected invalid width error"); }
|
||||
catch (ArgumentException) { }
|
||||
var converter = new StringNullOrEmpty2VisibilityConverter();
|
||||
Check(Equals(converter.Convert(null!, typeof(Visibility), null!, CultureInfo.InvariantCulture), Visibility.Visible), "Null placeholder");
|
||||
Check(Equals(converter.Convert("value", typeof(Visibility), null!, CultureInfo.InvariantCulture), Visibility.Collapsed), "Nonempty placeholder");
|
||||
Console.WriteLine("PASS: cleanup, async events, settings, arguments, WPF layout and converter boundaries.");
|
||||
}
|
||||
|
||||
private static async Task VerifyEvents()
|
||||
{
|
||||
var events = new AsyncEvent<EventArgs>();
|
||||
var calls = new List<int>();
|
||||
Func<object?, EventArgs, Task> second = (_, _) => { calls.Add(2); return Task.CompletedTask; };
|
||||
events.Subscribe(async (_, _) => { await Task.Yield(); calls.Add(1); events.Unsubscribe(second); });
|
||||
events.Subscribe(second);
|
||||
await events.InvokeAsync(null, EventArgs.Empty);
|
||||
Check(calls.SequenceEqual([1, 2]), "Event snapshot and order");
|
||||
calls.Clear();
|
||||
await events.InvokeAsync(null, EventArgs.Empty);
|
||||
Check(calls.SequenceEqual([1]), "Event unsubscribe");
|
||||
}
|
||||
|
||||
private static void Check(bool result, string message)
|
||||
{
|
||||
if (!result) throw new Exception(message);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SettingsModel { public int Value { get; set; } = 7; }
|
||||
internal sealed class TestSettings(string path) : JsonSettingsServiceBase<SettingsModel>
|
||||
{
|
||||
public override string FilePath => path;
|
||||
public override SettingsModel GetDefaultModel() => new();
|
||||
}
|
||||
|
||||
internal sealed class DefaultPathSettings : JsonSettingsServiceBase<SettingsModel>
|
||||
{
|
||||
public override SettingsModel GetDefaultModel() => new();
|
||||
}
|
||||
Reference in new issue
Block a user