C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
ui_conformance_test.c
Go to the documentation of this file.
1/** @file ui_conformance_test.c
2 @ingroup ui_backend
3 @brief Compile-time and smoke-test conformance test for the UALUI API.
4
5 This program verifies that:
6 1. All public types and function signatures in ui_backend.h compile
7 correctly against the compiled-in backend.
8 2. The init/shutdown lifecycle works (when run from a terminal).
9 3. Surface creation, movement, sizing, and destruction work.
10 4. ui_get_backend() and ui_get_caps() return sensible values.
11 5. The escape-hatch headers compile (included but not called at runtime
12 since they require the matching backend).
13
14 Build with the NCurses backend:
15 gcc -std=c23 -I../include -I. \
16 ui_conformance_test.c ui_ncurses.c ui_ncurses_draw.c \
17 ui_ncurses_input.c ../ual/ui_layout.c \
18 $(pkg-config --cflags --libs panelw ncursesw) -o conformance_ncurses
19
20 Build with the NotCurses backend:
21 gcc -std=c23 -I../include -I. \
22 ui_conformance_test.c ui_notcurses.c ui_notcurses_draw.c \
23 ui_notcurses_input.c ../ual/ui_layout.c \
24 $(pkg-config --cflags --libs notcurses) -o conformance_notcurses
25*/
26
27#define _GNU_SOURCE
28#include "ui_backend.h"
29#include "ui_layout.h"
30#include <stdio.h>
31#include <string.h>
32
33/* Pull in whichever compat header matches the compiled backend. */
34#if defined(NCURSES_UI) || defined(UAL_UI)
35#include "ui_ncurses_compat.h"
36#endif
37#ifdef NOTCURSES_UI
38#include "ui_notcurses_compat.h"
39#endif
40
41/* -------------------------------------------------------------------------
42 Compile-time type checks — these just verify the API types are consistent.
43 ------------------------------------------------------------------------- */
44static void compile_time_checks(void) {
45 /* Verify all public types exist and have the expected fields. */
46 UiConfig cfg = {.enable_mouse = false, .enable_alt_screen = false, .cursor_visible = true, .tty_path = NULL};
47 UiEvent ev;
48 UiRect rect = {.y = 0, .x = 0, .lines = 10, .cols = 20};
49 UiStyle style = {0};
50 UiCaps caps;
51 UiBorderKind bk = UI_BORDER_ROUNDED;
52 UiBackend be;
53 UiColor col;
54 UiColorPair cp;
55
56 (void)cfg;
57 (void)ev;
58 (void)rect;
59 (void)style;
60 (void)caps;
61 (void)bk;
62 (void)be;
63 (void)col;
64 (void)cp;
65
66 /* Verify enum values are defined. */
73}
74
75/* -------------------------------------------------------------------------
76 Runtime tests
77 ------------------------------------------------------------------------- */
78static int test_lifecycle(void) {
79 UiConfig cfg = {
80 .enable_mouse = false,
81 .enable_alt_screen = true,
82 .cursor_visible = false,
83 .tty_path = NULL,
84 };
85
86 UiRuntime *ui = ui_init(&cfg);
87 if (!ui) {
88 fprintf(stderr, "FAIL: ui_init() returned NULL\n");
89 return 1;
90 }
91
92 /* Screen size */
93 int lines = 0, cols = 0;
94 ui_get_screen_size(ui, &lines, &cols);
95 if (lines <= 0 || cols <= 0) {
96 fprintf(stderr, "FAIL: invalid screen size %dx%d\n", lines, cols);
97 ui_shutdown(ui);
98 return 1;
99 }
100 printf("PASS: screen size %d lines x %d cols\n", lines, cols);
101
102 /* Backend identity */
103 UiBackend be = ui_get_backend(ui);
104 printf("PASS: backend = %s\n",
105 be == UI_BACKEND_NCURSES ? "ncurses" : be == UI_BACKEND_NOTCURSES ? "notcurses"
106 : "unknown");
107
108 /* Capabilities */
109 UiCaps caps;
110 ui_get_caps(ui, &caps);
111 printf("PASS: caps truecolor=%d palette256=%d mouse=%d unicode=%d resize=%d pairs=%d\n",
112 caps.truecolor, caps.palette256, caps.mouse,
113 caps.unicode, caps.resize, caps.color_pairs);
114
115 /* Surface */
116 UiSurface *s = ui_surface_new(ui, BOX, NULL, 0, 5, 20, 2, 4);
117
118 if (!s) {
119 fprintf(stderr, "FAIL: ui_surface_new() returned NULL\n");
120 ui_shutdown(ui);
121 return 1;
122 }
123 printf("PASS: surface created\n");
124
125 /* Drawing */
126 UiStyle style = ui_style_from_hex("#d0d0d0", "#000714", WA_NORMAL, " ");
127
129 ui_draw_text(s, BOX, 1, 1, &style, "UALUI conformance test");
130 ui_render(ui);
131 printf("PASS: surface drawn and rendered\n");
132
133 /* Framed surface (layout helper) */
134 UiRect fr = {.y = 8, .x = 4, .lines = 6, .cols = 30};
135 UiFramedSurface fs = ui_framed_surface_new(ui, NULL, fr);
136 if (!fs.outer || !fs.inner) {
137 fprintf(stderr, "FAIL: ui_framed_surface_new() failed\n");
139 ui_shutdown(ui);
140 return 1;
141 }
143 ui_draw_text(fs.inner, WIN, 0, 0, &style, "framed surface");
144 ui_render(ui);
145 printf("PASS: framed surface created and drawn\n");
146
147 /* Cleanup */
150 ui_shutdown(ui);
151 printf("PASS: shutdown clean\n");
152 return 0;
153}
154
155int main(void) {
156 compile_time_checks();
157 printf("PASS: compile-time type checks\n");
158 return test_lifecycle();
159}
void ui_render()
Definition ui_ncurses.c:800
UiRuntime * ui_init(const UiConfig *config)
Definition ui_ncurses.c:261
UiSurface * ui_surface_new(uint w, UiSurface *parent, uint p, uint lines, uint cols, uint y, uint x)
Definition ui_ncurses.c:414
@ UI_KEY_CHAR
Definition ui_backend.h:44
@ UI_KEY_DOWN
Definition ui_backend.h:51
@ UI_KEY_NONE
Definition ui_backend.h:43
@ UI_KEY_ESCAPE
Definition ui_backend.h:46
@ UI_KEY_LEFT
Definition ui_backend.h:52
@ UI_KEY_F1
Definition ui_backend.h:62
@ UI_KEY_ENTER
Definition ui_backend.h:45
@ UI_KEY_UP
Definition ui_backend.h:50
@ UI_KEY_F12
Definition ui_backend.h:73
@ UI_KEY_RIGHT
Definition ui_backend.h:53
int ui_draw_text(UiSurface *s, uint w, uint y, uint x, const char *text)
void ui_surface_destroy(UiSurface *s)
Definition ui_ncurses.c:377
void ui_get_screen_size(uint *lines, uint *cols)
Definition ui_ncurses.c:692
void ui_shutdown()
Definition ui_ncurses.c:344
uint16_t UiStyle
Definition ui_backend.h:35
void ui_get_caps(UiCaps *caps)
Query the capabilities of the active backend.
Definition ui_ncurses.c:88
@ UI_BACKEND_NCURSES
Definition ui_backend.h:156
@ UI_BACKEND_NOTCURSES
Definition ui_backend.h:157
@ UI_MOUSE_SCROLL_DOWN
Definition ui_backend.h:82
@ UI_MOUSE_PRESS
Definition ui_backend.h:78
@ UI_MOUSE_SCROLL_UP
Definition ui_backend.h:81
@ UI_MOUSE_NONE
Definition ui_backend.h:77
@ UI_MOUSE_RELEASE
Definition ui_backend.h:79
int ui_draw_border(UiSurface *s, uint w, UiBorderKind kind, const UiStyle *style)
UiBackend ui_get_backend()
Return which backend is powering this runtime.
Definition ui_ncurses.c:84
@ UI_BORDER_ROUNDED
Definition ui_backend.h:89
@ UI_BORDER_LIGHT
Definition ui_backend.h:88
UiFramedSurface ui_framed_surface_new(UiSurface *parent, UiRect rect)
Creates a new framed surface with the specified parent and rectangle.
Definition ui_layout.c:26
void ui_framed_surface_destroy(UiFramedSurface *fs)
Destroys a framed surface and releases its resources.
Definition ui_layout.c:54
#define WA_NORMAL
int main(int argc, char **argv)
Capture the current terminal settings for later restoration.
Definition amort.c:30
int cols
Definition ui_backend.h:121
int lines
Definition ui_backend.h:120
bool cursor_visible
Definition ui_backend.h:145
const char * tty_path
Definition ui_backend.h:147
bool enable_mouse
Definition ui_backend.h:143
bool enable_alt_screen
Definition ui_backend.h:144
bool palette256
Definition ui_backend.h:170
bool mouse
Definition ui_backend.h:171
int color_pairs
Definition ui_backend.h:174
bool truecolor
Definition ui_backend.h:169
bool unicode
Definition ui_backend.h:172
bool resize
Definition ui_backend.h:173
UiSurface * inner
Definition ui_layout.h:20
UiSurface * outer
Definition ui_layout.h:19