// SPDX-License-Identifier: GPL-2.0-or-later #include #include #include #include #include #include #include #include "wiringrules.h" // How many wires a terminal may take (discussion #1158). The rules are // tested on their own; the project setting and the refusal are tested // through the real binary: --resave keeps a element and // adds none to a project without it, and qet.addConductor() is refused // past the limit unless the master switch is off. class tst_wiringrules : public QObject { Q_OBJECT QTemporaryDir m_dir; int m_run = 0; // Environment of one sandboxed run; @p master_off writes the master // switch off into that run's own settings. QProcessEnvironment sandbox(bool master_off = false) { const QString home = m_dir.filePath(QStringLiteral("home%1").arg(m_run)); const QString tmp = m_dir.filePath(QStringLiteral("tmp%1").arg(m_run)); const QString settings = m_dir.filePath(QStringLiteral("settings%1").arg(m_run)); ++m_run; QDir().mkpath(home); QDir().mkpath(tmp); QDir().mkpath(settings + QStringLiteral("/QElectroTech")); if (master_off) { QFile ini(settings + QStringLiteral("/QElectroTech/QElectroTech.ini")); if (ini.open(QIODevice::WriteOnly | QIODevice::Text)) ini.write("[diagrameditor]\nwiring_rules_enabled=false\n"); } 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("/.local/share")); env.insert(QStringLiteral("QET_SETTINGS_DIR"), settings); env.insert(QStringLiteral("TMPDIR"), tmp); return env; } // The fixture with @p rules inserted before , as a new file QString fixtureWith(const QString &rules) { QFile source(QFINDTESTDATA("fixtures/qet_bug_repro_resaved.qet")); if (!source.open(QIODevice::ReadOnly | QIODevice::Text)) return {}; QString text = QString::fromUtf8(source.readAll()); const int newdiagrams = text.indexOf(QLatin1String("= 0) return line.mid(i + mark.size()).trimmed(); } return {}; } private slots: void initTestCase() { QVERIFY(m_dir.isValid()); QVERIFY(QFile::exists(QStringLiteral(QET_TEST_BINARY_PATH))); } void limit() { WiringRules::Settings rules; QCOMPARE(WiringRules::limit(rules, true, false), 0); QCOMPARE(WiringRules::limit(rules, true, true), 0); rules.max_wires = 4; QCOMPARE(WiringRules::limit(rules, true, false), 4); QCOMPARE(WiringRules::limit(rules, true, true), 4); rules.one_wire_per_report = true; QCOMPARE(WiringRules::limit(rules, true, true), 1); QCOMPARE(WiringRules::limit(rules, true, false), 4); // The master switch turns every rule off QCOMPARE(WiringRules::limit(rules, false, false), 0); QCOMPARE(WiringRules::limit(rules, false, true), 0); } void hasRoom() { QVERIFY(WiringRules::hasRoom(0, 0)); QVERIFY(WiringRules::hasRoom(0, 19)); QVERIFY(WiringRules::hasRoom(2, 1)); QVERIFY(!WiringRules::hasRoom(2, 2)); QVERIFY(!WiringRules::hasRoom(2, 3)); QVERIFY(!WiringRules::hasRoom(1, 1)); } void xmlRoundTrip() { QDomDocument doc; QDomElement root = doc.createElement(QStringLiteral("project")); doc.appendChild(root); // No rule: nothing written, and reading nothing gives no rule WiringRules::toXml(WiringRules::Settings(), root); QVERIFY(root.firstChildElement().isNull()); QVERIFY(WiringRules::fromXml(root).isDefault()); WiringRules::Settings rules; rules.max_wires = 2; rules.one_wire_per_report = true; WiringRules::toXml(rules, root); QCOMPARE(root.firstChildElement().tagName(), QStringLiteral("wiring_rules")); QVERIFY(WiringRules::fromXml(root) == rules); } void savedSettingSurvivesResave() { const QString plain = resave(QFINDTESTDATA("fixtures/qet_bug_repro_resaved.qet")); QVERIFY2(!plain.isEmpty(), "--resave failed"); QVERIFY(!plain.contains(QLatin1String("wiring_rules"))); const QString with_rules = fixtureWith( QStringLiteral("")); QVERIFY(!with_rules.isEmpty()); const QString saved = resave(with_rules); QVERIFY2(!saved.isEmpty(), "--resave failed"); QVERIFY2(saved.contains(QLatin1String("max_wires_per_terminal=\"2\"")) && saved.contains(QLatin1String("one_wire_per_report=\"true\"")), "the setting was lost on save"); } void wirePastTheLimitIsRefused() { // Without a rule the wire is drawn, as on master QCOMPARE(addWireToWiredTerminal(QFINDTESTDATA("fixtures/qet_bug_repro_resaved.qet"), false), QStringLiteral("true")); // One wire per terminal: the terminal is full const QString limited = fixtureWith( QStringLiteral("")); QVERIFY(!limited.isEmpty()); QCOMPARE(addWireToWiredTerminal(limited, false), QStringLiteral("false")); // The master switch off: the project's rule does nothing QCOMPARE(addWireToWiredTerminal(limited, true), QStringLiteral("true")); } }; QTEST_GUILESS_MAIN(tst_wiringrules) #include "tst_wiringrules.moc"