Home | History | Annotate | Download | only in intltest
      1 /*
      2  *******************************************************************************
      3  * Copyright (C) 2004-2009, International Business Machines Corporation and         *
      4  * others. All Rights Reserved.                                                *
      5  *******************************************************************************
      6  */
      7 
      8 #include "unicode/utypes.h"
      9 
     10 #if !UCONFIG_NO_FORMATTING
     11 
     12 #include "itrbnfp.h"
     13 
     14 #include "unicode/umachine.h"
     15 
     16 #include "unicode/tblcoll.h"
     17 #include "unicode/coleitr.h"
     18 #include "unicode/ures.h"
     19 #include "unicode/ustring.h"
     20 #include "unicode/decimfmt.h"
     21 
     22 #include <string.h>
     23 
     24 // current macro not in icu1.8.1
     25 #define TESTCASE(id,test)             \
     26     case id:                          \
     27         name = #test;                 \
     28         if (exec) {                   \
     29             logln(#test "---");       \
     30             logln();                  \
     31             test();                   \
     32         }                             \
     33         break
     34 
     35 void IntlTestRBNFParse::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/)
     36 {
     37     if (exec) logln("TestSuite RuleBasedNumberFormatParse");
     38     switch (index) {
     39 #if U_HAVE_RBNF
     40         TESTCASE(0, TestParse);
     41 #else
     42         TESTCASE(0, TestRBNFParseDisabled);
     43 #endif
     44     default:
     45         name = "";
     46         break;
     47     }
     48 }
     49 
     50 #if U_HAVE_RBNF
     51 
     52 void
     53 IntlTestRBNFParse::TestParse() {
     54   // Try various rule parsing errors.  Shouldn't crash.
     55 
     56   logln("RBNF Parse test starting");
     57 
     58   // these rules make no sense but behave rationally
     59   const char* okrules[] = {
     60     "",
     61     "random text",
     62     "%foo:bar",
     63     "%foo: bar",
     64     "0:",
     65     "0::",
     66     ";",
     67     ";;",
     68     "%%foo:;",
     69     ":",
     70     "::",
     71     ":1",
     72     ":;",
     73     ":;:;",
     74     "-",
     75     "-1",
     76     "-:",
     77     ".",
     78     ".1",
     79     "[",
     80     "]",
     81     "[]",
     82     "[foo]",
     83     "[[]",
     84     "[]]",
     85     "[[]]",
     86     "[][]",
     87     "<",
     88     "<<",
     89     "<<<",
     90     "10:;9:;",
     91     ">",
     92     ">>",
     93     ">>>",
     94     "=",
     95     "==",
     96     "===",
     97     "=foo=",
     98 
     99     NULL,
    100   };
    101 
    102   // these rules would throw exceptions when formatting, if we could throw exceptions
    103   const char* exceptrules[] = {
    104     "10:", // formatting any value with a one's digit will fail
    105     "11: << x", // formating a multiple of 10 causes rollback rule to fail
    106     "%%foo: 0 foo; 10: =%%bar=; %%bar: 0: bar; 10: =%%foo=;",
    107 
    108     NULL,
    109   };
    110 
    111   // none of these rules should crash the formatter
    112   const char** allrules[] = {
    113     okrules,
    114     exceptrules,
    115     NULL,
    116   };
    117 
    118   for (int j = 0; allrules[j]; ++j) {
    119       const char** rules = allrules[j];
    120       for (int i = 0; rules[i]; ++i) {
    121           const char* rule = rules[i];
    122           logln("rule[%d] \"%s\"", i, rule);
    123           UErrorCode status = U_ZERO_ERROR;
    124           UParseError perr;
    125           RuleBasedNumberFormat* formatter = new RuleBasedNumberFormat(rule, Locale::getUS(), perr, status);
    126 
    127           if (U_SUCCESS(status)) {
    128               // format some values
    129 
    130               testfmt(formatter, 20, status);
    131               testfmt(formatter, 1.23, status);
    132               testfmt(formatter, -123, status);
    133               testfmt(formatter, .123, status);
    134               testfmt(formatter, 123, status);
    135 
    136           } else if (status == U_PARSE_ERROR) {
    137               logln("perror line: %x offset: %x context: %s|%s", perr.line, perr.offset, perr.preContext, perr.postContext);
    138           }
    139 
    140           delete formatter;
    141       }
    142   }
    143 }
    144 
    145 void
    146 IntlTestRBNFParse::testfmt(RuleBasedNumberFormat* formatter, double val, UErrorCode& status) {
    147     UnicodeString us;
    148     formatter->format((const Formattable)val, us, status);
    149     if (U_SUCCESS(status)) {
    150         us.insert(0, (UChar)'"');
    151         us.append((UChar)'"');
    152         logln(us);
    153     } else {
    154         logln("error: could not format %g, returned status: %d", val, status);
    155     }
    156 }
    157 
    158 void
    159 IntlTestRBNFParse::testfmt(RuleBasedNumberFormat* formatter, int val, UErrorCode& status) {
    160     UnicodeString us;
    161     formatter->format((const Formattable)(int32_t)val, us, status);
    162     if (U_SUCCESS(status)) {
    163         us.insert(0, (UChar)'"');
    164         us.append((UChar)'"');
    165         logln(us);
    166     } else {
    167         logln("error: could not format %d, returned status: %d", val, status);
    168     }
    169 }
    170 
    171 
    172 /* U_HAVE_RBNF */
    173 #else
    174 
    175 void
    176 IntlTestRBNF::TestRBNFParseDisabled() {
    177     errln("*** RBNF currently disabled on this platform ***\n");
    178 }
    179 
    180 /* U_HAVE_RBNF */
    181 #endif
    182 
    183 #endif /* #if !UCONFIG_NO_FORMATTING */
    184