#include "services/runtime_mode_service.h" #include "services/offline_simulation_service.h" #include "services/project_service.h" #include "domain/project_storage.h" #include "domain/register_repository.h" #include #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 testModeTransitions() { // 验证服务将 PLC 首读状态与领域模式切换规则正确组合 TestProjectStorage storage; ProjectService project_service(storage); VirtualRegisterRepository repository; OfflineSimulationService simulation_service(repository); RuntimeModeService service(project_service, simulation_service); require(service.mode() == ApplicationMode::Editing, "service must start in editing mode"); require(service.policy().allowsProjectEditing, "editing mode must allow project editing"); require(service.enterOfflineRunning().succeeded, "editing mode must enter offline running"); require(service.simulationState() == SimulationState::Running, "offline mode must start the software executor"); require(service.policy().usesVirtualRegisters, "offline running must use virtual registers"); require(service.enterOnlineRunning().error == ModeTransitionError::MustReturnToEditing, "running modes must not switch directly"); require(service.enterEditing().succeeded, "offline running must return to editing"); require(service.simulationState() == SimulationState::Stopped, "returning to editing must stop the software executor first"); require(service.enterOnlineRunning().error == ModeTransitionError::InitialPlcReadRequired, "online running must require an initial PLC read"); service.setInitialPlcReadCompleted(true); require(service.initialPlcReadCompleted(), "service must retain the initial PLC read state"); require(service.enterOnlineRunning().succeeded, "online running must start after an initial PLC read"); require(service.simulationState() == SimulationState::Stopped, "online running must never start the software executor"); require(service.policy().usesPlcRegisters, "online running must use PLC registers"); require(!service.policy().runsLogicExecutor, "online running must keep the software executor stopped"); } } // namespace int main() { try { // 运行模式只有这一组状态机边界测试 testModeTransitions(); } catch (const std::exception &error) { std::cerr << "runtime mode service tests failed: " << error.what() << '\n'; return 1; } std::cout << "runtime mode service tests passed\n"; return 0; }