| // © 2018 and later: Unicode, Inc. and others. |
| // License & terms of use: http://www.unicode.org/copyright.html |
| |
| #include "unicode/utypes.h" |
| |
| #if !UCONFIG_NO_FORMATTING |
| |
| // Allow implicit conversion from char16_t* to UnicodeString for this file: |
| // Helpful in toString methods and elsewhere. |
| #define UNISTR_FROM_STRING_EXPLICIT |
| |
| #include "unicode/unumberformatter.h" |
| #include "unicode/umisc.h" |
| #include "unicode/unum.h" |
| #include "cintltst.h" |
| #include "cmemory.h" |
| |
| static void TestSkeletonFormatToString(void); |
| |
| static void TestSkeletonFormatToFields(void); |
| |
| static void TestExampleCode(void); |
| |
| void addUNumberFormatterTest(TestNode** root); |
| |
| void addUNumberFormatterTest(TestNode** root) { |
| addTest(root, &TestSkeletonFormatToString, "unumberformatter/TestSkeletonFormatToString"); |
| addTest(root, &TestSkeletonFormatToFields, "unumberformatter/TestSkeletonFormatToFields"); |
| addTest(root, &TestExampleCode, "unumberformatter/TestExampleCode"); |
| } |
| |
| |
| #define CAPACITY 30 |
| |
| static void TestSkeletonFormatToString() { |
| UErrorCode ec = U_ZERO_ERROR; |
| UChar buffer[CAPACITY]; |
| UFormattedNumber* result = NULL; |
| |
| // setup: |
| UNumberFormatter* f = unumf_openForSkeletonAndLocale( |
| u"precision-integer currency/USD sign-accounting", -1, "en", &ec); |
| assertSuccessCheck("Should create without error", &ec, TRUE); |
| result = unumf_openResult(&ec); |
| assertSuccess("Should create result without error", &ec); |
| |
| // int64 test: |
| unumf_formatInt(f, -444444, result, &ec); |
| // Missing data will give a U_MISSING_RESOURCE_ERROR here. |
| if (assertSuccessCheck("Should format integer without error", &ec, TRUE)) { |
| unumf_resultToString(result, buffer, CAPACITY, &ec); |
| assertSuccess("Should print string to buffer without error", &ec); |
| assertUEquals("Should produce expected string result", u"($444,444)", buffer); |
| |
| // double test: |
| unumf_formatDouble(f, -5142.3, result, &ec); |
| assertSuccess("Should format double without error", &ec); |
| unumf_resultToString(result, buffer, CAPACITY, &ec); |
| assertSuccess("Should print string to buffer without error", &ec); |
| assertUEquals("Should produce expected string result", u"($5,142)", buffer); |
| |
| // decnumber test: |
| unumf_formatDecimal(f, "9.876E2", -1, result, &ec); |
| assertSuccess("Should format decimal without error", &ec); |
| unumf_resultToString(result, buffer, CAPACITY, &ec); |
| assertSuccess("Should print string to buffer without error", &ec); |
| assertUEquals("Should produce expected string result", u"$988", buffer); |
| } |
| |
| // cleanup: |
| unumf_closeResult(result); |
| unumf_close(f); |
| } |
| |
| |
| static void TestSkeletonFormatToFields() { |
| UErrorCode ec = U_ZERO_ERROR; |
| UFieldPositionIterator* ufpositer = NULL; |
| |
| // setup: |
| UNumberFormatter* uformatter = unumf_openForSkeletonAndLocale( |
| u".00 measure-unit/length-meter sign-always", -1, "en", &ec); |
| assertSuccessCheck("Should create without error", &ec, TRUE); |
| UFormattedNumber* uresult = unumf_openResult(&ec); |
| assertSuccess("Should create result without error", &ec); |
| unumf_formatInt(uformatter, 9876543210L, uresult, &ec); // "+9,876,543,210.00 m" |
| if (assertSuccessCheck("unumf_formatInt() failed", &ec, TRUE)) { |
| |
| // field position test: |
| UFieldPosition ufpos = {UNUM_DECIMAL_SEPARATOR_FIELD}; |
| unumf_resultNextFieldPosition(uresult, &ufpos, &ec); |
| assertIntEquals("Field position should be correct", 14, ufpos.beginIndex); |
| assertIntEquals("Field position should be correct", 15, ufpos.endIndex); |
| |
| // field position iterator test: |
| ufpositer = ufieldpositer_open(&ec); |
| if (assertSuccessCheck("Should create iterator without error", &ec, TRUE)) { |
| |
| unumf_resultGetAllFieldPositions(uresult, ufpositer, &ec); |
| static const UFieldPosition expectedFields[] = { |
| // Field, begin index, end index |
| {UNUM_SIGN_FIELD, 0, 1}, |
| {UNUM_GROUPING_SEPARATOR_FIELD, 2, 3}, |
| {UNUM_GROUPING_SEPARATOR_FIELD, 6, 7}, |
| {UNUM_GROUPING_SEPARATOR_FIELD, 10, 11}, |
| {UNUM_INTEGER_FIELD, 1, 14}, |
| {UNUM_DECIMAL_SEPARATOR_FIELD, 14, 15}, |
| {UNUM_FRACTION_FIELD, 15, 17} |
| }; |
| UFieldPosition actual; |
| for (int32_t i = 0; i < sizeof(expectedFields) / sizeof(*expectedFields); i++) { |
| // Iterate using the UFieldPosition to hold state... |
| UFieldPosition expected = expectedFields[i]; |
| actual.field = ufieldpositer_next(ufpositer, &actual.beginIndex, &actual.endIndex); |
| assertTrue("Should not return a negative index yet", actual.field >= 0); |
| if (expected.field != actual.field) { |
| log_err( |
| "FAIL: iteration %d; expected field %d; got %d\n", i, expected.field, actual.field); |
| } |
| if (expected.beginIndex != actual.beginIndex) { |
| log_err( |
| "FAIL: iteration %d; expected beginIndex %d; got %d\n", |
| i, |
| expected.beginIndex, |
| actual.beginIndex); |
| } |
| if (expected.endIndex != actual.endIndex) { |
| log_err( |
| "FAIL: iteration %d; expected endIndex %d; got %d\n", |
| i, |
| expected.endIndex, |
| actual.endIndex); |
| } |
| } |
| actual.field = ufieldpositer_next(ufpositer, &actual.beginIndex, &actual.endIndex); |
| assertTrue("No more fields; should return a negative index", actual.field < 0); |
| |
| // next field iteration: |
| actual.field = UNUM_GROUPING_SEPARATOR_FIELD; |
| actual.beginIndex = 0; |
| actual.endIndex = 0; |
| int32_t i = 1; |
| while (unumf_resultNextFieldPosition(uresult, &actual, &ec)) { |
| UFieldPosition expected = expectedFields[i++]; |
| assertIntEquals("Grouping separator begin index", expected.beginIndex, actual.beginIndex); |
| assertIntEquals("Grouping separator end index", expected.endIndex, actual.endIndex); |
| } |
| assertIntEquals("Should have seen all grouping separators", 4, i); |
| } |
| } |
| |
| // cleanup: |
| unumf_closeResult(uresult); |
| unumf_close(uformatter); |
| ufieldpositer_close(ufpositer); |
| } |
| |
| |
| static void TestExampleCode() { |
| // This is the example code given in unumberformatter.h. |
| |
| // Setup: |
| UErrorCode ec = U_ZERO_ERROR; |
| UNumberFormatter* uformatter = unumf_openForSkeletonAndLocale(u"precision-integer", -1, "en", &ec); |
| UFormattedNumber* uresult = unumf_openResult(&ec); |
| UChar* buffer = NULL; |
| assertSuccessCheck("There should not be a failure in the example code", &ec, TRUE); |
| |
| // Format a double: |
| unumf_formatDouble(uformatter, 5142.3, uresult, &ec); |
| if (assertSuccessCheck("There should not be a failure in the example code", &ec, TRUE)) { |
| |
| // Export the string to a malloc'd buffer: |
| int32_t len = unumf_resultToString(uresult, NULL, 0, &ec); |
| assertTrue("No buffer yet", ec == U_BUFFER_OVERFLOW_ERROR); |
| ec = U_ZERO_ERROR; |
| buffer = (UChar*) uprv_malloc((len+1)*sizeof(UChar)); |
| unumf_resultToString(uresult, buffer, len+1, &ec); |
| assertSuccess("There should not be a failure in the example code", &ec); |
| assertUEquals("Should produce expected string result", u"5,142", buffer); |
| } |
| |
| // Cleanup: |
| unumf_close(uformatter); |
| unumf_closeResult(uresult); |
| uprv_free(buffer); |
| } |
| |
| |
| #endif /* #if !UCONFIG_NO_FORMATTING */ |