diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-14 11:46:47 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-14 11:46:47 +0200 |
| commit | 8f1ff70f4fabf9c077fa26b2ca99c6664d1b146b (patch) | |
| tree | 54bd706bae73a110678b992ad24d034ddab77f1c | |
| parent | 1c3f86d5a8e62f8617bbf1b7b834c81701e8b5c4 (diff) | |
| download | qtmaildir-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>
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md | 8 | ||||
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md | 55 |
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 |
