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