|
- #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 <iostream>
- #include <stdexcept>
- #include <string>
-
- 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;
- }
|