+void NumberFormatTest::TestGetAffixes() {
+ UErrorCode status = U_ZERO_ERROR;
+ DecimalFormatSymbols sym("en_US", status);
+ UnicodeString pattern("\\u00a4\\u00a4\\u00a4 0.00 %\\u00a4\\u00a4");
+ pattern = pattern.unescape();
+ DecimalFormat fmt(pattern, sym, status);
+ if (U_FAILURE(status)) {
+ dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
+ return;
+ }
+ UnicodeString affixStr;
+ assertEquals("", "US dollars ", fmt.getPositivePrefix(affixStr));
+ assertEquals("", " %USD", fmt.getPositiveSuffix(affixStr));
+ assertEquals("", "-US dollars ", fmt.getNegativePrefix(affixStr));
+ assertEquals("", " %USD", fmt.getNegativeSuffix(affixStr));
+
+ // Test equality with affixes. set affix methods can't capture special
+ // characters which is why equality should fail.
+ {
+ DecimalFormat fmtCopy(fmt);
+ assertTrue("", fmt == fmtCopy);
+ UnicodeString someAffix;
+ fmtCopy.setPositivePrefix(fmtCopy.getPositivePrefix(someAffix));
+ assertTrue("", fmt != fmtCopy);
+ }
+ {
+ DecimalFormat fmtCopy(fmt);
+ assertTrue("", fmt == fmtCopy);
+ UnicodeString someAffix;
+ fmtCopy.setPositiveSuffix(fmtCopy.getPositiveSuffix(someAffix));
+ assertTrue("", fmt != fmtCopy);
+ }
+ {
+ DecimalFormat fmtCopy(fmt);
+ assertTrue("", fmt == fmtCopy);
+ UnicodeString someAffix;
+ fmtCopy.setNegativePrefix(fmtCopy.getNegativePrefix(someAffix));
+ assertTrue("", fmt != fmtCopy);
+ }
+ {
+ DecimalFormat fmtCopy(fmt);
+ assertTrue("", fmt == fmtCopy);
+ UnicodeString someAffix;
+ fmtCopy.setNegativeSuffix(fmtCopy.getNegativeSuffix(someAffix));
+ assertTrue("", fmt != fmtCopy);
+ }
+ fmt.setPositivePrefix("Don't");
+ fmt.setPositiveSuffix("do");
+ UnicodeString someAffix("be''eet\\u00a4\\u00a4\\u00a4 it.");
+ someAffix = someAffix.unescape();
+ fmt.setNegativePrefix(someAffix);
+ fmt.setNegativeSuffix("%");
+ assertEquals("", "Don't", fmt.getPositivePrefix(affixStr));
+ assertEquals("", "do", fmt.getPositiveSuffix(affixStr));
+ assertEquals("", someAffix, fmt.getNegativePrefix(affixStr));
+ assertEquals("", "%", fmt.getNegativeSuffix(affixStr));
+}
+
+void NumberFormatTest::TestToPatternScientific11648() {
+ UErrorCode status = U_ZERO_ERROR;
+ Locale en("en");
+ DecimalFormatSymbols sym(en, status);
+ DecimalFormat fmt("0.00", sym, status);
+ if (U_FAILURE(status)) {
+ dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
+ return;
+ }
+ fmt.setScientificNotation(TRUE);
+ UnicodeString pattern;
+ assertEquals("", "0.00E0", fmt.toPattern(pattern));
+ DecimalFormat fmt2(pattern, sym, status);
+ assertSuccess("", status);
+}
+
+void NumberFormatTest::TestBenchmark() {
+/*
+ UErrorCode status = U_ZERO_ERROR;
+ Locale en("en");
+ DecimalFormatSymbols sym(en, status);
+ DecimalFormat fmt("0.0000000", new DecimalFormatSymbols(sym), status);
+// DecimalFormat fmt("0.00000E0", new DecimalFormatSymbols(sym), status);
+// DecimalFormat fmt("0", new DecimalFormatSymbols(sym), status);
+ FieldPosition fpos(0);
+ clock_t start = clock();
+ for (int32_t i = 0; i < 1000000; ++i) {
+ UnicodeString append;
+ fmt.format(3.0, append, fpos, status);
+// fmt.format(4.6692016, append, fpos, status);
+// fmt.format(1234567.8901, append, fpos, status);
+// fmt.format(2.99792458E8, append, fpos, status);
+// fmt.format(31, append);
+ }
+ errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
+ assertSuccess("", status);
+
+ UErrorCode status = U_ZERO_ERROR;
+ MessageFormat fmt("{0, plural, one {I have # friend.} other {I have # friends.}}", status);
+ FieldPosition fpos(0);
+ Formattable one(1.0);
+ Formattable three(3.0);
+ clock_t start = clock();
+ for (int32_t i = 0; i < 500000; ++i) {
+ UnicodeString append;
+ fmt.format(&one, 1, append, fpos, status);
+ UnicodeString append2;
+ fmt.format(&three, 1, append2, fpos, status);
+ }
+ errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
+ assertSuccess("", status);
+
+ UErrorCode status = U_ZERO_ERROR;
+ Locale en("en");
+ Measure measureC(23, MeasureUnit::createCelsius(status), status);
+ MeasureFormat fmt(en, UMEASFMT_WIDTH_WIDE, status);
+ FieldPosition fpos(0);
+ clock_t start = clock();
+ for (int32_t i = 0; i < 1000000; ++i) {
+ UnicodeString appendTo;
+ fmt.formatMeasures(
+ &measureC, 1, appendTo, fpos, status);
+ }
+ errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
+ assertSuccess("", status);
+*/
+}
+
+void NumberFormatTest::TestFractionalDigitsForCurrency() {
+ UErrorCode status = U_ZERO_ERROR;
+ LocalPointer<NumberFormat> fmt(NumberFormat::createCurrencyInstance("en", status));
+ if (U_FAILURE(status)) {
+ dataerrln("Error creating NumberFormat - %s", u_errorName(status));
+ return;
+ }
+ UChar JPY[] = {0x4A, 0x50, 0x59, 0x0};
+ fmt->setCurrency(JPY, status);
+ if (!assertSuccess("", status)) {
+ return;
+ }
+ assertEquals("", 0, fmt->getMaximumFractionDigits());
+}
+
+
+void NumberFormatTest::TestFormatCurrencyPlural() {
+ UErrorCode status = U_ZERO_ERROR;
+ Locale locale = Locale::createCanonical("en_US");
+ NumberFormat *fmt = NumberFormat::createInstance(locale, UNUM_CURRENCY_PLURAL, status);
+ if (U_FAILURE(status)) {
+ dataerrln("Error creating NumberFormat - %s", u_errorName(status));
+ return;
+ }
+ UnicodeString formattedNum;
+ fmt->format(11234.567, formattedNum, NULL, status);
+ assertEquals("", "11,234.57 US dollars", formattedNum);
+ delete fmt;
+}
+
+void NumberFormatTest::TestCtorApplyPatternDifference() {
+ UErrorCode status = U_ZERO_ERROR;
+ DecimalFormatSymbols sym("en_US", status);
+ UnicodeString pattern("\\u00a40");
+ DecimalFormat fmt(pattern.unescape(), sym, status);
+ if (U_FAILURE(status)) {
+ dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
+ return;
+ }
+ UnicodeString result;
+ assertEquals(
+ "ctor favors precision of currency",
+ "$5.00",
+ fmt.format(5, result));
+ result.remove();
+ fmt.applyPattern(pattern.unescape(), status);
+ assertEquals(
+ "applyPattern favors precision of pattern",
+ "$5",
+ fmt.format(5, result));
+}
+
+void NumberFormatTest::Test11868() {
+ double posAmt = 34.567;
+ double negAmt = -9876.543;
+
+ Locale selectedLocale("en_US");
+ UErrorCode status = U_ZERO_ERROR;
+
+ UnicodeString result;
+ FieldPosition fpCurr(UNUM_CURRENCY_FIELD);
+ LocalPointer<NumberFormat> fmt(
+ NumberFormat::createInstance(
+ selectedLocale, UNUM_CURRENCY_PLURAL, status));
+ if (!assertSuccess("Format creation", status)) {
+ return;
+ }
+ fmt->format(posAmt, result, fpCurr, status);
+ assertEquals("", "34.57 US dollars", result);
+ assertEquals("begin index", 6, fpCurr.getBeginIndex());
+ assertEquals("end index", 16, fpCurr.getEndIndex());
+
+ // Test field position iterator
+ {
+ NumberFormatTest_Attributes attributes[] = {
+ {UNUM_INTEGER_FIELD, 0, 2},
+ {UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3},
+ {UNUM_FRACTION_FIELD, 3, 5},
+ {UNUM_CURRENCY_FIELD, 6, 16},
+ {0, -1, 0}};
+ UnicodeString result;
+ FieldPositionIterator iter;
+ fmt->format(posAmt, result, &iter, status);
+ assertEquals("", "34.57 US dollars", result);
+ verifyFieldPositionIterator(attributes, iter);
+ }
+
+ result.remove();
+ fmt->format(negAmt, result, fpCurr, status);
+ assertEquals("", "-9,876.54 US dollars", result);
+ assertEquals("begin index", 10, fpCurr.getBeginIndex());
+ assertEquals("end index", 20, fpCurr.getEndIndex());
+
+ // Test field position iterator
+ {
+ NumberFormatTest_Attributes attributes[] = {
+ {UNUM_SIGN_FIELD, 0, 1},
+ {UNUM_GROUPING_SEPARATOR_FIELD, 2, 3},
+ {UNUM_INTEGER_FIELD, 1, 6},
+ {UNUM_DECIMAL_SEPARATOR_FIELD, 6, 7},
+ {UNUM_FRACTION_FIELD, 7, 9},
+ {UNUM_CURRENCY_FIELD, 10, 20},
+ {0, -1, 0}};
+ UnicodeString result;
+ FieldPositionIterator iter;
+ fmt->format(negAmt, result, &iter, status);
+ assertEquals("", "-9,876.54 US dollars", result);
+ verifyFieldPositionIterator(attributes, iter);
+ }
+}
+
+void NumberFormatTest::Test10727_RoundingZero() {
+ DigitList d;
+ d.set(-0.0);
+ assertFalse("", d.isPositive());
+ d.round(3);
+ assertFalse("", d.isPositive());
+}
+
+void NumberFormatTest::Test11376_getAndSetPositivePrefix() {
+ {
+ const UChar USD[] = {0x55, 0x53, 0x44, 0x0};
+ UErrorCode status = U_ZERO_ERROR;
+ LocalPointer<NumberFormat> fmt(
+ NumberFormat::createCurrencyInstance("en", status));
+ if (!assertSuccess("", status)) {
+ return;
+ }
+ DecimalFormat *dfmt = (DecimalFormat *) fmt.getAlias();
+ dfmt->setCurrency(USD);
+ UnicodeString result;
+
+ // This line should be a no-op. I am setting the positive prefix
+ // to be the same thing it was before.
+ dfmt->setPositivePrefix(dfmt->getPositivePrefix(result));
+
+ UnicodeString appendTo;
+ assertEquals("", "$3.78", dfmt->format(3.78, appendTo, status));
+ assertSuccess("", status);
+ }
+ {
+ const UChar USD[] = {0x55, 0x53, 0x44, 0x0};
+ UErrorCode status = U_ZERO_ERROR;
+ LocalPointer<NumberFormat> fmt(
+ NumberFormat::createInstance("en", UNUM_CURRENCY_PLURAL, status));
+ if (!assertSuccess("", status)) {
+ return;
+ }
+ DecimalFormat *dfmt = (DecimalFormat *) fmt.getAlias();
+ UnicodeString result;
+ UnicodeString tripleIntlCurrency(" \\u00a4\\u00a4\\u00a4");
+ tripleIntlCurrency = tripleIntlCurrency.unescape();
+ assertEquals("", tripleIntlCurrency, dfmt->getPositiveSuffix(result));
+ dfmt->setCurrency(USD);
+
+ // getPositiveSuffix() always returns the suffix for the
+ // "other" plural category
+ assertEquals("", " US dollars", dfmt->getPositiveSuffix(result));
+ UnicodeString appendTo;
+ assertEquals("", "3.78 US dollars", dfmt->format(3.78, appendTo, status));
+ assertEquals("", " US dollars", dfmt->getPositiveSuffix(result));
+ dfmt->setPositiveSuffix("booya");
+ appendTo.remove();
+ assertEquals("", "3.78booya", dfmt->format(3.78, appendTo, status));
+ assertEquals("", "booya", dfmt->getPositiveSuffix(result));
+ }
+}
+
+void NumberFormatTest::Test11475_signRecognition() {
+ UErrorCode status = U_ZERO_ERROR;
+ DecimalFormatSymbols sym("en", status);
+ UnicodeString result;
+ {
+ DecimalFormat fmt("+0.00", sym, status);
+ if (!assertSuccess("", status)) {
+ return;
+ }
+ NumberFormatTest_Attributes attributes[] = {
+ {UNUM_SIGN_FIELD, 0, 1},
+ {UNUM_INTEGER_FIELD, 1, 2},
+ {UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3},
+ {UNUM_FRACTION_FIELD, 3, 5},
+ {0, -1, 0}};
+ UnicodeString result;
+ FieldPositionIterator iter;
+ fmt.format(2.3, result, &iter, status);
+ assertEquals("", "+2.30", result);
+ verifyFieldPositionIterator(attributes, iter);
+ }
+ {
+ DecimalFormat fmt("++0.00+;-(#)--", sym, status);
+ if (!assertSuccess("", status)) {
+ return;
+ }
+ {
+ NumberFormatTest_Attributes attributes[] = {
+ {UNUM_SIGN_FIELD, 0, 2},
+ {UNUM_INTEGER_FIELD, 2, 3},
+ {UNUM_DECIMAL_SEPARATOR_FIELD, 3, 4},
+ {UNUM_FRACTION_FIELD, 4, 6},
+ {UNUM_SIGN_FIELD, 6, 7},
+ {0, -1, 0}};
+ UnicodeString result;
+ FieldPositionIterator iter;
+ fmt.format(2.3, result, &iter, status);
+ assertEquals("", "++2.30+", result);
+ verifyFieldPositionIterator(attributes, iter);
+ }
+ {
+ NumberFormatTest_Attributes attributes[] = {
+ {UNUM_SIGN_FIELD, 0, 1},
+ {UNUM_INTEGER_FIELD, 2, 3},
+ {UNUM_DECIMAL_SEPARATOR_FIELD, 3, 4},
+ {UNUM_FRACTION_FIELD, 4, 6},
+ {UNUM_SIGN_FIELD, 7, 9},
+ {0, -1, 0}};
+ UnicodeString result;
+ FieldPositionIterator iter;
+ fmt.format(-2.3, result, &iter, status);
+ assertEquals("", "-(2.30)--", result);
+ verifyFieldPositionIterator(attributes, iter);
+ }
+ }
+}
+
+void NumberFormatTest::Test11640_getAffixes() {
+ UErrorCode status = U_ZERO_ERROR;
+ DecimalFormatSymbols symbols("en_US", status);
+ if (!assertSuccess("", status)) {
+ return;
+ }
+ UnicodeString pattern("\\u00a4\\u00a4\\u00a4 0.00 %\\u00a4\\u00a4");
+ pattern = pattern.unescape();
+ DecimalFormat fmt(pattern, symbols, status);
+ if (!assertSuccess("", status)) {
+ return;
+ }
+ UnicodeString affixStr;
+ assertEquals("", "US dollars ", fmt.getPositivePrefix(affixStr));
+ assertEquals("", " %USD", fmt.getPositiveSuffix(affixStr));
+ assertEquals("", "-US dollars ", fmt.getNegativePrefix(affixStr));
+ assertEquals("", " %USD", fmt.getNegativeSuffix(affixStr));
+}
+
+void NumberFormatTest::Test11649_toPatternWithMultiCurrency() {
+ UnicodeString pattern("\\u00a4\\u00a4\\u00a4 0.00");
+ pattern = pattern.unescape();
+ UErrorCode status = U_ZERO_ERROR;
+ DecimalFormat fmt(pattern, status);
+ if (!assertSuccess("", status)) {
+ return;
+ }
+ static UChar USD[] = {0x55, 0x53, 0x44, 0x0};
+ fmt.setCurrency(USD);
+ UnicodeString appendTo;
+
+ assertEquals("", "US dollars 12.34", fmt.format(12.34, appendTo));
+
+ UnicodeString topattern;
+ fmt.toPattern(topattern);
+ DecimalFormat fmt2(topattern, status);
+ if (!assertSuccess("", status)) {
+ return;
+ }
+ fmt2.setCurrency(USD);
+
+ appendTo.remove();
+ assertEquals("", "US dollars 12.34", fmt2.format(12.34, appendTo));
+}
+
+
+void NumberFormatTest::verifyFieldPositionIterator(
+ NumberFormatTest_Attributes *expected, FieldPositionIterator &iter) {
+ int32_t idx = 0;
+ FieldPosition fp;
+ while (iter.next(fp)) {
+ if (expected[idx].spos == -1) {
+ errln("Iterator should have ended. got %d", fp.getField());
+ return;
+ }
+ assertEquals("id", expected[idx].id, fp.getField());
+ assertEquals("start", expected[idx].spos, fp.getBeginIndex());
+ assertEquals("end", expected[idx].epos, fp.getEndIndex());
+ ++idx;
+ }
+ if (expected[idx].spos != -1) {
+ errln("Premature end of iterator. expected %d", expected[idx].id);
+ }
+}
+
+void NumberFormatTest::checkExceptionIssue11735() {
+ UErrorCode status;
+ Locale enLocale("en");
+ DecimalFormatSymbols symbols(enLocale, status);
+
+ if (U_FAILURE(status)) {
+ errln((UnicodeString)
+ "Fail: Construct DecimalFormatSymbols");
+ }
+
+ DecimalFormat fmt("0", symbols, status);
+ if (U_FAILURE(status)) {
+ errln((UnicodeString)
+ "Fail: Construct DecimalFormat formatter");
+ }
+
+ ParsePosition ppos(0);
+ fmt.parseCurrency("53.45", ppos); // NPE thrown here in ICU4J.
+ assertEquals("Issue11735 ppos", 0, ppos.getIndex());
+}