1/* 2 ******************************************************************************* 3 * Copyright (C) 2004, 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((UnicodeString)""); \ 31 test(); \ 32 } \ 33 break 34 35void 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 52void 53IntlTestRBNFParse::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 145void 146IntlTestRBNFParse::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 158void 159IntlTestRBNFParse::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 175void 176IntlTestRBNF::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