OLD | NEW |
(Empty) | |
| 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* &n
ame, 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 excep
tions |
| 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, Loc
ale::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, UErrorC
ode& 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 */ |
OLD | NEW |