[glib: 3/6] tests: Add basic test for glib-genmarshal
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 3/6] tests: Add basic test for glib-genmarshal
- Date: Mon, 10 Jun 2019 17:32:52 +0000 (UTC)
commit e34839f8f4bf33e54faa1b42d7bf0d9168bf7f7b
Author: Philip Withnall <withnall endlessm com>
Date: Fri Jun 7 18:52:00 2019 +0100
tests: Add basic test for glib-genmarshal
This is a basic test suite for the `glib-genmarshal` utility, lifted
mostly directly from the tests for `glib-mkenums`.
Signed-off-by: Philip Withnall <withnall endlessm com>
gobject/tests/genmarshal.py | 336 ++++++++++++++++++++++++++++++++++++++++++++
gobject/tests/meson.build | 1 +
2 files changed, 337 insertions(+)
---
diff --git a/gobject/tests/genmarshal.py b/gobject/tests/genmarshal.py
new file mode 100644
index 000000000..d00f180ff
--- /dev/null
+++ b/gobject/tests/genmarshal.py
@@ -0,0 +1,336 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+#
+# Copyright © 2019 Endless Mobile, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA
+
+"""Integration tests for glib-genmarshal utility."""
+
+import collections
+import os
+import shutil
+import subprocess
+import tempfile
+from textwrap import dedent
+import unittest
+
+import taptestrunner
+
+
+Result = collections.namedtuple('Result', ('info', 'out', 'err', 'subs'))
+
+
+class TestGenmarshal(unittest.TestCase):
+ """Integration test for running glib-genmarshal.
+
+ This can be run when installed or uninstalled. When uninstalled, it
+ requires G_TEST_BUILDDIR and G_TEST_SRCDIR to be set.
+
+ The idea with this test harness is to test the glib-genmarshal utility, its
+ handling of command line arguments, its exit statuses, and its handling of
+ various marshaller lists. In future we could split the core glib-genmarshal
+ parsing and generation code out into a library and unit test that, and
+ convert this test to just check command line behaviour.
+ """
+ def setUp(self):
+ self.timeout_seconds = 10 # seconds per test
+ self.tmpdir = tempfile.TemporaryDirectory()
+ os.chdir(self.tmpdir.name)
+ print('tmpdir:', self.tmpdir.name)
+ if 'G_TEST_BUILDDIR' in os.environ:
+ self.__genmarshal = \
+ os.path.join(os.environ['G_TEST_BUILDDIR'], '..',
+ 'glib-genmarshal')
+ else:
+ self.__genmarshal = shutil.which('glib-genmarshal')
+ print('genmarshal:', self.__genmarshal)
+
+ def tearDown(self):
+ self.tmpdir.cleanup()
+
+ def runGenmarshal(self, *args):
+ argv = [self.__genmarshal]
+ argv.extend(args)
+ print('Running:', argv)
+
+ env = os.environ.copy()
+ env['LC_ALL'] = 'C.UTF-8'
+ print('Environment:', env)
+
+ info = subprocess.run(argv, timeout=self.timeout_seconds,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ env=env)
+ info.check_returncode()
+ out = info.stdout.decode('utf-8').strip()
+ err = info.stderr.decode('utf-8').strip()
+
+ # Known substitutions for standard boilerplate
+ subs = {
+ 'standard_top_comment':
+ 'This file is generated by glib-genmarshal, do not modify '
+ 'it. This code is licensed under the same license as the '
+ 'containing project. Note that it links to GLib, so must '
+ 'comply with the LGPL linking clauses.',
+ 'standard_top_pragma': dedent(
+ '''
+ #ifndef __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__
+ #define __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__
+ ''').strip(),
+ 'standard_bottom_pragma': dedent(
+ '''
+ #endif /* __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__ */
+ ''').strip(),
+ 'standard_includes': dedent(
+ '''
+ #include <glib-object.h>
+ ''').strip(),
+ 'standard_marshal_peek_defines': dedent(
+ '''
+ #ifdef G_ENABLE_DEBUG
+ #define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
+ #define g_marshal_value_peek_char(v) g_value_get_schar (v)
+ #define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
+ #define g_marshal_value_peek_int(v) g_value_get_int (v)
+ #define g_marshal_value_peek_uint(v) g_value_get_uint (v)
+ #define g_marshal_value_peek_long(v) g_value_get_long (v)
+ #define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
+ #define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
+ #define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
+ #define g_marshal_value_peek_enum(v) g_value_get_enum (v)
+ #define g_marshal_value_peek_flags(v) g_value_get_flags (v)
+ #define g_marshal_value_peek_float(v) g_value_get_float (v)
+ #define g_marshal_value_peek_double(v) g_value_get_double (v)
+ #define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
+ #define g_marshal_value_peek_param(v) g_value_get_param (v)
+ #define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
+ #define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
+ #define g_marshal_value_peek_object(v) g_value_get_object (v)
+ #define g_marshal_value_peek_variant(v) g_value_get_variant (v)
+ #else /* !G_ENABLE_DEBUG */
+ /* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
+ * Do not access GValues directly in your code. Instead, use the
+ * g_value_get_*() functions
+ */
+ #define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
+ #define g_marshal_value_peek_char(v) (v)->data[0].v_int
+ #define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
+ #define g_marshal_value_peek_int(v) (v)->data[0].v_int
+ #define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
+ #define g_marshal_value_peek_long(v) (v)->data[0].v_long
+ #define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
+ #define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
+ #define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
+ #define g_marshal_value_peek_enum(v) (v)->data[0].v_long
+ #define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
+ #define g_marshal_value_peek_float(v) (v)->data[0].v_float
+ #define g_marshal_value_peek_double(v) (v)->data[0].v_double
+ #define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
+ #define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
+ #define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
+ #define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
+ #define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
+ #define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer
+ #endif /* !G_ENABLE_DEBUG */
+ ''').strip(),
+ }
+
+ result = Result(info, out, err, subs)
+
+ print('Output:', result.out)
+ return result
+
+ def runGenmarshalWithList(self, list_contents, *args):
+ with tempfile.NamedTemporaryFile(dir=self.tmpdir.name,
+ suffix='.list') as list_file:
+ # Write out the list.
+ list_file.write(list_contents.encode('utf-8'))
+ print(list_file.name + ':', list_contents)
+ list_file.flush()
+
+ header_result = self.runGenmarshal(list_file.name,
+ '--header', *args)
+ body_result = self.runGenmarshal(list_file.name,
+ '--body', *args)
+
+ header_result.subs['list_path'] = list_file.name
+ body_result.subs['list_path'] = list_file.name
+
+ return (header_result, body_result)
+
+ def test_help(self):
+ """Test the --help argument."""
+ result = self.runGenmarshal('--help')
+ self.assertIn('usage: glib-genmarshal', result.out)
+
+ def test_no_args(self):
+ """Test running with no arguments at all."""
+ result = self.runGenmarshal()
+ self.assertEqual('', result.err)
+ self.assertEqual('', result.out)
+
+ def test_empty_list(self):
+ """Test running with an empty list."""
+ (header_result, body_result) = \
+ self.runGenmarshalWithList('', '--quiet')
+
+ self.assertEqual('', header_result.err)
+ self.assertEqual('', body_result.err)
+
+ self.assertEqual(dedent(
+ '''
+ /* {standard_top_comment} */
+ {standard_top_pragma}
+
+ {standard_includes}
+
+ G_BEGIN_DECLS
+
+
+ G_END_DECLS
+
+ {standard_bottom_pragma}
+ ''').strip().format(**header_result.subs),
+ header_result.out.strip())
+
+ self.assertEqual(dedent(
+ '''
+ /* {standard_top_comment} */
+ {standard_includes}
+
+ {standard_marshal_peek_defines}
+ ''').strip().format(**body_result.subs),
+ body_result.out.strip())
+
+ def test_void_boolean(self):
+ """Test running with a basic VOID:BOOLEAN list."""
+ (header_result, body_result) = \
+ self.runGenmarshalWithList('VOID:BOOLEAN', '--quiet')
+
+ self.assertEqual('', header_result.err)
+ self.assertEqual('', body_result.err)
+
+ self.assertEqual(dedent(
+ '''
+ /* {standard_top_comment} */
+ {standard_top_pragma}
+
+ {standard_includes}
+
+ G_BEGIN_DECLS
+
+ /* VOID:BOOLEAN ({list_path}:1) */
+ #define g_cclosure_user_marshal_VOID__BOOLEAN g_cclosure_marshal_VOID__BOOLEAN
+
+
+ G_END_DECLS
+
+ {standard_bottom_pragma}
+ ''').strip().format(**header_result.subs),
+ header_result.out.strip())
+
+ self.assertEqual(dedent(
+ '''
+ /* {standard_top_comment} */
+ {standard_includes}
+
+ {standard_marshal_peek_defines}
+ ''').strip().format(**body_result.subs),
+ body_result.out.strip())
+
+ def test_void_boolean_int64(self):
+ """Test running with a non-trivial VOID:BOOLEAN,INT64 list."""
+ (header_result, body_result) = \
+ self.runGenmarshalWithList('VOID:BOOLEAN,INT64', '--quiet')
+
+ self.assertEqual('', header_result.err)
+ self.assertEqual('', body_result.err)
+
+ self.assertEqual(dedent(
+ '''
+ /* {standard_top_comment} */
+ {standard_top_pragma}
+
+ {standard_includes}
+
+ G_BEGIN_DECLS
+
+ /* VOID:BOOLEAN,INT64 ({list_path}:1) */
+ extern
+ void g_cclosure_user_marshal_VOID__BOOLEAN_INT64 (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+
+ G_END_DECLS
+
+ {standard_bottom_pragma}
+ ''').strip().format(**header_result.subs),
+ header_result.out.strip())
+
+ self.assertEqual(dedent(
+ '''
+ /* {standard_top_comment} */
+ {standard_includes}
+
+ {standard_marshal_peek_defines}
+
+ /* VOID:BOOLEAN,INT64 ({list_path}:1) */
+ void
+ g_cclosure_user_marshal_VOID__BOOLEAN_INT64 (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+ {{
+ typedef void (*GMarshalFunc_VOID__BOOLEAN_INT64) (gpointer data1,
+ gboolean arg1,
+ gint64 arg2,
+ gpointer data2);
+ GCClosure *cc = (GCClosure *) closure;
+ gpointer data1, data2;
+ GMarshalFunc_VOID__BOOLEAN_INT64 callback;
+
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {{
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }}
+ else
+ {{
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }}
+ callback = (GMarshalFunc_VOID__BOOLEAN_INT64) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_boolean (param_values + 1),
+ g_marshal_value_peek_int64 (param_values + 2),
+ data2);
+ }}
+ ''').strip().format(**body_result.subs),
+ body_result.out.strip())
+
+
+if __name__ == '__main__':
+ unittest.main(testRunner=taptestrunner.TAPTestRunner())
diff --git a/gobject/tests/meson.build b/gobject/tests/meson.build
index 0a2e7de03..9d5aac849 100644
--- a/gobject/tests/meson.build
+++ b/gobject/tests/meson.build
@@ -57,6 +57,7 @@ if cc.get_id() != 'msvc'
endif
python_tests = [
+ 'genmarshal.py',
'mkenums.py',
]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]