Bundled registry/sample loading, edge selection populating the grouped property panel, undoable title edit, solver + animation clock, and a headless render smoke check. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
139 lines
4.7 KiB
C++
139 lines
4.7 KiB
C++
// End-to-end scenarios against the real MainWindow with bundled resources
|
|
// (registry config, SVGs, sample document), offscreen.
|
|
|
|
#include "app/MainWindow.h"
|
|
#include "app/PropertyPanel.h"
|
|
#include "core/FlowSolver.h"
|
|
#include "core/NetworkModel.h"
|
|
#include "scene/DiagramScene.h"
|
|
#include "scene/EdgeItem.h"
|
|
#include "scene/NodeItem.h"
|
|
|
|
#include <QComboBox>
|
|
#include <QDoubleSpinBox>
|
|
#include <QGroupBox>
|
|
#include <QLineEdit>
|
|
#include <QTest>
|
|
#include <QUndoStack>
|
|
|
|
using namespace diag;
|
|
|
|
class TestApp : public QObject {
|
|
Q_OBJECT
|
|
private slots:
|
|
void initTestCase()
|
|
{
|
|
Q_INIT_RESOURCE(resources);
|
|
}
|
|
|
|
void registryLoads_fromBundledConfig()
|
|
{
|
|
MainWindow window;
|
|
const TypeRegistry* reg = window.model()->registry();
|
|
QVERIFY(reg->nodeTypes().size() >= 9);
|
|
QVERIFY(reg->relation(QStringLiteral("water")));
|
|
QVERIFY(reg->relation(QStringLiteral("power")));
|
|
QVERIFY(reg->catalogue(QStringLiteral("pipe_series")));
|
|
QCOMPARE(reg->nodeGroups(),
|
|
(QStringList{QStringLiteral("Water supply"), QStringLiteral("Power")}));
|
|
}
|
|
|
|
void sampleLoads_andRoutes()
|
|
{
|
|
MainWindow window;
|
|
window.show();
|
|
window.loadSample();
|
|
QVERIFY(window.model()->nodeIds().size() >= 8);
|
|
QVERIFY(window.model()->edgeIds().size() >= 7);
|
|
// Every edge item has an orthogonal polyline attached to its ports.
|
|
for (QUuid id : window.model()->edgeIds()) {
|
|
EdgeItem* item = window.scene()->edgeItem(id);
|
|
QVERIFY(item);
|
|
QVERIFY(item->polyline().size() >= 2);
|
|
}
|
|
}
|
|
|
|
void selectingEdge_populatesGroupedPropertyPanel()
|
|
{
|
|
MainWindow window;
|
|
window.show();
|
|
window.loadSample();
|
|
const QUuid edgeId = window.model()->edgeIds().first();
|
|
window.scene()->clearSelection();
|
|
window.scene()->edgeItem(edgeId)->setSelected(true);
|
|
|
|
auto* panel = window.findChild<PropertyPanel*>();
|
|
QVERIFY(panel);
|
|
const auto groups = panel->findChildren<QGroupBox*>();
|
|
QStringList titles;
|
|
for (auto* g : groups)
|
|
titles << g->title();
|
|
QVERIFY(titles.contains(QStringLiteral("General")));
|
|
QVERIFY(titles.contains(QStringLiteral("Presentation")));
|
|
QVERIFY(titles.contains(QStringLiteral("Physics")));
|
|
// Style enums and physics editors exist.
|
|
QVERIFY(panel->findChildren<QComboBox*>().size() >= 3);
|
|
QVERIFY(panel->findChildren<QDoubleSpinBox*>().size() >= 2);
|
|
}
|
|
|
|
void editingTitle_isUndoable()
|
|
{
|
|
MainWindow window;
|
|
window.show();
|
|
window.loadSample();
|
|
const QUuid nodeId = window.model()->nodeIds().first();
|
|
window.scene()->clearSelection();
|
|
window.scene()->nodeItem(nodeId)->setSelected(true);
|
|
|
|
auto* panel = window.findChild<PropertyPanel*>();
|
|
auto* titleEdit = panel->findChild<QLineEdit*>();
|
|
QVERIFY(titleEdit);
|
|
titleEdit->setText(QStringLiteral("Renamed"));
|
|
emit titleEdit->editingFinished();
|
|
QCOMPARE(window.model()->nodeProperty(nodeId, "title").toString(),
|
|
QStringLiteral("Renamed"));
|
|
window.scene()->undoStack()->undo();
|
|
QCOMPARE(window.model()->nodeProperty(nodeId, "title").toString(),
|
|
QStringLiteral("Intake"));
|
|
}
|
|
|
|
void simulation_assignsFlowsAndAnimates()
|
|
{
|
|
MainWindow window;
|
|
window.show();
|
|
window.loadSample();
|
|
window.scene()->setFlowAnimationEnabled(true);
|
|
|
|
// Solve both networks like the Simulation menu action does.
|
|
for (const Relation& rel : window.model()->registry()->relations())
|
|
FlowSolver::apply(*window.model(),
|
|
FlowSolver::solve(*window.model(), rel.id));
|
|
|
|
// Water main from the intake carries the full balanced demand.
|
|
double maxWater = 0;
|
|
for (QUuid id : window.model()->edgeIds())
|
|
if (window.model()->edge(id)->relation == QLatin1String("water"))
|
|
maxWater = qMax(maxWater, qAbs(window.model()->edge(id)->flowRate));
|
|
QVERIFY(maxWater > 1.0);
|
|
QVERIFY(window.scene()->maxAbsFlow() >= maxWater);
|
|
|
|
const double phase0 = window.scene()->animationPhase();
|
|
QTRY_VERIFY_WITH_TIMEOUT(window.scene()->animationPhase() > phase0, 1000);
|
|
window.scene()->setFlowAnimationEnabled(false);
|
|
}
|
|
|
|
void screenshot_rendersWithoutCrash()
|
|
{
|
|
MainWindow window;
|
|
window.resize(1000, 700);
|
|
window.show();
|
|
window.loadSample();
|
|
const QPixmap shot = window.grab();
|
|
QVERIFY(!shot.isNull());
|
|
QVERIFY(shot.width() > 0);
|
|
}
|
|
};
|
|
|
|
QTEST_MAIN(TestApp)
|
|
#include "tst_app.moc"
|