/** * test_rx_realtime.cpp — Tests for Step 4: Rx panel real-time display. */ #include #include #include #include #include #include "main_window.h" #ifndef LDF_SAMPLE_PATH #error "LDF_SAMPLE_PATH must be defined by CMake" #endif class TestRxRealtime : public QObject { Q_OBJECT private: MainWindow* m_window; private slots: void init() { m_window = new MainWindow(); m_window->loadLdfFile(QString(LDF_SAMPLE_PATH)); } void cleanup() { delete m_window; m_window = nullptr; } // ─── Frame Reception ────────────────────────────────────────── void test_timestampUpdates() { m_window->receiveRxFrame(0x20, {0x03, 0xC8}); auto* item = m_window->rxTable()->topLevelItem(0); QString ts = item->text(0); QVERIFY(ts != QString::fromUtf8("—")); QVERIFY(ts.contains(":")); } void test_frameBytesStored() { m_window->receiveRxFrame(0x20, {0x03, 0xC8}); auto* item = m_window->rxTable()->topLevelItem(0); QVariantList bytes = item->data(4, Qt::UserRole).toList(); QCOMPARE(bytes[0].toInt(), 0x03); QCOMPARE(bytes[1].toInt(), 0xC8); } void test_frameValueDisplayed() { m_window->receiveRxFrame(0x20, {0x03, 0xC8}); auto* item = m_window->rxTable()->topLevelItem(0); QVERIFY(item->text(4).contains("C8")); } void test_signalValuesUnpacked() { // Motor_Status: MotorStatus (bit 0, w2), MotorTemp (bit 8, w8) m_window->receiveRxFrame(0x20, {0x03, 0xC8}); auto* item = m_window->rxTable()->topLevelItem(0); QCOMPARE(item->child(0)->data(4, Qt::UserRole).toInt(), 3); // MotorStatus QCOMPARE(item->child(1)->data(4, Qt::UserRole).toInt(), 200); // MotorTemp } void test_unknownFrameIdIgnored() { m_window->receiveRxFrame(0xFF, {0x00}); // No crash } void test_updateSameFrameTwice() { m_window->receiveRxFrame(0x20, {0x01, 0x10}); m_window->receiveRxFrame(0x20, {0x02, 0x20}); auto* item = m_window->rxTable()->topLevelItem(0); QVariantList bytes = item->data(4, Qt::UserRole).toList(); QCOMPARE(bytes[0].toInt(), 0x02); QCOMPARE(bytes[1].toInt(), 0x20); } // ─── Change Highlighting ────────────────────────────────────── void test_changedSignalHighlighted() { m_window->receiveRxFrame(0x20, {0x01, 0x10}); m_window->receiveRxFrame(0x20, {0x01, 0x20}); auto* tempSig = m_window->rxTable()->topLevelItem(0)->child(1); QColor bg = tempSig->background(4).color(); QCOMPARE(bg.red(), 255); QCOMPARE(bg.green(), 255); } void test_unchangedSignalNotHighlighted() { m_window->receiveRxFrame(0x20, {0x01, 0x10}); m_window->receiveRxFrame(0x20, {0x01, 0x20}); auto* statusSig = m_window->rxTable()->topLevelItem(0)->child(0); QCOMPARE(statusSig->background(4).style(), Qt::NoBrush); } void test_firstReceptionNoHighlight() { m_window->receiveRxFrame(0x20, {0x01, 0x10}); auto* item = m_window->rxTable()->topLevelItem(0); for (int j = 0; j < item->childCount(); ++j) QCOMPARE(item->child(j)->background(4).style(), Qt::NoBrush); } // ─── Auto-scroll ───────────────────────────────────────────── void test_autoScrollDefaultOn() { QVERIFY(m_window->autoScrollCheck()->isChecked()); } void test_autoScrollCanBeDisabled() { m_window->autoScrollCheck()->setChecked(false); QVERIFY(!m_window->autoScrollCheck()->isChecked()); } // ─── Clear ─────────────────────────────────────────────────── void test_clearResetsTimestamps() { m_window->receiveRxFrame(0x20, {0x01, 0x10}); m_window->onClearRx(); for (int i = 0; i < m_window->rxTable()->topLevelItemCount(); ++i) QCOMPARE(m_window->rxTable()->topLevelItem(i)->text(0), QString::fromUtf8("—")); } void test_clearResetsValues() { m_window->receiveRxFrame(0x20, {0x01, 0x10}); m_window->onClearRx(); for (int i = 0; i < m_window->rxTable()->topLevelItemCount(); ++i) QCOMPARE(m_window->rxTable()->topLevelItem(i)->text(4), QString::fromUtf8("—")); } void test_clearResetsHighlights() { m_window->receiveRxFrame(0x20, {0x01, 0x10}); m_window->receiveRxFrame(0x20, {0x02, 0x20}); m_window->onClearRx(); auto* item = m_window->rxTable()->topLevelItem(0); for (int j = 0; j < item->childCount(); ++j) QCOMPARE(item->child(j)->background(4).style(), Qt::NoBrush); } // ─── Hex/Dec ───────────────────────────────────────────────── void test_rxHexMode() { m_window->receiveRxFrame(0x20, {0x03, 0xC8}); auto* item = m_window->rxTable()->topLevelItem(0); QVERIFY(item->text(4).contains("C8")); QVERIFY(item->child(1)->text(4).startsWith("0x")); } void test_rxDecMode() { m_window->hexModeCheck()->setChecked(false); m_window->receiveRxFrame(0x20, {0x03, 0xC8}); auto* item = m_window->rxTable()->topLevelItem(0); QVERIFY(item->text(4).contains("200")); QVERIFY(!item->child(1)->text(4).startsWith("0x")); m_window->hexModeCheck()->setChecked(true); } }; QTEST_MAIN(TestRxRealtime) #include "test_rx_realtime.moc"