Files
Tahgibu/tests/tgb_test.h
T
2026-10-24 12:01:52 -03:00

92 lines
4.0 KiB
C

/* Mini marco de pruebas (solo cabecera). Cada CHECK que falla se cuenta e imprime. */
#ifndef TGB_TEST_H
#define TGB_TEST_H
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tahgibu/tahgibu.h"
#pragma GCC diagnostic ignored "-Wunused-function" /* no todas las pruebas usan todos los ayudantes */
static int g_fail = 0, g_checks = 0;
#define CHECK(cond) do { g_checks++; if (!(cond)) { g_fail++; printf(" FALLO %s:%d: %s\n", __FILE__, __LINE__, #cond); } } while (0)
#define CHECK_EQ(a, b) do { long long _a = (long long)(a), _b = (long long)(b); g_checks++; \
if (_a != _b) { g_fail++; printf(" FALLO %s:%d: %s == %s (%lld != %lld)\n", __FILE__, __LINE__, #a, #b, _a, _b); } } while (0)
/* Espera un estado concreto (éxito = TGB_OK). */
#define CHECK_STATUS(expr, expected) do { tgb_status _s = (expr); g_checks++; \
if (_s != (expected)) { g_fail++; printf(" FALLO %s:%d: %s devolvió %s, se esperaba %s (%s)\n", __FILE__, __LINE__, #expr, \
tgb_status_name(_s), tgb_status_name(expected), tgb_last_error()); } } while (0)
#define CHECK_OK(expr) CHECK_STATUS(expr, TGB_OK)
#define TEST(name) static void name(void)
#define RUN(name) do { int _before = g_fail; name(); printf("%s %s\n", g_fail == _before ? "[ok] " : "[FALLO]", #name); } while (0)
#define TEST_SUMMARY() do { printf("\n%d comprobaciones, %d fallos\n", g_checks, g_fail); return g_fail ? 1 : 0; } while (0)
static int _rm_cb(const char *path, const struct stat *sb, int flag, struct FTW *ftw) {
(void)sb; (void)flag; (void)ftw;
return remove(path);
}
static void tgb_test_rmtree(const char *root) { nftw(root, _rm_cb, 16, FTW_DEPTH | FTW_PHYS); }
/* Crea un contexto cuyas carpetas viven en un directorio temporal propio. */
static tgb_context *tgb_test_context(char *root, size_t cap) {
char tmpl[] = "/tmp/tgb-test-XXXXXX";
if (!mkdtemp(tmpl)) { printf("no se pudo crear carpeta temporal\n"); exit(2); }
snprintf(root, cap, "%s", tmpl);
char c[600], d[600], k[600], s[600];
snprintf(c, sizeof c, "%s/config", root);
snprintf(d, sizeof d, "%s/data", root);
snprintf(k, sizeof k, "%s/cache", root);
snprintf(s, sizeof s, "%s/state", root);
tgb_context_config cfg = {c, d, k, s};
tgb_context *ctx = NULL;
if (tgb_context_create(&cfg, &ctx) != TGB_OK) { printf("contexto: %s\n", tgb_last_error()); exit(2); }
return ctx;
}
/* Contexto sobre las MISMAS carpetas que otro (para simular otro proceso o un reinicio). */
static tgb_context *tgb_test_context_at(const char *root) {
char c[600], d[600], k[600], s[600];
snprintf(c, sizeof c, "%s/config", root);
snprintf(d, sizeof d, "%s/data", root);
snprintf(k, sizeof k, "%s/cache", root);
snprintf(s, sizeof s, "%s/state", root);
tgb_context_config cfg = {c, d, k, s};
tgb_context *ctx = NULL;
if (tgb_context_create(&cfg, &ctx) != TGB_OK) { printf("contexto: %s\n", tgb_last_error()); exit(2); }
return ctx;
}
static const tgb_color RED = {255, 0, 0, 255}, BLUE = {0, 0, 255, 255}, BLACK = {0, 0, 0, 255}, GREEN = {0, 255, 0, 255};
static size_t count_alpha(const tgb_canvas *c) {
size_t n = 0;
for (int y = 0; y < tgb_canvas_height(c); y++)
for (int x = 0; x < tgb_canvas_width(c); x++)
if (tgb_canvas_get(c, x, y).a) n++;
return n;
}
static bool is_px(const tgb_canvas *c, int x, int y, tgb_color col) {
tgb_color p = tgb_canvas_get(c, x, y);
return p.r == col.r && p.g == col.g && p.b == col.b && p.a == col.a;
}
/* Dibuja un punto en la celda (frame_index, layer_index) con sesión de edición. */
static tgb_status paint_px(tgb_document *doc, size_t f, size_t l, int x, int y, tgb_color col) {
tgb_status s = tgb_edit_begin(doc, tgb_frame_id(doc, f), tgb_layer_id(doc, l), "Punto");
if (s != TGB_OK) return s;
tgb_canvas_set(tgb_edit_canvas(doc), x, y, col);
return tgb_edit_end(doc);
}
static tgb_color px_at(const tgb_document *doc, size_t f, size_t l, int x, int y) {
return tgb_canvas_get(tgb_frame_cel(doc, f, l), x, y);
}
#endif