#include "domain/project_storage.h" #include "services/data_point_service.h" #include "services/project_service.h" #include #include namespace { class TestProjectStorage final : public ProjectStorage { public: ProjectSaveResult save(const Project &, const std::string &) override { return {true, ProjectStorageError::None, {}}; } ProjectLoadResult load(const std::string &) override { return {false, {}, ProjectStorageError::FileReadFailed, {}}; } }; void require(bool condition, const std::string &message) { if (!condition) { throw std::runtime_error(message); } } void testUniqueDataPointsAndReferences() { TestProjectStorage storage; ProjectService project_service(storage); DataPointService service(project_service); const RegisterAddress m0{RegisterArea::M, 0}; const RegisterAddress m1{RegisterArea::M, 1}; const RegisterAddress d0{RegisterArea::D, 0}; require(service.add({m0, "StartCommand", "启动命令"}).succeeded, "a valid data point must be added"); require(service.add({d0, "Temperature", "温度"}).succeeded, "M and D data points must coexist"); require(service.add({m0, "DuplicateAddress", {}}).error == DataPointError::DuplicateAddress, "duplicate data point addresses must be rejected"); require(service.add({m1, "StartCommand", {}}).error == DataPointError::DuplicateName, "duplicate data point names must be rejected"); HmiControl button; button.id = "start-button"; button.type = HmiControlType::Button; button.bounds = {0, 0, 100, 40}; button.text = "启动"; button.binding = m0; HmiPage page; page.id = "main-page"; page.name = "主画面"; page.controls.push_back(button); project_service.editProject().hmiPages.push_back(page); LogicNode contact; contact.id = "start-contact"; contact.config = ContactNodeConfig{m0, ContactMode::NormallyOpen}; LadderRung rung; rung.id = "rung-1"; rung.name = "网络 1"; rung.condition = ConditionExpression::fromNode(contact); ControlLogic logic; logic.id = "logic-1"; logic.name = "控制逻辑 1"; logic.rungs.push_back(rung); project_service.editProject().controlLogics.push_back(logic); const auto references = service.references(m0); require(references.size() == 2U, "data point references must include HMI and ladder locations"); require(service.remove(m0).error == DataPointError::AddressInUse, "referenced data points must not be deleted"); require(service.update(m0, {m1, "StartCommand", "启动命令"}).error == DataPointError::AddressInUse, "referenced data point addresses must not change"); require(service.update(m0, {m0, "Start", "启动命令"}).succeeded, "referenced data point names and comments may change"); require(service.remove(RegisterAddress{RegisterArea::D, 99}).error == DataPointError::NotFound, "removing an unknown data point must report not found"); } } // namespace int main() { try { testUniqueDataPointsAndReferences(); } catch (const std::exception &error) { std::cerr << "data point service tests failed: " << error.what() << '\n'; return 1; } std::cout << "data point service tests passed\n"; return 0; }