From 959695ed5c42d9911090198a4006ae76f41f4f7f Mon Sep 17 00:00:00 2001 From: hairykiwi <174199+hairykiwi@users.noreply.github.com> Date: Sun, 18 Oct 2026 13:01:27 +0100 Subject: [PATCH] Add regression test for elements-panel project-open auto-select crash - tst_elementspanelprojectopen drives ElementsPanel::projectWasOpened() -- the slot the application connects to a project being opened -- on a fresh panel whose first reload() has not run, reproducing the detached-item ordering deterministically offscreen. - On master without the guard the test fails: the auto-select leaves currentItem() pointing at an item whose treeWidget() is not the panel (and on some builds crashes in QTreeModel). With the guard it passes: no item is selected while the project is detached. - Registered via qet_add_app_test(), which links the application code and runs a real QETApp offscreen. Generated-by: Claude Code Signed-off-by: hairykiwi <174199+hairykiwi@users.noreply.github.com> --- tests/qttest/CMakeLists.txt | 5 +++ tests/qttest/tst_elementspanelprojectopen.cpp | 44 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 tests/qttest/tst_elementspanelprojectopen.cpp diff --git a/tests/qttest/CMakeLists.txt b/tests/qttest/CMakeLists.txt index 6dd92f413..5355ea699 100644 --- a/tests/qttest/CMakeLists.txt +++ b/tests/qttest/CMakeLists.txt @@ -290,6 +290,11 @@ qet_add_app_test(tst_folioimageload tst_folioimageload.cpp) # selection has nothing to edit for a moment (#1439). qet_add_app_test(tst_selectionpanelheight tst_selectionpanelheight.cpp) +# Opening a project before the elements panel's first reload() left its tree +# item detached, and selecting the item's first child crashed in QTreeModel +# (pre-existing since a82f6de23). +qet_add_app_test(tst_elementspanelprojectopen tst_elementspanelprojectopen.cpp) + # SVG export with smaller pictures (--svg-small-pictures, the export dialog's # option): a picture drawn at a tenth of its size is stored at four times # that, a small one whole; without the option every picture is whole. diff --git a/tests/qttest/tst_elementspanelprojectopen.cpp b/tests/qttest/tst_elementspanelprojectopen.cpp new file mode 100644 index 000000000..41cb1b8cf --- /dev/null +++ b/tests/qttest/tst_elementspanelprojectopen.cpp @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include "qetapptest.h" + +#include "elementspanel.h" +#include "projectview.h" +#include "qetproject.h" + +// projectWasOpened() adds the project to the elements panel. Before the panel's +// first reload() the project's tree item is left detached (treeWidget() == +// nullptr), and selecting its first child crashed in QTreeModel +// (pre-existing since a82f6de23). +class tst_elementspanelprojectopen : public QObject +{ + Q_OBJECT + + private slots: + void addProjectBeforeReloadDoesNotCrash() + { + // A real one-folio project from the running app; diagrams() + // builds the lazy folio, so the project item will have a child. + QETDiagramEditor *editor = QetAppTest::editor(); + QVERIFY(editor); + QVERIFY(editor->newProject()); + ProjectView *pv = editor->currentProjectView(); + QVERIFY(pv); + QETProject *project = pv->project(); + QVERIFY(project); + QVERIFY(!project->diagrams().isEmpty()); + + // Fresh panel: reload() has not run, so the project item is inserted detached. + ElementsPanel panel; + + // Without the guard this selects a detached item; with it, nothing is selected. + panel.projectWasOpened(project); + + QTreeWidgetItem *current = panel.currentItem(); + QVERIFY2(current == nullptr || current->treeWidget() == &panel, + "the panel selected a detached item it does not own"); + } +}; + +QET_APP_TEST_MAIN(tst_elementspanelprojectopen) + +#include "tst_elementspanelprojectopen.moc"