]> Pileus Git - ~andy/gtk/blob - tests/css/parser/test-css-parser.c
tests: Check errors in css test
[~andy/gtk] / tests / css / parser / test-css-parser.c
1 /*
2  * Copyright (C) 2011 Red Hat Inc.
3  *
4  * Author:
5  *      Benjamin Otte <otte@redhat.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include "config.h"
24
25 #include <string.h>
26 #include <glib/gstdio.h>
27 #include <gtk/gtk.h>
28
29 static char *
30 test_get_reference_file (const char *css_file)
31 {
32   GString *file = g_string_new (NULL);
33
34   if (g_str_has_suffix (css_file, ".css"))
35     g_string_append_len (file, css_file, strlen (css_file) - 4);
36   else
37     g_string_append (file, css_file);
38   
39   g_string_append (file, ".ref.css");
40
41   if (!g_file_test (file->str, G_FILE_TEST_EXISTS))
42     {
43       g_string_free (file, TRUE);
44       return g_strdup (css_file);
45     }
46
47   return g_string_free (file, FALSE);
48 }
49
50 static char *
51 test_get_errors_file (const char *css_file)
52 {
53   GString *file = g_string_new (NULL);
54
55   if (g_str_has_suffix (css_file, ".css"))
56     g_string_append_len (file, css_file, strlen (css_file) - 4);
57   else
58     g_string_append (file, css_file);
59   
60   g_string_append (file, ".errors");
61
62   if (!g_file_test (file->str, G_FILE_TEST_EXISTS))
63     {
64       g_string_free (file, TRUE);
65       return NULL;
66     }
67
68   return g_string_free (file, FALSE);
69 }
70
71 static char *
72 diff_with_file (const char  *file1,
73                 char        *text,
74                 gssize       len,
75                 GError     **error)
76 {
77   const char *command[] = { "diff", "-u", file1, NULL, NULL };
78   char *diff, *tmpfile;
79   int fd;
80
81   diff = NULL;
82
83   if (len < 0)
84     len = strlen (text);
85   
86   /* write the text buffer to a temporary file */
87   fd = g_file_open_tmp (NULL, &tmpfile, error);
88   if (fd < 0)
89     return NULL;
90
91   if (write (fd, text, len) != (int) len)
92     {
93       close (fd);
94       g_set_error (error,
95                    G_FILE_ERROR, G_FILE_ERROR_FAILED,
96                    "Could not write data to temporary file '%s'", tmpfile);
97       goto done;
98     }
99   close (fd);
100   command[3] = tmpfile;
101
102   /* run diff command */
103   g_spawn_sync (NULL, 
104                 (char **) command,
105                 NULL,
106                 G_SPAWN_SEARCH_PATH,
107                 NULL, NULL,
108                 &diff,
109                 NULL, NULL,
110                 error);
111
112 done:
113   g_unlink (tmpfile);
114   g_free (tmpfile);
115
116   return diff;
117 }
118
119 static void
120 parsing_error_cb (GtkCssProvider *provider,
121                   const gchar     *path,
122                   guint            line,
123                   guint            position,
124                   const GError *   error,
125                   GString *        errors)
126 {
127   char *basename;
128
129   g_assert (path);
130   g_assert (line > 0);
131
132   basename = g_path_get_basename (path);
133
134   g_string_append_printf (errors,
135                           "%s:%u: error: %s %u\n",
136                           basename, line,
137                           g_quark_to_string (error->domain),
138                           error->code);
139
140   g_free (basename);
141 }
142
143 static void
144 test_css_file (GFile *file)
145 {
146   GtkCssProvider *provider;
147   char *css, *diff;
148   char *css_file, *reference_file, *errors_file;
149   GString *errors;
150   GError *error = NULL;
151
152   css_file = g_file_get_path (file);
153   errors = g_string_new ("");
154
155   provider = gtk_css_provider_new ();
156   g_signal_connect (provider, 
157                     "parsing-error",
158                     G_CALLBACK (parsing_error_cb),
159                     errors);
160   gtk_css_provider_load_from_path (provider,
161                                    css_file,
162                                    &error);
163   g_assert_no_error (error);
164
165   css = gtk_css_provider_to_string (provider);
166
167   g_assert_no_error (error);
168
169   reference_file = test_get_reference_file (css_file);
170
171   diff = diff_with_file (reference_file, css, -1, &error);
172   g_assert_no_error (error);
173
174   if (diff && diff[0])
175     {
176       g_test_message ("%s", diff);
177       g_assert_not_reached ();
178     }
179
180   g_free (css);
181   g_free (reference_file);
182
183   errors_file = test_get_errors_file (css_file);
184
185   if (errors_file)
186     {
187       diff = diff_with_file (errors_file, errors->str, errors->len, &error);
188       g_assert_no_error (error);
189
190       if (diff && diff[0])
191         {
192           g_test_message ("%s", diff);
193           g_assert_not_reached ();
194         }
195     }
196   else if (errors->str[0])
197     {
198       g_test_message ("Unexpected errors:\n%s", errors->str);
199       g_assert_not_reached ();
200     }
201
202   g_free (errors_file);
203   g_string_free (errors, TRUE);
204
205   g_free (diff);
206   g_free (css_file);
207 }
208
209 int
210 main (int argc, char **argv)
211 {
212   const char *basedir;
213   GError *error = NULL;
214   GFile *dir;
215   GFileEnumerator *enumerator;
216   GFileInfo *info;
217
218   gtk_test_init (&argc, &argv);
219
220   if (g_getenv ("srcdir"))
221     basedir = g_getenv ("srcdir");
222   else
223     basedir = ".";
224     
225   dir = g_file_new_for_path (basedir);
226   enumerator = g_file_enumerate_children (dir, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, &error);
227   g_assert_no_error (error);
228
229   while ((info = g_file_enumerator_next_file (enumerator, NULL, &error)))
230     {
231       GFile *file;
232       const char *filename;
233
234       filename = g_file_info_get_name (info);
235
236       if (!g_str_has_suffix (filename, ".css") ||
237           g_str_has_suffix (filename, ".out.css") ||
238           g_str_has_suffix (filename, ".ref.css"))
239         {
240           g_object_unref (info);
241           continue;
242         }
243
244       file = g_file_get_child (dir, filename);
245
246       g_test_add_vtable (g_file_get_path (file),
247                          0,
248                          file,
249                          NULL,
250                          (GTestFixtureFunc) test_css_file,
251                          (GTestFixtureFunc) g_object_unref);
252
253       g_object_unref (info);
254     }
255   
256   g_assert_no_error (error);
257   g_object_unref (enumerator);
258
259   return g_test_run ();
260 }
261