综合平台编程器项目的远程存储
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

165 rader
6.2 KiB

  1. #include "domain/virtual_register_repository.h"
  2. #include "services/alarm_service.h"
  3. #include "services/hmi_editor_service.h"
  4. #include "services/hmi_navigation_service.h"
  5. #include "services/hmi_runtime_service.h"
  6. #include "services/logic_editor_service.h"
  7. #include "services/offline_simulation_service.h"
  8. #include "services/project_service.h"
  9. #include "services/register_monitor_service.h"
  10. #include "services/runtime_mode_service.h"
  11. #include "support/test_support.h"
  12. #include "ui/hmi_editor_widget.h"
  13. #include "ui/logic_editor_widget.h"
  14. #include "ui/runtime_monitor_widget.h"
  15. #include "ui/runtime_panel_controller.h"
  16. #include <QApplication>
  17. #include <QCoreApplication>
  18. #include <QEventLoop>
  19. #include <QLabel>
  20. #include <QWidget>
  21. #include <iostream>
  22. #include <stdexcept>
  23. #include <string>
  24. namespace {
  25. using TestProjectStorage = TestSupport::InMemoryProjectStorage;
  26. using TestSupport::require;
  27. ControlLogic makeAlwaysOnLogic()
  28. {
  29. ControlLogic logic;
  30. logic.id = "queued-trace-logic";
  31. logic.name = "Queued trace logic";
  32. LadderRung rung;
  33. rung.id = "always-on-rung";
  34. rung.name = "Always on";
  35. rung.condition = ConditionExpression::fromWire("always-on-wire", 10);
  36. LogicNode output;
  37. output.id = "always-on-output";
  38. output.config = CoilNodeConfig{
  39. RegisterAddress{RegisterArea::M, 1}, CoilMode::Normal};
  40. rung.output = output;
  41. logic.rungs.push_back(rung);
  42. return logic;
  43. }
  44. void testQueuedOfflineTraceIsIgnoredAfterReturningToEditing()
  45. {
  46. TestProjectStorage storage;
  47. ProjectService project_service(storage);
  48. VirtualRegisterRepository virtual_repository;
  49. OfflineSimulationService simulation_service(virtual_repository);
  50. OnlineLogicMonitorService online_monitor_service(virtual_repository);
  51. RuntimeModeService runtime_mode_service(
  52. project_service, simulation_service, online_monitor_service);
  53. HmiEditorService hmi_editor_service(project_service);
  54. HmiRuntimeService hmi_runtime_service(virtual_repository);
  55. LogicEditorService logic_editor_service(project_service);
  56. HmiNavigationService hmi_navigation_service(project_service);
  57. AlarmService alarm_service(project_service, virtual_repository);
  58. RegisterMonitorService register_monitor_service(virtual_repository);
  59. const ControlLogic logic = makeAlwaysOnLogic();
  60. project_service.editProject().controlLogics.push_back(logic);
  61. QWidget parent;
  62. HmiEditorWidget hmi_editor_widget(
  63. hmi_editor_service, hmi_runtime_service, alarm_service, &parent);
  64. LogicEditorWidget logic_editor_widget(logic_editor_service, &parent);
  65. QLabel executor_status_label(&parent);
  66. std::string current_logic_id = logic.id;
  67. logic_editor_widget.setLogicId(current_logic_id);
  68. RuntimePanelController controller(
  69. parent,
  70. runtime_mode_service,
  71. project_service,
  72. hmi_editor_service,
  73. hmi_runtime_service,
  74. logic_editor_service,
  75. hmi_navigation_service,
  76. alarm_service,
  77. register_monitor_service,
  78. hmi_editor_widget,
  79. logic_editor_widget,
  80. executor_status_label,
  81. [&current_logic_id] { return current_logic_id; },
  82. [&current_logic_id](const std::string &logic_id)
  83. {
  84. current_logic_id = logic_id;
  85. },
  86. [](const std::string &) {},
  87. [](const QString &, int) {},
  88. [](const QString &) {},
  89. [] {});
  90. controller.configure();
  91. require(runtime_mode_service.enterOfflineRunning().succeeded,
  92. "offline simulation must start for queued trace regression");
  93. controller.enterRuntime(
  94. {}, logic.id, runtime_mode_service.mode(),
  95. runtime_mode_service.plcConnectionState());
  96. QLabel *logic_label = controller.runtimeMonitorWidget()
  97. ->findChild<QLabel *>(QStringLiteral("logicLabel"));
  98. QLabel *notice_label = controller.runtimeMonitorWidget()
  99. ->findChild<QLabel *>(QStringLiteral("logicNoticeLabel"));
  100. require(logic_label != nullptr && notice_label != nullptr,
  101. "runtime monitor must expose its local trace labels");
  102. require(logic_label->text() == QStringLiteral("梯形图运行状态")
  103. && !notice_label->isVisible(),
  104. "offline runtime must keep the normal ladder trace heading");
  105. controller.runtimeMonitorWidget()->setMode(
  106. ApplicationMode::OnlineRunning, PlcConnectionState::Connected);
  107. require(logic_label->text() == QStringLiteral("本地推算轨迹")
  108. && notice_label->isVisible()
  109. && notice_label->text().contains(QStringLiteral("不写入 PLC 程序或 M/D"))
  110. && notice_label->text().contains(QStringLiteral("HMI 和自由监控仍可写 PLC")),
  111. "online runtime must explain the read-only local trace boundary");
  112. controller.runtimeMonitorWidget()->setMode(
  113. ApplicationMode::OfflineRunning, PlcConnectionState::Disconnected);
  114. require(simulation_service.executeOnce().succeeded,
  115. "offline simulation must produce a trace before editing");
  116. require(simulation_service.traceSnapshot()
  117. .forLogic(logic.id).rungValues.at("always-on-rung"),
  118. "the queued trace must contain an energized rung");
  119. require(runtime_mode_service.enterEditing().succeeded,
  120. "offline simulation must return to editing before queued delivery");
  121. controller.leaveRuntime(
  122. runtime_mode_service.mode(), runtime_mode_service.plcConnectionState());
  123. logic_editor_widget.clearRuntimeTrace();
  124. require(!logic_editor_widget.runtimeTraceEnabled(),
  125. "editing transition must initially clear the runtime trace");
  126. QCoreApplication::processEvents(QEventLoop::AllEvents);
  127. require(!logic_editor_widget.runtimeTraceEnabled(),
  128. "a queued offline scan must not restore the trace after returning to editing");
  129. }
  130. } // namespace
  131. int main(int argc, char *argv[])
  132. {
  133. qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("offscreen"));
  134. QApplication application(argc, argv);
  135. try
  136. {
  137. testQueuedOfflineTraceIsIgnoredAfterReturningToEditing();
  138. }
  139. catch (const std::exception &error)
  140. {
  141. std::cerr << "runtime panel controller tests failed: "
  142. << error.what() << '\n';
  143. return 1;
  144. }
  145. std::cout << "runtime panel controller tests passed\n";
  146. return 0;
  147. }