summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChoe Hwanjin <choe.hwanjin@gmail.com>2020-04-20 17:49:33 +0900
committerChoe Hwanjin <choe.hwanjin@gmail.com>2020-04-20 17:49:33 +0900
commit24eecbcdc015a90c9e6fc5b33201f6e899ae556c (patch)
tree1fb83f05a2658336c6af5badb286aeaac54944e1
parentd47291d2c4f9e8e79012f0488678e4802a8d8f92 (diff)
parent712b0677f196e7ed6b13ff6050db080afd2efca8 (diff)
downloadibus-hangul-24eecbcdc015a90c9e6fc5b33201f6e899ae556c.tar.gz
Merge branch 'testcases' of https://github.com/epico/ibus-hangul
Merge pull request #96 * 'testcases' of https://github.com/epico/ibus-hangul: Write runtest script Write ibus-hangul.c test case Update autoconf to compile ibus-hangul tests https://github.com/libhangul/ibus-hangul/pull/96
-rw-r--r--Makefile.am1
-rw-r--r--configure.ac18
-rw-r--r--ibus-hangul.spec.in3
-rw-r--r--src/Makefile.am27
-rw-r--r--tests/Makefile.am77
-rw-r--r--tests/ibus-hangul.c322
-rw-r--r--tests/meta.test.in4
-rwxr-xr-xtests/runtest25
8 files changed, 472 insertions, 5 deletions
diff --git a/Makefile.am b/Makefile.am
index 3deaff8..fcb70d3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,6 +20,7 @@
SUBDIRS = \
src \
+ tests \
setup \
icons \
data \
diff --git a/configure.ac b/configure.ac
index 1a1b992..664c2a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -64,6 +64,11 @@ PKG_CHECK_MODULES(HANGUL, [
libhangul >= 0.1.0
])
+# check gtk
+PKG_CHECK_MODULES(GTK, [
+ gtk+-3.0 >= 3.0.0
+])
+
# check env
AC_PATH_PROG(ENV_PROG, env)
AC_SUBST(ENV_PROG)
@@ -84,6 +89,18 @@ AC_DEFINE_UNQUOTED(
[Define to the read-only architecture-independent data directory.]
)
+# --enable-installed-tests
+AC_ARG_ENABLE(installed-tests,
+ AS_HELP_STRING([--enable-installed-tests],
+ [Enable to installed tests]),
+ [enable_installed_tests=$enableval],
+ [enable_installed_tests=no]
+)
+AM_CONDITIONAL([ENABLE_INSTALLED_TESTS], [test x"$enable_installed_tests" = x"yes"])
+if test x"$enable_installed_tests" = x"no"; then
+ enable_installed_tests="no (disabled, use --enable-installed-tests to enable)"
+fi
+
# OUTPUT files
AC_CONFIG_FILES([
po/Makefile.in
@@ -91,6 +108,7 @@ Makefile
ibus-hangul.spec
src/Makefile
src/hangul.xml.in
+tests/Makefile
setup/Makefile
icons/Makefile
data/Makefile
diff --git a/ibus-hangul.spec.in b/ibus-hangul.spec.in
index f6c86fc..3281a16 100644
--- a/ibus-hangul.spec.in
+++ b/ibus-hangul.spec.in
@@ -36,6 +36,9 @@ make DESTDIR=${RPM_BUILD_ROOT} install
%find_lang %{name}
+%check
+make check DISABLE_GUI_TESTS=ibus-hangul
+
%clean
rm -rf $RPM_BUILD_ROOT
diff --git a/src/Makefile.am b/src/Makefile.am
index 2efff43..bda8a04 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,6 +28,27 @@ AM_LDFLAGS = \
@HANGUL_LIBS@ \
$(NULL)
+noinst_LIBRARIES = \
+ libinternal.a
+ $(NULL)
+
+libinternal_a_SOURCES = \
+ engine.c \
+ engine.h \
+ ustring.c \
+ ustring.h \
+ i18n.h \
+ $(NULL)
+
+libinternal_a_CFLAGS = \
+ @IBUS_CFLAGS@ \
+ @HANGUL_CFLAGS@ \
+ -DPKGDATADIR=\"$(pkgdatadir)\" \
+ -DLOCALEDIR=\"$(localedir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DIBUSHANGUL_DATADIR=\"$(datadir)/ibus-hangul\" \
+ $(NULL)
+
check_PROGRAMS = \
test-ustring
$(NULL)
@@ -40,11 +61,6 @@ libexec_PROGRAMS = ibus-engine-hangul
ibus_engine_hangul_SOURCES = \
main.c \
- engine.c \
- engine.h \
- ustring.c \
- ustring.h \
- i18n.h \
$(NULL)
ibus_engine_hangul_CFLAGS = \
@@ -57,6 +73,7 @@ ibus_engine_hangul_CFLAGS = \
$(NULL)
ibus_engine_hangul_LDADD = \
+ libinternal.a \
@IBUS_LIBS@ \
@HANGUL_LIBS@ \
$(NULL)
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..59339aa
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,77 @@
+# vim:set noet ts=4:
+#
+# ibus-hangul - The Hangul engine for IBus
+#
+# Copyright (c) 2019 Peng Wu <alexepico@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+TESTS = \
+ ibus-hangul \
+ $(NULL)
+
+CLEANFILES = $(test_metas)
+
+EXTRA_DIST = $(test_metas_in) runtest
+
+noinst_PROGRAMS = $(TESTS)
+
+TESTS_ENVIRONMENT = \
+ top_builddir=$(top_builddir) \
+ top_srcdir=$(top_srcdir) \
+ builddir=$(builddir) \
+ srcdir=$(srcdir) \
+ LD_LIBRARY_PATH="$(top_builddir)/src/.libs:$(top_builddir)/src" \
+ DISABLE_GUI_TESTS="$(DISABLE_GUI_TESTS)" \
+ $(NULL)
+
+LOG_COMPILER = $(srcdir)/runtest
+test_metas_in = meta.test.in
+
+if ENABLE_INSTALLED_TESTS
+test_execs = ibus-hangul
+test_metas = $(addsuffix .test, $(test_execs))
+test_sources_DATA = $(test_metas)
+test_sourcesdir = $(datadir)/installed-tests/ibus-hangul
+test_execs_PROGRAMS = $(TESTS)
+test_execsdir = $(libexecdir)/installed-tests/ibus-hangul
+endif
+
+ibus_hangul_SOURCES = ibus-hangul.c
+ibus_hangul_CFLAGS = \
+ @IBUS_CFLAGS@ \
+ @HANGUL_CFLAGS@ \
+ @GTK_CFLAGS@ \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ -DPKGDATADIR=\"$(pkgdatadir)\" \
+ -DLOCALEDIR=\"$(localedir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DIBUSHANGUL_DATADIR=\"$(datadir)/ibus-hangul\" \
+ $(NULL)
+
+ibus_hangul_LDADD = \
+ ../src/libinternal.a \
+ @IBUS_LIBS@ \
+ @HANGUL_LIBS@ \
+ @GTK_LIBS@ \
+ $(NULL)
+
+$(test_metas): $(test_metas_in) $(test_programs)
+ f=`echo $@ | sed -e 's/\.test//'`; \
+ TEST_EXEC=$(test_execsdir)/$$f; \
+ sed -e "s|@TEST_EXEC[@]|$$TEST_EXEC|g" $(test_metas_in) > $@.tmp; \
+ mv $@.tmp $@; \
+ $(NULL)
diff --git a/tests/ibus-hangul.c b/tests/ibus-hangul.c
new file mode 100644
index 0000000..4375f90
--- /dev/null
+++ b/tests/ibus-hangul.c
@@ -0,0 +1,322 @@
+#include <unistd.h>
+#include <gtk/gtk.h>
+#include "ibus.h"
+#include "engine.h"
+
+#define GREEN "\033[0;32m"
+#define RED "\033[0;31m"
+#define NC "\033[0m"
+
+typedef struct {
+ const gchar * input;
+ const gchar * output;
+}TestCase;
+
+IBusBus *m_bus;
+IBusEngine *m_engine;
+gchar *m_srcdir;
+
+IBusKeymap *keymap = NULL;
+
+const guint m_switch_hangul[3] = {IBUS_Hangul, 122, 0};
+
+const TestCase m_test_cases[] =
+{
+ {"rk ", "가"}
+};
+
+static gboolean window_focus_in_event_cb (GtkWidget *entry,
+ GdkEventFocus *event,
+ gpointer data);
+
+static guint16 guess_keycode (IBusKeymap *keymap,
+ guint keyval,
+ guint32 modifiers)
+{
+ /* The IBusKeymap only have 256 entries here,
+ Use Brute Force method to get keycode from keyval. */
+ guint16 keycode = 0;
+ for (; keycode < 256; ++keycode) {
+ if (keyval == ibus_keymap_lookup_keysym (keymap, keycode, modifiers))
+ return keycode;
+ }
+ return 0;
+}
+
+static IBusEngine *
+create_engine_cb (IBusFactory *factory,
+ const gchar *name,
+ gpointer data)
+{
+ static int i = 1;
+ gchar *engine_path =
+ g_strdup_printf ("/org/freedesktop/IBus/engine/hangultest/%d",
+ i++);
+
+ m_engine = ibus_engine_new_with_type (IBUS_TYPE_HANGUL_ENGINE,
+ name,
+ engine_path,
+ ibus_bus_get_connection (m_bus));
+ g_free (engine_path);
+
+ return m_engine;
+}
+
+static gboolean
+register_ibus_engine ()
+{
+ IBusFactory *factory;
+ IBusComponent *component;
+ IBusEngineDesc *desc;
+
+ m_bus = ibus_bus_new ();
+ if (!ibus_bus_is_connected (m_bus)) {
+ g_critical ("ibus-daemon is not running.");
+ return FALSE;
+ }
+ factory = ibus_factory_new (ibus_bus_get_connection (m_bus));
+ g_signal_connect (factory, "create-engine",
+ G_CALLBACK (create_engine_cb), NULL);
+
+ component = ibus_component_new (
+ "org.freedesktop.IBus.HangulTest",
+ "Hangul Engine Test",
+ "1.5.1",
+ "GPL",
+ "Peng Huang <shawn.p.huang@gmail.com>",
+ "https://github.com/ibus/ibus/wiki",
+ "",
+ "ibus-hangul");
+ desc = ibus_engine_desc_new (
+ "hangultest",
+ "Hangul Test",
+ "Hangul Test",
+ "en",
+ "GPL",
+ "Peng Huang <shawn.p.huang@gmail.com>",
+ "ibus-hangul",
+ "us");
+ ibus_component_add_engine (component, desc);
+ ibus_bus_register_component (m_bus, component);
+
+ return TRUE;
+}
+
+static gboolean
+finit (gpointer data)
+{
+ g_test_incomplete ("time out");
+ gtk_main_quit ();
+ return FALSE;
+}
+
+static void
+set_engine_cb (GObject *object, GAsyncResult *res, gpointer data)
+{
+ IBusBus *bus = IBUS_BUS (object);
+ GtkWidget *entry = GTK_WIDGET (data);
+ GError *error = NULL;
+ gint i;
+ const gchar *p = NULL;
+
+ if (!ibus_bus_set_global_engine_async_finish (bus, res, &error)) {
+ gchar *msg = g_strdup_printf ("set engine failed: %s", error->message);
+ g_test_incomplete (msg);
+ g_free (msg);
+ g_error_free (error);
+ return;
+ }
+
+ {
+ /* Switch hangul mode. */
+ guint keyval = m_switch_hangul[0];
+ guint keycode = m_switch_hangul[1];
+ guint modifiers = m_switch_hangul[2];
+ gboolean retval;
+
+ if (keyval == 0) {
+ g_test_incomplete ("ibus-hangul switch key is not set correctly.");
+ return;
+ }
+ g_signal_emit_by_name (m_engine, "process-key-event",
+ keyval, keycode, modifiers, &retval);
+ modifiers |= IBUS_RELEASE_MASK;
+ sleep(1);
+ g_signal_emit_by_name (m_engine, "process-key-event",
+ keyval, keycode, modifiers, &retval);
+ }
+
+ {
+ /* Run test cases */
+ for (i = 0;
+ i < G_N_ELEMENTS(m_test_cases);
+ i++) {
+ for (p = m_test_cases[i].input; *p; p++) {
+ gboolean retval;
+ guint keyval = *p;
+ guint modifiers = 0;
+ guint keycode = guess_keycode (keymap, keyval, modifiers);
+
+ if (keyval == 0)
+ break;
+ g_signal_emit_by_name (m_engine, "process-key-event",
+ keyval, keycode, modifiers, &retval);
+ modifiers |= IBUS_RELEASE_MASK;
+ sleep(1);
+ g_signal_emit_by_name (m_engine, "process-key-event",
+ keyval, keycode, modifiers, &retval);
+ }
+ }
+ }
+
+ g_signal_handlers_disconnect_by_func (entry,
+ G_CALLBACK (window_focus_in_event_cb),
+ NULL);
+ g_timeout_add_seconds (10, finit, NULL);
+}
+
+static gboolean
+window_focus_in_event_cb (GtkWidget *entry, GdkEventFocus *event, gpointer data)
+{
+ g_assert (m_bus != NULL);
+ ibus_bus_set_global_engine_async (m_bus,
+ "hangultest",
+ -1,
+ NULL,
+ set_engine_cb,
+ entry);
+ return FALSE;
+}
+
+static void
+window_inserted_text_cb (GtkEntryBuffer *buffer,
+ guint position,
+ const gchar *chars,
+ guint nchars,
+ gpointer data)
+{
+/* https://gitlab.gnome.org/GNOME/gtk/commit/9981f46e0b
+ * The latest GTK does not emit "inserted-text" when the text is "".
+ */
+#if !GTK_CHECK_VERSION (3, 22, 16)
+ static int n_loop = 0;
+#endif
+ static guint index = 0;
+ gunichar code = g_utf8_get_char (chars);
+ const gchar *test;
+ GtkEntry *entry = GTK_ENTRY (data);
+
+#if !GTK_CHECK_VERSION (3, 22, 16)
+ if (n_loop % 2 == 1) {
+ n_loop = 0;
+ return;
+ }
+#endif
+
+ {
+ /* Run test case */
+ const gchar *p = chars;
+ const gchar *output = m_test_cases[index].output;
+ guint j = 0;
+ gboolean valid_output = TRUE;
+
+ if (0 != g_strcmp0 (p, output))
+ valid_output = FALSE;
+ index++;
+
+ if (valid_output) {
+ test = GREEN "PASS" NC;
+ } else {
+ test = RED "FAIL" NC;
+ g_test_fail ();
+ }
+ g_print ("%05d %s expected: %s typed: %s\n",
+ index, test, output, p);
+ }
+
+ if (index == G_N_ELEMENTS(m_test_cases)) {
+ gtk_main_quit ();
+ return;
+ }
+
+#if !GTK_CHECK_VERSION (3, 22, 16)
+ n_loop++;
+#endif
+ gtk_entry_set_text (entry, "");
+}
+
+static void
+create_window ()
+{
+ GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ GtkWidget *entry = gtk_entry_new ();
+ GtkEntryBuffer *buffer;
+
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
+ g_signal_connect (entry, "focus-in-event",
+ G_CALLBACK (window_focus_in_event_cb), NULL);
+ buffer = gtk_entry_get_buffer (GTK_ENTRY (entry));
+ g_signal_connect (buffer, "inserted-text",
+ G_CALLBACK (window_inserted_text_cb), entry);
+ gtk_container_add (GTK_CONTAINER (window), entry);
+ gtk_widget_show_all (window);
+}
+
+static void
+test_hangul (void)
+{
+ GLogLevelFlags flags;
+ if (!register_ibus_engine ()) {
+ g_test_fail ();
+ return;
+ }
+
+ ibus_hangul_init (m_bus);
+
+ create_window ();
+ /* FIXME:
+ * IBusIMContext opens GtkIMContextSimple as the slave and
+ * GtkIMContextSimple opens the compose table on el_GR.UTF-8, and the
+ * multiple outputs in el_GR's compose causes a warning in gtkcomposetable
+ * and the warning always causes a fatal in GTest:
+ " "GTK+ supports to output one char only: "
+ */
+ flags = g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL);
+ gtk_main ();
+ g_log_set_always_fatal (flags);
+}
+
+int
+main (int argc, char *argv[])
+{
+ const gchar *test_name;
+ gchar *test_path;
+
+ /* Run test cases with X Window. */
+ g_setenv ("GDK_BACKEND", "x11", TRUE);
+
+ ibus_init ();
+ /* Avoid a warning of "AT-SPI: Could not obtain desktop path or name"
+ * with gtk_main().
+ */
+ g_setenv ("NO_AT_BRIDGE", "1", TRUE);
+ g_test_init (&argc, &argv, NULL);
+ gtk_init (&argc, &argv);
+
+ m_srcdir = argc > 1 ? g_strdup (argv[1]) : g_strdup (".");
+
+#if GLIB_CHECK_VERSION (2, 58, 0)
+ test_name = g_get_language_names_with_category ("LC_CTYPE")[0];
+#else
+ test_name = g_getenv ("LANG");
+#endif
+
+ test_path = g_build_filename ("/ibus-hangul", test_name, NULL);
+ g_test_add_func (test_path, test_hangul);
+ g_free (test_path);
+
+ keymap = ibus_keymap_get("us");
+
+ return g_test_run ();
+}
diff --git a/tests/meta.test.in b/tests/meta.test.in
new file mode 100644
index 0000000..ae2b299
--- /dev/null
+++ b/tests/meta.test.in
@@ -0,0 +1,4 @@
+[Test]
+Type=session
+Exec=@TEST_EXEC@ --tap
+Output=TAP
diff --git a/tests/runtest b/tests/runtest
new file mode 100755
index 0000000..24d3f7b
--- /dev/null
+++ b/tests/runtest
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+: ${top_builddir:=../..}
+: ${top_srcdir:=../..}
+: ${builddir:=.}
+: ${srcdir:=.}
+: ${DISABLE_GUI_TESTS:=''}
+
+ibus-daemon --xim --panel disable --config disable &
+sleep 30
+
+tst=$1
+
+for t in $DISABLE_GUI_TESTS; do
+ if test $t = `basename $tst`; then
+ exit 77
+ fi
+done
+
+$builddir/$tst
+retval=$?
+
+ibus exit
+
+exit $retval