1 /*
2  * Copyright (C) 2010 David King <davidk@openismus.com>
3  * Copyright (C) 2010 - 2011 Vivien Malerba <malerba@gnome-db.org>
4  * Copyright (C) 2011 Murray Cumming <murrayc@murrayc.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 
21 #include <libgda/libgda.h>
22 static gboolean test_parse_iso8601_date (void);
23 static gboolean test_parse_iso8601_time (void);
24 static gboolean test_parse_iso8601_timestamp (void);
25 static gboolean test_date_handler (void);
26 static gboolean test_time_handler (void);
27 static gboolean test_timestamp_handler (void);
28 
29 int
main(int argc,char ** argv)30 main (int argc, char** argv)
31 {
32 	gint nfailed = 0;
33 
34 	if (! test_parse_iso8601_date ())
35 		nfailed++;
36 	if (! test_parse_iso8601_time ())
37 		nfailed++;
38 	if (! test_parse_iso8601_timestamp ())
39 		nfailed++;
40 
41 	gda_init ();
42 	if (! test_date_handler ())
43 		nfailed++;
44 	if (! test_time_handler ())
45 		nfailed++;
46 	if (! test_timestamp_handler ())
47 		nfailed++;
48 
49 	if (nfailed > 0) {
50 		g_print ("FAILED: %d tests failed\n", nfailed);
51 		return EXIT_FAILURE;
52 	}
53 	else {
54 		g_print ("All tests passed\n");
55 		return EXIT_SUCCESS;
56 	}
57 }
58 
59 typedef struct {
60 	gchar   *in_string;
61 	gboolean exp_retval;
62 	guint    exp_day;
63 	guint    exp_month;
64 	gint    exp_year;
65 } TestDate;
66 
67 TestDate datedata[] = {
68 	{"1996-11-22", TRUE, 22, 11, 1996},
69 	{"1996-22-23", FALSE, 0, 0, 0},
70 	{"96-7-23", TRUE, 23, 7, 96},
71 	{"2050-12-31", TRUE, 31, 12, 2050},
72 	{"2050-11-31", FALSE, 0, 0, 0},
73 	{"1996-02-29", TRUE, 29, 2, 1996},
74 	{"1997-02-29", FALSE, 0, 0, 0},
75 	{"1900-5-22", TRUE, 22, 5, 1900},
76 	{"1900.05-22", FALSE, 0, 0, 0},
77 	{"1900-05.22", FALSE, 0, 0, 0},
78 	{"1900-05-22 ", FALSE, 0, 0, 0},
79 	{" 1900-05-22", FALSE, 0, 0, 0},
80 	{"1900 -05-22", FALSE, 0, 0, 0},
81 	{"1900- 05-22", FALSE, 0, 0, 0},
82 	{"1900-05 -22", FALSE, 0, 0, 0},
83 	{"1900-05- 22", FALSE, 0, 0, 0},
84 	{"65535-05-22", TRUE, 22, 5, 65535},
85 	{"1-05-22", TRUE, 22, 5, 1},
86 	{"65536-05-22", FALSE, 0, 0, 0},
87 };
88 
89 static gboolean
test_parse_iso8601_date(void)90 test_parse_iso8601_date (void)
91 {
92 	guint i;
93 
94 	for (i = 0; i < sizeof (datedata) / sizeof (TestDate); i++) {
95 		TestDate td = datedata[i];
96 		GDate date;
97 		/*g_print ("[%s]\n", td.in_string);*/
98 		if (gda_parse_iso8601_date (&date, td.in_string) != td.exp_retval) {
99 			g_print ("Wrong result for gda_parse_iso8601_date (\"%s\"): got %s\n",
100 				 td.in_string, td.exp_retval ? "FALSE" : "TRUE");
101 			return FALSE;
102 		}
103 		if (td.exp_retval &&
104 		    ((g_date_get_day (&date) != td.exp_day) ||
105 		     (g_date_get_month (&date) != td.exp_month) ||
106 		     (g_date_get_year (&date) != td.exp_year))) {
107 			g_print ("Wrong result for gda_parse_iso8601_date (\"%s\"):\n"
108 				 "   exp: DD=%d MM=%d YYYY=%d\n"
109 				 "   got: DD=%d MM=%d YYYY=%d\n",
110 				 td.in_string, td.exp_day, td.exp_month, td.exp_year,
111 				 g_date_get_day (&date), g_date_get_month (&date),
112 				 g_date_get_year (&date));
113 			return FALSE;
114 		}
115 	}
116 	g_print ("All %d iso8601 date parsing tests passed\n", i);
117 
118 	return TRUE;
119 }
120 
121 typedef struct {
122 	gchar   *in_string;
123 	gboolean exp_retval;
124 	GdaTime  exp_time;
125 } TestTime;
126 
127 TestTime timedata[] = {
128 	{"11:22:56", TRUE, {11, 22, 56, 0, GDA_TIMEZONE_INVALID}},
129 	{"1:22:56", TRUE, {1, 22, 56, 0, GDA_TIMEZONE_INVALID}},
130 	{"1:22:60", FALSE, {1, 22, 0, 0, GDA_TIMEZONE_INVALID}},
131 	{"1:60:45", FALSE, {1, 0, 0, 0, GDA_TIMEZONE_INVALID}},
132 	{"24:23:45", FALSE, {0, 0, 0, 0, GDA_TIMEZONE_INVALID}},
133 	{"23:59:59", TRUE, {23, 59, 59, 0, GDA_TIMEZONE_INVALID}},
134 	{"0:0:00", TRUE, {0, 0, 0, 0, GDA_TIMEZONE_INVALID}},
135 	{"12:1:0", TRUE, {12, 1, 0, 0, GDA_TIMEZONE_INVALID}},
136 	{" 12:00:00", FALSE, {0, 0, 0, 0, GDA_TIMEZONE_INVALID}},
137 	{"12 :00:00", FALSE, {12, 0, 0, 0, GDA_TIMEZONE_INVALID}},
138 	{"12: 00:00", FALSE, {12, 0, 0, 0, GDA_TIMEZONE_INVALID}},
139 	{"12: 00:00", FALSE, {12, 0, 0, 0, GDA_TIMEZONE_INVALID}},
140 	{"12:1 :00", FALSE, {12, 1, 0, 0, GDA_TIMEZONE_INVALID}},
141 	{"12:1:2 ", FALSE, {12, 1, 2, 0, GDA_TIMEZONE_INVALID}},
142 	{"12:1:2.", FALSE, {12, 1, 2, 0, GDA_TIMEZONE_INVALID}},
143 	{"12:1:2:", FALSE, {12, 1, 2, 0, GDA_TIMEZONE_INVALID}},
144 	{"12:1:2.123", TRUE, {12, 1, 2, 123, GDA_TIMEZONE_INVALID}},
145 	{"12:1:2-2", TRUE, {12, 1, 2, 0, -2*60*60}},
146 	{"12:1:2+11", TRUE, {12, 1, 2, 0, 11*60*60}},
147 	{"12:1:2.1234+11", TRUE, {12, 1, 2, 1234, 11*60*60}},
148 	{"12:1:2.12345678-3", TRUE, {12, 1, 2, 12345678, -3*60*60}},
149 	{"12:1:2.12345678 UTC", TRUE, {12, 1, 2, 12345678, 0}},
150 	{"12:1:2.12345678 INVALID", FALSE, {12, 1, 2, 12345678, GDA_TIMEZONE_INVALID}},
151 };
152 
153 static gboolean
test_parse_iso8601_time(void)154 test_parse_iso8601_time (void)
155 {
156 	guint i;
157 
158 	for (i = 0; i < sizeof (timedata) / sizeof (TestTime); i++) {
159 		TestTime td = timedata[i];
160 		GdaTime time;
161 		/*g_print ("[%s]\n", td.in_string);*/
162 		if (gda_parse_iso8601_time (&time, td.in_string) != td.exp_retval) {
163 			g_print ("Wrong result for gda_parse_iso8601_time (\"%s\"): got %s\n",
164 				 td.in_string, td.exp_retval ? "FALSE" : "TRUE");
165 			return FALSE;
166 		}
167 		if ((time.hour != td.exp_time.hour) ||
168 		    (time.minute != td.exp_time.minute) ||
169 		    (time.second != td.exp_time.second) ||
170 		    (time.fraction != td.exp_time.fraction) ||
171 		    (time.timezone != td.exp_time.timezone)) {
172 			g_print ("Wrong result for gda_parse_iso8601_time (\"%s\"):\n"
173 				 "   exp: HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n"
174 				 "   got: HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n",
175 				 td.in_string,
176 				 td.exp_time.hour, td.exp_time.minute, td.exp_time.second,
177 				 td.exp_time.fraction, td.exp_time.timezone,
178 				 time.hour, time.minute, time.second,
179 				 time.fraction, time.timezone);
180 			return FALSE;
181 		}
182 	}
183 	g_print ("All %d iso8601 time parsing tests passed\n", i);
184 
185 	return TRUE;
186 }
187 
188 static gboolean
test_parse_iso8601_timestamp(void)189 test_parse_iso8601_timestamp (void)
190 {
191 	guint idate, itime;
192 
193 	for (idate = 0; idate < sizeof (datedata) / sizeof (TestTime); idate++) {
194 		TestDate td = datedata [idate];
195 		for (itime = 0; itime < sizeof (timedata) / sizeof (TestTime); itime++) {
196 			TestTime tt = timedata[itime];
197 			gchar *str;
198 			str = g_strdup_printf ("%s %s", td.in_string, tt.in_string);
199 
200 			GdaTimestamp timestamp;
201 			gboolean exp_result = td.exp_retval && tt.exp_retval;
202 			/*g_print ("[%s]\n", str);*/
203 			if (gda_parse_iso8601_timestamp (&timestamp, str) != exp_result) {
204 				g_print ("Wrong result for gda_parse_iso8601_timestamp (\"%s\"): got %s\n",
205 					 td.in_string, exp_result ? "FALSE" : "TRUE");
206 				return FALSE;
207 			}
208 
209 			if ((td.exp_retval &&
210 			     ((timestamp.year != td.exp_year) ||
211 			      (timestamp.month != td.exp_month) ||
212 			      (timestamp.day != td.exp_day))) &&
213 			    (((timestamp.hour != tt.exp_time.hour) ||
214 			      (timestamp.minute != tt.exp_time.minute) ||
215 			      (timestamp.second != tt.exp_time.second) ||
216 			      (timestamp.fraction != tt.exp_time.fraction) ||
217 			      (timestamp.timezone != tt.exp_time.timezone)))) {
218 				g_print ("Wrong result for gda_parse_iso8601_timestamp (\"%s\"):\n"
219 					 "   exp: DD=%d MM=%d YYYY=%d HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n"
220 					 "   got: DD=%d MM=%d YYYY=%d HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n",
221 					 str, td.exp_day, td.exp_month, td.exp_year,
222 					 tt.exp_time.hour, tt.exp_time.minute, tt.exp_time.second, tt.exp_time.fraction, tt.exp_time.timezone,
223 					 timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.minute,
224 					 timestamp.second, timestamp.fraction, timestamp.timezone);
225 
226 				g_free (str);
227 				return FALSE;
228 			}
229 			g_free (str);
230 		}
231 	}
232 	g_print ("All %d iso8601 timestamp parsing tests passed\n", idate * itime);
233 
234 	return TRUE;
235 }
236 
237 
238 static gboolean
test_date_handler(void)239 test_date_handler (void)
240 {
241 	GdaDataHandler *dh;
242 	guint i;
243 	dh = gda_handler_time_new_no_locale ();
244 	gda_handler_time_set_str_spec (GDA_HANDLER_TIME (dh),
245 				       G_DATE_YEAR, G_DATE_MONTH, G_DATE_DAY, '-', FALSE);
246 
247 	for (i = 0; i < sizeof (datedata) / sizeof (TestDate); i++) {
248 		TestDate td = datedata[i];
249 		GValue *value;
250 		/*g_print ("[%s]\n", td.in_string);*/
251 
252 		value = gda_data_handler_get_value_from_str (dh, td.in_string, G_TYPE_DATE);
253 		if ((!value && td.exp_retval) ||
254 		    (value && !td.exp_retval)) {
255 			g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", G_TYPE_DATE): got %s\n",
256 				 td.in_string, td.exp_retval ? "FALSE" : "TRUE");
257 			g_object_unref (dh);
258 			return FALSE;
259 		}
260 
261 		if (! td.exp_retval)
262 			continue;
263 		GDate *pdate, date;
264 		pdate = g_value_get_boxed (value);
265 		date = *pdate;
266 		gda_value_free (value);
267 
268 		if ((g_date_get_day (&date) != td.exp_day) ||
269 		    (g_date_get_month (&date) != td.exp_month) ||
270 		    (g_date_get_year (&date) != td.exp_year)) {
271 			g_print ("Wrong result for gda_parse_iso8601_date (\"%s\"):\n"
272 				 "   exp: DD=%d MM=%d YYYY=%d\n"
273 				 "   got: DD=%d MM=%d YYYY=%d\n",
274 				 td.in_string, td.exp_day, td.exp_month, td.exp_year,
275 				 g_date_get_day (&date), g_date_get_month (&date),
276 				 g_date_get_year (&date));
277 			g_object_unref (dh);
278 			return FALSE;
279 		}
280 	}
281 	g_print ("All %d GdaDataHandler (G_TYPE_DATE) parsing tests passed\n", i);
282 	g_object_unref (dh);
283 	return TRUE;
284 }
285 
286 TestTime timedata2[] = {
287 	{"112256", TRUE, {11, 22, 56, 0, GDA_TIMEZONE_INVALID}},
288 	{"012256", TRUE, {1, 22, 56, 0, GDA_TIMEZONE_INVALID}},
289 	{"012260", FALSE, {1, 22, 0, 0, GDA_TIMEZONE_INVALID}},
290 	{"016045", FALSE, {1, 0, 0, 0, GDA_TIMEZONE_INVALID}},
291 	{"242345", FALSE, {0, 0, 0, 0, GDA_TIMEZONE_INVALID}},
292 	{"235959", TRUE, {23, 59, 59, 0, GDA_TIMEZONE_INVALID}},
293 	{"000000", TRUE, {0, 0, 0, 0, GDA_TIMEZONE_INVALID}},
294 	{"120100", TRUE, {12, 1, 0, 0, GDA_TIMEZONE_INVALID}},
295 	{" 120000", FALSE, {0, 0, 0, 0, GDA_TIMEZONE_INVALID}},
296 	{"12 0000", FALSE, {12, 0, 0, 0, GDA_TIMEZONE_INVALID}},
297 	{"12 0000", FALSE, {12, 0, 0, 0, GDA_TIMEZONE_INVALID}},
298 	{"12 0000", FALSE, {12, 0, 0, 0, GDA_TIMEZONE_INVALID}},
299 	{"1201 00", FALSE, {12, 1, 0, 0, GDA_TIMEZONE_INVALID}},
300 	{"120102 ", FALSE, {12, 1, 2, 0, GDA_TIMEZONE_INVALID}},
301 	{"120102.", FALSE, {12, 1, 2, 0, GDA_TIMEZONE_INVALID}},
302 	{"120102:", FALSE, {12, 1, 2, 0, GDA_TIMEZONE_INVALID}},
303 	{"120102.123", TRUE, {12, 1, 2, 123, GDA_TIMEZONE_INVALID}},
304 	{"120102-2", TRUE, {12, 1, 2, 0, -2*60*60}},
305 	{"120102+11", TRUE, {12, 1, 2, 0, 11*60*60}},
306 	{"120102.1234+11", TRUE, {12, 1, 2, 1234, 11*60*60}},
307 	{"120102.12345678-3", TRUE, {12, 1, 2, 12345678, -3*60*60}},
308 };
309 
310 static gboolean
test_time_handler(void)311 test_time_handler (void)
312 {
313 	GdaDataHandler *dh;
314 	guint i, j;
315 	dh = gda_data_handler_get_default (GDA_TYPE_TIME);
316 	g_assert (dh);
317 
318 	for (i = 0; i < sizeof (timedata) / sizeof (TestTime); i++) {
319 		TestTime td = timedata[i];
320 		GValue *value;
321 		/*g_print ("[%s]\n", td.in_string);*/
322 
323 		value = gda_data_handler_get_value_from_str (dh, td.in_string, GDA_TYPE_TIME);
324 		if ((!value && td.exp_retval) ||
325 		    (value && !td.exp_retval)) {
326 			g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIME): got %s\n",
327 				 td.in_string, td.exp_retval ? "FALSE" : "TRUE");
328 			g_object_unref (dh);
329 			return FALSE;
330 		}
331 
332 		if (! td.exp_retval)
333 			continue;
334 		const GdaTime *ptime;
335 		GdaTime time;
336 		ptime = gda_value_get_time (value);
337 		time = *ptime;
338 		gda_value_free (value);
339 
340 		if ((time.hour != td.exp_time.hour) ||
341 		    (time.minute != td.exp_time.minute) ||
342 		    (time.second != td.exp_time.second) ||
343 		    (time.fraction != td.exp_time.fraction) ||
344 		    (time.timezone != td.exp_time.timezone)) {
345 			g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIME):\n"
346 				 "   exp: HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n"
347 				 "   got: HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n",
348 				 td.in_string,
349 				 td.exp_time.hour, td.exp_time.minute, td.exp_time.second,
350 				 td.exp_time.fraction, td.exp_time.timezone,
351 				 time.hour, time.minute, time.second,
352 				 time.fraction, time.timezone);
353 			return FALSE;
354 		}
355 	}
356 
357 	for (j = 0; j < sizeof (timedata2) / sizeof (TestTime); j++) {
358 		TestTime td = timedata2[j];
359 		GValue *value;
360 		/*g_print ("[%s]\n", td.in_string);*/
361 
362 		value = gda_data_handler_get_value_from_str (dh, td.in_string, GDA_TYPE_TIME);
363 		if ((!value && td.exp_retval) ||
364 		    (value && !td.exp_retval)) {
365 			g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIME): got %s\n",
366 				 td.in_string, td.exp_retval ? "FALSE" : "TRUE");
367 			g_object_unref (dh);
368 			return FALSE;
369 		}
370 
371 		if (! td.exp_retval)
372 			continue;
373 		const GdaTime *ptime;
374 		GdaTime time;
375 		ptime = gda_value_get_time (value);
376 		time = *ptime;
377 		gda_value_free (value);
378 
379 		if ((time.hour != td.exp_time.hour) ||
380 		    (time.minute != td.exp_time.minute) ||
381 		    (time.second != td.exp_time.second) ||
382 		    (time.fraction != td.exp_time.fraction) ||
383 		    (time.timezone != td.exp_time.timezone)) {
384 			g_print ("Wrong result forgda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIME):\n"
385 				 "   exp: HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n"
386 				 "   got: HH=%d MM=%d SS=%d FF=%ld TZ=%ld\n",
387 				 td.in_string,
388 				 td.exp_time.hour, td.exp_time.minute, td.exp_time.second,
389 				 td.exp_time.fraction, td.exp_time.timezone,
390 				 time.hour, time.minute, time.second,
391 				 time.fraction, time.timezone);
392 			return FALSE;
393 		}
394 	}
395 
396 	g_print ("All %d GdaDataHandler (GDA_TYPE_TIME) parsing tests passed\n", i + j);
397 	g_object_unref (dh);
398 	return TRUE;
399 }
400 
401 static gboolean
test_timestamp_handler(void)402 test_timestamp_handler (void)
403 {
404 	GdaDataHandler *dh;
405 	guint idate, itime, itime2;
406 	dh = gda_handler_time_new_no_locale ();
407 	gda_handler_time_set_str_spec (GDA_HANDLER_TIME (dh),
408 				       G_DATE_YEAR, G_DATE_MONTH, G_DATE_DAY, '-', FALSE);
409 
410 	for (idate = 0; idate < sizeof (datedata) / sizeof (TestTime); idate++) {
411 		TestDate td = datedata [idate];
412 		for (itime = 0; itime < sizeof (timedata) / sizeof (TestTime); itime++) {
413 			TestTime tt = timedata[itime];
414 			gchar *str;
415 			str = g_strdup_printf ("%s %s", td.in_string, tt.in_string);
416 
417 			GValue *value;
418 			gboolean exp_result = td.exp_retval && tt.exp_retval;
419 			/*g_print ("[%s]\n", str);*/
420 
421 			value = gda_data_handler_get_value_from_str (dh, str, GDA_TYPE_TIMESTAMP);
422 			if ((!value && exp_result) ||
423 			    (value && !exp_result)) {
424 				g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIMESTAMP): got %s\n",
425 					 str, exp_result ? "FALSE" : "TRUE");
426 				g_object_unref (dh);
427 				return FALSE;
428 			}
429 
430 			if (! exp_result) {
431 				g_free (str);
432 				continue;
433 			}
434 			const GdaTimestamp *ptimestamp;
435 			GdaTimestamp timestamp;
436 			ptimestamp = gda_value_get_timestamp (value);
437 			timestamp = *ptimestamp;
438 			gda_value_free (value);
439 
440 			if ((td.exp_retval &&
441 			     ((timestamp.year != td.exp_year) ||
442 			      (timestamp.month != td.exp_month) ||
443 			      (timestamp.day != td.exp_day))) &&
444 			    ((tt.exp_retval) &&
445 			     ((timestamp.hour != tt.exp_time.hour) ||
446 			      (timestamp.minute != tt.exp_time.minute) ||
447 			      (timestamp.second != tt.exp_time.second) ||
448 			      (timestamp.fraction != tt.exp_time.fraction) ||
449 			      (timestamp.timezone != tt.exp_time.timezone)))) {
450 				g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIMESTAMP):\n"
451 					 "   exp: DD=%d MM=%d YYYY=%d HH=%d MM=%d SS=%d FF=%ld TZ=%ld\\n"
452 					 "   got: DD=%d MM=%d YYYY=%d HH=%d MM=%d SS=%d FF=%ld TZ=%ld\\n",
453 					 str, td.exp_day, td.exp_month, td.exp_year,
454 					 tt.exp_time.hour, tt.exp_time.minute, tt.exp_time.second, tt.exp_time.fraction, tt.exp_time.timezone,
455 					 timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.minute,
456 					 timestamp.second, timestamp.fraction, timestamp.timezone);
457 
458 				g_object_unref (dh);
459 				g_free (str);
460 				return FALSE;
461 			}
462 			g_free (str);
463 		}
464 	}
465 
466 	for (idate = 0; idate < sizeof (datedata) / sizeof (TestTime); idate++) {
467 		TestDate td = datedata [idate];
468 		for (itime2 = 0; itime2 < sizeof (timedata2) / sizeof (TestTime); itime2++) {
469 			TestTime tt = timedata2[itime2];
470 			gchar *str;
471 			str = g_strdup_printf ("%s %s", td.in_string, tt.in_string);
472 
473 			GValue *value;
474 			gboolean exp_result = td.exp_retval && tt.exp_retval;
475 			/*g_print ("[%s]\n", str);*/
476 
477 			value = gda_data_handler_get_value_from_str (dh, str, GDA_TYPE_TIMESTAMP);
478 			if ((!value && exp_result) ||
479 			    (value && !exp_result)) {
480 				g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIMESTAMP): got %s\n",
481 					 str, exp_result ? "FALSE" : "TRUE");
482 				g_object_unref (dh);
483 				return FALSE;
484 			}
485 
486 			if (! exp_result) {
487 				g_free (str);
488 				continue;
489 			}
490 			const GdaTimestamp *ptimestamp;
491 			GdaTimestamp timestamp;
492 			ptimestamp = gda_value_get_timestamp (value);
493 			timestamp = *ptimestamp;
494 			gda_value_free (value);
495 
496 			if ((timestamp.year != td.exp_year) ||
497 			    (timestamp.month != td.exp_month) ||
498 			    (timestamp.day != td.exp_day) ||
499 			    (timestamp.hour != tt.exp_time.hour) ||
500 			    (timestamp.minute != tt.exp_time.minute) ||
501 			    (timestamp.second != tt.exp_time.second) ||
502 			    (timestamp.fraction != tt.exp_time.fraction) ||
503 			    (timestamp.timezone != tt.exp_time.timezone)) {
504 				g_print ("Wrong result for gda_data_handler_get_value_from_str (\"%s\", GDA_TYPE_TIMESTAMP):\n"
505 					 "   exp: DD=%d MM=%d YYYY=%d HH=%d MM=%d SS=%d FF=%ld TZ=%ld\\n"
506 					 "   got: DD=%d MM=%d YYYY=%d HH=%d MM=%d SS=%d FF=%ld TZ=%ld\\n",
507 					 str, td.exp_day, td.exp_month, td.exp_year,
508 					 tt.exp_time.hour, tt.exp_time.minute, tt.exp_time.second, tt.exp_time.fraction, tt.exp_time.timezone,
509 					 timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.minute,
510 					 timestamp.second, timestamp.fraction, timestamp.timezone);
511 
512 				g_object_unref (dh);
513 				g_free (str);
514 				return FALSE;
515 			}
516 			g_free (str);
517 		}
518 	}
519 
520 	g_print ("All %d GdaDataHandler (GDA_TYPE_TIMESTAMP) parsing tests passed\n", idate * (itime + itime2));
521 	g_object_unref (dh);
522 	return TRUE;
523 }
524