|
- #include "services/plc_discovery_gateway.h"
- #include "support/test_support.h"
- #include "ui/plc_connection_dialog.h"
-
- #include <QApplication>
- #include <QComboBox>
- #include <QCoreApplication>
- #include <QEventLoop>
- #include <QLabel>
- #include <QProgressBar>
- #include <QPushButton>
- #include <QToolButton>
-
- #include <functional>
- #include <iostream>
- #include <stdexcept>
- #include <utility>
-
- namespace {
-
- using TestSupport::require;
-
- class FakePlcDiscoveryGateway final : public PlcDiscoveryGateway
- {
- public:
- PlcCommunicationResult startDiscovery(
- const PlcSerialConfiguration &preferred) override
- {
- ++start_count;
- last_preferred = preferred;
- discovering = true;
- return {true, {}};
- }
-
- void cancelDiscovery() override
- {
- if (!discovering)
- {
- return;
- }
- ++cancel_count;
- discovering = false;
- if (finished_callback)
- {
- finished_callback({false, true, {}, {}});
- }
- }
-
- bool isDiscovering() const override
- {
- return discovering;
- }
-
- void setCallbacks(
- std::function<void(const PlcDiscoveryProgress &)> progress_changed,
- std::function<void(const PlcDiscoveryOutcome &)> discovery_finished) override
- {
- progress_callback = std::move(progress_changed);
- finished_callback = std::move(discovery_finished);
- }
-
- void reportProgress(
- const PlcSerialConfiguration &candidate,
- std::size_t current,
- std::size_t total)
- {
- if (progress_callback)
- {
- progress_callback({candidate, current, total});
- }
- }
-
- void reportFound(const PlcSerialConfiguration &configuration)
- {
- discovering = false;
- if (finished_callback)
- {
- finished_callback({true, false, configuration, "found"});
- }
- }
-
- bool discovering = false;
- int start_count = 0;
- int cancel_count = 0;
- PlcSerialConfiguration last_preferred;
- std::function<void(const PlcDiscoveryProgress &)> progress_callback;
- std::function<void(const PlcDiscoveryOutcome &)> finished_callback;
- };
-
- void testDiscoveryFindsAndAcceptsConfiguration()
- {
- FakePlcDiscoveryGateway gateway;
- PlcSerialConfiguration initial;
- initial.portName = "COM1";
- int prepare_count = 0;
- PlcConnectionDialog dialog(
- initial, gateway, [&prepare_count] { ++prepare_count; });
-
- QPushButton *search_button = dialog.findChild<QPushButton *>("autoSearchButton");
- QProgressBar *progress_bar = dialog.findChild<QProgressBar *>(
- "discoveryProgressBar");
- QLabel *status_label = dialog.findChild<QLabel *>("discoveryStatusLabel");
- require(search_button != nullptr && progress_bar != nullptr
- && status_label != nullptr,
- "PLC dialog must expose automatic discovery controls");
-
- search_button->click();
- require(prepare_count == 1 && gateway.start_count == 1 && gateway.discovering,
- "automatic discovery must release the formal connection and start once");
- require(search_button->text() == QStringLiteral("停止搜索")
- && !progress_bar->isHidden(),
- "the dialog must show searchable progress and a stop command");
-
- PlcSerialConfiguration found = initial;
- found.portName = "COM3";
- found.serverAddress = 1;
- found.baudRate = 19200;
- found.dataBits = 8;
- found.parity = 0;
- found.stopBits = 1;
- gateway.reportProgress(found, 4, 180);
- require(progress_bar->maximum() == 180 && progress_bar->value() == 4
- && status_label->text().contains(QStringLiteral("COM3"))
- && status_label->text().contains(QStringLiteral("8N1")),
- "discovery progress must identify the active port and serial frame");
-
- gateway.reportFound(found);
- QCoreApplication::processEvents(QEventLoop::AllEvents);
- const PlcSerialConfiguration selected = dialog.configuration();
- require(dialog.result() == QDialog::Accepted,
- "a successful discovery must automatically accept the dialog");
- require(selected.portName == found.portName
- && selected.serverAddress == found.serverAddress
- && selected.baudRate == found.baudRate
- && selected.dataBits == found.dataBits
- && selected.parity == found.parity
- && selected.stopBits == found.stopBits,
- "a successful discovery must copy every detected serial parameter");
- }
-
- void testDiscoveryCanBeCancelled()
- {
- FakePlcDiscoveryGateway gateway;
- PlcSerialConfiguration initial;
- initial.portName = "COM1";
- PlcConnectionDialog dialog(initial, gateway, [] {});
- QPushButton *search_button = dialog.findChild<QPushButton *>("autoSearchButton");
- QLabel *status_label = dialog.findChild<QLabel *>("discoveryStatusLabel");
-
- search_button->click();
- search_button->click();
- require(gateway.cancel_count == 1 && !gateway.discovering,
- "the stop command must cancel the active discovery");
- require(search_button->isEnabled()
- && search_button->text() == QStringLiteral("自动搜索")
- && status_label->text() == QStringLiteral("已停止自动搜索"),
- "the dialog must return to an editable state after cancellation");
- }
-
- void testPortRefreshRemovesUnavailableSelection()
- {
- FakePlcDiscoveryGateway gateway;
- PlcSerialConfiguration initial;
- initial.portName = "COM_STALE_TEST_999";
- PlcConnectionDialog dialog(initial, gateway, [] {});
- QComboBox *port_combo = dialog.findChild<QComboBox *>("serialPortComboBox");
- QToolButton *refresh_button = dialog.findChild<QToolButton *>(
- "refreshPortsButton");
- require(port_combo != nullptr && refresh_button != nullptr,
- "PLC dialog must expose a serial port refresh command");
- require(port_combo->findText(QString::fromLatin1(initial.portName.c_str())) < 0,
- "opening the dialog must not restore an unavailable saved port");
-
- const QString stale_port = QStringLiteral("COM_STALE_TEST_998");
- port_combo->addItem(stale_port);
- port_combo->setCurrentText(stale_port);
- refresh_button->click();
- require(port_combo->findText(stale_port) < 0
- && port_combo->currentText() != stale_port,
- "refreshing ports must remove an unplugged or unavailable selection");
- }
-
- } // namespace
-
- int main(int argc, char *argv[])
- {
- qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("offscreen"));
- QApplication application(argc, argv);
- return TestSupport::runTestSuite("PLC connection dialog tests", {
- {"testDiscoveryFindsAndAcceptsConfiguration", testDiscoveryFindsAndAcceptsConfiguration},
- {"testDiscoveryCanBeCancelled", testDiscoveryCanBeCancelled},
- {"testPortRefreshRemovesUnavailableSelection", testPortRefreshRemovesUnavailableSelection},
- });
- }
|