]> git.draconx.ca Git - gob-dx.git/blob - tests/interface.at
Expand the interface implementation 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 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]))])
12
13 m4_define([TEST_TYPE_MODULE_],
14 [AT_KEYWORDS([dynamic])dnl
15
16 AT_DATA([$3-mod.gob], [[%{
17 #include "$3.h"
18 %}
19 class $1:Mod from G:Type:Module
20 {
21   override (G:Type:Module) gboolean load(G:Type:Module *m)
22   {
23     $2_register_type(m);
24     return TRUE;
25   }
26 }
27 ]])
28 AT_CHECK([gob2 $3-mod.gob])
29 TEST_COMPILE_GOBJECT([$3-mod.c], [0], [], [ignore])])
30
31 dnl Create the Test:Fooable interface with the following interface method:
32 dnl
33 dnl   int foo(G:Object *obj);
34 dnl
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])])
40
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]),
46                       [$3], [$4])])
47
48 m4_define([TEST_FOOABLE_IMPL_DYN],
49 [TEST_FOOABLE_IMPL([$1], [$2], [$3], [(dynamic)])
50 TEST_TYPE_MODULE([$1])])
51
52 m4_define([TEST_FOOABLE_IMPL_],
53 [AT_DATA([$2.gob], [[%{
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include "test-fooable.h"
57 %}
58 ]m4_if([$4], [g-object], [], [[
59 %h{
60 #include "$4.h"
61 %}
62 ]])[
63 class $1 from $3]m4_default_nblank([
64   $6])[
65   (interface Test:Fooable)
66 {
67   interface Test:Fooable private int foo(G:Object *go)
68   {
69     $5
70     abort();
71   }
72 }
73 ]])
74 AT_CHECK([gob2 $2.gob])
75 TEST_COMPILE_GOBJECT([$2.c], [0], [], [ignore])])
76
77 dnl Test that a static type can implement an interface.
78 AT_SETUP([interface implementation])
79 AT_KEYWORDS([runtime])dnl
80
81 TEST_FOOABLE_IFACE()
82 TEST_FOOABLE_IMPL([Test:A], [G:Object], [return 42;])
83
84 AT_DATA([main.c],
85 [[#include <stdio.h>
86 #include <stdlib.h>
87 #include "test-fooable.h"
88 #include "test-a.h"
89
90 int main(void)
91 {
92   int rc;
93
94   rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
95   printf("%d\n", rc);
96   if (rc < 0)
97     return EXIT_FAILURE;
98   return 0;
99 }
100 ]])
101 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
102
103 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
104   test-a.o test-fooable.o main.o])
105 AT_CHECK([./main], [0], [42
106 ])
107
108 AT_CLEANUP
109
110 dnl Test that a dynamic type can implement an interface.
111 AT_SETUP([interface implementation (dynamic)])
112 AT_KEYWORDS([runtime])dnl
113
114 TEST_FOOABLE_IFACE()
115 TEST_FOOABLE_IMPL_DYN([Test:A], [G:Object], [return 54;])
116
117 AT_DATA([main.c],
118 [[#include <stdio.h>
119 #include <stdlib.h>
120 #include "test-fooable.h"
121 #include "test-a.h"
122 #include "test-a-mod.h"
123
124 int main(void)
125 {
126   int rc;
127
128   g_type_module_use(g_object_new(TEST_TYPE_A_MOD, NULL));
129
130   rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
131   printf("%d\n", rc);
132   if (rc < 0)
133     return EXIT_FAILURE;
134   return 0;
135 }
136 ]])
137 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
138
139 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
140   test-a.o test-a-mod.o test-fooable.o main.o])
141 AT_CHECK([./main], [0], [54
142 ])
143
144 AT_CLEANUP
145
146 dnl Test that a static type can override the interface implementation
147 dnl in the parent type.
148 AT_SETUP([interface method override])
149 AT_KEYWORDS([runtime])dnl
150
151 TEST_FOOABLE_IFACE()
152 TEST_FOOABLE_IMPL([Test:A], [G:Object],
153   [puts("Test:A foo called"); return 42;])
154 TEST_FOOABLE_IMPL([Test:B], [Test:A],
155   [puts("Test:B foo called"); return 54;])
156
157 AT_DATA([main.c],
158 [[#include <stdio.h>
159 #include <stdlib.h>
160 #include "test-fooable.h"
161 #include "test-a.h"
162 #include "test-b.h"
163
164 int main(void)
165 {
166   int rc;
167
168   rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
169   printf("%d\n", rc);
170   if (rc < 0)
171     return EXIT_FAILURE;
172
173   rc = test_foo(g_object_new(TEST_TYPE_B, NULL));
174   printf("%d\n", rc);
175   if (rc < 0)
176     return EXIT_FAILURE;
177
178   return 0;
179 }
180 ]])
181 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
182
183 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
184   test-a.o test-b.o test-fooable.o main.o])
185 AT_CHECK([./main], [0], [Test:A foo called
186 42
187 Test:B foo called
188 54
189 ])
190
191 AT_CLEANUP
192
193 dnl Test that a dynamic type can override the interface implementation of
194 dnl a static parent type.
195 AT_SETUP([interface method override (dynamic)])
196 AT_KEYWORDS([runtime])dnl
197
198 TEST_FOOABLE_IFACE()
199 TEST_FOOABLE_IMPL([Test:A], [G:Object],
200   [puts("Test:A foo called"); return 42;])
201 TEST_FOOABLE_IMPL_DYN([Test:B], [Test:A],
202   [puts("Test:B foo called"); return 54;])
203
204 AT_DATA([main.c],
205 [[#include <stdio.h>
206 #include "test-fooable.h"
207 #include "test-a.h"
208 #include "test-b.h"
209 #include "test-b-mod.h"
210
211 int main(void)
212 {
213   int rc;
214
215   g_type_module_use(g_object_new(TEST_TYPE_B_MOD, NULL));
216
217   rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
218   printf("%d\n", rc);
219   if (rc < 0)
220     return EXIT_FAILURE;
221
222   rc = test_foo(g_object_new(TEST_TYPE_B, NULL));
223   printf("%d\n", rc);
224   if (rc < 0)
225     return EXIT_FAILURE;
226
227   return 0;
228 }
229 ]])
230 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
231
232 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
233   test-a.o test-b.o test-b-mod.o test-fooable.o main.o])
234
235 # Currently borked
236 AT_XFAIL_IF([:])
237 AT_CHECK([./main], [0], [Test:A foo called
238 42
239 Test:B foo called
240 54
241 ])
242
243 AT_CLEANUP
244
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
249
250 TEST_FOOABLE_IFACE()
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;])
255
256 AT_DATA([main.c],
257 [[#include <stdio.h>
258 #include "test-fooable.h"
259 #include "test-a.h"
260 #include "test-a-mod.h"
261 #include "test-b.h"
262 #include "test-b-mod.h"
263
264 int main(void)
265 {
266   int rc;
267
268   g_type_module_use(g_object_new(TEST_TYPE_A_MOD, NULL));
269   g_type_module_use(g_object_new(TEST_TYPE_B_MOD, NULL));
270
271   rc = test_foo(g_object_new(TEST_TYPE_A, NULL));
272   printf("%d\n", rc);
273   if (rc < 0)
274     return EXIT_FAILURE;
275
276   rc = test_foo(g_object_new(TEST_TYPE_B, NULL));
277   printf("%d\n", rc);
278   if (rc < 0)
279     return EXIT_FAILURE;
280
281   return 0;
282 }
283 ]])
284 TEST_COMPILE_GOBJECT([main.c], [0], [], [ignore])
285
286 AT_CHECK([$CC $CFLAGS $LDFLAGS $LIBGOBJECT_LIBS -o main \
287   test-a.o test-a-mod.o test-b.o test-b-mod.o test-fooable.o main.o])
288
289 # Currently borked
290 AT_XFAIL_IF([:])
291 AT_CHECK([./main], [0], [Test:A foo called
292 42
293 Test:B foo called
294 54
295 ])
296
297 AT_CLEANUP