综合平台编程器项目的远程存储
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 

195 Zeilen
6.8 KiB

  1. #include "services/plc_discovery_gateway.h"
  2. #include "support/test_support.h"
  3. #include "ui/plc_connection_dialog.h"
  4. #include <QApplication>
  5. #include <QComboBox>
  6. #include <QCoreApplication>
  7. #include <QEventLoop>
  8. #include <QLabel>
  9. #include <QProgressBar>
  10. #include <QPushButton>
  11. #include <QToolButton>
  12. #include <functional>
  13. #include <iostream>
  14. #include <stdexcept>
  15. #include <utility>
  16. namespace {
  17. using TestSupport::require;
  18. class FakePlcDiscoveryGateway final : public PlcDiscoveryGateway
  19. {
  20. public:
  21. PlcCommunicationResult startDiscovery(
  22. const PlcSerialConfiguration &preferred) override
  23. {
  24. ++start_count;
  25. last_preferred = preferred;
  26. discovering = true;
  27. return {true, {}};
  28. }
  29. void cancelDiscovery() override
  30. {
  31. if (!discovering)
  32. {
  33. return;
  34. }
  35. ++cancel_count;
  36. discovering = false;
  37. if (finished_callback)
  38. {
  39. finished_callback({false, true, {}, {}});
  40. }
  41. }
  42. bool isDiscovering() const override
  43. {
  44. return discovering;
  45. }
  46. void setCallbacks(
  47. std::function<void(const PlcDiscoveryProgress &)> progress_changed,
  48. std::function<void(const PlcDiscoveryOutcome &)> discovery_finished) override
  49. {
  50. progress_callback = std::move(progress_changed);
  51. finished_callback = std::move(discovery_finished);
  52. }
  53. void reportProgress(
  54. const PlcSerialConfiguration &candidate,
  55. std::size_t current,
  56. std::size_t total)
  57. {
  58. if (progress_callback)
  59. {
  60. progress_callback({candidate, current, total});
  61. }
  62. }
  63. void reportFound(const PlcSerialConfiguration &configuration)
  64. {
  65. discovering = false;
  66. if (finished_callback)
  67. {
  68. finished_callback({true, false, configuration, "found"});
  69. }
  70. }
  71. bool discovering = false;
  72. int start_count = 0;
  73. int cancel_count = 0;
  74. PlcSerialConfiguration last_preferred;
  75. std::function<void(const PlcDiscoveryProgress &)> progress_callback;
  76. std::function<void(const PlcDiscoveryOutcome &)> finished_callback;
  77. };
  78. void testDiscoveryFindsAndAcceptsConfiguration()
  79. {
  80. FakePlcDiscoveryGateway gateway;
  81. PlcSerialConfiguration initial;
  82. initial.portName = "COM1";
  83. int prepare_count = 0;
  84. PlcConnectionDialog dialog(
  85. initial, gateway, [&prepare_count] { ++prepare_count; });
  86. QPushButton *search_button = dialog.findChild<QPushButton *>("autoSearchButton");
  87. QProgressBar *progress_bar = dialog.findChild<QProgressBar *>(
  88. "discoveryProgressBar");
  89. QLabel *status_label = dialog.findChild<QLabel *>("discoveryStatusLabel");
  90. require(search_button != nullptr && progress_bar != nullptr
  91. && status_label != nullptr,
  92. "PLC dialog must expose automatic discovery controls");
  93. search_button->click();
  94. require(prepare_count == 1 && gateway.start_count == 1 && gateway.discovering,
  95. "automatic discovery must release the formal connection and start once");
  96. require(search_button->text() == QStringLiteral("停止搜索")
  97. && !progress_bar->isHidden(),
  98. "the dialog must show searchable progress and a stop command");
  99. PlcSerialConfiguration found = initial;
  100. found.portName = "COM3";
  101. found.serverAddress = 1;
  102. found.baudRate = 19200;
  103. found.dataBits = 8;
  104. found.parity = 0;
  105. found.stopBits = 1;
  106. gateway.reportProgress(found, 4, 180);
  107. require(progress_bar->maximum() == 180 && progress_bar->value() == 4
  108. && status_label->text().contains(QStringLiteral("COM3"))
  109. && status_label->text().contains(QStringLiteral("8N1")),
  110. "discovery progress must identify the active port and serial frame");
  111. gateway.reportFound(found);
  112. QCoreApplication::processEvents(QEventLoop::AllEvents);
  113. const PlcSerialConfiguration selected = dialog.configuration();
  114. require(dialog.result() == QDialog::Accepted,
  115. "a successful discovery must automatically accept the dialog");
  116. require(selected.portName == found.portName
  117. && selected.serverAddress == found.serverAddress
  118. && selected.baudRate == found.baudRate
  119. && selected.dataBits == found.dataBits
  120. && selected.parity == found.parity
  121. && selected.stopBits == found.stopBits,
  122. "a successful discovery must copy every detected serial parameter");
  123. }
  124. void testDiscoveryCanBeCancelled()
  125. {
  126. FakePlcDiscoveryGateway gateway;
  127. PlcSerialConfiguration initial;
  128. initial.portName = "COM1";
  129. PlcConnectionDialog dialog(initial, gateway, [] {});
  130. QPushButton *search_button = dialog.findChild<QPushButton *>("autoSearchButton");
  131. QLabel *status_label = dialog.findChild<QLabel *>("discoveryStatusLabel");
  132. search_button->click();
  133. search_button->click();
  134. require(gateway.cancel_count == 1 && !gateway.discovering,
  135. "the stop command must cancel the active discovery");
  136. require(search_button->isEnabled()
  137. && search_button->text() == QStringLiteral("自动搜索")
  138. && status_label->text() == QStringLiteral("已停止自动搜索"),
  139. "the dialog must return to an editable state after cancellation");
  140. }
  141. void testPortRefreshRemovesUnavailableSelection()
  142. {
  143. FakePlcDiscoveryGateway gateway;
  144. PlcSerialConfiguration initial;
  145. initial.portName = "COM_STALE_TEST_999";
  146. PlcConnectionDialog dialog(initial, gateway, [] {});
  147. QComboBox *port_combo = dialog.findChild<QComboBox *>("serialPortComboBox");
  148. QToolButton *refresh_button = dialog.findChild<QToolButton *>(
  149. "refreshPortsButton");
  150. require(port_combo != nullptr && refresh_button != nullptr,
  151. "PLC dialog must expose a serial port refresh command");
  152. require(port_combo->findText(QString::fromLatin1(initial.portName.c_str())) < 0,
  153. "opening the dialog must not restore an unavailable saved port");
  154. const QString stale_port = QStringLiteral("COM_STALE_TEST_998");
  155. port_combo->addItem(stale_port);
  156. port_combo->setCurrentText(stale_port);
  157. refresh_button->click();
  158. require(port_combo->findText(stale_port) < 0
  159. && port_combo->currentText() != stale_port,
  160. "refreshing ports must remove an unplugged or unavailable selection");
  161. }
  162. } // namespace
  163. int main(int argc, char *argv[])
  164. {
  165. qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("offscreen"));
  166. QApplication application(argc, argv);
  167. return TestSupport::runTestSuite("PLC connection dialog tests", {
  168. {"testDiscoveryFindsAndAcceptsConfiguration", testDiscoveryFindsAndAcceptsConfiguration},
  169. {"testDiscoveryCanBeCancelled", testDiscoveryCanBeCancelled},
  170. {"testPortRefreshRemovesUnavailableSelection", testPortRefreshRemovesUnavailableSelection},
  171. });
  172. }