1 #include "config.h"
2
3 #include <stdlib.h>
4 #include <string.h>
5 #include <glib.h>
6 #include <gmodule.h>
7
8 #include "backends/x11/nested/meta-backend-x11-nested.h"
9 #include "meta-test/meta-context-test.h"
10 #include "tests/clutter-test-utils.h"
11
12 #include "test-unit-names.h"
13
14 #define MAX_DESC_SIZE 72
15
16 static GModule *module = NULL;
17
18 static gpointer
get_symbol_with_suffix(const char * unit_name,const char * suffix)19 get_symbol_with_suffix (const char *unit_name,
20 const char *suffix)
21 {
22 char *main_symbol_name;
23 gpointer func;
24
25 main_symbol_name = g_strconcat (unit_name, "_", suffix, NULL);
26 main_symbol_name = g_strdelimit (main_symbol_name, "-", '_');
27
28 g_module_symbol (module, main_symbol_name, &func);
29
30 g_free (main_symbol_name);
31
32 return func;
33 }
34
35 static gpointer
get_unit_name_main(const char * unit_name)36 get_unit_name_main (const char *unit_name)
37 {
38 return get_symbol_with_suffix (unit_name, "main");
39 }
40 static char *
get_unit_name_description(const char * unit_name,gssize max_len)41 get_unit_name_description (const char *unit_name,
42 gssize max_len)
43 {
44 const char *description;
45 gpointer func;
46 char *retval;
47
48 func = get_symbol_with_suffix (unit_name, "describe");
49 if (func == NULL)
50 description = "No description found";
51 else
52 {
53 const char *(* unit_test_describe) (void);
54
55 unit_test_describe = func;
56
57 description = unit_test_describe ();
58 }
59
60 if (max_len > 0 && strlen (description) >= max_len)
61 {
62 GString *buf = g_string_sized_new (max_len);
63 char *newline;
64
65 newline = strchr (description, '\n');
66 if (newline != NULL)
67 {
68 g_string_append_len (buf, description,
69 MIN (newline - description - 1, max_len - 3));
70 }
71 else
72 g_string_append_len (buf, description, max_len - 3);
73
74 g_string_append (buf, "...");
75
76 retval = g_string_free (buf, FALSE);
77 }
78 else
79 retval = g_strdup (description);
80
81 return retval;
82 }
83
84 static gboolean list_all = FALSE;
85 static gboolean describe = FALSE;
86 static char **unit_names = NULL;
87
88 static GOptionEntry entries[] = {
89 {
90 "describe", 'd',
91 0,
92 G_OPTION_ARG_NONE, &describe,
93 "Describe the interactive unit test", NULL,
94 },
95 {
96 "list-all", 'l',
97 0,
98 G_OPTION_ARG_NONE, &list_all,
99 "List all available units", NULL,
100 },
101 {
102 G_OPTION_REMAINING, 0,
103 0,
104 G_OPTION_ARG_STRING_ARRAY, &unit_names,
105 "The interactive unit test", "UNIT_NAME"
106 },
107 { NULL }
108 };
109
110 int
main(int argc,char ** argv)111 main (int argc, char **argv)
112 {
113 int ret, i, n_unit_names;
114 GOptionContext *context;
115
116 context = g_option_context_new (" - Interactive test suite");
117 g_option_context_add_main_entries (context, entries, NULL);
118 g_option_context_set_help_enabled (context, TRUE);
119 g_option_context_set_ignore_unknown_options (context, TRUE);
120 if (!g_option_context_parse (context, &argc, &argv, NULL))
121 {
122 g_print ("Usage: test-interactive <unit_test>\n");
123 return EXIT_FAILURE;
124 }
125
126 g_option_context_free (context);
127
128 module = g_module_open (NULL, 0);
129 if (!module)
130 g_error ("*** Failed to open self for symbol lookup");
131
132 ret = EXIT_SUCCESS;
133
134 if (list_all)
135 {
136 g_print ("* Available unit tests:\n");
137
138 for (i = 0; i < G_N_ELEMENTS (test_unit_names); i++)
139 {
140 char *str;
141 gsize len;
142
143 len = MAX_DESC_SIZE - strlen (test_unit_names[i]);
144 str = get_unit_name_description (test_unit_names[i], len - 2);
145
146 g_print (" - %s:%*s%s\n",
147 test_unit_names[i],
148 (int) (len - strlen (str)), " ",
149 str);
150
151 g_free (str);
152 }
153
154 ret = EXIT_SUCCESS;
155 goto out;
156 }
157
158 if (unit_names != NULL)
159 n_unit_names = g_strv_length (unit_names);
160 else
161 {
162 g_print ("Usage: test-interactive <unit_test>\n");
163 ret = EXIT_FAILURE;
164 goto out;
165 }
166
167 for (i = 0; i < n_unit_names; i++)
168 {
169 const char *unit_name = unit_names[i];
170 char *unit_test = NULL;
171 gboolean found;
172 int j;
173
174 unit_test = g_path_get_basename (unit_name);
175
176 found = FALSE;
177 for (j = 0; j < G_N_ELEMENTS (test_unit_names); j++)
178 {
179 if (strcmp (test_unit_names[j], unit_test) == 0)
180 {
181 found = TRUE;
182 break;
183 }
184 }
185
186 if (!found)
187 g_error ("*** Unit '%s' does not exist", unit_test);
188
189 if (describe)
190 {
191 char *str;
192
193 str = get_unit_name_description (unit_test, -1);
194
195 g_print ("* %s:\n%s\n\n", unit_test, str);
196
197 g_free (str);
198
199 ret = EXIT_SUCCESS;
200 }
201 else
202 {
203 int (* unit_test_main) (int argc, char **argv);
204 gpointer func;
205
206 func = get_unit_name_main (unit_test);
207 if (func == NULL)
208 g_error ("*** Unable to find the main entry point for '%s'", unit_test);
209
210 unit_test_main = func;
211
212 ret = unit_test_main (n_unit_names, unit_names);
213
214 g_free (unit_test);
215
216 break;
217 }
218
219 g_free (unit_test);
220 }
221
222 out:
223 g_module_close (module);
224
225 return ret;
226 }
227
228