* add xdgmime from freedesktop.org
[citadel.git] / libcitadel / lib / xdgmime / test-mime-data.c
1 /* test-mime-data.c: tests for the mime implementation
2  *
3  * More info can be found at http://www.freedesktop.org/standards/
4  * 
5  * Copyright (C) 2005  Red Hat, Inc.
6  * Copyright (C) 2005  Matthias Clasen <mclasen@redhat.com>
7  *
8  * Licensed under the Academic Free License version 2.0
9  * Or under the following terms:
10  * 
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the
23  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24  * Boston, MA 02111-1307, USA.
25  */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <libgen.h>
31
32 #include "xdgmime.h"
33
34 static int error = 0;
35 static int total = 0;
36 static int failed = 0;
37 static int xfailed = 0;
38 static int xmatch = 0;
39
40 static int verbose = 0;
41
42 static void
43 check_mime_type (const char *mt,
44                  const char *mt_expected,
45                  int         xfail,
46                  const char *test,
47                  const char *filename)
48 {
49   total++;
50
51   if (strcmp (mt, mt_expected) != 0)
52     {
53       failed++;
54       
55       if (xfail)
56         {
57           xfailed++;
58           
59           if (verbose > 1)
60           printf ("%s, '%s' test: expected %s, got %s (expected failure)\n", 
61                   filename, test, mt_expected, mt);
62         }
63       else
64         {
65           if (verbose > 0)
66             printf ("%s, '%s' test: expected %s, got %s\n", 
67                     filename, test, mt_expected, mt);
68         }
69
70     }
71   else
72     {
73       if (xfail)
74         {
75           xmatch++;
76           
77           if (verbose > 1)
78           printf ("%s, '%s' test: got %s (unexpected match)\n", 
79                   filename, test, mt);
80         }
81     }
82
83 }
84
85 static void 
86 test_by_name (const char *filename,
87               const char *mt_expected,
88               int         xfail)
89 {
90   const char *mt;
91
92   mt = xdg_mime_get_mime_type_from_file_name (filename);
93
94   check_mime_type (mt, mt_expected, xfail, "name", filename);
95 }
96
97 static void 
98 test_by_data (const char *dir,
99               const char *filename,
100               const char *mt_expected,
101               int         xfail)
102 {
103   FILE  *file;
104   const char *mt;
105   int max_extent;
106   char *data;
107   int bytes_read;
108   char path[1024];
109
110   snprintf (path, 1024, "%s/%s", dir, filename);
111
112   file = fopen (path, "r");
113
114   if (file == NULL)
115     {
116       printf ("Could not open %s\n", path);
117       error++;
118
119       return;
120     }
121
122   max_extent = xdg_mime_get_max_buffer_extents ();
123   data = malloc (max_extent);
124
125   if (data == NULL)
126     {
127       printf ("Failed to allocate memory for file %s\n", filename);
128       error++;
129
130       return;
131     }
132
133   bytes_read = fread (data, 1, max_extent, file);
134   
135   if (ferror (file))
136     {
137       printf ("Error reading file %s\n", path);
138       error++;
139
140       free (data);
141       fclose (file);
142       
143      return;
144     }
145
146   mt = xdg_mime_get_mime_type_for_data (data, bytes_read);
147   
148   free (data);
149   fclose (file);
150   
151   check_mime_type (mt, mt_expected, xfail, "data", filename);
152 }
153
154 static void 
155 test_by_file (const char *dir,
156               const char *filename,
157               const char *mt_expected,
158               int         xfail)
159 {
160   const char *mt;
161   char path[1024];
162
163   snprintf (path, 1024, "%s/%s", dir, filename);
164
165   mt = xdg_mime_get_mime_type_for_file (path, NULL);
166   
167   check_mime_type (mt, mt_expected, xfail, "file", filename);
168 }
169
170 static void
171 test_single_file (const char *dir,
172                   const char *filename,
173                   const char *mimetype,
174                   int         xfail_name,
175                   int         xfail_data,
176                   int         xfail_file)
177 {
178   test_by_name (filename, mimetype, xfail_name);
179   test_by_data (dir, filename, mimetype, xfail_data);
180   test_by_file (dir, filename, mimetype, xfail_file);
181 }
182
183 static void
184 read_from_file (const char *filename)
185 {
186   FILE *file;
187   char line[255];
188   int lineno = 0;
189   char *testfile, *mimetype, *flags;
190   char *rest, *space, end;
191   char *dir, *tmp;
192   int xfail_name, xfail_data, xfail_file;
193   
194   file = fopen (filename, "r");
195   tmp = strdup (filename);
196   dir = strdup (dirname (tmp));
197   free (tmp);
198
199   if (file == NULL)
200     {
201       printf ("Could not open %s\n", filename);
202       exit (1);
203     }
204
205   while (fgets (line, 255, file) != NULL)
206     {
207       lineno++;
208
209       rest = line;
210       while (*rest == ' ') rest++;
211       
212       if (*rest == '#' || *rest == '\n')
213         continue;
214
215       space = strchr (rest, ' ');
216       if (!space)
217         {
218           printf ("Malformed line in %s:%d\n\t%s\n", filename, lineno, line);
219           continue;
220         }
221
222       *space = '\0';
223       testfile = rest;
224
225       rest = space + 1;
226       while (*rest == ' ') rest++;
227       space = rest;
228       while (*space != ' ' && *space != '\n') space++;
229       end = *space;
230
231       *space = '\0';
232       mimetype = rest;
233       
234       xfail_name = 0;
235       xfail_data = 0;
236       xfail_file = 0;
237
238       if (end != '\n')
239         {
240           rest = space + 1;
241           while (*rest == ' ') rest++;
242           space = rest;
243           while (*space != ' ' && *space != '\n') space++;
244           end = *space;
245           
246           *space = '\0';
247           flags = rest;
248
249           switch (strlen (flags))
250            {
251              default:
252                printf ("%s.%d: Extra flags are ignored\n", filename, lineno);
253                /* Fall thu  */
254              case 3:
255                if (flags[2] == 'x')
256                  xfail_file = 1;
257                /* Fall thu  */
258              case 2:
259                if (flags[1] == 'x')
260                  xfail_data = 1;
261                /* Fall thu  */
262              case 1: 
263                if (flags[0] == 'x')
264                  xfail_name = 1;
265                break;
266              case 0: ;
267                /* Should not happen */
268           }
269         }
270
271       test_single_file (dir, testfile, mimetype, 
272                         xfail_name, xfail_data, xfail_file);
273     }
274
275   fclose (file);
276
277   free (dir);
278 }
279
280 static void
281 usage (void)
282 {
283   printf ("usage: test-mime-data <FILE>\n\n");
284   printf ("Tests the mime system.\n");
285   printf ("Testcases are specified in the following format:\n\n");
286   printf ("# comment\n");
287   printf ("<filename1> <mimetype> [<flags>]\n");
288   printf ("<filename2> <mimetype> [<flags>]\n");
289   printf ("...\n\n");
290   printf ("Where an 'x' in the 1st, 2nd or 3rd position in <flags>\n");
291   printf ("indicates an expected failure when determining the\n");
292   printf ("mimetype by name, data or file.\n");
293
294   exit (1);
295 }
296
297 int 
298 main (int argc, char *argv[])
299 {
300   int i;
301
302   if (argc < 2)
303     usage ();
304   
305   for (i = 1; i < argc; i++)
306     {
307       if (strcmp (argv[i], "-v") == 0)
308         verbose++;
309       else
310         read_from_file (argv[i]);
311     }
312   
313   if (error > 0 || failed > 0)
314     {
315       printf ("%d errors, %d comparisons, %d failed",
316               error, total, failed);
317       if (xfailed > 0)
318         printf (" (%d expected)", xfailed);
319       if (xmatch > 0)
320         printf (", %d unexpected successes", xmatch);
321       printf ("\n");
322
323       return 1;
324     }
325
326   return 0;
327 }