X-Git-Url: https://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/185449d25b2f9c93d2928e4745e8aa64d7d9ab9c..00ae41703c606f0ea98febed8f67435f875f7e6f:/tests/general.at diff --git a/tests/general.at b/tests/general.at index 355f09e..4001942 100644 --- a/tests/general.at +++ b/tests/general.at @@ -1,4 +1,4 @@ -dnl Copyright © 2019 Nick Bowler +dnl Copyright © 2019-2020 Nick Bowler dnl License GPLv2+: GNU General Public License version 2 or any later version. dnl This is free software: you are free to change and redistribute it. dnl There is NO WARRANTY, to the extent permitted by law. @@ -66,3 +66,246 @@ AT_CHECK([awk -NF : '$1 == "main.c" && $2 == "15" { exit 42 }' stderr], [42]) AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main str.o main.o]) AT_CLEANUP + +dnl Check that dynamic types are accepted and compile OK... +AT_SETUP([dynamic types]) +AT_KEYWORDS([dynamic]) + +AT_DATA([test.gob], +[[class :Test from G:Object (dynamic) +{ + public void test(void) + { + } +} +]]) +AT_CHECK([gob2 test.gob]) + +AT_DATA([main.c], +[[#include "test.h" +int main(void) +{ + test_register_type(NULL); +} +]]) + +TEST_COMPILE_GOBJECT([test.c], [0], [], [ignore]) +TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore]) +AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main test.o main.o]) + +AT_CLEANUP + +dnl Dynamic types: simple test case which checks that we can instantiate a +dnl dynamic type after registration. +AT_SETUP([dynamic type registration]) +AT_KEYWORDS([dynamic runtime]) + +AT_DATA([test.gob], +[[%{ +#include +%} +class :Test from G:Object (dynamic) +{ + public gchar *s = { g_strdup("(nil)") }; + property STRING s (link); + + public void test(self) + { + printf("%s\n", self->s); + } +} +]]) + +AT_DATA([mod.gob], +[[%{ +#include "test.h" +%} +class :Mod from G:Type:Module +{ + override (G:Type:Module) gboolean load(G:Type:Module *m) + { + test_register_type(m); + return TRUE; + } +} +]]) + +AT_DATA([main.c], +[[#include +#include "mod.h" +#include "test.h" + +void devnull(const char *a, GLogLevelFlags b, const char *c, gpointer d) { } + +int main(void) +{ + GTypeModule *m = g_object_new(mod_get_type(), NULL); + guint handler; + Test *t; + + /* should fail, suppress internal glib logging... */ + handler = g_log_set_handler("GLib-GObject", G_LOG_LEVEL_MASK, devnull, 0); + t = g_object_new(test_get_type(), NULL); + if (t != NULL) + return EXIT_FAILURE; + g_log_remove_handler("GLib-GObject", handler); + + g_type_module_use(m); + /* should work now */ + t = g_object_new(test_get_type(), "s", "Hello, World", (char *)NULL); + if (!t) + return EXIT_FAILURE; + + test_test(t); + return EXIT_SUCCESS; +} +]]) + +AT_CHECK([gob2 mod.gob]) +AT_CHECK([gob2 test.gob]) +TEST_COMPILE_GOBJECT([mod.c], [0], [], [ignore]) +TEST_COMPILE_GOBJECT([test.c], [0], [], [ignore]) +TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore]) +AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main mod.o test.o main.o]) +AT_CHECK([./main], [0], [Hello, World +]) + +AT_CLEANUP + +dnl Dynamic types: check that we can call interface methods of dynamic types. +AT_SETUP([dynamic interface implementation]) +AT_KEYWORDS([dynamic runtime interface]) + +AT_DATA([iface.h], +[[#define IF_TYPE_TEST if_test_get_type() + +typedef struct IFTestIface { + GTypeInterface parent; + + void (*test)(GObject *obj); +} IFTestIface; + +GType if_test_get_type(void); +]]) + +AT_DATA([test.gob], +[[%{ +#include +#include "iface.h" +%} + +class :Test from G:Object (dynamic) + (interface IF:Test) +{ + private const char *s = { "Hello, World!" }; + interface IF:Test private void test(G:Object *o) + { + Self *self = SELF(o); + printf("%s\n", self->_priv->s); + } +} +]]) + +AT_DATA([mod.gob], +[[%{ +#include "test.h" +%} +class :Mod from G:Type:Module +{ + override (G:Type:Module) gboolean load(G:Type:Module *m) + { + test_register_type(m); + return TRUE; + } +} +]]) + +AT_DATA([main.c], +[[#include "test.h" +#include "mod.h" +#include "iface.h" + +GType if_test_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (IFTestIface), + NULL, + NULL, + }; + + type = g_type_register_static(G_TYPE_INTERFACE, "IFTest", &info, 0); + } + return type; +} + +int main(void) +{ + GTypeModule *m = g_object_new(TYPE_MOD, NULL); + GObject *t; + + g_type_module_use(m); + t = g_object_new(TYPE_TEST, NULL); + + g_return_val_if_fail(G_TYPE_CHECK_INSTANCE_TYPE(t, IF_TYPE_TEST), + EXIT_FAILURE); + G_TYPE_INSTANCE_GET_INTERFACE(t, IF_TYPE_TEST, IFTestIface)->test(t); + + return EXIT_SUCCESS; +} +]]) + +AT_CHECK([gob2 mod.gob]) +AT_CHECK([gob2 test.gob]) +TEST_COMPILE_GOBJECT([mod.c], [0], [], [ignore]) +TEST_COMPILE_GOBJECT([test.c], [0], [], [ignore]) +TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore]) +AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main mod.o test.o main.o]) +AT_CHECK([./main], [0], [Hello, World! +]) + +AT_CLEANUP + +AT_SETUP([GOB2_CHECK min-version test]) + +AT_DATA([configure.ac], +[[AC_PREREQ([2.62]) +AC_INIT([test], [0]) +AC_OUTPUT +]]) +AT_CHECK([$AUTOCONF && test -f configure || exit 77], [0], [ignore], [ignore]) + +m4_define([MYVER], + m4_bpatsubst(m4_dquote(m4_defn([AT_PACKAGE_VERSION])), [[^][0-9.]])) + +m4_define([MYVER_P1], m4_dquote(m4_reverse(m4_unquote( + m4_split(m4_defn([MYVER]), [[.]]))))) +m4_define([MYVER_P1], m4_join([.], m4_reverse( + m4_eval(m4_car(MYVER_P1)+1), m4_shift(MYVER_P1)))) + +AT_DATA([test.in], [[@GOB2@ +]]) + +cat >configure.ac <expout +AT_CHECK([cat test], [0], [expout], [ignore]) + +sed '/GOB2_CHECK/c\ +[GOB2_CHECK(]m4_dquote(m4_defn([MYVER_P1]))[)]' configure.ac >configure.new +mv -f configure.new configure.ac +AT_CHECK([$AUTOCONF --force]) +AT_CHECK([./configure], [1], [ignore], [ignore]) + +AT_CLEANUP