trainlog/tui/tests/test_sync_history.c

172 lines
5.3 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "trainlog/sync_history.h"
#define CHECK(value) do { if (!(value)) { fprintf(stderr, "FAIL line %d\n", __LINE__); return 1; } } while (0)
static bool read_text(
const char *path,
char *output,
size_t capacity
)
{
FILE *file;
size_t used;
file = fopen(path, "rb");
if (file == NULL) {
return false;
}
used = fread(output, 1U, capacity - 1U, file);
output[used] = '\0';
return fclose(file) == 0;
}
static void initialize_failure(
TrainlogSyncReport *report,
const char *sync_id,
TrainlogSyncDirection direction,
const char *error
)
{
(void)memset(report, 0, sizeof(*report));
report->direction = direction;
(void)snprintf(report->sync_id, sizeof(report->sync_id), "%s", sync_id);
(void)snprintf(
report->started_at,
sizeof(report->started_at),
"%s",
"2026-01-02T03:04:05+00:00"
);
(void)snprintf(report->error, sizeof(report->error), "%s", error);
(void)snprintf(report->summary, sizeof(report->summary), "%s", error);
}
int main(void)
{
char temporary[] = "/tmp/trainlog-sync-history-XXXXXX";
char history_path[512];
char run_path[512];
char text[4096];
char line[768];
const TrainlogSyncDirection directions[] = {
TRAINLOG_SYNC_ANDROID_TO_PC,
TRAINLOG_SYNC_PC_TO_ANDROID,
TRAINLOG_SYNC_BIDIRECTIONAL
};
const char *const ids[] = {
"sy_00000000-0000-4000-8000-000000000001",
"sy_00000000-0000-4000-8000-000000000002",
"sy_00000000-0000-4000-8000-000000000003"
};
const char *const errors[] = {
"Échec neutre sans indication de sens.",
"Échec neutre sans indication de sens.",
"Android→PC indisponible; PC→Android non tenté."
};
const char *const json_directions[] = {
"\"direction\":\"android_to_pc\"",
"\"direction\":\"pc_to_android\"",
"\"direction\":\"bidirectional\""
};
const char *const detail_directions[] = {
"Direction : Android→PC",
"Direction : PC→Android",
"Direction : PC↔Android"
};
FILE *history;
TrainlogSyncHistoryEntry entry;
TrainlogSyncReport report;
size_t index;
CHECK(trainlog_sync_history_parse_line(
"sy_legacy\t02/01/2026 03:04\t0\tPC→Android visible seulement dans le résumé\n",
&entry
));
CHECK(!entry.direction_known);
CHECK(strcmp(trainlog_sync_history_direction_label(&entry), "direction inconnue") == 0);
CHECK(trainlog_sync_history_parse_line(
"02/01/2026 03:04\t1\tAndroid→PC ancien\n",
&entry
));
CHECK(!entry.direction_known && entry.sync_id[0] == '\0');
CHECK(!trainlog_sync_history_parse_line(
"sy_bad\t02/01/2026 03:04\t0\tx\téchec\n",
&entry
));
CHECK(!trainlog_sync_history_parse_line(
"sy_bad\t02/01/2026 03:04\t0\ta\téchec\textra\n",
&entry
));
CHECK(mkdtemp(temporary) != NULL);
CHECK(setenv("XDG_DATA_HOME", temporary, 1) == 0);
for (index = 0U; index < 3U; ++index) {
initialize_failure(&report, ids[index], directions[index], errors[index]);
CHECK(trainlog_sync_record_local_run(
TRAINLOG_SYNC_TRIGGER_TUI,
&report
));
CHECK(snprintf(
run_path,
sizeof(run_path),
"%s/trainlog/sync_runs/%s.json",
temporary,
ids[index]
) > 0);
CHECK(read_text(run_path, text, sizeof(text)));
CHECK(strstr(text, json_directions[index]) != NULL);
CHECK(strstr(text, errors[index]) != NULL);
CHECK(snprintf(
run_path,
sizeof(run_path),
"%s/trainlog/sync_runs/%s.txt",
temporary,
ids[index]
) > 0);
CHECK(read_text(run_path, text, sizeof(text)));
CHECK(strstr(text, detail_directions[index]) != NULL);
CHECK(strstr(text, errors[index]) != NULL);
}
CHECK(snprintf(
history_path,
sizeof(history_path),
"%s/trainlog/sync_history.log",
temporary
) > 0);
history = fopen(history_path, "rb");
CHECK(history != NULL);
for (index = 0U; index < 3U; ++index) {
CHECK(fgets(line, sizeof(line), history) != NULL);
CHECK(trainlog_sync_history_parse_line(line, &entry));
CHECK(entry.direction_known);
CHECK(entry.direction == directions[index]);
CHECK(strcmp(entry.summary, errors[index]) == 0);
}
CHECK(fgets(line, sizeof(line), history) == NULL);
CHECK(fclose(history) == 0);
for (index = 0U; index < 3U; ++index) {
(void)snprintf(run_path, sizeof(run_path), "%s/trainlog/sync_runs/%s.json", temporary, ids[index]);
CHECK(unlink(run_path) == 0);
(void)snprintf(run_path, sizeof(run_path), "%s/trainlog/sync_runs/%s.txt", temporary, ids[index]);
CHECK(unlink(run_path) == 0);
}
CHECK(unlink(history_path) == 0);
(void)snprintf(run_path, sizeof(run_path), "%s/trainlog/sync_runs", temporary);
CHECK(rmdir(run_path) == 0);
(void)snprintf(run_path, sizeof(run_path), "%s/trainlog", temporary);
CHECK(rmdir(run_path) == 0);
CHECK(rmdir(temporary) == 0);
puts("PASS sync history directions");
return 0;
}