fix invoke tests
[gnome.gobject-introspection] / tests / invoke / invoke.c
1 #include <stdlib.h>
2 #include <string.h>
3
4 #include <glib.h>
5 #include <girepository.h>
6
7 typedef struct
8 {
9   int foo;
10 } TestStruct;
11
12
13 int
14 main (int argc, char *argv[])
15 {
16   const gchar *testfns = "./testfns.la";
17   GModule *handle;
18   GIRepository *rep;
19   GIBaseInfo *info;
20   GIFunctionInfo *function;
21   GIStructInfo *record;
22   GArgument in_args[3];
23   GArgument out_args[3];
24   GArgument retval;
25   gint res;
26   gchar *blurb;
27   guint len;
28   GError *error = NULL;
29   TestStruct *s;
30   
31   g_type_init ();
32
33   rep = g_irepository_get_default ();
34
35   g_assert (!g_irepository_is_registered (NULL, "testfns", NULL));
36   
37   handle = g_module_open (testfns, 0);
38   if (!handle)
39     {
40       g_error ("module open failed: %s\n", g_module_error ());
41       return 1;
42     }
43
44   g_assert (g_irepository_is_registered (NULL, "testfns", NULL));
45
46 #if 0
47   g_print ("after dlopening %s: %d infos in the repository\n", 
48            testfns,
49            g_irepository_get_n_infos (rep, "testfns"));
50 #endif
51
52   /* test1 calculates x + 4, 
53    * taking x as an in parameter
54    * and returning the result 
55    */
56   info = g_irepository_find_by_name (rep, "testfns", "test1");  
57   g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
58   function = (GIFunctionInfo *)info;
59
60   retval.v_int = 0;
61   in_args[0].v_int = 4;
62   if (!g_function_info_invoke (function, in_args, 1, NULL, 0, &retval, &error))
63     g_print ("Invokation of %s failed: %s\n",
64              g_base_info_get_name (info),
65              error->message);
66
67   g_assert (retval.v_int == 8);
68   g_base_info_unref (info);
69   
70   /* test2 calculates x + 4, 
71    * taking x as an in parameter
72    * and storing the result in an out parameter
73    */
74   info = g_irepository_find_by_name (rep, "testfns", "test2");  
75   g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
76   function = (GIFunctionInfo *)info;
77
78   in_args[0].v_int = 5;
79   res = 0;
80   out_args[0].v_pointer = &res;
81   if (!g_function_info_invoke (function, in_args, 1, out_args, 1, &retval, &error))
82     g_print ("Invokation of %s failed: %s\n",
83              g_base_info_get_name (info),
84              error->message);
85
86   g_assert (res == 9);
87   g_base_info_unref (info);
88   
89   /* test3 calculates x + 4, 
90    * taking x as an inout parameter
91    * and storing the result in the same parameter
92    */
93   info = g_irepository_find_by_name (rep, "testfns", "test3");  
94   g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
95   function = (GIFunctionInfo *)info;
96
97   res = 6;
98   in_args[0].v_pointer = out_args[0].v_pointer = &res;
99   if (!g_function_info_invoke (function, in_args, 1, out_args, 1, &retval, &error))
100     g_print ("Invokation of %s failed: %s\n",
101              g_base_info_get_name (info),
102              error->message);
103
104   g_assert (res == 10);
105   g_base_info_unref (info);
106
107   /* test4 prints out a string
108    */
109   info = g_irepository_find_by_name (rep, "testfns", "test4");  
110   g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
111   function = (GIFunctionInfo *)info;
112
113   in_args[0].v_pointer = "hello world\n";
114   if (!g_function_info_invoke (function, in_args, 1, NULL, 0, &retval, &error))
115     g_print ("Invokation of %s failed: %s\n",
116              g_base_info_get_name (info),
117              error->message);
118
119   g_base_info_unref (info);
120
121   /* test5 returns a string and a length
122    */
123   info = g_irepository_find_by_name (rep, "testfns", "test5");  
124   g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
125   function = (GIFunctionInfo *)info;
126
127   blurb = NULL;
128   len = 0;
129   out_args[0].v_pointer = &blurb;
130   out_args[1].v_pointer = &len;
131   if (!g_function_info_invoke (function, NULL, 0, out_args, 2, &retval, &error))
132     g_print ("Invokation of %s failed: %s\n",
133              g_base_info_get_name (info),
134              error->message);
135   
136   g_assert (strcmp (blurb, "hey there") == 0);
137   g_assert (len == strlen (blurb));
138   g_base_info_unref (info);
139   
140
141   /* test GList*/
142   g_print ("Test 6\n");
143   info = g_irepository_find_by_name (rep, "testfns", "test6");
144   g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
145   function = (GIFunctionInfo *)info;
146
147   {
148     GList *list = NULL;
149     list = g_list_prepend (list, GINT_TO_POINTER(1));
150     list = g_list_prepend (list, GINT_TO_POINTER(2));
151     retval.v_int = 0;
152     in_args[0].v_pointer = out_args[0].v_pointer = list;
153     if (!g_function_info_invoke (function, in_args, 1, NULL, 0, &retval, &error))
154       g_print ("Invokation of %s failed: %s\n",
155                g_base_info_get_name (info),
156                error->message);
157
158     g_print("returned %d\n", retval.v_int);
159     g_assert (retval.v_int == 2);
160     g_list_free (list);
161   }
162
163   g_base_info_unref (info);
164   g_clear_error (&error);
165
166   /* test GList more, transfer ownership*/
167   g_print ("Test 7\n");
168   info = g_irepository_find_by_name (rep, "testfns", "test7");
169   g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
170   function = (GIFunctionInfo *)info;
171
172   {
173     GList *list = NULL;
174     list = g_list_prepend (list, g_strdup("there..."));
175     list = g_list_prepend (list, g_strdup("Hey "));
176     retval.v_pointer = NULL;
177     in_args[0].v_pointer = out_args[0].v_pointer = list;
178     if (!g_function_info_invoke (function, in_args, 1, NULL, 0, &retval, &error))
179       g_print ("Invokation of %s failed: %s\n",
180                g_base_info_get_name (info),
181                error->message);
182
183     g_print("returned %p\n", retval.v_pointer);
184     g_assert (strcmp(retval.v_pointer, "Hey there...")==0);
185     g_list_foreach (list, (GFunc) g_free, NULL);
186     g_list_free (list);
187 #if 0
188     g_assert (g_callable_info_get_caller_owns ((GICallableInfo *)function) ==
189               GI_TRANSFER_EVERYTHING);
190 #endif    
191     g_free (retval.v_pointer);
192   }
193
194   g_base_info_unref (info);
195   g_clear_error (&error);
196
197   g_print("Test 8\n");
198   info = g_irepository_find_by_name (rep, "testfns", "TestStruct");
199   g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_STRUCT);
200   record = (GIStructInfo *)info;
201   info = (GIBaseInfo*)g_struct_info_find_method (record, "test8");
202   g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
203   function = (GIFunctionInfo *)info;
204   g_assert (g_function_info_get_flags (function) & GI_FUNCTION_IS_CONSTRUCTOR);
205
206   {
207     in_args[0].v_int = 42;
208     retval.v_pointer = NULL;
209
210     if (!g_function_info_invoke (function, in_args, 1, NULL, 0, &retval, &error))
211       g_print ("Invocation of %s failed: %s\n",
212                g_base_info_get_name (info),
213                error->message);
214
215     s = (TestStruct *)retval.v_pointer;
216
217     g_assert(s->foo == 42);
218
219   }
220
221   g_base_info_unref (info);
222   g_clear_error (&error);
223
224   g_print("Test 9\n");
225   info = (GIBaseInfo*)g_struct_info_find_method (record, "test9");
226   g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
227   function = (GIFunctionInfo *)info;
228   g_assert (g_function_info_get_flags (function) & GI_FUNCTION_IS_METHOD);
229
230   {
231     TestStruct s = { 42 };
232     int out_i;
233
234     retval.v_pointer = NULL;
235     in_args[0].v_pointer = &s;
236     out_args[0].v_pointer = &out_i;
237     if (!g_function_info_invoke (function, in_args, 1, out_args, 1, &retval, &error))
238       g_print ("Invocation of %s failed: %s\n",
239                g_base_info_get_name (info),
240                error->message);
241
242     g_assert(out_i == 42);
243   }
244
245   g_base_info_unref (info);
246   g_base_info_unref ((GIBaseInfo*)record);
247   g_clear_error (&error);
248
249
250   /* test error handling */
251
252 #if 0
253   /* "broken" is in the typelib but not in the .so*/
254   info = g_irepository_find_by_name (rep, "testfns", "broken");  
255   g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
256   function = (GIFunctionInfo *)info;
257
258   if (!g_function_info_invoke (function, NULL, 0, NULL, 0, NULL, &error))
259     g_print ("Invokation of %s failed: %s\n",
260              g_base_info_get_name (info),
261              error->message);
262
263   g_base_info_unref (info);
264   g_clear_error (&error);
265 #endif
266
267   /* too few in arguments */
268   info = g_irepository_find_by_name (rep, "testfns", "test2");  
269   g_assert (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION);
270   function = (GIFunctionInfo *)info;
271
272   g_assert (!g_function_info_invoke (function, NULL, 0, NULL, 0, NULL, &error) &&
273             error != NULL &&
274             error->domain == G_INVOKE_ERROR &&
275             error->code == G_INVOKE_ERROR_ARGUMENT_MISMATCH);
276
277   g_clear_error (&error);
278
279   /* too few out arguments */
280   g_assert (!g_function_info_invoke (function, in_args, 1, NULL, 0, NULL, &error) &&
281             error != NULL &&
282             error->domain == G_INVOKE_ERROR &&
283             error->code == G_INVOKE_ERROR_ARGUMENT_MISMATCH);
284
285   g_clear_error (&error);
286
287   /* too many in arguments */
288   g_assert (!g_function_info_invoke (function, in_args, 2, out_args, 1, NULL, &error) &&
289             error != NULL &&
290             error->domain == G_INVOKE_ERROR &&
291             error->code == G_INVOKE_ERROR_ARGUMENT_MISMATCH);
292
293   g_clear_error (&error);
294
295   /* too many out arguments */
296   g_assert (!g_function_info_invoke (function, in_args, 1, out_args, 2, NULL, &error) &&
297             error != NULL &&
298             error->domain == G_INVOKE_ERROR &&
299             error->code == G_INVOKE_ERROR_ARGUMENT_MISMATCH);
300
301   g_clear_error (&error);
302
303   return 0;
304 }