crelativedateformattest.c [plain text]
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION
#include "unicode/ureldatefmt.h"
#include "unicode/unum.h"
#include "unicode/udisplaycontext.h"
#include "unicode/ustring.h"
#include "cintltst.h"
#include "cmemory.h"
#include "cformtst.h"
static void TestRelDateFmt(void);
static void TestNumericField(void);
static void TestCombineDateTime(void);
static void TestFields(void);
void addRelativeDateFormatTest(TestNode** root);
#define TESTCASE(x) addTest(root, &x, "tsformat/crelativedateformattest/" #x)
void addRelativeDateFormatTest(TestNode** root)
{
TESTCASE(TestRelDateFmt);
TESTCASE(TestNumericField);
TESTCASE(TestCombineDateTime);
TESTCASE(TestFields);
}
static const double offsets[] = { -5.0, -2.2, -2.0, -1.0, -0.7, -0.0, 0.0, 0.7, 1.0, 2.0, 5.0 };
enum { kNumOffsets = UPRV_LENGTHOF(offsets) };
typedef struct {
int32_t field;
int32_t beginPos;
int32_t endPos;
} FieldsDat;
static const char* en_decDef_long_midSent_sec[kNumOffsets*2] = {
"5 seconds ago", "5 seconds ago",
"2.2 seconds ago", "2.2 seconds ago",
"2 seconds ago", "2 seconds ago",
"1 second ago", "1 second ago",
"0.7 seconds ago", "0.7 seconds ago",
"now", "0 seconds ago",
"now", "in 0 seconds",
"in 0.7 seconds", "in 0.7 seconds",
"in 1 second", "in 1 second",
"in 2 seconds", "in 2 seconds",
"in 5 seconds", "in 5 seconds"
};
static const FieldsDat en_attrDef_long_midSent_sec[kNumOffsets*2] = {
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 6}, {UDAT_REL_NUMERIC_FIELD, 3, 6},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
};
static const char* en_decDef_long_midSent_week[kNumOffsets*2] = {
"5 weeks ago", "5 weeks ago",
"2.2 weeks ago", "2.2 weeks ago",
"2 weeks ago", "2 weeks ago",
"last week", "1 week ago",
"0.7 weeks ago", "0.7 weeks ago",
"this week", "0 weeks ago",
"this week", "in 0 weeks",
"in 0.7 weeks", "in 0.7 weeks",
"next week", "in 1 week",
"in 2 weeks", "in 2 weeks",
"in 5 weeks", "in 5 weeks"
};
static const FieldsDat en_attrDef_long_midSent_week[kNumOffsets*2] = {
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 6}, {UDAT_REL_NUMERIC_FIELD, 3, 6},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
};
static const char* en_dec0_long_midSent_week[kNumOffsets*2] = {
"5 weeks ago", "5 weeks ago",
"2 weeks ago", "2 weeks ago",
"2 weeks ago", "2 weeks ago",
"last week", "1 week ago",
"0 weeks ago", "0 weeks ago",
"this week", "0 weeks ago",
"this week", "in 0 weeks",
"in 0 weeks", "in 0 weeks",
"next week", "in 1 week",
"in 2 weeks", "in 2 weeks",
"in 5 weeks", "in 5 weeks"
};
static const FieldsDat en_attr0_long_midSent_week[kNumOffsets*2] = {
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
};
static const char* en_decDef_short_midSent_week[kNumOffsets*2] = {
"5 wk. ago", "5 wk. ago",
"2.2 wk. ago", "2.2 wk. ago",
"2 wk. ago", "2 wk. ago",
"last wk.", "1 wk. ago",
"0.7 wk. ago", "0.7 wk. ago",
"this wk.", "0 wk. ago",
"this wk.", "in 0 wk.",
"in 0.7 wk.", "in 0.7 wk.",
"next wk.", "in 1 wk.",
"in 2 wk.", "in 2 wk.",
"in 5 wk.", "in 5 wk."
};
static const FieldsDat en_attrDef_short_midSent_week[kNumOffsets*2] = {
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 6}, {UDAT_REL_NUMERIC_FIELD, 3, 6},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
};
static const char* en_decDef_long_midSent_min[kNumOffsets*2] = {
"5 minutes ago", "5 minutes ago",
"2.2 minutes ago", "2.2 minutes ago",
"2 minutes ago", "2 minutes ago",
"1 minute ago", "1 minute ago",
"0.7 minutes ago", "0.7 minutes ago",
"this minute", "0 minutes ago",
"this minute", "in 0 minutes",
"in 0.7 minutes", "in 0.7 minutes",
"in 1 minute", "in 1 minute",
"in 2 minutes", "in 2 minutes",
"in 5 minutes", "in 5 minutes"
};
static const FieldsDat en_attrDef_long_midSent_min[kNumOffsets*2] = {
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3},
{-1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{-1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 6}, {UDAT_REL_NUMERIC_FIELD, 3, 6},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
};
static const char* en_dec0_long_midSent_tues[kNumOffsets*2] = {
"5 Tuesdays ago", "5 Tuesdays ago",
"", "",
"2 Tuesdays ago", "2 Tuesdays ago",
"last Tuesday", "1 Tuesday ago",
"", "",
"this Tuesday", "0 Tuesdays ago",
"this Tuesday", "in 0 Tuesdays",
"", "",
"next Tuesday", "in 1 Tuesday",
"in 2 Tuesdays", "in 2 Tuesdays",
"in 5 Tuesdays", "in 5 Tuesdays",
};
static const FieldsDat en_attr0_long_midSent_tues[kNumOffsets*2] = {
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, { -1, -1, -1},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, { -1, -1, -1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{ -1, -1, -1}, { -1, -1, -1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
};
static const char* fr_decDef_long_midSent_day[kNumOffsets*2] = {
"il y a 5 jours", "il y a 5 jours",
"il y a 2,2 jours", "il y a 2,2 jours",
"avant-hier", "il y a 2 jours",
"hier", "il y a 1 jour",
"il y a 0,7 jour", "il y a 0,7 jour",
"aujourd\\u2019hui", "il y a 0 jour",
"aujourd\\u2019hui", "dans 0 jour",
"dans 0,7 jour", "dans 0,7 jour",
"demain", "dans 1 jour",
"apr\\u00E8s-demain", "dans 2 jours",
"dans 5 jours", "dans 5 jours"
};
static const FieldsDat fr_attrDef_long_midSent_day[kNumOffsets*2] = {
{UDAT_REL_NUMERIC_FIELD, 7, 8}, {UDAT_REL_NUMERIC_FIELD, 7, 8},
{UDAT_REL_NUMERIC_FIELD, 7, 10}, {UDAT_REL_NUMERIC_FIELD, 7, 10},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 7, 8},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 7, 8},
{UDAT_REL_NUMERIC_FIELD, 7, 10}, {UDAT_REL_NUMERIC_FIELD, 7, 10},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 7, 8},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 5, 6},
{UDAT_REL_NUMERIC_FIELD, 5, 8}, {UDAT_REL_NUMERIC_FIELD, 5, 8},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 5, 6},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 5, 6},
{UDAT_REL_NUMERIC_FIELD, 5, 6}, {UDAT_REL_NUMERIC_FIELD, 5, 6},
};
static const char* ak_decDef_long_stdAlon_sec[kNumOffsets*2] = {
"-5 s", "-5 s",
"-2.2 s", "-2.2 s",
"-2 s", "-2 s",
"-1 s", "-1 s",
"-0.7 s", "-0.7 s",
"now", "-0 s",
"now", "+0 s",
"+0.7 s", "+0.7 s",
"+1 s", "+1 s",
"+2 s", "+2 s",
"+5 s", "+5 s",
};
static const FieldsDat ak_attrDef_long_stdAlon_sec[kNumOffsets*2] = {
{UDAT_REL_NUMERIC_FIELD, 1, 2}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
{UDAT_REL_NUMERIC_FIELD, 1, 4}, {UDAT_REL_NUMERIC_FIELD, 1, 4},
{UDAT_REL_NUMERIC_FIELD, 1, 2}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
{UDAT_REL_NUMERIC_FIELD, 1, 2}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
{UDAT_REL_NUMERIC_FIELD, 1, 4}, {UDAT_REL_NUMERIC_FIELD, 1, 4},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
{UDAT_REL_NUMERIC_FIELD, 1, 4}, {UDAT_REL_NUMERIC_FIELD, 1, 4},
{UDAT_REL_NUMERIC_FIELD, 1, 2}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
{UDAT_REL_NUMERIC_FIELD, 1, 2}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
{UDAT_REL_NUMERIC_FIELD, 1, 2}, {UDAT_REL_NUMERIC_FIELD, 1, 2},
};
static const char* enIN_decDef_short_midSent_weds[kNumOffsets*2] = {
"5 Wed. ago", "5 Wed. ago",
"2.2 Wed. ago", "2.2 Wed. ago",
"2 Wed. ago", "2 Wed. ago",
"last Wed", "1 Wed. ago",
"0.7 Wed. ago", "0.7 Wed. ago",
"this Wed", "0 Wed. ago",
"this Wed", "in 0 Wed.",
"in 0.7 Wed.", "in 0.7 Wed.",
"next Wed", "in 1 Wed", "in 2 Wed.", "in 2 Wed.",
"in 5 Wed.", "in 5 Wed."
};
static const FieldsDat enIN_attrDef_short_midSent_weds[kNumOffsets*2] = {
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3},
{UDAT_REL_NUMERIC_FIELD, 0, 1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{UDAT_REL_NUMERIC_FIELD, 0, 3}, {UDAT_REL_NUMERIC_FIELD, 0, 3},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 0, 1},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 6}, {UDAT_REL_NUMERIC_FIELD, 3, 6},
{ -1, -1, -1}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
{UDAT_REL_NUMERIC_FIELD, 3, 4}, {UDAT_REL_NUMERIC_FIELD, 3, 4},
};
static const char* nb_decDef_long_midSent_day[kNumOffsets*2] = {
"for 5 dager siden", "for 5 dager siden",
"for 2,2 dager siden", "for 2,2 dager siden",
"i forg\\u00E5rs", "for 2 dager siden",
"i g\\u00E5r", "for 1 dag siden",
"for 0,7 dager siden", "for 0,7 dager siden",
"i dag", "for 0 dager siden",
"i dag", "om 0 dager",
"om 0,7 dager", "om 0,7 dager",
"i morgen", "om 1 dag",
"i overmorgen", "om 2 dager",
"om 5 dager", "om 5 dager"
};
typedef struct {
const char* locale;
int32_t decPlaces;
UDateRelativeDateTimeFormatterStyle width;
UDisplayContext capContext;
URelativeDateTimeUnit unit;
const char ** expectedResults;
const FieldsDat* expectedAttributes;
} RelDateTimeFormatTestItem;
static const RelDateTimeFormatTestItem fmtTestItems[] = {
{ "en", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_SECOND,
en_decDef_long_midSent_sec, en_attrDef_long_midSent_sec },
{ "en", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_WEEK,
en_decDef_long_midSent_week, en_attrDef_long_midSent_week},
{ "en", 0, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_WEEK,
en_dec0_long_midSent_week, en_attr0_long_midSent_week},
{ "en", -1, UDAT_STYLE_SHORT, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_WEEK,
en_decDef_short_midSent_week, en_attrDef_short_midSent_week},
{ "en", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_MINUTE,
en_decDef_long_midSent_min, en_attrDef_long_midSent_min},
{ "en", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_TUESDAY,
en_dec0_long_midSent_tues, en_attr0_long_midSent_tues},
{ "fr", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_DAY,
fr_decDef_long_midSent_day, fr_attrDef_long_midSent_day},
{ "ak", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, UDAT_REL_UNIT_SECOND,
ak_decDef_long_stdAlon_sec, ak_attrDef_long_stdAlon_sec},
{ "en_IN", -1, UDAT_STYLE_SHORT, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_WEDNESDAY,
enIN_decDef_short_midSent_weds, enIN_attrDef_short_midSent_weds},
{ NULL, 0, (UDateRelativeDateTimeFormatterStyle)0, (UDisplayContext)0, (URelativeDateTimeUnit)0, NULL, NULL }
};
enum { kUBufMax = 64, kBBufMax = 256 };
static void TestRelDateFmt()
{
const RelDateTimeFormatTestItem *itemPtr;
log_verbose("\nTesting ureldatefmt_open(), ureldatefmt_format(), ureldatefmt_formatNumeric() with various parameters\n");
for (itemPtr = fmtTestItems; itemPtr->locale != NULL; itemPtr++) {
URelativeDateTimeFormatter *reldatefmt = NULL;
UNumberFormat* nfToAdopt = NULL;
UErrorCode status = U_ZERO_ERROR;
int32_t iOffset;
if (itemPtr->decPlaces >= 0) {
nfToAdopt = unum_open(UNUM_DECIMAL, NULL, 0, itemPtr->locale, NULL, &status);
if ( U_FAILURE(status) ) {
log_data_err("FAIL: unum_open(UNUM_DECIMAL, ...) for locale %s: %s\n", itemPtr->locale, myErrorName(status));
continue;
}
unum_setAttribute(nfToAdopt, UNUM_MIN_FRACTION_DIGITS, itemPtr->decPlaces);
unum_setAttribute(nfToAdopt, UNUM_MAX_FRACTION_DIGITS, itemPtr->decPlaces);
unum_setAttribute(nfToAdopt, UNUM_ROUNDING_MODE, UNUM_ROUND_DOWN);
}
reldatefmt = ureldatefmt_open(itemPtr->locale, nfToAdopt, itemPtr->width, itemPtr->capContext, &status);
if ( U_FAILURE(status) ) {
log_data_err("FAIL: ureldatefmt_open() for locale %s, decPlaces %d, width %d, capContext %d: %s\n",
itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
myErrorName(status) );
continue;
}
for (iOffset = 0; iOffset < kNumOffsets; iOffset++) {
UChar ubufget[kUBufMax];
int32_t ulenget;
if (itemPtr->unit >= UDAT_REL_UNIT_SUNDAY && offsets[iOffset] != -1.0 && offsets[iOffset] != 0.0 && offsets[iOffset] != 1.0) {
continue;
}
status = U_ZERO_ERROR;
ulenget = ureldatefmt_format(reldatefmt, offsets[iOffset], itemPtr->unit, ubufget, kUBufMax, &status);
if ( U_FAILURE(status) ) {
log_err("FAIL: ureldatefmt_format() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d: %s\n",
itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
offsets[iOffset], (int)itemPtr->unit, myErrorName(status) );
} else {
UChar ubufexp[kUBufMax];
int32_t ulenexp = u_unescape(itemPtr->expectedResults[iOffset*2], ubufexp, kUBufMax);
if (ulenget != ulenexp || u_strncmp(ubufget, ubufexp, ulenexp) != 0) {
char bbufget[kBBufMax];
u_austrncpy(bbufget, ubufget, kUBufMax);
log_err("ERROR: ureldatefmt_format() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d;\n expected %s\n get %s\n",
itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
offsets[iOffset], (int)itemPtr->unit, itemPtr->expectedResults[iOffset*2], bbufget );
}
}
if (itemPtr->unit >= UDAT_REL_UNIT_SUNDAY) {
continue;
}
status = U_ZERO_ERROR;
ulenget = ureldatefmt_formatNumeric(reldatefmt, offsets[iOffset], itemPtr->unit, ubufget, kUBufMax, &status);
if ( U_FAILURE(status) ) {
log_err("FAIL: ureldatefmt_formatNumeric() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d: %s\n",
itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
offsets[iOffset], (int)itemPtr->unit, myErrorName(status) );
} else {
UChar ubufexp[kUBufMax];
int32_t ulenexp = u_unescape(itemPtr->expectedResults[iOffset*2 + 1], ubufexp, kUBufMax);
if (ulenget != ulenexp || u_strncmp(ubufget, ubufexp, ulenexp) != 0) {
char bbufget[kBBufMax];
u_austrncpy(bbufget, ubufget, kUBufMax);
log_err("ERROR: ureldatefmt_formatNumeric() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d;\n expected %s\n get %s\n",
itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
offsets[iOffset], (int)itemPtr->unit, itemPtr->expectedResults[iOffset*2 + 1], bbufget );
}
}
}
ureldatefmt_close(reldatefmt);
}
}
static void TestNumericField()
{
const RelDateTimeFormatTestItem *itemPtr;
log_verbose("\nTesting ureldatefmt_open(), ureldatefmt_formatForFields(), ureldatefmt_formatNumericForFields() with various parameters\n");
for (itemPtr = fmtTestItems; itemPtr->locale != NULL; itemPtr++) {
URelativeDateTimeFormatter *reldatefmt = NULL;
UNumberFormat* nfToAdopt = NULL;
UErrorCode status = U_ZERO_ERROR;
int32_t iOffset;
if (itemPtr->decPlaces >= 0) {
nfToAdopt = unum_open(UNUM_DECIMAL, NULL, 0, itemPtr->locale, NULL, &status);
if ( U_FAILURE(status) ) {
log_data_err("FAIL: unum_open(UNUM_DECIMAL, ...) for locale %s: %s\n", itemPtr->locale, myErrorName(status));
continue;
}
unum_setAttribute(nfToAdopt, UNUM_MIN_FRACTION_DIGITS, itemPtr->decPlaces);
unum_setAttribute(nfToAdopt, UNUM_MAX_FRACTION_DIGITS, itemPtr->decPlaces);
unum_setAttribute(nfToAdopt, UNUM_ROUNDING_MODE, UNUM_ROUND_DOWN);
}
reldatefmt = ureldatefmt_open(itemPtr->locale, nfToAdopt, itemPtr->width, itemPtr->capContext, &status);
if ( U_FAILURE(status) ) {
log_data_err("FAIL: ureldatefmt_open() for locale %s, decPlaces %d, width %d, capContext %d: %s\n",
itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
myErrorName(status) );
continue;
}
for (iOffset = 0; iOffset < kNumOffsets; iOffset++) {
if (itemPtr->unit >= UDAT_REL_UNIT_SUNDAY && offsets[iOffset] != -1.0 && offsets[iOffset] != 0.0 && offsets[iOffset] != 1.0) {
continue;
}
status = U_ZERO_ERROR;
UFormattedRelativeDateTime* fv = ureldatefmt_openResult(&status);
if ( U_FAILURE(status) ) {
log_err("ureldatefmt_openResult fails, status %s\n", u_errorName(status));
continue;
}
ureldatefmt_formatToResult(reldatefmt, offsets[iOffset], itemPtr->unit, fv, &status);
if ( U_FAILURE(status) ) {
log_err("FAIL: ureldatefmt_formatForFields() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d: %s\n",
itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
offsets[iOffset], (int)itemPtr->unit, myErrorName(status) );
} else {
UChar ubufexp[kUBufMax];
int32_t ulenexp = u_unescape(itemPtr->expectedResults[iOffset*2], ubufexp, kUBufMax);
int32_t ulenget;
const UChar* ubufget = ufmtval_getString(ureldatefmt_resultAsValue(fv, &status), &ulenget, &status);
assertUEquals("String content", ubufexp, ubufget);
assertIntEquals("String length", ulenexp, ulenget);
FieldsDat expectedAttr = itemPtr->expectedAttributes[iOffset*2];
UConstrainedFieldPosition* cfpos = ucfpos_open(&status);
UBool foundNumeric = FALSE;
while (TRUE) {
foundNumeric = ufmtval_nextPosition(ureldatefmt_resultAsValue(fv, &status), cfpos, &status);
if (!foundNumeric) {
break;
}
if (ucfpos_getCategory(cfpos, &status) == UFIELD_CATEGORY_RELATIVE_DATETIME
&& ucfpos_getField(cfpos, &status) == UDAT_REL_NUMERIC_FIELD) {
break;
}
}
assertSuccess("Looking for numeric", &status);
int32_t beginPos, endPos;
ucfpos_getIndexes(cfpos, &beginPos, &endPos, &status);
if (expectedAttr.field == -1) {
if (foundNumeric) {
log_err("ureldatefmt_formatForFields as \"%s\"; expect no field, but got %d\n",
itemPtr->expectedResults[iOffset*2],
ucfpos_getField(cfpos, &status));
}
} else {
if (!foundNumeric ||
beginPos != expectedAttr.beginPos ||
endPos != expectedAttr.endPos) {
log_err("ureldatefmt_formatForFields as \"%s\"; expect field %d range %d-%d, get range %d-%d\n",
itemPtr->expectedResults[iOffset*2],
expectedAttr.field, expectedAttr.beginPos, expectedAttr.endPos,
beginPos, endPos);
}
}
ucfpos_close(cfpos);
}
if (itemPtr->unit >= UDAT_REL_UNIT_SUNDAY) {
ureldatefmt_closeResult(fv);
continue;
}
status = U_ZERO_ERROR;
ureldatefmt_formatNumericToResult(reldatefmt, offsets[iOffset], itemPtr->unit, fv, &status);
if ( U_FAILURE(status) ) {
log_err("FAIL: ureldatefmt_formatNumericForFields() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d: %s\n",
itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext,
offsets[iOffset], (int)itemPtr->unit, myErrorName(status) );
} else {
UChar ubufexp[kUBufMax];
int32_t ulenexp = u_unescape(itemPtr->expectedResults[iOffset*2 + 1], ubufexp, kUBufMax);
int32_t ulenget;
const UChar* ubufget = ufmtval_getString(ureldatefmt_resultAsValue(fv, &status), &ulenget, &status);
assertUEquals("String content", ubufexp, ubufget);
assertIntEquals("String length", ulenexp, ulenget);
FieldsDat expectedAttr = itemPtr->expectedAttributes[iOffset*2 + 1];
UConstrainedFieldPosition* cfpos = ucfpos_open(&status);
UBool foundNumeric = FALSE;
while (TRUE) {
foundNumeric = ufmtval_nextPosition(ureldatefmt_resultAsValue(fv, &status), cfpos, &status);
if (!foundNumeric) {
break;
}
if (ucfpos_getCategory(cfpos, &status) == UFIELD_CATEGORY_RELATIVE_DATETIME
&& ucfpos_getField(cfpos, &status) == UDAT_REL_NUMERIC_FIELD) {
break;
}
}
assertSuccess("Looking for numeric", &status);
int32_t beginPos, endPos;
ucfpos_getIndexes(cfpos, &beginPos, &endPos, &status);
if (expectedAttr.field == -1) {
if (foundNumeric) {
log_err("ureldatefmt_formatForFields as \"%s\"; expect no field, but got %d rang %d-%d\n",
itemPtr->expectedResults[iOffset*2],
ucfpos_getField(cfpos, &status), beginPos, endPos);
}
} else {
if (!foundNumeric ||
(beginPos != expectedAttr.beginPos || endPos != expectedAttr.endPos)) {
log_err("ureldatefmt_formatForFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
itemPtr->expectedResults[iOffset*2 + 1],
expectedAttr.field, expectedAttr.beginPos, expectedAttr.endPos,
ucfpos_getField(cfpos, &status), beginPos, endPos);
}
}
ucfpos_close(cfpos);
}
ureldatefmt_closeResult(fv);
}
ureldatefmt_close(reldatefmt);
}
}
typedef struct {
const char* locale;
UDateRelativeDateTimeFormatterStyle width;
UDisplayContext capContext;
const char * relativeDateString;
const char * timeString;
const char * expectedResult;
} CombineDateTimeTestItem;
static const CombineDateTimeTestItem combTestItems[] = {
{ "en", UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, "yesterday", "3:45 PM", "yesterday, 3:45 PM" },
{ "fi", UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, "eilen", "3:45 PM", "eilen klo 3:45 PM" },
{ NULL, (UDateRelativeDateTimeFormatterStyle)0, (UDisplayContext)0, NULL, NULL, NULL }
};
static void TestCombineDateTime()
{
const CombineDateTimeTestItem *itemPtr;
log_verbose("\nTesting ureldatefmt_combineDateAndTime() with various parameters\n");
for (itemPtr = combTestItems; itemPtr->locale != NULL; itemPtr++) {
URelativeDateTimeFormatter *reldatefmt = NULL;
UErrorCode status = U_ZERO_ERROR;
UChar ubufreldate[kUBufMax];
UChar ubuftime[kUBufMax];
UChar ubufget[kUBufMax];
int32_t ulenreldate, ulentime, ulenget;
reldatefmt = ureldatefmt_open(itemPtr->locale, NULL, itemPtr->width, itemPtr->capContext, &status);
if ( U_FAILURE(status) ) {
log_data_err("FAIL: ureldatefmt_open() for locale %s, width %d, capContext %d: %s\n",
itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, myErrorName(status) );
continue;
}
ulenreldate = u_unescape(itemPtr->relativeDateString, ubufreldate, kUBufMax);
ulentime = u_unescape(itemPtr->timeString, ubuftime, kUBufMax);
ulenget = ureldatefmt_combineDateAndTime(reldatefmt, ubufreldate, ulenreldate, ubuftime, ulentime, ubufget, kUBufMax, &status);
if ( U_FAILURE(status) ) {
log_err("FAIL: ureldatefmt_combineDateAndTime() for locale %s, width %d, capContext %d: %s\n",
itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, myErrorName(status) );
} else {
UChar ubufexp[kUBufMax];
int32_t ulenexp = u_unescape(itemPtr->expectedResult, ubufexp, kUBufMax);
if (ulenget != ulenexp || u_strncmp(ubufget, ubufexp, ulenexp) != 0) {
char bbufget[kBBufMax];
u_austrncpy(bbufget, ubufget, kUBufMax);
log_err("ERROR: ureldatefmt_combineDateAndTime() for locale %s, width %d, capContext %d;\n expected %s\n get %s\n",
itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, itemPtr->expectedResult, bbufget );
}
}
status = U_ZERO_ERROR;
ulenget = ureldatefmt_combineDateAndTime(reldatefmt, ubufreldate, ulenreldate, ubuftime, ulentime, NULL, 0, &status);
if ( status != U_BUFFER_OVERFLOW_ERROR) {
log_err("FAIL: ureldatefmt_combineDateAndTime() preflight for locale %s, width %d, capContext %d: expected U_BUFFER_OVERFLOW_ERROR, got %s\n",
itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, myErrorName(status) );
} else {
UChar ubufexp[kUBufMax];
int32_t ulenexp = u_unescape(itemPtr->expectedResult, ubufexp, kUBufMax);
if (ulenget != ulenexp) {
log_err("ERROR: ureldatefmt_combineDateAndTime() preflight for locale %s, width %d, capContext %d;\n expected len %d, get len %d\n",
itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, ulenexp, ulenget );
}
}
ureldatefmt_close(reldatefmt);
}
}
static void TestFields() {
UErrorCode ec = U_ZERO_ERROR;
URelativeDateTimeFormatter* fmt = ureldatefmt_open(
"en-us",
NULL,
UDAT_STYLE_SHORT,
UDISPCTX_CAPITALIZATION_NONE,
&ec);
assertSuccess("Creating RelDTFmt", &ec);
UFormattedRelativeDateTime* frdt = ureldatefmt_openResult(&ec);
assertSuccess("Creating FmtVal", &ec);
ureldatefmt_formatNumericToResult(fmt, -50, UDAT_REL_UNIT_SATURDAY, frdt, &ec);
assertSuccess("formatNumeric", &ec);
{
const UFormattedValue* fv = ureldatefmt_resultAsValue(frdt, &ec);
assertSuccess("Should convert without error", &ec);
static const UFieldPositionWithCategory expectedFieldPositions[] = {
{UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, 0, 2},
{UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD, 0, 2},
{UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 3, 11}};
checkMixedFormattedValue(
"FormattedRelativeDateTime as FormattedValue (numeric)",
fv,
u"50 Sat. ago",
expectedFieldPositions,
UPRV_LENGTHOF(expectedFieldPositions));
}
ureldatefmt_formatToResult(fmt, -1, UDAT_REL_UNIT_WEEK, frdt, &ec);
assertSuccess("format", &ec);
{
const UFormattedValue* fv = ureldatefmt_resultAsValue(frdt, &ec);
assertSuccess("Should convert without error", &ec);
static const UFieldPositionWithCategory expectedFieldPositions[] = {
{UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 0, 8}};
checkMixedFormattedValue(
"FormattedRelativeDateTime as FormattedValue (relative)",
fv,
u"last wk.",
expectedFieldPositions,
UPRV_LENGTHOF(expectedFieldPositions));
}
ureldatefmt_closeResult(frdt);
ureldatefmt_close(fmt);
}
#endif