test: share the rectangle drawing fixture

Thirteen test classes built the same origin-anchored rectangle drawing in
their own private helper (MakeRectDrawing, MakeRect or Rect). They now
call TestHelpers.MakeRectDrawing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ajandClaude Opus 5.5 committed 2026-11-01 10:21:27 -05:00
1 parent 24169a5f8f
commit bdd6625713
14 files changed
+86 -217

No files matched your search

@@ -20,7 +20,7 @@ public class BenchmarkScoringTests
public void SharedCostEqualsBenchmarkRunForEveryEdgeAndUnplacedParts(
double rate, double x, double y, double salvage)
{
var benchmarkJob = Job(0.5, (Rect(10, 5), 3));
var benchmarkJob = Job(0.5, (TestHelpers.MakeRectDrawing(10, 5), 3));
NestJob? capturedJob = null;
NestJobResult? capturedResult = null;
var engine = Engine("Shared cost parity", job =>
@@ -97,7 +97,7 @@ public class BenchmarkScoringTests
[Fact]
public void Run_RotationOutsideConstraint_IsInvalid()
{
var part = Rect(10, 5);
var part = TestHelpers.MakeRectDrawing(10, 5);
LockRotation(part);
var job = Job(0.5, (part, 1));
@@ -112,7 +112,7 @@ public class BenchmarkScoringTests
[Fact]
public void Run_StockWithLoosenedSpacing_IsInvalid()
{
var job = Job(0.5, (Rect(10, 5), 1));
var job = Job(0.5, (TestHelpers.MakeRectDrawing(10, 5), 1));
var result = RunSingle(
job,
@@ -134,7 +134,7 @@ public class BenchmarkScoringTests
[Fact]
public void Run_PartInsideAnotherPartsCutout_IsValidWhenItClearsTheEdge()
{
var job = Job(0.5, (Frame(), 1), (Rect(4, 4), 1));
var job = Job(0.5, (Frame(), 1), (TestHelpers.MakeRectDrawing(4, 4), 1));
var clear = RunSingle(
job,
@@ -154,7 +154,7 @@ public class BenchmarkScoringTests
[Fact]
public void Run_OverlappingNeighbors_AreStillCaughtBySweep()
{
var job = Job(0.5, (Rect(10, 5), 3));
var job = Job(0.5, (TestHelpers.MakeRectDrawing(10, 5), 3));
var result = RunSingle(
job,
@@ -173,7 +173,7 @@ public class BenchmarkScoringTests
[Fact]
public void Run_WithSalvageCredit_CompactLayoutOutscoresScatteredLayout()
{
var job = Job(0.5, (Rect(10, 5), 2));
var job = Job(0.5, (TestHelpers.MakeRectDrawing(10, 5), 2));
var engines = new List<NestingEngineInfo>
{
Engine("Compact", j => Sheet(j, (j.Parts[0].Id, 0, 0, 0), (j.Parts[0].Id, 0, 10, 0))),
@@ -234,17 +234,6 @@ public class BenchmarkScoringTests
PlatesUsed = 1,
};
private static Drawing Rect(double w, double h)
{
var pgm = new OpenNest.CNC.Program();
pgm.Codes.Add(new RapidMove(new Vector(0, 0)));
pgm.Codes.Add(new LinearMove(new Vector(w, 0)));
pgm.Codes.Add(new LinearMove(new Vector(w, h)));
pgm.Codes.Add(new LinearMove(new Vector(0, h)));
pgm.Codes.Add(new LinearMove(new Vector(0, 0)));
return new Drawing("rect", pgm);
}
/// <summary>20x20 square with a 10x10 cutout centerd in it.</summary>
private static Drawing Frame()
{
+1 -12
View File
@@ -96,7 +96,7 @@ public class ClampZoneTests
for (var i = 0; i < 8; i++)
plate.ClampZones.Add(new ClampZone($"clamp-{i}", new Box(i * 2.0, 0, 1.5, 0.625)));
var drawing = MakeRectDrawing(10, 5);
var drawing = TestHelpers.MakeRectDrawing(10, 5);
drawing.Quantity.Required = 4;
var part = new Part(drawing);
plate.Parts.Add(part);
@@ -119,15 +119,4 @@ public class ClampZoneTests
Assert.Empty(plate.Parts);
Assert.DoesNotContain(plate.ClampZones, z => ReferenceEquals(z, null));
}
private static Drawing MakeRectDrawing(double length, double width)
{
var pgm = new Program();
pgm.Codes.Add(new RapidMove(new Vector(0, 0)));
pgm.Codes.Add(new LinearMove(new Vector(length, 0)));
pgm.Codes.Add(new LinearMove(new Vector(length, width)));
pgm.Codes.Add(new LinearMove(new Vector(0, width)));
pgm.Codes.Add(new LinearMove(new Vector(0, 0)));
return new Drawing("rect", pgm);
}
}
+3 -14
View File
@@ -11,17 +11,6 @@ public class CanonicalAngleTests
{
private const double AngleTol = 0.002; // ~0.11°
private static Drawing MakeRect(double w, double h)
{
var pgm = new OpenNest.CNC.Program();
pgm.Codes.Add(new RapidMove(new Vector(0, 0)));
pgm.Codes.Add(new LinearMove(new Vector(w, 0)));
pgm.Codes.Add(new LinearMove(new Vector(w, h)));
pgm.Codes.Add(new LinearMove(new Vector(0, h)));
pgm.Codes.Add(new LinearMove(new Vector(0, 0)));
return new Drawing("rect", pgm);
}
private static Drawing RotateCopy(Drawing src, double angle)
{
var pgm = src.Program.Clone() as OpenNest.CNC.Program;
@@ -32,7 +21,7 @@ public class CanonicalAngleTests
[Fact]
public void AxisAlignedRectangle_ReturnsZero()
{
var d = MakeRect(100, 50);
var d = TestHelpers.MakeRectDrawing(100, 50);
Assert.Equal(0.0, CanonicalAngle.Compute(d), precision: 6);
}
@@ -59,7 +48,7 @@ public class CanonicalAngleTests
[InlineData(1.2)]
public void Rectangle_ReturnsNegatedRotation_Modulo90(double theta)
{
var rotated = RotateCopy(MakeRect(100, 50), theta);
var rotated = RotateCopy(TestHelpers.MakeRectDrawing(100, 50), theta);
var angle = CanonicalAngle.Compute(rotated);
// Applying the returned angle should leave MBR axis-aligned.
@@ -76,7 +65,7 @@ public class CanonicalAngleTests
[Fact]
public void NearZeroInput_SnapsToZero()
{
var rotated = RotateCopy(MakeRect(100, 50), 0.0005);
var rotated = RotateCopy(TestHelpers.MakeRectDrawing(100, 50), 0.0005);
Assert.Equal(0.0, CanonicalAngle.Compute(rotated), precision: 6);
}
@@ -6,23 +6,12 @@ namespace OpenNest.Tests.Engine;
public class EngineRefactorSmokeTests
{
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 PlateFiller_FillNestItem_ProducesResults()
{
var plate = new Plate(60, 120);
var filler = new PlateFiller(plate);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var parts = filler.Fill(
item,
@@ -39,7 +28,7 @@ public class EngineRefactorSmokeTests
{
var plate = new Plate(60, 120);
var filler = new PlateFiller(plate);
var drawing = MakeRectDrawing(20, 10);
var drawing = TestHelpers.MakeRectDrawing(20, 10);
var groupParts = new List<Part> { new Part(drawing) };
var parts = filler.Fill(
@@ -58,7 +47,7 @@ public class EngineRefactorSmokeTests
var plate = new Plate(60, 120);
var filler = new PlateFiller(plate);
filler.ForceFullAngleSweep = true;
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var parts = filler.Fill(
item,
@@ -77,7 +66,7 @@ public class EngineRefactorSmokeTests
{
var plate = new Plate(60, 120) { PartSpacing = 0.5 };
var filler = new PlateFiller(plate) { StopAtQuantity = stopAtQuantity };
var item = new NestItem { Drawing = MakeRectDrawing(7, 3), Quantity = 23 };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(7, 3), Quantity = 23 };
var parts = filler.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None);
@@ -98,8 +87,8 @@ public class EngineRefactorSmokeTests
var filler = new PlateFiller(plate, PlateFillPolicy.Fill, PlateLayout.Strips);
var items = new List<NestItem>
{
new NestItem { Drawing = MakeRectDrawing(20, 10, "large"), Quantity = 10 },
new NestItem { Drawing = MakeRectDrawing(8, 5, "small"), Quantity = 5 },
new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10, "large"), Quantity = 10 },
new NestItem { Drawing = TestHelpers.MakeRectDrawing(8, 5, "small"), Quantity = 5 },
};
var parts = filler.Nest(items, null, System.Threading.CancellationToken.None);
@@ -114,8 +103,8 @@ public class EngineRefactorSmokeTests
var filler = new PlateFiller(plate);
var items = new List<NestItem>
{
new NestItem { Drawing = MakeRectDrawing(20, 10, "a"), Quantity = 5 },
new NestItem { Drawing = MakeRectDrawing(15, 8, "b"), Quantity = 3 },
new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10, "a"), Quantity = 5 },
new NestItem { Drawing = TestHelpers.MakeRectDrawing(15, 8, "b"), Quantity = 3 },
};
var parts = filler.Nest(items, null, System.Threading.CancellationToken.None);
@@ -127,7 +116,7 @@ public class EngineRefactorSmokeTests
public void BruteForceRunner_StillWorks()
{
var plate = new Plate(60, 120);
var drawing = MakeRectDrawing(20, 10);
var drawing = TestHelpers.MakeRectDrawing(20, 10);
var result = OpenNest.Engine.ML.BruteForceRunner.Run(
drawing,
@@ -11,17 +11,6 @@ namespace OpenNest.Tests.Engine;
/// </summary>
public class ExplicitPlacementStrategyTests
{
private static Drawing MakeRectDrawing(double w, double h, string name = "rect")
{
var pgm = new Program();
pgm.Codes.Add(new RapidMove(new Vector(0, 0)));
pgm.Codes.Add(new LinearMove(new Vector(w, 0)));
pgm.Codes.Add(new LinearMove(new Vector(w, h)));
pgm.Codes.Add(new LinearMove(new Vector(0, h)));
pgm.Codes.Add(new LinearMove(new Vector(0, 0)));
return new Drawing(name, pgm);
}
[Theory]
[InlineData(null)]
[InlineData("")]
@@ -51,7 +40,7 @@ public class ExplicitPlacementStrategyTests
public void PlateFillService_Nest_ResolvesNamedStrategyAndRejectsUnknown()
{
var plate = new Plate(new Size(60, 80));
var drawing = MakeRectDrawing(6, 4, "part");
var drawing = TestHelpers.MakeRectDrawing(6, 4, "part");
var parts = PlateFillService.Nest(
"Vertical Remnant",
+1 -12
View File
@@ -10,23 +10,12 @@ public class PartClassifierTests
{
// ── helpers ──────────────────────────────────────────────────────────────
private static Drawing MakeRectDrawing(double w, double h)
{
var pgm = new OpenNest.CNC.Program();
pgm.Codes.Add(new RapidMove(new Vector(0, 0)));
pgm.Codes.Add(new LinearMove(new Vector(w, 0)));
pgm.Codes.Add(new LinearMove(new Vector(w, h)));
pgm.Codes.Add(new LinearMove(new Vector(0, h)));
pgm.Codes.Add(new LinearMove(new Vector(0, 0)));
return new Drawing("rect", pgm);
}
// ── tests ─────────────────────────────────────────────────────────────────
[Fact]
public void Classify_PureRectangle_ReturnsRectangle()
{
var drawing = MakeRectDrawing(100, 50);
var drawing = TestHelpers.MakeRectDrawing(100, 50);
var result = PartClassifier.Classify(drawing);
Assert.Equal(PartType.Rectangle, result.Type);
+3 -14
View File
@@ -8,17 +8,6 @@ namespace OpenNest.Tests.Engine;
public class RemnantEngineTests
{
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 VerticalRemnantPlateFiller_UsesHorizontalPreferredDirection()
{
@@ -40,7 +29,7 @@ public class RemnantEngineTests
{
var plate = new Plate(60, 120);
var filler = new PlateFiller(plate, PlateFillPolicy.VerticalRemnant);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var parts = filler.Fill(
item,
@@ -57,7 +46,7 @@ public class RemnantEngineTests
{
var plate = new Plate(60, 120);
var filler = new PlateFiller(plate, PlateFillPolicy.HorizontalRemnant);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var parts = filler.Fill(
item,
@@ -80,7 +69,7 @@ public class RemnantEngineTests
public void VerticalRemnantPlateFiller_ProducesTighterXExtent_ThanDefault()
{
var plate = new Plate(60, 120);
var drawing = MakeRectDrawing(20, 10);
var drawing = TestHelpers.MakeRectDrawing(20, 10);
var item = new NestItem { Drawing = drawing };
var defaultFiller = new PlateFiller(plate);
@@ -10,17 +10,6 @@ namespace OpenNest.Tests.Fill;
[Collection(nameof(OpenNest.Tests.BestFit.FillCacheCollection))]
public class AngleCandidateBuilderTests
{
private static Drawing MakeRectDrawing(double w, double h)
{
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("rect", pgm);
}
private static ClassificationResult MakeClassification(
double primaryAngle = 0,
PartType type = PartType.Irregular
@@ -32,7 +21,7 @@ public class AngleCandidateBuilderTests
public void Characterization_ClassifiedParts_PreserveExactBaseAngleOrder(PartType type)
{
var builder = new AngleCandidateBuilder();
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var primary = Angle.ToRadians(7);
var angles = builder.Build(item, MakeClassification(primary, type), new Box(0, 0, 100, 50));
@@ -50,7 +39,7 @@ public class AngleCandidateBuilderTests
var builder = new AngleCandidateBuilder();
var item = new NestItem
{
Drawing = MakeRectDrawing(20, 10),
Drawing = TestHelpers.MakeRectDrawing(20, 10),
RotationStart = 0,
RotationEnd = Angle.HalfPI,
StepAngle = Angle.ToRadians(30),
@@ -69,7 +58,7 @@ public class AngleCandidateBuilderTests
var builder = new AngleCandidateBuilder();
var item = new NestItem
{
Drawing = MakeRectDrawing(20, 10),
Drawing = TestHelpers.MakeRectDrawing(20, 10),
RotationStart = Angle.ToRadians(10),
RotationEnd = Angle.ToRadians(20),
StepAngle = step,
@@ -86,7 +75,7 @@ public class AngleCandidateBuilderTests
var builder = new AngleCandidateBuilder();
var item = new NestItem
{
Drawing = MakeRectDrawing(20, 10),
Drawing = TestHelpers.MakeRectDrawing(20, 10),
RotationStart = Angle.ToRadians(40),
RotationEnd = Angle.ToRadians(10),
};
@@ -109,7 +98,7 @@ public class AngleCandidateBuilderTests
new() { AngleDeg = 65, PartCount = 0 },
new() { AngleDeg = 120, PartCount = -1 },
});
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var angles = builder.Build(item, MakeClassification(Angle.ToRadians(7)), new Box(0, 0, 100, 50));
@@ -170,7 +159,7 @@ public class AngleCandidateBuilderTests
{
var calls = new PredictionCalls { Available = false };
var builder = calls.CreateBuilder();
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var angles = builder.Build(item, MakeClassification(Angle.ToRadians(7)), new Box(0, 0, 100, 50));
@@ -183,7 +172,7 @@ public class AngleCandidateBuilderTests
{
var calls = new PredictionCalls();
var builder = calls.CreateBuilder();
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var workArea = new Box(3, 5, 123, 47);
var angles = builder.Build(item, MakeClassification(Angle.ToRadians(7)), workArea);
@@ -203,7 +192,7 @@ public class AngleCandidateBuilderTests
{
var calls = new PredictionCalls { Features = null };
var builder = calls.CreateBuilder();
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var angles = builder.Build(item, MakeClassification(Angle.ToRadians(7)), new Box(0, 0, 100, 50));
@@ -219,7 +208,7 @@ public class AngleCandidateBuilderTests
{
var calls = new PredictionCalls { Prediction = empty ? new List<double>() : null };
var builder = calls.CreateBuilder();
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var angles = builder.Build(item, MakeClassification(Angle.ToRadians(7)), new Box(0, 0, 100, 50));
@@ -239,7 +228,7 @@ public class AngleCandidateBuilderTests
var original = predicted.ToArray();
var calls = new PredictionCalls { Prediction = predicted };
var builder = calls.CreateBuilder();
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var angles = builder.Build(item, MakeClassification(Angle.ToRadians(7)), new Box(0, 0, 100, 50));
@@ -263,7 +252,7 @@ public class AngleCandidateBuilderTests
var original = predicted.ToArray();
var calls = new PredictionCalls { Prediction = predicted };
var builder = calls.CreateBuilder();
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var angles = builder.Build(item, MakeClassification(primary), new Box(0, 0, 100, 50));
@@ -280,7 +269,7 @@ public class AngleCandidateBuilderTests
public void Build_Unavailable_WithCardinalBase_DeduplicatesSweepWithoutReordering()
{
var calls = new PredictionCalls { Available = false };
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var angles = calls.CreateBuilder().Build(item, MakeClassification(), new Box(0, 0, 100, 50));
@@ -302,7 +291,7 @@ public class AngleCandidateBuilderTests
{
var calls = new PredictionCalls();
var builder = calls.CreateBuilder();
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var classification = MakeClassification(Angle.ToRadians(7));
var expected = new[] { 7.0, 97, 45 };
if (branch.EndsWith("circle"))
@@ -340,7 +329,7 @@ public class AngleCandidateBuilderTests
var builder = calls.CreateBuilder();
builder.ForceFullSweep = true;
builder.RecordProductive(new List<AngleResult> { new() { AngleDeg = 45, PartCount = 1 } });
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var angles = builder.Build(item, MakeClassification(Angle.ToRadians(7)), new Box(0, 0, 100, 50));
@@ -358,7 +347,7 @@ public class AngleCandidateBuilderTests
new() { AngleDeg = 45, PartCount = 0 },
new() { AngleDeg = 60, PartCount = -1 },
});
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var angles = builder.Build(item, MakeClassification(Angle.ToRadians(7)), new Box(0, 0, 100, 50));
@@ -386,7 +375,7 @@ public class AngleCandidateBuilderTests
predictedFeatures = features;
return null!;
});
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
PerfCounters.Reset();
try
@@ -411,7 +400,7 @@ public class AngleCandidateBuilderTests
public void Build_ReturnsAtLeastTwoAngles()
{
var builder = new AngleCandidateBuilder();
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var workArea = new Box(0, 0, 100, 100);
var angles = builder.Build(item, MakeClassification(), workArea);
@@ -423,7 +412,7 @@ public class AngleCandidateBuilderTests
public void Build_RectangleType_NarrowWorkArea_UsesBaseAnglesOnly()
{
var builder = new AngleCandidateBuilder();
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var narrowArea = new Box(0, 0, 100, 8); // narrower than part's longest side
var angles = builder.Build(item, MakeClassification(0, PartType.Rectangle), narrowArea);
@@ -436,7 +425,7 @@ public class AngleCandidateBuilderTests
public void ForceFullSweep_ProducesFullSweep()
{
var builder = new AngleCandidateBuilder { ForceFullSweep = true };
var item = new NestItem { Drawing = MakeRectDrawing(5, 5) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(5, 5) };
var workArea = new Box(0, 0, 100, 100);
var angles = builder.Build(item, MakeClassification(), workArea);
@@ -449,7 +438,7 @@ public class AngleCandidateBuilderTests
public void RecordProductive_PrunesSubsequentBuilds()
{
var builder = new AngleCandidateBuilder { ForceFullSweep = true };
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var workArea = new Box(0, 0, 100, 8);
// First build — full sweep
@@ -477,7 +466,7 @@ public class AngleCandidateBuilderTests
public void Build_RectanglePart_ReturnsTwoAngles()
{
var builder = new AngleCandidateBuilder();
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var workArea = new Box(0, 0, 100, 100);
var classification = MakeClassification(0, PartType.Rectangle);
@@ -490,7 +479,7 @@ public class AngleCandidateBuilderTests
public void Build_CirclePart_ReturnsOneAngle()
{
var builder = new AngleCandidateBuilder();
var item = new NestItem { Drawing = MakeRectDrawing(10, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(10, 10) };
var workArea = new Box(0, 0, 100, 100);
var classification = MakeClassification(0, PartType.Circle);
@@ -506,7 +495,7 @@ public class AngleCandidateBuilderTests
var builder = new AngleCandidateBuilder();
var item = new NestItem
{
Drawing = MakeRectDrawing(100, 50),
Drawing = TestHelpers.MakeRectDrawing(100, 50),
RotationStart = Angle.ToRadians(10),
RotationEnd = Angle.ToRadians(90),
StepAngle = Angle.ToRadians(10),
@@ -528,7 +517,7 @@ public class AngleCandidateBuilderTests
var builder = new AngleCandidateBuilder();
var item = new NestItem
{
Drawing = MakeRectDrawing(100, 50),
Drawing = TestHelpers.MakeRectDrawing(100, 50),
RotationStart = 0,
RotationEnd = System.Math.PI,
StepAngle = Angle.ToRadians(45),
+5 -16
View File
@@ -91,20 +91,9 @@ namespace OpenNest.Tests.Fill
);
}
private static Drawing MakeRectDrawing(double w, double h)
{
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("rect", pgm);
}
private static Part MakeRectPart(double x, double y, double w, double h)
{
var drawing = MakeRectDrawing(w, h);
var drawing = TestHelpers.MakeRectDrawing(w, h);
var part = new Part(drawing) { Location = new Vector(x, y) };
part.UpdateBounds();
return part;
@@ -232,9 +221,9 @@ namespace OpenNest.Tests.Fill
public void Push_RotatedParts_PreservesSpacingOnRepeatedPushes(double degrees)
{
var angle = OpenNest.Math.Angle.ToRadians(degrees);
var obstacle = Part.CreateAtOrigin(MakeRectDrawing(10, 10), angle);
var obstacle = Part.CreateAtOrigin(TestHelpers.MakeRectDrawing(10, 10), angle);
obstacle.Offset(20, 20);
var moving = Part.CreateAtOrigin(MakeRectDrawing(10, 10), angle);
var moving = Part.CreateAtOrigin(TestHelpers.MakeRectDrawing(10, 10), angle);
moving.Offset(60, 20);
var parts = new List<Part> { moving };
var obstacles = new List<Part> { obstacle };
@@ -261,7 +250,7 @@ namespace OpenNest.Tests.Fill
{
var obstacle = MakeRectPart(20, 20, 10, 10);
var moving = Part.CreateAtOrigin(
MakeRectDrawing(10, 10),
TestHelpers.MakeRectDrawing(10, 10),
OpenNest.Math.Angle.ToRadians(degrees)
);
moving.Offset(60, 31);
@@ -363,7 +352,7 @@ namespace OpenNest.Tests.Fill
[InlineData(2, true)]
public void Push_InsideStationaryHole_CannotPassThroughItsWall(double spacing, bool plateEntry)
{
var program = MakeRectDrawing(60, 60).Program;
var program = TestHelpers.MakeRectDrawing(60, 60).Program;
program.Codes.Add(new OpenNest.CNC.RapidMove(new Vector(10, 10)));
program.Codes.Add(new OpenNest.CNC.LinearMove(new Vector(50, 10)));
program.Codes.Add(new OpenNest.CNC.LinearMove(new Vector(50, 50)));
@@ -32,21 +32,10 @@ public class IterativeShrinkFillerTests
Assert.Empty(result.Leftovers);
}
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 Fill_SingleItem_PlacesParts()
{
var drawing = MakeRectDrawing(20, 10);
var drawing = TestHelpers.MakeRectDrawing(20, 10);
var items = new List<NestItem>
{
new NestItem { Drawing = drawing, Quantity = 5 },
@@ -69,8 +58,8 @@ public class IterativeShrinkFillerTests
{
var items = new List<NestItem>
{
new NestItem { Drawing = MakeRectDrawing(20, 10, "large"), Quantity = 5 },
new NestItem { Drawing = MakeRectDrawing(8, 5, "small"), Quantity = 5 },
new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10, "large"), Quantity = 5 },
new NestItem { Drawing = TestHelpers.MakeRectDrawing(8, 5, "small"), Quantity = 5 },
};
Func<NestItem, Box, List<Part>> fillFunc = (ni, b) =>
@@ -95,7 +84,7 @@ public class IterativeShrinkFillerTests
// Huge quantity that can't all fit on a small plate
var items = new List<NestItem>
{
new NestItem { Drawing = MakeRectDrawing(20, 10), Quantity = 1000 },
new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10), Quantity = 1000 },
};
Func<NestItem, Box, List<Part>> fillFunc = (ni, b) =>
@@ -117,7 +106,7 @@ public class IterativeShrinkFillerTests
{
var items = new List<NestItem>
{
new NestItem { Drawing = MakeRectDrawing(20, 10), Quantity = 0 },
new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10), Quantity = 0 },
};
Func<NestItem, Box, List<Part>> fillFunc = (ni, b) =>
@@ -141,7 +130,7 @@ public class IterativeShrinkFillerTests
var items = new List<NestItem>
{
new NestItem { Drawing = MakeRectDrawing(20, 10), Quantity = 10 },
new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10), Quantity = 10 },
};
Func<NestItem, Box, List<Part>> fillFunc = (ni, b) =>
+3 -14
View File
@@ -6,17 +6,6 @@ namespace OpenNest.Tests.Fill;
public class PairFillerTests
{
private static Drawing MakeRectDrawing(double w, double h)
{
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("rect", pgm);
}
private static Plate MakePlate(double width, double length, double spacing = 0.5)
{
return new Plate { Size = new Size(width, length), PartSpacing = spacing };
@@ -26,7 +15,7 @@ public class PairFillerTests
public void Fill_ReturnsPartsForSimpleDrawing()
{
var filler = new PairFiller(MakePlate(120, 60));
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var workArea = new Box(0, 0, 120, 60);
var result = filler.Fill(item, workArea);
@@ -39,7 +28,7 @@ public class PairFillerTests
public void Fill_EmptyResult_WhenPartTooLarge()
{
var filler = new PairFiller(MakePlate(10, 10));
var item = new NestItem { Drawing = MakeRectDrawing(20, 20) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 20) };
var workArea = new Box(0, 0, 10, 10);
var result = filler.Fill(item, workArea);
@@ -55,7 +44,7 @@ public class PairFillerTests
cts.Cancel();
var filler = new PairFiller(MakePlate(120, 60));
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var workArea = new Box(0, 0, 120, 60);
var result = filler.Fill(item, workArea, token: cts.Token);
+7 -18
View File
@@ -11,23 +11,12 @@ 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 filler = new PlateFiller(plate);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
filler.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None);
@@ -42,7 +31,7 @@ public class FillPipelineTests
{
var plate = new Plate(60, 120);
var filler = new PlateFiller(plate);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var parts = filler.Fill(
item,
@@ -66,7 +55,7 @@ public class FillPipelineTests
{
var plate = new Plate(60, 120);
var filler = new PlateFiller(plate);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var cts = new System.Threading.CancellationTokenSource();
cts.Cancel();
@@ -82,7 +71,7 @@ public class FillPipelineTests
{
var plate = new Plate(60, 120);
var filler = new PlateFiller(plate);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var reports = new List<NestProgress>();
filler.Fill(item, plate.WorkArea(), new SyncProgress(reports.Add), CancellationToken.None);
@@ -98,7 +87,7 @@ public class FillPipelineTests
{
var plate = new Plate(60, 120);
var filler = new PlateFiller(plate);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var reports = new List<NestProgress>();
filler.Fill(item, plate.WorkArea(), new SyncProgress(reports.Add), CancellationToken.None);
@@ -114,7 +103,7 @@ public class FillPipelineTests
{
var plate = new Plate(60, 120);
var filler = new PlateFiller(plate);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
using var cts = new CancellationTokenSource();
NestProgress first = null;
@@ -138,7 +127,7 @@ public class FillPipelineTests
{
var plate = new Plate(60, 120);
var filler = new PlateFiller(plate);
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var item = new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10) };
var shown = new List<int>();
filler.Fill(
+5 -16
View File
@@ -9,20 +9,9 @@ namespace OpenNest.Tests.Strategies;
public class StripeFillerTests
{
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);
}
private static Pattern MakeRectPattern(double w, double h)
{
var drawing = MakeRectDrawing(w, h);
var drawing = TestHelpers.MakeRectDrawing(w, h);
var part = Part.CreateAtOrigin(drawing);
var pattern = new Pattern();
pattern.Parts.Add(part);
@@ -162,7 +151,7 @@ public class StripeFillerTests
public void Fill_ProducesNonOverlappingPartsForSimpleDrawing()
{
var plate = new Plate(60, 120) { PartSpacing = 0.5 };
var drawing = MakeRectDrawing(20, 10);
var drawing = TestHelpers.MakeRectDrawing(20, 10);
var item = new NestItem { Drawing = drawing };
var workArea = new Box(0, 0, 120, 60);
@@ -198,7 +187,7 @@ public class StripeFillerTests
public void Fill_VerticalProducesNonOverlappingParts()
{
var plate = new Plate(60, 120) { PartSpacing = 0.5 };
var drawing = MakeRectDrawing(20, 10);
var drawing = TestHelpers.MakeRectDrawing(20, 10);
var item = new NestItem { Drawing = drawing };
var workArea = new Box(0, 0, 120, 60);
@@ -230,7 +219,7 @@ public class StripeFillerTests
private static List<Part> StripeFill(int maxQuantity, NestDirection axis)
{
var plate = new Plate(60, 120) { PartSpacing = 0.5 };
var drawing = MakeRectDrawing(20, 10);
var drawing = TestHelpers.MakeRectDrawing(20, 10);
var context = new OpenNest.Engine.Strategies.FillContext
{
Item = new NestItem { Drawing = drawing, Quantity = maxQuantity },
@@ -262,7 +251,7 @@ public class StripeFillerTests
public void Fill_ReturnsEmpty_WhenNoBestFits()
{
var plate = new Plate(60, 120) { PartSpacing = 0.5 };
var drawing = MakeRectDrawing(20, 10);
var drawing = TestHelpers.MakeRectDrawing(20, 10);
var item = new NestItem { Drawing = drawing };
var workArea = new Box(0, 0, 120, 60);
+12
View File
@@ -74,6 +74,18 @@ internal static class TestHelpers
/// <summary>The number of parts the plate's cut-offs materialize, one per trimmed segment.</summary>
public static int CutOffPartCount(Plate plate) => plate.CutOffs.Sum(c => c.SegmentPrograms().Count);
/// <summary>A w x h rectangle from the origin, counterclockwise: +X first, then up.</summary>
public static Drawing MakeRectDrawing(double w, double h, string name = "rect")
{
var pgm = new Program();
pgm.Codes.Add(new RapidMove(new Vector(0, 0)));
pgm.Codes.Add(new LinearMove(new Vector(w, 0)));
pgm.Codes.Add(new LinearMove(new Vector(w, h)));
pgm.Codes.Add(new LinearMove(new Vector(0, h)));
pgm.Codes.Add(new LinearMove(new Vector(0, 0)));
return new Drawing(name, pgm);
}
public static Drawing MakeSquareDrawing(double size = 10)
{
// CW winding matches CNC convention (OffsetSide.Left = outward)