]> git.draconx.ca Git - gob-dx.git/blob - tests/interface.at
Minor testsuite cleanup.
[gob-dx.git] / tests / interface.at
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.
5
6 dnl Create the Test:Fooable interface with the following interface method:
7 dnl
8 dnl   int foo(G:Object *obj);
9 dnl
10 dnl Link in test-fooable.o
11 m4_define([TEST_FOOABLE_IFACE],
12 [AT_KEYWORDS([interface])dnl
13 AT_CHECK([cp $srcdir/t/test-fooable.c $srcdir/t/test-fooable.h .])
14 TEST_COMPILE_GOBJECT([test-fooable.c], [0], [], [ignore])])
15
16 dnl TEST_FOOABLE_IMPL(Class:Name, Parent:Class, foo_body)
17 dnl TEST_FOOABLE_IMPL_DYN(Class:Name, Parent:Class, foo_body)
18 m4_define([TEST_FOOABLE_IMPL],
19   [TEST_FOOABLE_IMPL_([$1], TEST_CLASSNAME_REPLACE_SEP([$1], [-]),
20                       [$2], TEST_CLASSNAME_REPLACE_SEP([$2], [-]),
21                       [$3], [$4])])
22
23 m4_define([TEST_FOOABLE_IMPL_DYN],
24 [TEST_FOOABLE_IMPL([$1], [$2], [$3], [(dynamic)])
25 TEST_TYPE_MODULE([$1])])
26
27 m4_define([TEST_FOOABLE_IMPL_],
28 [AT_DATA([$2.gob], [[%{
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include "test-fooable.h"
32 %}
33 ]m4_if([$4], [g-object], [], [[
34 %h{
35 #include "$4.h"
36 %}
37 ]])[
38 class $1 from $3]m4_default_nblank([
39   $6])[
40   (interface Test:Fooable)
41 {
42   interface Test:Fooable private int foo(G:Object *go)
43     onerror 88
44   {
45     $5
46     abort();
47   }
48 }
49 ]])
50 AT_CHECK([gob2 $2.gob])
51 TEST_COMPILE_GOBJECT([$2.c], [0], [], [ignore])])
52
53 dnl Test that a static type can implement an interface.
54 AT_SETUP([interface implementation])
55 AT_KEYWORDS([runtime])dnl
56
57 TEST_FOOABLE_IFACE()
58 TEST_FOOABLE_IMPL([Test:A], [G:Object], [return 42;])
59
60 AT_DATA([main.c],
61 [[#include <stdio.h>
62 #include <stdlib.h>
63 #include "test-fooable.h"
64 #include "test-a.h"
65
66 int main(void)
67 {
68   int rc;
69
70   rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
71   printf("%d\n", rc);
72   if (rc < 0)
73     return EXIT_FAILURE;
74   return 0;
75 }
76 ]])
77 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
78
79 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
80   test-a.o test-fooable.o main.o])
81 AT_CHECK([./main], [0], [42
82 ])
83
84 AT_CLEANUP
85
86 dnl Test that a dynamic type can implement an interface.
87 AT_SETUP([interface implementation (dynamic)])
88 AT_KEYWORDS([runtime])dnl
89
90 TEST_FOOABLE_IFACE()
91 TEST_FOOABLE_IMPL_DYN([Test:A], [G:Object], [return 54;])
92
93 AT_DATA([main.c],
94 [[#include <stdio.h>
95 #include <stdlib.h>
96 #include "test-fooable.h"
97 #include "test-a.h"
98 #include "test-a-mod.h"
99
100 int main(void)
101 {
102   int rc;
103
104   g_type_module_use(g_object_new(TEST_TYPE_A_MOD, NULL));
105
106   rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
107   printf("%d\n", rc);
108   if (rc < 0)
109     return EXIT_FAILURE;
110   return 0;
111 }
112 ]])
113 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
114
115 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
116   test-a.o test-a-mod.o test-fooable.o main.o])
117 AT_CHECK([./main], [0], [54
118 ])
119
120 AT_CLEANUP
121
122 dnl Test that a static type can override the interface implementation
123 dnl in the parent type.
124 AT_SETUP([interface method override])
125 AT_KEYWORDS([runtime])dnl
126
127 TEST_FOOABLE_IFACE()
128 TEST_FOOABLE_IMPL([Test:A], [G:Object],
129   [puts("Test:A foo called"); return 42;])
130 TEST_FOOABLE_IMPL([Test:B], [Test:A],
131   [puts("Test:B foo called"); return 54;])
132
133 AT_DATA([main.c],
134 [[#include <stdio.h>
135 #include <stdlib.h>
136 #include "test-fooable.h"
137 #include "test-a.h"
138 #include "test-b.h"
139
140 int main(void)
141 {
142   int rc;
143
144   rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
145   printf("%d\n", rc);
146   if (rc < 0)
147     return EXIT_FAILURE;
148
149   rc = test_foo(g_object_new(TEST_TYPE_B, NULL));
150   printf("%d\n", rc);
151   if (rc < 0)
152     return EXIT_FAILURE;
153
154   return 0;
155 }
156 ]])
157 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
158
159 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
160   test-a.o test-b.o test-fooable.o main.o])
161 AT_CHECK([./main], [0], [Test:A foo called
162 42
163 Test:B foo called
164 54
165 ])
166
167 AT_CLEANUP
168
169 dnl Test that a dynamic type can override the interface implementation of
170 dnl a static parent type.
171 AT_SETUP([interface method override (dynamic)])
172 AT_KEYWORDS([runtime])dnl
173
174 TEST_FOOABLE_IFACE()
175 TEST_FOOABLE_IMPL([Test:A], [G:Object],
176   [puts("Test:A foo called"); return 42;])
177 TEST_FOOABLE_IMPL_DYN([Test:B], [Test:A],
178   [puts("Test:B foo called"); return 54;])
179
180 AT_DATA([main.c],
181 [[#include <stdio.h>
182 #include <stdlib.h>
183 #include "test-fooable.h"
184 #include "test-a.h"
185 #include "test-b.h"
186 #include "test-b-mod.h"
187
188 int main(void)
189 {
190   int rc;
191
192   g_type_module_use(g_object_new(TEST_TYPE_B_MOD, NULL));
193
194   rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
195   printf("%d\n", rc);
196   if (rc < 0)
197     return EXIT_FAILURE;
198
199   rc = test_foo(g_object_new(TEST_TYPE_B, NULL));
200   printf("%d\n", rc);
201   if (rc < 0)
202     return EXIT_FAILURE;
203
204   return 0;
205 }
206 ]])
207 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
208
209 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
210   test-a.o test-b.o test-b-mod.o test-fooable.o main.o])
211
212 AT_CHECK([./main], [0], [Test:A foo called
213 42
214 Test:B foo called
215 54
216 ])
217
218 AT_CLEANUP
219
220 dnl Test that a dynamic type can override the interface implementation of a
221 dnl dynamic parent type.
222 AT_SETUP([interface method override (dynamic) #2])
223 AT_KEYWORDS([runtime])dnl
224
225 TEST_FOOABLE_IFACE()
226 TEST_FOOABLE_IMPL_DYN([Test:A], [G:Object],
227   [puts("Test:A foo called"); return 42;])
228 TEST_FOOABLE_IMPL_DYN([Test:B], [Test:A],
229   [puts("Test:B foo called"); return 54;])
230
231 AT_DATA([main.c],
232 [[#include <stdio.h>
233 #include <stdlib.h>
234 #include "test-fooable.h"
235 #include "test-a.h"
236 #include "test-a-mod.h"
237 #include "test-b.h"
238 #include "test-b-mod.h"
239
240 int main(void)
241 {
242   int rc;
243
244   g_type_module_use(g_object_new(TEST_TYPE_A_MOD, NULL));
245   g_type_module_use(g_object_new(TEST_TYPE_B_MOD, NULL));
246
247   rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
248   printf("%d\n", rc);
249   if (rc < 0)
250     return EXIT_FAILURE;
251
252   rc = test_foo(g_object_new(TEST_TYPE_B, NULL));
253   printf("%d\n", rc);
254   if (rc < 0)
255     return EXIT_FAILURE;
256
257   return 0;
258 }
259 ]])
260 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
261
262 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
263   test-a.o test-a-mod.o test-b.o test-b-mod.o test-fooable.o main.o])
264
265 AT_CHECK([./main], [0], [Test:A foo called
266 42
267 Test:B foo called
268 54
269 ])
270
271 AT_CLEANUP
272
273 AT_SETUP([interface method chaining])
274 AT_KEYWORDS([runtime])dnl
275
276 TEST_FOOABLE_IFACE()
277 TEST_FOOABLE_IMPL([Test:A], [G:Object],
278   [puts("Test:A foo called"); return PARENT_HANDLER(go);])
279 TEST_FOOABLE_IMPL([Test:B], [Test:A],
280   [puts("Test:B foo called"); return PARENT_HANDLER(go);])
281 TEST_FOOABLE_IMPL([Test:C], [Test:B],
282   [puts("Test:C foo called"); return PARENT_HANDLER(go);])
283
284 AT_DATA([main.c],
285 [[#include <stdio.h>
286 #include <stdlib.h>
287 #include "test-fooable.h"
288 #include "test-a.h"
289 #include "test-b.h"
290 #include "test-c.h"
291
292 int main(void)
293 {
294   int rc;
295
296   rc = test_foo(g_object_new(TEST_TYPE_C, NULL));
297   printf("%d\n", rc);
298   if (rc < 0)
299     return EXIT_FAILURE;
300
301   return 0;
302 }
303 ]])
304
305 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
306
307 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
308   test-a.o test-b.o test-c.o test-fooable.o main.o])
309 AT_CHECK([./main], [0], [Test:C foo called
310 Test:B foo called
311 Test:A foo called
312 88
313 ])
314
315 AT_CLEANUP
316
317 AT_SETUP([interface method chaining (dynamic)])
318 AT_KEYWORDS([runtime])dnl
319
320 TEST_FOOABLE_IFACE()
321 TEST_FOOABLE_IMPL_DYN([Test:A], [G:Object],
322   [puts("Test:A foo called"); return PARENT_HANDLER(go);])
323 TEST_FOOABLE_IMPL_DYN([Test:B], [Test:A],
324   [puts("Test:B foo called"); return PARENT_HANDLER(go);])
325 TEST_FOOABLE_IMPL_DYN([Test:C], [Test:B],
326   [puts("Test:C foo called"); return PARENT_HANDLER(go);])
327
328 AT_DATA([main.c],
329 [[#include <stdio.h>
330 #include <stdlib.h>
331 #include "test-fooable.h"
332 #include "test-a.h"
333 #include "test-a-mod.h"
334 #include "test-b.h"
335 #include "test-b-mod.h"
336 #include "test-c.h"
337 #include "test-c-mod.h"
338
339 int main(void)
340 {
341   int rc;
342
343   g_type_module_use(g_object_new(TEST_TYPE_A_MOD, NULL));
344   g_type_module_use(g_object_new(TEST_TYPE_B_MOD, NULL));
345   g_type_module_use(g_object_new(TEST_TYPE_C_MOD, NULL));
346
347   rc = test_foo(g_object_new(TEST_TYPE_C, NULL));
348   printf("%d\n", rc);
349   if (rc < 0)
350     return EXIT_FAILURE;
351
352   return 0;
353 }
354 ]])
355
356 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
357
358 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
359   test-a.o test-a-mod.o test-b.o test-b-mod.o test-c.o test-c-mod.o \
360   test-fooable.o main.o])
361 AT_CHECK([./main], [0], [Test:C foo called
362 Test:B foo called
363 Test:A foo called
364 88
365 ])
366
367 AT_CLEANUP