diff --git a/tests/qttest/CMakeLists.txt b/tests/qttest/CMakeLists.txt index 644cf4725..ca8b577ec 100644 --- a/tests/qttest/CMakeLists.txt +++ b/tests/qttest/CMakeLists.txt @@ -290,6 +290,11 @@ qet_add_app_test(tst_assistantinfopaths tst_assistantinfopaths.cpp) # %T in a report or cross reference formula is the target folio's title. qet_add_app_test(tst_reportfoliotitle tst_reportfoliotitle.cpp) +# The cable cells of a terminal strip are worked out from the cables of +# the project: wired shows the cable and its core read only, unwired keeps +# what was typed in, and nothing stale is written into the element. +qet_add_app_test(tst_terminalcableauto tst_terminalcableauto.cpp) + # Escape during a picture's resize, rotate or pivot drag puts it back, keeps # it selected and records no undo step (#1414); the key goes to the view. qet_add_app_test(tst_imagehandleescape tst_imagehandleescape.cpp) diff --git a/tests/qttest/tst_terminalcableauto.cpp b/tests/qttest/tst_terminalcableauto.cpp new file mode 100644 index 000000000..c82a4c8cd --- /dev/null +++ b/tests/qttest/tst_terminalcableauto.cpp @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + Copyright 2006-2026 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "qetapptest.h" +#include "TerminalStrip/realterminal.h" +#include "TerminalStrip/terminalstrip.h" +#include "TerminalStrip/ui/terminalstripmodel.h" +#include "cable/cable.h" +#include "qetgraphicsitem/conductor.h" +#include "qetgraphicsitem/element.h" +#include "qetgraphicsitem/terminal.h" +#include "qetproject.h" + +/** + The Cable and Color / wire number columns of the terminal strip editor + are worked out from the cables of the project: a terminal with a cable + wired to it shows that cable and its core, the cell is read only, and + nothing is written into the element -- so a cable renamed or removed + cannot leave a stale value behind. A terminal no cable is wired to + keeps the value typed in by hand, cell and all. + + fixtures/every_feature.qet has the strip X1 whose two terminals are + wired to conductors on the folio, and no cable at all. +*/ +class tst_terminalcableauto : public QObject +{ + Q_OBJECT + + // The wired terminal of strip X1: its element carries a conductor. + static QSharedPointer wiredTerminal(QETProject &project) + { + const QVector strips = project.terminalStrip(); + if (strips.isEmpty()) return {}; + for (const QSharedPointer &real_t + : strips.first()->realTerminals()) + { + Element *element = real_t ? real_t->element() : nullptr; + if (!element) continue; + for (Terminal *terminal : element->terminals()) + if (terminal && !terminal->conductors().isEmpty()) + return real_t; + } + return {}; + } + + static Conductor *conductorOf(const QSharedPointer &real_t) + { + Element *element = real_t->element(); + if (!element) return nullptr; + for (Terminal *terminal : element->terminals()) { + if (!terminal) continue; + const QList conductors = terminal->conductors(); + if (!conductors.isEmpty()) return conductors.first(); + } + return nullptr; + } + + // The cable the create dialog hands over: owned by the project, four + // cores, core 1 (blue) wired to the terminal's conductor. + static Cable *wireCable(QETProject &project, + const QSharedPointer &real_t, + int core = 1) + { + Cable *cable = project.newCable(); + cable->setDesignation(QStringLiteral("15W1")); + cable->setCoreCount(4); + cable->setCoreColors({QStringLiteral("bn"), QStringLiteral("bl"), + QStringLiteral("gn/ye"), QStringLiteral("gy")}); + CableCore assignment; + assignment.core = core; + assignment.conductor = conductorOf(real_t)->uuid(); + cable->setCore(assignment); + return cable; + } + +private slots: + void wiredCableIsWorkedOutAndReadsOnly() + { + const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet"); + QVERIFY2(!fixture.isEmpty(), "fixture project not found"); + QETProject project(fixture); + QCOMPARE(project.state(), QETProject::Ok); + + const auto real_t = wiredTerminal(project); + QVERIFY2(!real_t.isNull(), "the fixture has a wired terminal"); + Element *element = real_t->element(); + + //Without a cable, the cells show nothing and may be typed in + QVERIFY(!real_t->cableIsAutomatic()); + TerminalStripModel model_before(project.terminalStrip().first()); + QVERIFY(model_before.rowCount() > 0); + QVERIFY(model_before.flags(model_before.index(0, TerminalStripModel::Cable)) + & Qt::ItemIsEditable); + + wireCable(project, real_t); + + //The terminal itself reads the cable and its core + QCOMPARE(real_t->cable(), QStringLiteral("15W1")); + QVERIFY(real_t->cableIsAutomatic()); + QCOMPARE(real_t->cableWire(), QStringLiteral("bl")); + + //The automatic value is never written into the element: nothing + //stays behind once the cable is renamed or removed + QVERIFY(element); + QVERIFY(element->elementData().m_informations + .value(RealTerminal::cableInfoKey()).toString().isEmpty()); + + //The model shows both cells and keeps them out of the edits + TerminalStripModel model(project.terminalStrip().first()); + QCOMPARE(model.rowCount(), model_before.rowCount()); + const QModelIndex cable_cell = model.index(0, TerminalStripModel::Cable); + const QModelIndex wire_cell = model.index(0, TerminalStripModel::CableWire); + QCOMPARE(model.data(cable_cell).toString(), QStringLiteral("15W1")); + QCOMPARE(model.data(wire_cell).toString(), QStringLiteral("bl")); + QVERIFY(!(model.flags(cable_cell) & Qt::ItemIsEditable)); + QVERIFY(!(model.flags(wire_cell) & Qt::ItemIsEditable)); + //The other cells go on being editable + QVERIFY(model.flags(model.index(0, TerminalStripModel::Label)) + & Qt::ItemIsEditable); + } + + void coreWithoutColorIsShownAsItsNumber() + { + const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet"); + QETProject project(fixture); + QCOMPARE(project.state(), QETProject::Ok); + + const auto real_t = wiredTerminal(project); + QVERIFY(!real_t.isNull()); + + Cable *cable = project.newCable(); + cable->setDesignation(QStringLiteral("15W1")); + cable->setCoreCount(4); + //A type file which gives no colours: the number of the core is shown + CableCore assignment; + assignment.core = 1; + assignment.conductor = conductorOf(real_t)->uuid(); + cable->setCore(assignment); + + QCOMPARE(real_t->cable(), QStringLiteral("15W1")); + QCOMPARE(real_t->cableWire(), QStringLiteral("2")); + QVERIFY(real_t->cableIsAutomatic()); + } + + void typedValueStaysWhenNoCableIsThere() + { + const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet"); + QETProject project(fixture); + QCOMPARE(project.state(), QETProject::Ok); + + const auto real_t = wiredTerminal(project); + QVERIFY(!real_t.isNull()); + Element *element = real_t->element(); + QVERIFY(element); + + //A cable designation typed in by hand in the editor + ElementData typed = element->elementData(); + typed.m_informations.addValue(RealTerminal::cableInfoKey(), + QStringLiteral("K9")); + element->setElementData(typed); + QCOMPARE(real_t->cable(), QStringLiteral("K9")); + QVERIFY(!real_t->cableIsAutomatic()); + + //Wired to a cable: the cable is shown, the typed value is set aside + Cable *cable = wireCable(project, real_t); + QCOMPARE(real_t->cable(), QStringLiteral("15W1")); + QVERIFY(real_t->cableIsAutomatic()); + QCOMPARE(real_t->cableWire(), QStringLiteral("bl")); + + //Cable removed: the typed value is back, no stale 15W1 anywhere + cable->removeCore(1); + QCOMPARE(real_t->cable(), QStringLiteral("K9")); + QVERIFY(!real_t->cableIsAutomatic()); + QVERIFY(element->elementData().m_informations + .value(RealTerminal::cableInfoKey()) + .toString() == QStringLiteral("K9")); + + TerminalStripModel model(project.terminalStrip().first()); + QVERIFY(model.flags(model.index(0, TerminalStripModel::Cable)) + & Qt::ItemIsEditable); + } +}; + +QET_APP_TEST_MAIN(tst_terminalcableauto) + +#include "tst_terminalcableauto.moc"