From e7cbd99db6563f3a1247a54d45d8a9dce9ff7bc3 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Sun, 20 Sep 2026 17:40:06 -0400 Subject: [PATCH] Separate WinForms tests so main test suite runs on Linux --- CLAUDE.md | 4 ++- OpenNest.Api/OpenNest.Api.csproj | 2 +- OpenNest.Data/OpenNest.Data.csproj | 2 +- .../OpenNest.Posts.Cincinnati.csproj | 4 +-- .../OpenNest.Posts.GravographIS.csproj | 4 +-- OpenNest.Tests/OpenNest.Tests.csproj | 3 +-- .../Bending/CadBendNoteTests.cs | 0 .../CuttingParametersSerializerTests.cs | 0 .../OpenNest.WinForms.Tests.csproj | 19 ++++++++++++++ OpenNest.sln | 14 ++++++++++ README.md | 26 ++++++++++++++++--- 11 files changed, 65 insertions(+), 13 deletions(-) rename {OpenNest.Tests => OpenNest.WinForms.Tests}/Bending/CadBendNoteTests.cs (100%) rename {OpenNest.Tests => OpenNest.WinForms.Tests}/CuttingStrategy/CuttingParametersSerializerTests.cs (100%) create mode 100644 OpenNest.WinForms.Tests/OpenNest.WinForms.Tests.csproj diff --git a/CLAUDE.md b/CLAUDE.md index 975553c..76abbac 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,7 +14,9 @@ This is a .NET 8 solution using SDK-style `.csproj` files. The desktop app and W dotnet build OpenNest.sln ``` -Cross-platform whole-job engine tests (net8.0, runs on Linux/macOS/Windows without the desktop project or DXF fixtures): `dotnet test OpenNest.Engine.Tests/OpenNest.Engine.Tests.csproj`. The existing `OpenNest.Tests` suite targets `net8.0-windows` and requires a Windows runner; cross-compiling on Linux is not Windows runtime verification. +Cross-platform whole-job engine tests (net8.0, runs on Linux/macOS/Windows without the desktop project or DXF fixtures): `dotnet test OpenNest.Engine.Tests/OpenNest.Engine.Tests.csproj`. The main `OpenNest.Tests` suite also targets `net8.0`: run `dotnet test OpenNest.Tests/OpenNest.Tests.csproj` independently on Linux/macOS/Windows. It must not reference the WinForms `OpenNest` project. The API, Data, Cincinnati, and GravographIS libraries target `net8.0`; post-processor build deployment still targets the desktop app's `net8.0-windows/Posts` directory. Optional CHR-font fixtures are configured through `OpenNest.Tests/test-config.json` and skip when absent. + +`OpenNest.WinForms.Tests` contains the desktop-assembly-dependent `CadBendNoteTests` (`CadText`) and `CuttingParametersSerializerTests` (`CuttingParametersSerializer`). It targets `net8.0-windows`, references `OpenNest`, and requires a Windows runner: `dotnet test OpenNest.WinForms.Tests/OpenNest.WinForms.Tests.csproj`. Keep future desktop-dependent tests here rather than in `OpenNest.Tests`. Linux cross-compilation uses `dotnet build OpenNest.WinForms.Tests/OpenNest.WinForms.Tests.csproj -p:EnableWindowsTargeting=true`; cross-compilation is not Windows runtime verification. Cross-platform CAD import tests: `dotnet test OpenNest.IO.Tests/OpenNest.IO.Tests.csproj`. These synthetic-DXF and bend-repair tests target `net8.0`, require no external fixtures, and are included in the solution. Build the headless console independently with `dotnet build OpenNest.Console/OpenNest.Console.csproj`. diff --git a/OpenNest.Api/OpenNest.Api.csproj b/OpenNest.Api/OpenNest.Api.csproj index b5ea17a..c019c63 100644 --- a/OpenNest.Api/OpenNest.Api.csproj +++ b/OpenNest.Api/OpenNest.Api.csproj @@ -1,6 +1,6 @@ - net8.0-windows + net8.0 OpenNest.Api OpenNest.Api diff --git a/OpenNest.Data/OpenNest.Data.csproj b/OpenNest.Data/OpenNest.Data.csproj index 9103a22..dcf94b0 100644 --- a/OpenNest.Data/OpenNest.Data.csproj +++ b/OpenNest.Data/OpenNest.Data.csproj @@ -1,6 +1,6 @@ - net8.0-windows + net8.0 OpenNest.Data OpenNest.Data enable diff --git a/OpenNest.Posts.Cincinnati/OpenNest.Posts.Cincinnati.csproj b/OpenNest.Posts.Cincinnati/OpenNest.Posts.Cincinnati.csproj index 0109553..1a1bdc6 100644 --- a/OpenNest.Posts.Cincinnati/OpenNest.Posts.Cincinnati.csproj +++ b/OpenNest.Posts.Cincinnati/OpenNest.Posts.Cincinnati.csproj @@ -1,6 +1,6 @@ - net8.0-windows + net8.0 OpenNest.Posts.Cincinnati @@ -13,7 +13,7 @@ - ..\OpenNest\bin\$(Configuration)\$(TargetFramework)\Posts\ + ..\OpenNest\bin\$(Configuration)\net8.0-windows\Posts\ $(MSBuildProjectDirectory)\OpenNest.Posts.Cincinnati.json $(PostsDir)OpenNest.Posts.Cincinnati.json diff --git a/OpenNest.Posts.GravographIS/OpenNest.Posts.GravographIS.csproj b/OpenNest.Posts.GravographIS/OpenNest.Posts.GravographIS.csproj index a359c3d..6842a7c 100644 --- a/OpenNest.Posts.GravographIS/OpenNest.Posts.GravographIS.csproj +++ b/OpenNest.Posts.GravographIS/OpenNest.Posts.GravographIS.csproj @@ -1,6 +1,6 @@ - net8.0-windows + net8.0 OpenNest.Posts.GravographIS @@ -12,7 +12,7 @@ - ..\OpenNest\bin\$(Configuration)\$(TargetFramework)\Posts\ + ..\OpenNest\bin\$(Configuration)\net8.0-windows\Posts\ diff --git a/OpenNest.Tests/OpenNest.Tests.csproj b/OpenNest.Tests/OpenNest.Tests.csproj index 9f465c4..7d4c4df 100644 --- a/OpenNest.Tests/OpenNest.Tests.csproj +++ b/OpenNest.Tests/OpenNest.Tests.csproj @@ -1,7 +1,7 @@ - net8.0-windows + net8.0 enable enable @@ -29,7 +29,6 @@ - diff --git a/OpenNest.Tests/Bending/CadBendNoteTests.cs b/OpenNest.WinForms.Tests/Bending/CadBendNoteTests.cs similarity index 100% rename from OpenNest.Tests/Bending/CadBendNoteTests.cs rename to OpenNest.WinForms.Tests/Bending/CadBendNoteTests.cs diff --git a/OpenNest.Tests/CuttingStrategy/CuttingParametersSerializerTests.cs b/OpenNest.WinForms.Tests/CuttingStrategy/CuttingParametersSerializerTests.cs similarity index 100% rename from OpenNest.Tests/CuttingStrategy/CuttingParametersSerializerTests.cs rename to OpenNest.WinForms.Tests/CuttingStrategy/CuttingParametersSerializerTests.cs diff --git a/OpenNest.WinForms.Tests/OpenNest.WinForms.Tests.csproj b/OpenNest.WinForms.Tests/OpenNest.WinForms.Tests.csproj new file mode 100644 index 0000000..4ea51cf --- /dev/null +++ b/OpenNest.WinForms.Tests/OpenNest.WinForms.Tests.csproj @@ -0,0 +1,19 @@ + + + net8.0-windows + enable + enable + false + true + + + + + + + + + + + + diff --git a/OpenNest.sln b/OpenNest.sln index 7a28092..f925c30 100644 --- a/OpenNest.sln +++ b/OpenNest.sln @@ -40,6 +40,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenNest.Engine.Tests", "Op EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenNest.IO.Tests", "OpenNest.IO.Tests\OpenNest.IO.Tests.csproj", "{BA93522B-8A93-4689-A850-D042483964B9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenNest.WinForms.Tests", "OpenNest.WinForms.Tests\OpenNest.WinForms.Tests.csproj", "{6A96D511-A633-4892-A6CE-73D0A211454E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -242,6 +244,18 @@ Global {BA93522B-8A93-4689-A850-D042483964B9}.Release|x64.Build.0 = Release|Any CPU {BA93522B-8A93-4689-A850-D042483964B9}.Release|x86.ActiveCfg = Release|Any CPU {BA93522B-8A93-4689-A850-D042483964B9}.Release|x86.Build.0 = Release|Any CPU + {6A96D511-A633-4892-A6CE-73D0A211454E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6A96D511-A633-4892-A6CE-73D0A211454E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6A96D511-A633-4892-A6CE-73D0A211454E}.Debug|x64.ActiveCfg = Debug|Any CPU + {6A96D511-A633-4892-A6CE-73D0A211454E}.Debug|x64.Build.0 = Debug|Any CPU + {6A96D511-A633-4892-A6CE-73D0A211454E}.Debug|x86.ActiveCfg = Debug|Any CPU + {6A96D511-A633-4892-A6CE-73D0A211454E}.Debug|x86.Build.0 = Debug|Any CPU + {6A96D511-A633-4892-A6CE-73D0A211454E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6A96D511-A633-4892-A6CE-73D0A211454E}.Release|Any CPU.Build.0 = Release|Any CPU + {6A96D511-A633-4892-A6CE-73D0A211454E}.Release|x64.ActiveCfg = Release|Any CPU + {6A96D511-A633-4892-A6CE-73D0A211454E}.Release|x64.Build.0 = Release|Any CPU + {6A96D511-A633-4892-A6CE-73D0A211454E}.Release|x86.ActiveCfg = Release|Any CPU + {6A96D511-A633-4892-A6CE-73D0A211454E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index 6ac085a..34cbb03 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ OpenNest takes your part drawings, lets you define your sheet (plate) sizes, and ## Prerequisites - **Windows 10 or later** for the desktop app and Windows-dependent projects -- The headless console and engine/import test projects target `net8.0` and can be built independently on Linux, macOS, or Windows +- The headless console, API, data and post-processor libraries, and cross-platform test projects target `net8.0` and can be built independently on Linux, macOS, or Windows - [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) ## Getting Started @@ -80,7 +80,23 @@ dotnet csharpier format . # apply; use `check` instead of `format` to verify dotnet test OpenNest.Engine.Tests/OpenNest.Engine.Tests.csproj ``` -`OpenNest.Engine.Tests` targets `net8.0` and runs on Linux, macOS, and Windows without the desktop project or local DXF fixtures. The existing `OpenNest.Tests` suite still requires Windows. +`OpenNest.Engine.Tests` targets `net8.0` and runs on Linux, macOS, and Windows without the desktop project or local DXF fixtures. + +The main suite also runs independently on Linux, macOS, and Windows, with no reference to the WinForms application: + +```bash +dotnet test OpenNest.Tests/OpenNest.Tests.csproj +``` + +`OpenNest.Tests` covers the core, engine, import, API, data, and post-processor libraries. Optional CHR-font tests skip when their local fixtures are unavailable; configure them with `OpenNest.Tests/test-config.json`. + +Desktop-assembly tests live separately in `OpenNest.WinForms.Tests` (`net8.0-windows`): `CadBendNoteTests` tests `OpenNest.Controls.CadText`, and `CuttingParametersSerializerTests` tests `OpenNest.Forms.CuttingParametersSerializer`. Run these on Windows: + +```bash +dotnet test OpenNest.WinForms.Tests/OpenNest.WinForms.Tests.csproj +``` + +The full solution still requires Windows. Linux can cross-compile the desktop tests with `dotnet build OpenNest.WinForms.Tests/OpenNest.WinForms.Tests.csproj -p:EnableWindowsTargeting=true`, but that does not verify Windows runtime behavior. The new whole-job contracts in `OpenNest.Engine/Jobs` (`namespace OpenNest`) use owned immutable geometry/settings, explicit part IDs and positive demand, finite or unlimited stock (`null` means unlimited; zero means unavailable), and result ID/pose values rather than mutable desktop models. Callers own their inputs: the job copies everything at entry and the result leaks no mutable `Drawing`, `Plate`, or `NestItem`. One job is one material/thickness/unit system — no cross-material pooling. Rotation is in radians about the geometry origin, followed by translation into the plate quadrant frame. Strategy factories belong to each runner, not the global registry. In the public API, the legacy `SheetSize` request field is the unlimited-stock fallback only when `Plates` is null; an explicit empty `Plates` list means no available stock. @@ -252,7 +268,8 @@ OpenNest.sln ├── OpenNest.Benchmark/ # Head-to-head comparison of registered nest engines ├── OpenNest.Mcp/ # MCP server for AI tool integration ├── OpenNest.Posts.Cincinnati/ # Cincinnati CL-707 laser post-processor plugin -└── OpenNest.Tests/ # Unit tests (xUnit) +├── OpenNest.Tests/ # Cross-platform unit tests (net8.0, xUnit) +└── OpenNest.WinForms.Tests/ # Desktop-assembly tests (Windows only) ``` | Project | What it does | @@ -268,7 +285,8 @@ OpenNest.sln | **OpenNest.Posts.Cincinnati** | Post-processor plugin for Cincinnati CL-707/800/900/940/CLX laser cutting machines. Outputs Cincinnati-format G-code with material library, kerf compensation, and pierce logic. | | **OpenNest.Mcp** | MCP (Model Context Protocol) server exposing nesting operations as tools for AI assistants. | | **OpenNest.Benchmark** | Runs every registered whole-job nesting engine (`INestingEngine`) against a set of `.nest` files and scores them by material utilization, so competing engines — each owning its own multi-plate strategy — can be compared head-to-head. | -| **OpenNest.Tests** | 89 test files covering core geometry, fill strategies, splitting, bending, BOM import, post-processing, and the API. | +| **OpenNest.Tests** | Cross-platform tests covering core geometry, fill strategies, splitting, bending, BOM import, post-processing, data, and the API. | +| **OpenNest.WinForms.Tests** | Windows-only tests for desktop CAD bend-note presentation and cutting-parameter serialization. | ### StockLadder whole-job baseline