From b00e6632f6d64086884a1d35ce7b5ac9c65ca46d Mon Sep 17 00:00:00 2001 From: Jan Arne Petersen Date: Tue, 21 Aug 2012 18:28:49 +0200 Subject: [PATCH] tests: Add unit test for text model Add tests for activate/deactivate and unfocusing of the assigned surface. --- tests/.gitignore | 2 +- tests/Makefile.am | 8 +- tests/test-text-client.c | 260 +++++++++++++++++++++++++++++++++++++++++++++++ tests/text-test.c | 213 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 480 insertions(+), 3 deletions(-) create mode 100644 tests/test-text-client.c create mode 100644 tests/text-test.c diff --git a/tests/.gitignore b/tests/.gitignore index 45f7735..f46c8d2 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,4 +1,4 @@ matrix-test setbacklight test-client - +test-text-client diff --git a/tests/Makefile.am b/tests/Makefile.am index 80f6db8..b471cc4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -TESTS = surface-test.la client-test.la event-test.la +TESTS = surface-test.la client-test.la event-test.la text-test.la TESTS_ENVIRONMENT = $(SHELL) $(top_srcdir)/tests/weston-test @@ -9,7 +9,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src -DUNIT_TEST $(COMPOSITOR_CFLAGS) check_LTLIBRARIES = $(TESTS) -check_PROGRAMS = test-client +check_PROGRAMS = test-client test-text-client AM_LDFLAGS = -module -avoid-version -rpath $(libdir) @@ -18,10 +18,14 @@ test_runner_src = test-runner.c test-runner.h surface_test_la_SOURCES = surface-test.c $(test_runner_src) client_test_la_SOURCES = client-test.c $(test_runner_src) event_test_la_SOURCES = event-test.c $(test_runner_src) +text_test_la_SOURCES = text-test.c $(test_runner_src) test_client_SOURCES = test-client.c test_client_LDADD = $(SIMPLE_CLIENT_LIBS) +test_text_client_SOURCES = test-text-client.c ../clients/text-protocol.c +test_text_client_LDADD = $(SIMPLE_CLIENT_LIBS) + noinst_PROGRAMS = $(setbacklight) matrix-test matrix_test_SOURCES = \ diff --git a/tests/test-text-client.c b/tests/test-text-client.c new file mode 100644 index 0000000..877fbc6 --- /dev/null +++ b/tests/test-text-client.c @@ -0,0 +1,260 @@ +/* + * Copyright © 2012 Openismus GmbH + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "../clients/text-client-protocol.h" + +struct display { + struct wl_display *display; + struct wl_compositor *compositor; + + struct wl_surface *surface; + struct wl_seat *seat; + + struct text_model_factory *factory; + struct text_model *text_model; + + unsigned int activated; + unsigned int deactivated; +}; + +static void +text_model_commit_string(void *data, + struct text_model *text_model, + const char *text, + uint32_t index) +{ +} + +static void +text_model_preedit_string(void *data, + struct text_model *text_model, + const char *text, + uint32_t index) +{ +} + +static void +text_model_preedit_styling(void *data, + struct text_model *text_model) +{ +} + +static void +text_model_key(void *data, + struct text_model *text_model) +{ +} + +static void +text_model_selection_replacement(void *data, + struct text_model *text_model) +{ +} + +static void +text_model_direction(void *data, + struct text_model *text_model) +{ +} + +static void +text_model_locale(void *data, + struct text_model *text_model) +{ +} + +static void +text_model_activated(void *data, + struct text_model *text_model) +{ + struct display *display = data; + + fprintf(stderr, "%s\n", __FUNCTION__); + + display->activated += 1; +} + +static void +text_model_deactivated(void *data, + struct text_model *text_model) +{ + struct display *display = data; + + display->deactivated += 1; +} + +static const struct text_model_listener text_model_listener = { + text_model_commit_string, + text_model_preedit_string, + text_model_preedit_styling, + text_model_key, + text_model_selection_replacement, + text_model_direction, + text_model_locale, + text_model_activated, + text_model_deactivated +}; + +static void +handle_global(struct wl_display *_display, uint32_t id, + const char *interface, uint32_t version, void *data) +{ + struct display *display = data; + + if (strcmp(interface, "wl_compositor") == 0) { + display->compositor = + wl_display_bind(display->display, + id, &wl_compositor_interface); + } else if (strcmp(interface, "wl_seat") == 0) { + display->seat = wl_display_bind(display->display, id, + &wl_seat_interface); + } else if (strcmp(interface, "text_model_factory") == 0) { + display->factory = wl_display_bind(display->display, id, + &text_model_factory_interface); + } +} + +static void +create_surface(int fd, struct display *display) +{ + char buf[64]; + int len; + + display->surface = wl_compositor_create_surface(display->compositor); + wl_display_flush(display->display); + + len = snprintf(buf, sizeof buf, "surface %d\n", + wl_proxy_get_id((struct wl_proxy *) display->surface)); + assert(write(fd, buf, len) == len); +} + +static void +create_text_model(int fd, struct display *display) +{ + char buf[64]; + int len; + + display->text_model = text_model_factory_create_text_model(display->factory); + text_model_add_listener(display->text_model, &text_model_listener, display); + wl_display_flush(display->display); + + len = snprintf(buf, sizeof buf, "text_model %d\n", + wl_proxy_get_id((struct wl_proxy *) display->text_model)); + assert(write(fd, buf, len) == len); +} + +static void +write_state(int fd, struct display *display) +{ + char buf[64]; + int len; + + wl_display_flush(display->display); + len = snprintf(buf, sizeof buf, "activated %u deactivated %u\n", + display->activated, display->deactivated); + assert(write(fd, buf, len) == len); + wl_display_roundtrip(display->display); +} + +static void +activate_text_model(int fd, struct display *display) +{ + write_state(fd, display); + + text_model_activate(display->text_model, display->seat, display->surface); + + wl_display_flush(display->display); + wl_display_roundtrip(display->display); +} + +static void +deactivate_text_model(int fd, struct display *display) +{ + write_state(fd, display); + + text_model_deactivate(display->text_model, display->seat); + + wl_display_flush(display->display); + wl_display_roundtrip(display->display); +} + +int main(int argc, char *argv[]) +{ + struct display *display; + char buf[256], *p; + int ret, fd; + + display = malloc(sizeof *display); + assert(display); + + display->display = wl_display_connect(NULL); + assert(display->display); + + display->activated = 0; + display->deactivated = 0; + + wl_display_add_global_listener(display->display, + handle_global, display); + wl_display_iterate(display->display, WL_DISPLAY_READABLE); + wl_display_roundtrip(display->display); + + fd = 0; + p = getenv("TEST_SOCKET"); + if (p) + fd = strtol(p, NULL, 0); + + while (1) { + ret = read(fd, buf, sizeof buf); + if (ret == -1) { + fprintf(stderr, "read error: fd %d, %m\n", fd); + return -1; + } + + fprintf(stderr, "test-client: got %.*s\n", ret - 1, buf); + + if (strncmp(buf, "bye\n", ret) == 0) { + return 0; + } else if (strncmp(buf, "create-surface\n", ret) == 0) { + create_surface(fd, display); + } else if (strncmp(buf, "create-text-model\n", ret) == 0) { + create_text_model(fd, display); + } else if (strncmp(buf, "activate-text-model\n", ret) == 0) { + activate_text_model(fd, display); + } else if (strncmp(buf, "deactivate-text-model\n", ret) == 0) { + deactivate_text_model(fd, display); + } else if (strncmp(buf, "assert-state\n", ret) == 0) { + write_state(fd, display); + } else { + fprintf(stderr, "unknown command %.*s\n", ret, buf); + return -1; + } + } + + assert(0); +} diff --git a/tests/text-test.c b/tests/text-test.c new file mode 100644 index 0000000..bd2a5c5 --- /dev/null +++ b/tests/text-test.c @@ -0,0 +1,213 @@ +/* + * Copyright © 2012 Openismus GmbH + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include + +#include "test-runner.h" + +struct text_test_data { + struct weston_layer *layer; + + unsigned int expected_activated_count; + unsigned int expected_deactivated_count; + + const char *next_command; + void (*next_handle)(struct test_client *client); +}; + +static void +pre_assert_state(struct test_client *client, + unsigned int expected_activated_count, + unsigned int expected_deactivated_count) +{ + unsigned int activated_count, deactivated_count; + + assert(sscanf(client->buf, "activated %u deactivated %u", &activated_count, &deactivated_count) == 2); + fprintf(stderr, "Text model activations: %u deactivations: %u\n", activated_count, deactivated_count); + assert(activated_count == expected_activated_count); + assert(deactivated_count == expected_deactivated_count); +} + +static void +handle_assert_state(struct test_client *client) +{ + struct text_test_data *data = client->data; + + pre_assert_state(client, data->expected_activated_count, data->expected_deactivated_count); + + test_client_send(client, data->next_command); + client->handle = data->next_handle; +} + +static void +post_assert_state(struct test_client *client, + unsigned int expected_activated_count, + unsigned int expected_deactivated_count, + const char *next_command, + void (*next_handle)(struct test_client *client)) +{ + struct text_test_data *data = client->data; + + data->expected_activated_count = expected_activated_count; + data->expected_deactivated_count = expected_deactivated_count; + + data->next_command = next_command; + data->next_handle = next_handle; + + test_client_send(client, "assert-state\n"); + client->handle = handle_assert_state; +} + +static struct weston_seat* +get_seat(struct test_client *client) +{ + struct wl_list *seat_list; + struct weston_seat *seat; + + seat_list = &client->compositor->seat_list; + assert(wl_list_length(seat_list) == 1); + seat = container_of(seat_list->next, struct weston_seat, link); + + return seat; +} + +static void +handle_surface_unfocus(struct test_client *client) +{ + struct weston_seat *seat; + + seat = get_seat(client); + + pre_assert_state(client, 2, 1); + + /* Unfocus the surface */ + wl_keyboard_set_focus(&seat->keyboard, NULL); + + post_assert_state(client, 2, 2, "bye\n", NULL); +} + +static void +handle_reactivate_text_model(struct test_client *client) +{ + pre_assert_state(client, 1, 1); + + /* text_model is activated */ + + post_assert_state(client, 2, 1, + "assert-state\n", handle_surface_unfocus); +} + +static void +handle_deactivate_text_model(struct test_client *client) +{ + pre_assert_state(client, 1, 0); + + /* text_model is deactivated */ + + post_assert_state(client, 1, 1, + "activate-text-model\n", handle_reactivate_text_model); +} + +static void +handle_activate_text_model(struct test_client *client) +{ + pre_assert_state(client, 0, 0); + + /* text_model is activated */ + + post_assert_state(client, 1, 0, + "deactivate-text-model\n", handle_deactivate_text_model); +} + +static void +handle_text_model(struct test_client *client) +{ + uint32_t id; + struct wl_resource *resource; + + assert(sscanf(client->buf, "text_model %u", &id) == 1); + fprintf(stderr, "got text_model id %u\n", id); + resource = wl_client_get_object(client->client, id); + assert(resource); + assert(strcmp(resource->object.interface->name, "text_model") == 0); + + test_client_send(client, "activate-text-model\n"); + client->handle = handle_activate_text_model; +} + +static void +handle_surface(struct test_client *client) +{ + uint32_t id; + struct wl_resource *resource; + struct weston_surface *surface; + struct text_test_data *data = client->data; + struct weston_seat *seat; + + assert(sscanf(client->buf, "surface %u", &id) == 1); + fprintf(stderr, "got surface id %u\n", id); + resource = wl_client_get_object(client->client, id); + assert(resource); + assert(strcmp(resource->object.interface->name, "wl_surface") == 0); + + surface = (struct weston_surface *) resource; + + weston_surface_configure(surface, 100, 100, 200, 200); + weston_surface_assign_output(surface); + weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0); + + data->layer = malloc(sizeof *data->layer); + weston_layer_init(data->layer, &client->compositor->cursor_layer.link); + wl_list_insert(&data->layer->surface_list, &surface->layer_link); + weston_surface_damage(surface); + + seat = get_seat(client); + client->compositor->focus = 1; /* Make it work even if pointer is + * outside X window. */ + wl_keyboard_set_focus(&seat->keyboard, &surface->surface); + + test_client_send(client, "create-text-model\n"); + client->handle = handle_text_model; +} + +TEST(text_test) +{ + struct test_client *client; + struct text_test_data *data; + + client = test_client_launch(compositor, "test-text-client"); + client->terminate = 1; + + test_client_send(client, "create-surface\n"); + client->handle = handle_surface; + + data = malloc(sizeof *data); + assert(data); + client->data = data; + +} -- 2.7.4