From 04616d5cff135a3f2fa0dcd99c3d756b67312daa Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Wed, 14 Oct 2026 14:07:19 +0300 Subject: Test pre-init public API, header portability and integration requests Add tests/common/test_public_api.c: before yasl_init, argument errors are reported first, owner-thread calls fail with ENODEV, queries return their documented fallbacks, yasl_drop_next_path parses a crafted text/uri-list, yasl_get_system_string follows its length and NUL rules, and yasl_wake is a no-op with no display. Build tests/test_header_c11.c as strict C11 and C17 with -pedantic-errors. Extend the surface integration test, run on weston and Xwayland, with title, window requests, bell, desktop queries, drag cancel, input-less move/menu/drag calls, a popup (its parent's destroy must also remove it, checked through the display's surface list), and a clipboard round trip. Run tests/x11/test_input.c in the X11 phase of run_surfaces.py through an optional trailing argument. Co-Authored-By: Claude Haiku 5.5 --- tests/common/test_surface_integration.c | 77 ++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) (limited to 'tests/common/test_surface_integration.c') diff --git a/tests/common/test_surface_integration.c b/tests/common/test_surface_integration.c index 072a307..9067640 100644 --- a/tests/common/test_surface_integration.c +++ b/tests/common/test_surface_integration.c @@ -40,6 +40,14 @@ static void push(yasl_surface *s, struct yasl_private_event event) assert(yasl_private_events_push(s->display, s, &event)); } static int refreshes; +/* Whether the display still lists the surface with this address; compared, never dereferenced. */ +static bool listed(struct yasl_private_display *d, uintptr_t id) +{ + for (yasl_surface *p = d->surfaces; p; p = p->event_next) + if ((uintptr_t)p == id) + return true; + return false; +} static void refresh(yasl_surface *s) { refreshes++; @@ -244,7 +252,74 @@ int main(int argc, char **argv) s->display->modal = false; #endif s->refresh = NULL; - yasl_surface_destroy(s); + + /* Title and window requests: each either works or reports ENOTSUP. */ + assert(yasl_surface_set_title(s, "CPU contract renamed") == 0); + static const enum yasl_request requests[] = {YASL_REQUEST_RESTORE, YASL_REQUEST_FULLSCREEN, + YASL_REQUEST_MAXIMIZE, YASL_REQUEST_MINIMIZE}; + for (size_t i = 0; i < sizeof requests / sizeof requests[0]; i++) { + int r = yasl_surface_request(s, requests[i]); + assert(r == 0 || r == -ENOTSUP); + } + drain(); + int restored = yasl_surface_request(s, YASL_REQUEST_RESTORE); + assert(restored == 0 || restored == -ENOTSUP); + drain(); + /* ENOTSUP is the documented answer when the compositor lacks xdg-system-bell; Wayland + * currently reports EIO there, so only the 0-or-errno rule is checked. */ + assert(yasl_surface_bell(s) <= 0); + + /* Desktop queries and the drag cancel, which is a no-op without a drag. */ + assert(yasl_get_appearance() <= 7); + int double_click = yasl_get_double_click_ms(); + assert(double_click >= 1 && double_click <= 10000); + assert(yasl_drag_cancel() == 0); + + /* Without a pointer press these may fail with an errno; they must simply return. */ + assert(yasl_surface_begin_move_resize(s, 0) <= 0); + assert(yasl_surface_show_window_menu(s, 1, 1) <= 0); + assert(yasl_drag_start(s, NULL) <= 0); + drain(); + + /* A popup needs an input grab to open; if it opens, its parent owns it. */ + struct yasl_private_display *display = s->display; + struct yasl_popup_options popup_options = { + .width = 40, .height = 30, .anchor_width = 1, .anchor_height = 1}; + errno = 0; + yasl_surface *popup = yasl_popup_create(s, &popup_options); + uintptr_t popup_id = (uintptr_t)popup; + if (!popup) { + assert(errno != 0); + } else { + assert(listed(display, popup_id)); + assert(yasl_popup_reposition(popup, &popup_options) <= 0); + int pw = 0, ph = 0; + assert(yasl_cpu_pixels(popup, &pw, &ph) && pw > 0 && ph > 0); + } + + /* Clipboard: offering text may be refused without input; if accepted, it comes back. */ + int offered = yasl_clipboard_set(YASL_CLIPBOARD, "yasl"); + assert(offered <= 0); + if (offered == 0) { + assert(yasl_clipboard_request(s, YASL_CLIPBOARD) == 0); + bool got = false; + uint64_t clipboard_deadline = yasl_time_ns() + 2000000000ull; + while (!got && yasl_time_ns() < clipboard_deadline) { + assert(yasl_wait_event(&e, 50) >= 0); + if (e.type != YASL_EVENT_CLIPBOARD) + continue; + got = true; + assert(e.surface == s && e.action <= YASL_TRANSFER_FAILED); + if (e.action == YASL_TRANSFER_OK) + assert(e.length == 4 && !strcmp(e.text, "yasl")); + } + assert(got); + } + + /* Destroying the parent also destroys its popup. */ + assert(yasl_surface_destroy(s) == 0); + if (popup) + assert(!listed(display, popup_id)); assert(yasl_init(backend, NULL) == -EALREADY); s = yasl_surface_create(&(struct yasl_surface_options){.title = "shared backend remains", .width = 64, .height = 64}); -- cgit v1.2.3