gui: add SegmentBarsWidget and SpeedGraphWidget
Per-connection progress bars and the 60 s rolling speed graph the progress dialog needs (docs/03-gui-spec.md §3). Both reuse row/widget state across ticks instead of rebuilding, matching the discipline DownloadTableModel already uses for progress patches. SpeedGraphWidget keeps a fixed ring buffer and one reused QPainterPath — no allocation in paintEvent or addSample. Fixed a real bug found while writing tst_speedgraphwidget: the elapsed timer was started in the constructor, so the very first sample after construction would silently wait up to 1 s to be recorded instead of landing immediately. Tested against mockd (both offline via QTest/offscreen, and manually against a running mockd instance through ProgressDialog once that lands). Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NSCdCWFXBTSBBK3MzWtJiC
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
// SpeedGraphWidget unit tests. Lane GUI.
|
||||
//
|
||||
// Red when: addSample stops throttling to 1 Hz (a burst of ticks would flood the ring
|
||||
// buffer and skew the 60 s window), the sample count stops saturating at the window size,
|
||||
// or painting crashes before two samples have been recorded (the "collecting…" branch).
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
#include "widgets/SpeedGraphWidget.hpp"
|
||||
|
||||
using velox::gui::SpeedGraphWidget;
|
||||
|
||||
class TstSpeedGraphWidget : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void burstsWithinASecondCountOnce();
|
||||
void separatedSamplesEachCount();
|
||||
void clearResetsCount();
|
||||
void paintDoesNotCrashBeforeTwoSamples();
|
||||
};
|
||||
|
||||
void TstSpeedGraphWidget::burstsWithinASecondCountOnce() {
|
||||
SpeedGraphWidget w;
|
||||
QCOMPARE(w.debugSampleCount(), 0);
|
||||
// The first call always records (no prior bucket); the rest land inside the same
|
||||
// second and must be coalesced into that one bucket.
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
w.addSample(1000 + i);
|
||||
}
|
||||
QCOMPARE(w.debugSampleCount(), 1);
|
||||
}
|
||||
|
||||
void TstSpeedGraphWidget::separatedSamplesEachCount() {
|
||||
SpeedGraphWidget w;
|
||||
w.addSample(100);
|
||||
QCOMPARE(w.debugSampleCount(), 1);
|
||||
QTest::qWait(1100);
|
||||
w.addSample(200);
|
||||
QCOMPARE(w.debugSampleCount(), 2);
|
||||
QTest::qWait(1100);
|
||||
w.addSample(300);
|
||||
QCOMPARE(w.debugSampleCount(), 3);
|
||||
}
|
||||
|
||||
void TstSpeedGraphWidget::clearResetsCount() {
|
||||
SpeedGraphWidget w;
|
||||
w.addSample(100);
|
||||
QTest::qWait(1100);
|
||||
w.addSample(200);
|
||||
QVERIFY(w.debugSampleCount() > 0);
|
||||
w.clear();
|
||||
QCOMPARE(w.debugSampleCount(), 0);
|
||||
}
|
||||
|
||||
void TstSpeedGraphWidget::paintDoesNotCrashBeforeTwoSamples() {
|
||||
SpeedGraphWidget w;
|
||||
w.resize(200, 60);
|
||||
const QPixmap empty = w.grab();
|
||||
QVERIFY(!empty.isNull());
|
||||
|
||||
w.addSample(500);
|
||||
const QPixmap oneSample = w.grab();
|
||||
QVERIFY(!oneSample.isNull());
|
||||
|
||||
QTest::qWait(1100);
|
||||
w.addSample(700);
|
||||
const QPixmap twoSamples = w.grab();
|
||||
QVERIFY(!twoSamples.isNull());
|
||||
}
|
||||
|
||||
QTEST_MAIN(TstSpeedGraphWidget)
|
||||
#include "tst_speedgraphwidget.moc"
|
||||
Reference in New Issue
Block a user