mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-03 18:11:36 -05:00
"Fill" said nothing about what the engine does, since every engine fills. It is now Lattice, and Fill stays an alias, so saved selections, scripts and API requests keep working. Engine descriptions are rewritten in plain language and shown beside each name in the desktop engine lists; the main toolbar's tooltip also says when Fill Area falls back to Lattice. Docs also cover the leftover placement from the previous commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
107 lines
4.2 KiB
C#
107 lines
4.2 KiB
C#
using System.ComponentModel;
|
|
using System.Reflection;
|
|
using System.Text.RegularExpressions;
|
|
using OpenNest.CNC;
|
|
using OpenNest.Engine.Jobs;
|
|
using OpenNest.Geometry;
|
|
using OpenNest.IO;
|
|
using OpenNest.Mcp;
|
|
using OpenNest.Mcp.Tools;
|
|
|
|
namespace OpenNest.FrontEnd.Tests;
|
|
|
|
/// <summary>Front ends that are not told an engine use Default; fill tools use Fill.</summary>
|
|
[Collection("FrontEndRegistry")]
|
|
public class DefaultEngineSelectionTests : IDisposable
|
|
{
|
|
private readonly string directory = Path.Combine(Path.GetTempPath(), "opennest-default-engine-" + Guid.NewGuid());
|
|
|
|
public DefaultEngineSelectionTests() => Directory.CreateDirectory(directory);
|
|
public void Dispose() => Directory.Delete(directory, true);
|
|
|
|
private static NestSession Session(bool occupied = false)
|
|
{
|
|
var shape = new Shape();
|
|
shape.Entities.Add(new Line(new Vector(0, 0), new Vector(2, 0)));
|
|
shape.Entities.Add(new Line(new Vector(2, 0), new Vector(2, 2)));
|
|
shape.Entities.Add(new Line(new Vector(2, 2), new Vector(0, 2)));
|
|
shape.Entities.Add(new Line(new Vector(0, 2), new Vector(0, 0)));
|
|
var session = new NestSession { Nest = new Nest("fixture") };
|
|
session.Nest.Drawings.Add(new Drawing("square", OpenNest.Converters.ConvertGeometry.ToProgram(shape)));
|
|
var plate = session.Nest.CreatePlate();
|
|
plate.Size = new Size(20, 30);
|
|
plate.PartSpacing = 0.2;
|
|
plate.EdgeSpacing = new Spacing(0.5, 0.5, 0.5, 0.5);
|
|
if (occupied) // The nest writer keeps only plates that hold parts; autonest replaces them.
|
|
plate.Parts.Add(new Part(session.Nest.Drawings.Single()));
|
|
return session;
|
|
}
|
|
|
|
[Fact]
|
|
public void McpAutonestWithoutAnEngineUsesDefault()
|
|
{
|
|
var session = Session();
|
|
|
|
var response = new NestingTools(session).AutoNestPlate(0, "square", "2");
|
|
|
|
Assert.Contains("(Default engine): success", response);
|
|
Assert.Equal(2, session.GetPlate(0).Parts.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public void McpFillToolsWithoutAnEngineUseLattice()
|
|
{
|
|
var session = Session();
|
|
session.DefaultEngineName = "Rectangles"; // The session default is for autonest only.
|
|
|
|
var response = new NestingTools(session).FillPlate(0, "square", 2);
|
|
|
|
Assert.Contains("(Lattice): success", response);
|
|
Assert.Equal(2, session.GetPlate(0).Parts.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public void McpAutonestEngineDescriptionNamesEveryBuiltInEngine()
|
|
{
|
|
var engine = typeof(NestingTools).GetMethod(nameof(NestingTools.AutoNestPlate))!
|
|
.GetParameters().Single(p => p.Name == "engine");
|
|
var description = engine.GetCustomAttribute<DescriptionAttribute>()!.Description;
|
|
var builtIns = NestingEngineRegistry.AvailableEngines
|
|
.Where(e => e.Factory().GetType().Assembly == typeof(NestingEngineRegistry).Assembly)
|
|
.Select(e => e.Name)
|
|
.ToList();
|
|
|
|
Assert.Contains("Default", builtIns);
|
|
Assert.All(builtIns, name => Assert.Matches(@"\b" + Regex.Escape(name) + @"\b", description));
|
|
Assert.StartsWith("Whole-job engine. Default (used when omitted)", description);
|
|
}
|
|
|
|
[Fact]
|
|
public void ConsoleAutonestWithoutAnEngineUsesDefault()
|
|
{
|
|
var input = Path.Combine(directory, "input.nest");
|
|
var output = Path.Combine(directory, "output.nest");
|
|
Assert.True(new NestWriter(Session(occupied: true).Nest).Write(input));
|
|
var method = Assembly.Load("OpenNest.Console").GetType("NestConsole")!
|
|
.GetMethod("Run", BindingFlags.Static | BindingFlags.Public)!;
|
|
var (originalOut, originalError) = (Console.Out, Console.Error);
|
|
using var captured = new StringWriter();
|
|
int exit;
|
|
try
|
|
{
|
|
Console.SetOut(captured);
|
|
Console.SetError(captured);
|
|
exit = (int)method.Invoke(null, new object[] { new[] { input, "--autonest", "--quantity", "2", "--output", output } })!;
|
|
}
|
|
finally
|
|
{
|
|
Console.SetOut(originalOut);
|
|
Console.SetError(originalError);
|
|
}
|
|
|
|
Assert.True(exit == 0, captured.ToString());
|
|
Assert.Contains("Engine: Default", captured.ToString());
|
|
Assert.Equal(2, Assert.Single(new NestReader(output).Read().Plates).Parts.Count);
|
|
}
|
|
}
|