summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-14 11:46:47 +0200
committerDanilo M. <danix@danix.xyz>2026-08-14 11:46:47 +0200
commit8f1ff70f4fabf9c077fa26b2ca99c6664d1b146b (patch)
tree54bd706bae73a110678b992ad24d034ddab77f1c /docs
parent1c3f86d5a8e62f8617bbf1b7b834c81701e8b5c4 (diff)
downloadqtmaildir-8f1ff70f4fabf9c077fa26b2ca99c6664d1b146b.tar.gz
qtmaildir-8f1ff70f4fabf9c077fa26b2ca99c6664d1b146b.zip
docs: record the modal that hangs test_mainwindow as item 84
Cause verified by attaching gdb to the hung process rather than inferred: showWarnings() raises QMessageBox::warning from the MainWindow constructor, and nothing offscreen can dismiss it, so any config problem in a test's fixture blocks the constructor forever. Not a defect in the application. The modal is right for a person and the code says why; the defect is that a test cannot dismiss it and the resulting failure is a silent hang rather than an error naming the cause. Corrects item 81's closing note, which blamed the missing maildir key itself. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'docs')
-rw-r--r--docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md8
-rw-r--r--docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md55
2 files changed, 60 insertions, 3 deletions
diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md
index 50dd8ee..8cfa6b0 100644
--- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md
+++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md
@@ -4736,6 +4736,8 @@ A third surfaced while testing. A generated saved query that resolves to an
EMPTY query is skipped when the row is built (`src/mainwindow.cpp:1692`), so a
test asserting that Sent offers no rule action passed by finding no Sent button
at all. It needs a configured account with a sent folder to assert anything.
-An account section missing `maildir` does not merely fail, it HANGS
-`test_mainwindow` outright, which is how this was found: the suite ran past
-its two-minute timeout with no output.
+An account section missing `maildir` HANGS `test_mainwindow` outright, which is
+how this was found: the suite ran past its two-minute timeout with no output.
+The cause is not the account at all, it is `showWarnings()` raising a modal
+from the MainWindow constructor for any config problem, with nothing offscreen
+to dismiss it. Filed as item 84.
diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
index 16d7e23..ac830fa 100644
--- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
+++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md
@@ -148,6 +148,7 @@ taking that too literally.
| 81 | No way to turn a saved query into a tagging rule | workflow | S | **done** 2026-08-14, unreleased; see `specs/2026-08-14-query-to-rule-design.md` |
| 82 | A saved query cannot be edited, unpinned or deleted from the UI | defect | S | **done** 2026-08-13, shipped in 0.18.0. Right-click offers Edit, Pin/Unpin and Delete |
| 83 | A rule named with spaces is written to the file and dropped by every reader | defect | S | **done** 2026-08-14, unreleased. The name is sanitised into an id, save validates, a bad id loads for repair |
+| 84 | A config problem blocks `test_mainwindow` on a modal nobody can dismiss | testing | S | open; measured 2026-08-14, `showWarnings()` calls `QMessageBox::warning` from the constructor |
Sizes are rough: XS under an hour, S a sitting, M a session.
@@ -502,6 +503,60 @@ in CLAUDE.md.
**Size: M.**
+## 84. A config problem blocks `test_mainwindow` on a modal nobody can dismiss
+
+**Observed (2026-08-14):** a new test in `test_mainwindow` hung with no output
+and was killed at the two-minute timeout. It had configured an account section
+carrying only `sent=`, with no `maildir=`.
+
+**Cause (verified by attaching gdb to the hung process, not inferred).**
+
+```
+#7 QDialog::exec()
+#9 MainWindow::showWarnings ... src/mainwindow.cpp:1670
+#10 MainWindow::MainWindow ... src/mainwindow.cpp:381
+```
+
+`Config::load` handles the malformed account exactly as it should: it records
+"Account 'one' has no maildir; ignoring it" and carries on
+(`src/config.cpp:413-418`). `showWarnings()` then puts every collected problem
+in a `QMessageBox::warning`, which is modal, and it is called from the
+`MainWindow` CONSTRUCTOR. Under the offscreen platform nothing can dismiss it,
+so the constructor never returns.
+
+**This is not a defect in the application.** The modal is deliberate and is
+right for a person: a config problem should interrupt startup rather than
+scroll past, and the code comment at `src/mainwindow.cpp:1661` explains which
+problems qualify. A user sees the dialog and clicks OK. The defect is that a
+TEST cannot, and the failure it produces is a silent hang rather than an error
+naming the cause, which cost a debugging detour to identify.
+
+**Constraint on any fix: the modal must survive for real use.** Suppressing it
+whenever `QTEST_MAIN` is linked would be the obvious move and is wrong, since
+that is exactly the path `test_mainwindow` exercises and a suppressed dialog
+means the startup warning ships untested. Two candidates, neither yet chosen:
+
+- A `MainWindow` flag, defaulting to showing the modal, that the tests set. It
+ makes the behaviour explicit and testable in both states.
+- Collecting the problems and emitting them, with the modal raised by a caller
+ outside the constructor. Larger, and it separates "what is wrong" from "how
+ the user is told", which is the better shape if anything else ever needs the
+ list.
+
+**Related: every test that configures an account is one typo away from this.**
+The suite has several, all of them currently well-formed. A malformed one does
+not fail, it hangs, and a hang in CI reads as an infrastructure problem rather
+than a test problem.
+
+**A second trap sits on top of the first and wasted as much time.** A hang
+leaves the test binary running, and a later `ctest` then runs a STALE binary
+while the source on disk has moved on, so the failure appears to persist after
+it has been fixed and to vanish for reasons unconnected to the change. Kill any
+surviving `test_mainwindow` and rebuild before concluding anything about a hang
+here.
+
+**Size: S.** The diagnosis is the expensive part and it is already done.
+
## Deferred, unsized, or split out
Items noted while triaging but not part of the original list. Same numbering