1/* 2******************************************************************************* 3* Copyright (C) 2014, International Business Machines Corporation and * 4* others. All Rights Reserved. * 5******************************************************************************* 6* 7* File numfmtspectest.cpp 8* 9******************************************************************************* 10*/ 11#include <stdio.h> 12#include <stdlib.h> 13 14#include "intltest.h" 15 16#if !UCONFIG_NO_FORMATTING 17 18#include "unicode/localpointer.h" 19#include "unicode/decimfmt.h" 20#include "unicode/dtfmtsym.h" 21#include "uassert.h" 22 23static const UChar kJPY[] = {0x4A, 0x50, 0x59}; 24 25static void fixNonBreakingSpace(UnicodeString &str) { 26 for (int32_t i = 0; i < str.length(); ++i) { 27 if (str[i] == 0xa0) { 28 str.setCharAt(i, 0x20); 29 } 30 } 31} 32 33static NumberFormat *nfWithPattern(const char *pattern) { 34 UnicodeString upattern(pattern, -1, US_INV); 35 upattern = upattern.unescape(); 36 UErrorCode status = U_ZERO_ERROR; 37 DecimalFormat *result = new DecimalFormat( 38 upattern, new DecimalFormatSymbols("fr", status), status); 39 U_ASSERT(status == U_ZERO_ERROR); 40 return result; 41} 42 43static UnicodeString format(double d, const NumberFormat &fmt) { 44 UnicodeString result; 45 fmt.format(d, result); 46 fixNonBreakingSpace(result); 47 return result; 48} 49 50class NumberFormatSpecificationTest : public IntlTest { 51public: 52 NumberFormatSpecificationTest() { 53 } 54 void TestBasicPatterns(); 55 void TestNfSetters(); 56 void TestRounding(); 57 void TestSignificantDigits(); 58 void TestScientificNotation(); 59 void TestPercent(); 60 void TestPerMilli(); 61 void TestPadding(); 62 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0); 63private: 64 void assertPatternFr( 65 const char *expected, double x, const char *pattern, UBool possibleDataError=FALSE); 66 67}; 68 69void NumberFormatSpecificationTest::runIndexedTest( 70 int32_t index, UBool exec, const char *&name, char *) { 71 if (exec) { 72 logln("TestSuite NumberFormatSpecificationTest: "); 73 } 74 TESTCASE_AUTO_BEGIN; 75 TESTCASE_AUTO(TestBasicPatterns); 76 TESTCASE_AUTO(TestNfSetters); 77 TESTCASE_AUTO(TestRounding); 78 TESTCASE_AUTO(TestSignificantDigits); 79 TESTCASE_AUTO(TestScientificNotation); 80 TESTCASE_AUTO(TestPercent); 81 TESTCASE_AUTO(TestPerMilli); 82 TESTCASE_AUTO(TestPadding); 83 TESTCASE_AUTO_END; 84} 85 86void NumberFormatSpecificationTest::TestBasicPatterns() { 87 assertPatternFr("1 234,57", 1234.567, "#,##0.##", TRUE); 88 assertPatternFr("1234,57", 1234.567, "0.##", TRUE); 89 assertPatternFr("1235", 1234.567, "0", TRUE); 90 assertPatternFr("1 234,567", 1234.567, "#,##0.###", TRUE); 91 assertPatternFr("1234,567", 1234.567, "###0.#####", TRUE); 92 assertPatternFr("1234,5670", 1234.567, "###0.0000#", TRUE); 93 assertPatternFr("01234,5670", 1234.567, "00000.0000", TRUE); 94 assertPatternFr("1 234,57 \\u20ac", 1234.567, "#,##0.00 \\u00a4", TRUE); 95} 96 97void NumberFormatSpecificationTest::TestNfSetters() { 98 LocalPointer<NumberFormat> nf(nfWithPattern("#,##0.##")); 99 nf->setMaximumIntegerDigits(5); 100 nf->setMinimumIntegerDigits(4); 101 assertEquals("", "34 567,89", format(1234567.89, *nf), TRUE); 102 assertEquals("", "0 034,56", format(34.56, *nf), TRUE); 103} 104 105void NumberFormatSpecificationTest::TestRounding() { 106 assertPatternFr("1,0", 1.25, "0.5", TRUE); 107 assertPatternFr("2,0", 1.75, "0.5", TRUE); 108 assertPatternFr("-1,0", -1.25, "0.5", TRUE); 109 assertPatternFr("-02,0", -1.75, "00.5", TRUE); 110 assertPatternFr("0", 2.0, "4", TRUE); 111 assertPatternFr("8", 6.0, "4", TRUE); 112 assertPatternFr("8", 10.0, "4", TRUE); 113 assertPatternFr("99,90", 99.0, "2.70", TRUE); 114 assertPatternFr("273,00", 272.0, "2.73", TRUE); 115 assertPatternFr("1 03,60", 104.0, "#,#3.70", TRUE); 116} 117 118void NumberFormatSpecificationTest::TestSignificantDigits() { 119 assertPatternFr("1230", 1234.0, "@@@", TRUE); 120 assertPatternFr("1 234", 1234.0, "@,@@@", TRUE); 121 assertPatternFr("1 235 000", 1234567.0, "@,@@@", TRUE); 122 assertPatternFr("1 234 567", 1234567.0, "@@@@,@@@", TRUE); 123 assertPatternFr("12 34 567,00", 1234567.0, "@@@@,@@,@@@", TRUE); 124 assertPatternFr("12 34 567,0", 1234567.0, "@@@@,@@,@@#", TRUE); 125 assertPatternFr("12 34 567", 1234567.0, "@@@@,@@,@##", TRUE); 126 assertPatternFr("12 34 567", 1234567.001, "@@@@,@@,@##", TRUE); 127 assertPatternFr("12 34 567", 1234567.001, "@@@@,@@,###", TRUE); 128 assertPatternFr("1 200", 1234.0, "#,#@@", TRUE); 129} 130 131void NumberFormatSpecificationTest::TestScientificNotation() { 132 assertPatternFr("1,23E4", 12345.0, "0.00E0", TRUE); 133 assertPatternFr("123,00E2", 12300.0, "000.00E0", TRUE); 134 assertPatternFr("123,0E2", 12300.0, "000.0#E0", TRUE); 135 assertPatternFr("123,0E2", 12300.1, "000.0#E0", TRUE); 136 assertPatternFr("123,01E2", 12301.0, "000.0#E0", TRUE); 137 assertPatternFr("123,01E+02", 12301.0, "000.0#E+00", TRUE); 138 assertPatternFr("12,3E3", 12345.0, "##0.00E0", TRUE); 139 assertPatternFr("12,300E3", 12300.1, "##0.0000E0", TRUE); 140 assertPatternFr("12,30E3", 12300.1, "##0.000#E0", TRUE); 141 assertPatternFr("12,301E3", 12301.0, "##0.000#E0", TRUE); 142 if (!logKnownIssue("11020")) { 143 assertPatternFr("1,25E4", 12301.2, "0.05E0"); 144 } 145 assertPatternFr("170,0E-3", 0.17, "##0.000#E0", TRUE); 146 147} 148 149void NumberFormatSpecificationTest::TestPercent() { 150 assertPatternFr("57,3%", 0.573, "0.0%", TRUE); 151 assertPatternFr("%57,3", 0.573, "%0.0", TRUE); 152 assertPatternFr("p%p57,3", 0.573, "p%p0.0", TRUE); 153 assertPatternFr("p%p0,6", 0.573, "p'%'p0.0", TRUE); 154 assertPatternFr("%3,260", 0.0326, "%@@@@", TRUE); 155 assertPatternFr("%1 540", 15.43, "%#,@@@", TRUE); 156 assertPatternFr("%1 656,4", 16.55, "%#,##4.1", TRUE); 157 assertPatternFr("%16,3E3", 162.55, "%##0.00E0", TRUE); 158} 159 160void NumberFormatSpecificationTest::TestPerMilli() { 161 assertPatternFr("573,0\\u2030", 0.573, "0.0\\u2030", TRUE); 162 assertPatternFr("\\u2030573,0", 0.573, "\\u20300.0", TRUE); 163 assertPatternFr("p\\u2030p573,0", 0.573, "p\\u2030p0.0", TRUE); 164 assertPatternFr("p\\u2030p0,6", 0.573, "p'\\u2030'p0.0", TRUE); 165 assertPatternFr("\\u203032,60", 0.0326, "\\u2030@@@@", TRUE); 166 assertPatternFr("\\u203015 400", 15.43, "\\u2030#,@@@", TRUE); 167 assertPatternFr("\\u203016 551,7", 16.55, "\\u2030#,##4.1", TRUE); 168 assertPatternFr("\\u2030163E3", 162.55, "\\u2030##0.00E0", TRUE); 169} 170 171void NumberFormatSpecificationTest::TestPadding() { 172 assertPatternFr("$***1 234", 1234, "$**####,##0", TRUE); 173 assertPatternFr("xxx$1 234", 1234, "*x$####,##0", TRUE); 174 assertPatternFr("1 234xxx$", 1234, "####,##0*x$", TRUE); 175 assertPatternFr("1 234$xxx", 1234, "####,##0$*x", TRUE); 176 assertPatternFr("ne1 234nx", -1234, "####,##0$*x;ne#n", TRUE); 177 assertPatternFr("n1 234*xx", -1234, "####,##0$*x;n#'*'", TRUE); 178 assertPatternFr("yyyy%432,6", 4.33, "*y%4.2######", TRUE); 179 if (!logKnownIssue("11025")) { 180 assertPatternFr("EUR *433,00", 433.0, "\\u00a4\\u00a4 **####0.00"); 181 assertPatternFr("EUR *433,00", 433.0, "\\u00a4\\u00a4 **#######0"); 182 } 183 { 184 UnicodeString upattern("\\u00a4\\u00a4 **#######0", -1, US_INV); 185 upattern = upattern.unescape(); 186 UErrorCode status = U_ZERO_ERROR; 187 UnicodeString result; 188 DecimalFormat fmt( 189 upattern, new DecimalFormatSymbols("fr", status), status); 190 fmt.setCurrency(kJPY); 191 fmt.format(433.22, result); 192 assertSuccess("", status); 193 assertEquals("", "JPY ****433", result, TRUE); 194 } 195 { 196 UnicodeString upattern( 197 "\\u00a4\\u00a4 **#######0;\\u00a4\\u00a4 (#)", -1, US_INV); 198 upattern = upattern.unescape(); 199 UErrorCode status = U_ZERO_ERROR; 200 UnicodeString result; 201 DecimalFormat fmt( 202 upattern, 203 new DecimalFormatSymbols("en_US", status), 204 status); 205 fmt.format(-433.22, result); 206 assertSuccess("", status); 207 assertEquals("", "USD (433.22)", result, TRUE); 208 } 209 const char *paddedSciPattern = "QU**00.#####E0"; 210 assertPatternFr("QU***43,3E-1", 4.33, paddedSciPattern, TRUE); 211 { 212 UErrorCode status = U_ZERO_ERROR; 213 DecimalFormatSymbols *sym = new DecimalFormatSymbols("fr", status); 214 sym->setSymbol(DecimalFormatSymbols::kExponentialSymbol, "EE"); 215 DecimalFormat fmt( 216 paddedSciPattern, 217 sym, 218 status); 219 UnicodeString result; 220 fmt.format(4.33, result); 221 assertSuccess("", status); 222 assertEquals("", "QU**43,3EE-1", result, TRUE); 223 } 224 // padding cannot work as intended with scientific notation. 225 assertPatternFr("QU**43,32E-1", 4.332, paddedSciPattern, TRUE); 226} 227 228void NumberFormatSpecificationTest::assertPatternFr( 229 const char *expected, 230 double x, 231 const char *pattern, 232 UBool possibleDataError) { 233 UnicodeString upattern(pattern, -1, US_INV); 234 UnicodeString uexpected(expected, -1, US_INV); 235 upattern = upattern.unescape(); 236 uexpected = uexpected.unescape(); 237 UErrorCode status = U_ZERO_ERROR; 238 UnicodeString result; 239 DecimalFormat fmt( 240 upattern, new DecimalFormatSymbols("fr_FR", status), status); 241 fmt.format(x, result); 242 fixNonBreakingSpace(result); 243 assertSuccess("", status); 244 assertEquals("", uexpected, result, possibleDataError); 245} 246 247extern IntlTest *createNumberFormatSpecificationTest() { 248 return new NumberFormatSpecificationTest(); 249} 250 251#endif 252