mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-05 16:52:10 -04:00
test(desktop): fix Windows-only WinForms and cross-platform test failures
The new windows-desktop CI job surfaced several tests that had never actually run on Windows: - SeparatorPenLifetimeTests expected Control.Disposed to fire only once; current WinForms re-fires it on every Dispose() call. - EditNestFocusTraversalTests assumed the Plates tab was selected by default, which stopped being true once Drawings became the landing tab; select it explicitly before asserting focus. - NestReportExportTests asserted an exact plate count that ignored PlateManager's trailing sentinel plate, and didn't expect the nest name in the busy-export message. - AtomicReportFileTests only expected IOException when replacing a directory target; Windows raises UnauthorizedAccessException instead, which callers already treat the same way. Also register a ThreadException handler so an exception inside a WndProc callback fails the test normally instead of popping a modal dialog that blocks the desktop. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3ba8f4e3b2
commit
5f9e8814a7
5 files changed
+40
-3
No files matched your search
@@ -54,7 +54,11 @@ public sealed class AtomicReportFileTests : IDisposable
|
||||
{
|
||||
var path = Path.Combine(directory, "not-a-file.pdf");
|
||||
Directory.CreateDirectory(path);
|
||||
Assert.ThrowsAny<IOException>(() => AtomicReportFile.Write(path, stream => stream.Write("PDF"u8)));
|
||||
// Moving onto a directory target raises IOException on some platforms and
|
||||
// UnauthorizedAccessException on others (observed on Windows); callers treat both alike.
|
||||
var error = Record.Exception(() => AtomicReportFile.Write(path, stream => stream.Write("PDF"u8)));
|
||||
Assert.True(error is IOException or UnauthorizedAccessException,
|
||||
$"Expected IOException or UnauthorizedAccessException, got {error?.GetType()}");
|
||||
Assert.True(Directory.Exists(path));
|
||||
Assert.Empty(Directory.GetFiles(directory));
|
||||
}
|
||||
|
||||
@@ -37,8 +37,9 @@ public class SeparatorPenLifetimeTests
|
||||
|
||||
control.Dispose();
|
||||
|
||||
// Control.Dispose(bool) re-raises Disposed on every call; only cleanup is idempotent.
|
||||
Assert.True(control.IsDisposed);
|
||||
Assert.Equal(1, disposedEvents);
|
||||
Assert.Equal(2, disposedEvents);
|
||||
Assert.Throws<ArgumentException>(() => graphics.DrawLine(lightPen, 0, 0, 3, 0));
|
||||
Assert.Throws<ArgumentException>(() => graphics.DrawLine(darkPen, 0, 1, 3, 1));
|
||||
});
|
||||
|
||||
@@ -83,6 +83,7 @@ public class EditNestFocusTraversalTests
|
||||
outer.Controls.Add(inner);
|
||||
form.ShowSidePanel(outer, "Focus regression");
|
||||
var plates = PlateList(form);
|
||||
SelectPlatesTab(form, plates); // Drawings is the default tab; the list can't take focus while hidden.
|
||||
Assert.True(original.Focus());
|
||||
Assert.True(form.ContainsFocus);
|
||||
Assert.Same(original, inner.ActiveControl);
|
||||
@@ -112,6 +113,7 @@ public class EditNestFocusTraversalTests
|
||||
using var form = CreateForm();
|
||||
form.Show();
|
||||
var plates = PlateList(form);
|
||||
SelectPlatesTab(form, plates); // Drawings is the default tab; the list can't take focus while hidden.
|
||||
Assert.True(plates.Focus());
|
||||
|
||||
form.UpdatePlateList();
|
||||
@@ -138,6 +140,12 @@ public class EditNestFocusTraversalTests
|
||||
private static ListView PlateList(EditNestForm form) =>
|
||||
Assert.IsType<ListView>(Assert.Single(form.Controls.Find("platesListView", true)));
|
||||
|
||||
private static void SelectPlatesTab(EditNestForm form, ListView plates)
|
||||
{
|
||||
var tabControl = Assert.IsType<TabControl>(Assert.Single(form.Controls.Find("tabControl1", true)));
|
||||
tabControl.SelectedTab = Assert.IsType<TabPage>(plates.Parent);
|
||||
}
|
||||
|
||||
private static void RunSta(System.Action testBody)
|
||||
{
|
||||
Exception? testFailure = null;
|
||||
|
||||
@@ -148,6 +148,8 @@ public class NestReportExportTests
|
||||
form.PlateView.SetOverlapAutoCheck(null); // Background overlap workers are irrelevant here.
|
||||
form.Show();
|
||||
form.PlateManager.LoadAt(1);
|
||||
// EnsureSentinel already appended a trailing empty plate behind the two loaded here.
|
||||
var plateCountBeforeExport = nest.Plates.Count;
|
||||
var path = Path.Combine(Path.GetTempPath(), $"opennest-report-ok-{Guid.NewGuid():N}.pdf");
|
||||
try
|
||||
{
|
||||
@@ -160,7 +162,7 @@ public class NestReportExportTests
|
||||
Assert.True(bytes.Length > 1000);
|
||||
// Selected plate and job contents are untouched by reporting.
|
||||
Assert.Equal(1, form.PlateManager.CurrentIndex);
|
||||
Assert.Equal(2, nest.Plates.Count);
|
||||
Assert.Equal(plateCountBeforeExport, nest.Plates.Count);
|
||||
Assert.Single(nest.Plates[0].Parts);
|
||||
Assert.Equal(2, nest.Drawings.Count);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace OpenNest.WinForms.Tests;
|
||||
|
||||
internal static class TestAssemblySetup
|
||||
{
|
||||
// SetUnhandledExceptionMode only changes which *default* dialog style WinForms would
|
||||
// show; it still shows one. A registered ThreadException handler is what actually
|
||||
// suppresses it (WinForms always prefers the handler over the default dialog), which
|
||||
// matters here because none of our tests call Application.Run() to install one.
|
||||
// Without this, an exception thrown inside a WndProc callback (e.g. a DataGridView
|
||||
// commit failure during Show()) pops a modal ThreadExceptionDialog that blocks the
|
||||
// desktop until someone dismisses it by hand, instead of failing the test normally.
|
||||
[ModuleInitializer]
|
||||
internal static void Initialize()
|
||||
{
|
||||
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
|
||||
Application.ThreadException += (_, e) =>
|
||||
Console.Error.WriteLine($"Suppressed ThreadExceptionDialog: {e.Exception}");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user