feat(box): routine manifest parser + host test
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
// Host unit test for the routine manifest parser.
|
||||
#define LISAEL_HOST_TEST
|
||||
#include "audio/routine_manifest.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *SAMPLE =
|
||||
"{\"routines\":["
|
||||
"{\"id\":\"matin\",\"title\":\"Le matin\",\"icon\":\"matin.bin\",\"steps\":["
|
||||
"{\"text\":\"Habille-toi\",\"icon\":\"matin_01.bin\",\"audio\":\"matin_01.mp3\"},"
|
||||
"{\"text\":\"Petit-déjeuner\",\"icon\":\"matin_02.bin\",\"audio\":\"matin_02.mp3\"}]},"
|
||||
"{\"id\":\"soir\",\"title\":\"Le soir\",\"icon\":\"soir.bin\",\"steps\":["
|
||||
"{\"text\":\"Brosse tes dents\",\"icon\":\"soir_01.bin\",\"audio\":\"soir_01.mp3\"}]},"
|
||||
"{\"id\":\"vide\",\"title\":\"Vide\",\"icon\":\"vide.bin\",\"steps\":[]}"
|
||||
"]}";
|
||||
|
||||
int main(void) {
|
||||
lisael_routine_t r[LISAEL_MAX_ROUTINES];
|
||||
int n = lisael_routine_parse(SAMPLE, r, LISAEL_MAX_ROUTINES);
|
||||
assert(n == 2); // empty routine skipped
|
||||
assert(strcmp(r[0].id, "matin") == 0);
|
||||
assert(strcmp(r[0].title, "Le matin") == 0);
|
||||
assert(strcmp(r[0].icon, "matin.bin") == 0);
|
||||
assert(r[0].n_steps == 2);
|
||||
assert(strcmp(r[0].steps[0].text, "Habille-toi") == 0);
|
||||
assert(strcmp(r[0].steps[1].icon, "matin_02.bin") == 0);
|
||||
assert(strcmp(r[0].steps[1].audio, "matin_02.mp3") == 0);
|
||||
assert(strcmp(r[1].id, "soir") == 0);
|
||||
assert(r[1].n_steps == 1);
|
||||
|
||||
// malformed / wrong-shape inputs -> -1
|
||||
assert(lisael_routine_parse("not json", r, LISAEL_MAX_ROUTINES) == -1);
|
||||
assert(lisael_routine_parse("[]", r, LISAEL_MAX_ROUTINES) == -1); // array root, not object
|
||||
assert(lisael_routine_parse("{\"foo\":1}", r, LISAEL_MAX_ROUTINES) == -1); // no "routines"
|
||||
|
||||
// empty routines array -> 0 (valid, just no content)
|
||||
lisael_routine_t r2[LISAEL_MAX_ROUTINES];
|
||||
assert(lisael_routine_parse("{\"routines\":[]}", r2, LISAEL_MAX_ROUTINES) == 0);
|
||||
|
||||
// a step missing "text" is skipped; icon/audio optional (stay "")
|
||||
int m = lisael_routine_parse(
|
||||
"{\"routines\":[{\"id\":\"x\",\"title\":\"X\",\"steps\":["
|
||||
"{\"icon\":\"a.bin\"}," // no text -> skipped
|
||||
"{\"text\":\"Range\"}]}]}", // no icon/audio -> ""
|
||||
r2, LISAEL_MAX_ROUTINES);
|
||||
assert(m == 1 && r2[0].n_steps == 1);
|
||||
assert(strcmp(r2[0].steps[0].text, "Range") == 0);
|
||||
assert(r2[0].steps[0].icon[0] == '\0');
|
||||
assert(r2[0].steps[0].audio[0] == '\0');
|
||||
|
||||
// guard clauses
|
||||
assert(lisael_routine_parse(NULL, r2, LISAEL_MAX_ROUTINES) == -1);
|
||||
assert(lisael_routine_parse("{\"routines\":[]}", r2, 0) == -1);
|
||||
|
||||
// caps: never exceed LISAEL_MAX_STEPS even if JSON has more
|
||||
char big[2048];
|
||||
int o = snprintf(big, sizeof(big), "{\"routines\":[{\"id\":\"b\",\"title\":\"B\",\"steps\":[");
|
||||
for (int i = 0; i < 20; i++) { // 20 > LISAEL_MAX_STEPS (12)
|
||||
o += snprintf(big + o, sizeof(big) - o,
|
||||
"%s{\"text\":\"s%d\"}", i ? "," : "", i);
|
||||
}
|
||||
snprintf(big + o, sizeof(big) - o, "]}]}");
|
||||
lisael_routine_t r3[LISAEL_MAX_ROUTINES];
|
||||
int k = lisael_routine_parse(big, r3, LISAEL_MAX_ROUTINES);
|
||||
assert(k == 1 && r3[0].n_steps == LISAEL_MAX_STEPS);
|
||||
|
||||
printf("OK: %d routines\n", n);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user