mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-13 10:21:09 -05:00
PostProcessorLoader and PostProcessorMaterials move unchanged (namespace OpenNest kept) into the toolkit-neutral library, so the Avalonia app can load the posts in Posts/ and register their materials as the WinForms app does. Each DLL still loads on its own and a failing one is reported in the result instead of stopping the others; the WinForms MainForm shows the failures as before. New tests load a copy of the test assembly as a post plug-in beside a broken DLL: the broken one is reported, the good one's posts load and its materials are registered once each, ignoring case and blanks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
79 lines
3.0 KiB
C#
79 lines
3.0 KiB
C#
namespace OpenNest.Desktop.Tests;
|
|
|
|
/// <summary>
|
|
/// Post processors load from a Posts directory one DLL at a time: a DLL that fails is
|
|
/// reported and the others still load, and the materials they provide are registered.
|
|
/// </summary>
|
|
public sealed class PostProcessorLoaderTests : IDisposable
|
|
{
|
|
private readonly string directory = Path.Combine(Path.GetTempPath(), "OpenNestDesktopTests", Guid.NewGuid().ToString("N"));
|
|
|
|
public PostProcessorLoaderTests() => Directory.CreateDirectory(directory);
|
|
|
|
public void Dispose()
|
|
{
|
|
try { Directory.Delete(directory, recursive: true); } catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) { }
|
|
}
|
|
|
|
[Fact]
|
|
public void Load_IsolatesAFailingDllReportsItAndRegistersTheOthersMaterials()
|
|
{
|
|
// This test assembly is a post plug-in (it holds MaterialPost); the broken DLL is not .NET at all.
|
|
File.Copy(typeof(MaterialPost).Assembly.Location, Path.Combine(directory, "Good.Posts.dll"));
|
|
File.WriteAllText(Path.Combine(directory, "Broken.Posts.dll"), "not an assembly");
|
|
File.WriteAllText(Path.Combine(directory, "Readme.txt"), "ignored");
|
|
|
|
var result = PostProcessorLoader.Load(directory);
|
|
|
|
var failure = Assert.Single(result.Failures);
|
|
Assert.StartsWith("Broken.Posts.dll: ", failure);
|
|
Assert.Contains(result.PostProcessors, post => post.Name == MaterialPost.PostName);
|
|
Assert.Contains("Unobtainium", PostProcessorMaterials.Names, StringComparer.Ordinal);
|
|
Assert.Contains("aluminum 5052", PostProcessorMaterials.Names, StringComparer.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Load_WithoutAPostsDirectory_LoadsNothing()
|
|
{
|
|
var result = PostProcessorLoader.Load(Path.Combine(directory, "missing"));
|
|
|
|
Assert.Empty(result.PostProcessors);
|
|
Assert.Empty(result.Failures);
|
|
}
|
|
|
|
[Fact]
|
|
public void Materials_AreAddedOnceIgnoringCaseAndBlanksInNameOrder()
|
|
{
|
|
PostProcessorMaterials.AddFrom(new MaterialPost(["zz Order B", "ZZ ORDER a", " ", "zz order b"]));
|
|
|
|
var names = PostProcessorMaterials.Names.Where(n => n.StartsWith("zz", StringComparison.OrdinalIgnoreCase)).ToList();
|
|
Assert.Equal(["ZZ ORDER a", "zz Order B"], names);
|
|
Assert.DoesNotContain(" ", PostProcessorMaterials.Names);
|
|
}
|
|
|
|
internal sealed class MaterialPost : IPostProcessor, IMaterialProvidingPostProcessor
|
|
{
|
|
public const string PostName = "Material Test Post";
|
|
|
|
private readonly IReadOnlyList<string> materials;
|
|
|
|
public MaterialPost() : this(["Unobtainium", "aluminum 5052"])
|
|
{
|
|
}
|
|
|
|
public MaterialPost(IReadOnlyList<string> materials) => this.materials = materials;
|
|
|
|
public string Name => PostName;
|
|
|
|
public string Author => "Tests";
|
|
|
|
public string Description => "Provides materials.";
|
|
|
|
public IEnumerable<string> GetMaterialNames() => materials;
|
|
|
|
public void Post(Nest nest, Stream outputStream) { }
|
|
|
|
public void Post(Nest nest, string outputFile) { }
|
|
}
|
|
}
|