mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-10 14:14:18 +02:00
Add a terminal name check when saving an element
Discussion #1157. IEC 61666 §4.1 requires each terminal to be identified unambiguously within its object, so two terminals of one element must not share a name. On save, the element editor now: - refuses to save when two terminals share a name, lists the names ("N ×3") and selects those terminals; - warns, and still saves, when a terminal has no name. Folio reports, conductor definitions and thumbnails are skipped. Names are compared after trimming surrounding spaces, case sensitive. Settings > General > Editor has a new checkbox, on by default, that turns both checks off (elementeditor/check-terminal-names). --check-elements applies the same rule: repeated names are a FAIL, missing names a WARN. It ignores the setting, since it is an explicit check. On the shipped collection this reports 82 FAILs, the elements that repeat a terminal name today. The rule lives in the header-only editor/terminalnamecheck.h, shared by both, and is unit tested by tst_terminalnamecheck. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -111,6 +111,13 @@ add_test(NAME tst_alignment COMMAND tst_alignment)
|
||||
target_include_directories(tst_alignment PRIVATE ${QET_DIR}/sources)
|
||||
target_link_libraries(tst_alignment PRIVATE Qt::Test)
|
||||
|
||||
# terminalnamecheck.h is header-only: the terminal name rule applied by the
|
||||
# element editor on save and by --check-elements.
|
||||
add_executable(tst_terminalnamecheck tst_terminalnamecheck.cpp)
|
||||
add_test(NAME tst_terminalnamecheck COMMAND tst_terminalnamecheck)
|
||||
target_include_directories(tst_terminalnamecheck PRIVATE ${QET_DIR}/sources)
|
||||
target_link_libraries(tst_terminalnamecheck PRIVATE Qt::Test)
|
||||
|
||||
# itemgroups.cpp keeps group membership and the selection rule apart from
|
||||
# Diagram, so it is tested here on a plain scene of rectangles.
|
||||
add_executable(tst_itemgroups tst_itemgroups.cpp ${QET_DIR}/sources/itemgroups.cpp)
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#include <QtTest>
|
||||
|
||||
#include "editor/terminalnamecheck.h"
|
||||
|
||||
class tst_terminalnamecheck : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void uniqueNamesPass()
|
||||
{
|
||||
QVERIFY(TerminalNameCheck::repeatedNames({"A1", "A2", "13", "14"}).isEmpty());
|
||||
}
|
||||
|
||||
// Shelly Pro 2PM in the shipped collection: three terminals named N.
|
||||
void repeatedNamesAreCounted()
|
||||
{
|
||||
const auto repeated = TerminalNameCheck::repeatedNames(
|
||||
{"L", "N", "O1", "N", "O2", "N", "L"});
|
||||
QCOMPARE(repeated.size(), 2);
|
||||
QCOMPARE(repeated.at(0), qMakePair(QString("L"), 2));
|
||||
QCOMPARE(repeated.at(1), qMakePair(QString("N"), 3));
|
||||
QCOMPARE(TerminalNameCheck::describe(repeated),
|
||||
QString::fromUtf8("L ×2, N ×3"));
|
||||
}
|
||||
|
||||
void surroundingSpacesAreIgnored()
|
||||
{
|
||||
QCOMPARE(TerminalNameCheck::repeatedNames({"PE", " PE "}).size(), 1);
|
||||
}
|
||||
|
||||
void caseMatters()
|
||||
{
|
||||
QVERIFY(TerminalNameCheck::repeatedNames({"n", "N"}).isEmpty());
|
||||
}
|
||||
|
||||
// Unnamed terminals are reported as unnamed, never as a repeat of "".
|
||||
void unnamedAreNotRepeats()
|
||||
{
|
||||
const QStringList names{"", " ", "1", ""};
|
||||
QVERIFY(TerminalNameCheck::repeatedNames(names).isEmpty());
|
||||
QCOMPARE(TerminalNameCheck::unnamedCount(names), 3);
|
||||
}
|
||||
|
||||
// describe() goes into a tr() message with %1: a name holding %2 stays literal.
|
||||
void describeKeepsPercentLiteral()
|
||||
{
|
||||
QCOMPARE(TerminalNameCheck::describe({qMakePair(QString("%2"), 2)}),
|
||||
QString::fromUtf8("%2 ×2"));
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_GUILESS_MAIN(tst_terminalnamecheck)
|
||||
|
||||
#include "tst_terminalnamecheck.moc"
|
||||
Reference in New Issue
Block a user