refactor: organize test project into subdirectories by feature area
Move 43 root-level test files into feature-specific subdirectories mirroring the main codebase structure: Geometry, Fill, BestFit, CutOffs, CuttingStrategy, Engine, IO. Update namespaces to match folder paths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
using OpenNest.CNC;
|
||||
using OpenNest.CNC.CuttingStrategy;
|
||||
using OpenNest.Geometry;
|
||||
|
||||
namespace OpenNest.Tests.CuttingStrategy;
|
||||
|
||||
public class CuttingResultTests
|
||||
{
|
||||
[Fact]
|
||||
public void CuttingResult_StoresValues()
|
||||
{
|
||||
var pgm = new Program();
|
||||
pgm.Codes.Add(new RapidMove(new Vector(1, 2)));
|
||||
var point = new Vector(3, 4);
|
||||
|
||||
var result = new CuttingResult { Program = pgm, LastCutPoint = point };
|
||||
|
||||
Assert.Same(pgm, result.Program);
|
||||
Assert.Equal(3, result.LastCutPoint.X);
|
||||
Assert.Equal(4, result.LastCutPoint.Y);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
using OpenNest.CNC;
|
||||
using OpenNest.CNC.CuttingStrategy;
|
||||
using OpenNest.Engine;
|
||||
using OpenNest.Engine.Sequencing;
|
||||
using OpenNest.Geometry;
|
||||
|
||||
namespace OpenNest.Tests.CuttingStrategy;
|
||||
|
||||
public class LeadInAssignerTests
|
||||
{
|
||||
private static Part MakeSquarePartAt(double x, double y)
|
||||
{
|
||||
var pgm = new Program();
|
||||
pgm.Codes.Add(new RapidMove(new Vector(0, 0)));
|
||||
pgm.Codes.Add(new LinearMove(new Vector(0, 10)));
|
||||
pgm.Codes.Add(new LinearMove(new Vector(10, 10)));
|
||||
pgm.Codes.Add(new LinearMove(new Vector(10, 0)));
|
||||
pgm.Codes.Add(new LinearMove(new Vector(0, 0)));
|
||||
var drawing = new Drawing("test", pgm);
|
||||
return new Part(drawing, new Vector(x, y));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Assign_SetsHasManualLeadInsOnAllParts()
|
||||
{
|
||||
var plate = new Plate(60, 120);
|
||||
plate.Parts.Add(MakeSquarePartAt(10, 10));
|
||||
plate.Parts.Add(MakeSquarePartAt(30, 30));
|
||||
plate.CuttingParameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
var assigner = new LeadInAssigner { Sequencer = new LeftSideSequencer() };
|
||||
assigner.Assign(plate);
|
||||
|
||||
Assert.All(plate.Parts, p => Assert.True(p.HasManualLeadIns));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Assign_SkipsLockedParts()
|
||||
{
|
||||
var plate = new Plate(60, 120);
|
||||
var lockedPart = MakeSquarePartAt(10, 10);
|
||||
lockedPart.LeadInsLocked = true;
|
||||
lockedPart.HasManualLeadIns = true;
|
||||
var originalProgram = lockedPart.Program;
|
||||
|
||||
plate.Parts.Add(lockedPart);
|
||||
plate.Parts.Add(MakeSquarePartAt(30, 30));
|
||||
plate.CuttingParameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
var assigner = new LeadInAssigner { Sequencer = new LeftSideSequencer() };
|
||||
assigner.Assign(plate);
|
||||
|
||||
Assert.Same(originalProgram, lockedPart.Program);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Assign_RemovesExistingLeadInsBeforeReapply()
|
||||
{
|
||||
var plate = new Plate(60, 120);
|
||||
plate.Parts.Add(MakeSquarePartAt(10, 10));
|
||||
plate.CuttingParameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
var assigner = new LeadInAssigner { Sequencer = new LeftSideSequencer() };
|
||||
assigner.Assign(plate);
|
||||
var countAfterFirst = plate.Parts[0].Program.Codes.Count;
|
||||
|
||||
assigner.Assign(plate);
|
||||
var countAfterSecond = plate.Parts[0].Program.Codes.Count;
|
||||
|
||||
Assert.Equal(countAfterFirst, countAfterSecond);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Assign_PartsContainLeadinLayerCodes()
|
||||
{
|
||||
var plate = new Plate(60, 120);
|
||||
plate.Parts.Add(MakeSquarePartAt(10, 10));
|
||||
plate.CuttingParameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
var assigner = new LeadInAssigner { Sequencer = new LeftSideSequencer() };
|
||||
assigner.Assign(plate);
|
||||
|
||||
var hasLeadin = plate.Parts[0].Program.Codes.OfType<LinearMove>().Any(m => m.Layer == LayerType.Leadin);
|
||||
Assert.True(hasLeadin);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Assign_PreservesRotationOnRotatedParts()
|
||||
{
|
||||
var drawing = MakeSquareDrawing();
|
||||
var rotation = System.Math.PI / 2; // 90 degrees
|
||||
var part = Part.CreateAtOrigin(drawing, rotation);
|
||||
part.Offset(10, 10);
|
||||
|
||||
var plate = new Plate(60, 120);
|
||||
plate.Parts.Add(part);
|
||||
plate.CuttingParameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
var assigner = new LeadInAssigner { Sequencer = new LeftSideSequencer() };
|
||||
assigner.Assign(plate);
|
||||
|
||||
Assert.Equal(rotation, part.Rotation, 6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Assign_ThenRemove_PreservesRotation()
|
||||
{
|
||||
var drawing = MakeSquareDrawing();
|
||||
var rotation = System.Math.PI / 4; // 45 degrees
|
||||
var part = Part.CreateAtOrigin(drawing, rotation);
|
||||
part.Offset(15, 15);
|
||||
|
||||
var plate = new Plate(60, 120);
|
||||
plate.Parts.Add(part);
|
||||
plate.CuttingParameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
var assigner = new LeadInAssigner { Sequencer = new LeftSideSequencer() };
|
||||
assigner.Assign(plate);
|
||||
Assert.Equal(rotation, part.Rotation, 6);
|
||||
|
||||
part.RemoveLeadIns();
|
||||
Assert.Equal(rotation, part.Rotation, 6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Assign_PreservesLocationOnRotatedParts()
|
||||
{
|
||||
var drawing = MakeSquareDrawing();
|
||||
var part = Part.CreateAtOrigin(drawing, System.Math.PI / 2);
|
||||
part.Offset(20, 30);
|
||||
var location = part.Location;
|
||||
|
||||
var plate = new Plate(60, 120);
|
||||
plate.Parts.Add(part);
|
||||
plate.CuttingParameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
var assigner = new LeadInAssigner { Sequencer = new LeftSideSequencer() };
|
||||
assigner.Assign(plate);
|
||||
|
||||
Assert.Equal(location.X, part.Location.X, 6);
|
||||
Assert.Equal(location.Y, part.Location.Y, 6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Assign_ThenRemove_RestoresBoundingBox()
|
||||
{
|
||||
var drawing = MakeSquareDrawing();
|
||||
var rotation = System.Math.PI / 2;
|
||||
var part = Part.CreateAtOrigin(drawing, rotation);
|
||||
part.Offset(10, 10);
|
||||
var originalBbox = part.BoundingBox;
|
||||
|
||||
var plate = new Plate(60, 120);
|
||||
plate.Parts.Add(part);
|
||||
plate.CuttingParameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
var assigner = new LeadInAssigner { Sequencer = new LeftSideSequencer() };
|
||||
assigner.Assign(plate);
|
||||
part.RemoveLeadIns();
|
||||
|
||||
Assert.Equal(originalBbox.X, part.BoundingBox.X, 4);
|
||||
Assert.Equal(originalBbox.Y, part.BoundingBox.Y, 4);
|
||||
Assert.Equal(originalBbox.Width, part.BoundingBox.Width, 4);
|
||||
Assert.Equal(originalBbox.Length, part.BoundingBox.Length, 4);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Assign_ProgramGeometryMatchesRotatedOriginal()
|
||||
{
|
||||
var drawing = MakeSquareDrawing();
|
||||
var rotation = System.Math.PI / 2;
|
||||
var part = Part.CreateAtOrigin(drawing, rotation);
|
||||
part.Offset(10, 10);
|
||||
|
||||
// Get the original rotated geometry
|
||||
var originalGeometry = OpenNest.Converters.ConvertProgram.ToGeometry(part.Program);
|
||||
var originalNonRapid = originalGeometry.Where(e => e.Layer != SpecialLayers.Rapid).ToList();
|
||||
|
||||
var plate = new Plate(60, 120);
|
||||
plate.Parts.Add(part);
|
||||
plate.CuttingParameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
var assigner = new LeadInAssigner { Sequencer = new LeftSideSequencer() };
|
||||
assigner.Assign(plate);
|
||||
|
||||
// The lead-in program should produce geometry that contains the
|
||||
// original rotated shape (plus lead-in/out extensions)
|
||||
var leadInGeometry = OpenNest.Converters.ConvertProgram.ToGeometry(part.Program);
|
||||
var leadInNonRapid = leadInGeometry.Where(e =>
|
||||
e.Layer != SpecialLayers.Rapid &&
|
||||
e.Layer != SpecialLayers.Leadin &&
|
||||
e.Layer != SpecialLayers.Leadout).ToList();
|
||||
|
||||
// The bounding box of the cut geometry should be close to original
|
||||
var origBbox = GetEntityBounds(originalNonRapid);
|
||||
var leadBbox = GetEntityBounds(leadInNonRapid);
|
||||
|
||||
Assert.Equal(origBbox.Width, leadBbox.Width, 2);
|
||||
Assert.Equal(origBbox.Length, leadBbox.Length, 2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Assign_MultipleRotatedParts_AllPreserveRotation()
|
||||
{
|
||||
var drawing = MakeSquareDrawing();
|
||||
var rotations = new[] { 0.0, System.Math.PI / 6, System.Math.PI / 4, System.Math.PI / 2 };
|
||||
|
||||
var plate = new Plate(60, 120);
|
||||
for (var i = 0; i < rotations.Length; i++)
|
||||
{
|
||||
var part = Part.CreateAtOrigin(drawing, rotations[i]);
|
||||
part.Offset(10 + i * 15, 10);
|
||||
plate.Parts.Add(part);
|
||||
}
|
||||
|
||||
plate.CuttingParameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
var assigner = new LeadInAssigner { Sequencer = new LeftSideSequencer() };
|
||||
assigner.Assign(plate);
|
||||
|
||||
for (var i = 0; i < rotations.Length; i++)
|
||||
Assert.Equal(rotations[i], plate.Parts[i].Rotation, 6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Assign_Twice_PreservesRotation()
|
||||
{
|
||||
var drawing = MakeSquareDrawing();
|
||||
var rotation = System.Math.PI / 3; // 60 degrees
|
||||
var part = Part.CreateAtOrigin(drawing, rotation);
|
||||
part.Offset(10, 10);
|
||||
|
||||
var plate = new Plate(60, 120);
|
||||
plate.Parts.Add(part);
|
||||
plate.CuttingParameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
var assigner = new LeadInAssigner { Sequencer = new LeftSideSequencer() };
|
||||
assigner.Assign(plate);
|
||||
Assert.Equal(rotation, part.Rotation, 6);
|
||||
|
||||
// Assign again (this removes first, then re-applies)
|
||||
assigner.Assign(plate);
|
||||
Assert.Equal(rotation, part.Rotation, 6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Assign_AfterExternalHasManualLeadIns_PreservesRotation()
|
||||
{
|
||||
// Simulates loading a nest where HasManualLeadIns was saved as true
|
||||
// but the program doesn't actually contain lead-in codes.
|
||||
var drawing = MakeSquareDrawing();
|
||||
var rotation = System.Math.PI / 2;
|
||||
var part = Part.CreateAtOrigin(drawing, rotation);
|
||||
part.Offset(10, 10);
|
||||
part.HasManualLeadIns = true; // externally set (e.g., by NestReader)
|
||||
|
||||
var plate = new Plate(60, 120);
|
||||
plate.Parts.Add(part);
|
||||
plate.CuttingParameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
var assigner = new LeadInAssigner { Sequencer = new LeftSideSequencer() };
|
||||
assigner.Assign(plate);
|
||||
|
||||
Assert.Equal(rotation, part.Rotation, 6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveLeadIns_AfterExternalHasManualLeadIns_PreservesRotation()
|
||||
{
|
||||
// Simulates the case where HasManualLeadIns is set externally
|
||||
// and then lead-ins are removed.
|
||||
var drawing = MakeSquareDrawing();
|
||||
var rotation = System.Math.PI / 3;
|
||||
var part = Part.CreateAtOrigin(drawing, rotation);
|
||||
part.Offset(10, 10);
|
||||
part.HasManualLeadIns = true;
|
||||
|
||||
part.RemoveLeadIns();
|
||||
|
||||
Assert.Equal(rotation, part.Rotation, 6);
|
||||
}
|
||||
|
||||
private static Drawing MakeSquareDrawing()
|
||||
{
|
||||
var pgm = new Program();
|
||||
pgm.Codes.Add(new RapidMove(new Vector(0, 0)));
|
||||
pgm.Codes.Add(new LinearMove(new Vector(0, 10)));
|
||||
pgm.Codes.Add(new LinearMove(new Vector(10, 10)));
|
||||
pgm.Codes.Add(new LinearMove(new Vector(10, 0)));
|
||||
pgm.Codes.Add(new LinearMove(new Vector(0, 0)));
|
||||
return new Drawing("test", pgm);
|
||||
}
|
||||
|
||||
private static Box GetEntityBounds(List<OpenNest.Geometry.Entity> entities)
|
||||
{
|
||||
double minX = double.MaxValue, minY = double.MaxValue;
|
||||
double maxX = double.MinValue, maxY = double.MinValue;
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
if (entity is OpenNest.Geometry.Line line)
|
||||
{
|
||||
UpdateBounds(line.StartPoint, ref minX, ref minY, ref maxX, ref maxY);
|
||||
UpdateBounds(line.EndPoint, ref minX, ref minY, ref maxX, ref maxY);
|
||||
}
|
||||
}
|
||||
|
||||
return new Box(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
private static void UpdateBounds(Vector pt, ref double minX, ref double minY, ref double maxX, ref double maxY)
|
||||
{
|
||||
if (pt.X < minX) minX = pt.X;
|
||||
if (pt.Y < minY) minY = pt.Y;
|
||||
if (pt.X > maxX) maxX = pt.X;
|
||||
if (pt.Y > maxY) maxY = pt.Y;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using OpenNest.CNC;
|
||||
using OpenNest.CNC.CuttingStrategy;
|
||||
using OpenNest.Geometry;
|
||||
|
||||
namespace OpenNest.Tests.CuttingStrategy;
|
||||
|
||||
public class LeadInLayerTagTests
|
||||
{
|
||||
private static readonly Vector Point = new(5, 5);
|
||||
private const double Normal = 0.0;
|
||||
|
||||
[Fact]
|
||||
public void LineLeadIn_SetsLeadinLayer()
|
||||
{
|
||||
var leadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 };
|
||||
var codes = leadIn.Generate(Point, Normal);
|
||||
var linear = codes.OfType<LinearMove>().Single();
|
||||
Assert.Equal(LayerType.Leadin, linear.Layer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ArcLeadIn_SetsLeadinLayer()
|
||||
{
|
||||
var leadIn = new ArcLeadIn { Radius = 0.25 };
|
||||
var codes = leadIn.Generate(Point, Normal);
|
||||
var arc = codes.OfType<ArcMove>().Single();
|
||||
Assert.Equal(LayerType.Leadin, arc.Layer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LineArcLeadIn_SetsLeadinLayerOnAllMoves()
|
||||
{
|
||||
var leadIn = new LineArcLeadIn { LineLength = 0.5, ArcRadius = 0.25, ApproachAngle = 135 };
|
||||
var codes = leadIn.Generate(Point, Normal);
|
||||
Assert.All(codes.OfType<LinearMove>(), m => Assert.Equal(LayerType.Leadin, m.Layer));
|
||||
Assert.All(codes.OfType<ArcMove>(), m => Assert.Equal(LayerType.Leadin, m.Layer));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CleanHoleLeadIn_SetsLeadinLayerOnAllMoves()
|
||||
{
|
||||
var leadIn = new CleanHoleLeadIn { LineLength = 0.5, ArcRadius = 0.25, Kerf = 0.05 };
|
||||
var codes = leadIn.Generate(Point, Normal);
|
||||
Assert.All(codes.OfType<LinearMove>(), m => Assert.Equal(LayerType.Leadin, m.Layer));
|
||||
Assert.All(codes.OfType<ArcMove>(), m => Assert.Equal(LayerType.Leadin, m.Layer));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LineLineLeadIn_SetsLeadinLayerOnAllMoves()
|
||||
{
|
||||
var leadIn = new LineLineLeadIn { Length1 = 0.5, Length2 = 0.3, ApproachAngle1 = 90, ApproachAngle2 = 90 };
|
||||
var codes = leadIn.Generate(Point, Normal);
|
||||
Assert.All(codes.OfType<LinearMove>(), m => Assert.Equal(LayerType.Leadin, m.Layer));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NoLeadIn_NoLinearOrArcMoves()
|
||||
{
|
||||
var leadIn = new NoLeadIn();
|
||||
var codes = leadIn.Generate(Point, Normal);
|
||||
Assert.Empty(codes.OfType<LinearMove>());
|
||||
Assert.Empty(codes.OfType<ArcMove>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LineLeadOut_SetsLeadoutLayer()
|
||||
{
|
||||
var leadOut = new LineLeadOut { Length = 0.5, ApproachAngle = 90 };
|
||||
var codes = leadOut.Generate(Point, Normal);
|
||||
var linear = codes.OfType<LinearMove>().Single();
|
||||
Assert.Equal(LayerType.Leadout, linear.Layer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ArcLeadOut_SetsLeadoutLayer()
|
||||
{
|
||||
var leadOut = new ArcLeadOut { Radius = 0.25 };
|
||||
var codes = leadOut.Generate(Point, Normal);
|
||||
var arc = codes.OfType<ArcMove>().Single();
|
||||
Assert.Equal(LayerType.Leadout, arc.Layer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NoLeadOut_ReturnsEmptyList()
|
||||
{
|
||||
var leadOut = new NoLeadOut();
|
||||
var codes = leadOut.Generate(Point, Normal);
|
||||
Assert.Empty(codes);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using OpenNest.CNC;
|
||||
using OpenNest.Geometry;
|
||||
|
||||
namespace OpenNest.Tests.CuttingStrategy;
|
||||
|
||||
public class MotionSuppressedTests
|
||||
{
|
||||
[Fact]
|
||||
public void LinearMove_Suppressed_DefaultsFalse()
|
||||
{
|
||||
var move = new LinearMove(new Vector(1, 2));
|
||||
Assert.False(move.Suppressed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ArcMove_Suppressed_DefaultsFalse()
|
||||
{
|
||||
var move = new ArcMove(new Vector(1, 2), new Vector(0, 0));
|
||||
Assert.False(move.Suppressed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RapidMove_Suppressed_DefaultsFalse()
|
||||
{
|
||||
var move = new RapidMove(new Vector(1, 2));
|
||||
Assert.False(move.Suppressed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Suppressed_CanBeSet()
|
||||
{
|
||||
var move = new LinearMove(new Vector(1, 2));
|
||||
move.Suppressed = true;
|
||||
Assert.True(move.Suppressed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Clone_PreservesSuppressed()
|
||||
{
|
||||
var move = new LinearMove(new Vector(1, 2));
|
||||
move.Suppressed = true;
|
||||
var clone = (LinearMove)move.Clone();
|
||||
Assert.True(clone.Suppressed);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
using OpenNest.CNC;
|
||||
using OpenNest.CNC.CuttingStrategy;
|
||||
using OpenNest.Geometry;
|
||||
|
||||
namespace OpenNest.Tests.CuttingStrategy;
|
||||
|
||||
public class PartLeadInTests
|
||||
{
|
||||
private static Part MakeSquarePart()
|
||||
{
|
||||
var pgm = new Program();
|
||||
pgm.Codes.Add(new RapidMove(new Vector(0, 0)));
|
||||
pgm.Codes.Add(new LinearMove(new Vector(0, 10)));
|
||||
pgm.Codes.Add(new LinearMove(new Vector(10, 10)));
|
||||
pgm.Codes.Add(new LinearMove(new Vector(10, 0)));
|
||||
pgm.Codes.Add(new LinearMove(new Vector(0, 0)));
|
||||
var drawing = new Drawing("test", pgm);
|
||||
return new Part(drawing);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyLeadIns_SetsHasManualLeadIns()
|
||||
{
|
||||
var part = MakeSquarePart();
|
||||
var parameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 },
|
||||
InternalLeadIn = new LineLeadIn { Length = 0.25, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
part.ApplyLeadIns(parameters, new Vector(-5, -5));
|
||||
|
||||
Assert.True(part.HasManualLeadIns);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyLeadIns_StoresCuttingParameters()
|
||||
{
|
||||
var part = MakeSquarePart();
|
||||
var parameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 },
|
||||
InternalLeadIn = new LineLeadIn { Length = 0.25, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
part.ApplyLeadIns(parameters, new Vector(-5, -5));
|
||||
|
||||
Assert.Same(parameters, part.CuttingParameters);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyLeadIns_ProgramContainsLeadinCodes()
|
||||
{
|
||||
var part = MakeSquarePart();
|
||||
var parameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
part.ApplyLeadIns(parameters, new Vector(-5, -5));
|
||||
|
||||
var hasLeadin = part.Program.Codes.OfType<LinearMove>().Any(m => m.Layer == LayerType.Leadin);
|
||||
Assert.True(hasLeadin);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveLeadIns_RestoresOriginalProgram()
|
||||
{
|
||||
var part = MakeSquarePart();
|
||||
var originalCodeCount = part.Program.Codes.Count;
|
||||
var parameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
part.ApplyLeadIns(parameters, new Vector(-5, -5));
|
||||
part.RemoveLeadIns();
|
||||
|
||||
Assert.False(part.HasManualLeadIns);
|
||||
Assert.Null(part.CuttingParameters);
|
||||
Assert.Equal(originalCodeCount, part.Program.Codes.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveLeadIns_PreservesRotation()
|
||||
{
|
||||
var part = MakeSquarePart();
|
||||
part.Rotate(System.Math.PI / 4); // 45 degrees
|
||||
var rotation = part.Rotation;
|
||||
|
||||
var parameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
part.ApplyLeadIns(parameters, new Vector(-5, -5));
|
||||
part.RemoveLeadIns();
|
||||
|
||||
Assert.Equal(rotation, part.Rotation, 6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveLeadIns_PreservesLocation()
|
||||
{
|
||||
var part = MakeSquarePart();
|
||||
part.Offset(20, 30);
|
||||
var location = part.Location;
|
||||
|
||||
var parameters = new CuttingParameters
|
||||
{
|
||||
ExternalLeadIn = new LineLeadIn { Length = 0.5, ApproachAngle = 90 }
|
||||
};
|
||||
|
||||
part.ApplyLeadIns(parameters, new Vector(-5, -5));
|
||||
part.RemoveLeadIns();
|
||||
|
||||
Assert.Equal(location.X, part.Location.X, 6);
|
||||
Assert.Equal(location.Y, part.Location.Y, 6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LeadInsLocked_DefaultsFalse()
|
||||
{
|
||||
var part = MakeSquarePart();
|
||||
Assert.False(part.LeadInsLocked);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user