综合平台编程器项目的远程存储
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

132 lines
4.5 KiB

  1. #include "domain/project_storage.h"
  2. #include "services/logic_editor_service.h"
  3. #include "services/project_service.h"
  4. #include <exception>
  5. #include <iostream>
  6. #include <stdexcept>
  7. namespace {
  8. class TestProjectStorage final : public ProjectStorage
  9. {
  10. public:
  11. ProjectSaveResult save(const Project &, const std::string &) override
  12. {
  13. return {true, ProjectStorageError::None, {}};
  14. }
  15. ProjectLoadResult load(const std::string &) override
  16. {
  17. return {false, {}, ProjectStorageError::FileReadFailed, {}};
  18. }
  19. };
  20. void require(bool condition, const std::string &message)
  21. {
  22. if (!condition)
  23. {
  24. throw std::runtime_error(message);
  25. }
  26. }
  27. void testEditorOperations()
  28. {
  29. TestProjectStorage storage;
  30. ProjectService project_service(storage);
  31. LogicEditorService service(project_service);
  32. const LogicEditorResult logic_result = service.ensureDefaultLogic();
  33. require(logic_result.succeeded, "default logic must be created");
  34. const std::string logic_id = logic_result.id;
  35. const std::string rung_id = service.firstRungId(logic_id);
  36. require(!rung_id.empty(), "default logic must contain an editable rung");
  37. const LogicEditorResult stop_result = service.appendCondition(
  38. logic_id,
  39. rung_id,
  40. ContactNodeConfig{
  41. RegisterAddress{RegisterArea::M, 1},
  42. ContactMode::NormallyClosed});
  43. const LogicEditorResult start_result = service.appendCondition(
  44. logic_id,
  45. rung_id,
  46. ContactNodeConfig{
  47. RegisterAddress{RegisterArea::M, 0},
  48. ContactMode::NormallyOpen});
  49. require(stop_result.succeeded && start_result.succeeded,
  50. "series contacts must be appended as ladder stages");
  51. const std::string start_stage_id = service.stageIdForNode(
  52. logic_id, start_result.id);
  53. const LogicEditorResult hold_result = service.addParallelCondition(
  54. logic_id,
  55. rung_id,
  56. start_stage_id,
  57. ContactNodeConfig{
  58. RegisterAddress{RegisterArea::M, 2},
  59. ContactMode::NormallyOpen});
  60. const LogicEditorResult coil_result = service.setOutput(
  61. logic_id,
  62. rung_id,
  63. CoilNodeConfig{
  64. RegisterAddress{RegisterArea::M, 2},
  65. CoilMode::Normal});
  66. require(hold_result.succeeded && coil_result.succeeded,
  67. "parallel hold contact and output coil must be added");
  68. const LadderRung *rung = service.findRung(logic_id, rung_id);
  69. require(rung != nullptr && rung->stages.size() == 2,
  70. "series conditions must occupy ordered stages");
  71. require(rung->stages.at(1).branches.size() == 2,
  72. "parallel conditions must share one stage");
  73. require(rung->output.has_value(), "rung output must be fixed separately");
  74. require(service.findLogic(logic_id)->validate(),
  75. "configured self-hold ladder must pass full validation");
  76. const LogicNode *start = service.findNode(logic_id, start_result.id);
  77. require(start != nullptr, "added condition must be discoverable");
  78. require(service.updateNodeConfig(
  79. logic_id,
  80. start_result.id,
  81. ContactNodeConfig{
  82. RegisterAddress{RegisterArea::M, 2},
  83. ContactMode::NormallyClosed})
  84. .succeeded,
  85. "contact properties must be editable");
  86. require(service.removeNode(logic_id, hold_result.id).succeeded,
  87. "parallel branch deletion must succeed");
  88. require(service.findRung(logic_id, rung_id)->stages.at(1).branches.size() == 1,
  89. "deleting one branch must keep the ladder stage");
  90. require(service.removeNode(logic_id, start_result.id).succeeded,
  91. "last branch deletion must succeed");
  92. require(service.findRung(logic_id, rung_id)->stages.size() == 1,
  93. "deleting the last branch must remove the empty stage");
  94. const LogicEditorResult second_rung = service.addRung(logic_id);
  95. require(second_rung.succeeded, "additional ladder rungs must be supported");
  96. require(service.removeRung(logic_id, second_rung.id).succeeded,
  97. "additional ladder rungs must be removable");
  98. require(!service.removeRung(logic_id, rung_id).succeeded,
  99. "the only remaining ladder rung must not be removed");
  100. }
  101. } // namespace
  102. int main()
  103. {
  104. try
  105. {
  106. testEditorOperations();
  107. }
  108. catch (const std::exception &error)
  109. {
  110. std::cerr << "logic editor service tests failed: " << error.what() << '\n';
  111. return 1;
  112. }
  113. std::cout << "logic editor service tests passed\n";
  114. return 0;
  115. }