From bdd66257135cd88a0978e1d433d2742983e0e2eb Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Sun, 1 Nov 2026 10:13:13 -0500 Subject: [PATCH] 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 --- .../Benchmark/BenchmarkScoringTests.cs | 23 ++------ OpenNest.Tests/ClampZoneTests.cs | 13 +--- OpenNest.Tests/Engine/CanonicalAngleTests.cs | 17 +----- .../Engine/EngineRefactorSmokeTests.cs | 29 +++------ .../Engine/ExplicitPlacementStrategyTests.cs | 13 +--- OpenNest.Tests/Engine/PartClassifierTests.cs | 13 +--- OpenNest.Tests/Engine/RemnantEngineTests.cs | 17 +----- .../Fill/AngleCandidateBuilderTests.cs | 59 ++++++++----------- OpenNest.Tests/Fill/CompactorTests.cs | 21 ++----- .../Fill/IterativeShrinkFillerTests.cs | 23 ++------ OpenNest.Tests/Fill/PairFillerTests.cs | 17 +----- .../Strategies/FillPipelineTests.cs | 25 +++----- .../Strategies/StripeFillerTests.cs | 21 ++----- OpenNest.Tests/TestHelpers.cs | 12 ++++ 14 files changed, 86 insertions(+), 217 deletions(-) diff --git a/OpenNest.Tests/Benchmark/BenchmarkScoringTests.cs b/OpenNest.Tests/Benchmark/BenchmarkScoringTests.cs index 78a98a86..30347afa 100644 --- a/OpenNest.Tests/Benchmark/BenchmarkScoringTests.cs +++ b/OpenNest.Tests/Benchmark/BenchmarkScoringTests.cs @@ -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 { 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); - } - /// 20x20 square with a 10x10 cutout centerd in it. private static Drawing Frame() { diff --git a/OpenNest.Tests/ClampZoneTests.cs b/OpenNest.Tests/ClampZoneTests.cs index e720f927..bdcf4a5b 100644 --- a/OpenNest.Tests/ClampZoneTests.cs +++ b/OpenNest.Tests/ClampZoneTests.cs @@ -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); - } } diff --git a/OpenNest.Tests/Engine/CanonicalAngleTests.cs b/OpenNest.Tests/Engine/CanonicalAngleTests.cs index 94ccd733..3d872f42 100644 --- a/OpenNest.Tests/Engine/CanonicalAngleTests.cs +++ b/OpenNest.Tests/Engine/CanonicalAngleTests.cs @@ -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); } diff --git a/OpenNest.Tests/Engine/EngineRefactorSmokeTests.cs b/OpenNest.Tests/Engine/EngineRefactorSmokeTests.cs index df5eaff5..0db7b8d5 100644 --- a/OpenNest.Tests/Engine/EngineRefactorSmokeTests.cs +++ b/OpenNest.Tests/Engine/EngineRefactorSmokeTests.cs @@ -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 { 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 { - 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 { - 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, diff --git a/OpenNest.Tests/Engine/ExplicitPlacementStrategyTests.cs b/OpenNest.Tests/Engine/ExplicitPlacementStrategyTests.cs index a6db75aa..c2126b90 100644 --- a/OpenNest.Tests/Engine/ExplicitPlacementStrategyTests.cs +++ b/OpenNest.Tests/Engine/ExplicitPlacementStrategyTests.cs @@ -11,17 +11,6 @@ namespace OpenNest.Tests.Engine; /// 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", diff --git a/OpenNest.Tests/Engine/PartClassifierTests.cs b/OpenNest.Tests/Engine/PartClassifierTests.cs index ac5c206d..421f2c3d 100644 --- a/OpenNest.Tests/Engine/PartClassifierTests.cs +++ b/OpenNest.Tests/Engine/PartClassifierTests.cs @@ -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); diff --git a/OpenNest.Tests/Engine/RemnantEngineTests.cs b/OpenNest.Tests/Engine/RemnantEngineTests.cs index e67895fc..44188e21 100644 --- a/OpenNest.Tests/Engine/RemnantEngineTests.cs +++ b/OpenNest.Tests/Engine/RemnantEngineTests.cs @@ -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); diff --git a/OpenNest.Tests/Fill/AngleCandidateBuilderTests.cs b/OpenNest.Tests/Fill/AngleCandidateBuilderTests.cs index c6f5d005..751b030d 100644 --- a/OpenNest.Tests/Fill/AngleCandidateBuilderTests.cs +++ b/OpenNest.Tests/Fill/AngleCandidateBuilderTests.cs @@ -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() : 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 { 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), diff --git a/OpenNest.Tests/Fill/CompactorTests.cs b/OpenNest.Tests/Fill/CompactorTests.cs index 4d0d91b9..398dafef 100644 --- a/OpenNest.Tests/Fill/CompactorTests.cs +++ b/OpenNest.Tests/Fill/CompactorTests.cs @@ -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 { moving }; var obstacles = new List { 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))); diff --git a/OpenNest.Tests/Fill/IterativeShrinkFillerTests.cs b/OpenNest.Tests/Fill/IterativeShrinkFillerTests.cs index 08b0df22..efa54826 100644 --- a/OpenNest.Tests/Fill/IterativeShrinkFillerTests.cs +++ b/OpenNest.Tests/Fill/IterativeShrinkFillerTests.cs @@ -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 { new NestItem { Drawing = drawing, Quantity = 5 }, @@ -69,8 +58,8 @@ public class IterativeShrinkFillerTests { var items = new List { - 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> 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 { - new NestItem { Drawing = MakeRectDrawing(20, 10), Quantity = 1000 }, + new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10), Quantity = 1000 }, }; Func> fillFunc = (ni, b) => @@ -117,7 +106,7 @@ public class IterativeShrinkFillerTests { var items = new List { - new NestItem { Drawing = MakeRectDrawing(20, 10), Quantity = 0 }, + new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10), Quantity = 0 }, }; Func> fillFunc = (ni, b) => @@ -141,7 +130,7 @@ public class IterativeShrinkFillerTests var items = new List { - new NestItem { Drawing = MakeRectDrawing(20, 10), Quantity = 10 }, + new NestItem { Drawing = TestHelpers.MakeRectDrawing(20, 10), Quantity = 10 }, }; Func> fillFunc = (ni, b) => diff --git a/OpenNest.Tests/Fill/PairFillerTests.cs b/OpenNest.Tests/Fill/PairFillerTests.cs index 72cc4e5b..c4fe6356 100644 --- a/OpenNest.Tests/Fill/PairFillerTests.cs +++ b/OpenNest.Tests/Fill/PairFillerTests.cs @@ -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); diff --git a/OpenNest.Tests/Strategies/FillPipelineTests.cs b/OpenNest.Tests/Strategies/FillPipelineTests.cs index 0e633220..63961ccd 100644 --- a/OpenNest.Tests/Strategies/FillPipelineTests.cs +++ b/OpenNest.Tests/Strategies/FillPipelineTests.cs @@ -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(); 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(); 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(); filler.Fill( diff --git a/OpenNest.Tests/Strategies/StripeFillerTests.cs b/OpenNest.Tests/Strategies/StripeFillerTests.cs index 9b686a0f..954ed64e 100644 --- a/OpenNest.Tests/Strategies/StripeFillerTests.cs +++ b/OpenNest.Tests/Strategies/StripeFillerTests.cs @@ -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 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); diff --git a/OpenNest.Tests/TestHelpers.cs b/OpenNest.Tests/TestHelpers.cs index 9451bc34..10284997 100644 --- a/OpenNest.Tests/TestHelpers.cs +++ b/OpenNest.Tests/TestHelpers.cs @@ -74,6 +74,18 @@ internal static class TestHelpers /// The number of parts the plate's cut-offs materialize, one per trimmed segment. public static int CutOffPartCount(Plate plate) => plate.CutOffs.Sum(c => c.SegmentPrograms().Count); + /// A w x h rectangle from the origin, counterclockwise: +X first, then up. + 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)