Move markup parse tests to the test framework
[platform/upstream/glib.git] / glib / tests / markup-parse.c
1 #undef G_DISABLE_ASSERT
2 #undef G_LOG_DOMAIN
3
4 #include <string.h>
5 #include <stdio.h>
6 #include <glib.h>
7
8 #ifndef SRCDIR
9 #define SRCDIR "."
10 #endif
11
12 static int depth = 0;
13 static GString *string;
14
15 static void
16 indent (int extra)
17 {
18   int i = 0;
19   while (i < depth)
20     {
21       g_string_append (string, "  ");
22       ++i;
23     }
24 }
25
26 static void
27 start_element_handler  (GMarkupParseContext *context,
28                         const gchar         *element_name,
29                         const gchar        **attribute_names,
30                         const gchar        **attribute_values,
31                         gpointer             user_data,
32                         GError             **error)
33 {
34   int i;
35   
36   indent (0);
37   g_string_append_printf (string, "ELEMENT '%s'\n", element_name);
38
39   i = 0;
40   while (attribute_names[i] != NULL)
41     {
42       indent (1);
43
44       g_string_append_printf (string, "%s=\"%s\"\n",
45                               attribute_names[i],
46                               attribute_values[i]);
47       
48       ++i;
49     }
50   
51   ++depth;
52 }
53
54 static void
55 end_element_handler (GMarkupParseContext *context,
56                      const gchar         *element_name,
57                      gpointer             user_data,
58                      GError             **error)
59 {
60   --depth;
61   indent (0);
62   g_string_append_printf (string, "END '%s'\n", element_name);
63   }
64
65 static void
66 text_handler (GMarkupParseContext *context,
67               const gchar         *text,
68               gsize                text_len,
69               gpointer             user_data,
70               GError             **error)
71 {
72   indent (0);
73   g_string_append_printf (string, "TEXT '%.*s'\n", (int)text_len, text);
74 }
75
76
77 static void
78 passthrough_handler (GMarkupParseContext *context,
79                      const gchar         *passthrough_text,
80                      gsize                text_len,
81                      gpointer             user_data,
82                      GError             **error)
83 {
84   indent (0);
85
86   g_string_append_printf (string, "PASS '%.*s'\n", (int)text_len, passthrough_text);
87 }
88
89 static void
90 error_handler (GMarkupParseContext *context,
91                GError              *error,
92                gpointer             user_data)
93 {
94   g_string_append_printf (string, "ERROR %s\n", error->message);
95 }
96
97 static const GMarkupParser parser = {
98   start_element_handler,
99   end_element_handler,
100   text_handler,
101   passthrough_handler,
102   error_handler
103 };
104
105 static const GMarkupParser silent_parser = {
106   NULL,
107   NULL,
108   NULL,
109   NULL,
110   error_handler
111 };
112
113 static int
114 test_in_chunks (const gchar *contents,
115                 gint         length,
116                 gint         chunk_size)
117 {
118   GMarkupParseContext *context;
119   int i = 0;
120   
121   context = g_markup_parse_context_new (&silent_parser, 0, NULL, NULL);
122
123   while (i < length)
124     {
125       int this_chunk = MIN (length - i, chunk_size);
126
127       if (!g_markup_parse_context_parse (context,
128                                          contents + i,
129                                          this_chunk,
130                                          NULL))
131         {
132           g_markup_parse_context_free (context);
133           return 1;
134         }
135
136       i += this_chunk;
137     }
138       
139   if (!g_markup_parse_context_end_parse (context, NULL))
140     {
141       g_markup_parse_context_free (context);
142       return 1;
143     }
144
145   g_markup_parse_context_free (context);
146
147   return 0;
148 }
149
150 static int
151 test_file (const gchar *filename)
152 {
153   gchar *contents;
154   gsize  length;
155   GError *error;
156   GMarkupParseContext *context;
157   gint line, col;
158
159   error = NULL;
160   if (!g_file_get_contents (filename,
161                             &contents,
162                             &length,
163                             &error))
164     {
165       fprintf (stderr, "%s\n", error->message);
166       g_error_free (error);
167       return 1;
168     }
169
170   context = g_markup_parse_context_new (&parser, 0, NULL, NULL);
171   g_assert (g_markup_parse_context_get_user_data (context) == NULL);
172   g_markup_parse_context_get_position (context, &line, &col);
173   g_assert (line == 1 && col == 1);
174
175   if (!g_markup_parse_context_parse (context, contents, length, NULL))
176     {
177       g_markup_parse_context_free (context);
178       return 1;
179     }
180
181   if (!g_markup_parse_context_end_parse (context, NULL))
182     {
183       g_markup_parse_context_free (context);
184       return 1;
185     }
186
187   g_markup_parse_context_free (context);
188
189   /* A byte at a time */
190   if (test_in_chunks (contents, length, 1) != 0)
191     return 1;
192
193   /* 2 bytes */
194   if (test_in_chunks (contents, length, 2) != 0)
195     return 1;
196
197   /*5 bytes */
198   if (test_in_chunks (contents, length, 5) != 0)
199     return 1;
200   
201   /* 12 bytes */
202   if (test_in_chunks (contents, length, 12) != 0)
203     return 1;
204   
205   /* 1024 bytes */
206   if (test_in_chunks (contents, length, 1024) != 0)
207     return 1;
208
209   return 0;
210 }
211
212 static gchar *
213 get_expected_filename (const gchar *filename)
214 {
215   gchar *f, *p, *expected;
216
217   f = g_strdup (filename);
218   p = strstr (f, ".gmarkup");
219   *p = 0;
220   expected = g_strconcat (f, ".expected", NULL);
221   g_free (f);
222
223   return expected;
224 }
225
226 static void
227 test_parse (gconstpointer d)
228 {
229   const gchar *filename = d;
230   gchar *expected_file;
231   gchar *expected;
232   gint res;
233
234   depth = 0;
235   string = g_string_sized_new (0);
236
237   res = test_file (filename);
238
239   if (strstr (filename, "valid"))
240     g_assert_cmpint (res, ==, 0);
241   else
242     g_assert_cmpint (res, ==, 1);
243
244   expected_file = get_expected_filename (filename);
245   if (g_file_get_contents (expected_file, &expected, NULL, NULL))
246     {
247       g_assert_cmpstr (string->str, ==, expected);
248       g_free (expected);
249     }
250   g_free (expected_file);
251
252   g_string_free (string, TRUE);
253 }
254
255 int
256 main (int argc, char *argv[])
257 {
258   GDir *dir;
259   GError *error;
260   const gchar *name;
261   gchar *path;
262
263   g_test_init (&argc, &argv, NULL);
264
265   /* allow to easily generate expected output for new test cases */
266   if (argc > 1)
267     {
268       string = g_string_sized_new (0);
269       test_file (argv[1]);
270       g_print (string->str);
271       return 0;
272     }
273
274   error = NULL;
275   dir = g_dir_open (SRCDIR "/markups", 0, &error);
276   g_assert_no_error (error);
277   while ((name = g_dir_read_name (dir)) != NULL)
278     {
279       if (strstr (name, "expected"))
280         continue;
281
282       path = g_strdup_printf ("/markup/parse/%s", name);
283       g_test_add_data_func (path, g_build_filename (SRCDIR, "markups", name, NULL),  test_parse);
284       g_free (path);
285     }
286   g_dir_close (dir);
287
288   return g_test_run ();
289 }
290