1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1998-2009, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6/*
7* File putiltst.c (Tests the API in putil)
8*
9* Modification History:
10*
11*   Date          Name        Description
12*   07/12/2000    Madhu       Creation
13*******************************************************************************
14*/
15
16#include "unicode/utypes.h"
17#include "cintltst.h"
18#include "cmemory.h"
19#include "unicode/putil.h"
20#include "unicode/ustring.h"
21#include "cstring.h"
22#include "putilimp.h"
23
24static UBool compareWithNAN(double x, double y);
25static void doAssert(double expect, double got, const char *message);
26
27static void TestPUtilAPI(void){
28
29    double  n1=0.0, y1=0.0, expn1, expy1;
30    double  value1 = 0.021;
31    char *str=0;
32    UBool isTrue=FALSE;
33
34    log_verbose("Testing the API uprv_modf()\n");
35    y1 = uprv_modf(value1, &n1);
36    expn1=0;
37    expy1=0.021;
38    if(y1 != expy1   || n1 != expn1){
39        log_err("Error in uprv_modf.  Expected IntegralValue=%f, Got=%f, \n Expected FractionalValue=%f, Got=%f\n",
40             expn1, n1, expy1, y1);
41    }
42    if(VERBOSITY){
43        log_verbose("[float]  x = %f  n = %f y = %f\n", value1, n1, y1);
44    }
45    log_verbose("Testing the API uprv_fmod()\n");
46    expn1=uprv_fmod(30.50, 15.00);
47    doAssert(expn1, 0.5, "uprv_fmod(30.50, 15.00) failed.");
48
49    log_verbose("Testing the API uprv_ceil()\n");
50    expn1=uprv_ceil(value1);
51    doAssert(expn1, 1, "uprv_ceil(0.021) failed.");
52
53    log_verbose("Testing the API uprv_floor()\n");
54    expn1=uprv_floor(value1);
55    doAssert(expn1, 0, "uprv_floor(0.021) failed.");
56
57    log_verbose("Testing the API uprv_fabs()\n");
58    expn1=uprv_fabs((2.02-1.345));
59    doAssert(expn1, 0.675, "uprv_fabs(2.02-1.345) failed.");
60
61    log_verbose("Testing the API uprv_fmax()\n");
62    doAssert(uprv_fmax(2.4, 1.2), 2.4, "uprv_fmax(2.4, 1.2) failed.");
63
64    log_verbose("Testing the API uprv_fmax() with x value= NaN\n");
65    expn1=uprv_fmax(uprv_getNaN(), 1.2);
66    doAssert(expn1, uprv_getNaN(), "uprv_fmax(uprv_getNaN(), 1.2) failed. when one parameter is NaN");
67
68    log_verbose("Testing the API uprv_fmin()\n");
69    doAssert(uprv_fmin(2.4, 1.2), 1.2, "uprv_fmin(2.4, 1.2) failed.");
70
71    log_verbose("Testing the API uprv_fmin() with x value= NaN\n");
72    expn1=uprv_fmin(uprv_getNaN(), 1.2);
73    doAssert(expn1, uprv_getNaN(), "uprv_fmin(uprv_getNaN(), 1.2) failed. when one parameter is NaN");
74
75    log_verbose("Testing the API uprv_max()\n");
76    doAssert(uprv_max(4, 2), 4, "uprv_max(4, 2) failed.");
77
78    log_verbose("Testing the API uprv_min()\n");
79    doAssert(uprv_min(-4, 2), -4, "uprv_min(-4, 2) failed.");
80
81    log_verbose("Testing the API uprv_trunc()\n");
82    doAssert(uprv_trunc(12.3456), 12, "uprv_trunc(12.3456) failed.");
83    doAssert(uprv_trunc(12.234E2), 1223, "uprv_trunc(12.234E2) failed.");
84    doAssert(uprv_trunc(uprv_getNaN()), uprv_getNaN(), "uprv_trunc(uprv_getNaN()) failed. with parameter=NaN");
85    doAssert(uprv_trunc(uprv_getInfinity()), uprv_getInfinity(), "uprv_trunc(uprv_getInfinity()) failed. with parameter=Infinity");
86
87
88    log_verbose("Testing the API uprv_pow10()\n");
89    doAssert(uprv_pow10(4), 10000, "uprv_pow10(4) failed.");
90
91    log_verbose("Testing the API uprv_isNegativeInfinity()\n");
92    isTrue=uprv_isNegativeInfinity(uprv_getInfinity() * -1);
93    if(isTrue != TRUE){
94        log_err("ERROR: uprv_isNegativeInfinity failed.\n");
95    }
96    log_verbose("Testing the API uprv_isPositiveInfinity()\n");
97    isTrue=uprv_isPositiveInfinity(uprv_getInfinity());
98    if(isTrue != TRUE){
99        log_err("ERROR: uprv_isPositiveInfinity failed.\n");
100    }
101    log_verbose("Testing the API uprv_isInfinite()\n");
102    isTrue=uprv_isInfinite(uprv_getInfinity());
103    if(isTrue != TRUE){
104        log_err("ERROR: uprv_isInfinite failed.\n");
105    }
106
107#if 0
108    log_verbose("Testing the API uprv_digitsAfterDecimal()....\n");
109    doAssert(uprv_digitsAfterDecimal(value1), 3, "uprv_digitsAfterDecimal() failed.");
110    doAssert(uprv_digitsAfterDecimal(1.2345E2), 2, "uprv_digitsAfterDecimal(1.2345E2) failed.");
111    doAssert(uprv_digitsAfterDecimal(1.2345E-2), 6, "uprv_digitsAfterDecimal(1.2345E-2) failed.");
112    doAssert(uprv_digitsAfterDecimal(1.2345E2), 2, "uprv_digitsAfterDecimal(1.2345E2) failed.");
113    doAssert(uprv_digitsAfterDecimal(-1.2345E-20), 24, "uprv_digitsAfterDecimal(1.2345E-20) failed.");
114    doAssert(uprv_digitsAfterDecimal(1.2345E20), 0, "uprv_digitsAfterDecimal(1.2345E20) failed.");
115    doAssert(uprv_digitsAfterDecimal(-0.021), 3, "uprv_digitsAfterDecimal(-0.021) failed.");
116    doAssert(uprv_digitsAfterDecimal(23.0), 0, "uprv_digitsAfterDecimal(23.0) failed.");
117    doAssert(uprv_digitsAfterDecimal(0.022223333321), 9, "uprv_digitsAfterDecimal(0.022223333321) failed.");
118#endif
119
120    log_verbose("Testing the API u_errorName()...\n");
121    str=(char*)u_errorName((UErrorCode)0);
122    if(strcmp(str, "U_ZERO_ERROR") != 0){
123        log_err("ERROR: u_getVersion() failed. Expected: U_ZERO_ERROR Got=%s\n",  str);
124    }
125    log_verbose("Testing the API u_errorName()...\n");
126    str=(char*)u_errorName((UErrorCode)-127);
127    if(strcmp(str, "U_USING_DEFAULT_WARNING") != 0){
128        log_err("ERROR: u_getVersion() failed. Expected: U_USING_DEFAULT_WARNING Got=%s\n",  str);
129    }
130    log_verbose("Testing the API u_errorName().. with BOGUS ERRORCODE...\n");
131    str=(char*)u_errorName((UErrorCode)200);
132    if(strcmp(str, "[BOGUS UErrorCode]") != 0){
133        log_err("ERROR: u_getVersion() failed. Expected: [BOGUS UErrorCode] Got=%s\n",  str);
134    }
135
136    {
137        const char* dataDirectory;
138        int32_t dataDirectoryLen;
139        UChar *udataDir=0;
140        UChar temp[100];
141        char *charvalue=0;
142        log_verbose("Testing chars to UChars\n");
143
144         /* This cannot really work on a japanese system. u_uastrcpy will have different results than */
145        /* u_charsToUChars when there is a backslash in the string! */
146        /*dataDirectory=u_getDataDirectory();*/
147
148        dataDirectory="directory1";  /*no backslashes*/
149        dataDirectoryLen=(int32_t)strlen(dataDirectory);
150        udataDir=(UChar*)malloc(sizeof(UChar) * (dataDirectoryLen + 1));
151        u_charsToUChars(dataDirectory, udataDir, (dataDirectoryLen + 1));
152        u_uastrcpy(temp, dataDirectory);
153
154        if(u_strcmp(temp, udataDir) != 0){
155            log_err("ERROR: u_charsToUChars failed. Expected %s, Got %s\n", austrdup(temp), austrdup(udataDir));
156        }
157        log_verbose("Testing UChars to chars\n");
158        charvalue=(char*)malloc(sizeof(char) * (u_strlen(udataDir) + 1));
159
160        u_UCharsToChars(udataDir, charvalue, (u_strlen(udataDir)+1));
161        if(strcmp(charvalue, dataDirectory) != 0){
162            log_err("ERROR: u_UCharsToChars failed. Expected %s, Got %s\n", charvalue, dataDirectory);
163        }
164        free(charvalue);
165        free(udataDir);
166    }
167
168    log_verbose("Testing uprv_timezone()....\n");
169    {
170        int32_t tzoffset = uprv_timezone();
171        log_verbose("Value returned from uprv_timezone = %d\n",  tzoffset);
172        if (tzoffset != 28800) {
173            log_verbose("***** WARNING: If testing in the PST timezone, t_timezone should return 28800! *****");
174        }
175        if ((tzoffset % 1800 != 0)) {
176            log_err("FAIL: t_timezone may be incorrect. It is not a multiple of 30min.");
177        }
178        /*tzoffset=uprv_getUTCtime();*/
179
180    }
181}
182
183static void TestVersion()
184{
185    UVersionInfo versionArray = {0x01, 0x00, 0x02, 0x02};
186    UVersionInfo versionArray2 = {0x01, 0x00, 0x02, 0x02};
187    char versionString[17]; /* xxx.xxx.xxx.xxx\0 */
188    UChar versionUString[] = { 0x0031, 0x002E, 0x0030, 0x002E,
189                               0x0032, 0x002E, 0x0038, 0x0000 }; /* 1.0.2.8 */
190
191    log_verbose("Testing the API u_versionToString().....\n");
192    u_versionToString(versionArray, versionString);
193    if(strcmp(versionString, "1.0.2.2") != 0){
194        log_err("ERROR: u_versionToString() failed. Expected: 1.0.2.2, Got=%s\n", versionString);
195    }
196    log_verbose("Testing the API u_versionToString().....with versionArray=NULL\n");
197    u_versionToString(NULL, versionString);
198    if(strcmp(versionString, "") != 0){
199        log_err("ERROR: u_versionToString() failed. with versionArray=NULL. It should just return\n");
200    }
201    log_verbose("Testing the API u_versionToString().....with versionArray=NULL\n");
202    u_versionToString(NULL, versionString);
203    if(strcmp(versionString, "") != 0){
204        log_err("ERROR: u_versionToString() failed . It should just return\n");
205    }
206    log_verbose("Testing the API u_versionToString().....with versionString=NULL\n");
207    u_versionToString(versionArray, NULL);
208    if(strcmp(versionString, "") != 0){
209        log_err("ERROR: u_versionToString() failed. with versionArray=NULL  It should just return\n");
210    }
211    versionArray[0] = 0x0a;
212    log_verbose("Testing the API u_versionToString().....\n");
213    u_versionToString(versionArray, versionString);
214    if(strcmp(versionString, "10.0.2.2") != 0){
215        log_err("ERROR: u_versionToString() failed. Expected: 10.0.2.2, Got=%s\n", versionString);
216    }
217    versionArray[0] = 0xa0;
218    u_versionToString(versionArray, versionString);
219    if(strcmp(versionString, "160.0.2.2") != 0){
220        log_err("ERROR: u_versionToString() failed. Expected: 160.0.2.2, Got=%s\n", versionString);
221    }
222    versionArray[0] = 0xa0;
223    versionArray[1] = 0xa0;
224    u_versionToString(versionArray, versionString);
225    if(strcmp(versionString, "160.160.2.2") != 0){
226        log_err("ERROR: u_versionToString() failed. Expected: 160.160.2.2, Got=%s\n", versionString);
227    }
228    versionArray[0] = 0x01;
229    versionArray[1] = 0x0a;
230    u_versionToString(versionArray, versionString);
231    if(strcmp(versionString, "1.10.2.2") != 0){
232        log_err("ERROR: u_versionToString() failed. Expected: 160.160.2.2, Got=%s\n", versionString);
233    }
234
235    log_verbose("Testing the API u_versionFromString() ....\n");
236    u_versionFromString(versionArray, "1.3.5.6");
237    u_versionToString(versionArray, versionString);
238    if(strcmp(versionString, "1.3.5.6") != 0){
239        log_err("ERROR: u_getVersion() failed. Expected: 1.3.5.6, Got=%s\n",  versionString);
240    }
241    log_verbose("Testing the API u_versionFromString() where versionArray=NULL....\n");
242    u_versionFromString(NULL, "1.3.5.6");
243    u_versionToString(versionArray, versionString);
244    if(strcmp(versionString, "1.3.5.6") != 0){
245        log_err("ERROR: u_getVersion() failed. Expected: 1.3.5.6, Got=%s\n",  versionString);
246    }
247
248    log_verbose("Testing the API u_getVersion().....\n");
249    u_getVersion(versionArray);
250    u_versionToString(versionArray, versionString);
251    if(strcmp(versionString, U_ICU_VERSION) != 0){
252        log_err("ERROR: u_getVersion() failed. Got=%s, expected %s\n",  versionString, U_ICU_VERSION);
253    }
254    /* test unicode */
255    log_verbose("Testing u_versionFromUString...\n");
256    u_versionFromString(versionArray,"1.0.2.8");
257    u_versionFromUString(versionArray2, versionUString);
258    u_versionToString(versionArray2, versionString);
259    if(memcmp(versionArray, versionArray2, sizeof(UVersionInfo))) {
260       log_err("FAIL: u_versionFromUString produced a different result - not 1.0.2.8 but %s [%x.%x.%x.%x]\n",
261          versionString,
262        (int)versionArray2[0],
263        (int)versionArray2[1],
264        (int)versionArray2[2],
265        (int)versionArray2[3]);
266    }
267    else {
268       log_verbose(" from UString: %s\n", versionString);
269    }
270}
271
272static void TestCompareVersions()
273{
274   /* use a 1d array to be palatable to java */
275   const char *testCases[] = {
276      /*  v1          <|=|>       v2  */
277    "0.0.0.0",    "=",        "0.0.0.0",
278    "3.1.2.0",    ">",        "3.0.9.0",
279    "3.2.8.6",    "<",        "3.4",
280    "4.0",        ">",        "3.2",
281    NULL,        NULL,        NULL
282   };
283   const char *v1str;
284   const char *opstr;
285   const char *v2str;
286   int32_t op, invop, got, invgot;
287   UVersionInfo v1, v2;
288   int32_t j;
289   log_verbose("Testing u_compareVersions()\n");
290   for(j=0;testCases[j]!=NULL;j+=3) {
291    v1str = testCases[j+0];
292    opstr = testCases[j+1];
293    v2str = testCases[j+2];
294    switch(opstr[0]) {
295        case '-':
296        case '<': op = -1; break;
297        case '0':
298        case '=': op = 0; break;
299        case '+':
300        case '>': op = 1; break;
301        default:  log_err("Bad operator at j/3=%d\n", (j/3)); return;
302    }
303    invop = 0-op; /* inverse operation: with v1 and v2 switched */
304    u_versionFromString(v1, v1str);
305    u_versionFromString(v2, v2str);
306    got = u_compareVersions(v1,v2);
307    invgot = u_compareVersions(v2,v1); /* oppsite */
308    if(got==op) {
309        log_verbose("%d: %s %s %s, OK\n", (j/3), v1str, opstr, v2str);
310    } else {
311        log_err("%d: %s %s %s: wanted %d got %d\n", (j/3), v1str, opstr, v2str, op, got);
312    }
313    if(invgot==invop) {
314        log_verbose("%d: %s (%d) %s, OK (inverse)\n", (j/3), v2str, invop, v1str);
315    } else {
316        log_err("%d: %s (%d) %s: wanted %d got %d\n", (j/3), v2str, invop, v1str, invop, invgot);
317    }
318   }
319}
320
321
322
323#if 0
324static void testIEEEremainder()
325{
326    double    pinf        = uprv_getInfinity();
327    double    ninf        = -uprv_getInfinity();
328    double    nan         = uprv_getNaN();
329/*    double    pzero       = 0.0;*/
330/*    double    nzero       = 0.0;
331    nzero *= -1;*/
332
333     /* simple remainder checks*/
334    remainderTest(7.0, 2.5, -0.5);
335    remainderTest(7.0, -2.5, -0.5);
336     /* this should work
337     remainderTest(43.7, 2.5, 1.2);
338     */
339
340    /* infinity and real*/
341    remainderTest(1.0, pinf, 1.0);
342    remainderTest(1.0, ninf, 1.0);
343
344    /*test infinity and real*/
345    remainderTest(nan, 1.0, nan);
346    remainderTest(1.0, nan, nan);
347    /*test infinity and nan*/
348    remainderTest(ninf, nan, nan);
349    remainderTest(pinf, nan, nan);
350
351    /* test infinity and zero */
352/*    remainderTest(pinf, pzero, 1.25);
353    remainderTest(pinf, nzero, 1.25);
354    remainderTest(ninf, pzero, 1.25);
355    remainderTest(ninf, nzero, 1.25); */
356}
357
358static void remainderTest(double x, double y, double exp)
359{
360    double result = uprv_IEEEremainder(x,y);
361
362    if(        uprv_isNaN(result) &&
363        ! ( uprv_isNaN(x) || uprv_isNaN(y))) {
364        log_err("FAIL: got NaN as result without NaN as argument");
365        log_err("      IEEEremainder(%f, %f) is %f, expected %f\n", x, y, result, exp);
366    }
367    else if(!compareWithNAN(result, exp)) {
368        log_err("FAIL:  IEEEremainder(%f, %f) is %f, expected %f\n", x, y, result, exp);
369    } else{
370        log_verbose("OK: IEEEremainder(%f, %f) is %f\n", x, y, result);
371    }
372
373}
374#endif
375
376static UBool compareWithNAN(double x, double y)
377{
378  if( uprv_isNaN(x) || uprv_isNaN(y) ) {
379    if(!uprv_isNaN(x) || !uprv_isNaN(y) ) {
380      return FALSE;
381    }
382  }
383  else if (y != x) { /* no NaN's involved */
384    return FALSE;
385  }
386
387  return TRUE;
388}
389
390static void doAssert(double got, double expect, const char *message)
391{
392  if(! compareWithNAN(expect, got) ) {
393    log_err("ERROR :  %s. Expected : %lf, Got: %lf\n", message, expect, got);
394  }
395}
396
397
398#define _CODE_ARR_LEN 8
399static const UErrorCode errorCode[_CODE_ARR_LEN] = {
400    U_USING_FALLBACK_WARNING,
401    U_STRING_NOT_TERMINATED_WARNING,
402    U_ILLEGAL_ARGUMENT_ERROR,
403    U_STATE_TOO_OLD_ERROR,
404    U_BAD_VARIABLE_DEFINITION,
405    U_RULE_MASK_ERROR,
406    U_UNEXPECTED_TOKEN,
407    U_UNSUPPORTED_ATTRIBUTE
408};
409
410static const char* str[] = {
411    "U_USING_FALLBACK_WARNING",
412    "U_STRING_NOT_TERMINATED_WARNING",
413    "U_ILLEGAL_ARGUMENT_ERROR",
414    "U_STATE_TOO_OLD_ERROR",
415    "U_BAD_VARIABLE_DEFINITION",
416    "U_RULE_MASK_ERROR",
417    "U_UNEXPECTED_TOKEN",
418    "U_UNSUPPORTED_ATTRIBUTE"
419};
420
421static void TestErrorName(void){
422    int32_t code=0;
423    const char* errorName ;
424    for(;code<U_ERROR_LIMIT;code++){
425        errorName = u_errorName((UErrorCode)code);
426    }
427
428    for(code=0;code<_CODE_ARR_LEN; code++){
429        errorName = u_errorName(errorCode[code]);
430        if(uprv_strcmp(str[code],errorName )!=0){
431            log_err("Error : u_errorName failed. Expected: %s Got: %s \n",str[code],errorName);
432        }
433    }
434}
435
436void addPUtilTest(TestNode** root);
437
438void
439addPUtilTest(TestNode** root)
440{
441    addTest(root, &TestPUtilAPI,       "putiltst/TestPUtilAPI");
442    addTest(root, &TestVersion,       "putiltst/TestVersion");
443    addTest(root, &TestCompareVersions,       "putiltst/TestCompareVersions");
444/*    addTest(root, &testIEEEremainder,  "putiltst/testIEEEremainder"); */
445    addTest(root, &TestErrorName, "putiltst/TestErrorName");
446}
447
448