aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-13 16:21:42 +0200
committerDanilo M. <danix@danix.xyz>2026-08-13 16:21:42 +0200
commit0422205803c8f6980a447fdaa1dc270a486970cd (patch)
treeaf9d8b005ad5ffae91860dfdadf727ce578fb60f /tests
parent3b771d03f2df572de29af3156817de3cb7ef6bef (diff)
downloadqtmaildir-0422205803c8f6980a447fdaa1dc270a486970cd.tar.gz
qtmaildir-0422205803c8f6980a447fdaa1dc270a486970cd.zip
fix(rules): save the window size on Cancel and Save, not only on X
The geometry was saved from closeEvent, and neither dialog button sends one: Cancel calls reject(), Save calls accept(), and only the window manager's X button produces a QCloseEvent. So the size and the column widths were kept for the one route out of three that a user almost never takes, and a resize followed by Cancel came back forgotten. The save moves to a done(int) override, which both buttons funnel through and which QWidget::close() also reaches. The test that covered this passed against the bug because it asserted with close(). It now drives all three routes rather than trusting one to stand for the others, and shows the dialog before the close leg: close() on a widget that was never visible returns early without reaching done(), so that assertion would otherwise prove nothing. Both traps recorded in CLAUDE.md, since neither is specific to this dialog. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/test_tagrules.cpp58
1 files changed, 56 insertions, 2 deletions
diff --git a/tests/test_tagrules.cpp b/tests/test_tagrules.cpp
index af30938..0d81df7 100644
--- a/tests/test_tagrules.cpp
+++ b/tests/test_tagrules.cpp
@@ -52,6 +52,7 @@ private slots:
void aFolderRowUsesTheDropdownAndKeepsItsSuffix();
void theTextModeToggleSurvivesBeingSwitchedOn();
void theWindowSizeAndColumnWidthsSurviveAReopen();
+ void theWindowSizeIsSavedOnEveryWayOutOfTheDialog();
void aReloadDoesNotDiscardARestoredColumnWidth();
private:
@@ -683,8 +684,13 @@ void TestTagRules::theWindowSizeAndColumnWidthsSurviveAReopen()
TagRulesDialog dialog;
dialog.resize(900, 640);
dialog.setColumnWidthForTest(0, 123);
- // The save is on close, matching where MainWindow writes its own.
- dialog.close();
+ // CANCEL, not close(). The first version of this saved from
+ // closeEvent and asserted with close(), which passes while the real
+ // dialog forgets everything: Cancel calls reject() and Save calls
+ // accept(), and neither sends a QCloseEvent. Only the window
+ // manager's X button does, so the test exercised the one path the
+ // buttons never take. The user found it by hand in one try.
+ dialog.reject();
}
// Asserted on the stored VALUE, not on the reopened frame. Item 46: the
@@ -705,6 +711,54 @@ void TestTagRules::theWindowSizeAndColumnWidthsSurviveAReopen()
qputenv("XDG_STATE_HOME", previousState);
}
+void TestTagRules::theWindowSizeIsSavedOnEveryWayOutOfTheDialog()
+{
+ // There are three ways out and they take different code paths: Cancel
+ // calls reject(), Save calls accept(), and the window manager's X button
+ // sends a QCloseEvent. Saving from closeEvent alone covers only the
+ // third, which is how the first version of this shipped and forgot the
+ // size on both buttons. done(int) is the funnel the two buttons share and
+ // close() also reaches, so all three are asserted here rather than
+ // trusting one to stand for the others.
+ QTemporaryDir configHome;
+ QTemporaryDir stateHome;
+ QVERIFY(configHome.isValid());
+ QVERIFY(stateHome.isValid());
+ const QByteArray previousState = qgetenv("XDG_STATE_HOME");
+ qputenv("XDG_CONFIG_HOME", configHome.path().toUtf8());
+ qputenv("XDG_STATE_HOME", stateHome.path().toUtf8());
+ writeTwoRules(configHome);
+
+ const auto widthAfter = [&](int width, const char *how) {
+ QFile::remove(MainWindow::uiStatePath());
+ TagRulesDialog dialog;
+ // Shown, because QWidget::close() on a widget that was never visible
+ // returns early without reaching done(). The X button it stands for
+ // only exists on a window that is on screen, so testing the closed
+ // path from a hidden dialog proves nothing about it.
+ dialog.show();
+ dialog.setColumnWidthForTest(0, width);
+ if (qstrcmp(how, "reject") == 0)
+ dialog.reject();
+ else if (qstrcmp(how, "accept") == 0)
+ dialog.saveForTest();
+ else
+ dialog.close();
+
+ TagRulesDialog reopened;
+ return reopened.columnWidthForTest(0);
+ };
+
+ QCOMPARE(widthAfter(121, "reject"), 121);
+ QCOMPARE(widthAfter(122, "accept"), 122);
+ QCOMPARE(widthAfter(123, "close"), 123);
+
+ if (previousState.isEmpty())
+ qunsetenv("XDG_STATE_HOME");
+ else
+ qputenv("XDG_STATE_HOME", previousState);
+}
+
void TestTagRules::aReloadDoesNotDiscardARestoredColumnWidth()
{
// The width did not survive a close, and it did not survive an ADD or a