From 5a9e4858f1a2b6cad02ef1d272fc5bed959ec0bf Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Wed, 16 Oct 2019 17:58:55 +0900 Subject: [PATCH] Integrate anthy automation tests to ibus-desktop-testing-runner The test cases can be run with ibus-desktop-testing-runner: % ibus-desktop-testing-runner \ --no-graphics \ --runner=gnome \ --tests='ibus-anthy' \ --output='./ibus-anthy.log' \ --result='./test.log' ibus-desktop-testing-runner requires gnome-desktop-testing-runner in case --runner option is given. --- configure.ac | 14 +++++ tests/Makefile.am | 46 +++++++++++++-- tests/anthycases.py | 0 tests/anthytest.py | 135 +++++++++++++++++++++++++++----------------- tests/meta.test.in | 4 ++ 5 files changed, 142 insertions(+), 57 deletions(-) mode change 100644 => 100755 tests/anthycases.py mode change 100644 => 100755 tests/anthytest.py create mode 100644 tests/meta.test.in diff --git a/configure.ac b/configure.ac index 06c4521..64afcc6 100644 --- a/configure.ac +++ b/configure.ac @@ -398,6 +398,20 @@ LAYOUT_XML="${LAYOUT}" AC_SUBST(LAYOUT) AC_SUBST(LAYOUT_XML) +dnl --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 + + dnl libtool versioning dnl dnl If LT_VERSION_INFO="lt_current:lt_revision:lt_age", libibus is diff --git a/tests/Makefile.am b/tests/Makefile.am index b2d35d6..d891ff2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -19,12 +19,48 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +CLEANFILES = + check: + @TAP_DIR=`python -m site --user-site`/tap; \ + if test x"$$TAP_DIR" != x -a ! -d "$$TAP_DIR" ; then \ + echo "pip install tap.py --user"; \ + pip install tap.py --user; \ + fi; \ bash -x $(srcdir)/test-build.sh --builddir=$(builddir) --srcdir=$(srcdir) +if ENABLE_INSTALLED_TESTS +test_execsdir = $(libexecdir)/installed-tests/ibus-anthy +test_execs = anthytest +test_execs_SCRIPTS = \ + anthycases.py \ + anthytest.py \ + $(NULL) + +test_metas_in = meta.test.in +test_metas = $(addsuffix .test, $(test_execs)) +test_sources_DATA = \ + $(test_metas) \ + $(NULL) +test_sourcesdir = $(datadir)/installed-tests/ibus-anthy + +CLEANFILES += \ + $(test_metas) \ + $(NULL) +endif + +$(test_metas): $(test_metas_in) + f=`echo $@ | sed -e 's/\.test//'`; \ + TEST_EXEC=$(test_execsdir)/$${f}.py; \ + sed -e "s|@TEST_EXEC[@]|$$TEST_EXEC|g" $(test_metas_in) > $@.tmp; \ + mv $@.tmp $@; \ + $(NULL) + EXTRA_DIST = \ - anthycases.py \ - anthytest.py \ - test-build.sh \ - test-console.sh \ - $(NULL) + anthycases.py \ + anthytest.py \ + meta.test.in \ + test-build.sh \ + test-console.sh \ + $(NULL) diff --git a/tests/anthycases.py b/tests/anthycases.py old mode 100644 new mode 100755 diff --git a/tests/anthytest.py b/tests/anthytest.py old mode 100644 new mode 100755 index 377576c..11d0e2b --- a/tests/anthytest.py +++ b/tests/anthytest.py @@ -5,19 +5,28 @@ from __future__ import print_function from gi import require_version as gi_require_version gi_require_version('GLib', '2.0') +gi_require_version('Gio', '2.0') gi_require_version('Gtk', '3.0') gi_require_version('IBus', '1.0') from gi.repository import GLib +from gi.repository import Gio from gi.repository import Gtk from gi.repository import IBus +import argparse import getopt import os import sys import subprocess +import unittest + +try: + from tap import TAPTestRunner +except ModuleNotFoundError as err: + print('Ignore tap module: %s' % str(err)) PY3K = sys.version_info >= (3, 0) -DONE_EXIT = False +DONE_EXIT = True if 'IBUS_ANTHY_ENGINE_PATH' in os.environ: engine_path = os.environ['IBUS_ANTHY_ENGINE_PATH'] @@ -31,11 +40,28 @@ sys.path.append('/usr/share/ibus-anthy/engine') from anthycases import TestCases -class AnthyTest: +# Need to flush the output against Gtk.main() +def printflush(sentence): + try: + print(sentence, flush=True) + except IOError: + pass + +def printerr(sentence): + try: + print(sentence, flush=True, file=sys.stderr) + except IOError: + pass + +class AnthyTest(unittest.TestCase): global DONE_EXIT ENGINE_PATH = '/com/redhat/IBus/engines/Anthy/Test/Engine' - def __init__(self): + + @classmethod + def setUpClass(cls): IBus.init() + + def setUp(self): self.__id = 0 self.__rerun = False self.__test_index = 0 @@ -141,7 +167,6 @@ class AnthyTest: if not self.__bus.set_global_engine_async_finish(res): warning('set engine failed: ' + error.message) return - print('enabled engine') self.__enable_hiragana() self.__main_test() @@ -173,28 +198,15 @@ class AnthyTest: self.__run_cases('commit') def __enable_hiragana(self): - commands = ['gsettings', 'get', - 'org.freedesktop.ibus.engine.anthy.common', - 'input-mode' - ] - if PY3K: - py3result = subprocess.run(commands, stdout=subprocess.PIPE) - try: - result = int(py3result.stdout) - except ValueError: - # No user data - result = 0 - else: - py2result = subprocess.check_output(commands) - result = py2result - if result == '': - result = 0 + settings = Gio.Settings( + schema = "org.freedesktop.ibus.engine.anthy.common"); + result = settings.get_int('input-mode') if result != 0: - print('Enable hiragana', result) + printflush('Enable hiragana %d' % result) key = TestCases['init'] self.__typing(key[0], key[1], key[2]) else: - print('Already hiragana') + printflush('Already hiragana') def __main_test(self): self.__conversion_index = 0 @@ -214,7 +226,8 @@ class AnthyTest: i = 0 if type == 'string': if start == -1 and end == -1: - print('test step:', tag, 'sequences: "' + cases['string'] + '"') + printflush('test step: %s sequences: "%s"' \ + % (tag, str(cases['string']))) for a in cases['string']: if start >= 0 and i < start: i += 1 @@ -222,12 +235,14 @@ class AnthyTest: if end >= 0 and i >= end: break; if start != -1 or end != -1: - print('test step:', tag, 'sequences: "' + cases['string'][i] + '"') + printflush('test step: %s sequences: "%s"' \ + % (tag, str(cases['string']))) self.__typing(ord(a), 0, 0) i += 1 if type == 'keys': if start == -1 and end == -1: - print('test step:', tag, 'sequences:', cases['keys']) + printflush('test step: %s sequences: %s' \ + % (tag, str(cases['keys']))) for key in cases['keys']: if start >= 0 and i < start: i += 1 @@ -235,7 +250,8 @@ class AnthyTest: if end >= 0 and i >= end: break; if start != -1 or end != -1: - print('test step: %s sequences: [0x%X, 0x%X, 0x%X]' % (tag, key[0], key[1], key[2])) + printflush('test step: %s sequences: [0x%X, 0x%X, 0x%X]' \ + % (tag, key[0], key[1], key[2])) self.__typing(key[0], key[1], key[2]) i += 1 @@ -248,9 +264,10 @@ class AnthyTest: tests = TestCases['tests'][self.__test_index] cases = tests['result'] if cases['string'] == chars: - print("OK: ", chars) + printflush('OK: %d %s' % (self.__test_index, chars)) else: - print("NG: ", cases['string'], chars) + printflush('NG: %d %s %s' \ + % (self.__test_index, str(cases['string']), chars)) self.__test_index += 1 if self.__test_index == len(TestCases['tests']): if DONE_EXIT: @@ -259,9 +276,15 @@ class AnthyTest: self.__entry.set_text('') self.__main_test() - def run(self): + def main(self): Gtk.main() + def test_typing(self): + if not self.register_ibus_engine(): + sys.exit(-1) + self.create_window() + self.main() + def print_help(out, v = 0): print('-e, --exit Exit this program after test is done.', file=out) @@ -285,25 +308,30 @@ def get_userhome(): return userhome def main(): - shortopt = 'efh' - longopt = ['exit', 'force', 'help'] force_run = False - try: - opts, args = getopt.getopt(sys.argv[1:], shortopt, longopt) - except getopt.GetoptError as err: - print_help(sys.stderr, 1) - - for o, a in opts: - if o in ('-e', '--exit'): - global DONE_EXIT - DONE_EXIT = True - elif o in ('-f', '--force'): - force_run = True - elif o in ('-h', '--help'): - print_help(sys.stderr) - else: - print('Unknown argument: %s' % o, file=sys.stderr) - print_help(sys.stderr, 1) + parser = argparse.ArgumentParser() + parser.add_argument('-k', '--keep', action='store_true', + help='keep this GtkWindow after test is done') + parser.add_argument('-f', '--force', action='store_true', + help='run this program forcibly with .anthy') + parser.add_argument('-t', '--tap', action='store_true', + help='enable TAP') + parser.add_argument('-F', '--unittest-failfast', action='store_true', + help='stop on first fail or error in unittest') + parser.add_argument('-H', '--unittest-help', action='store_true', + help='show unittest help message and exit') + args, unittest_args = parser.parse_known_args() + sys.argv[1:] = unittest_args + if args.keep: + global DONE_EXIT + DONE_EXIT = False + if args.force: + force_run = True + if args.unittest_failfast: + sys.argv.append('-f') + if args.unittest_help: + sys.argv.append('-h') + unittest.main() for anthy_config in ['/.config/anthy', '/.anthy']: anthy_user_dir = get_userhome() + anthy_config @@ -312,11 +340,14 @@ def main(): print('Please remove %s before the test' % anthy_last_file, file=sys.stderr) sys.exit(-1) - EngineTest = AnthyTest() - if not EngineTest.register_ibus_engine(): - sys.exit(-1) - EngineTest.create_window() - EngineTest.run() + + if args.tap: + loader = unittest.TestLoader() + runner = TAPTestRunner() + runner.set_stream(True) + unittest.main(testRunner=runner, testLoader=loader) + else: + unittest.main() if __name__ == '__main__': main() 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 -- 2.21.0 From a2e418003b3733c5792fbab62a2e364a343a6e49 Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Wed, 4 Dec 2019 16:58:52 +0900 Subject: [PATCH] configure: Fix to install zipcode dict with anthy-unicode (#1779129) --- configure.ac | 2 +- setup/python2/main.py | 6 +++--- setup/python3/main.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 64afcc6..3fecd12 100644 --- a/configure.ac +++ b/configure.ac @@ -236,7 +236,7 @@ AC_ARG_WITH(anthy-zipcode, [AC_HELP_STRING([--with-anthy-zipcode=FILE], [file path of Anty zipcode.t])], [ANTHY_ZIPCODE_FILE="$withval"], - [ANTHY_ZIPCODE_FILE="$datadir/anthy/zipcode.t"]) + [ANTHY_ZIPCODE_FILE="$datadir/$ANTHY_PC/zipcode.t"]) test "x$prefix" = xNONE && prefix=$ac_default_prefix eval ANTHY_ZIPCODE_FILE=$ANTHY_ZIPCODE_FILE eval ANTHY_ZIPCODE_FILE=$ANTHY_ZIPCODE_FILE diff --git a/setup/python2/main.py b/setup/python2/main.py index 1fb5a67..4e6b15b 100644 --- a/setup/python2/main.py +++ b/setup/python2/main.py @@ -4,8 +4,8 @@ # # Copyright (c) 2007-2008 Peng Huang # Copyright (c) 2009 Hideaki ABE -# Copyright (c) 2010-2017 Takao Fujiwara -# Copyright (c) 2007-2017 Red Hat, Inc. +# Copyright (c) 2010-2019 Takao Fujiwara +# Copyright (c) 2007-2019 Red Hat, Inc. # # 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 @@ -1460,7 +1460,7 @@ class AnthySetup(object): Gtk.MessageType.ERROR) return if not path.exists(dict_file[0]): - self.__run_message_dialog(_("Your file does not exist: ") + dict_file, + self.__run_message_dialog(_("Your file does not exist: ") + dict_file[0], Gtk.MessageType.ERROR) return diff --git a/setup/python3/main.py b/setup/python3/main.py index 5fd3040..340e8ef 100644 --- a/setup/python3/main.py +++ b/setup/python3/main.py @@ -4,8 +4,8 @@ # # Copyright (c) 2007-2008 Peng Huang # Copyright (c) 2009 Hideaki ABE -# Copyright (c) 2010-2017 Takao Fujiwara -# Copyright (c) 2007-2017 Red Hat, Inc. +# Copyright (c) 2010-2019 Takao Fujiwara +# Copyright (c) 2007-2019 Red Hat, Inc. # # 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 @@ -1454,7 +1454,7 @@ class AnthySetup(object): Gtk.MessageType.ERROR) return if not path.exists(dict_file[0]): - self.__run_message_dialog(_("Your file does not exist: ") + dict_file, + self.__run_message_dialog(_("Your file does not exist: ") + dict_file[0], Gtk.MessageType.ERROR) return -- 2.21.0 From 390d6273096fe0e435a0d145e6a785f38372ba67 Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Thu, 2 Jul 2020 14:47:39 +0900 Subject: [PATCH] tests: Enable pycotap --- tests/anthytest.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/tests/anthytest.py b/tests/anthytest.py index 11d0e2b..03a7c31 100755 --- a/tests/anthytest.py +++ b/tests/anthytest.py @@ -20,10 +20,23 @@ import sys import subprocess import unittest +TAP_MODULE_NONE, \ +TAP_MODULE_TAPPY, \ +TAP_MODULE_PYCOTAP = list(range(3)) + +tap_module = TAP_MODULE_NONE + try: from tap import TAPTestRunner -except ModuleNotFoundError as err: - print('Ignore tap module: %s' % str(err)) + tap_module = TAP_MODULE_TAPPY + print('Load tappy') +except ModuleNotFoundError: + try: + from pycotap import TAPTestRunner + tap_module = TAP_MODULE_PYCOTAP + print('Load pycotap') + except ModuleNotFoundError as err: + print('Ignore tap module: %s' % str(err)) PY3K = sys.version_info >= (3, 0) DONE_EXIT = True @@ -344,7 +357,8 @@ def main(): if args.tap: loader = unittest.TestLoader() runner = TAPTestRunner() - runner.set_stream(True) + if tap_module == TAP_MODULE_TAPPY: + runner.set_stream(True) unittest.main(testRunner=runner, testLoader=loader) else: unittest.main() -- 2.24.1 From f4f35c32942a649d67fb52730d7a5d4f2ef5058a Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Thu, 9 Jul 2020 20:20:57 +0900 Subject: [PATCH] tests: Use unittest.fail and unittest.skipIf --- tests/anthytest.py | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/tests/anthytest.py b/tests/anthytest.py index 03a7c31..bff3078 100755 --- a/tests/anthytest.py +++ b/tests/anthytest.py @@ -5,10 +5,12 @@ from __future__ import print_function from gi import require_version as gi_require_version gi_require_version('GLib', '2.0') +gi_require_version('Gdk', '3.0') gi_require_version('Gio', '2.0') gi_require_version('Gtk', '3.0') gi_require_version('IBus', '1.0') from gi.repository import GLib +from gi.repository import Gdk from gi.repository import Gio from gi.repository import Gtk from gi.repository import IBus @@ -66,6 +68,7 @@ def printerr(sentence): except IOError: pass +@unittest.skipIf(Gdk.Display.open('') == None, 'Display cannot be open.') class AnthyTest(unittest.TestCase): global DONE_EXIT ENGINE_PATH = '/com/redhat/IBus/engines/Anthy/Test/Engine' @@ -84,7 +87,7 @@ class AnthyTest(unittest.TestCase): def register_ibus_engine(self): self.__bus = IBus.Bus() if not self.__bus.is_connected(): - error('ibus-daemon is not running') + self.fail('ibus-daemon is not running') return False; self.__bus.get_connection().signal_subscribe('org.freedesktop.DBus', 'org.freedesktop.DBus', @@ -130,12 +133,24 @@ class AnthyTest(unittest.TestCase): interface_name, signal_name, parameters, user_data): if signal_name == 'NameOwnerChanged': - import engine + try: + import engine + except ModuleNotFoundError as e: + with self.subTest(i = 'name-owner-changed'): + self.fail('NG: Not installed ibus-anthy %s' % str(e)) + Gtk.main_quit() + return engine.Engine.CONFIG_RELOADED() def __create_engine_cb(self, factory, engine_name): if engine_name == 'testanthy': - import engine + try: + import engine + except ModuleNotFoundError as e: + with self.subTest(i = 'create-engine'): + self.fail('NG: Not installed ibus-anthy %s' % str(e)) + Gtk.main_quit() + return self.__id += 1 self.__engine = engine.Engine(self.__bus, '%s/%d' % (self.ENGINE_PATH, self.__id)) self.__engine.connect('focus-in', self.__engine_focus_in) @@ -178,7 +193,8 @@ class AnthyTest(unittest.TestCase): def __set_engine_cb(self, object, res): if not self.__bus.set_global_engine_async_finish(res): - warning('set engine failed: ' + error.message) + with self.subTest(i = self.__test_index): + self.fail('set engine failed: ' + error.message) return self.__enable_hiragana() self.__main_test() @@ -238,18 +254,14 @@ class AnthyTest(unittest.TestCase): type = list(cases.keys())[0] i = 0 if type == 'string': - if start == -1 and end == -1: - printflush('test step: %s sequences: "%s"' \ - % (tag, str(cases['string']))) + printflush('test step: %s sequences: "%s"' \ + % (tag, str(cases['string']))) for a in cases['string']: if start >= 0 and i < start: i += 1 continue if end >= 0 and i >= end: break; - if start != -1 or end != -1: - printflush('test step: %s sequences: "%s"' \ - % (tag, str(cases['string']))) self.__typing(ord(a), 0, 0) i += 1 if type == 'keys': @@ -279,8 +291,11 @@ class AnthyTest(unittest.TestCase): if cases['string'] == chars: printflush('OK: %d %s' % (self.__test_index, chars)) else: - printflush('NG: %d %s %s' \ - % (self.__test_index, str(cases['string']), chars)) + with self.subTest(i = self.__test_index): + self.fail('NG: %d %s %s' \ + % (self.__test_index, str(cases['string']), chars)) + if DONE_EXIT: + Gtk.main_quit() self.__test_index += 1 if self.__test_index == len(TestCases['tests']): if DONE_EXIT: -- 2.24.1