This repository has been archived on 2022-05-21. You can view files and clone it, but cannot push or open issues or pull requests.
LEFTONE/util/statman/test.c

161 lines
3.6 KiB
C
Raw Permalink Normal View History

#undef NDEBUG
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
#include "./statman.h"
typedef enum {
CHECK_POINT_NONE,
CHECK_POINT_STATE0_INITIALIZE,
CHECK_POINT_STATE1_INITIALIZE,
CHECK_POINT_STATE2_INITIALIZE,
CHECK_POINT_STATE3_INITIALIZE,
CHECK_POINT_STATE0_UPDATE,
CHECK_POINT_STATE1_UPDATE,
CHECK_POINT_STATE2_UPDATE,
CHECK_POINT_STATE0_FINALIZE,
CHECK_POINT_STATE1_FINALIZE,
CHECK_POINT_STATE2_FINALIZE,
CHECK_POINT_STATE3_FINALIZE,
} check_point_t;
static check_point_t actual_[256] = {0};
static size_t actual_length_ = 0;
static inline void check_point_(check_point_t cp) {
assert(actual_length_ < sizeof(actual_)/sizeof(actual_[0]));
actual_[actual_length_++] = cp;
}
static void state_initialize_(
const statman_meta_t* meta, void* time, statman_state_t* next) {
assert(meta != NULL);
assert(time != NULL);
assert(next != NULL);
check_point_(CHECK_POINT_STATE0_INITIALIZE+meta->state);
}
static void state3_initialize_(
const statman_meta_t* meta, void* time, statman_state_t* next) {
assert(meta != NULL);
assert(time != NULL);
assert(next != NULL);
check_point_(CHECK_POINT_STATE3_INITIALIZE);
*next = 0;
}
static void state_update_(
const statman_meta_t* meta, void* time, statman_state_t* next) {
assert(meta != NULL);
assert(time != NULL);
assert(next != NULL);
check_point_(CHECK_POINT_STATE0_UPDATE+meta->state);
size_t *t = (typeof(t)) time;
if ((*t)++%2 == 0) *next = meta->state+1;
}
static void state_finalize_(
const statman_meta_t* meta, void* time, statman_state_t* next) {
assert(meta != NULL);
assert(time != NULL);
assert(next != NULL);
check_point_(CHECK_POINT_STATE0_FINALIZE+meta->state);
*next = 0;
}
static const statman_meta_t table_[] = {
{
.state = 0,
.name = "0",
.initialize = state_initialize_,
.update = state_update_,
.finalize = state_finalize_,
},
{
.state = 1,
.name = "1",
.initialize = state_initialize_,
.update = state_update_,
.finalize = state_finalize_,
},
{
.state = 2,
.name = "2",
.initialize = state_initialize_,
.update = state_update_,
.finalize = state_finalize_,
},
{
.state = 3,
.name = "3",
.initialize = state3_initialize_,
},
};
int main(void) {
statman_state_t state = 0;
size_t time = 0;
/* state0 -> state1 */
statman_update(table_, &time, &state);
assert(state == 1);
assert(time == 2);
/* state1 -> state2 */
statman_update(table_, &time, &state);
assert(state == 2);
assert(time == 4);
/* state2 -> state0 */
statman_update(table_, &time, &state);
assert(state == 0);
assert(time == 6);
/* state0 -> state1 */
statman_update(table_, &time, &state);
assert(state == 1);
assert(time == 8);
/* stat1's finalizer forces to move to 0 */
statman_transition_to(table_, &time, &state, 2);
assert(state == 0);
assert(time == 8);
static const check_point_t expects[] = {
CHECK_POINT_STATE0_UPDATE,
CHECK_POINT_STATE1_INITIALIZE,
CHECK_POINT_STATE1_UPDATE,
CHECK_POINT_STATE1_UPDATE,
CHECK_POINT_STATE2_INITIALIZE,
CHECK_POINT_STATE2_UPDATE,
CHECK_POINT_STATE2_UPDATE,
CHECK_POINT_STATE3_INITIALIZE,
CHECK_POINT_STATE0_INITIALIZE,
CHECK_POINT_STATE0_UPDATE,
CHECK_POINT_STATE0_UPDATE,
CHECK_POINT_STATE1_INITIALIZE,
CHECK_POINT_STATE1_UPDATE,
CHECK_POINT_STATE1_FINALIZE,
CHECK_POINT_STATE0_INITIALIZE,
};
assert(actual_length_ == sizeof(expects)/sizeof(expects[0]));
for (size_t i = 0; i < actual_length_; ++i) {
assert(expects[i] == actual_[i]);
}
}