mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-04 18:04:14 +02:00
2e2801b617
qet.deleteElement() built its DeleteQGraphicsItemCommand from the element alone. The Delete key's selection also carries the wires on the element's terminals (DiagramContent's conductors to update), and the command removes those with it. From a script they stayed: still listed by qet.conductorUuids(), still saved, attached to an element that was gone. The wires on the element's terminals now go into the command, as for the Delete key. tst_scriptconductoruuid checks that no wire is left with an end on the deleted element (it failed before this change: 1 left). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015FPuYPS4T7QuEwjNu22rXD
127 lines
5.0 KiB
C++
127 lines
5.0 KiB
C++
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
#include <QtTest>
|
|
|
|
#include <QFile>
|
|
#include <QJsonArray>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QProcess>
|
|
#include <QProcessEnvironment>
|
|
#include <QTemporaryDir>
|
|
#include <QUuid>
|
|
|
|
// qet.conductorUuids(folio) and qet.conductorEnds(folio, uuid): a script can
|
|
// list a folio's conductors by uuid and find where each one runs, in the
|
|
// "{element} terminal N" form conductors() prints and the conductor calls
|
|
// take. Runs a script through the real binary's --run.
|
|
class tst_scriptconductoruuid : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
QTemporaryDir m_dir;
|
|
|
|
// Run @p script on the fixture in a sandbox of its own and return the
|
|
// JSON object it logged.
|
|
QJsonObject run(const QString &script)
|
|
{
|
|
const QString path = m_dir.filePath(QStringLiteral("probe.js"));
|
|
const QString home = m_dir.filePath(QStringLiteral("home"));
|
|
QDir().mkpath(home);
|
|
QFile f(path);
|
|
if (!f.open(QIODevice::WriteOnly)) return {};
|
|
f.write(script.toUtf8());
|
|
f.close();
|
|
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
env.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("offscreen"));
|
|
env.insert(QStringLiteral("QET_ENABLE_SCRIPTING"), QStringLiteral("1"));
|
|
env.insert(QStringLiteral("HOME"), home);
|
|
env.insert(QStringLiteral("XDG_CONFIG_HOME"), home + QStringLiteral("/config"));
|
|
env.insert(QStringLiteral("XDG_DATA_HOME"), home + QStringLiteral("/data"));
|
|
QProcess proc;
|
|
proc.setProcessEnvironment(env);
|
|
proc.start(QStringLiteral(QET_TEST_BINARY_PATH),
|
|
{QStringLiteral("--run"), path,
|
|
QFINDTESTDATA("fixtures/qet_bug_repro_resaved.qet")});
|
|
if (!proc.waitForFinished(60000)) return {};
|
|
const QString out = QString::fromUtf8(proc.readAllStandardOutput()
|
|
+ proc.readAllStandardError());
|
|
const QString mark = QStringLiteral("PROBE ");
|
|
for (const QString &line : out.split(QLatin1Char('\n'))) {
|
|
const int i = line.indexOf(mark);
|
|
if (i >= 0)
|
|
return QJsonDocument::fromJson(line.mid(i + mark.size()).toUtf8()).object();
|
|
}
|
|
return {};
|
|
}
|
|
|
|
private slots:
|
|
void initTestCase()
|
|
{
|
|
QVERIFY(m_dir.isValid());
|
|
QVERIFY(QFile::exists(QStringLiteral(QET_TEST_BINARY_PATH)));
|
|
}
|
|
|
|
void uuidsAndEndsMatchConductors()
|
|
{
|
|
const QJsonObject r = run(QStringLiteral(
|
|
"var uuids = qet.conductorUuids(0);\n"
|
|
"var ends = uuids.map(function (u) { return qet.conductorEnds(0, u); });\n"
|
|
"qet.log('PROBE ' + JSON.stringify({lines: qet.conductors(0), uuids: uuids, ends: ends,\n"
|
|
" unknown: qet.conductorEnds(0, '{00000000-0000-0000-0000-000000000001}'),\n"
|
|
" junk: qet.conductorEnds(0, 'not a uuid'),\n"
|
|
" badFolio: qet.conductorUuids(99)}));\n"));
|
|
QVERIFY2(!r.isEmpty(), "the script logged nothing");
|
|
|
|
const QJsonArray lines = r.value(QStringLiteral("lines")).toArray();
|
|
const QJsonArray uuids = r.value(QStringLiteral("uuids")).toArray();
|
|
const QJsonArray ends = r.value(QStringLiteral("ends")).toArray();
|
|
QCOMPARE(lines.size(), 7); // the fixture's conductors
|
|
QCOMPARE(uuids.size(), lines.size());
|
|
QSet<QString> distinct;
|
|
for (int i = 0; i < uuids.size(); ++i) {
|
|
const QString u = uuids.at(i).toString();
|
|
QVERIFY2(!QUuid(u).isNull(), qPrintable(u));
|
|
distinct.insert(u);
|
|
// same order as conductors(), and the same two ends it prints
|
|
const QJsonArray e = ends.at(i).toArray();
|
|
QCOMPARE(e.size(), 2);
|
|
const QString expected = e.at(0).toString() + QStringLiteral(" -- ")
|
|
+ e.at(1).toString() + QStringLiteral(" : ");
|
|
QVERIFY2(lines.at(i).toString().startsWith(expected),
|
|
qPrintable(lines.at(i).toString() + QStringLiteral(" | ") + expected));
|
|
}
|
|
QCOMPARE(distinct.size(), uuids.size());
|
|
|
|
QVERIFY(r.value(QStringLiteral("unknown")).toArray().isEmpty());
|
|
QVERIFY(r.value(QStringLiteral("junk")).toArray().isEmpty());
|
|
QVERIFY(r.value(QStringLiteral("badFolio")).toArray().isEmpty());
|
|
}
|
|
|
|
// qet.deleteElement() takes the wires on the element's terminals with
|
|
// it, as the Delete key does; they used to stay on the folio, attached
|
|
// to an element that was gone.
|
|
void deleteElementTakesItsWires()
|
|
{
|
|
const QJsonObject r = run(QStringLiteral(
|
|
"var p = 'embed://import/probe/v2_fuse.elmt';\n"
|
|
"var a = qet.addElement(0, p, 400, 400);\n"
|
|
"var b = qet.addElement(0, p, 470, 490);\n"
|
|
"qet.addConductor(0, a, 0, b, 0);\n"
|
|
"var before = qet.conductorUuids(0).length;\n"
|
|
"var deleted = qet.deleteElement(0, a);\n"
|
|
"var dangling = qet.conductorUuids(0).filter(function (u) {\n"
|
|
" return qet.conductorEnds(0, u).some(function (e) { return e.indexOf(a) === 0; }); });\n"
|
|
"qet.log('PROBE ' + JSON.stringify({deleted: deleted, before: before,\n"
|
|
" after: qet.conductorUuids(0).length, dangling: dangling.length}));\n"));
|
|
QVERIFY2(!r.isEmpty(), "the script logged nothing");
|
|
QVERIFY(r.value(QStringLiteral("deleted")).toBool());
|
|
QCOMPARE(r.value(QStringLiteral("dangling")).toInt(), 0);
|
|
QCOMPARE(r.value(QStringLiteral("after")).toInt(), r.value(QStringLiteral("before")).toInt() - 1);
|
|
}
|
|
};
|
|
|
|
QTEST_APPLESS_MAIN(tst_scriptconductoruuid)
|
|
|
|
#include "tst_scriptconductoruuid.moc"
|