|
|
|
#include <catch2/catch_test_macros.hpp>
|
|
|
|
#include <fmt/core.h>
|
|
|
|
#include <string>
|
|
|
|
#include "../fsm.hpp"
|
|
|
|
|
|
|
|
using namespace fmt;
|
|
|
|
using std::string;
|
|
|
|
|
|
|
|
enum class MyState {
|
|
|
|
START, RUNNING, END
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class MyEvent {
|
|
|
|
STARTED, PUSH, QUIT
|
|
|
|
};
|
|
|
|
|
|
|
|
class MyFSM : public DeadSimpleFSM<MyState, MyEvent> {
|
|
|
|
public:
|
|
|
|
void event(MyEvent ev, string data="") {
|
|
|
|
switch(_state) {
|
|
|
|
FSM_STATE(MyState, START, ev);
|
|
|
|
FSM_STATE(MyState, RUNNING, ev, data);
|
|
|
|
FSM_STATE(MyState, END, ev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void START(MyEvent ev) {
|
|
|
|
println("<<< START");
|
|
|
|
state(MyState::RUNNING);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RUNNING(MyEvent ev, string &data) {
|
|
|
|
if(ev == MyEvent::QUIT) {
|
|
|
|
println("<<< QUITTING {}", data);
|
|
|
|
state(MyState::END);
|
|
|
|
} else {
|
|
|
|
println("<<< RUN: {}", data);
|
|
|
|
state(MyState::RUNNING);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void END(MyEvent ev) {
|
|
|
|
println("<<< STOP");
|
|
|
|
state(MyState::END);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_CASE("confirm fsm works with optional data", "[utils]") {
|
|
|
|
MyFSM fsm;
|
|
|
|
|
|
|
|
REQUIRE(fsm.in_state(MyState::START));
|
|
|
|
|
|
|
|
fsm.event(MyEvent::STARTED);
|
|
|
|
REQUIRE(fsm.in_state(MyState::RUNNING));
|
|
|
|
|
|
|
|
fsm.event(MyEvent::PUSH);
|
|
|
|
REQUIRE(fsm.in_state(MyState::RUNNING));
|
|
|
|
|
|
|
|
fsm.event(MyEvent::PUSH);
|
|
|
|
REQUIRE(fsm.in_state(MyState::RUNNING));
|
|
|
|
|
|
|
|
fsm.event(MyEvent::PUSH);
|
|
|
|
REQUIRE(fsm.in_state(MyState::RUNNING));
|
|
|
|
|
|
|
|
fsm.event(MyEvent::QUIT, "DONE!");
|
|
|
|
REQUIRE(fsm.in_state(MyState::END));
|
|
|
|
}
|