]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/cintltst/cnmdptst.c
ICU-62107.0.1.tar.gz
[apple/icu.git] / icuSources / test / cintltst / cnmdptst.c
index 33f1d3ce435b73e20e9defcf90c9180e7774eb1a..de04e2c6354f1ea41bf7da3808bfd7f4af41b779 100644 (file)
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /********************************************************************
  * COPYRIGHT:
- * Copyright (c) 1997-2008, International Business Machines Corporation
+ * Copyright (c) 1997-2016, International Business Machines Corporation
  * and others. All Rights Reserved.
  ********************************************************************/
 /*******************************************************************************
 #include "unicode/uloc.h"
 #include "unicode/unum.h"
 #include "unicode/ustring.h"
+#include "unicode/putil.h"
 #include "cintltst.h"
 #include "cnmdptst.h"
 #include "cmemory.h"
 #include "cstring.h"
+#include "ulist.h"
 
 #define CHECK(status,str) if (U_FAILURE(status)) { log_err("FAIL: %s\n", str); return; }
 
@@ -50,6 +54,7 @@ void addNumFrDepTest(TestNode** root)
   addTest(root, &TestSecondaryGrouping, "tsformat/cnmdptst/TestSecondaryGrouping");
   addTest(root, &TestCurrencyKeywords, "tsformat/cnmdptst/TestCurrencyKeywords");
   addTest(root, &TestRounding5350, "tsformat/cnmdptst/TestRounding5350");
+  addTest(root, &TestGetKeywordValuesForLocale, "tsformat/cnmdptst/TestGetKeywordValuesForLocale");
 }
 
 /*Test Various format patterns*/
@@ -64,18 +69,18 @@ static void TestPatterns(void)
     UChar *str=NULL;
     UErrorCode status = U_ZERO_ERROR;
     const char* pat[]    = { "#.#", "#.", ".#", "#" };
-    const char* newpat[] = { "#0.#", "#0.", "#.0", "#" };
+    const char* newpat[] = { "#0.#", "#0.", "#.0", "#" }; // ICU 61 behavior
     const char* num[]    = { "0",   "0.", ".0", "0" };
 
     log_verbose("\nTesting different format patterns\n");
-    pat_length = sizeof(pat) / sizeof(pat[0]);
+    pat_length = UPRV_LENGTHOF(pat);
     for (i=0; i < pat_length; ++i)
     {
         status = U_ZERO_ERROR;
         u_uastrcpy(upat, pat[i]);
         fmt= unum_open(UNUM_IGNORE,upat, u_strlen(upat), "en_US",NULL, &status);
         if (U_FAILURE(status)) {
-            log_err("FAIL: Number format constructor failed for pattern %s\n", pat[i]);
+            log_err_status(status, "FAIL: Number format constructor failed for pattern %s -> %s\n", pat[i], u_errorName(status));
             continue;
         }
         lneed=0;
@@ -128,7 +133,7 @@ static void TestQuotes(void)
     u_uastrcpy(pat, "a'fo''o'b#");
     fmt =unum_open(UNUM_IGNORE,pat, u_strlen(pat), "en_US",NULL, &status);
     if(U_FAILURE(status)){
-        log_err("Error in number format costruction using pattern \"a'fo''o'b#\"\n");
+        log_err_status(status, "Error in number format costruction using pattern \"a'fo''o'b#\" -> %s\n", u_errorName(status));
     }
     lneed=0;
     lneed=unum_format(fmt, 123, NULL, lneed, NULL, &status);
@@ -138,7 +143,7 @@ static void TestQuotes(void)
         unum_format(fmt, 123, str, lneed+1,  NULL, &status);
     }
     if(U_FAILURE(status) || !str) {
-        log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
+        log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
         return;
     }
     log_verbose("Pattern \"%s\" \n", u_austrcpy(tempBuf, pat) );
@@ -194,7 +199,7 @@ static void TestExponential(void)
     char tempMsgBug[256];
     double a;
     UErrorCode status = U_ZERO_ERROR;
-#ifdef OS390
+#if U_PLATFORM == U_PF_OS390
     static const double val[] = { 0.01234, 123456789, 1.23e75, -3.141592653e-78 };
 #else
     static const double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
@@ -218,7 +223,7 @@ static void TestExponential(void)
     };
     static const double valParse[] =
     {
-#ifdef OS390
+#if U_PLATFORM == U_PF_OS390
         0.01234, 123460000, 1.23E75, -3.1416E-78,
         0.01234, 123460000, 1.23E75, -3.1416E-78,
         0.01234, 123456800, 1.23E75, -3.141593E-78,
@@ -241,9 +246,9 @@ static void TestExponential(void)
     };
 
 
-    pat_length = sizeof(pat) / sizeof(pat[0]);
-    val_length = sizeof(val) / sizeof(val[0]);
-    lval_length = sizeof(lval) / sizeof(lval[0]);
+    pat_length = UPRV_LENGTHOF(pat);
+    val_length = UPRV_LENGTHOF(val);
+    lval_length = UPRV_LENGTHOF(lval);
     ival = 0;
     ilval = 0;
     for (p=0; p < pat_length; ++p)
@@ -252,7 +257,7 @@ static void TestExponential(void)
         u_uastrcpy(upat, pat[p]);
         fmt=unum_open(UNUM_IGNORE,upat, u_strlen(upat), "en_US",NULL, &status);
         if (U_FAILURE(status)) {
-            log_err("FAIL: Bad status returned by Number format construction with pattern %s\n, pat[i]");
+            log_err_status(status, "FAIL: Bad status returned by Number format construction with pattern %s -> %s\n", pat[p], u_errorName(status));
             continue;
         }
         lneed= u_strlen(upat) + 1;
@@ -348,7 +353,7 @@ static void TestCurrencySign(void)
     pattern[0]=pattern[11]=0xa4; /* insert latin-1 currency symbol */
     fmt = unum_open(UNUM_IGNORE,pattern, u_strlen(pattern), "en_US",NULL, &status);
     if(U_FAILURE(status)){
-        log_err("Error in number format construction with pattern  \"\\xA4#,##0.00;-\\xA4#,##0.00\\\" \n");
+        log_err_status(status, "Error in number format construction with pattern  \"\\xA4#,##0.00;-\\xA4#,##0.00\\\" -> %s\n", u_errorName(status));
     }
     lneed=0;
     lneed=unum_formatDouble(fmt, 1234.56, NULL, lneed, NULL, &status);
@@ -358,7 +363,7 @@ static void TestCurrencySign(void)
         unum_formatDouble(fmt, 1234.56, str, lneed+1, NULL, &status);
     }
     if(U_FAILURE(status)) {
-        log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
+        log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
     }
     lneed=0;
     lneed=unum_toPattern(fmt, FALSE, NULL, lneed, &status);
@@ -372,9 +377,9 @@ static void TestCurrencySign(void)
     if(U_SUCCESS(status) && str) {
         res=(UChar*)malloc(sizeof(UChar) * (strlen("$1,234.56")+1) );
         u_uastrcpy(res, "$1,234.56");
-        if (u_strcmp(str, res) !=0) log_err("FAIL: Expected $1,234.56\n");
+        if (u_strcmp(str, res) !=0) log_data_err("FAIL: Expected $1,234.56\n");
     } else {
-        log_err("Error formatting\n");
+        log_err_status(status, "Error formatting -> %s\n", u_errorName(status));
     }
     free(str);
     free(res);
@@ -388,12 +393,12 @@ static void TestCurrencySign(void)
         unum_formatDouble(fmt, -1234.56, str, lneed+1, NULL, &status);
     }
     if(U_FAILURE(status)) {
-        log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
+        log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
     }
     if(str) {
         res=(UChar*)malloc(sizeof(UChar) * (strlen("-$1,234.56")+1) );
         u_uastrcpy(res, "-$1,234.56");
-        if (u_strcmp(str, res) != 0) log_err("FAIL: Expected -$1,234.56\n");
+        if (u_strcmp(str, res) != 0) log_data_err("FAIL: Expected -$1,234.56\n");
         free(str);
         free(res);
     }
@@ -422,7 +427,7 @@ static void TestCurrency(void)
         currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status);
 
         if(U_FAILURE(status)){
-            log_err("Error in the construction of number format with style currency:\n%s\n",
+            log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n",
                 myErrorName(status));
         } else {
             lneed=0;
@@ -467,11 +472,11 @@ static void TestCurrencyPreEuro(void)
         "nl_NL_PREEURO",
     };
 
-    const char* result[]={
-        "2\\u00A0\\u20A7", "2\\u00A0F",            "\\u00A31.50",                      "1,50\\u00A0mk",   "2\\u00A0F",         "\\u20A4\\u00A02",
-        "1$50\\u00A0Esc.", "\\u00F6S\\u00A01,50",  "1,50\\u00A0\\u0394\\u03C1\\u03C7", "\\u20A7\\u00A02", "1,50\\u00A0FB",     "\\u00a31.50",
-        "1,50\\u00A0BF",   "1,50\\u00A0DM",        "1,50\\u00A0BF",                    "2\\u00A0\\u20A7", "1,50\\u00A0F",      "2\\u00A0\\u20A7",
-        "fl\\u00A01,50"
+    const char* result[]={ // ICU 61 behavior
+        "\\u20A7\\u00A02", "2\\u00A0F",            "IEP1.50",                      "1,50\\u00A0mk",   "2\\u00A0F",         "ITL\\u00A02",
+        "1$50\\u00A0\\u200B", "\\u00F6S\\u00A01,50",  "1,50\\u00A0\\u0394\\u03C1\\u03C7", "2\\u00A0\\u20A7", "1,50\\u00A0FB",     "IEP1.50",
+        "1,50\\u00A0BEF",   "1,50\\u00A0DM",        "1,50\\u00A0BEF",                    "\\u20A7\\u00A02", "1,50\\u00A0F",      "2\\u00A0\\u20A7",
+        "NLG\\u00A01,50"
     };
 
     log_verbose("\nTesting the number format with different currency patterns\n");
@@ -480,13 +485,13 @@ static void TestCurrencyPreEuro(void)
         char curID[256] = {0};
         uloc_canonicalize(locale[i], curID, 256, &status);
         if(U_FAILURE(status)){
-            log_err("Could not canonicalize %s. Error: %s \n", locale[i], u_errorName(status));
+            log_data_err("Could not canonicalize %s. Error: %s (Are you missing data?)\n", locale[i], u_errorName(status));
             continue;
         }
         currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,curID,NULL, &status);
 
         if(U_FAILURE(status)){
-            log_err("Error in the construction of number format with style currency:\n%s\n",
+            log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n",
                 myErrorName(status));
         } else {
             lneed=0;
@@ -542,7 +547,7 @@ static void TestCurrencyObject(void)
 
     const char* result[]={
         "1\\u00A0234,56\\u00A0\\u20AC",
-        "1\\u00A0235\\u00A0\\u00A5JP",
+        "1\\u00A0235\\u00A0JPY",
     };
 
     log_verbose("\nTesting the number format with different currency codes\n");
@@ -552,7 +557,7 @@ static void TestCurrencyObject(void)
         UChar isoCode[16]={0};
         currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status);
         if(U_FAILURE(status)){
-            log_err("Error in the construction of number format with style currency:\n%s\n",
+            log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n",
                 myErrorName(status));
         } else {
             if (*currency[i]) {
@@ -616,7 +621,7 @@ static void TestRounding487(void)
     nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status);
 
     if(U_FAILURE(status)){
-        log_err("FAIL: failure in the construction of number format: %s\n", myErrorName(status));
+        log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status));
     } else {
         roundingTest(nnf, 0.00159999, 4, "0.0016");
         roundingTest(nnf, 0.00995, 4, "0.01");
@@ -681,7 +686,7 @@ static void TestDoubleAttribute(void)
     def=unum_open(style, NULL,0,NULL,NULL, &status);
 
     if (U_FAILURE(status)) {
-        log_err("Fail: error creating a default number formatter\n");
+        log_data_err("Fail: error creating a default number formatter -> %s (Are you missing data?)\n", u_errorName(status));
     } else {
         attr=UNUM_ROUNDING_INCREMENT;
         dvalue=unum_getDoubleAttribute(def, attr);
@@ -716,24 +721,27 @@ static void TestSecondaryGrouping(void) {
 
     u_uastrcpy(buffer, "#,##,###");
     f = unum_open(UNUM_IGNORE,buffer, -1, "en_US",NULL, &status);
-    CHECK(status, "DecimalFormat ct");
+    if (U_FAILURE(status)) {
+        log_data_err("Error DecimalFormat ct -> %s (Are you missing data?)\n", u_errorName(status));
+        return;
+    }
 
     pos.field = 0;
     unum_format(f, (int32_t)123456789L, resultBuffer, 512 , &pos, &status);
     u_uastrcpy(buffer, "12,34,56,789");
     if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
     {
-        log_err("Fail: Formatting \"#,##,###\" pattern with 123456789 got %s, expected %s\n", resultBuffer, "12,34,56,789");
+        log_err("Fail: Formatting \"#,##,###\" pattern with 123456789 got %s, expected %s\n", austrdup(resultBuffer), "12,34,56,789");
     }
     if (pos.beginIndex != 0 && pos.endIndex != 12) {
         log_err("Fail: Formatting \"#,##,###\" pattern pos = (%d, %d) expected pos = (0, 12)\n", pos.beginIndex, pos.endIndex);
     }
     memset(resultBuffer,0, sizeof(UChar)*512);
     unum_toPattern(f, FALSE, resultBuffer, 512, &status);
-    u_uastrcpy(buffer, "#,##,###");
+    u_uastrcpy(buffer, "#,##,###"); // ICU 61 behavior
     if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
     {
-        log_err("Fail: toPattern() got %s, expected %s\n", resultBuffer, "#,##,###");
+        log_err("Fail: toPattern() got %s, expected %s\n", austrdup(resultBuffer), "#,##,###");
     }
     memset(resultBuffer,0, sizeof(UChar)*512);
     u_uastrcpy(buffer, "#,###");
@@ -747,14 +755,14 @@ static void TestSecondaryGrouping(void) {
     u_uastrcpy(buffer, "12,3456,789");
     if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
     {
-        log_err("Fail: Formatting \"#,###\" pattern with 123456789 got %s, expected %s\n", resultBuffer, "12,3456,789");
+        log_err("Fail: Formatting \"#,###\" pattern with 123456789 got %s, expected %s\n", austrdup(resultBuffer), "12,3456,789");
     }
     memset(resultBuffer,0, sizeof(UChar)*512);
     unum_toPattern(f, FALSE, resultBuffer, 512, &status);
-    u_uastrcpy(buffer, "#,####,###");
+    u_uastrcpy(buffer, "#,####,###"); // ICU 61 behavior
     if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
     {
-        log_err("Fail: toPattern() got %s, expected %s\n", resultBuffer, "#,####,###");
+        log_err("Fail: toPattern() got %s, expected %s\n", austrdup(resultBuffer), "#,####,###");
     }
     memset(resultBuffer,0, sizeof(UChar)*512);
     g = unum_open(UNUM_DECIMAL, NULL,0,"hi_IN",NULL, &status);
@@ -847,7 +855,7 @@ static void TestCurrencyKeywords(void)
 
     for(i = 0; i < noLocales; i++) {
         strcpy(currLoc, uloc_getAvailable(i));
-        for(j = 0; j < sizeof(currencies)/sizeof(currencies[0]); j++) {
+        for(j = 0; j < UPRV_LENGTHOF(currencies); j++) {
             strcpy(locale, currLoc);
             strcat(locale, "@currency=");
             strcat(locale, currencies[j]);
@@ -862,6 +870,149 @@ static void TestCurrencyKeywords(void)
     }
 }
 
+static void TestGetKeywordValuesForLocale(void) {
+#define PREFERRED_SIZE 15
+#define MAX_NUMBER_OF_KEYWORDS 4
+    const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS] = {
+            { "root",               "USD", "USN", NULL },
+            { "und",                "USD", "USN", NULL },
+ /*           { "und_ZZ",             "USD", NULL, NULL },  -- temporarily remove as this locale now has 15 entries */
+            { "en_US",              "USD", "USN", NULL },
+            { "en_029",             "USD", "USN", NULL },
+            { "en_TH",              "THB", NULL, NULL },
+            { "de",                 "EUR", NULL, NULL },
+            { "de_DE",              "EUR", NULL, NULL },
+            { "ar",                 "EGP", NULL, NULL },
+            { "ar_PS",              "ILS", "JOD", NULL },
+            { "en@currency=CAD",    "USD", "USN", NULL },
+            { "fr@currency=zzz",    "EUR", NULL, NULL },
+            { "de_DE@currency=DEM", "EUR", NULL, NULL },
+            { "en_US@rg=THZZZZ",    "THB", NULL, NULL },
+            { "de@rg=USZZZZ",       "USD", "USN", NULL },
+            { "en_US@currency=CAD;rg=THZZZZ", "THB", NULL, NULL },
+    };
+    const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = {
+            2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1
+    };
+    /* ucurr_forLocale results for same locales; "" if no result expected */
+    const char *FORLOCALE[PREFERRED_SIZE] = {
+            "",    "",    "USD", "",
+            "THB", "",    "EUR", "",
+            "ILS", "CAD", "ZZZ", "DEM",
+            "THB", "USD", "CAD"
+    };
+    UErrorCode status = U_ZERO_ERROR;
+    int32_t i, j, size;
+    UEnumeration *pref, *all;
+    const char *loc = NULL;
+    UBool matchPref, matchAll;
+    const char *value = NULL;
+    int32_t valueLength = 0;
+    
+    UList *ALLList = NULL;
+    
+    UEnumeration *ALL = ucurr_getKeywordValuesForLocale("currency", uloc_getDefault(), FALSE, &status);
+    if (ALL == NULL) {
+        log_err_status(status, "ERROR getting keyword value for default locale. -> %s\n", u_errorName(status));
+        return;
+    }
+    
+    for (i = 0; i < PREFERRED_SIZE; i++) {
+        UChar getCurrU[4];
+        int32_t getCurrLen;
+
+        status = U_ZERO_ERROR;
+        pref = NULL;
+        all = NULL;
+        loc = PREFERRED[i][0];
+        pref = ucurr_getKeywordValuesForLocale("currency", loc, TRUE, &status);
+        matchPref = FALSE;
+        matchAll = FALSE;
+        
+        size = uenum_count(pref, &status);
+        
+        if (size == EXPECTED_SIZE[i]) {
+            matchPref = TRUE;
+            for (j = 0; j < size; j++) {
+                if ((value = uenum_next(pref, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
+                    if (uprv_strcmp(value, PREFERRED[i][j+1]) != 0) {
+                        log_err("ERROR: locale %s got keywords #%d %s expected %s\n", loc, j, value, PREFERRED[i][j+1]);
+
+                        matchPref = FALSE;
+                        break;
+                    }
+                } else {
+                    matchPref = FALSE;
+                    log_err("ERROR getting keyword value for locale \"%s\"\n", loc);
+                    break;
+                }
+            }
+        } else {
+            log_err("FAIL: size of locale \"%s\" %d does not match expected size %d\n", loc, size, EXPECTED_SIZE[i]);
+        }
+        
+        if (!matchPref) {
+            log_err("FAIL: Preferred values for locale \"%s\" does not match expected.\n", loc);
+            break;
+        }
+        uenum_close(pref);
+        
+        all = ucurr_getKeywordValuesForLocale("currency", loc, FALSE, &status);
+        
+        size = uenum_count(all, &status);
+        
+        if (U_SUCCESS(status) && size == uenum_count(ALL, &status)) {
+            matchAll = TRUE;
+            ALLList = ulist_getListFromEnum(ALL);
+            for (j = 0; j < size; j++) {
+                if ((value = uenum_next(all, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
+                    if (!ulist_containsString(ALLList, value, uprv_strlen(value))) {
+                        log_err("Locale %s have %s not in ALL\n", loc, value);
+                        matchAll = FALSE;
+                        break;
+                    }
+                } else {
+                    matchAll = FALSE;
+                    log_err("ERROR getting \"all\" keyword value for locale \"%s\"\n", loc);
+                    break;
+                }
+            }
+           if (!matchAll) {
+            log_err("FAIL: All values for locale \"%s\" does not match expected.\n", loc);
+           }
+        } else {
+            if(U_FAILURE(status)) {
+               log_err("ERROR: %s\n", u_errorName(status));
+            } else if(size!=uenum_count(ALL, &status)) {
+               log_err("ERROR: got size of %d, wanted %d\n", size, uenum_count(ALL, &status));
+            }
+        }
+        
+        uenum_close(all);
+        
+        status = U_ZERO_ERROR;
+        getCurrLen = ucurr_forLocale(loc, getCurrU, 4, &status);
+        if(U_FAILURE(status)) {
+            if (FORLOCALE[i][0] != 0) {
+                log_err("ERROR: ucurr_forLocale %s, status %s\n", loc, u_errorName(status));
+            }
+        } else if (getCurrLen != 3) {
+            if (FORLOCALE[i][0] != 0 || getCurrLen != -1) {
+                log_err("ERROR: ucurr_forLocale %s, returned len %d\n", loc, getCurrLen);
+            }
+        } else {
+            char getCurrB[4];
+            u_UCharsToChars(getCurrU, getCurrB, 4);
+            if ( uprv_strncmp(getCurrB, FORLOCALE[i], 4) != 0 ) {
+                log_err("ERROR: ucurr_forLocale %s, expected %s, got %s\n", loc, FORLOCALE[i], getCurrB);
+            }
+        }
+    }
+    
+    uenum_close(ALL);
+    
+}
+
 /**
  * Test proper handling of rounding modes.
  */
@@ -875,7 +1026,7 @@ static void TestRounding5350(void)
     nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status);
 
     if(U_FAILURE(status)){
-        log_err("FAIL: failure in the construction of number format: %s\n", myErrorName(status));
+        log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status));
         return;
     }