using OpenNest.Engine.Strategies; using OpenNest.Geometry; namespace OpenNest.Tests.Strategies; public class FillPipelineTests { private static Drawing MakeRectDrawing(double w, double h, string name = "rect") { var pgm = new OpenNest.CNC.Program(); pgm.Codes.Add(new OpenNest.CNC.RapidMove(new Vector(0, 0))); pgm.Codes.Add(new OpenNest.CNC.LinearMove(new Vector(w, 0))); pgm.Codes.Add(new OpenNest.CNC.LinearMove(new Vector(w, h))); pgm.Codes.Add(new OpenNest.CNC.LinearMove(new Vector(0, h))); pgm.Codes.Add(new OpenNest.CNC.LinearMove(new Vector(0, 0))); return new Drawing(name, pgm); } [Fact] public void Pipeline_PopulatesPhaseResults() { var plate = new Plate(60, 120); var engine = new DefaultNestEngine(plate); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; engine.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None); Assert.True(engine.PhaseResults.Count >= FillStrategyRegistry.Strategies.Count, $"Expected phase results from all active strategies, got {engine.PhaseResults.Count}"); } [Fact] public void Pipeline_SetsWinnerPhase() { var plate = new Plate(60, 120); var engine = new DefaultNestEngine(plate); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; var parts = engine.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None); Assert.True(parts.Count > 0); Assert.True(engine.WinnerPhase == NestPhase.Pairs || engine.WinnerPhase == NestPhase.Linear || engine.WinnerPhase == NestPhase.RectBestFit || engine.WinnerPhase == NestPhase.Extents || engine.WinnerPhase == NestPhase.Custom); } [Fact] public void Pipeline_RespectsCancellation() { var plate = new Plate(60, 120); var engine = new DefaultNestEngine(plate); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; var cts = new System.Threading.CancellationTokenSource(); cts.Cancel(); // Pre-cancelled token should return empty or partial results without throwing var parts = engine.Fill(item, plate.WorkArea(), null, cts.Token); // Should not throw — graceful degradation Assert.NotNull(parts); } }