1/*
2*******************************************************************************
3* Copyright (C) 2013-2014, International Business Machines Corporation and    *
4* others. All Rights Reserved.                                                *
5*******************************************************************************
6*
7* File RELDATEFMTTEST.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/numfmt.h"
20#include "unicode/reldatefmt.h"
21
22#define LENGTHOF(array) (int32_t)(sizeof(array) / sizeof((array)[0]))
23
24static const char *DirectionStr(UDateDirection direction);
25static const char *RelativeUnitStr(UDateRelativeUnit unit);
26static const char *AbsoluteUnitStr(UDateAbsoluteUnit unit);
27
28typedef struct WithQuantityExpected {
29    double value;
30    UDateDirection direction;
31    UDateRelativeUnit unit;
32    const char *expected;
33} WithQuantityExpected;
34
35typedef struct WithoutQuantityExpected {
36    UDateDirection direction;
37    UDateAbsoluteUnit unit;
38    const char *expected;
39} WithoutQuantityExpected;
40
41static WithQuantityExpected kEnglish[] = {
42        {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 0 seconds"},
43        {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 0.5 seconds"},
44        {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 1 second"},
45        {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 2 seconds"},
46        {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 0 minutes"},
47        {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 0.5 minutes"},
48        {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 1 minute"},
49        {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 2 minutes"},
50        {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 0 hours"},
51        {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 0.5 hours"},
52        {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 1 hour"},
53        {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 2 hours"},
54        {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 0 days"},
55        {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 0.5 days"},
56        {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 1 day"},
57        {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 2 days"},
58        {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 0 weeks"},
59        {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 0.5 weeks"},
60        {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 1 week"},
61        {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 2 weeks"},
62        {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 0 months"},
63        {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 0.5 months"},
64        {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 1 month"},
65        {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 2 months"},
66        {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 0 years"},
67        {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 0.5 years"},
68        {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 1 year"},
69        {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 2 years"},
70
71        {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "0 seconds ago"},
72        {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "0.5 seconds ago"},
73        {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "1 second ago"},
74        {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "2 seconds ago"},
75        {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "0 minutes ago"},
76        {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "0.5 minutes ago"},
77        {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "1 minute ago"},
78        {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "2 minutes ago"},
79        {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "0 hours ago"},
80        {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "0.5 hours ago"},
81        {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "1 hour ago"},
82        {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "2 hours ago"},
83        {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "0 days ago"},
84        {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "0.5 days ago"},
85        {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "1 day ago"},
86        {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "2 days ago"},
87        {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "0 weeks ago"},
88        {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "0.5 weeks ago"},
89        {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "1 week ago"},
90        {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "2 weeks ago"},
91        {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "0 months ago"},
92        {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "0.5 months ago"},
93        {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "1 month ago"},
94        {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "2 months ago"},
95        {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "0 years ago"},
96        {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "0.5 years ago"},
97        {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "1 year ago"},
98        {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "2 years ago"}
99};
100
101static WithQuantityExpected kEnglishDecimal[] = {
102        {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 0.0 seconds"},
103        {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 0.5 seconds"},
104        {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 1.0 seconds"},
105        {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 2.0 seconds"}
106};
107
108static WithQuantityExpected kSerbian[] = {
109        {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 0 \\u043c\\u0435\\u0441\\u0435\\u0446\\u0438"},
110        {1.2, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 1,2 \\u043c\\u0435\\u0441\\u0435\\u0446\\u0430"},
111        {21.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 21 \\u043c\\u0435\\u0441\\u0435\\u0446"}
112};
113
114static WithoutQuantityExpected kEnglishNoQuantity[] = {
115        {UDAT_DIRECTION_NEXT_2, UDAT_ABSOLUTE_DAY, ""},
116
117        {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_DAY, "tomorrow"},
118        {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_WEEK, "next week"},
119        {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONTH, "next month"},
120        {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_YEAR, "next year"},
121        {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONDAY, "next Monday"},
122        {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_TUESDAY, "next Tuesday"},
123        {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_WEDNESDAY, "next Wednesday"},
124        {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_THURSDAY, "next Thursday"},
125        {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_FRIDAY, "next Friday"},
126        {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SATURDAY, "next Saturday"},
127        {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SUNDAY, "next Sunday"},
128
129        {UDAT_DIRECTION_LAST_2, UDAT_ABSOLUTE_DAY, ""},
130
131        {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_DAY, "yesterday"},
132        {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_WEEK, "last week"},
133        {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_MONTH, "last month"},
134        {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_YEAR, "last year"},
135        {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_MONDAY, "last Monday"},
136        {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_TUESDAY, "last Tuesday"},
137        {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_WEDNESDAY, "last Wednesday"},
138        {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_THURSDAY, "last Thursday"},
139        {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_FRIDAY, "last Friday"},
140        {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SATURDAY, "last Saturday"},
141        {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SUNDAY, "last Sunday"},
142
143        {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_DAY, "today"},
144        {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_WEEK, "this week"},
145        {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_MONTH, "this month"},
146        {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_YEAR, "this year"},
147        {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_MONDAY, "this Monday"},
148        {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_TUESDAY, "this Tuesday"},
149        {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_WEDNESDAY, "this Wednesday"},
150        {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_THURSDAY, "this Thursday"},
151        {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_FRIDAY, "this Friday"},
152        {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SATURDAY, "this Saturday"},
153        {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SUNDAY, "this Sunday"},
154
155        {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_DAY, "day"},
156        {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_WEEK, "week"},
157        {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_MONTH, "month"},
158        {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_YEAR, "year"},
159        {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_MONDAY, "Monday"},
160        {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_TUESDAY, "Tuesday"},
161        {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_WEDNESDAY, "Wednesday"},
162        {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_THURSDAY, "Thursday"},
163        {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_FRIDAY, "Friday"},
164        {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SATURDAY, "Saturday"},
165        {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SUNDAY, "Sunday"},
166
167        {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_NOW, "now"}
168};
169
170static WithoutQuantityExpected kSpanishNoQuantity[] = {
171        {UDAT_DIRECTION_NEXT_2, UDAT_ABSOLUTE_DAY, "pasado ma\\u00F1ana"},
172        {UDAT_DIRECTION_LAST_2, UDAT_ABSOLUTE_DAY, "antes de ayer"}
173};
174
175class RelativeDateTimeFormatterTest : public IntlTest {
176public:
177    RelativeDateTimeFormatterTest() {
178    }
179
180    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0);
181private:
182    void TestEnglish();
183    void TestSerbian();
184    void TestEnglishNoQuantity();
185    void TestSpanishNoQuantity();
186    void TestFormatWithQuantityIllegalArgument();
187    void TestFormatWithoutQuantityIllegalArgument();
188    void TestCustomNumberFormat();
189    void TestCombineDateAndTime();
190    void RunTest(
191            const Locale& locale,
192            const WithQuantityExpected* expectedResults,
193            int32_t expectedResultLength);
194    void RunTest(
195            const Locale& locale,
196            const WithoutQuantityExpected* expectedResults,
197            int32_t expectedResultLength);
198    void RunTest(
199            const RelativeDateTimeFormatter& fmt,
200            const WithQuantityExpected* expectedResults,
201            int32_t expectedResultLength,
202            const char *description);
203    void RunTest(
204            const RelativeDateTimeFormatter& fmt,
205            const WithoutQuantityExpected* expectedResults,
206            int32_t expectedResultLength,
207            const char *description);
208    void CheckExpectedResult(
209            const RelativeDateTimeFormatter& fmt,
210            const WithQuantityExpected& expectedResult,
211            const char* description);
212    void CheckExpectedResult(
213            const RelativeDateTimeFormatter& fmt,
214            const WithoutQuantityExpected& expectedResult,
215            const char* description);
216    void VerifyIllegalArgument(
217            const RelativeDateTimeFormatter& fmt,
218            UDateDirection direction,
219            UDateRelativeUnit unit);
220    void VerifyIllegalArgument(
221            const RelativeDateTimeFormatter& fmt,
222            UDateDirection direction,
223            UDateAbsoluteUnit unit);
224};
225
226void RelativeDateTimeFormatterTest::runIndexedTest(
227        int32_t index, UBool exec, const char *&name, char *) {
228    if (exec) {
229        logln("TestSuite RelativeDateTimeFormatterTest: ");
230    }
231    TESTCASE_AUTO_BEGIN;
232    TESTCASE_AUTO(TestEnglish);
233    TESTCASE_AUTO(TestSerbian);
234    TESTCASE_AUTO(TestEnglishNoQuantity);
235    TESTCASE_AUTO(TestSpanishNoQuantity);
236    TESTCASE_AUTO(TestFormatWithQuantityIllegalArgument);
237    TESTCASE_AUTO(TestFormatWithoutQuantityIllegalArgument);
238    TESTCASE_AUTO(TestCustomNumberFormat);
239    TESTCASE_AUTO(TestCombineDateAndTime);
240    TESTCASE_AUTO_END;
241}
242
243void RelativeDateTimeFormatterTest::TestEnglish() {
244    RunTest("en", kEnglish, LENGTHOF(kEnglish));
245}
246
247void RelativeDateTimeFormatterTest::TestSerbian() {
248    RunTest("sr", kSerbian, LENGTHOF(kSerbian));
249}
250
251void RelativeDateTimeFormatterTest::TestEnglishNoQuantity() {
252    RunTest("en", kEnglishNoQuantity, LENGTHOF(kEnglishNoQuantity));
253}
254
255void RelativeDateTimeFormatterTest::TestSpanishNoQuantity() {
256    RunTest("es", kSpanishNoQuantity, LENGTHOF(kSpanishNoQuantity));
257}
258
259void RelativeDateTimeFormatterTest::TestFormatWithQuantityIllegalArgument() {
260    UErrorCode status = U_ZERO_ERROR;
261    RelativeDateTimeFormatter fmt("en", status);
262    if (U_FAILURE(status)) {
263        dataerrln("Failure creating format object - %s", u_errorName(status));
264        return;
265    }
266    VerifyIllegalArgument(fmt, UDAT_DIRECTION_PLAIN, UDAT_RELATIVE_DAYS);
267    VerifyIllegalArgument(fmt, UDAT_DIRECTION_THIS, UDAT_RELATIVE_DAYS);
268}
269
270void RelativeDateTimeFormatterTest::TestFormatWithoutQuantityIllegalArgument() {
271    UErrorCode status = U_ZERO_ERROR;
272    RelativeDateTimeFormatter fmt("en", status);
273    if (U_FAILURE(status)) {
274        dataerrln("Failure creating format object - %s", u_errorName(status));
275        return;
276    }
277    VerifyIllegalArgument(fmt, UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_NOW);
278    VerifyIllegalArgument(fmt, UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_NOW);
279    VerifyIllegalArgument(fmt, UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_NOW);
280}
281
282void RelativeDateTimeFormatterTest::TestCustomNumberFormat() {
283    NumberFormat *nf;
284    UErrorCode status = U_ZERO_ERROR;
285    {
286        RelativeDateTimeFormatter fmt("en", status);
287        if (U_FAILURE(status)) {
288            dataerrln(
289                    "Failure creating format object - %s", u_errorName(status));
290            return;
291        }
292        nf = (NumberFormat *) fmt.getNumberFormat().clone();
293    }
294    nf->setMinimumFractionDigits(1);
295    nf->setMaximumFractionDigits(1);
296    RelativeDateTimeFormatter fmt("en", nf, status);
297
298    // Test copy constructor.
299    RelativeDateTimeFormatter fmt2(fmt);
300    RunTest(fmt2, kEnglishDecimal, LENGTHOF(kEnglishDecimal), "en decimal digits");
301
302    // Test assignment
303    fmt = RelativeDateTimeFormatter("es", status);
304    RunTest(fmt, kSpanishNoQuantity, LENGTHOF(kSpanishNoQuantity), "assignment operator");
305
306}
307
308void RelativeDateTimeFormatterTest::TestCombineDateAndTime() {
309    UErrorCode status = U_ZERO_ERROR;
310    RelativeDateTimeFormatter fmt("en", status);
311    if (U_FAILURE(status)) {
312        dataerrln("Failure creating format object - %s", u_errorName(status));
313        return;
314    }
315    UnicodeString actual;
316    fmt.combineDateAndTime(
317        UnicodeString("yesterday"),
318        UnicodeString("3:50"),
319        actual,
320        status);
321    UnicodeString expected("yesterday, 3:50");
322    if (expected != actual) {
323        errln("Expected "+expected+", got "+actual);
324    }
325}
326
327
328void RelativeDateTimeFormatterTest::RunTest(
329        const Locale& locale,
330        const WithQuantityExpected* expectedResults,
331        int32_t expectedResultLength) {
332    UErrorCode status = U_ZERO_ERROR;
333    RelativeDateTimeFormatter fmt(locale, status);
334    if (U_FAILURE(status)) {
335        dataerrln("Unable to create format object - %s", u_errorName(status));
336        return;
337   }
338    RunTest(fmt, expectedResults, expectedResultLength, locale.getName());
339}
340
341void RelativeDateTimeFormatterTest::RunTest(
342        const Locale& locale,
343        const WithoutQuantityExpected* expectedResults,
344        int32_t expectedResultLength) {
345    UErrorCode status = U_ZERO_ERROR;
346    RelativeDateTimeFormatter fmt(locale, status);
347    if (U_FAILURE(status)) {
348        dataerrln("Unable to create format object - %s", u_errorName(status));
349        return;
350    }
351    RunTest(fmt, expectedResults, expectedResultLength, locale.getName());
352}
353
354void RelativeDateTimeFormatterTest::RunTest(
355        const RelativeDateTimeFormatter& fmt,
356        const WithQuantityExpected* expectedResults,
357        int32_t expectedResultLength,
358        const char *description) {
359    for (int32_t i = 0; i < expectedResultLength; ++i) {
360        CheckExpectedResult(fmt, expectedResults[i], description);
361    }
362}
363
364void RelativeDateTimeFormatterTest::RunTest(
365        const RelativeDateTimeFormatter& fmt,
366        const WithoutQuantityExpected* expectedResults,
367        int32_t expectedResultLength,
368        const char *description) {
369    for (int32_t i = 0; i < expectedResultLength; ++i) {
370        CheckExpectedResult(fmt, expectedResults[i], description);
371    }
372}
373
374void RelativeDateTimeFormatterTest::CheckExpectedResult(
375        const RelativeDateTimeFormatter& fmt,
376        const WithQuantityExpected& expectedResult,
377        const char* description) {
378    UErrorCode status = U_ZERO_ERROR;
379    UnicodeString actual;
380    fmt.format(expectedResult.value, expectedResult.direction, expectedResult.unit, actual, status);
381    UnicodeString expected(expectedResult.expected, -1, US_INV);
382    expected = expected.unescape();
383    char buffer[256];
384    sprintf(
385            buffer,
386            "%s, %f, %s, %s",
387            description,
388            expectedResult.value,
389            DirectionStr(expectedResult.direction),
390            RelativeUnitStr(expectedResult.unit));
391    if (actual != expected) {
392        errln(UnicodeString("Fail: Expected: ") + expected
393                + ", Got: " + actual
394                + ", For: " + buffer);
395    }
396}
397
398void RelativeDateTimeFormatterTest::CheckExpectedResult(
399        const RelativeDateTimeFormatter& fmt,
400        const WithoutQuantityExpected& expectedResult,
401        const char* description) {
402    UErrorCode status = U_ZERO_ERROR;
403    UnicodeString actual;
404    fmt.format(expectedResult.direction, expectedResult.unit, actual, status);
405    UnicodeString expected(expectedResult.expected, -1, US_INV);
406    expected = expected.unescape();
407    char buffer[256];
408    sprintf(
409            buffer,
410            "%s, %s, %s",
411            description,
412            DirectionStr(expectedResult.direction),
413            AbsoluteUnitStr(expectedResult.unit));
414    if (actual != expected) {
415        errln(UnicodeString("Fail: Expected: ") + expected
416                + ", Got: " + actual
417                + ", For: " + buffer);
418    }
419}
420
421void RelativeDateTimeFormatterTest::VerifyIllegalArgument(
422        const RelativeDateTimeFormatter& fmt,
423        UDateDirection direction,
424        UDateRelativeUnit unit) {
425    UnicodeString appendTo;
426    UErrorCode status = U_ZERO_ERROR;
427    fmt.format(1.0, direction, unit, appendTo, status);
428    if (status != U_ILLEGAL_ARGUMENT_ERROR) {
429        errln("Expected U_ILLEGAL_ARGUMENT_ERROR, got %s", u_errorName(status));
430    }
431}
432
433void RelativeDateTimeFormatterTest::VerifyIllegalArgument(
434        const RelativeDateTimeFormatter& fmt,
435        UDateDirection direction,
436        UDateAbsoluteUnit unit) {
437    UnicodeString appendTo;
438    UErrorCode status = U_ZERO_ERROR;
439    fmt.format(direction, unit, appendTo, status);
440    if (status != U_ILLEGAL_ARGUMENT_ERROR) {
441        errln("Expected U_ILLEGAL_ARGUMENT_ERROR, got %s", u_errorName(status));
442    }
443}
444
445static const char *kLast2 = "Last_2";
446static const char *kLast = "Last";
447static const char *kThis = "This";
448static const char *kNext = "Next";
449static const char *kNext2 = "Next_2";
450static const char *kPlain = "Plain";
451
452static const char *kSeconds = "Seconds";
453static const char *kMinutes = "Minutes";
454static const char *kHours = "Hours";
455static const char *kDays = "Days";
456static const char *kWeeks = "Weeks";
457static const char *kMonths = "Months";
458static const char *kYears = "Years";
459
460static const char *kSunday = "Sunday";
461static const char *kMonday = "Monday";
462static const char *kTuesday = "Tuesday";
463static const char *kWednesday = "Wednesday";
464static const char *kThursday = "Thursday";
465static const char *kFriday = "Friday";
466static const char *kSaturday = "Saturday";
467static const char *kDay = "Day";
468static const char *kWeek = "Week";
469static const char *kMonth = "Month";
470static const char *kYear = "Year";
471static const char *kNow = "Now";
472
473static const char *kUndefined = "Undefined";
474
475static const char *DirectionStr(
476        UDateDirection direction) {
477    switch (direction) {
478        case UDAT_DIRECTION_LAST_2:
479            return kLast2;
480        case UDAT_DIRECTION_LAST:
481            return kLast;
482        case UDAT_DIRECTION_THIS:
483            return kThis;
484        case UDAT_DIRECTION_NEXT:
485            return kNext;
486        case UDAT_DIRECTION_NEXT_2:
487            return kNext2;
488        case UDAT_DIRECTION_PLAIN:
489            return kPlain;
490        default:
491            return kUndefined;
492    }
493    return kUndefined;
494}
495
496static const char *RelativeUnitStr(
497        UDateRelativeUnit unit) {
498    switch (unit) {
499        case UDAT_RELATIVE_SECONDS:
500            return kSeconds;
501        case UDAT_RELATIVE_MINUTES:
502            return kMinutes;
503        case UDAT_RELATIVE_HOURS:
504            return kHours;
505        case UDAT_RELATIVE_DAYS:
506            return kDays;
507        case UDAT_RELATIVE_WEEKS:
508            return kWeeks;
509        case UDAT_RELATIVE_MONTHS:
510            return kMonths;
511        case UDAT_RELATIVE_YEARS:
512            return kYears;
513        default:
514            return kUndefined;
515    }
516    return kUndefined;
517}
518
519static const char *AbsoluteUnitStr(
520        UDateAbsoluteUnit unit) {
521    switch (unit) {
522        case UDAT_ABSOLUTE_SUNDAY:
523            return kSunday;
524        case UDAT_ABSOLUTE_MONDAY:
525            return kMonday;
526        case UDAT_ABSOLUTE_TUESDAY:
527            return kTuesday;
528        case UDAT_ABSOLUTE_WEDNESDAY:
529            return kWednesday;
530        case UDAT_ABSOLUTE_THURSDAY:
531            return kThursday;
532        case UDAT_ABSOLUTE_FRIDAY:
533            return kFriday;
534        case UDAT_ABSOLUTE_SATURDAY:
535            return kSaturday;
536        case UDAT_ABSOLUTE_DAY:
537            return kDay;
538        case UDAT_ABSOLUTE_WEEK:
539            return kWeek;
540        case UDAT_ABSOLUTE_MONTH:
541            return kMonth;
542        case UDAT_ABSOLUTE_YEAR:
543            return kYear;
544        case UDAT_ABSOLUTE_NOW:
545            return kNow;
546        default:
547            return kUndefined;
548    }
549    return kUndefined;
550}
551
552extern IntlTest *createRelativeDateTimeFormatterTest() {
553    return new RelativeDateTimeFormatterTest();
554}
555
556#endif
557