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