/* * Round-trips the JS writer's real output through the C reader. * * The writer (src/pkjs/index.js) and the reader (src/c/main.c) are two implementations * of one format, in two languages, that never run in the same process. Nothing but a * test like this can catch them drifting apart — and drift decodes as plausible-looking * garbage rather than as an error, which is the failure worth spending a harness on. * * Build: see run-tests.sh. Reads the payload as hex on stdin. */ #include "pebble_stub.h" /* main.c includes ; the build passes -include pebble_stub.h and -Dpebble_h so that include resolves to nothing. See run-tests.sh. */ #define main pebble_main /* keep main.c's entry point out of the way */ #include "../src/c/main.c" #undef main static int failures = 0; static void check(const char *label, bool ok) { printf(" %s %s\n", ok ? "PASS" : "FAIL", label); if (!ok) failures++; } int main(void) { static uint8_t buffer[4096]; uint16_t length = 0; unsigned int byte; while (scanf("%2x", &byte) == 1 && length < sizeof(buffer)) buffer[length++] = (uint8_t)byte; printf("payload: %u bytes\n", length); bool ok = parse_plan(buffer, length); check("parses", ok); if (!ok) { printf(" status: %s\n", s_status); return 1; } check("room count is 3", s_room_count == 3); check("room 0 is named Kitchen", strcmp(s_rooms[0].name, "Kitchen") == 0); check("room 0 is occupied", s_rooms[0].state == 1); check("room 0 has 4 vertices", s_rooms[0].vertex_count == 4); check("room 0 has 1 occupant", s_rooms[0].occupant_count == 1); check("occupant initial is A", s_rooms[0].occupants[0].initial == 'A'); check("occupant colour index 0", s_rooms[0].occupants[0].colour == 0); check("occupant has a position", s_rooms[0].occupants[0].has_position); check("occupant name survived", strcmp(s_rooms[0].occupants[0].name, "Amir") == 0); check("room 1 is named Loggia", strcmp(s_rooms[1].name, "Loggia") == 0); /* A radar target outranks "HA never reports this area": somebody IS in there, and a positive detection beats no data. The first draft of this test asserted the opposite and was wrong. */ check("room 1 is occupied (radar, nobody named)", s_rooms[1].state == 1); check("room 1 has an anonymous target", s_rooms[1].target_count == 1); check("room 1 has no occupants", s_rooms[1].occupant_count == 0); check("room 2 is the unknown state", s_rooms[2].state == 2); check("room 2 has no targets", s_rooms[2].target_count == 0); check("1 unplaced person", s_unplaced_count == 1); check("unplaced is Bibi", strcmp(s_unplaced[0].name, "Bibi") == 0); /* A truncated payload must be refused wholesale, never half-decoded: a plan missing its last rooms looks exactly like a real plan. */ bool truncated = parse_plan(buffer, length / 2); check("truncated payload refused", !truncated && s_room_count == 0); /* A version bump on the phone must not decode as garbage here. */ buffer[0] = 99; check("wrong version refused", !parse_plan(buffer, length)); printf(failures ? "\nFAILURES: %d\n" : "\nall wire-format checks passed\n", failures); return failures ? 1 : 0; }