using OpenNest.Data; using OpenNest.Geometry; namespace OpenNest.Tests.Data; /// /// Decision logic of the desktop Clamps dialog: edits one nest's rail in its units, keeps /// "apply to this nest" (OK) separate from "save as machine defaults" (immediate write). /// public class ClampRailEditorTests { private static readonly double[] MachineCenters = { 6, 21, 36, 51, 66, 81, 96, 111 }; [Fact] public void NestWithoutARailStartsEmptyAtTheDefaultClampSize() { var editor = new ClampRailEditor(null, Units.Inches, applyToNewNests: false); Assert.Equal(1.5, editor.Width); Assert.Equal(0.625, editor.Depth); Assert.Empty(editor.Centers); Assert.Null(editor.BuildRail()); var metric = new ClampRailEditor(null, Units.Millimeters, applyToNewNests: false); Assert.Equal(1.5 * 25.4, metric.Width, 9); } [Fact] public void NestRailIsEditedInPlace() { var rail = new ClampRail(1.5, 0.625, MachineCenters); var editor = new ClampRailEditor(rail, Units.Inches, applyToNewNests: true); Assert.Equal(MachineCenters, editor.Centers); Assert.Equal(rail, editor.BuildRail()); Assert.True(editor.ApplyToNewNests); } [Fact] public void CentersStaySortedAndRefuseInvalidOrDuplicateValues() { var editor = new ClampRailEditor(null, Units.Inches, applyToNewNests: false); Assert.True(editor.TryAddCenter(21, out _)); Assert.True(editor.TryAddCenter(6, out var none)); Assert.Null(none); Assert.False(editor.TryAddCenter(21, out var duplicate)); Assert.Contains("already", duplicate); Assert.False(editor.TryAddCenter(-1, out var negative)); Assert.Contains("origin", negative); Assert.False(editor.TryAddCenter(double.NaN, out _)); Assert.Equal(new[] { 6.0, 21 }, editor.Centers); editor.RemoveCenterAt(0); editor.RemoveCenterAt(5); // out of range: ignored Assert.Equal(new[] { 21.0 }, editor.Centers); } [Fact] public void ApplyingToTheNestReResolvesEveryPlate() { var nest = new Nest(); nest.PlateDefaults.Size = new Size(48, 120); var full = nest.CreatePlate(); var shorter = nest.CreatePlate(); shorter.Size = new Size(48, 60); var editor = new ClampRailEditor(null, Units.Inches, applyToNewNests: false); foreach (var center in MachineCenters) Assert.True(editor.TryAddCenter(center, out _)); editor.ApplyTo(nest); Assert.Equal(8, full.ClampZones.Count); Assert.Equal(4, shorter.ClampZones.Count); Assert.Equal(8, nest.CreatePlate().ClampZones.Count); // Removing every clamp and applying removes them from the nest. while (editor.Centers.Count > 0) editor.RemoveCenterAt(0); editor.ApplyTo(nest); Assert.Null(nest.PlateDefaults.ClampRail); Assert.All(nest.Plates, p => Assert.Empty(p.ClampZones)); } [Fact] public void InvalidClampSizeIsRefusedBeforeApplyingOrSaving() { var nest = new Nest(); var plate = nest.CreatePlate(); var editor = new ClampRailEditor(null, Units.Inches, applyToNewNests: true); editor.TryAddCenter(6, out _); editor.Width = 0; Assert.Throws(() => editor.ApplyTo(nest)); Assert.Throws(() => editor.ToMachineDefaults()); Assert.Empty(plate.ClampZones); Assert.Null(nest.PlateDefaults.ClampRail); } [Fact] public void MachineDefaultsCaptureTheEditedValuesInTheNestsUnits() { var editor = new ClampRailEditor(null, Units.Millimeters, applyToNewNests: true); editor.Width = 40; editor.Depth = 16; editor.TryAddCenter(150, out _); var settings = editor.ToMachineDefaults(); Assert.True(settings.Enabled); Assert.Equal(Units.Millimeters, settings.Units); Assert.Equal(40, settings.Width); Assert.Equal(16, settings.Depth); Assert.Equal(new[] { 150.0 }, settings.Centers); // Without any clamp listed, saved defaults never enable clamps for new nests. editor.RemoveCenterAt(0); Assert.False(editor.ToMachineDefaults().Enabled); editor.ApplyToNewNests = false; editor.TryAddCenter(150, out _); Assert.False(editor.ToMachineDefaults().Enabled); } [Fact] public void LoadingMachineDefaultsOnlyFillsTheEditorInTheNestsUnits() { var nest = new Nest { Units = Units.Millimeters }; var plate = nest.CreatePlate(); var defaults = new ClampSettings { Enabled = true, Units = Units.Inches, Width = 1.5, Depth = 0.625, Centers = new[] { 21.0, 6 }, }; var editor = new ClampRailEditor(null, Units.Millimeters, applyToNewNests: false); editor.LoadMachineDefaults(defaults); Assert.Equal(1.5 * 25.4, editor.Width, 9); Assert.Equal(0.625 * 25.4, editor.Depth, 9); Assert.Equal(new[] { 6 * 25.4, 21 * 25.4 }, editor.Centers); Assert.True(editor.ApplyToNewNests); Assert.Empty(plate.ClampZones); // nothing applied until OK Assert.Null(nest.PlateDefaults.ClampRail); // Disabled defaults still load their values but do not ask to enable new nests. defaults.Enabled = false; editor.LoadMachineDefaults(defaults); Assert.False(editor.ApplyToNewNests); Assert.Equal(2, editor.Centers.Count); } [Fact] public void ConvertedSettingsKeepEnabledAndScaleEveryLength() { var inches = new ClampSettings { Enabled = true, Width = 1.5, Depth = 0.625, Centers = new[] { 6.0 } }; var metric = inches.ConvertedTo(Units.Millimeters); Assert.True(metric.Enabled); Assert.Equal(Units.Millimeters, metric.Units); Assert.Equal(38.1, metric.Width, 9); Assert.Equal(15.875, metric.Depth, 9); Assert.Equal(152.4, metric.Centers[0], 9); Assert.Equal(1.5, inches.Width); // the source is not modified Assert.Equal(1.5, inches.ConvertedTo(Units.Inches).Width); } // D9: the editor carries removal minutes through the same three boundaries as size. [Fact] public void RemovalMinutesStartsFromTheRailOrMachineDefault() { var rail = new ClampRail(1.5, 0.625, MachineCenters, removalMinutes: 7); Assert.Equal(7, new ClampRailEditor(rail, Units.Inches, false).RemovalMinutes); Assert.Equal(ClampRail.DefaultRemovalMinutes, new ClampRailEditor(null, Units.Inches, false).RemovalMinutes); } [Fact] public void RemovalMinutesIsNeverConvertedBetweenUnitsOnLoadOrBuild() { var editor = new ClampRailEditor(null, Units.Millimeters, applyToNewNests: true); editor.RemovalMinutes = 8; editor.TryAddCenter(150, out _); Assert.Equal(8, editor.ToMachineDefaults().RemovalMinutes); Assert.Equal(8, editor.BuildRail()!.RemovalMinutes); var defaults = new ClampSettings { Enabled = true, Units = Units.Inches, RemovalMinutes = 9, Centers = new[] { 6.0 }, }; editor.LoadMachineDefaults(defaults); Assert.Equal(9, editor.RemovalMinutes); // a time, so unaffected by the unit change } [Fact] public void InvalidRemovalMinutesIsRefusedBeforeSaving() { var editor = new ClampRailEditor(null, Units.Inches, applyToNewNests: true); editor.TryAddCenter(6, out _); editor.RemovalMinutes = -1; Assert.Throws(() => editor.ToMachineDefaults()); Assert.Throws(() => editor.BuildRail()); } }