Git init
[profile/ivi/libsoup2.4.git] / tests / date.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2005 Novell, Inc.
4  */
5
6 #include <stdio.h>
7 #include <string.h>
8
9 #include <libsoup/soup-date.h>
10 #include <glib.h>
11
12 #include "test-utils.h"
13
14 static gboolean check_ok (const char *strdate, SoupDate *date);
15
16 static SoupDate *
17 make_date (const char *strdate)
18 {
19         char *dup;
20         SoupDate *date;
21
22         /* We do it this way so that if soup_date_new_from_string()
23          * reads off the end of the string, it will trigger an error
24          * when valgrinding, rather than just reading the start of the
25          * next const string.
26          */
27         dup = g_strdup (strdate);
28         date = soup_date_new_from_string (dup);
29         g_free (dup);
30         return date;
31 }
32
33 static const struct {
34         SoupDateFormat format;
35         const char *date;
36 } good_dates[] = {
37         { SOUP_DATE_HTTP,            "Sat, 06 Nov 2004 08:09:07 GMT" },
38         { SOUP_DATE_COOKIE,          "Sat, 06-Nov-2004 08:09:07 GMT" },
39         { SOUP_DATE_RFC2822,         "Sat, 6 Nov 2004 08:09:07 -0430" },
40         { SOUP_DATE_ISO8601_COMPACT, "20041106T080907" },
41         { SOUP_DATE_ISO8601_FULL,    "2004-11-06T08:09:07" },
42         { SOUP_DATE_ISO8601_XMLRPC,  "20041106T08:09:07" }
43 };
44
45 static void
46 check_good (SoupDateFormat format, const char *strdate)
47 {
48         SoupDate *date;
49         char *strdate2;
50
51         date = make_date (strdate);
52         if (date)
53                 strdate2 = soup_date_to_string (date, format);
54         if (!check_ok (strdate, date))
55                 return;
56
57         if (strcmp (strdate, strdate2) != 0) {
58                 debug_printf (1, "  restringification failed: '%s' -> '%s'\n",
59                               strdate, strdate2);
60                 errors++;
61         }
62         g_free (strdate2);
63 }
64
65 static const char *ok_dates[] = {
66         /* rfc1123-date, and broken variants */
67         "Sat, 06 Nov 2004 08:09:07 GMT",
68         "Sat, 6 Nov 2004 08:09:07 GMT",
69         "Sat,  6 Nov 2004 08:09:07 GMT",
70         "Sat, 06 Nov 2004 08:09:07",
71         "06 Nov 2004 08:09:07 GMT",
72         "SAT, 06 NOV 2004 08:09:07 +1000",
73
74         /* rfc850-date, and broken variants */
75         "Saturday, 06-Nov-04 08:09:07 GMT",
76         "Saturday, 6-Nov-04 08:09:07 GMT",
77         "Saturday,  6-Nov-04 08:09:07 GMT",
78         "Saturday, 06-Nov-104 08:09:07 GMT",
79         "Saturday, 06-Nov-04 08:09:07",
80         "06-Nov-04 08:09:07 GMT",
81
82         /* asctime-date, and broken variants */
83         "Sat Nov  6 08:09:07 2004",
84         "Sat Nov 06 08:09:07 2004",
85         "Sat Nov 6 08:09:07 2004",
86         "Sat Nov  6 08:09:07 2004 GMT",
87
88         /* ISO 8601 */
89         "2004-11-06T08:09:07Z",
90         "20041106T08:09:07Z",
91         "20041106T08:09:07+00:00",
92         "20041106T080907+00:00",
93
94         /* Netscape cookie spec date, and broken variants */
95         "Sat, 06-Nov-2004 08:09:07 GMT",
96         "Sat, 6-Nov-2004 08:09:07 GMT",
97         "Sat,  6-Nov-2004 08:09:07 GMT",
98         "Sat, 06-Nov-2004 08:09:07",
99
100         /* Original version of Netscape cookie spec, and broken variants */
101         "Sat, 06-Nov-04 08:09:07 GMT",
102         "Sat, 6-Nov-04 08:09:07 GMT",
103         "Sat,  6-Nov-04 08:09:07 GMT",
104         "Sat, 06-Nov-104 08:09:07 GMT",
105         "Sat, 06-Nov-04 08:09:07",
106
107         /* Netscape cookie spec example syntax, and broken variants */
108         "Saturday, 06-Nov-04 08:09:07 GMT",
109         "Saturday, 6-Nov-04 08:09:07 GMT",
110         "Saturday,  6-Nov-04 08:09:07 GMT",
111         "Saturday, 06-Nov-104 08:09:07 GMT",
112         "Saturday, 06-Nov-2004 08:09:07 GMT",
113         "Saturday, 6-Nov-2004 08:09:07 GMT",
114         "Saturday,  6-Nov-2004 08:09:07 GMT",
115         "Saturday, 06-Nov-04 08:09:07",
116
117         /* Miscellaneous broken formats seen on the web */
118         "Sat 06-Nov-2004  08:9:07",
119         "Saturday, 06-Nov-04 8:9:07 GMT",
120         "Sat, 06 Nov 2004 08:09:7 GMT"
121 };
122
123 #define TIME_T 1099728547L
124 #define TIME_T_STRING "1099728547"
125
126 static gboolean
127 check_ok (const char *strdate, SoupDate *date)
128 {
129         debug_printf (2, "%s\n", strdate);
130
131         if (date &&
132             date->year == 2004 && date->month == 11 && date->day == 6 &&
133             date->hour == 8 && date->minute == 9 && date->second == 7) {
134                 soup_date_free (date);
135                 return TRUE;
136         }
137
138         debug_printf (1, "  date parsing failed for '%s'.\n", strdate);
139         if (date) {
140                 debug_printf (1, "    got: %d %d %d - %d %d %d\n\n",
141                               date->year, date->month, date->day,
142                               date->hour, date->minute, date->second);
143                 soup_date_free (date);
144         }
145         errors++;
146         return FALSE;
147 }
148
149 static const char *bad_dates[] = {
150         /* broken rfc1123-date */
151         ", 06 Nov 2004 08:09:07 GMT",
152         "Sat, Nov 2004 08:09:07 GMT",
153         "Sat, 06 2004 08:09:07 GMT",
154         "Sat, 06 Nov 08:09:07 GMT",
155         "Sat, 06 Nov 2004 :09:07 GMT",
156         "Sat, 06 Nov 2004 09:07 GMT",
157         "Sat, 06 Nov 2004 08::07 GMT",
158         "Sat, 06 Nov 2004 08:09: GMT",
159
160         /* broken rfc850-date */
161         ", 06-Nov-04 08:09:07 GMT",
162         "Saturday, -Nov-04 08:09:07 GMT",
163         "Saturday, Nov-04 08:09:07 GMT",
164         "Saturday, 06-04 08:09:07 GMT",
165         "Saturday, 06--04 08:09:07 GMT",
166         "Saturday, 06-Nov- 08:09:07 GMT",
167         "Saturday, 06-Nov 08:09:07 GMT",
168         "Saturday, 06-Nov-04 :09:07 GMT",
169         "Saturday, 06-Nov-04 09:07 GMT",
170         "Saturday, 06-Nov-04 08::07 GMT",
171         "Saturday, 06-Nov-04 08:09: GMT",
172
173         /* broken asctime-date */
174         "Nov  6 08:09:07 2004",
175         "Sat  6 08:09:07 2004",
176         "Sat Nov 08:09:07 2004",
177         "Sat Nov  6 :09:07 2004",
178         "Sat Nov  6 09:07 2004",
179         "Sat Nov  6 08::07 2004",
180         "Sat Nov  6 08:09: 2004",
181         "Sat Nov  6 08:09:07",
182         "Sat Nov  6 08:09:07 GMT 2004"
183 };
184
185 static void
186 check_bad (const char *strdate, SoupDate *date)
187 {
188         debug_printf (2, "%s\n", strdate);
189
190         if (!date)
191                 return;
192         errors++;
193
194         debug_printf (1, "  date parsing succeeded for '%s'!\n", strdate);
195         debug_printf (1, "    got: %d %d %d - %d %d %d\n\n",
196                       date->year, date->month, date->day,
197                       date->hour, date->minute, date->second);
198         soup_date_free (date);
199 }
200
201 static const struct conversion {
202         const char *source;
203         const char *http, *cookie, *rfc2822, *compact, *full, *xmlrpc;
204 } conversions[] = {
205         /* SOUP_DATE_HTTP */
206         { "Sat, 06 Nov 2004 08:09:07 GMT",
207
208           "Sat, 06 Nov 2004 08:09:07 GMT",
209           "Sat, 06-Nov-2004 08:09:07 GMT",
210           "Sat, 6 Nov 2004 08:09:07 +0000",
211           "20041106T080907Z",
212           "2004-11-06T08:09:07Z",
213           "20041106T08:09:07" },
214
215         /* RFC2822 GMT */
216         { "Sat, 6 Nov 2004 08:09:07 +0000",
217
218           "Sat, 06 Nov 2004 08:09:07 GMT",
219           "Sat, 06-Nov-2004 08:09:07 GMT",
220           "Sat, 6 Nov 2004 08:09:07 +0000",
221           "20041106T080907Z",
222           "2004-11-06T08:09:07Z",
223           "20041106T08:09:07" },
224
225         /* RFC2822 with positive offset */
226         { "Sat, 6 Nov 2004 08:09:07 +0430",
227
228           "Sat, 06 Nov 2004 04:39:07 GMT",
229           "Sat, 06-Nov-2004 04:39:07 GMT",
230           "Sat, 6 Nov 2004 08:09:07 +0430",
231           "20041106T080907+0430",
232           "2004-11-06T08:09:07+04:30",
233           "20041106T08:09:07" },
234
235         /* RFC2822 with negative offset */
236         { "Sat, 6 Nov 2004 08:09:07 -0430",
237
238           "Sat, 06 Nov 2004 12:39:07 GMT",
239           "Sat, 06-Nov-2004 12:39:07 GMT",
240           "Sat, 6 Nov 2004 08:09:07 -0430",
241           "20041106T080907-0430",
242           "2004-11-06T08:09:07-04:30",
243           "20041106T08:09:07" },
244
245         /* RFC2822 floating */
246         { "Sat, 6 Nov 2004 08:09:07 -0000",
247
248           "Sat, 06 Nov 2004 08:09:07 GMT",
249           "Sat, 06-Nov-2004 08:09:07 GMT",
250           "Sat, 6 Nov 2004 08:09:07 -0000",
251           "20041106T080907",
252           "2004-11-06T08:09:07",
253           "20041106T08:09:07" },
254
255         /* ISO GMT */
256         { "2004-11-06T08:09:07Z",
257
258           "Sat, 06 Nov 2004 08:09:07 GMT",
259           "Sat, 06-Nov-2004 08:09:07 GMT",
260           "Sat, 6 Nov 2004 08:09:07 +0000",
261           "20041106T080907Z",
262           "2004-11-06T08:09:07Z",
263           "20041106T08:09:07" },
264
265         /* ISO with positive offset */
266         { "2004-11-06T08:09:07+04:30",
267
268           "Sat, 06 Nov 2004 04:39:07 GMT",
269           "Sat, 06-Nov-2004 04:39:07 GMT",
270           "Sat, 6 Nov 2004 08:09:07 +0430",
271           "20041106T080907+0430",
272           "2004-11-06T08:09:07+04:30",
273           "20041106T08:09:07" },
274
275         /* ISO with negative offset */
276         { "2004-11-06T08:09:07-04:30",
277
278           "Sat, 06 Nov 2004 12:39:07 GMT",
279           "Sat, 06-Nov-2004 12:39:07 GMT",
280           "Sat, 6 Nov 2004 08:09:07 -0430",
281           "20041106T080907-0430",
282           "2004-11-06T08:09:07-04:30",
283           "20041106T08:09:07" },
284
285         /* ISO floating */
286         { "2004-11-06T08:09:07",
287
288           "Sat, 06 Nov 2004 08:09:07 GMT",
289           "Sat, 06-Nov-2004 08:09:07 GMT",
290           "Sat, 6 Nov 2004 08:09:07 -0000",
291           "20041106T080907",
292           "2004-11-06T08:09:07",
293           "20041106T08:09:07" }
294 };
295
296 static void
297 check_conversion (const struct conversion *conv)
298 {
299         SoupDate *date;
300         char *str;
301
302         debug_printf (2, "%s\n", conv->source);
303         date = make_date (conv->source);
304         if (!date) {
305                 debug_printf (1, "  date parsing failed for '%s'.\n", conv->source);
306                 errors++;
307                 return;
308         }
309
310         str = soup_date_to_string (date, SOUP_DATE_HTTP);
311         if (!str || strcmp (str, conv->http) != 0) {
312                 debug_printf (1, "  conversion of '%s' to HTTP failed:\n"
313                               "    wanted: %s\n    got:    %s\n",
314                               conv->source, conv->http, str ? str : "(null)");
315                 errors++;
316         }
317         g_free (str);
318
319         str = soup_date_to_string (date, SOUP_DATE_COOKIE);
320         if (!str || strcmp (str, conv->cookie) != 0) {
321                 debug_printf (1, "  conversion of '%s' to COOKIE failed:\n"
322                               "    wanted: %s\n    got:    %s\n",
323                               conv->source, conv->cookie, str ? str : "(null)");
324                 errors++;
325         }
326         g_free (str);
327
328         str = soup_date_to_string (date, SOUP_DATE_RFC2822);
329         if (!str || strcmp (str, conv->rfc2822) != 0) {
330                 debug_printf (1, "  conversion of '%s' to RFC2822 failed:\n"
331                               "    wanted: %s\n    got:    %s\n",
332                               conv->source, conv->rfc2822, str ? str : "(null)");
333                 errors++;
334         }
335         g_free (str);
336
337         str = soup_date_to_string (date, SOUP_DATE_ISO8601_COMPACT);
338         if (!str || strcmp (str, conv->compact) != 0) {
339                 debug_printf (1, "  conversion of '%s' to COMPACT failed:\n"
340                               "    wanted: %s\n    got:    %s\n",
341                               conv->source, conv->compact, str ? str : "(null)");
342                 errors++;
343         }
344         g_free (str);
345
346         str = soup_date_to_string (date, SOUP_DATE_ISO8601_FULL);
347         if (!str || strcmp (str, conv->full) != 0) {
348                 debug_printf (1, "  conversion of '%s' to FULL failed:\n"
349                               "    wanted: %s\n    got:    %s\n",
350                               conv->source, conv->full, str ? str : "(null)");
351                 errors++;
352         }
353         g_free (str);
354
355         str = soup_date_to_string (date, SOUP_DATE_ISO8601_XMLRPC);
356         if (!str || strcmp (str, conv->xmlrpc) != 0) {
357                 debug_printf (1, "  conversion of '%s' to XMLRPC failed:\n"
358                               "    wanted: %s\n    got:    %s\n",
359                               conv->source, conv->xmlrpc, str ? str : "(null)");
360                 errors++;
361         }
362         g_free (str);
363
364         soup_date_free (date);
365 }
366
367 int
368 main (int argc, char **argv)
369 {
370         int i;
371
372         test_init (argc, argv, NULL);
373
374         debug_printf (1, "Good dates:\n");
375         for (i = 0; i < G_N_ELEMENTS (good_dates); i++)
376                 check_good (good_dates[i].format, good_dates[i].date);
377
378         debug_printf (1, "\nOK dates:\n");
379         for (i = 0; i < G_N_ELEMENTS (ok_dates); i++)
380                 check_ok (ok_dates[i], make_date (ok_dates[i]));
381         check_ok (TIME_T_STRING, soup_date_new_from_time_t (TIME_T));
382
383         debug_printf (1, "\nBad dates:\n");
384         for (i = 0; i < G_N_ELEMENTS (bad_dates); i++)
385                 check_bad (bad_dates[i], make_date (bad_dates[i]));
386
387         debug_printf (1, "\nConversions:\n");
388         for (i = 0; i < G_N_ELEMENTS (conversions); i++)
389                 check_conversion (&conversions[i] );
390
391         test_cleanup ();
392         return errors != 0;
393 }