diff --git a/ChangeLog b/ChangeLog index bb070995f..2ebc63c66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-06-10 Chris Lord + + * tests/Makefile.am: + * tests/test-entry-auto.c: + Add automatic test for ClutterEntry, by Tommi Komulainen + 2008-06-10 Chris Lord * clutter/cogl/common/cogl-primitives.c: (_cogl_path_arc): diff --git a/tests/Makefile.am b/tests/Makefile.am index 92eb08d3a..363e70bc0 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -13,7 +13,7 @@ noinst_PROGRAMS = test-textures test-events test-offscreen test-scale \ test-cogl-tex-getset test-cogl-offscreen \ test-cogl-tex-polygon test-stage-read-pixels \ test-random-text test-clip test-paint-wrapper \ - test-texture-quality + test-texture-quality test-entry-auto if X11_TESTS noinst_PROGRAMS += test-pixmap @@ -66,5 +66,6 @@ test_stage_read_pixels_SOURCES = test-stage-read-pixels.c test_random_text_SOURCES = test-random-text.c test_paint_wrapper_SOURCES = test-paint-wrapper.c test_texture_quality_SOURCES = test-texture-quality.c +test_entry_auto_SOURCES = test-entry-auto.c EXTRA_DIST = redhand.png test-script.json diff --git a/tests/test-entry-auto.c b/tests/test-entry-auto.c new file mode 100644 index 000000000..f340953d8 --- /dev/null +++ b/tests/test-entry-auto.c @@ -0,0 +1,301 @@ + +#include +#include + +#ifndef g_assert_cmpint +# define g_assert_cmpint(x,y,z) g_assert((x) y (z)) +#endif + +typedef struct { + gunichar unichar; + const char bytes[6]; + gint nbytes; +} TestData; + +const TestData +test_data[] = { + { 0xe4, "\xc3\xa4", 2 }, /* LATIN SMALL LETTER A WITH DIAERESIS */ + { 0x2665, "\xe2\x99\xa5", 3 } /* BLACK HEART SUIT */ +}; + +static void +selfcheck (const TestData *t) +{ + gunichar unichar; + char bytes[6]; + int nbytes; + + g_assert (g_unichar_validate (t->unichar)); + + nbytes = g_unichar_to_utf8 (t->unichar, bytes); + bytes[nbytes] = '\0'; + g_assert (nbytes == t->nbytes); + g_assert (memcmp (t->bytes, bytes, nbytes) == 0); + + unichar = g_utf8_get_char_validated (bytes, nbytes); + g_assert (unichar == t->unichar); +} + +static int +get_nbytes (ClutterEntry *entry) +{ + const char *s = clutter_entry_get_text (entry); + return strlen (s); +} + +static int +get_nchars (ClutterEntry *entry) +{ + const char *s = clutter_entry_get_text (entry); + g_assert (g_utf8_validate (s, -1, NULL)); + return g_utf8_strlen (s, -1); +} + +#define DONT_MOVE_CURSOR (-2) + +static void +insert_unichar (ClutterEntry *entry, gunichar unichar, int position) +{ + if (position > DONT_MOVE_CURSOR) + { + clutter_entry_set_cursor_position (entry, position); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, position); + } + + clutter_entry_insert_unichar (entry, unichar); +} + +static void +test_empty (ClutterEntry *entry, const TestData *unused) +{ + g_assert (clutter_entry_get_text (entry) == NULL); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1); +} + +static void +test_set_empty (ClutterEntry *entry, const TestData *unused) +{ + /* annoyingly slightly different from initially empty */ + clutter_entry_set_text (entry, ""); + g_assert_cmpint (get_nchars (entry), ==, 0); + g_assert_cmpint (get_nbytes (entry), ==, 0); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1); +} + +static void +test_set_text (ClutterEntry *entry, const TestData *unused) +{ + clutter_entry_set_text (entry, "abcdef"); + g_assert_cmpint (get_nchars (entry), ==, 6); + g_assert_cmpint (get_nbytes (entry), ==, 6); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1); + + clutter_entry_set_cursor_position (entry, 5); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 5); + + clutter_entry_set_text (entry, ""); + /* FIXME: cursor position should be -1? + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1); + */ +} + +static void +test_insert (ClutterEntry *entry, const TestData *t) +{ + clutter_entry_insert_unichar (entry, t->unichar); + clutter_entry_insert_unichar (entry, t->unichar); + + insert_unichar (entry, t->unichar, 1); + g_assert_cmpint (get_nchars (entry), ==, 3); + g_assert_cmpint (get_nbytes (entry), ==, 3 * t->nbytes); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 2); +} + +static void +test_append_some (ClutterEntry *entry, const TestData *t) +{ + int i; + + for (i = 1; i <= 4; i++) + { + insert_unichar (entry, t->unichar, DONT_MOVE_CURSOR); + g_assert_cmpint (get_nchars (entry), ==, i); + g_assert_cmpint (get_nbytes (entry), ==, i * t->nbytes); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1); + } +} + +static void +test_prepend_some (ClutterEntry *entry, const TestData *t) +{ + int i; + + clutter_entry_insert_unichar (entry, t->unichar); + g_assert_cmpint (get_nchars (entry), ==, 1); + g_assert_cmpint (get_nbytes (entry), ==, 1 * t->nbytes); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1); + + for (i = 2; i <= 4; i++) + { + insert_unichar (entry, t->unichar, 0); + g_assert_cmpint (get_nchars (entry), ==, i); + g_assert_cmpint (get_nbytes (entry), ==, i * t->nbytes); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1); + } +} + +static void +test_delete_chars (ClutterEntry *entry, const TestData *t) +{ + int i; + + for (i = 0; i < 4; i++) + clutter_entry_insert_unichar (entry, t->unichar); + + clutter_entry_set_cursor_position (entry, 2); + clutter_entry_delete_chars (entry, 1); + g_assert_cmpint (get_nchars (entry), ==, 3); + g_assert_cmpint (get_nbytes (entry), ==, 3 * t->nbytes); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1); + + clutter_entry_set_cursor_position (entry, 2); + clutter_entry_delete_chars (entry, 1); + g_assert_cmpint (get_nchars (entry), ==, 2); + g_assert_cmpint (get_nbytes (entry), ==, 2 * t->nbytes); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1); +} + +static void +test_delete_text (ClutterEntry *entry, const TestData *t) +{ + int i; + + for (i = 0; i < 4; i++) + clutter_entry_insert_unichar (entry, t->unichar); + + clutter_entry_set_cursor_position (entry, 3); + clutter_entry_delete_text (entry, 2, 4); + g_assert_cmpint (get_nchars (entry), ==, 2); + g_assert_cmpint (get_nbytes (entry), ==, 2 * t->nbytes); + /* FIXME: cursor position should be -1? + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1); + */ +} + +static void +init_event (ClutterKeyEvent *event) +{ + event->type = CLUTTER_KEY_PRESS; + event->time = 0; /* not needed */ + event->flags = CLUTTER_EVENT_FLAG_SYNTHETIC; + event->stage = NULL; /* not needed */ + event->source = NULL; /* not needed */ + event->modifier_state = 0; + event->hardware_keycode = 0; /* not needed */ +} + +static void +send_keyval (ClutterEntry *entry, int keyval) +{ + ClutterKeyEvent event; + + init_event (&event); + event.keyval = keyval; + event.unicode_value = 0; /* should be ignored for cursor keys etc. */ + + clutter_entry_handle_key_event (entry, &event); +} + +static void +send_unichar (ClutterEntry *entry, gunichar unichar) +{ + ClutterKeyEvent event; + + init_event (&event); + event.keyval = 0; /* should be ignored for printable characters */ + event.unicode_value = unichar; + + clutter_entry_handle_key_event (entry, &event); +} + +static void +test_cursor (ClutterEntry *entry, const TestData *t) +{ + int i; + + for (i = 0; i < 4; ++i) + clutter_entry_insert_unichar (entry, t->unichar); + clutter_entry_set_cursor_position (entry, 2); + + /* test cursor moves and is clamped */ + send_keyval (entry, CLUTTER_Left); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1); + + send_keyval (entry, CLUTTER_Left); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 0); + + send_keyval (entry, CLUTTER_Left); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 0); + + /* delete text containing the cursor */ + clutter_entry_set_cursor_position (entry, 3); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 3); + + clutter_entry_delete_text (entry, 2, 4); + send_keyval (entry, CLUTTER_Left); + /* FIXME: cursor position should be -1? + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1); + */ +} + +static void +test_event (ClutterEntry *entry, const TestData *t) +{ + send_unichar (entry, t->unichar); + g_assert_cmpint (get_nchars (entry), ==, 1); + g_assert_cmpint (get_nbytes (entry), ==, 1 * t->nbytes); + g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1); +} + +static void +run (void (*test_func)(ClutterEntry *, const TestData *), const TestData *t) +{ + ClutterActor *entry; + + entry = clutter_entry_new (); + test_func (CLUTTER_ENTRY (entry), t); + clutter_actor_destroy (entry); +} + +int +main (int argc, char **argv) +{ + int i; + + g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); + + for (i = 0; i < G_N_ELEMENTS (test_data); ++i) + selfcheck (&test_data[i]); + + clutter_init (&argc, &argv); + + run (test_empty, NULL); + run (test_set_empty, NULL); + run (test_set_text, NULL); + + for (i = 0; i < G_N_ELEMENTS (test_data); ++i) + { + const TestData *t = &test_data[i]; + + run (test_append_some, t); + run (test_prepend_some, t); + run (test_insert, t); + run (test_delete_chars, t); + run (test_delete_text, t); + run (test_cursor, t); + run (test_event, t); + } + + return 0; +} +