getdate.y: disallow countable dayshifts like "4 yesterday ago"
[gnulib.git] / tests / test-getdate.c
1 /* Test of getdate() function.
2    Copyright (C) 2008 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* Written by Simon Josefsson <simon@josefsson.org>, 2008.  */
19
20 #include <config.h>
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "getdate.h"
27
28 #define ASSERT(expr)                                                    \
29   do                                                                    \
30     {                                                                   \
31       if (!(expr))                                                      \
32         {                                                               \
33           fprintf (stderr, "%s:%d: assertion failed\n",                 \
34                    __FILE__, __LINE__);                                 \
35           fflush (stderr);                                              \
36           abort ();                                                     \
37         }                                                               \
38     }                                                                   \
39   while (0)
40
41 #ifdef DEBUG
42 #define LOG(str, now, res)                                              \
43   printf ("string `%s' diff %d %d\n",                   \
44           str, res.tv_sec - now.tv_sec, res.tv_nsec - now.tv_nsec);
45 #else
46 #define LOG(str, now, res) 0
47 #endif
48
49 int
50 main (int argc, char **argv)
51 {
52   bool ret;
53   struct timespec result;
54   struct timespec result2;
55   struct timespec now;
56   const char *p;
57
58   now.tv_sec = 4711;
59   now.tv_nsec = 1267;
60   p = "now";
61   ASSERT (get_date (&result, p, &now));
62   LOG (p, now, result);
63   ASSERT (now.tv_sec == result.tv_sec && now.tv_nsec == result.tv_nsec);
64
65   now.tv_sec = 4711;
66   now.tv_nsec = 1267;
67   p = "tomorrow";
68   ASSERT (get_date (&result, p, &now));
69   LOG (p, now, result);
70   ASSERT (now.tv_sec + 24 * 60 * 60 == result.tv_sec
71           && now.tv_nsec == result.tv_nsec);
72
73   now.tv_sec = 4711;
74   now.tv_nsec = 1267;
75   p = "yesterday";
76   ASSERT (get_date (&result, p, &now));
77   LOG (p, now, result);
78   ASSERT (now.tv_sec - 24 * 60 * 60 == result.tv_sec
79           && now.tv_nsec == result.tv_nsec);
80
81   now.tv_sec = 4711;
82   now.tv_nsec = 1267;
83   p = "4 hours";
84   ASSERT (get_date (&result, p, &now));
85   LOG (p, now, result);
86   ASSERT (now.tv_sec + 4 * 60 * 60 == result.tv_sec
87           && now.tv_nsec == result.tv_nsec);
88
89   /* test if timezone is not being ignored for day offset */
90   now.tv_sec = 4711;
91   now.tv_nsec = 1267;
92   p = "UTC+400 +24 hours";
93   ASSERT (get_date (&result, p, &now));
94   LOG (p, now, result);
95   p = "UTC+400 +1 day";
96   ASSERT (get_date (&result2, p, &now));
97   LOG (p, now, result2);
98   ASSERT (result.tv_sec == result2.tv_sec
99           && result.tv_nsec == result2.tv_nsec);
100
101   /* test if several time zones formats are handled same way */
102   now.tv_sec = 4711;
103   now.tv_nsec = 1267;
104   p = "UTC+14:00";
105   ASSERT (get_date (&result, p, &now));
106   LOG (p, now, result);
107   p = "UTC+14";
108   ASSERT (get_date (&result2, p, &now));
109   LOG (p, now, result2);
110   ASSERT (result.tv_sec == result2.tv_sec
111           && result.tv_nsec == result2.tv_nsec);
112   p = "UTC+1400";
113   ASSERT (get_date (&result2, p, &now));
114   LOG (p, now, result2);
115   ASSERT (result.tv_sec == result2.tv_sec
116           && result.tv_nsec == result2.tv_nsec);
117
118   now.tv_sec = 4711;
119   now.tv_nsec = 1267;
120   p = "UTC-14:00";
121   ASSERT (get_date (&result, p, &now));
122   LOG (p, now, result);
123   p = "UTC-14";
124   ASSERT (get_date (&result2, p, &now));
125   LOG (p, now, result2);
126   ASSERT (result.tv_sec == result2.tv_sec
127           && result.tv_nsec == result2.tv_nsec);
128   p = "UTC-1400";
129   ASSERT (get_date (&result2, p, &now));
130   LOG (p, now, result2);
131   ASSERT (result.tv_sec == result2.tv_sec
132           && result.tv_nsec == result2.tv_nsec);
133
134   now.tv_sec = 4711;
135   now.tv_nsec = 1267;
136   p = "UTC+0:15";
137   ASSERT (get_date (&result, p, &now));
138   LOG (p, now, result);
139   p = "UTC+0015";
140   ASSERT (get_date (&result2, p, &now));
141   LOG (p, now, result2);
142   ASSERT (result.tv_sec == result2.tv_sec
143           && result.tv_nsec == result2.tv_nsec);
144
145   now.tv_sec = 4711;
146   now.tv_nsec = 1267;
147   p = "UTC-1:30";
148   ASSERT (get_date (&result, p, &now));
149   LOG (p, now, result);
150   p = "UTC-130";
151   ASSERT (get_date (&result2, p, &now));
152   LOG (p, now, result2);
153   ASSERT (result.tv_sec == result2.tv_sec
154           && result.tv_nsec == result2.tv_nsec);
155
156
157   /* TZ out of range should cause get_date failure */
158   now.tv_sec = 4711;
159   now.tv_nsec = 1267;
160   p = "UTC+25:00";
161   ASSERT (!get_date (&result, p, &now));
162
163         /* Check for several invalid countable dayshifts */
164   now.tv_sec = 4711;
165   now.tv_nsec = 1267;
166   p = "UTC+4:00 +40 yesterday";
167   ASSERT (!get_date (&result, p, &now));
168   p = "UTC+4:00 next yesterday";
169   ASSERT (!get_date (&result, p, &now));
170   p = "UTC+4:00 tomorrow ago";
171   ASSERT (!get_date (&result, p, &now));
172   p = "UTC+4:00 40 now ago";
173   ASSERT (!get_date (&result, p, &now));
174   p = "UTC+4:00 last tomorrow";
175   ASSERT (!get_date (&result, p, &now));
176   p = "UTC+4:00 -4 today";
177   ASSERT (!get_date (&result, p, &now));
178
179   /* And check correct usage of dayshifts */
180   now.tv_sec = 4711;
181   now.tv_nsec = 1267;
182   p = "UTC+400 tomorrow";
183   ASSERT (get_date (&result, p, &now));
184   LOG (p, now, result);
185   p = "UTC+400 +1 day";
186   ASSERT (get_date (&result2, p, &now));
187   LOG (p, now, result2);
188   ASSERT (result.tv_sec == result2.tv_sec
189           && result.tv_nsec == result2.tv_nsec);
190   now.tv_sec = 4711;
191   now.tv_nsec = 1267;
192   p = "UTC+400 yesterday";
193   ASSERT (get_date (&result, p, &now));
194   LOG (p, now, result);
195   p = "UTC+400 1 day ago";
196   ASSERT (get_date (&result2, p, &now));
197   LOG (p, now, result2);
198   ASSERT (result.tv_sec == result2.tv_sec
199           && result.tv_nsec == result2.tv_nsec);
200   now.tv_sec = 4711;
201   now.tv_nsec = 1267;
202   p = "UTC+400 now";
203   ASSERT (get_date (&result, p, &now));
204   LOG (p, now, result);
205   p = "UTC+400 +0 minutes"; /* silly, but simple "UTC+400" is different*/
206   ASSERT (get_date (&result2, p, &now));
207   LOG (p, now, result2);
208   ASSERT (result.tv_sec == result2.tv_sec
209           && result.tv_nsec == result2.tv_nsec);
210
211   return 0;
212 }