• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *******************************************************************************
5 * Copyright (C) 2013-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 *******************************************************************************
8 *
9 * File RELDATEFMTTEST.CPP
10 *
11 *******************************************************************************
12 */
13 #include <memory>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <vector>
17 
18 #include "intltest.h"
19 
20 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION
21 
22 #include "unicode/localpointer.h"
23 #include "unicode/numfmt.h"
24 #include "unicode/reldatefmt.h"
25 #include "unicode/rbnf.h"
26 #include "cmemory.h"
27 #include "itformat.h"
28 
29 static const char *DirectionStr(UDateDirection direction);
30 static const char *RelativeUnitStr(UDateRelativeUnit unit);
31 static const char *RelativeDateTimeUnitStr(URelativeDateTimeUnit unit);
32 static const char *AbsoluteUnitStr(UDateAbsoluteUnit unit);
33 
34 typedef struct WithQuantityExpected {
35     double value;
36     UDateDirection direction;
37     UDateRelativeUnit unit;
38     const char *expected;
39 } WithQuantityExpected;
40 
41 typedef struct WithoutQuantityExpected {
42     UDateDirection direction;
43     UDateAbsoluteUnit unit;
44     const char *expected;
45 } WithoutQuantityExpected;
46 
47 static WithQuantityExpected kEnglish[] = {
48         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 0 seconds"},
49         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 0.5 seconds"},
50         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 1 second"},
51         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 2 seconds"},
52         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 0 minutes"},
53         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 0.5 minutes"},
54         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 1 minute"},
55         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 2 minutes"},
56         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 0 hours"},
57         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 0.5 hours"},
58         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 1 hour"},
59         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 2 hours"},
60         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 0 days"},
61         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 0.5 days"},
62         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 1 day"},
63         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 2 days"},
64         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 0 weeks"},
65         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 0.5 weeks"},
66         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 1 week"},
67         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 2 weeks"},
68         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 0 months"},
69         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 0.5 months"},
70         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 1 month"},
71         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 2 months"},
72         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 0 years"},
73         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 0.5 years"},
74         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 1 year"},
75         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 2 years"},
76 
77         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "0 seconds ago"},
78         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "0.5 seconds ago"},
79         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "1 second ago"},
80         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "2 seconds ago"},
81         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "0 minutes ago"},
82         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "0.5 minutes ago"},
83         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "1 minute ago"},
84         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "2 minutes ago"},
85         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "0 hours ago"},
86         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "0.5 hours ago"},
87         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "1 hour ago"},
88         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "2 hours ago"},
89         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "0 days ago"},
90         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "0.5 days ago"},
91         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "1 day ago"},
92         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "2 days ago"},
93         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "0 weeks ago"},
94         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "0.5 weeks ago"},
95         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "1 week ago"},
96         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "2 weeks ago"},
97         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "0 months ago"},
98         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "0.5 months ago"},
99         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "1 month ago"},
100         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "2 months ago"},
101         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "0 years ago"},
102         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "0.5 years ago"},
103         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "1 year ago"},
104         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "2 years ago"}
105 };
106 
107 static WithQuantityExpected kEnglishCaps[] = {
108         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "In 0 seconds"},
109         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "In 0.5 seconds"},
110         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "In 1 second"},
111         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "In 2 seconds"},
112         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "In 0 minutes"},
113         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "In 0.5 minutes"},
114         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "In 1 minute"},
115         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "In 2 minutes"},
116         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "In 0 hours"},
117         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "In 0.5 hours"},
118         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "In 1 hour"},
119         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "In 2 hours"},
120         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "In 0 days"},
121         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "In 0.5 days"},
122         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "In 1 day"},
123         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "In 2 days"},
124         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "In 0 weeks"},
125         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "In 0.5 weeks"},
126         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "In 1 week"},
127         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "In 2 weeks"},
128         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "In 0 months"},
129         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "In 0.5 months"},
130         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "In 1 month"},
131         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "In 2 months"},
132         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "In 0 years"},
133         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "In 0.5 years"},
134         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "In 1 year"},
135         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "In 2 years"},
136 
137         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "0 seconds ago"},
138         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "0.5 seconds ago"},
139         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "1 second ago"},
140         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "2 seconds ago"},
141         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "0 minutes ago"},
142         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "0.5 minutes ago"},
143         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "1 minute ago"},
144         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "2 minutes ago"},
145         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "0 hours ago"},
146         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "0.5 hours ago"},
147         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "1 hour ago"},
148         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "2 hours ago"},
149         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "0 days ago"},
150         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "0.5 days ago"},
151         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "1 day ago"},
152         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "2 days ago"},
153         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "0 weeks ago"},
154         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "0.5 weeks ago"},
155         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "1 week ago"},
156         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "2 weeks ago"},
157         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "0 months ago"},
158         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "0.5 months ago"},
159         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "1 month ago"},
160         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "2 months ago"},
161         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "0 years ago"},
162         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "0.5 years ago"},
163         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "1 year ago"},
164         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "2 years ago"}
165 };
166 
167 static WithQuantityExpected kEnglishShort[] = {
168         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 0 sec."},
169         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 0.5 sec."},
170         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 1 sec."},
171         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 2 sec."},
172         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 0 min."},
173         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 0.5 min."},
174         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 1 min."},
175         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 2 min."},
176         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 0 hr."},
177         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 0.5 hr."},
178         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 1 hr."},
179         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 2 hr."},
180         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 0 days"},
181         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 0.5 days"},
182         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 1 day"},
183         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 2 days"},
184         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 0 wk."},
185         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 0.5 wk."},
186         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 1 wk."},
187         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 2 wk."},
188         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 0 mo."},
189         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 0.5 mo."},
190         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 1 mo."},
191         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 2 mo."},
192         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 0 yr."},
193         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 0.5 yr."},
194         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 1 yr."},
195         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 2 yr."},
196         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "0 sec. ago"},
197         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "0.5 sec. ago"},
198         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "1 sec. ago"},
199         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "2 sec. ago"},
200         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "0 min. ago"},
201         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "0.5 min. ago"},
202         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "1 min. ago"},
203         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "2 min. ago"},
204         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "0 hr. ago"},
205         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "0.5 hr. ago"},
206         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "1 hr. ago"},
207         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "2 hr. ago"},
208         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "0 days ago"},
209         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "0.5 days ago"},
210         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "1 day ago"},
211         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "2 days ago"},
212         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "0 wk. ago"},
213         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "0.5 wk. ago"},
214         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "1 wk. ago"},
215         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "2 wk. ago"},
216         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "0 mo. ago"},
217         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "0.5 mo. ago"},
218         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "1 mo. ago"},
219         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "2 mo. ago"},
220         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "0 yr. ago"},
221         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "0.5 yr. ago"},
222         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "1 yr. ago"},
223         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "2 yr. ago"}
224 };
225 
226 static WithQuantityExpected kEnglishNarrow[] = {
227         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 0s"},
228         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 0.5s"},
229         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 1s"},
230         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 2s"},
231         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 0m"},
232         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 0.5m"},
233         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 1m"},
234         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MINUTES, "in 2m"},
235         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 0h"},
236         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 0.5h"},
237         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 1h"},
238         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_HOURS, "in 2h"},
239         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 0d"},
240         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 0.5d"},
241         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 1d"},
242         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, "in 2d"},
243         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 0w"},
244         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 0.5w"},
245         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 1w"},
246         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_WEEKS, "in 2w"},
247         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 0mo"},
248         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 0.5mo"},
249         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 1mo"},
250         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "in 2mo"},
251         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 0y"},
252         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 0.5y"},
253         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 1y"},
254         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_YEARS, "in 2y"},
255 
256         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "0s ago"},
257         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "0.5s ago"},
258         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "1s ago"},
259         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_SECONDS, "2s ago"},
260         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "0m ago"},
261         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "0.5m ago"},
262         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "1m ago"},
263         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MINUTES, "2m ago"},
264         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "0h ago"},
265         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "0.5h ago"},
266         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "1h ago"},
267         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, "2h ago"},
268         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "0d ago"},
269         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "0.5d ago"},
270         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "1d ago"},
271         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, "2d ago"},
272         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "0w ago"},
273         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "0.5w ago"},
274         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "1w ago"},
275         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_WEEKS, "2w ago"},
276         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "0mo ago"},
277         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "0.5mo ago"},
278         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "1mo ago"},
279         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "2mo ago"},
280         {0.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "0y ago"},
281         {0.5, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "0.5y ago"},
282         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "1y ago"},
283         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, "2y ago"}
284 };
285 
286 static WithQuantityExpected kEnglishDecimal[] = {
287         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 0.0 seconds"},
288         {0.5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 0.5 seconds"},
289         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 1.0 seconds"},
290         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, "in 2.0 seconds"}
291 };
292 
293 static WithQuantityExpected kSerbian[] = {
294         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 0 \\u043c\\u0435\\u0441\\u0435\\u0446\\u0438"},
295         {1.2, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 1,2 \\u043c\\u0435\\u0441\\u0435\\u0446\\u0430"},
296         {21.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 21 \\u043c\\u0435\\u0441\\u0435\\u0446"}
297 };
298 
299 static WithQuantityExpected kSerbianNarrow[] = {
300         {0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 0 \\u043c."},
301         {1.2, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 1,2 \\u043c."},
302         {21.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "\\u0437\\u0430 21 \\u043c."}
303 };
304 
305 static WithoutQuantityExpected kEnglishNoQuantity[] = {
306         {UDAT_DIRECTION_NEXT_2, UDAT_ABSOLUTE_DAY, ""},
307 
308         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_DAY, "tomorrow"},
309         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_WEEK, "next week"},
310         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONTH, "next month"},
311         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_QUARTER, "next quarter"},
312         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_YEAR, "next year"},
313         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONDAY, "next Monday"},
314         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_TUESDAY, "next Tuesday"},
315         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_WEDNESDAY, "next Wednesday"},
316         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_THURSDAY, "next Thursday"},
317         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_FRIDAY, "next Friday"},
318         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SATURDAY, "next Saturday"},
319         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SUNDAY, "next Sunday"},
320 
321         {UDAT_DIRECTION_LAST_2, UDAT_ABSOLUTE_DAY, ""},
322 
323         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_DAY, "yesterday"},
324         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_WEEK, "last week"},
325         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_MONTH, "last month"},
326         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_QUARTER, "last quarter"},
327         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_YEAR, "last year"},
328         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_MONDAY, "last Monday"},
329         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_TUESDAY, "last Tuesday"},
330         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_WEDNESDAY, "last Wednesday"},
331         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_THURSDAY, "last Thursday"},
332         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_FRIDAY, "last Friday"},
333         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SATURDAY, "last Saturday"},
334         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SUNDAY, "last Sunday"},
335 
336         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_DAY, "today"},
337         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_WEEK, "this week"},
338         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_MONTH, "this month"},
339         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_QUARTER, "this quarter"},
340         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_YEAR, "this year"},
341         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_MONDAY, "this Monday"},
342         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_TUESDAY, "this Tuesday"},
343         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_WEDNESDAY, "this Wednesday"},
344         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_THURSDAY, "this Thursday"},
345         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_FRIDAY, "this Friday"},
346         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SATURDAY, "this Saturday"},
347         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SUNDAY, "this Sunday"},
348         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_HOUR, "this hour"},
349         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_MINUTE, "this minute"},
350 
351         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_DAY, "day"},
352         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_WEEK, "week"},
353         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_MONTH, "month"},
354         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_QUARTER, "quarter"},
355         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_YEAR, "year"},
356         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_MONDAY, "Monday"},
357         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_TUESDAY, "Tuesday"},
358         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_WEDNESDAY, "Wednesday"},
359         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_THURSDAY, "Thursday"},
360         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_FRIDAY, "Friday"},
361         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SATURDAY, "Saturday"},
362         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SUNDAY, "Sunday"},
363         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_HOUR, "hour"},
364         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_MINUTE, "minute"},
365 
366         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_NOW, "now"}
367 };
368 
369 static WithoutQuantityExpected kEnglishNoQuantityCaps[] = {
370         {UDAT_DIRECTION_NEXT_2, UDAT_ABSOLUTE_DAY, ""},
371 
372         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_DAY, "Tomorrow"},
373         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_WEEK, "Next week"},
374         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONTH, "Next month"},
375         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_QUARTER, "Next quarter"},
376         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_YEAR, "Next year"},
377         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONDAY, "Next Monday"},
378         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_TUESDAY, "Next Tuesday"},
379         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_WEDNESDAY, "Next Wednesday"},
380         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_THURSDAY, "Next Thursday"},
381         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_FRIDAY, "Next Friday"},
382         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SATURDAY, "Next Saturday"},
383         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SUNDAY, "Next Sunday"},
384 
385         {UDAT_DIRECTION_LAST_2, UDAT_ABSOLUTE_DAY, ""},
386 
387         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_DAY, "Yesterday"},
388         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_WEEK, "Last week"},
389         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_MONTH, "Last month"},
390         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_QUARTER, "Last quarter"},
391         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_YEAR, "Last year"},
392         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_MONDAY, "Last Monday"},
393         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_TUESDAY, "Last Tuesday"},
394         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_WEDNESDAY, "Last Wednesday"},
395         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_THURSDAY, "Last Thursday"},
396         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_FRIDAY, "Last Friday"},
397         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SATURDAY, "Last Saturday"},
398         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SUNDAY, "Last Sunday"},
399 
400         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_DAY, "Today"},
401         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_WEEK, "This week"},
402         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_MONTH, "This month"},
403         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_QUARTER, "This quarter"},
404         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_YEAR, "This year"},
405         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_MONDAY, "This Monday"},
406         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_TUESDAY, "This Tuesday"},
407         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_WEDNESDAY, "This Wednesday"},
408         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_THURSDAY, "This Thursday"},
409         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_FRIDAY, "This Friday"},
410         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SATURDAY, "This Saturday"},
411         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SUNDAY, "This Sunday"},
412 
413         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_DAY, "Day"},
414         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_WEEK, "Week"},
415         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_MONTH, "Month"},
416         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_QUARTER, "Quarter"},
417         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_YEAR, "Year"},
418         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_MONDAY, "Monday"},
419         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_TUESDAY, "Tuesday"},
420         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_WEDNESDAY, "Wednesday"},
421         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_THURSDAY, "Thursday"},
422         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_FRIDAY, "Friday"},
423         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SATURDAY, "Saturday"},
424         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SUNDAY, "Sunday"},
425 
426         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_NOW, "Now"}
427 };
428 
429 static WithoutQuantityExpected kEnglishNoQuantityShort[] = {
430         {UDAT_DIRECTION_NEXT_2, UDAT_ABSOLUTE_DAY, ""},
431 
432         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_DAY, "tomorrow"},
433         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_WEEK, "next wk."},
434         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONTH, "next mo."},
435         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_QUARTER, "next qtr."},
436         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_YEAR, "next yr."},
437         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONDAY, "next Mon."},
438         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_TUESDAY, "next Tue."},
439         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_WEDNESDAY, "next Wed."},
440         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_THURSDAY, "next Thu."},
441         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_FRIDAY, "next Fri."},
442         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SATURDAY, "next Sat."},
443         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SUNDAY, "next Sun."},
444 
445         {UDAT_DIRECTION_LAST_2, UDAT_ABSOLUTE_DAY, ""},
446 
447         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_DAY, "yesterday"},
448         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_WEEK, "last wk."},
449         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_MONTH, "last mo."},
450         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_QUARTER, "last qtr."},
451         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_YEAR, "last yr."},
452         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_MONDAY, "last Mon."},
453         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_TUESDAY, "last Tue."},
454         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_WEDNESDAY, "last Wed."},
455         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_THURSDAY, "last Thu."},
456         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_FRIDAY, "last Fri."},
457         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SATURDAY, "last Sat."},
458         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SUNDAY, "last Sun."},
459 
460         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_DAY, "today"},
461         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_WEEK, "this wk."},
462         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_MONTH, "this mo."},
463         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_QUARTER, "this qtr."},
464         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_YEAR, "this yr."},
465         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_MONDAY, "this Mon."},
466         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_TUESDAY, "this Tue."},
467         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_WEDNESDAY, "this Wed."},
468         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_THURSDAY, "this Thu."},
469         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_FRIDAY, "this Fri."},
470         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SATURDAY, "this Sat."},
471         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SUNDAY, "this Sun."},
472 
473         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_DAY, "day"},
474         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_WEEK, "wk."},
475         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_MONTH, "mo."},
476         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_QUARTER, "qtr."},
477         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_YEAR, "yr."},
478         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_MONDAY, "Mo"},
479         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_TUESDAY, "Tu"},
480         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_WEDNESDAY, "We"},
481         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_THURSDAY, "Th"},
482         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_FRIDAY, "Fr"},
483         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SATURDAY, "Sa"},
484         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SUNDAY, "Su"},
485 
486         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_NOW, "now"}
487 };
488 
489 static WithoutQuantityExpected kEnglishNoQuantityNarrow[] = {
490         {UDAT_DIRECTION_NEXT_2, UDAT_ABSOLUTE_DAY, ""},
491 
492         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_DAY, "tomorrow"},
493         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_WEEK, "next wk."},
494         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONTH, "next mo."},
495         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_QUARTER, "next qtr."},
496         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_YEAR, "next yr."},
497         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONDAY, "next M"},
498         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_TUESDAY, "next Tu"},
499         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_WEDNESDAY, "next W"},
500         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_THURSDAY, "next Th"},
501         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_FRIDAY, "next F"},
502         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SATURDAY, "next Sa"},
503         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SUNDAY, "next Su"},
504 
505         {UDAT_DIRECTION_LAST_2, UDAT_ABSOLUTE_DAY, ""},
506 
507         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_DAY, "yesterday"},
508         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_WEEK, "last wk."},
509         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_MONTH, "last mo."},
510         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_QUARTER, "last qtr."},
511         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_YEAR, "last yr."},
512         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_MONDAY, "last M"},
513         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_TUESDAY, "last Tu"},
514         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_WEDNESDAY, "last W"},
515         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_THURSDAY, "last Th"},
516         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_FRIDAY, "last F"},
517         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SATURDAY, "last Sa"},
518         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SUNDAY, "last Su"},
519 
520         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_DAY, "today"},
521         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_WEEK, "this wk."},
522         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_MONTH, "this mo."},
523         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_QUARTER, "this qtr."},
524         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_YEAR, "this yr."},
525         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_MONDAY, "this M"},
526         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_TUESDAY, "this Tu"},
527         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_WEDNESDAY, "this W"},
528         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_THURSDAY, "this Th"},
529         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_FRIDAY, "this F"},
530         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SATURDAY, "this Sa"},
531         {UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SUNDAY, "this Su"},
532 
533         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_DAY, "day"},
534         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_WEEK, "wk"},
535         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_MONTH, "mo"},
536         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_QUARTER, "qtr"},
537         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_YEAR, "yr"},
538         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_MONDAY, "M"},
539         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_TUESDAY, "T"},
540         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_WEDNESDAY, "W"},
541         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_THURSDAY, "T"},
542         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_FRIDAY, "F"},
543         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SATURDAY, "S"},
544         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SUNDAY, "S"},
545 
546         {UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_NOW, "now"}
547 };
548 
549 static WithoutQuantityExpected kSpanishNoQuantity[] = {
550         {UDAT_DIRECTION_NEXT_2, UDAT_ABSOLUTE_DAY, "pasado ma\\u00F1ana"},
551         {UDAT_DIRECTION_LAST_2, UDAT_ABSOLUTE_DAY, "anteayer"}
552 };
553 
554 typedef struct WithQuantityExpectedRelativeDateTimeUnit {
555     double value;
556     URelativeDateTimeUnit unit;
557     const char *expected;
558 } WithQuantityExpectedRelativeDateTimeUnit;
559 
560 static WithQuantityExpectedRelativeDateTimeUnit kEnglishFormatNumeric[] = {
561         {0.0, UDAT_REL_UNIT_SECOND, "in 0 seconds"},
562         {0.5, UDAT_REL_UNIT_SECOND, "in 0.5 seconds"},
563         {1.0, UDAT_REL_UNIT_SECOND, "in 1 second"},
564         {2.0, UDAT_REL_UNIT_SECOND, "in 2 seconds"},
565         {0.0, UDAT_REL_UNIT_MINUTE, "in 0 minutes"},
566         {0.5, UDAT_REL_UNIT_MINUTE, "in 0.5 minutes"},
567         {1.0, UDAT_REL_UNIT_MINUTE, "in 1 minute"},
568         {2.0, UDAT_REL_UNIT_MINUTE, "in 2 minutes"},
569         {0.0, UDAT_REL_UNIT_HOUR, "in 0 hours"},
570         {0.5, UDAT_REL_UNIT_HOUR, "in 0.5 hours"},
571         {1.0, UDAT_REL_UNIT_HOUR, "in 1 hour"},
572         {2.0, UDAT_REL_UNIT_HOUR, "in 2 hours"},
573         {0.0, UDAT_REL_UNIT_DAY, "in 0 days"},
574         {0.5, UDAT_REL_UNIT_DAY, "in 0.5 days"},
575         {1.0, UDAT_REL_UNIT_DAY, "in 1 day"},
576         {2.0, UDAT_REL_UNIT_DAY, "in 2 days"},
577         {0.0, UDAT_REL_UNIT_WEEK, "in 0 weeks"},
578         {0.5, UDAT_REL_UNIT_WEEK, "in 0.5 weeks"},
579         {1.0, UDAT_REL_UNIT_WEEK, "in 1 week"},
580         {2.0, UDAT_REL_UNIT_WEEK, "in 2 weeks"},
581         {0.0, UDAT_REL_UNIT_MONTH, "in 0 months"},
582         {0.5, UDAT_REL_UNIT_MONTH, "in 0.5 months"},
583         {1.0, UDAT_REL_UNIT_MONTH, "in 1 month"},
584         {2.0, UDAT_REL_UNIT_MONTH, "in 2 months"},
585         {0.0, UDAT_REL_UNIT_QUARTER, "in 0 quarters"},
586         {0.5, UDAT_REL_UNIT_QUARTER, "in 0.5 quarters"},
587         {1.0, UDAT_REL_UNIT_QUARTER, "in 1 quarter"},
588         {2.0, UDAT_REL_UNIT_QUARTER, "in 2 quarters"},
589         {0.0, UDAT_REL_UNIT_YEAR, "in 0 years"},
590         {0.5, UDAT_REL_UNIT_YEAR, "in 0.5 years"},
591         {1.0, UDAT_REL_UNIT_YEAR, "in 1 year"},
592         {2.0, UDAT_REL_UNIT_YEAR, "in 2 years"},
593         {0.0, UDAT_REL_UNIT_SUNDAY, "in 0 Sundays"},
594         {0.5, UDAT_REL_UNIT_SUNDAY, "in 0.5 Sundays"},
595         {1.0, UDAT_REL_UNIT_SUNDAY, "in 1 Sunday"},
596         {2.0, UDAT_REL_UNIT_SUNDAY, "in 2 Sundays"},
597         {0.0, UDAT_REL_UNIT_MONDAY, "in 0 Mondays"},
598         {0.5, UDAT_REL_UNIT_MONDAY, "in 0.5 Mondays"},
599         {1.0, UDAT_REL_UNIT_MONDAY, "in 1 Monday"},
600         {2.0, UDAT_REL_UNIT_MONDAY, "in 2 Mondays"},
601         {0.0, UDAT_REL_UNIT_TUESDAY, "in 0 Tuesdays"},
602         {0.5, UDAT_REL_UNIT_TUESDAY, "in 0.5 Tuesdays"},
603         {1.0, UDAT_REL_UNIT_TUESDAY, "in 1 Tuesday"},
604         {2.0, UDAT_REL_UNIT_TUESDAY, "in 2 Tuesdays"},
605         {0.0, UDAT_REL_UNIT_WEDNESDAY, "in 0 Wednesdays"},
606         {0.5, UDAT_REL_UNIT_WEDNESDAY, "in 0.5 Wednesdays"},
607         {1.0, UDAT_REL_UNIT_WEDNESDAY, "in 1 Wednesday"},
608         {2.0, UDAT_REL_UNIT_WEDNESDAY, "in 2 Wednesdays"},
609         {0.0, UDAT_REL_UNIT_THURSDAY, "in 0 Thursdays"},
610         {0.5, UDAT_REL_UNIT_THURSDAY, "in 0.5 Thursdays"},
611         {1.0, UDAT_REL_UNIT_THURSDAY, "in 1 Thursday"},
612         {2.0, UDAT_REL_UNIT_THURSDAY, "in 2 Thursdays"},
613         {0.0, UDAT_REL_UNIT_FRIDAY, "in 0 Fridays"},
614         {0.5, UDAT_REL_UNIT_FRIDAY, "in 0.5 Fridays"},
615         {1.0, UDAT_REL_UNIT_FRIDAY, "in 1 Friday"},
616         {2.0, UDAT_REL_UNIT_FRIDAY, "in 2 Fridays"},
617         {0.0, UDAT_REL_UNIT_SATURDAY, "in 0 Saturdays"},
618         {0.5, UDAT_REL_UNIT_SATURDAY, "in 0.5 Saturdays"},
619         {1.0, UDAT_REL_UNIT_SATURDAY, "in 1 Saturday"},
620         {2.0, UDAT_REL_UNIT_SATURDAY, "in 2 Saturdays"},
621 
622         {-0.0, UDAT_REL_UNIT_SECOND, "0 seconds ago"},
623         {-0.5, UDAT_REL_UNIT_SECOND, "0.5 seconds ago"},
624         {-1.0, UDAT_REL_UNIT_SECOND, "1 second ago"},
625         {-2.0, UDAT_REL_UNIT_SECOND, "2 seconds ago"},
626         {-0.0, UDAT_REL_UNIT_MINUTE, "0 minutes ago"},
627         {-0.5, UDAT_REL_UNIT_MINUTE, "0.5 minutes ago"},
628         {-1.0, UDAT_REL_UNIT_MINUTE, "1 minute ago"},
629         {-2.0, UDAT_REL_UNIT_MINUTE, "2 minutes ago"},
630         {-0.0, UDAT_REL_UNIT_HOUR, "0 hours ago"},
631         {-0.5, UDAT_REL_UNIT_HOUR, "0.5 hours ago"},
632         {-1.0, UDAT_REL_UNIT_HOUR, "1 hour ago"},
633         {-2.0, UDAT_REL_UNIT_HOUR, "2 hours ago"},
634         {-0.0, UDAT_REL_UNIT_DAY, "0 days ago"},
635         {-0.5, UDAT_REL_UNIT_DAY, "0.5 days ago"},
636         {-1.0, UDAT_REL_UNIT_DAY, "1 day ago"},
637         {-2.0, UDAT_REL_UNIT_DAY, "2 days ago"},
638         {-0.0, UDAT_REL_UNIT_WEEK, "0 weeks ago"},
639         {-0.5, UDAT_REL_UNIT_WEEK, "0.5 weeks ago"},
640         {-1.0, UDAT_REL_UNIT_WEEK, "1 week ago"},
641         {-2.0, UDAT_REL_UNIT_WEEK, "2 weeks ago"},
642         {-0.0, UDAT_REL_UNIT_MONTH, "0 months ago"},
643         {-0.5, UDAT_REL_UNIT_MONTH, "0.5 months ago"},
644         {-1.0, UDAT_REL_UNIT_MONTH, "1 month ago"},
645         {-2.0, UDAT_REL_UNIT_MONTH, "2 months ago"},
646         {-0.0, UDAT_REL_UNIT_QUARTER, "0 quarters ago"},
647         {-0.5, UDAT_REL_UNIT_QUARTER, "0.5 quarters ago"},
648         {-1.0, UDAT_REL_UNIT_QUARTER, "1 quarter ago"},
649         {-2.0, UDAT_REL_UNIT_QUARTER, "2 quarters ago"},
650         {-0.0, UDAT_REL_UNIT_YEAR, "0 years ago"},
651         {-0.5, UDAT_REL_UNIT_YEAR, "0.5 years ago"},
652         {-1.0, UDAT_REL_UNIT_YEAR, "1 year ago"},
653         {-2.0, UDAT_REL_UNIT_YEAR, "2 years ago"},
654         {-0.0, UDAT_REL_UNIT_SUNDAY, "0 Sundays ago"},
655         {-0.5, UDAT_REL_UNIT_SUNDAY, "0.5 Sundays ago"},
656         {-1.0, UDAT_REL_UNIT_SUNDAY, "1 Sunday ago"},
657         {-2.0, UDAT_REL_UNIT_SUNDAY, "2 Sundays ago"},
658         {-0.0, UDAT_REL_UNIT_MONDAY, "0 Mondays ago"},
659         {-0.5, UDAT_REL_UNIT_MONDAY, "0.5 Mondays ago"},
660         {-1.0, UDAT_REL_UNIT_MONDAY, "1 Monday ago"},
661         {-2.0, UDAT_REL_UNIT_MONDAY, "2 Mondays ago"},
662         {-0.0, UDAT_REL_UNIT_TUESDAY, "0 Tuesdays ago"},
663         {-0.5, UDAT_REL_UNIT_TUESDAY, "0.5 Tuesdays ago"},
664         {-1.0, UDAT_REL_UNIT_TUESDAY, "1 Tuesday ago"},
665         {-2.0, UDAT_REL_UNIT_TUESDAY, "2 Tuesdays ago"},
666         {-0.0, UDAT_REL_UNIT_WEDNESDAY, "0 Wednesdays ago"},
667         {-0.5, UDAT_REL_UNIT_WEDNESDAY, "0.5 Wednesdays ago"},
668         {-1.0, UDAT_REL_UNIT_WEDNESDAY, "1 Wednesday ago"},
669         {-2.0, UDAT_REL_UNIT_WEDNESDAY, "2 Wednesdays ago"},
670         {-0.0, UDAT_REL_UNIT_THURSDAY, "0 Thursdays ago"},
671         {-0.5, UDAT_REL_UNIT_THURSDAY, "0.5 Thursdays ago"},
672         {-1.0, UDAT_REL_UNIT_THURSDAY, "1 Thursday ago"},
673         {-2.0, UDAT_REL_UNIT_THURSDAY, "2 Thursdays ago"},
674         {-0.0, UDAT_REL_UNIT_FRIDAY, "0 Fridays ago"},
675         {-0.5, UDAT_REL_UNIT_FRIDAY, "0.5 Fridays ago"},
676         {-1.0, UDAT_REL_UNIT_FRIDAY, "1 Friday ago"},
677         {-2.0, UDAT_REL_UNIT_FRIDAY, "2 Fridays ago"},
678         {-0.0, UDAT_REL_UNIT_SATURDAY, "0 Saturdays ago"},
679         {-0.5, UDAT_REL_UNIT_SATURDAY, "0.5 Saturdays ago"},
680         {-1.0, UDAT_REL_UNIT_SATURDAY, "1 Saturday ago"},
681         {-2.0, UDAT_REL_UNIT_SATURDAY, "2 Saturdays ago"}
682 };
683 
684 static WithQuantityExpectedRelativeDateTimeUnit kEnglishFormat[] = {
685         {0.0, UDAT_REL_UNIT_SECOND, "now"},
686         {0.5, UDAT_REL_UNIT_SECOND, "in 0.5 seconds"},
687         {1.0, UDAT_REL_UNIT_SECOND, "in 1 second"},
688         {2.0, UDAT_REL_UNIT_SECOND, "in 2 seconds"},
689         {0.0, UDAT_REL_UNIT_MINUTE, "this minute"},
690         {0.5, UDAT_REL_UNIT_MINUTE, "in 0.5 minutes"},
691         {1.0, UDAT_REL_UNIT_MINUTE, "in 1 minute"},
692         {2.0, UDAT_REL_UNIT_MINUTE, "in 2 minutes"},
693         {0.0, UDAT_REL_UNIT_HOUR, "this hour"},
694         {0.5, UDAT_REL_UNIT_HOUR, "in 0.5 hours"},
695         {1.0, UDAT_REL_UNIT_HOUR, "in 1 hour"},
696         {2.0, UDAT_REL_UNIT_HOUR, "in 2 hours"},
697         {0.0, UDAT_REL_UNIT_DAY, "today"},
698         {0.5, UDAT_REL_UNIT_DAY, "in 0.5 days"},
699         {1.0, UDAT_REL_UNIT_DAY, "tomorrow"},
700         {2.0, UDAT_REL_UNIT_DAY, "in 2 days"},
701         {0.0, UDAT_REL_UNIT_WEEK, "this week"},
702         {0.5, UDAT_REL_UNIT_WEEK, "in 0.5 weeks"},
703         {1.0, UDAT_REL_UNIT_WEEK, "next week"},
704         {2.0, UDAT_REL_UNIT_WEEK, "in 2 weeks"},
705         {0.0, UDAT_REL_UNIT_MONTH, "this month"},
706         {0.5, UDAT_REL_UNIT_MONTH, "in 0.5 months"},
707         {1.0, UDAT_REL_UNIT_MONTH, "next month"},
708         {2.0, UDAT_REL_UNIT_MONTH, "in 2 months"},
709         {0.0, UDAT_REL_UNIT_QUARTER, "this quarter"},
710         {0.5, UDAT_REL_UNIT_QUARTER, "in 0.5 quarters"},
711         {1.0, UDAT_REL_UNIT_QUARTER, "next quarter"},
712         {2.0, UDAT_REL_UNIT_QUARTER, "in 2 quarters"},
713         {0.0, UDAT_REL_UNIT_YEAR, "this year"},
714         {0.5, UDAT_REL_UNIT_YEAR, "in 0.5 years"},
715         {1.0, UDAT_REL_UNIT_YEAR, "next year"},
716         {2.0, UDAT_REL_UNIT_YEAR, "in 2 years"},
717         {0.0, UDAT_REL_UNIT_SUNDAY, "this Sunday"},
718         {0.5, UDAT_REL_UNIT_SUNDAY, "in 0.5 Sundays"},
719         {1.0, UDAT_REL_UNIT_SUNDAY, "next Sunday"},
720         {2.0, UDAT_REL_UNIT_SUNDAY, "in 2 Sundays"},
721         {0.0, UDAT_REL_UNIT_MONDAY, "this Monday"},
722         {0.5, UDAT_REL_UNIT_MONDAY, "in 0.5 Mondays"},
723         {1.0, UDAT_REL_UNIT_MONDAY, "next Monday"},
724         {2.0, UDAT_REL_UNIT_MONDAY, "in 2 Mondays"},
725         {0.0, UDAT_REL_UNIT_TUESDAY, "this Tuesday"},
726         {0.5, UDAT_REL_UNIT_TUESDAY, "in 0.5 Tuesdays"},
727         {1.0, UDAT_REL_UNIT_TUESDAY, "next Tuesday"},
728         {2.0, UDAT_REL_UNIT_TUESDAY, "in 2 Tuesdays"},
729         {0.0, UDAT_REL_UNIT_WEDNESDAY, "this Wednesday"},
730         {0.5, UDAT_REL_UNIT_WEDNESDAY, "in 0.5 Wednesdays"},
731         {1.0, UDAT_REL_UNIT_WEDNESDAY, "next Wednesday"},
732         {2.0, UDAT_REL_UNIT_WEDNESDAY, "in 2 Wednesdays"},
733         {0.0, UDAT_REL_UNIT_THURSDAY, "this Thursday"},
734         {0.5, UDAT_REL_UNIT_THURSDAY, "in 0.5 Thursdays"},
735         {1.0, UDAT_REL_UNIT_THURSDAY, "next Thursday"},
736         {2.0, UDAT_REL_UNIT_THURSDAY, "in 2 Thursdays"},
737         {0.0, UDAT_REL_UNIT_FRIDAY, "this Friday"},
738         {0.5, UDAT_REL_UNIT_FRIDAY, "in 0.5 Fridays"},
739         {1.0, UDAT_REL_UNIT_FRIDAY, "next Friday"},
740         {2.0, UDAT_REL_UNIT_FRIDAY, "in 2 Fridays"},
741         {0.0, UDAT_REL_UNIT_SATURDAY, "this Saturday"},
742         {0.5, UDAT_REL_UNIT_SATURDAY, "in 0.5 Saturdays"},
743         {1.0, UDAT_REL_UNIT_SATURDAY, "next Saturday"},
744         {2.0, UDAT_REL_UNIT_SATURDAY, "in 2 Saturdays"},
745 
746         {-0.0, UDAT_REL_UNIT_SECOND, "now"},
747         {-0.5, UDAT_REL_UNIT_SECOND, "0.5 seconds ago"},
748         {-1.0, UDAT_REL_UNIT_SECOND, "1 second ago"},
749         {-2.0, UDAT_REL_UNIT_SECOND, "2 seconds ago"},
750         {-0.0, UDAT_REL_UNIT_MINUTE, "this minute"},
751         {-0.5, UDAT_REL_UNIT_MINUTE, "0.5 minutes ago"},
752         {-1.0, UDAT_REL_UNIT_MINUTE, "1 minute ago"},
753         {-2.0, UDAT_REL_UNIT_MINUTE, "2 minutes ago"},
754         {-0.0, UDAT_REL_UNIT_HOUR, "this hour"},
755         {-0.5, UDAT_REL_UNIT_HOUR, "0.5 hours ago"},
756         {-1.0, UDAT_REL_UNIT_HOUR, "1 hour ago"},
757         {-2.0, UDAT_REL_UNIT_HOUR, "2 hours ago"},
758         {-0.0, UDAT_REL_UNIT_DAY, "today"},
759         {-0.5, UDAT_REL_UNIT_DAY, "0.5 days ago"},
760         {-1.0, UDAT_REL_UNIT_DAY, "yesterday"},
761         {-2.0, UDAT_REL_UNIT_DAY, "2 days ago"},
762         {-0.0, UDAT_REL_UNIT_WEEK, "this week"},
763         {-0.5, UDAT_REL_UNIT_WEEK, "0.5 weeks ago"},
764         {-1.0, UDAT_REL_UNIT_WEEK, "last week"},
765         {-2.0, UDAT_REL_UNIT_WEEK, "2 weeks ago"},
766         {-0.0, UDAT_REL_UNIT_MONTH, "this month"},
767         {-0.5, UDAT_REL_UNIT_MONTH, "0.5 months ago"},
768         {-1.0, UDAT_REL_UNIT_MONTH, "last month"},
769         {-2.0, UDAT_REL_UNIT_MONTH, "2 months ago"},
770         {-0.0, UDAT_REL_UNIT_QUARTER, "this quarter"},
771         {-0.5, UDAT_REL_UNIT_QUARTER, "0.5 quarters ago"},
772         {-1.0, UDAT_REL_UNIT_QUARTER, "last quarter"},
773         {-2.0, UDAT_REL_UNIT_QUARTER, "2 quarters ago"},
774         {-0.0, UDAT_REL_UNIT_YEAR, "this year"},
775         {-0.5, UDAT_REL_UNIT_YEAR, "0.5 years ago"},
776         {-1.0, UDAT_REL_UNIT_YEAR, "last year"},
777         {-2.0, UDAT_REL_UNIT_YEAR, "2 years ago"},
778         {-0.0, UDAT_REL_UNIT_SUNDAY, "this Sunday"},
779         {-0.5, UDAT_REL_UNIT_SUNDAY, "0.5 Sundays ago"},
780         {-1.0, UDAT_REL_UNIT_SUNDAY, "last Sunday"},
781         {-2.0, UDAT_REL_UNIT_SUNDAY, "2 Sundays ago"},
782         {-0.0, UDAT_REL_UNIT_MONDAY, "this Monday"},
783         {-0.5, UDAT_REL_UNIT_MONDAY, "0.5 Mondays ago"},
784         {-1.0, UDAT_REL_UNIT_MONDAY, "last Monday"},
785         {-2.0, UDAT_REL_UNIT_MONDAY, "2 Mondays ago"},
786         {-0.0, UDAT_REL_UNIT_TUESDAY, "this Tuesday"},
787         {-0.5, UDAT_REL_UNIT_TUESDAY, "0.5 Tuesdays ago"},
788         {-1.0, UDAT_REL_UNIT_TUESDAY, "last Tuesday"},
789         {-2.0, UDAT_REL_UNIT_TUESDAY, "2 Tuesdays ago"},
790         {-0.0, UDAT_REL_UNIT_WEDNESDAY, "this Wednesday"},
791         {-0.5, UDAT_REL_UNIT_WEDNESDAY, "0.5 Wednesdays ago"},
792         {-1.0, UDAT_REL_UNIT_WEDNESDAY, "last Wednesday"},
793         {-2.0, UDAT_REL_UNIT_WEDNESDAY, "2 Wednesdays ago"},
794         {-0.0, UDAT_REL_UNIT_THURSDAY, "this Thursday"},
795         {-0.5, UDAT_REL_UNIT_THURSDAY, "0.5 Thursdays ago"},
796         {-1.0, UDAT_REL_UNIT_THURSDAY, "last Thursday"},
797         {-2.0, UDAT_REL_UNIT_THURSDAY, "2 Thursdays ago"},
798         {-0.0, UDAT_REL_UNIT_FRIDAY, "this Friday"},
799         {-0.5, UDAT_REL_UNIT_FRIDAY, "0.5 Fridays ago"},
800         {-1.0, UDAT_REL_UNIT_FRIDAY, "last Friday"},
801         {-2.0, UDAT_REL_UNIT_FRIDAY, "2 Fridays ago"},
802         {-0.0, UDAT_REL_UNIT_SATURDAY, "this Saturday"},
803         {-0.5, UDAT_REL_UNIT_SATURDAY, "0.5 Saturdays ago"},
804         {-1.0, UDAT_REL_UNIT_SATURDAY, "last Saturday"},
805         {-2.0, UDAT_REL_UNIT_SATURDAY, "2 Saturdays ago"}
806 };
807 
808 static WithQuantityExpected kAfrikaans[] = {
809         {1.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "oor 1 maand"},
810         {2.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, "oor 2 maande"},
811         {1.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "1 maand gelede"},
812         {2.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_MONTHS, "2 maande gelede"},
813 };
814 
815 static WithoutQuantityExpected kAfrikaansNoQuantity[] = {
816         {UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONTH, "volgende maand"},
817         {UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_MONTH, "verlede maand"},
818 };
819 
820 static WithQuantityExpectedRelativeDateTimeUnit kAfrikaansFormatNumeric[] = {
821         {0.0, UDAT_REL_UNIT_MONTH, "oor 0 maande"},
822         {1.0, UDAT_REL_UNIT_MONTH, "oor 1 maand"},
823         {2.0, UDAT_REL_UNIT_MONTH, "oor 2 maande"},
824         {-0.0, UDAT_REL_UNIT_MONTH, "0 maande gelede"},
825         {-1.0, UDAT_REL_UNIT_MONTH, "1 maand gelede"},
826         {-2.0, UDAT_REL_UNIT_MONTH, "2 maande gelede"},
827 };
828 
829 class RelativeDateTimeFormatterTest : public IntlTestWithFieldPosition {
830 public:
RelativeDateTimeFormatterTest()831     RelativeDateTimeFormatterTest() {
832     }
833 
834     void runIndexedTest(int32_t index, UBool exec, const char*& name, char* par = nullptr) override;
835 
836 private:
837     void TestEnglish();
838     void TestEnglishCaps();
839     void TestEnglishShort();
840     void TestEnglishNarrow();
841     void TestSerbian();
842     void TestSerbianFallback();
843     void TestEnglishNoQuantity();
844     void TestEnglishNoQuantityCaps();
845     void TestEnglishNoQuantityShort();
846     void TestEnglishNoQuantityNarrow();
847     void TestSpanishNoQuantity();
848     void TestAfrikaans();
849     void TestFormatWithQuantityIllegalArgument();
850     void TestFormatWithoutQuantityIllegalArgument();
851     void TestCustomNumberFormat();
852     void TestGetters();
853     void TestCombineDateAndTime();
854     void TestBadDisplayContext();
855     void TestFormat();
856     void TestFormatNumeric();
857     void TestLocales();
858     void TestFields();
859     void TestRBNF();
860 
861     void RunTest(
862             const Locale& locale,
863             const WithQuantityExpected* expectedResults,
864             int32_t expectedResultLength);
865     void RunTest(
866             const Locale& locale,
867             const WithQuantityExpectedRelativeDateTimeUnit* expectedResults,
868             int32_t expectedResultLength,
869             bool numeric);
870     void RunTest(
871             const Locale& locale,
872             UDateRelativeDateTimeFormatterStyle style,
873             const WithQuantityExpected* expectedResults,
874             int32_t expectedResultLength);
875     void RunTest(
876             const Locale& locale,
877             const WithoutQuantityExpected* expectedResults,
878             int32_t expectedResultLength);
879     void RunTest(
880             const Locale& locale,
881             UDateRelativeDateTimeFormatterStyle style,
882             const WithoutQuantityExpected* expectedResults,
883             int32_t expectedResultLength);
884     void RunTest(
885             const RelativeDateTimeFormatter& fmt,
886             const WithQuantityExpected* expectedResults,
887             int32_t expectedResultLength,
888             const char *description);
889     void RunTest(
890             const RelativeDateTimeFormatter& fmt,
891             const WithQuantityExpectedRelativeDateTimeUnit* expectedResults,
892             int32_t expectedResultLength,
893             const char *description,
894             bool numeric);
895     void RunTest(
896             const RelativeDateTimeFormatter& fmt,
897             const WithoutQuantityExpected* expectedResults,
898             int32_t expectedResultLength,
899             const char *description);
900     void CheckExpectedResult(
901             const RelativeDateTimeFormatter& fmt,
902             const WithQuantityExpected& expectedResult,
903             const char* description);
904     void CheckExpectedResult(
905             const RelativeDateTimeFormatter& fmt,
906             const WithQuantityExpectedRelativeDateTimeUnit& expectedResults,
907             const char* description,
908             bool numeric);
909     void CheckExpectedResult(
910             const RelativeDateTimeFormatter& fmt,
911             const WithoutQuantityExpected& expectedResult,
912             const char* description);
913     void VerifyIllegalArgument(
914             const RelativeDateTimeFormatter& fmt,
915             UDateDirection direction,
916             UDateRelativeUnit unit);
917     void VerifyIllegalArgument(
918             const RelativeDateTimeFormatter& fmt,
919             UDateDirection direction,
920             UDateAbsoluteUnit unit);
921     void TestSidewaysDataLoading();
922 };
923 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)924 void RelativeDateTimeFormatterTest::runIndexedTest(
925         int32_t index, UBool exec, const char *&name, char *) {
926     if (exec) {
927         logln("TestSuite RelativeDateTimeFormatterTest: ");
928     }
929     TESTCASE_AUTO_BEGIN;
930     TESTCASE_AUTO(TestEnglish);
931     TESTCASE_AUTO(TestEnglishCaps);
932     TESTCASE_AUTO(TestEnglishShort);
933     TESTCASE_AUTO(TestEnglishNarrow);
934     TESTCASE_AUTO(TestSerbian);
935     TESTCASE_AUTO(TestSerbianFallback);
936     TESTCASE_AUTO(TestEnglishNoQuantity);
937     TESTCASE_AUTO(TestEnglishNoQuantityCaps);
938     TESTCASE_AUTO(TestEnglishNoQuantityShort);
939     TESTCASE_AUTO(TestEnglishNoQuantityNarrow);
940     TESTCASE_AUTO(TestSpanishNoQuantity);
941     TESTCASE_AUTO(TestAfrikaans);
942     TESTCASE_AUTO(TestFormatWithQuantityIllegalArgument);
943     TESTCASE_AUTO(TestFormatWithoutQuantityIllegalArgument);
944     TESTCASE_AUTO(TestCustomNumberFormat);
945     TESTCASE_AUTO(TestGetters);
946     TESTCASE_AUTO(TestCombineDateAndTime);
947     TESTCASE_AUTO(TestBadDisplayContext);
948     TESTCASE_AUTO(TestSidewaysDataLoading);
949     TESTCASE_AUTO(TestFormat);
950     TESTCASE_AUTO(TestFormatNumeric);
951     TESTCASE_AUTO(TestLocales);
952     TESTCASE_AUTO(TestFields);
953     TESTCASE_AUTO(TestRBNF);
954     TESTCASE_AUTO_END;
955 }
956 
TestEnglish()957 void RelativeDateTimeFormatterTest::TestEnglish() {
958     RunTest("en", kEnglish, UPRV_LENGTHOF(kEnglish));
959 }
960 
TestEnglishCaps()961 void RelativeDateTimeFormatterTest::TestEnglishCaps() {
962     UErrorCode status = U_ZERO_ERROR;
963     RelativeDateTimeFormatter fmt(
964             "en",
965             nullptr,
966             UDAT_STYLE_LONG,
967             UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE,
968             status);
969     if (U_FAILURE(status)) {
970         dataerrln("Failed call to RelativeDateTimeFormatter(\"en\", nullptr, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, status); : %s", u_errorName(status));
971         return;
972     }
973     RelativeDateTimeFormatter fmt3(status);
974 
975     // Test assignment and copy constructor with capitalization on.
976     RelativeDateTimeFormatter fmt2(fmt);
977     fmt3 = fmt2;
978     assertSuccess("", status);
979     RunTest(fmt3, kEnglishCaps, UPRV_LENGTHOF(kEnglishCaps), "en caps");
980 }
981 
TestEnglishShort()982 void RelativeDateTimeFormatterTest::TestEnglishShort() {
983     RunTest("en", UDAT_STYLE_SHORT, kEnglishShort, UPRV_LENGTHOF(kEnglishShort));
984 }
985 
TestEnglishNarrow()986 void RelativeDateTimeFormatterTest::TestEnglishNarrow() {
987     RunTest("en", UDAT_STYLE_NARROW, kEnglishNarrow, UPRV_LENGTHOF(kEnglishNarrow));
988 }
989 
TestSerbian()990 void RelativeDateTimeFormatterTest::TestSerbian() {
991     RunTest("sr", kSerbian, UPRV_LENGTHOF(kSerbian));
992 }
993 
TestSerbianFallback()994 void RelativeDateTimeFormatterTest::TestSerbianFallback() {
995     RunTest("sr", UDAT_STYLE_NARROW, kSerbianNarrow, UPRV_LENGTHOF(kSerbianNarrow));
996 }
997 
TestEnglishNoQuantity()998 void RelativeDateTimeFormatterTest::TestEnglishNoQuantity() {
999     RunTest("en", kEnglishNoQuantity, UPRV_LENGTHOF(kEnglishNoQuantity));
1000 }
1001 
TestEnglishNoQuantityCaps()1002 void RelativeDateTimeFormatterTest::TestEnglishNoQuantityCaps() {
1003     UErrorCode status = U_ZERO_ERROR;
1004     RelativeDateTimeFormatter fmt(
1005             "en",
1006             nullptr,
1007             UDAT_STYLE_LONG,
1008             UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE,
1009             status);
1010     if (assertSuccess("RelativeDateTimeFormatter", status, true) == false) {
1011         return;
1012     }
1013     RunTest(
1014             fmt,
1015             kEnglishNoQuantityCaps,
1016             UPRV_LENGTHOF(kEnglishNoQuantityCaps),
1017             "en caps no quantity");
1018 }
1019 
TestEnglishNoQuantityShort()1020 void RelativeDateTimeFormatterTest::TestEnglishNoQuantityShort() {
1021     RunTest(
1022             "en",
1023             UDAT_STYLE_SHORT,
1024             kEnglishNoQuantityShort,
1025             UPRV_LENGTHOF(kEnglishNoQuantityShort));
1026 }
1027 
TestEnglishNoQuantityNarrow()1028 void RelativeDateTimeFormatterTest::TestEnglishNoQuantityNarrow() {
1029     RunTest(
1030             "en",
1031             UDAT_STYLE_NARROW,
1032             kEnglishNoQuantityNarrow,
1033             UPRV_LENGTHOF(kEnglishNoQuantityNarrow));
1034 }
1035 
TestSpanishNoQuantity()1036 void RelativeDateTimeFormatterTest::TestSpanishNoQuantity() {
1037     RunTest("es", kSpanishNoQuantity, UPRV_LENGTHOF(kSpanishNoQuantity));
1038 }
1039 
TestAfrikaans()1040 void RelativeDateTimeFormatterTest::TestAfrikaans() {
1041     RunTest("af", kAfrikaans, UPRV_LENGTHOF(kAfrikaans));
1042     RunTest("af", kAfrikaansNoQuantity, UPRV_LENGTHOF(kAfrikaansNoQuantity));
1043     RunTest("af", kAfrikaansFormatNumeric, UPRV_LENGTHOF(kAfrikaansFormatNumeric), true);
1044 }
1045 
TestFormatWithQuantityIllegalArgument()1046 void RelativeDateTimeFormatterTest::TestFormatWithQuantityIllegalArgument() {
1047     UErrorCode status = U_ZERO_ERROR;
1048     RelativeDateTimeFormatter fmt("en", status);
1049     if (U_FAILURE(status)) {
1050         dataerrln("Failure creating format object - %s", u_errorName(status));
1051         return;
1052     }
1053     VerifyIllegalArgument(fmt, UDAT_DIRECTION_PLAIN, UDAT_RELATIVE_DAYS);
1054     VerifyIllegalArgument(fmt, UDAT_DIRECTION_THIS, UDAT_RELATIVE_DAYS);
1055 }
1056 
TestFormatWithoutQuantityIllegalArgument()1057 void RelativeDateTimeFormatterTest::TestFormatWithoutQuantityIllegalArgument() {
1058     UErrorCode status = U_ZERO_ERROR;
1059     RelativeDateTimeFormatter fmt("en", status);
1060     if (U_FAILURE(status)) {
1061         dataerrln("Failure creating format object - %s", u_errorName(status));
1062         return;
1063     }
1064     VerifyIllegalArgument(fmt, UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_NOW);
1065     VerifyIllegalArgument(fmt, UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_NOW);
1066     VerifyIllegalArgument(fmt, UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_NOW);
1067 }
1068 
TestCustomNumberFormat()1069 void RelativeDateTimeFormatterTest::TestCustomNumberFormat() {
1070     NumberFormat *nf;
1071     UErrorCode status = U_ZERO_ERROR;
1072     {
1073         RelativeDateTimeFormatter fmt("en", status);
1074         if (U_FAILURE(status)) {
1075             dataerrln(
1076                     "Failure creating format object - %s", u_errorName(status));
1077             return;
1078         }
1079         nf = fmt.getNumberFormat().clone();
1080     }
1081     nf->setMinimumFractionDigits(1);
1082     nf->setMaximumFractionDigits(1);
1083     RelativeDateTimeFormatter fmt("en", nf, status);
1084 
1085     // Test copy constructor.
1086     RelativeDateTimeFormatter fmt2(fmt);
1087     RunTest(fmt2, kEnglishDecimal, UPRV_LENGTHOF(kEnglishDecimal), "en decimal digits");
1088 
1089     // Test assignment
1090     fmt = RelativeDateTimeFormatter("es", status);
1091     RunTest(fmt, kSpanishNoQuantity, UPRV_LENGTHOF(kSpanishNoQuantity), "assignment operator");
1092 
1093 }
1094 
TestGetters()1095 void RelativeDateTimeFormatterTest::TestGetters() {
1096     UErrorCode status = U_ZERO_ERROR;
1097     RelativeDateTimeFormatter fmt(
1098             "en",
1099             nullptr,
1100             UDAT_STYLE_NARROW,
1101             UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE,
1102             status);
1103     if (U_FAILURE(status)) {
1104         dataerrln("Failed call to RelativeDateTimeFormatter(\"en\", nullptr, UDAT_STYLE_NARROW, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, status);) : %s", u_errorName(status));
1105         return;
1106     }
1107     RelativeDateTimeFormatter fmt3(status);
1108 
1109     // copy and assignment.
1110     RelativeDateTimeFormatter fmt2(fmt);
1111     fmt3 = fmt2;
1112     assertEquals("style", (int32_t)UDAT_STYLE_NARROW, fmt3.getFormatStyle());
1113     assertEquals(
1114             "context",
1115             (int32_t)UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE,
1116             fmt3.getCapitalizationContext());
1117     assertSuccess("", status);
1118 }
1119 
TestCombineDateAndTime()1120 void RelativeDateTimeFormatterTest::TestCombineDateAndTime() {
1121     UErrorCode status = U_ZERO_ERROR;
1122     RelativeDateTimeFormatter fmt("en", status);
1123     if (U_FAILURE(status)) {
1124         dataerrln("Failure creating format object - %s", u_errorName(status));
1125         return;
1126     }
1127     UnicodeString actual;
1128     fmt.combineDateAndTime(
1129         UnicodeString("yesterday"),
1130         UnicodeString("3:50"),
1131         actual,
1132         status);
1133     UnicodeString expected("yesterday, 3:50");
1134     if (expected != actual) {
1135         errln("Expected "+expected+", got "+actual);
1136     }
1137 }
1138 
TestBadDisplayContext()1139 void RelativeDateTimeFormatterTest::TestBadDisplayContext() {
1140     UErrorCode status = U_ZERO_ERROR;
1141     RelativeDateTimeFormatter fmt(
1142             "en", nullptr, UDAT_STYLE_LONG, UDISPCTX_STANDARD_NAMES, status);
1143     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1144         errln("Expected U_ILLEGAL_ARGUMENT_ERROR, got %s", u_errorName(status));
1145     }
1146 }
1147 
1148 
1149 
RunTest(const Locale & locale,const WithQuantityExpected * expectedResults,int32_t expectedResultLength)1150 void RelativeDateTimeFormatterTest::RunTest(
1151         const Locale& locale,
1152         const WithQuantityExpected* expectedResults,
1153         int32_t expectedResultLength) {
1154     UErrorCode status = U_ZERO_ERROR;
1155     RelativeDateTimeFormatter fmt(locale, status);
1156     if (U_FAILURE(status)) {
1157         dataerrln("Unable to create format object - %s", u_errorName(status));
1158         return;
1159     }
1160     RunTest(fmt, expectedResults, expectedResultLength, locale.getName());
1161 }
1162 
RunTest(const Locale & locale,const WithQuantityExpectedRelativeDateTimeUnit * expectedResults,int32_t expectedResultLength,bool numeric)1163 void RelativeDateTimeFormatterTest::RunTest(
1164         const Locale& locale,
1165         const WithQuantityExpectedRelativeDateTimeUnit* expectedResults,
1166         int32_t expectedResultLength,
1167         bool numeric) {
1168     UErrorCode status = U_ZERO_ERROR;
1169     RelativeDateTimeFormatter fmt(locale, status);
1170     if (U_FAILURE(status)) {
1171         dataerrln("Unable to create format object - %s", u_errorName(status));
1172         return;
1173     }
1174     RunTest(fmt, expectedResults, expectedResultLength, locale.getName(), numeric);
1175 }
1176 
1177 
RunTest(const Locale & locale,UDateRelativeDateTimeFormatterStyle style,const WithQuantityExpected * expectedResults,int32_t expectedResultLength)1178 void RelativeDateTimeFormatterTest::RunTest(
1179         const Locale& locale,
1180         UDateRelativeDateTimeFormatterStyle style,
1181         const WithQuantityExpected* expectedResults,
1182         int32_t expectedResultLength) {
1183     UErrorCode status = U_ZERO_ERROR;
1184     RelativeDateTimeFormatter fmt(
1185             locale, nullptr, style, UDISPCTX_CAPITALIZATION_NONE, status);
1186     if (U_FAILURE(status)) {
1187         dataerrln("Unable to create format object - %s", u_errorName(status));
1188         return;
1189     }
1190     RunTest(fmt, expectedResults, expectedResultLength, locale.getName());
1191 }
1192 
RunTest(const Locale & locale,const WithoutQuantityExpected * expectedResults,int32_t expectedResultLength)1193 void RelativeDateTimeFormatterTest::RunTest(
1194         const Locale& locale,
1195         const WithoutQuantityExpected* expectedResults,
1196         int32_t expectedResultLength) {
1197     UErrorCode status = U_ZERO_ERROR;
1198     RelativeDateTimeFormatter fmt(locale, status);
1199     if (U_FAILURE(status)) {
1200         dataerrln("Unable to create format object - %s", u_errorName(status));
1201         return;
1202     }
1203     RunTest(fmt, expectedResults, expectedResultLength, locale.getName());
1204 }
1205 
RunTest(const Locale & locale,UDateRelativeDateTimeFormatterStyle style,const WithoutQuantityExpected * expectedResults,int32_t expectedResultLength)1206 void RelativeDateTimeFormatterTest::RunTest(
1207         const Locale& locale,
1208         UDateRelativeDateTimeFormatterStyle style,
1209         const WithoutQuantityExpected* expectedResults,
1210         int32_t expectedResultLength) {
1211     UErrorCode status = U_ZERO_ERROR;
1212     RelativeDateTimeFormatter fmt(
1213             locale, nullptr, style, UDISPCTX_CAPITALIZATION_NONE, status);
1214     if (U_FAILURE(status)) {
1215         dataerrln("Unable to create format object - %s", u_errorName(status));
1216         return;
1217     }
1218     RunTest(fmt, expectedResults, expectedResultLength, locale.getName());
1219 }
1220 
RunTest(const RelativeDateTimeFormatter & fmt,const WithQuantityExpected * expectedResults,int32_t expectedResultLength,const char * description)1221 void RelativeDateTimeFormatterTest::RunTest(
1222         const RelativeDateTimeFormatter& fmt,
1223         const WithQuantityExpected* expectedResults,
1224         int32_t expectedResultLength,
1225         const char *description) {
1226     for (int32_t i = 0; i < expectedResultLength; ++i) {
1227         CheckExpectedResult(fmt, expectedResults[i], description);
1228     }
1229 }
1230 
RunTest(const RelativeDateTimeFormatter & fmt,const WithQuantityExpectedRelativeDateTimeUnit * expectedResults,int32_t expectedResultLength,const char * description,bool numeric)1231 void RelativeDateTimeFormatterTest::RunTest(
1232         const RelativeDateTimeFormatter& fmt,
1233         const WithQuantityExpectedRelativeDateTimeUnit* expectedResults,
1234         int32_t expectedResultLength,
1235         const char *description,
1236         bool numeric) {
1237     for (int32_t i = 0; i < expectedResultLength; ++i) {
1238         CheckExpectedResult(fmt, expectedResults[i], description, numeric);
1239     }
1240 }
1241 
RunTest(const RelativeDateTimeFormatter & fmt,const WithoutQuantityExpected * expectedResults,int32_t expectedResultLength,const char * description)1242 void RelativeDateTimeFormatterTest::RunTest(
1243         const RelativeDateTimeFormatter& fmt,
1244         const WithoutQuantityExpected* expectedResults,
1245         int32_t expectedResultLength,
1246         const char *description) {
1247     for (int32_t i = 0; i < expectedResultLength; ++i) {
1248         CheckExpectedResult(fmt, expectedResults[i], description);
1249     }
1250 }
1251 
CheckExpectedResult(const RelativeDateTimeFormatter & fmt,const WithQuantityExpected & expectedResult,const char * description)1252 void RelativeDateTimeFormatterTest::CheckExpectedResult(
1253         const RelativeDateTimeFormatter& fmt,
1254         const WithQuantityExpected& expectedResult,
1255         const char* description) {
1256     UErrorCode status = U_ZERO_ERROR;
1257     UnicodeString actual;
1258     fmt.format(expectedResult.value, expectedResult.direction, expectedResult.unit, actual, status);
1259     UnicodeString expected(expectedResult.expected, -1, US_INV);
1260     expected = expected.unescape();
1261     char buffer[256];
1262     snprintf(
1263             buffer, sizeof(buffer),
1264             "%s, %f, %s, %s",
1265             description,
1266             expectedResult.value,
1267             DirectionStr(expectedResult.direction),
1268             RelativeUnitStr(expectedResult.unit));
1269     if (actual != expected) {
1270         errln(UnicodeString("Fail: Expected: ") + expected
1271                 + ", Got: " + actual
1272                 + ", For: " + buffer);
1273     }
1274 }
1275 
CheckExpectedResult(const RelativeDateTimeFormatter & fmt,const WithQuantityExpectedRelativeDateTimeUnit & expectedResult,const char * description,bool numeric)1276 void RelativeDateTimeFormatterTest::CheckExpectedResult(
1277         const RelativeDateTimeFormatter& fmt,
1278         const WithQuantityExpectedRelativeDateTimeUnit& expectedResult,
1279         const char* description,
1280         bool numeric) {
1281     UErrorCode status = U_ZERO_ERROR;
1282     UnicodeString actual;
1283     if (numeric) {
1284       fmt.formatNumeric(expectedResult.value, expectedResult.unit, actual, status);
1285     } else {
1286       fmt.format(expectedResult.value, expectedResult.unit, actual, status);
1287     }
1288     UnicodeString expected(expectedResult.expected, -1, US_INV);
1289     expected = expected.unescape();
1290     char buffer[256];
1291     snprintf(
1292             buffer, sizeof(buffer),
1293             "%s, %f, %s",
1294             description,
1295             expectedResult.value,
1296             RelativeDateTimeUnitStr(expectedResult.unit));
1297     if (actual != expected) {
1298         errln(UnicodeString("Fail: Expected: ") + expected
1299                 + ", Got: " + actual
1300                 + ", For: " + buffer);
1301     }
1302 }
1303 
CheckExpectedResult(const RelativeDateTimeFormatter & fmt,const WithoutQuantityExpected & expectedResult,const char * description)1304 void RelativeDateTimeFormatterTest::CheckExpectedResult(
1305         const RelativeDateTimeFormatter& fmt,
1306         const WithoutQuantityExpected& expectedResult,
1307         const char* description) {
1308     UErrorCode status = U_ZERO_ERROR;
1309     UnicodeString actual;
1310     fmt.format(expectedResult.direction, expectedResult.unit, actual, status);
1311     UnicodeString expected(expectedResult.expected, -1, US_INV);
1312     expected = expected.unescape();
1313     char buffer[256];
1314     snprintf(
1315             buffer, sizeof(buffer),
1316             "%s, %s, %s",
1317             description,
1318             DirectionStr(expectedResult.direction),
1319             AbsoluteUnitStr(expectedResult.unit));
1320     if (actual != expected) {
1321         errln(UnicodeString("Fail: Expected: ") + expected
1322                 + ", Got: " + actual
1323                 + ", For: " + buffer);
1324     }
1325 }
1326 
VerifyIllegalArgument(const RelativeDateTimeFormatter & fmt,UDateDirection direction,UDateRelativeUnit unit)1327 void RelativeDateTimeFormatterTest::VerifyIllegalArgument(
1328         const RelativeDateTimeFormatter& fmt,
1329         UDateDirection direction,
1330         UDateRelativeUnit unit) {
1331     UnicodeString appendTo;
1332     UErrorCode status = U_ZERO_ERROR;
1333     fmt.format(1.0, direction, unit, appendTo, status);
1334     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1335         errln("Expected U_ILLEGAL_ARGUMENT_ERROR, got %s", u_errorName(status));
1336     }
1337 }
1338 
VerifyIllegalArgument(const RelativeDateTimeFormatter & fmt,UDateDirection direction,UDateAbsoluteUnit unit)1339 void RelativeDateTimeFormatterTest::VerifyIllegalArgument(
1340         const RelativeDateTimeFormatter& fmt,
1341         UDateDirection direction,
1342         UDateAbsoluteUnit unit) {
1343     UnicodeString appendTo;
1344     UErrorCode status = U_ZERO_ERROR;
1345     fmt.format(direction, unit, appendTo, status);
1346     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1347         errln("Expected U_ILLEGAL_ARGUMENT_ERROR, got %s", u_errorName(status));
1348     }
1349 }
1350 
1351 /* Add tests to check "sideways" data loading. */
TestSidewaysDataLoading()1352 void RelativeDateTimeFormatterTest::TestSidewaysDataLoading() {
1353     UErrorCode status = U_ZERO_ERROR;
1354     UnicodeString actual;
1355     UnicodeString expected;
1356     Locale enGbLocale("en_GB");
1357 
1358     RelativeDateTimeFormatter fmt(enGbLocale, nullptr, UDAT_STYLE_NARROW,
1359                                   UDISPCTX_CAPITALIZATION_NONE, status);
1360     if (U_FAILURE(status)) {
1361         dataerrln("Unable to create RelativeDateTimeFormatter - %s", u_errorName(status));
1362         return;
1363     }
1364 
1365     status = U_ZERO_ERROR;
1366     actual = "";
1367     fmt.format(3.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, actual, status);
1368     expected = "in 3 mo";
1369     assertEquals("narrow in 3 mo", expected, actual);
1370 
1371     fmt.format(3.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, actual.remove(), status);
1372     expected = "3 days ago";
1373     assertEquals("3 days ago (positive 3.0): ", expected, actual);
1374 
1375     expected = "-3 days ago";
1376     fmt.format(-3.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, actual.remove(), status);
1377     assertEquals("3 days ago (negative 3.0): ", expected, actual);
1378 
1379     expected = "next yr";
1380     fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_YEAR, actual.remove(), status);
1381     assertEquals("next year: ", expected, actual);
1382 
1383     // Testing the SHORT style
1384     RelativeDateTimeFormatter fmtshort(enGbLocale, nullptr, UDAT_STYLE_SHORT,
1385                                   UDISPCTX_CAPITALIZATION_NONE, status);
1386     expected = "now";
1387     fmtshort.format(0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, actual.remove(), status);
1388 
1389     expected = "next yr";
1390     fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_YEAR, actual.remove(), status);
1391     assertEquals("next year: ", expected, actual);
1392 }
1393 
TestFormatNumeric()1394 void RelativeDateTimeFormatterTest::TestFormatNumeric() {
1395     RunTest("en", kEnglishFormatNumeric, UPRV_LENGTHOF(kEnglishFormatNumeric), true);
1396 }
1397 
TestFormat()1398 void RelativeDateTimeFormatterTest::TestFormat() {
1399     RunTest("en", kEnglishFormat, UPRV_LENGTHOF(kEnglishFormat), false);
1400 }
1401 
TestLocales()1402 void RelativeDateTimeFormatterTest::TestLocales() {
1403     int32_t numLocales = 0;
1404     const Locale *availableLocales = Locale::getAvailableLocales(numLocales);
1405     std::vector<std::unique_ptr<RelativeDateTimeFormatter>> allFormatters;
1406     for (int localeIdx=0; localeIdx<numLocales; localeIdx++) {
1407         const Locale &loc = availableLocales[localeIdx];
1408         UErrorCode status = U_ZERO_ERROR;
1409         std::unique_ptr<RelativeDateTimeFormatter> rdtf(new RelativeDateTimeFormatter(loc, status));
1410         allFormatters.push_back(std::move(rdtf));
1411         assertSuccess(loc.getName(), status);
1412     }
1413 }
1414 
TestFields()1415 void RelativeDateTimeFormatterTest::TestFields() {
1416     IcuTestErrorCode status(*this, "TestFields");
1417 
1418     RelativeDateTimeFormatter fmt("en-US", status);
1419 
1420     {
1421         const char16_t* message = u"automatic absolute unit";
1422         FormattedRelativeDateTime fv = fmt.formatToValue(1, UDAT_REL_UNIT_DAY, status);
1423         const char16_t* expectedString = u"tomorrow";
1424         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1425             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 0, 8}};
1426         checkMixedFormattedValue(
1427             message,
1428             fv,
1429             expectedString,
1430             expectedFieldPositions,
1431             UPRV_LENGTHOF(expectedFieldPositions));
1432     }
1433     {
1434         const char16_t* message = u"automatic numeric unit";
1435         FormattedRelativeDateTime fv = fmt.formatToValue(3, UDAT_REL_UNIT_DAY, status);
1436         const char16_t* expectedString = u"in 3 days";
1437         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1438             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 0, 2},
1439             {UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, 3, 4},
1440             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD, 3, 4},
1441             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 5, 9}};
1442         checkMixedFormattedValue(
1443             message,
1444             fv,
1445             expectedString,
1446             expectedFieldPositions,
1447             UPRV_LENGTHOF(expectedFieldPositions));
1448     }
1449     {
1450         const char16_t* message = u"manual absolute unit";
1451         FormattedRelativeDateTime fv = fmt.formatToValue(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONDAY, status);
1452         const char16_t* expectedString = u"next Monday";
1453         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1454             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 0, 11}};
1455         checkMixedFormattedValue(
1456             message,
1457             fv,
1458             expectedString,
1459             expectedFieldPositions,
1460             UPRV_LENGTHOF(expectedFieldPositions));
1461     }
1462     {
1463         const char16_t* message = u"manual numeric unit";
1464         FormattedRelativeDateTime fv = fmt.formatNumericToValue(1.5, UDAT_REL_UNIT_WEEK, status);
1465         const char16_t* expectedString = u"in 1.5 weeks";
1466         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1467             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 0, 2},
1468             {UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, 3, 4},
1469             {UFIELD_CATEGORY_NUMBER, UNUM_DECIMAL_SEPARATOR_FIELD, 4, 5},
1470             {UFIELD_CATEGORY_NUMBER, UNUM_FRACTION_FIELD, 5, 6},
1471             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD, 3, 6},
1472             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 7, 12}};
1473         checkMixedFormattedValue(
1474             message,
1475             fv,
1476             expectedString,
1477             expectedFieldPositions,
1478             UPRV_LENGTHOF(expectedFieldPositions));
1479     }
1480     {
1481         const char16_t* message = u"manual numeric resolved unit";
1482         FormattedRelativeDateTime fv = fmt.formatToValue(12, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, status);
1483         const char16_t* expectedString = u"12 hours ago";
1484         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1485             {UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, 0, 2},
1486             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD, 0, 2},
1487             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 3, 12}};
1488         checkMixedFormattedValue(
1489             message,
1490             fv,
1491             expectedString,
1492             expectedFieldPositions,
1493             UPRV_LENGTHOF(expectedFieldPositions));
1494     }
1495 
1496     // Test when the number field is at the end
1497     fmt = RelativeDateTimeFormatter("sw", status);
1498     {
1499         const char16_t* message = u"numeric field at end";
1500         FormattedRelativeDateTime fv = fmt.formatToValue(12, UDAT_REL_UNIT_HOUR, status);
1501         const char16_t* expectedString = u"baada ya saa 12";
1502         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1503             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 0, 12},
1504             {UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, 13, 15},
1505             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD, 13, 15}};
1506         checkMixedFormattedValue(
1507             message,
1508             fv,
1509             expectedString,
1510             expectedFieldPositions,
1511             UPRV_LENGTHOF(expectedFieldPositions));
1512     }
1513 }
1514 
TestRBNF()1515 void RelativeDateTimeFormatterTest::TestRBNF() {
1516     IcuTestErrorCode status(*this, "TestRBNF");
1517 
1518     LocalPointer<RuleBasedNumberFormat> rbnf(new RuleBasedNumberFormat(URBNF_SPELLOUT, "en-us", status));
1519     if (status.errIfFailureAndReset()) { return; }
1520     RelativeDateTimeFormatter fmt("en-us", rbnf.orphan(), status);
1521     UnicodeString result;
1522     assertEquals("format (direction)", "in five seconds",
1523         fmt.format(5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, result, status));
1524     assertEquals("formatNumeric", "one week ago",
1525         fmt.formatNumeric(-1, UDAT_REL_UNIT_WEEK, result.remove(), status));
1526     assertEquals("format (absolute)", "yesterday",
1527         fmt.format(UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_DAY, result.remove(), status));
1528     assertEquals("format (relative)", "in forty-two months",
1529         fmt.format(42, UDAT_REL_UNIT_MONTH, result.remove(), status));
1530 
1531     {
1532         const char16_t* message = u"formatToValue (relative)";
1533         FormattedRelativeDateTime fv = fmt.formatToValue(-100, UDAT_REL_UNIT_YEAR, status);
1534         const char16_t* expectedString = u"one hundred years ago";
1535         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1536             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD, 0, 11},
1537             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 12, 21}};
1538         checkMixedFormattedValue(
1539             message,
1540             fv,
1541             expectedString,
1542             expectedFieldPositions,
1543             UPRV_LENGTHOF(expectedFieldPositions));
1544     }
1545 }
1546 
1547 static const char *kLast2 = "Last_2";
1548 static const char *kLast = "Last";
1549 static const char *kThis = "This";
1550 static const char *kNext = "Next";
1551 static const char *kNext2 = "Next_2";
1552 static const char *kPlain = "Plain";
1553 
1554 static const char *kSeconds = "Seconds";
1555 static const char *kMinutes = "Minutes";
1556 static const char *kHours = "Hours";
1557 static const char *kDays = "Days";
1558 static const char *kWeeks = "Weeks";
1559 static const char *kMonths = "Months";
1560 static const char *kQuarters = "Quarters";
1561 static const char *kYears = "Years";
1562 static const char *kSundays = "Sundays";
1563 static const char *kMondays = "Mondays";
1564 static const char *kTuesdays = "Tuesdays";
1565 static const char *kWednesdays = "Wednesdays";
1566 static const char *kThursdays = "Thursdays";
1567 static const char *kFridays = "Fridays";
1568 static const char *kSaturdays = "Saturdays";
1569 
1570 static const char *kSunday = "Sunday";
1571 static const char *kMonday = "Monday";
1572 static const char *kTuesday = "Tuesday";
1573 static const char *kWednesday = "Wednesday";
1574 static const char *kThursday = "Thursday";
1575 static const char *kFriday = "Friday";
1576 static const char *kSaturday = "Saturday";
1577 static const char *kDay = "Day";
1578 static const char *kWeek = "Week";
1579 static const char *kMonth = "Month";
1580 static const char *kQuarter = "Quarter";
1581 static const char *kYear = "Year";
1582 static const char *kNow = "Now";
1583 
1584 static const char *kUndefined = "Undefined";
1585 
DirectionStr(UDateDirection direction)1586 static const char *DirectionStr(
1587         UDateDirection direction) {
1588     switch (direction) {
1589         case UDAT_DIRECTION_LAST_2:
1590             return kLast2;
1591         case UDAT_DIRECTION_LAST:
1592             return kLast;
1593         case UDAT_DIRECTION_THIS:
1594             return kThis;
1595         case UDAT_DIRECTION_NEXT:
1596             return kNext;
1597         case UDAT_DIRECTION_NEXT_2:
1598             return kNext2;
1599         case UDAT_DIRECTION_PLAIN:
1600             return kPlain;
1601         default:
1602             return kUndefined;
1603     }
1604     return kUndefined;
1605 }
1606 
RelativeUnitStr(UDateRelativeUnit unit)1607 static const char *RelativeUnitStr(
1608         UDateRelativeUnit unit) {
1609     switch (unit) {
1610         case UDAT_RELATIVE_SECONDS:
1611             return kSeconds;
1612         case UDAT_RELATIVE_MINUTES:
1613             return kMinutes;
1614         case UDAT_RELATIVE_HOURS:
1615             return kHours;
1616         case UDAT_RELATIVE_DAYS:
1617             return kDays;
1618         case UDAT_RELATIVE_WEEKS:
1619             return kWeeks;
1620         case UDAT_RELATIVE_MONTHS:
1621             return kMonths;
1622         case UDAT_RELATIVE_YEARS:
1623             return kYears;
1624         default:
1625             return kUndefined;
1626     }
1627     return kUndefined;
1628 }
1629 
RelativeDateTimeUnitStr(URelativeDateTimeUnit unit)1630 static const char *RelativeDateTimeUnitStr(
1631         URelativeDateTimeUnit  unit) {
1632     switch (unit) {
1633         case UDAT_REL_UNIT_SECOND:
1634             return kSeconds;
1635         case UDAT_REL_UNIT_MINUTE:
1636             return kMinutes;
1637         case UDAT_REL_UNIT_HOUR:
1638             return kHours;
1639         case UDAT_REL_UNIT_DAY:
1640             return kDays;
1641         case UDAT_REL_UNIT_WEEK:
1642             return kWeeks;
1643         case UDAT_REL_UNIT_MONTH:
1644             return kMonths;
1645         case UDAT_REL_UNIT_QUARTER:
1646             return kQuarters;
1647         case UDAT_REL_UNIT_YEAR:
1648             return kYears;
1649         case UDAT_REL_UNIT_SUNDAY:
1650             return kSundays;
1651         case UDAT_REL_UNIT_MONDAY:
1652             return kMondays;
1653         case UDAT_REL_UNIT_TUESDAY:
1654             return kTuesdays;
1655         case UDAT_REL_UNIT_WEDNESDAY:
1656             return kWednesdays;
1657         case UDAT_REL_UNIT_THURSDAY:
1658             return kThursdays;
1659         case UDAT_REL_UNIT_FRIDAY:
1660             return kFridays;
1661         case UDAT_REL_UNIT_SATURDAY:
1662             return kSaturdays;
1663         default:
1664             return kUndefined;
1665     }
1666     return kUndefined;
1667 }
1668 
AbsoluteUnitStr(UDateAbsoluteUnit unit)1669 static const char *AbsoluteUnitStr(
1670         UDateAbsoluteUnit unit) {
1671     switch (unit) {
1672         case UDAT_ABSOLUTE_SUNDAY:
1673             return kSunday;
1674         case UDAT_ABSOLUTE_MONDAY:
1675             return kMonday;
1676         case UDAT_ABSOLUTE_TUESDAY:
1677             return kTuesday;
1678         case UDAT_ABSOLUTE_WEDNESDAY:
1679             return kWednesday;
1680         case UDAT_ABSOLUTE_THURSDAY:
1681             return kThursday;
1682         case UDAT_ABSOLUTE_FRIDAY:
1683             return kFriday;
1684         case UDAT_ABSOLUTE_SATURDAY:
1685             return kSaturday;
1686         case UDAT_ABSOLUTE_DAY:
1687             return kDay;
1688         case UDAT_ABSOLUTE_WEEK:
1689             return kWeek;
1690         case UDAT_ABSOLUTE_MONTH:
1691             return kMonth;
1692         case UDAT_ABSOLUTE_QUARTER:
1693             return kQuarter;
1694         case UDAT_ABSOLUTE_YEAR:
1695             return kYear;
1696         case UDAT_ABSOLUTE_NOW:
1697             return kNow;
1698         default:
1699             return kUndefined;
1700     }
1701     return kUndefined;
1702 }
1703 
createRelativeDateTimeFormatterTest()1704 extern IntlTest *createRelativeDateTimeFormatterTest() {
1705     return new RelativeDateTimeFormatterTest();
1706 }
1707 
1708 #endif
1709