1 dnl Copyright © 2020 Nick Bowler
2 dnl License GPLv2+: GNU General Public License version 2 or any later version.
3 dnl This is free software: you are free to change and redistribute it.
4 dnl There is NO WARRANTY, to the extent permitted by law.
6 dnl TEST_TYPE_MODULE(Class:Name)
7 dnl Create a GTypeModule (Class:Name:Mod) which registers the dynamic
8 dnl type indiciated by Class:Name.
9 m4_define([TEST_TYPE_MODULE],
10 [TEST_TYPE_MODULE_([$1], m4_translit([[$1]], [:A-Z], [_a-z]),
11 m4_translit([[$1]], [:A-Z], [-a-z]))])
13 m4_define([TEST_TYPE_MODULE_],
14 [AT_KEYWORDS([dynamic])dnl
16 AT_DATA([$3-mod.gob], [[%{
19 class $1:Mod from G:Type:Module
21 override (G:Type:Module) gboolean load(G:Type:Module *m)
28 AT_CHECK([gob2 $3-mod.gob])
29 TEST_COMPILE_GOBJECT([$3-mod.c], [0], [], [ignore])])
31 dnl Create the Test:Fooable interface with the following interface method:
33 dnl int foo(G:Object *obj);
35 dnl Link in test-fooable.o
36 m4_define([TEST_FOOABLE_IFACE],
37 [AT_KEYWORDS([interface])dnl
38 AT_CHECK([cp $srcdir/t/test-fooable.c $srcdir/t/test-fooable.h .])
39 TEST_COMPILE_GOBJECT([test-fooable.c], [0], [], [ignore])])
41 dnl TEST_FOOABLE_IMPL(Class:Name, Parent:Class, foo_body)
42 dnl TEST_FOOABLE_IMPL_DYN(Class:Name, Parent:Class, foo_body)
43 m4_define([TEST_FOOABLE_IMPL],
44 [TEST_FOOABLE_IMPL_([$1], m4_translit([[$1]], [:A-Z], [-a-z]),
45 [$2], m4_translit([[$2]], [:A-Z], [-a-z]),
48 m4_define([TEST_FOOABLE_IMPL_DYN],
49 [TEST_FOOABLE_IMPL([$1], [$2], [$3], [(dynamic)])
50 TEST_TYPE_MODULE([$1])])
52 m4_define([TEST_FOOABLE_IMPL_],
53 [AT_DATA([$2.gob], [[%{
56 #include "test-fooable.h"
58 ]m4_if([$4], [g-object], [], [[
63 class $1 from $3]m4_default_nblank([
65 (interface Test:Fooable)
67 interface Test:Fooable private int foo(G:Object *go)
75 AT_CHECK([gob2 $2.gob])
76 TEST_COMPILE_GOBJECT([$2.c], [0], [], [ignore])])
78 dnl Test that a static type can implement an interface.
79 AT_SETUP([interface implementation])
80 AT_KEYWORDS([runtime])dnl
83 TEST_FOOABLE_IMPL([Test:A], [G:Object], [return 42;])
88 #include "test-fooable.h"
95 rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
102 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
104 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
105 test-a.o test-fooable.o main.o])
106 AT_CHECK([./main], [0], [42
111 dnl Test that a dynamic type can implement an interface.
112 AT_SETUP([interface implementation (dynamic)])
113 AT_KEYWORDS([runtime])dnl
116 TEST_FOOABLE_IMPL_DYN([Test:A], [G:Object], [return 54;])
121 #include "test-fooable.h"
123 #include "test-a-mod.h"
129 g_type_module_use(g_object_new(TEST_TYPE_A_MOD, NULL));
131 rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
138 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
140 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
141 test-a.o test-a-mod.o test-fooable.o main.o])
142 AT_CHECK([./main], [0], [54
147 dnl Test that a static type can override the interface implementation
148 dnl in the parent type.
149 AT_SETUP([interface method override])
150 AT_KEYWORDS([runtime])dnl
153 TEST_FOOABLE_IMPL([Test:A], [G:Object],
154 [puts("Test:A foo called"); return 42;])
155 TEST_FOOABLE_IMPL([Test:B], [Test:A],
156 [puts("Test:B foo called"); return 54;])
161 #include "test-fooable.h"
169 rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
174 rc = test_foo(g_object_new(TEST_TYPE_B, NULL));
182 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
184 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
185 test-a.o test-b.o test-fooable.o main.o])
186 AT_CHECK([./main], [0], [Test:A foo called
194 dnl Test that a dynamic type can override the interface implementation of
195 dnl a static parent type.
196 AT_SETUP([interface method override (dynamic)])
197 AT_KEYWORDS([runtime])dnl
200 TEST_FOOABLE_IMPL([Test:A], [G:Object],
201 [puts("Test:A foo called"); return 42;])
202 TEST_FOOABLE_IMPL_DYN([Test:B], [Test:A],
203 [puts("Test:B foo called"); return 54;])
208 #include "test-fooable.h"
211 #include "test-b-mod.h"
217 g_type_module_use(g_object_new(TEST_TYPE_B_MOD, NULL));
219 rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
224 rc = test_foo(g_object_new(TEST_TYPE_B, NULL));
232 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
234 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
235 test-a.o test-b.o test-b-mod.o test-fooable.o main.o])
237 AT_CHECK([./main], [0], [Test:A foo called
245 dnl Test that a dynamic type can override the interface implementation of a
246 dnl dynamic parent type.
247 AT_SETUP([interface method override (dynamic) #2])
248 AT_KEYWORDS([runtime])dnl
251 TEST_FOOABLE_IMPL_DYN([Test:A], [G:Object],
252 [puts("Test:A foo called"); return 42;])
253 TEST_FOOABLE_IMPL_DYN([Test:B], [Test:A],
254 [puts("Test:B foo called"); return 54;])
259 #include "test-fooable.h"
261 #include "test-a-mod.h"
263 #include "test-b-mod.h"
269 g_type_module_use(g_object_new(TEST_TYPE_A_MOD, NULL));
270 g_type_module_use(g_object_new(TEST_TYPE_B_MOD, NULL));
272 rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
277 rc = test_foo(g_object_new(TEST_TYPE_B, NULL));
285 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
287 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
288 test-a.o test-a-mod.o test-b.o test-b-mod.o test-fooable.o main.o])
290 AT_CHECK([./main], [0], [Test:A foo called
298 AT_SETUP([interface method chaining])
299 AT_KEYWORDS([runtime])dnl
302 TEST_FOOABLE_IMPL([Test:A], [G:Object],
303 [puts("Test:A foo called"); return PARENT_HANDLER(go);])
304 TEST_FOOABLE_IMPL([Test:B], [Test:A],
305 [puts("Test:B foo called"); return PARENT_HANDLER(go);])
306 TEST_FOOABLE_IMPL([Test:C], [Test:B],
307 [puts("Test:C foo called"); return PARENT_HANDLER(go);])
312 #include "test-fooable.h"
321 rc = test_foo(g_object_new(TEST_TYPE_C, NULL));
330 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
332 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
333 test-a.o test-b.o test-c.o test-fooable.o main.o])
334 AT_CHECK([./main], [0], [Test:C foo called
342 AT_SETUP([interface method chaining (dynamic)])
343 AT_KEYWORDS([runtime])dnl
346 TEST_FOOABLE_IMPL_DYN([Test:A], [G:Object],
347 [puts("Test:A foo called"); return PARENT_HANDLER(go);])
348 TEST_FOOABLE_IMPL_DYN([Test:B], [Test:A],
349 [puts("Test:B foo called"); return PARENT_HANDLER(go);])
350 TEST_FOOABLE_IMPL_DYN([Test:C], [Test:B],
351 [puts("Test:C foo called"); return PARENT_HANDLER(go);])
356 #include "test-fooable.h"
358 #include "test-a-mod.h"
360 #include "test-b-mod.h"
362 #include "test-c-mod.h"
368 g_type_module_use(g_object_new(TEST_TYPE_A_MOD, NULL));
369 g_type_module_use(g_object_new(TEST_TYPE_B_MOD, NULL));
370 g_type_module_use(g_object_new(TEST_TYPE_C_MOD, NULL));
372 rc = test_foo(g_object_new(TEST_TYPE_C, NULL));
381 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
383 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
384 test-a.o test-a-mod.o test-b.o test-b-mod.o test-c.o test-c-mod.o \
385 test-fooable.o main.o])
386 AT_CHECK([./main], [0], [Test:C foo called