Files
OpenNest/OpenNest.Tests/Diagnostics/PostVerificationPostContractTests.cs
T
ajandClaude Opus 5.5 f9abab0c6d feat(verify): warn when parts leave the plate or its edge spacing
Validate Nest and the pre-post review checked overlaps and part-to-part
spacing but never the sheet itself, so a part dragged past the plate edge,
a lead-in piercing off the sheet, or a part inside the edge spacing could
post without a warning. Only Auto Nest's own layout check held parts to
the work area.

PlateEdgeReview adds two finding kinds:
- OffPlate: any cut, lead or scribe motion past the sheet, or clean
  material outside an outlined sheet or over one of its obstacles.
- EdgeSpacing: clean material (leads excluded) outside the work area, or
  closer than the largest edge spacing to an outline or obstacle - the
  bound Auto Nest's layout check applies, with SpacingSlack, so layouts it
  accepted stay clear.

Cut-off parts are exempt. Routing-replay test fixtures sit at the sheet
origin with leads hanging off it; their route assertions now ignore the
sheet-bound kinds, and the post-contract fixture moves onto the sheet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 08:59:23 -05:00

64 lines
2.4 KiB
C#

using OpenNest.CNC.CuttingStrategy;
using OpenNest.Diagnostics;
using OpenNest.Geometry;
using OpenNest.Posts.Cincinnati;
using OpenNest.Posts.CincinnatiCIFiber;
using OpenNest.Posts.GravographIS;
namespace OpenNest.Tests.Diagnostics;
public class PostVerificationPostContractTests
{
[Fact]
public void ReorderingPostRequiresAcknowledgmentEvenWhenNestChecksAreClear()
{
var nest = ClearNest();
Assert.False(PostVerificationAnalyzer.Analyze(nest).HasWarnings);
var post = new GravographISPostProcessor(new GravographISPostConfig());
var report = PostVerificationAnalyzer.AnalyzeForPost(nest, post);
Assert.Contains(report.Findings, finding => finding.Kind == PostVerificationKind.Incomplete);
Assert.False(report.CanPost(false));
Assert.True(report.CanPost(true));
Assert.Contains(post.Name, report.ToDisplayText());
}
[Fact]
public void CincinnatiClDeclaresPlacedOrderOnlyWhenThisNestPostsInIt()
{
var report = PostVerificationAnalyzer.AnalyzeForPost(ClearNest(),
new CincinnatiPostProcessor(new CincinnatiPostConfig()));
Assert.Empty(report.Findings);
Assert.True(report.CanPost(false));
var subprograms = PostVerificationAnalyzer.AnalyzeForPost(ClearNest(),
new CincinnatiPostProcessor(new CincinnatiPostConfig { UsePartSubprograms = true }));
Assert.Contains(subprograms.Findings, finding => finding.Kind == PostVerificationKind.Incomplete);
Assert.False(subprograms.CanPost(false));
}
[Fact]
public void CIFiberUsesPlacedOrderWithoutAnExtraOrderWarning()
{
var report = PostVerificationAnalyzer.AnalyzeForPost(ClearNest(),
new CIFiberPostProcessor(new CIFiberPostConfig()));
Assert.Empty(report.Findings);
Assert.True(report.CanPost(false));
}
private static Nest ClearNest()
{
var program = new OpenNest.CNC.Program();
program.MoveTo(0, 0);
program.LineTo(4, 0);
program.LineTo(4, 4);
program.LineTo(0, 4);
program.LineTo(0, 0);
var part = new Part(new Drawing("square", program), new Vector(5, 5));
part.ApplyLeadIns(new CuttingParameters { ExternalLeadIn = new LineLeadIn { Length = 0.5 } },
new Vector(-2, -2));
var nest = new Nest();
nest.CreatePlate().Parts.Add(part);
return nest;
}
}