Add additional tests for GetTimeFormat() and GetDateFormat().
[wine] / dlls / kernel / tests / locale.c
1 /*
2  * Very basic unit test for locale functions
3  * Test run on win2K (French)
4  *
5  * Copyright (c) 2002 YASAR Mehmet
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "wine/test.h"
23 #include "winbase.h"
24 #include "winerror.h"
25 #include "winnls.h"
26
27 #define eq(received, expected, label, type) \
28         ok((received) == (expected), "%s: got " type " instead of " type, (label),(received),(expected))
29
30 #define BUFFER_SIZE             128
31 /* Buffer used by callback function */
32 char GlobalBuffer[BUFFER_SIZE];
33 #define COUNTOF(x) (sizeof(x)/sizeof(x)[0])
34
35 /* TODO :
36  * Unicode versions
37  * EnumTimeFormatsA
38  * EnumDateFormatsA
39  * LCMapStringA
40  * GetUserDefaultLangID
41  * ...
42  */
43
44 void TestGetLocaleInfoA()
45 {
46         int ret, cmp;
47         LCID lcid;
48         char buffer[BUFFER_SIZE], Expected[BUFFER_SIZE];
49
50         strcpy(Expected, "Monday");
51         lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
52         ok (lcid == 0x409, "wrong LCID calculated");
53
54         /* HTMLKit and "Font xplorer lite" expect GetLocaleInfoA to
55         * partially fill the buffer even if it is too short. See bug 637.
56         */
57         strcpy(Expected, "xxxxx");
58         memset( buffer, 'x', sizeof(buffer) );
59         ret = GetLocaleInfoA(lcid, LOCALE_SDAYNAME1, buffer, 0);
60         cmp = strncmp (buffer, Expected, strlen(Expected));
61         ok (cmp == 0, "GetLocaleInfoA got %s instead of %s", buffer, Expected);
62         eq (ret, lstrlenA("Monday") + 1, "GetLocaleInfoA with len=0", "%d");
63
64         strcpy(Expected, "Monxx");
65         memset( buffer, 'x', sizeof(buffer) );
66         ret = GetLocaleInfoA(lcid, LOCALE_SDAYNAME1, buffer, 3);
67         cmp = strncmp (buffer, Expected, strlen(Expected));
68         ok (cmp == 0, "GetLocaleInfoA got %s instead of %s", buffer, Expected);
69         eq (ret, 0, "GetLocaleInfoA with len = 3", "%d");
70
71         strcpy(Expected, "Monday");
72         memset( buffer, 'x', sizeof(buffer) );
73         ret = GetLocaleInfoA(lcid, LOCALE_SDAYNAME1, buffer, 10);
74         /* We check also presence of '\0' */
75         cmp = strncmp (buffer, Expected, strlen(Expected) + 1);
76         ok (cmp == 0, "GetLocaleInfoA got %s instead of %s", buffer, Expected);
77         eq (ret, lstrlenA(Expected)+1, "GetLocaleInfoA with len = 10", "%d" );
78
79         /* We check the whole buffer with strncmp */
80         memset( Expected, 'x', sizeof(Expected) );
81         strcpy(Expected, "Monday");
82         memset( buffer, 'x', sizeof(buffer) );
83         ret = GetLocaleInfoA(lcid, LOCALE_SDAYNAME1, buffer, BUFFER_SIZE);
84         cmp = strncmp (buffer, Expected, BUFFER_SIZE);
85         ok (cmp == 0, "GetLocaleInfoA got %s instead of %s", buffer, Expected);
86         eq (ret, lstrlenA(Expected)+1, "GetLocaleInfoA with len = 10", "%d" );
87
88 }
89
90
91 void TestGetTimeFormatA()
92 {
93   int ret, error, cmp;
94   SYSTEMTIME  curtime;
95   char buffer[BUFFER_SIZE], format[BUFFER_SIZE], Expected[BUFFER_SIZE];
96   LCID lcid;
97
98   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
99   strcpy(format, "tt HH':'mm'@'ss");
100
101   /* fill curtime with dummy data */
102   memset(&curtime, 2, sizeof(SYSTEMTIME));
103   memset(buffer, '0', sizeof(buffer));
104   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, format, buffer, COUNTOF(buffer));
105   error = GetLastError ();
106   ok (ret == 0, "GetTimeFormat should fail on dummy data");
107   eq (error, ERROR_INVALID_PARAMETER, "GetTimeFormat GetLastError()", "%d");
108   SetLastError(NO_ERROR);   /* clear out the last error */
109
110   /* test that we can correctly produce the expected output, not a very */
111   /* demanding test ;-) */
112   strcpy(Expected, "AM 08:56@13");
113   curtime.wHour = 8;  curtime.wMinute = 56;
114   curtime.wSecond = 13; curtime.wMilliseconds = 22;
115   memset(buffer, '0', sizeof(buffer));
116   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, format, buffer, COUNTOF(buffer));
117   cmp = strncmp (Expected, buffer, strlen(Expected)+1);
118   ok (cmp == 0, "GetTimeFormat got %s instead of %s", buffer, Expected);
119   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
120
121   /* check that the size reported by the above call is accuate */
122   memset(buffer, 'x', sizeof(buffer));
123   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, format, buffer, ret);
124   ok(ret==lstrlenA(Expected)+1 && GetLastError()==0,
125            "GetTimeFormat(right size): ret=%d error=%ld\n",ret,GetLastError());
126   ok(buffer[0] != 'x',"GetTimeFormat(right size): buffer=[%s]\n",buffer);
127
128   /* test failure due to insufficent buffer */
129   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, format, buffer, 2);
130   ok(ret==0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER,
131            "GetTimeFormat(len=2): ret=%d error=%ld", ret, GetLastError());
132
133   /* test with too small buffers */
134   SetLastError(0);
135   memset(buffer, '0', sizeof(buffer));
136   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, format, NULL, 0);
137   ok(ret==lstrlenA(Expected)+1 && GetLastError()==0,
138            "GetTimeFormat(len=0): ret=%d error=%ld\n",ret,GetLastError());
139
140   /************************************/
141   /* test out TIME_NOMINUTESORSECONDS */
142   strcpy(Expected, "8 AM");
143   memset(buffer, '0', sizeof(buffer));
144   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, TIME_NOMINUTESORSECONDS, &curtime, NULL, buffer, sizeof(buffer));
145   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
146   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
147   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
148
149   /* test out TIME_NOMINUTESORSECONDS with complex format strings */
150   strcpy(Expected, "4");
151   memset(buffer, '0', sizeof(buffer));
152   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, TIME_NOMINUTESORSECONDS, &curtime, "m1s2m3s4", buffer, sizeof(buffer));
153   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
154   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
155   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
156
157
158   /************************************/
159   /* test out TIME_NOSECONDS */
160   strcpy(Expected, "8:56 AM");
161   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, TIME_NOSECONDS, &curtime, NULL, buffer, sizeof(buffer));
162   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
163   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
164   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
165
166   /* test out TIME_NOSECONDS with a format string of "h:m:s tt" */
167   strcpy(Expected, "8:56 AM");
168   memset(buffer, '0', sizeof(buffer));
169   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, TIME_NOSECONDS, &curtime, "h:m:s tt", buffer, sizeof(buffer));
170   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
171   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
172   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
173
174   /* test out TIME_NOSECONDS a strange format string of multiple delimiters "h@:m@:s tt" */
175   /* expected behavior is to turn "hD1D2...mD3D4...sD5D6...tt" and turn this into */
176   /* "hD1D2...mD3D4...tt" */
177   strcpy(Expected, "8.@:56.@:AM");
178   memset(buffer, '0', sizeof(buffer));
179   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, TIME_NOSECONDS, &curtime, "h.@:m.@:s.@:tt", buffer, sizeof(buffer));
180   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
181   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
182   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
183
184   /* test out TIME_NOSECONDS with an string of "1s2s3s4" */
185   /* expect to see only "3" */
186   strcpy(Expected, "3");
187   memset(buffer, '0', sizeof(buffer));
188   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, TIME_NOSECONDS, &curtime, "s1s2s3", buffer, sizeof(buffer));
189   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
190   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
191   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
192
193   /************************/
194   /* Test out time marker */
195   /* test out time marker(AM/PM) behavior */
196   strcpy(Expected, "A/AM");
197   memset(buffer, '0', sizeof(buffer));
198   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "t/tt", buffer, sizeof(buffer));
199   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
200   ok (cmp == 0, "GetTimeFormat got '%s' instead of %s", buffer, Expected);
201   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
202
203   /* time marker testing part 2 */
204   curtime.wHour = 13;
205   strcpy(Expected, "P/PM");
206   memset(buffer, '0', sizeof(buffer));
207   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "t/tt", buffer, sizeof(buffer));
208   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
209   ok (cmp == 0, "GetTimeFormat got '%s' instead of %s", buffer, Expected);
210   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
211
212   /******************************/
213   /* test out TIME_NOTIMEMARKER */
214   /* NOTE: TIME_NOTIMEMARKER elminates all text around any time marker */
215   /*      formatting character until the previous or next formatting character */
216   strcpy(Expected, "156");
217   memset(buffer, '0', sizeof(buffer));
218   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, TIME_NOTIMEMARKER, &curtime, "h1t2tt3m", buffer, sizeof(buffer));
219   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
220   ok (cmp == 0, "GetTimeFormat got '%s' instead of %s", buffer, Expected);
221   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
222
223   /***********************************/
224   /* test out TIME_FORCE24HOURFORMAT */
225   strcpy(Expected, "13:56:13 PM");
226   memset(buffer, '0', sizeof(buffer));
227   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT, &curtime, "h:m:s tt", buffer, sizeof(buffer));
228   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
229   ok (cmp == 0, "GetTimeFormat got '%s' instead of %s", buffer, Expected);
230   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
231
232   /* check to confirm that unlike what msdn documentation suggests, the time marker */
233   /* is not added under TIME_FORCE24HOURFORMAT */
234   strcpy(Expected, "13:56:13");
235   memset(buffer, '0', sizeof(buffer));
236   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT, &curtime, "h:m:s", buffer, sizeof(buffer));
237   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
238   ok (cmp == 0, "GetTimeFormat got '%s' instead of %s", buffer, Expected);
239   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
240
241
242   /*********************************************/
243   /* test advanced formatting of GetTimeFormat */
244
245   /* test for 24 hour conversion and for leading zero */
246   /* NOTE: we do not test the "hh or HH" case since hours is two digits */
247   /* "h hh H HH m mm s ss t tt" */
248   curtime.wHour = 14; /* change this to 14 or 2pm */
249   curtime.wMinute = 5;
250   curtime.wSecond = 3;
251   strcpy(Expected, "2 02 14 14 5 05 3 03 P PM");
252   memset(buffer, '0', sizeof(buffer));
253   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "h hh H HH m mm s ss t tt", buffer, sizeof(buffer));
254   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
255   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
256   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
257
258   /* complete testing on the advanced formatting by testing "hh" and "HH" */
259   /* 0 hour is 12 o'clock or 00 hundred hours */
260   curtime.wHour = 0;
261   strcpy(Expected, "12/0/12/00");
262   memset(buffer, '0', sizeof(buffer));
263   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "h/H/hh/HH", buffer, sizeof(buffer));
264   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
265   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
266   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
267
268   /* test for LOCALE_NOUSEROVERRIDE set, lpFormat must be NULL */
269   strcpy(Expected, "0:5:3 AM");
270   memset(buffer, '0', sizeof(buffer));
271   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, LOCALE_NOUSEROVERRIDE, &curtime, "h:m:s tt", buffer, sizeof(buffer));
272   /* NOTE: we expect this to FAIL */
273   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
274   ok (ret == 0, "GetTimeFormat succeeded instead of failing for LOCALE_NOUSEROVERRIDE and a non-null lpFormat\n");
275
276   /* try to convert formatting strings with more than two letters */
277   /* "h:hh:hhh:H:HH:HHH:m:mm:mmm:M:MM:MMM:s:ss:sss:S:SS:SSS" */
278   /* NOTE: we expect any letter for which there is an upper case value */
279   /*    we should expect to see a replacement.  For letters that DO NOT */
280   /*    have upper case values we expect to see NO REPLACEMENT */
281   curtime.wHour = 8;  curtime.wMinute = 56;
282   curtime.wSecond = 13; curtime.wMilliseconds = 22;
283   strcpy(Expected, "8:08:08 8:08:08 56:56:56 M:MM:MMM 13:13:13 S:SS:SSS");
284   memset(buffer, '0', sizeof(buffer));
285   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "h:hh:hhh H:HH:HHH m:mm:mmm M:MM:MMM s:ss:sss S:SS:SSS", buffer, sizeof(buffer));
286   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
287   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
288   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
289
290   /* test that if the size of the buffer is zero that the buffer is not modified */
291   /* and that the number of necessary characters is returned */
292   /* NOTE: The count includes the terminating null. */
293   strcpy(buffer, "THIS SHOULD NOT BE MODIFIED");
294   strcpy(Expected, "THIS SHOULD NOT BE MODIFIED");
295   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "h", buffer, 0);
296   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
297   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
298   eq (ret, 2, "GetTimeFormat", "%d"); /* we expect to require two characters of space from "h" */
299
300   /* test that characters in single quotation marks are ignored and left in */
301   /* the same location in the output string */
302   strcpy(Expected, "8 h 8 H 08 HH 56 m 13 s A t AM tt");
303   memset(buffer, '0', sizeof(buffer));
304   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "h 'h' H 'H' HH 'HH' m 'm' s 's' t 't' tt 'tt'", buffer, sizeof(buffer));
305   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
306   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
307   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
308
309   /* test the printing of the single quotation marks when */
310   /* we use an invalid formatting string of "'''" instead of "''''" */
311   strcpy(Expected, "'");
312   memset(buffer, '0', sizeof(buffer));
313   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "'''", buffer, sizeof(buffer));
314   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
315   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
316   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
317
318   /* test that msdn suggested single quotation usage works as expected */
319   strcpy(Expected, "'");
320   memset(buffer, '0', sizeof(buffer));
321   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "''''", buffer, sizeof(buffer));
322   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
323   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
324   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
325
326   /* test for more normal use of single quotation mark */
327   strcpy(Expected, "08");
328   memset(buffer, '0', sizeof(buffer));
329   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "''HHHHHH", buffer, sizeof(buffer));
330   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
331   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
332   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
333
334   /* and test for normal use of the single quotation mark */
335   strcpy(Expected, "'HHHHHH");
336   memset(buffer, '0', sizeof(buffer));
337   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "'''HHHHHH'", buffer, sizeof(buffer));
338   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
339   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
340   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
341
342   /* test for more odd use of the single quotation mark */
343   strcpy(Expected, "'HHHHHH");
344   memset(buffer, '0', sizeof(buffer));
345   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "'''HHHHHH", buffer, sizeof(buffer));
346   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
347   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
348   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
349
350   /* test that with TIME_NOTIMEMARKER that even if something is defined */
351   /* as a literal we drop it before and after the markers until the next */
352   /* formatting character */
353   strcpy(Expected, "");
354   memset(buffer, '0', sizeof(buffer));
355   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, TIME_NOTIMEMARKER, &curtime, "'123'tt", buffer, sizeof(buffer));
356   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
357   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
358   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
359
360   /* test for expected return and error value when we have a */
361   /* non-null format and LOCALE_NOUSEROVERRIDE for flags */
362   SetLastError(NO_ERROR); /* reset last error value */
363   memset(buffer, '0', sizeof(buffer));
364   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, LOCALE_NOUSEROVERRIDE, &curtime, "'123'tt", buffer, sizeof(buffer));
365   error = GetLastError();
366   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
367   ok ((ret == 0) && (error == ERROR_INVALID_FLAGS), "GetTimeFormat got ret of '%d' and error of '%d'", ret, error);
368
369   /* test that invalid time values result in ERROR_INVALID_PARAMETER */
370   /* and a return value of 0 */
371   curtime.wHour = 25;
372   SetLastError(NO_ERROR); /* reset last error value */
373   memset(buffer, '0', sizeof(buffer));
374   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "'123'tt", buffer, sizeof(buffer));
375   error = GetLastError();
376   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
377   ok ((ret == 0) && (error == ERROR_INVALID_PARAMETER), "GetTimeFormat got ret of '%d' and error of '%d'", ret, error);
378
379   /* test that invalid information in the date section of the current time */
380   /* doesn't result in an error since GetTimeFormat() should ignore this information */
381   curtime.wHour = 12; /* valid wHour */
382   curtime.wMonth = 60; /* very invalid wMonth */
383   strcpy(Expected, "12:56:13");
384   SetLastError(NO_ERROR); /* reset last error value */
385   ret = GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &curtime, "h:m:s", buffer, sizeof(buffer));
386   error = GetLastError();
387   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
388   ok ((ret == lstrlenA(Expected)+1) && (error == NO_ERROR), "GetTimeFormat got ret of '%d' and error of '%d' and a buffer of '%s'", ret, error, buffer);
389 }
390
391 void TestGetDateFormatA()
392 {
393   int ret, error, cmp;
394   SYSTEMTIME  curtime;
395   char buffer[BUFFER_SIZE], format[BUFFER_SIZE], Expected[BUFFER_SIZE];
396   LCID lcid;
397
398   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
399   strcpy(format, "ddd',' MMM dd yy");
400
401   /* test for failure on dummy data */
402   memset(&curtime, 2, sizeof(SYSTEMTIME));
403   memset(buffer, '0', sizeof(buffer));
404   SetLastError(NO_ERROR);
405   ret = GetDateFormatA(lcid, 0, &curtime, format, buffer, COUNTOF(buffer));
406   error = GetLastError ();
407   ok(ret == 0, "GetDateFormat should fail on dummy data");
408   eq(error, ERROR_INVALID_PARAMETER, "GetDateFormat", "%d");
409
410   /* test for a simple case of date conversion */
411   todo_wine {
412     strcpy(Expected, "Sat, May 04 02");
413     curtime.wYear = 2002;
414     curtime.wMonth = 5;
415     curtime.wDay = 4;
416     curtime.wDayOfWeek = 3;
417     memset(buffer, 0, sizeof(buffer));
418     ret = GetDateFormatA(lcid, 0, &curtime, format, buffer, COUNTOF(buffer));
419     cmp = strncmp (Expected, buffer, strlen(Expected)+1);
420     ok (cmp == 0, "GetDateFormat got %s instead of %s", buffer, Expected);
421 /* Uncomment the below when todo_wine is removed */
422 /*    eq (ret, lstrlenA(Expected)+1, "GetDateFormat", "%d"); */
423   }
424
425   /* test format with "'" */
426   todo_wine {
427     strcpy(format, "ddd',' MMM dd ''''yy");
428     strcpy(Expected, "Sat, May 04 '02");
429     memset(buffer, 0, sizeof(buffer));
430     ret = GetDateFormatA(lcid, 0, &curtime, format, buffer, COUNTOF(buffer));
431     cmp = strncmp (Expected, buffer, strlen(Expected)+1);
432     ok (cmp == 0, "GetDateFormat got %s instead of %s", buffer, Expected);
433 /* Uncomment the below when todo_wine is removed */
434 /*    eq (ret, lstrlenA(Expected)+1, "GetDateFormat", "%d"); */
435   }
436
437   /* test for success with dummy time data */
438   todo_wine {
439     curtime.wHour = 36;
440     memset(buffer, 0, sizeof(buffer));
441     ret = GetDateFormatA(lcid, 0, &curtime, format, buffer, COUNTOF(buffer));
442     cmp = strncmp (Expected, buffer, strlen(Expected)+1);
443     ok (cmp == 0, "GetDateFormat got %s instead of %s", buffer, Expected);
444 /* Uncomment the below when the todo_wine is removed */
445 /*    eq (ret, lstrlenA(Expected)+1, "GetDateFormat", "%d"); */
446   }
447
448   /* test that we retrieve the expected size for the necessary output of this string */
449   SetLastError(NO_ERROR);
450   memset(buffer, 0, sizeof(buffer));
451   ret = GetDateFormatA(lcid, 0, &curtime, format, NULL, 0);
452   ok(ret==lstrlenA(Expected)+1 && GetLastError() == 0,
453           "GetDateFormat(len=0): ret=%d error=%ld buffer='%s', expected NO_ERROR(0)\n",ret,GetLastError(), buffer);
454
455   /* test that the expected size matches the actual required size by passing */
456   /* in the expected size */
457   memset(buffer, '0', sizeof(buffer));
458   ret = GetDateFormatA(lcid, 0, &curtime, format, buffer, ret);
459   ok(ret==lstrlenA(Expected)+1 && GetLastError()==0,
460            "GetDateFormat(right size): ret=%d error=%ld, buffer = '%s'\n",ret,GetLastError(), buffer);
461   ok(buffer[0]!='x',"GetDateFormat(right size): buffer=[%s]\n",buffer);
462
463   /* test that a buffer shorter than the necessary size results in ERROR_INSUFFICIENT_BUFFER */
464   ret = GetDateFormatA(lcid, 0, &curtime, format, buffer, 2);
465   ok(ret==0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER,
466            "GetDateFormat(len=2): ret=%d error=%ld", ret, GetLastError());
467
468   /* test for default behavior being DATE_SHORTDATE */
469   todo_wine {
470     strcpy(Expected, "5/4/02");
471     memset(buffer, '0', sizeof(buffer));
472     ret = GetDateFormat(lcid, 0, &curtime, NULL, buffer, sizeof(buffer));
473     cmp = strncmp (Expected, buffer, strlen(Expected)+1);
474     ok (cmp == 0, "GetDateFormat got '%s' instead of '%s'", buffer, Expected);
475     eq (ret, lstrlenA(Expected)+1, "GetDateFormat", "%d");
476   }
477
478
479   todo_wine {
480     /* test for expected DATE_LONGDATE behavior with null format */
481     strcpy(Expected, "Saturday, May 04, 2002");
482     memset(buffer, '0', sizeof(buffer));
483     ret = GetDateFormat(lcid, DATE_LONGDATE, &curtime, NULL, buffer, sizeof(buffer));
484     cmp = strncmp (Expected, buffer, strlen(Expected)+1);
485     ok (cmp == 0, "GetDateFormat got '%s' instead of '%s'", buffer, Expected);
486     eq (ret, lstrlenA(Expected)+1, "GetDateFormat", "%d");
487   }
488
489   /* test for expected DATE_YEARMONTH behavior with null format */
490   /* NT4 returns ERROR_INVALID_FLAGS for DATE_YEARMONTH */
491   todo_wine {
492     strcpy(Expected, "");
493     buffer[0] = 0;
494     SetLastError(NO_ERROR);
495     memset(buffer, '0', sizeof(buffer));
496     ret = GetDateFormat(lcid, DATE_YEARMONTH, &curtime, NULL, buffer, sizeof(buffer));
497     error = GetLastError();
498     cmp = strncmp (Expected, buffer, strlen(Expected)+1);
499     ok (ret == 0 && (error == ERROR_INVALID_FLAGS), "GetDateFormat check DATE_YEARMONTH with null format expected ERROR_INVALID_FLAGS got return of '%d' and error of '%d'", ret, error);
500   }
501
502   /* Test that using invalid DATE_* flags results in the correct error */
503   /* and return values */
504   strcpy(format, "m/d/y");
505   strcpy(Expected, "Saturday May 2002");
506   SetLastError(NO_ERROR);
507   memset(buffer, '0', sizeof(buffer));
508   ret = GetDateFormat(lcid, DATE_YEARMONTH | DATE_SHORTDATE | DATE_LONGDATE, &curtime, format, buffer, sizeof(buffer));
509   error = GetLastError();
510   cmp = strncmp (Expected, buffer, strlen(Expected)+1);
511   ok ((ret == 0) && (error == ERROR_INVALID_FLAGS), "GetDateFormat checking for mutually exclusive flags got '%s' instead of '%s', got error of %d, expected ERROR_INVALID_FLAGS", buffer, Expected, error);
512 }
513
514 void TestGetDateFormatW()
515 {
516     int ret, error, cmp;
517     SYSTEMTIME  curtime;
518     WCHAR buffer[BUFFER_SIZE], format[BUFFER_SIZE], Expected[BUFFER_SIZE];
519     LCID lcid;
520
521     lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
522
523     /* 1. Error cases */
524
525     /* 1a If flags is not zero then format must be null. */
526     ret = GetDateFormatW (LOCALE_SYSTEM_DEFAULT, DATE_LONGDATE, NULL, format, buffer, COUNTOF(buffer));
527     if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
528         return;
529     error = ret ? 0 : GetLastError();
530     ok (ret == 0 && error == ERROR_INVALID_FLAGS, "GetDateFormatW allowed flags and format");
531
532     /* 1b The buffer can only be null if the count is zero */
533     /* For the record other bad pointers result in a page fault (Win98) */
534     ret = GetDateFormatW (LOCALE_SYSTEM_DEFAULT, 0, NULL, format, NULL, COUNTOF(buffer));
535     error = ret ? 0 : GetLastError();
536     ok (ret == 0 && error == ERROR_INVALID_PARAMETER, "GetDateFormatW did not detect null buffer pointer.");
537     ret = GetDateFormatW (LOCALE_SYSTEM_DEFAULT, 0, NULL, format, NULL, 0);
538     error = ret ? 0 : GetLastError();
539     ok (ret != 0 && error == 0, "GetDateFormatW did not permit null buffer pointer when counting.");
540
541     /* 1c An incorrect day of week is corrected. */
542     curtime.wYear = 2002;
543     curtime.wMonth = 10;
544     curtime.wDay = 23;
545     curtime.wDayOfWeek = 5; /* should be 3 - Wednesday */
546     curtime.wHour = 0;
547     curtime.wMinute = 0;
548     curtime.wSecond = 0;
549     curtime.wMilliseconds = 234;
550     MultiByteToWideChar (CP_ACP, 0, "dddd d MMMM yyyy", -1, format, COUNTOF(format));
551     ret = GetDateFormatW (lcid, 0, &curtime, format, buffer, COUNTOF(buffer));
552     error = ret ? 0 : GetLastError();
553     MultiByteToWideChar (CP_ACP, 0, "Wednesday 23 October 2002", -1, Expected, COUNTOF(Expected));
554     cmp = ret ? lstrcmpW (buffer, Expected) : 2;
555     ok (ret == lstrlenW(Expected)+1 && error == 0 && cmp == 0, "Day of week correction failed\n");
556 }
557
558
559 void TestGetCurrencyFormat()
560 {
561 int ret, error, cmp;
562 char buffer[BUFFER_SIZE], Expected[BUFFER_SIZE], format[BUFFER_SIZE];
563 LCID lcid;
564
565         lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
566 #if 0
567         lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT );
568 #endif
569
570         memset( buffer, 'x', sizeof(buffer) );
571         ret = GetCurrencyFormatA(lcid, 0, "23,65", NULL, buffer, COUNTOF(buffer));
572         error = GetLastError ();
573         cmp = strncmp ("xxxx", buffer, 4);
574
575         ok (cmp == 0, "GetCurrencyFormat should fail with ','");
576         eq (ret, 0, "GetCurrencyFormat with ','", "%d");
577         eq (error, ERROR_INVALID_PARAMETER, "GetCurrencyFormat", "%d");
578
579         /* We check the whole buffer with strncmp */
580         strcpy (Expected, "$23.53");
581         strcpy (format, "23.53");
582         memset( buffer, 'x', sizeof(buffer) );
583         ret = GetCurrencyFormatA(lcid, 0, format, NULL, buffer, COUNTOF(buffer));
584         cmp = strncmp (Expected, buffer, BUFFER_SIZE);
585         ok (cmp == 0, "GetCurrencyFormatA got %s instead of %s", buffer, Expected);
586         eq (ret, lstrlenA(Expected)+1, "GetCurrencyFormatA","%d");
587
588         /* Test too small buffers */
589         SetLastError(0);
590         ret = GetCurrencyFormatA(lcid, 0, format, NULL, NULL, 0);
591         ok(ret==lstrlenA(Expected)+1 && GetLastError()==0,
592        "GetCurrencyFormatA(size=0): ret=%d error=%ld", ret, GetLastError());
593
594         memset( buffer, 'x', sizeof(buffer) );
595         ret = GetCurrencyFormatA(lcid, 0, format, NULL, buffer, ret);
596         ok(strcmp(buffer,Expected)==0,
597            "GetCurrencyFormatA(right size): got [%s] instead of [%s]", buffer, Expected);
598         eq (ret, lstrlenA(Expected)+1, "GetCurrencyFormatA(right size)", "%d");
599
600         ret = GetCurrencyFormatA(lcid, 0, format, NULL, buffer, 2);
601         ok(ret==0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER,
602            "GetCurrencyFormatA(size=2): ret=%d error=%ld", ret, GetLastError());
603 }
604
605
606 void TestGetNumberFormat()
607 {
608 int ret, error, cmp;
609 char buffer[BUFFER_SIZE], Expected[BUFFER_SIZE], input[BUFFER_SIZE];
610 LCID lcid;
611 NUMBERFMTA format;
612
613         lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
614
615         memset( buffer, 'x', sizeof(buffer) );
616         ret = GetNumberFormatA(lcid, 0, "23,65", NULL, buffer, COUNTOF(buffer));
617         error = GetLastError ();
618         cmp = strncmp ("xxx", buffer, 3);
619         ok (cmp == 0, "GetNumberFormat");
620         ok (ret == 0, "GetNumberFormat should return 0");
621         eq (error, ERROR_INVALID_PARAMETER, "GetNumberFormat", "%d");
622
623         strcpy(input, "2353");
624         strcpy(Expected, "2,353.00");
625         SetLastError(0);
626         ret = GetNumberFormatA(lcid, 0, input, NULL, NULL, 0);
627         ok(ret==lstrlenA(Expected)+1 && GetLastError()==0,
628        "GetNumberFormatA(size=0): ret=%d error=%ld", ret, GetLastError());
629
630         memset( buffer, 'x', sizeof(buffer) );
631         ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, ret);
632         ok(strcmp(buffer,Expected)==0,
633            "GetNumberFormatA(right size): got [%s] instead of [%s]", buffer, Expected);
634         eq(ret, lstrlenA(Expected)+1, "GetNumberFormat", "%d");
635
636         ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, 2);
637         ok(ret==0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER,
638            "GetNumberFormatA(size=2): ret=%d error=%ld", ret, GetLastError());
639
640         /* We check the whole buffer with strncmp */
641         memset(Expected, 'x', sizeof(Expected) );
642         strcpy(Expected, "2,353.00");
643         memset( buffer, 'x', sizeof(buffer) );
644         ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
645         cmp = strncmp (Expected, buffer, BUFFER_SIZE);
646         ok (cmp == 0, "GetNumberFormat got %s instead of %s", buffer, Expected);
647         eq (ret, lstrlenA(Expected)+1, "GetNumberFormat", "%d");
648
649         /* If the number of decimals is zero there should be no decimal
650          * separator.
651          * If the grouping size is zero there should be no grouping symbol
652          */
653         format.NumDigits = 0;
654         format.LeadingZero = 0;
655         format.Grouping = 0;
656         format.NegativeOrder = 0;
657         format.lpDecimalSep = ".";
658         format.lpThousandSep = ",";
659         strcpy (Expected, "123456789");
660         memset( buffer, 'x', sizeof(buffer) );
661         ret = GetNumberFormatA (0, 0, "123456789.0", &format, buffer, COUNTOF(buffer));
662         cmp = strncmp (Expected, buffer, sizeof(buffer));
663         ok (cmp == 0, "GetNumberFormat got %s instead of %s", buffer, Expected);
664
665 }
666
667
668 /* Callback function used by TestEnumTimeFormats */
669 BOOL CALLBACK EnumTimeFormatsProc(char * lpTimeFormatString)
670 {
671         trace("%s\n", lpTimeFormatString);
672         strcpy(GlobalBuffer, lpTimeFormatString);
673 #if 0
674         return TRUE;
675 #endif
676         return FALSE;
677 }
678
679 void TestEnumTimeFormats()
680 {
681 int ret;
682 LCID lcid;
683 char Expected[BUFFER_SIZE];
684
685         lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
686         memset( GlobalBuffer, 'x', sizeof(GlobalBuffer) );
687         strcpy(Expected, "h:mm:ss tt");
688         ret = EnumTimeFormatsA(EnumTimeFormatsProc, lcid, 0);
689
690         eq (ret, 1, "EnumTimeFormats should return 1", "%d");
691         ok (strncmp (GlobalBuffer, Expected, strlen(Expected)) == 0,
692                                 "EnumTimeFormats failed");
693         ok (ret == 1, "EnumTimeFormats should return 1");
694 }
695
696
697 void TestCompareStringA()
698 {
699 int ret;
700 LCID lcid;
701 char buffer1[BUFFER_SIZE], buffer2[BUFFER_SIZE];
702
703         lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT );
704
705         strcpy(buffer1, "Salut"); strcpy(buffer2, "Salute");
706         ret = CompareStringA(lcid, NORM_IGNORECASE, buffer1, -1, buffer2, -1);
707         ok (ret== 1, "CompareStringA (st1=%s str2=%s) expected result=1", buffer1, buffer2);
708
709         strcpy(buffer1, "Salut"); strcpy(buffer2, "saLuT");
710         ret = CompareStringA(lcid, NORM_IGNORECASE, buffer1, -1, buffer2, -1);
711         ok (ret== 2, "CompareStringA (st1=%s str2=%s) expected result=2", buffer1, buffer2);
712
713         strcpy(buffer1, "Salut"); strcpy(buffer2, "hola");
714         ret = CompareStringA(lcid, NORM_IGNORECASE, buffer1, -1, buffer2, -1);
715         ok (ret== 3, "CompareStringA (st1=%s str2=%s) expected result=3", buffer1, buffer2);
716
717         strcpy(buffer1, "héhé"); strcpy(buffer2, "hèhè");
718         ret = CompareStringA(lcid, NORM_IGNORECASE, buffer1, -1, buffer2, -1);
719         ok (ret== 1, "CompareStringA (st1=%s str2=%s) expected result=1", buffer1, buffer2);
720
721         lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
722
723         strcpy(buffer1, "héhé"); strcpy(buffer2, "hèhè");
724         ret = CompareStringA(lcid, NORM_IGNORECASE, buffer1, -1, buffer2, -1);
725         ok (ret== 1, "CompareStringA (st1=%s str2=%s) expected result=1", buffer1, buffer2);
726
727         ret = CompareStringA(lcid, NORM_IGNORECASE, buffer1, -1, buffer2, 0);
728         ok (ret== 3, "CompareStringA (st1=%s str2=%s) expected result=3", buffer1, buffer2);
729 }
730
731
732 START_TEST(locale)
733 {
734 #if 0
735         TestEnumTimeFormats();
736 #endif
737         TestGetLocaleInfoA();
738         TestGetTimeFormatA();
739         TestGetDateFormatA();
740         TestGetDateFormatW();
741         TestGetNumberFormat();
742         TestGetCurrencyFormat();
743         TestCompareStringA();
744 }