Files
OpenNest/OpenNest.WinForms.Tests/Forms/NestDefaultsFormTests.cs
T
ajandClaude Opus 5.5 b026bd19d2 feat(common-line): place parts on common lines automatically at a chosen level
Slice 3 of common-line cutting. On costly plate (N26-295: 3/16 RA310S at about
$2,500 a sheet) pairing parts one kerf apart fits the part the spacing cannot:
the last plate's 38 parts fit on one 48x120 with Auto Nest only with pairs.

- Drawing Properties gains "Allow common line" (Drawing.AllowCommonLine, off by
  default because customer edge-quality needs vary). The nest's CommonLineUsage
  (Off / When it adds parts / Whenever available) is set in Auto Nest and seeded
  from Tools > Nest Defaults; both persist (nest.json, defaults.json).
- NestPipeline runs the ordinary solve, then, with a level on, trials where
  eligible parts are offered as kerf-gap pair compounds. Placed pairs expand into
  parts plus explicit NestJobCommonLine groups, are validated again, and
  CommonLineRanking keeps a trial only by the level: count first, then sheets;
  "when it adds parts" keeps the plain layout on a tie, "whenever" also takes a
  shorter cut or less material, never at the cost of a part. Engines, FillScore
  and their comparers are unchanged; Off asks the engine exactly what it did.
- NestLayoutCheck exempts members only through a sheet's explicit group list and
  only when the job allows common lines; materializing and committing create
  Plate.CommonLines.
- Server nesting writes common-line jobs as version 3 and replays the recorded
  trial answers, so the desktop binds the same groups.
- Fill Area honors the level through a PlateFillService overload.
- The benchmark gains --common-lines <level> --kerf <k>.

Benchmark (synthetic nests + N26-295, --parallel 1): with no flag and with
--common-lines off every engine matches the base commit; with a level on no
layout becomes invalid and three runs save a sheet at equal nested area.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 19:38:00 -05:00

82 lines
3.2 KiB
C#

using System.Windows.Forms;
using OpenNest.Data;
using OpenNest.Forms;
using OpenNest.Geometry;
namespace OpenNest.WinForms.Tests.Forms;
public class NestDefaultsFormTests
{
[Fact]
public void SwitchingUnitsConvertsTheShownValues()
{
RunSta(() =>
{
var machine = new MachineConfig { Name = "Laser" };
var defaults = new NestDefaults
{
Units = Units.Inches,
Size = new Size(48, 96),
Quadrant = 3,
PartSpacing = 0.25,
EdgeSpacing = new Spacing(0.5, 1, 1.5, 2),
MachineId = machine.Id,
};
using var form = new NestDefaultsForm(defaults, new[] { machine }, ("Saved on this PC.", false));
Assert.Equal("in", Control<OpenNest.Controls.NumericUpDown>(form, "widthBox").Suffix);
Control<RadioButton>(form, "millimetersRadio").Checked = true;
var converted = form.GetDefaults();
Assert.Equal(Units.Millimeters, converted.Units);
Assert.Equal(new Size(1219.2, 2438.4), converted.Size);
Assert.Equal(6.35, converted.PartSpacing);
Assert.Equal(new Spacing(12.7, 25.4, 38.1, 50.8), converted.EdgeSpacing);
Assert.Equal(3, converted.Quadrant);
Assert.Equal(machine.Id, converted.MachineId);
Assert.Equal("mm", Control<OpenNest.Controls.NumericUpDown>(form, "edgeTopBox").Suffix);
Control<RadioButton>(form, "inchesRadio").Checked = true;
Assert.Equal(new Size(48, 96), form.GetDefaults().Size);
});
}
[Fact]
public void ReadOnlySourceDisablesSave()
{
RunSta(() =>
{
using var form = new NestDefaultsForm(new NestDefaults(), Array.Empty<MachineConfig>(),
("Shared, read-only: the server cannot be reached.", true));
Assert.False(Control<Button>(form, "saveButton").Enabled);
Assert.Equal("Shared, read-only: the server cannot be reached.", Control<Label>(form, "sourceLabel").Text);
});
}
[Fact]
public void CommonLineUsage_LoadsAndSaves_AndSurvivesAUnitSwitch()
{
RunSta(() =>
{
using var form = new NestDefaultsForm(new NestDefaults { CommonLineUsage = CommonLineUsage.Whenever },
Array.Empty<MachineConfig>(), ("Saved on this PC.", false));
var combo = Control<ComboBox>(form, "commonLineCombo");
Assert.Equal(2, combo.SelectedIndex);
Control<RadioButton>(form, "millimetersRadio").Checked = true;
Assert.Equal(CommonLineUsage.Whenever, form.GetDefaults().CommonLineUsage);
combo.SelectedIndex = 1;
Assert.Equal(CommonLineUsage.WhenItAddsParts, form.GetDefaults().CommonLineUsage);
combo.SelectedIndex = 0;
Assert.Equal(CommonLineUsage.Off, form.GetDefaults().CommonLineUsage);
});
}
private static T Control<T>(NestDefaultsForm form, string name) where T : Control =>
Assert.IsType<T>(form.Controls.Find(name, true).Single());
private static void RunSta(System.Action action) =>
StaTestThread.Run(action, Timeout.InfiniteTimeSpan, "The STA test did not complete.");
}