You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
6.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// © 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 <stdio.h>
#include "unicode/unumberformatter.h"
#include "unicode/unumberrangeformatter.h"
#include "unicode/umisc.h"
#include "unicode/unum.h"
#include "unicode/ustring.h"
#include "cformtst.h"
#include "cintltst.h"
#include "cmemory.h"
static void TestExampleCode(void);
static void TestFormattedValue(void);
static void TestSkeletonParseError(void);
static void TestGetDecimalNumbers(void);
void addUNumberRangeFormatterTest(TestNode** root);
#define TESTCASE(x) addTest(root, &x, "tsformat/unumberrangeformatter/" #x)
void addUNumberRangeFormatterTest(TestNode** root) {
TESTCASE(TestExampleCode);
TESTCASE(TestFormattedValue);
TESTCASE(TestSkeletonParseError);
TESTCASE(TestGetDecimalNumbers);
}
#define CAPACITY 30
static void TestExampleCode() {
// This is the example code given in unumberrangeformatter.h.
// Setup:
UErrorCode ec = U_ZERO_ERROR;
UNumberRangeFormatter* uformatter = unumrf_openForSkeletonWithCollapseAndIdentityFallback(
u"currency/USD precision-integer",
-1,
UNUM_RANGE_COLLAPSE_AUTO,
UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
"en-US",
NULL,
&ec);
UFormattedNumberRange* uresult = unumrf_openResult(&ec);
assertSuccessCheck("There should not be a failure in the example code", &ec, TRUE);
// Format a double range:
unumrf_formatDoubleRange(uformatter, 3.0, 5.0, uresult, &ec);
assertSuccessCheck("There should not be a failure in the example code", &ec, TRUE);
// Get the result string:
int32_t len;
const UChar* str = ufmtval_getString(unumrf_resultAsValue(uresult, &ec), &len, &ec);
assertSuccessCheck("There should not be a failure in the example code", &ec, TRUE);
assertUEquals("Should produce expected string result", u"$3 $5", str);
int32_t resultLength = str != NULL ? u_strlen(str) : 0;
assertIntEquals("Length should be as expected", resultLength, len);
// Cleanup:
unumrf_close(uformatter);
unumrf_closeResult(uresult);
}
static void TestFormattedValue() {
UErrorCode ec = U_ZERO_ERROR;
UNumberRangeFormatter* uformatter = unumrf_openForSkeletonWithCollapseAndIdentityFallback(
u"K",
-1,
UNUM_RANGE_COLLAPSE_AUTO,
UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
"en-US",
NULL,
&ec);
assertSuccessCheck("Should create without error", &ec, TRUE);
UFormattedNumberRange* uresult = unumrf_openResult(&ec);
assertSuccess("Should create result without error", &ec);
// Test the decimal number code path, too
unumrf_formatDecimalRange(uformatter, "5.5e4", -1, "1.5e5", -1, uresult, &ec);
if (assertSuccessCheck("Should format without error", &ec, TRUE)) {
const UFormattedValue* fv = unumrf_resultAsValue(uresult, &ec);
assertSuccess("Should convert without error", &ec);
static const UFieldPosition expectedFieldPositions[] = {
// field, begin index, end index
{UNUM_INTEGER_FIELD, 0, 2},
{UNUM_COMPACT_FIELD, 2, 3},
{UNUM_INTEGER_FIELD, 6, 9},
{UNUM_COMPACT_FIELD, 9, 10}};
checkFormattedValue(
"FormattedNumber as FormattedValue",
fv,
u"55K 150K",
UFIELD_CATEGORY_NUMBER,
expectedFieldPositions,
UPRV_LENGTHOF(expectedFieldPositions));
}
assertIntEquals("Identity result should match",
UNUM_IDENTITY_RESULT_NOT_EQUAL,
unumrf_resultGetIdentityResult(uresult, &ec));
// cleanup:
unumrf_closeResult(uresult);
unumrf_close(uformatter);
}
static void TestSkeletonParseError() {
UErrorCode ec = U_ZERO_ERROR;
UNumberRangeFormatter* uformatter;
UParseError perror;
// The UParseError can be null. The following should not segfault.
uformatter = unumrf_openForSkeletonWithCollapseAndIdentityFallback(
u".00 measure-unit/typo",
-1,
UNUM_RANGE_COLLAPSE_AUTO,
UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
"en",
NULL,
&ec);
unumrf_close(uformatter);
// Now test the behavior.
ec = U_ZERO_ERROR;
uformatter = unumrf_openForSkeletonWithCollapseAndIdentityFallback(
u".00 measure-unit/typo",
-1,
UNUM_RANGE_COLLAPSE_AUTO,
UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
"en",
&perror,
&ec);
assertIntEquals("Should have set error code", U_NUMBER_SKELETON_SYNTAX_ERROR, ec);
assertIntEquals("Should have correct skeleton error offset", 17, perror.offset);
assertUEquals("Should have correct pre context", u"0 measure-unit/", perror.preContext);
assertUEquals("Should have correct post context", u"typo", perror.postContext);
// cleanup:
unumrf_close(uformatter);
}
static void TestGetDecimalNumbers() {
UErrorCode ec = U_ZERO_ERROR;
UNumberRangeFormatter* uformatter = unumrf_openForSkeletonWithCollapseAndIdentityFallback(
u"currency/USD",
-1,
UNUM_RANGE_COLLAPSE_AUTO,
UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
"en-US",
NULL,
&ec);
assertSuccessCheck("Should create without error", &ec, TRUE);
UFormattedNumberRange* uresult = unumrf_openResult(&ec);
assertSuccess("Should create result without error", &ec);
unumrf_formatDoubleRange(uformatter, 3.0, 5.0, uresult, &ec);
const UChar* str = ufmtval_getString(unumrf_resultAsValue(uresult, &ec), NULL, &ec);
assertSuccessCheck("Formatting should succeed", &ec, TRUE);
assertUEquals("Should produce expected string result", u"$3.00 \u2013 $5.00", str);
char buffer[CAPACITY];
int32_t len = unumrf_resultGetFirstDecimalNumber(uresult, buffer, CAPACITY, &ec);
assertIntEquals("First len should be as expected", strlen(buffer), len);
assertEquals("First decimal should be as expected", "3", buffer);
len = unumrf_resultGetSecondDecimalNumber(uresult, buffer, CAPACITY, &ec);
assertIntEquals("Second len should be as expected", strlen(buffer), len);
assertEquals("Second decimal should be as expected", "5", buffer);
// cleanup:
unumrf_closeResult(uresult);
unumrf_close(uformatter);
}
#endif /* #if !UCONFIG_NO_FORMATTING */