#include "TestFixtures.h" #include "core/NetworkModel.h" #include #include using namespace diag; class TestModel : public QObject { Q_OBJECT private slots: void init() { fixtures::fillRegistry(m_reg); delete m_model; m_model = new NetworkModel(&m_reg, this); } void addNode_unknownTypeFails() { QVERIFY(m_model->addNode(QStringLiteral("nope"), {0, 0}).isNull()); QCOMPARE(m_model->nodeIds().size(), 0); } void addNode_emitsAndStores() { QSignalSpy spy(m_model, &NetworkModel::nodeAdded); const QUuid id = m_model->addNode(QStringLiteral("pump"), {100, 40}); QVERIFY(!id.isNull()); QCOMPARE(spy.count(), 1); QCOMPARE(m_model->node(id)->pos, QPointF(100, 40)); QCOMPARE(m_model->nodeTypeOf(id)->id, QStringLiteral("pump")); } void connect_validOutToIn() { const QUuid src = m_model->addNode(QStringLiteral("source"), {0, 0}); const QUuid pump = m_model->addNode(QStringLiteral("pump"), {200, 0}); QVERIFY(m_model->canConnect(src, "out", pump, "in")); const QUuid e = m_model->addEdge(src, "out", pump, "in"); QVERIFY(!e.isNull()); QCOMPARE(m_model->edge(e)->relation, QStringLiteral("water")); } void connect_directionNormalized() { // Dragging from the In port must still produce an Out->In edge. const QUuid src = m_model->addNode(QStringLiteral("source"), {0, 0}); const QUuid pump = m_model->addNode(QStringLiteral("pump"), {200, 0}); const QUuid e = m_model->addEdge(pump, "in", src, "out"); QVERIFY(!e.isNull()); QCOMPARE(m_model->edge(e)->fromNode, src); QCOMPARE(m_model->edge(e)->toNode, pump); } void connect_relationMismatchFails() { const QUuid gen = m_model->addNode(QStringLiteral("generator"), {0, 0}); const QUuid pump = m_model->addNode(QStringLiteral("pump"), {200, 0}); QString reason; QVERIFY(!m_model->canConnect(gen, "out", pump, "in", &reason)); QVERIFY(reason.contains(QStringLiteral("relation"))); QVERIFY(m_model->addEdge(gen, "out", pump, "in").isNull()); } void connect_twoInputsFails() { const QUuid a = m_model->addNode(QStringLiteral("pump"), {0, 0}); const QUuid b = m_model->addNode(QStringLiteral("consumer"), {200, 0}); QVERIFY(!m_model->canConnect(a, "in", b, "in")); } void connect_selfPortFails() { const QUuid j = m_model->addNode(QStringLiteral("junction"), {0, 0}); QVERIFY(!m_model->canConnect(j, "w", j, "w")); // Different ports on the same node are allowed. QVERIFY(m_model->canConnect(j, "w", j, "e")); } void connect_occupiedPortFails() { const QUuid src = m_model->addNode(QStringLiteral("source"), {0, 0}); const QUuid p1 = m_model->addNode(QStringLiteral("pump"), {200, 0}); const QUuid p2 = m_model->addNode(QStringLiteral("pump"), {200, 100}); QVERIFY(!m_model->addEdge(src, "out", p1, "in").isNull()); QString reason; QVERIFY(!m_model->canConnect(p2, "out", p1, "in", &reason)); QVERIFY(reason.contains(QStringLiteral("occupied"))); // Source "out" is unlimited (maxConnections = 0). QVERIFY(m_model->canConnect(src, "out", p2, "in")); } void connect_duplicateEdgeFails() { const QUuid src = m_model->addNode(QStringLiteral("source"), {0, 0}); const QUuid j = m_model->addNode(QStringLiteral("junction"), {200, 0}); QVERIFY(!m_model->addEdge(src, "out", j, "w").isNull()); QVERIFY(!m_model->canConnect(src, "out", j, "w")); QVERIFY(!m_model->canConnect(j, "w", src, "out")); } void junction_allowsManyConnections() { const QUuid j = m_model->addNode(QStringLiteral("junction"), {0, 0}); const QUuid src = m_model->addNode(QStringLiteral("source"), {-200, 0}); const QUuid c1 = m_model->addNode(QStringLiteral("consumer"), {200, -100}); const QUuid c2 = m_model->addNode(QStringLiteral("consumer"), {200, 100}); QVERIFY(!m_model->addEdge(src, "out", j, "w").isNull()); QVERIFY(!m_model->addEdge(j, "e", c1, "in").isNull()); QVERIFY(!m_model->addEdge(j, "e", c2, "in").isNull()); QCOMPARE(m_model->connectionCount(j, "e"), 2); } void removeNode_cascadesEdges() { const QUuid src = m_model->addNode(QStringLiteral("source"), {0, 0}); const QUuid pump = m_model->addNode(QStringLiteral("pump"), {200, 0}); const QUuid c = m_model->addNode(QStringLiteral("consumer"), {400, 0}); m_model->addEdge(src, "out", pump, "in"); m_model->addEdge(pump, "out", c, "in"); QSignalSpy edgeSpy(m_model, &NetworkModel::edgeRemoved); m_model->removeNode(pump); QCOMPARE(edgeSpy.count(), 2); QCOMPARE(m_model->edgeIds().size(), 0); QCOMPARE(m_model->nodeIds().size(), 2); } void moveNode_emitsAndUpdatesPortPos() { const QUuid pump = m_model->addNode(QStringLiteral("pump"), {0, 0}); QSignalSpy spy(m_model, &NetworkModel::nodeMoved); m_model->moveNode(pump, {100, 100}); QCOMPARE(spy.count(), 1); // Port "out" is at relative (1.0, 0.5) of a 60x60 node. QCOMPARE(m_model->portScenePos(pump, "out"), QPointF(160, 130)); } private: TypeRegistry m_reg; NetworkModel* m_model = nullptr; }; QTEST_GUILESS_MAIN(TestModel) #include "tst_model.moc"