Files
OpenNest/OpenNest.Tests/Diagnostics/OverlapPairPresentationTests.cs
T
ajandClaude Opus 5.5 f0d84e041c test: share the circle, square, rectangle and contour fixtures
Cutting-planning, diagnostics and fill tests drew the same circles,
squares, clockwise rectangles, closed polygons, rounded rectangles and
right-midpoint rectangle contours in private helpers. They now use
TestHelpers; files whose helper had its own default size keep a
one-line wrapper for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:50:50 -05:00

74 lines
3.0 KiB
C#

using System.Globalization;
using OpenNest.CNC;
using OpenNest.Diagnostics;
using OpenNest.Geometry;
using static OpenNest.Tests.TestHelpers;
namespace OpenNest.Tests.Diagnostics;
public class OverlapPairPresentationTests
{
[Theory]
[InlineData(Units.Inches, "in")]
[InlineData(Units.Millimeters, "mm")]
public void DetailsUseCapturedNamesSequenceIdsAndSuppliedUnits(Units units, string symbol)
{
var parts = new[]
{
MakeSquarePart("cutoff"), MakeSquarePart("left"), MakeSquarePart("right"),
};
parts[0].BaseDrawing.IsCutOff = true;
var snapshot = PlateOverlapAnalyzer.Capture(parts);
parts[1].BaseDrawing.Name = "changed";
var pair = Assert.Single(PlateOverlapAnalyzer.Analyze(snapshot).Pairs);
Assert.Equal("2/3", OverlapPairPresentation.Label(pair));
var text = OverlapPairPresentation.Details(pair, units, CultureInfo.InvariantCulture);
Assert.Equal($"Pair 2/3: left / right\nShared area ≈ 16 {symbol}²\nMarker: (2, 2) {symbol}", text);
}
[Theory]
[InlineData(1e-15)]
[InlineData(1e-100)]
[InlineData(double.Epsilon)]
[InlineData(0.000000123456)]
public void PositiveTinyValuesNeverFormatAsZero(double value)
{
var text = OverlapPairPresentation.Number(value, CultureInfo.InvariantCulture);
Assert.True(double.Parse(text, CultureInfo.InvariantCulture) > 0, text);
}
[Theory]
[InlineData(96, 1)]
[InlineData(144, 1.5)]
[InlineData(192, 2)]
public void HitRadiusIsScreenSizedDpiScaledAndInclusive(int dpi, double factor)
{
Assert.Equal(6 * factor, OverlapPairPresentation.MarkerHalfSize(dpi));
Assert.Equal(10 * factor, OverlapPairPresentation.HitRadius(dpi));
var pairs = PlateOverlapAnalyzer.Analyze(
new[] { MakeSquarePart("a"), MakeSquarePart("b") }).Pairs;
foreach (var zoom in new[] { 0.5, 20.0, 500.0 })
{
Vector ToScreen(Vector world) => new(100 + world.X * zoom, 200 - world.Y * zoom);
var center = ToScreen(pairs[0].Marker);
var radius = OverlapPairPresentation.HitRadius(dpi);
Assert.Single(OverlapPairPresentation.HitTest(pairs, ToScreen,
center + new Vector(radius, 0), dpi));
Assert.Empty(OverlapPairPresentation.HitTest(pairs, ToScreen,
center + new Vector(radius + 0.01, 0), dpi));
Assert.Empty(OverlapPairPresentation.HitTest(pairs, ToScreen,
center + new Vector(radius, radius), dpi));
}
}
[Fact]
public void CoincidentMarkersReturnEveryPairInIdOrderNotFragmentOrder()
{
var pairs = PlateOverlapAnalyzer.Analyze(
new[] { MakeSquarePart("a"), MakeSquarePart("b"), MakeSquarePart("c") }).Pairs;
var hits = OverlapPairPresentation.HitTest(pairs.Reverse(), p => p, new Vector(2, 2), 96);
Assert.Equal(new[] { "1/2", "1/3", "2/3" }, hits.Select(OverlapPairPresentation.Label));
Assert.All(hits, p => Assert.Single(p.Regions)); // One island per coincident pair.
}
}