mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-07 13:05:52 -05:00
A nest window gave no sign that its nest had changed since the last save, and closing it (or the app) discarded the edits silently. The undo history already tracks a save point, so the title now ends in " *" while the nest is off it (or holds an edit no scope recorded), and closing asks to save, discard or cancel. Yes saves through the storage in use; a database save cancels the close and closes the window once the upload succeeds. Saves now commit any unrecorded edit first so the save point covers what was written. The window's cleanup moves from OnClosing to OnFormClosed: another window can still cancel closing the app, and a nest window must not lose its plate manager when that happens. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
143 lines
4.4 KiB
C#
143 lines
4.4 KiB
C#
using System.Windows.Forms;
|
|
using OpenNest.Forms;
|
|
|
|
namespace OpenNest.WinForms.Tests.Forms;
|
|
|
|
// The title marks unsaved edits and closing asks before discarding them. Shares the undo
|
|
// tests' collection, since it drives the same main-window guards.
|
|
[Collection("Fill operation lifetime")]
|
|
public class UnsavedChangesTests
|
|
{
|
|
[Fact]
|
|
public void TheTitleIsMarkedWhileTheNestDiffersFromItsSavedState() => UndoTestEnv.Run(env =>
|
|
{
|
|
var editor = env.Editor;
|
|
Assert.False(editor.HasUnsavedChanges);
|
|
Assert.Equal("undo", editor.Text);
|
|
|
|
DeleteFirstPlatesParts(editor);
|
|
Assert.True(editor.HasUnsavedChanges);
|
|
Assert.Equal("undo *", editor.Text);
|
|
|
|
Assert.True(env.Host.TryUndo(editor));
|
|
Assert.False(editor.HasUnsavedChanges);
|
|
Assert.Equal("undo", editor.Text);
|
|
|
|
Assert.True(env.Host.TryRedo(editor));
|
|
Assert.Equal("undo *", editor.Text);
|
|
|
|
var path = TempNestPath("saved");
|
|
try
|
|
{
|
|
editor.SaveAs(path);
|
|
Assert.False(editor.HasUnsavedChanges);
|
|
Assert.Equal("saved", editor.Text);
|
|
}
|
|
finally
|
|
{
|
|
File.Delete(path);
|
|
}
|
|
});
|
|
|
|
[Fact]
|
|
public void AnEditNoScopeRecordedStillCountsAsUnsaved() => UndoTestEnv.Run(env =>
|
|
{
|
|
var editor = env.Editor;
|
|
editor.Nest.Plates[0].Parts.RemoveAt(0);
|
|
|
|
Assert.True(editor.HasUnsavedChanges);
|
|
});
|
|
|
|
[Fact]
|
|
public void ClosingAnUnchangedNestDoesNotAsk() => UndoTestEnv.Run(env =>
|
|
{
|
|
var asked = 0;
|
|
WithPrompt(env.Editor, () => { asked++; return DialogResult.Cancel; }, () =>
|
|
{
|
|
env.Editor.Close();
|
|
|
|
Assert.Equal(0, asked);
|
|
Assert.True(env.Editor.IsDisposed);
|
|
});
|
|
});
|
|
|
|
[Fact]
|
|
public void CancelKeepsTheWindowOpenAndNoClosesWithoutSaving() => UndoTestEnv.Run(env =>
|
|
{
|
|
var editor = env.Editor;
|
|
DeleteFirstPlatesParts(editor);
|
|
var answer = DialogResult.Cancel;
|
|
var asked = 0;
|
|
WithPrompt(editor, () => { asked++; return answer; }, () =>
|
|
{
|
|
editor.Close();
|
|
Assert.Equal(1, asked);
|
|
Assert.False(editor.IsDisposed);
|
|
Assert.True(editor.HasUnsavedChanges);
|
|
|
|
answer = DialogResult.No;
|
|
editor.Close();
|
|
Assert.Equal(2, asked);
|
|
Assert.True(editor.IsDisposed);
|
|
});
|
|
});
|
|
|
|
// Without a main window (whose save follows the machine's storage mode) Yes saves to a file.
|
|
[Fact]
|
|
public void YesSavesToTheNestsFileAndCloses() => StaTestThread.Run(() =>
|
|
{
|
|
using var editor = new EditNestForm(UndoTestEnv.BuildNest());
|
|
editor.PlateView.SetOverlapAutoCheck(null);
|
|
editor.Show();
|
|
var path = TempNestPath("yes");
|
|
try
|
|
{
|
|
editor.SaveAs(path);
|
|
var savedAt = File.GetLastWriteTimeUtc(path);
|
|
DeleteFirstPlatesParts(editor);
|
|
File.SetLastWriteTimeUtc(path, savedAt.AddMinutes(-1));
|
|
|
|
WithPrompt(editor, () => DialogResult.Yes, () =>
|
|
{
|
|
editor.Close();
|
|
|
|
Assert.True(editor.IsDisposed);
|
|
Assert.True(File.GetLastWriteTimeUtc(path) > savedAt.AddMinutes(-1));
|
|
});
|
|
}
|
|
finally
|
|
{
|
|
File.Delete(path);
|
|
}
|
|
}, TimeSpan.FromMinutes(1), "The STA test did not complete.");
|
|
|
|
private static void DeleteFirstPlatesParts(EditNestForm editor)
|
|
{
|
|
editor.PlateManager.LoadAt(0);
|
|
editor.PlateView.SelectAll();
|
|
editor.PlateView.Selection.DeleteSelected();
|
|
}
|
|
|
|
private static string TempNestPath(string name)
|
|
{
|
|
var directory = Path.Combine(Path.GetTempPath(), "OpenNest.WinForms.Tests", Guid.NewGuid().ToString("N"));
|
|
Directory.CreateDirectory(directory);
|
|
return Path.Combine(directory, name + ".nest");
|
|
}
|
|
|
|
// Answers for this test's window only; other windows closing meanwhile keep the default.
|
|
private static void WithPrompt(EditNestForm editor, Func<DialogResult> answer, Action body)
|
|
{
|
|
var previous = EditNestForm.UnsavedChangesPrompt;
|
|
EditNestForm.UnsavedChangesPrompt = form => ReferenceEquals(form, editor) ? answer() : previous(form);
|
|
try
|
|
{
|
|
body();
|
|
}
|
|
finally
|
|
{
|
|
EditNestForm.UnsavedChangesPrompt = previous;
|
|
}
|
|
}
|
|
}
|