• 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=0) override;
835 private:
836     void TestEnglish();
837     void TestEnglishCaps();
838     void TestEnglishShort();
839     void TestEnglishNarrow();
840     void TestSerbian();
841     void TestSerbianFallback();
842     void TestEnglishNoQuantity();
843     void TestEnglishNoQuantityCaps();
844     void TestEnglishNoQuantityShort();
845     void TestEnglishNoQuantityNarrow();
846     void TestSpanishNoQuantity();
847     void TestAfrikaans();
848     void TestFormatWithQuantityIllegalArgument();
849     void TestFormatWithoutQuantityIllegalArgument();
850     void TestCustomNumberFormat();
851     void TestGetters();
852     void TestCombineDateAndTime();
853     void TestBadDisplayContext();
854     void TestFormat();
855     void TestFormatNumeric();
856     void TestLocales();
857     void TestFields();
858     void TestRBNF();
859 
860     void RunTest(
861             const Locale& locale,
862             const WithQuantityExpected* expectedResults,
863             int32_t expectedResultLength);
864     void RunTest(
865             const Locale& locale,
866             const WithQuantityExpectedRelativeDateTimeUnit* expectedResults,
867             int32_t expectedResultLength,
868             bool numeric);
869     void RunTest(
870             const Locale& locale,
871             UDateRelativeDateTimeFormatterStyle style,
872             const WithQuantityExpected* expectedResults,
873             int32_t expectedResultLength);
874     void RunTest(
875             const Locale& locale,
876             const WithoutQuantityExpected* expectedResults,
877             int32_t expectedResultLength);
878     void RunTest(
879             const Locale& locale,
880             UDateRelativeDateTimeFormatterStyle style,
881             const WithoutQuantityExpected* expectedResults,
882             int32_t expectedResultLength);
883     void RunTest(
884             const RelativeDateTimeFormatter& fmt,
885             const WithQuantityExpected* expectedResults,
886             int32_t expectedResultLength,
887             const char *description);
888     void RunTest(
889             const RelativeDateTimeFormatter& fmt,
890             const WithQuantityExpectedRelativeDateTimeUnit* expectedResults,
891             int32_t expectedResultLength,
892             const char *description,
893             bool numeric);
894     void RunTest(
895             const RelativeDateTimeFormatter& fmt,
896             const WithoutQuantityExpected* expectedResults,
897             int32_t expectedResultLength,
898             const char *description);
899     void CheckExpectedResult(
900             const RelativeDateTimeFormatter& fmt,
901             const WithQuantityExpected& expectedResult,
902             const char* description);
903     void CheckExpectedResult(
904             const RelativeDateTimeFormatter& fmt,
905             const WithQuantityExpectedRelativeDateTimeUnit& expectedResults,
906             const char* description,
907             bool numeric);
908     void CheckExpectedResult(
909             const RelativeDateTimeFormatter& fmt,
910             const WithoutQuantityExpected& expectedResult,
911             const char* description);
912     void VerifyIllegalArgument(
913             const RelativeDateTimeFormatter& fmt,
914             UDateDirection direction,
915             UDateRelativeUnit unit);
916     void VerifyIllegalArgument(
917             const RelativeDateTimeFormatter& fmt,
918             UDateDirection direction,
919             UDateAbsoluteUnit unit);
920     void TestSidewaysDataLoading(void);
921 };
922 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)923 void RelativeDateTimeFormatterTest::runIndexedTest(
924         int32_t index, UBool exec, const char *&name, char *) {
925     if (exec) {
926         logln("TestSuite RelativeDateTimeFormatterTest: ");
927     }
928     TESTCASE_AUTO_BEGIN;
929     TESTCASE_AUTO(TestEnglish);
930     TESTCASE_AUTO(TestEnglishCaps);
931     TESTCASE_AUTO(TestEnglishShort);
932     TESTCASE_AUTO(TestEnglishNarrow);
933     TESTCASE_AUTO(TestSerbian);
934     TESTCASE_AUTO(TestSerbianFallback);
935     TESTCASE_AUTO(TestEnglishNoQuantity);
936     TESTCASE_AUTO(TestEnglishNoQuantityCaps);
937     TESTCASE_AUTO(TestEnglishNoQuantityShort);
938     TESTCASE_AUTO(TestEnglishNoQuantityNarrow);
939     TESTCASE_AUTO(TestSpanishNoQuantity);
940     TESTCASE_AUTO(TestAfrikaans);
941     TESTCASE_AUTO(TestFormatWithQuantityIllegalArgument);
942     TESTCASE_AUTO(TestFormatWithoutQuantityIllegalArgument);
943     TESTCASE_AUTO(TestCustomNumberFormat);
944     TESTCASE_AUTO(TestGetters);
945     TESTCASE_AUTO(TestCombineDateAndTime);
946     TESTCASE_AUTO(TestBadDisplayContext);
947     TESTCASE_AUTO(TestSidewaysDataLoading);
948     TESTCASE_AUTO(TestFormat);
949     TESTCASE_AUTO(TestFormatNumeric);
950     TESTCASE_AUTO(TestLocales);
951     TESTCASE_AUTO(TestFields);
952     TESTCASE_AUTO(TestRBNF);
953     TESTCASE_AUTO_END;
954 }
955 
TestEnglish()956 void RelativeDateTimeFormatterTest::TestEnglish() {
957     RunTest("en", kEnglish, UPRV_LENGTHOF(kEnglish));
958 }
959 
TestEnglishCaps()960 void RelativeDateTimeFormatterTest::TestEnglishCaps() {
961     UErrorCode status = U_ZERO_ERROR;
962     RelativeDateTimeFormatter fmt(
963             "en",
964             NULL,
965             UDAT_STYLE_LONG,
966             UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE,
967             status);
968     if (U_FAILURE(status)) {
969         dataerrln("Failed call to RelativeDateTimeFormatter(\"en\", NULL, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, status); : %s", u_errorName(status));
970         return;
971     }
972     RelativeDateTimeFormatter fmt3(status);
973 
974     // Test assignment and copy constructor with capitalization on.
975     RelativeDateTimeFormatter fmt2(fmt);
976     fmt3 = fmt2;
977     assertSuccess("", status);
978     RunTest(fmt3, kEnglishCaps, UPRV_LENGTHOF(kEnglishCaps), "en caps");
979 }
980 
TestEnglishShort()981 void RelativeDateTimeFormatterTest::TestEnglishShort() {
982     RunTest("en", UDAT_STYLE_SHORT, kEnglishShort, UPRV_LENGTHOF(kEnglishShort));
983 }
984 
TestEnglishNarrow()985 void RelativeDateTimeFormatterTest::TestEnglishNarrow() {
986     RunTest("en", UDAT_STYLE_NARROW, kEnglishNarrow, UPRV_LENGTHOF(kEnglishNarrow));
987 }
988 
TestSerbian()989 void RelativeDateTimeFormatterTest::TestSerbian() {
990     RunTest("sr", kSerbian, UPRV_LENGTHOF(kSerbian));
991 }
992 
TestSerbianFallback()993 void RelativeDateTimeFormatterTest::TestSerbianFallback() {
994     RunTest("sr", UDAT_STYLE_NARROW, kSerbianNarrow, UPRV_LENGTHOF(kSerbianNarrow));
995 }
996 
TestEnglishNoQuantity()997 void RelativeDateTimeFormatterTest::TestEnglishNoQuantity() {
998     RunTest("en", kEnglishNoQuantity, UPRV_LENGTHOF(kEnglishNoQuantity));
999 }
1000 
TestEnglishNoQuantityCaps()1001 void RelativeDateTimeFormatterTest::TestEnglishNoQuantityCaps() {
1002     UErrorCode status = U_ZERO_ERROR;
1003     RelativeDateTimeFormatter fmt(
1004             "en",
1005             NULL,
1006             UDAT_STYLE_LONG,
1007             UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE,
1008             status);
1009     if (assertSuccess("RelativeDateTimeFormatter", status, true) == false) {
1010         return;
1011     }
1012     RunTest(
1013             fmt,
1014             kEnglishNoQuantityCaps,
1015             UPRV_LENGTHOF(kEnglishNoQuantityCaps),
1016             "en caps no quantity");
1017 }
1018 
TestEnglishNoQuantityShort()1019 void RelativeDateTimeFormatterTest::TestEnglishNoQuantityShort() {
1020     RunTest(
1021             "en",
1022             UDAT_STYLE_SHORT,
1023             kEnglishNoQuantityShort,
1024             UPRV_LENGTHOF(kEnglishNoQuantityShort));
1025 }
1026 
TestEnglishNoQuantityNarrow()1027 void RelativeDateTimeFormatterTest::TestEnglishNoQuantityNarrow() {
1028     RunTest(
1029             "en",
1030             UDAT_STYLE_NARROW,
1031             kEnglishNoQuantityNarrow,
1032             UPRV_LENGTHOF(kEnglishNoQuantityNarrow));
1033 }
1034 
TestSpanishNoQuantity()1035 void RelativeDateTimeFormatterTest::TestSpanishNoQuantity() {
1036     RunTest("es", kSpanishNoQuantity, UPRV_LENGTHOF(kSpanishNoQuantity));
1037 }
1038 
TestAfrikaans()1039 void RelativeDateTimeFormatterTest::TestAfrikaans() {
1040     RunTest("af", kAfrikaans, UPRV_LENGTHOF(kAfrikaans));
1041     RunTest("af", kAfrikaansNoQuantity, UPRV_LENGTHOF(kAfrikaansNoQuantity));
1042     RunTest("af", kAfrikaansFormatNumeric, UPRV_LENGTHOF(kAfrikaansFormatNumeric), true);
1043 }
1044 
TestFormatWithQuantityIllegalArgument()1045 void RelativeDateTimeFormatterTest::TestFormatWithQuantityIllegalArgument() {
1046     UErrorCode status = U_ZERO_ERROR;
1047     RelativeDateTimeFormatter fmt("en", status);
1048     if (U_FAILURE(status)) {
1049         dataerrln("Failure creating format object - %s", u_errorName(status));
1050         return;
1051     }
1052     VerifyIllegalArgument(fmt, UDAT_DIRECTION_PLAIN, UDAT_RELATIVE_DAYS);
1053     VerifyIllegalArgument(fmt, UDAT_DIRECTION_THIS, UDAT_RELATIVE_DAYS);
1054 }
1055 
TestFormatWithoutQuantityIllegalArgument()1056 void RelativeDateTimeFormatterTest::TestFormatWithoutQuantityIllegalArgument() {
1057     UErrorCode status = U_ZERO_ERROR;
1058     RelativeDateTimeFormatter fmt("en", status);
1059     if (U_FAILURE(status)) {
1060         dataerrln("Failure creating format object - %s", u_errorName(status));
1061         return;
1062     }
1063     VerifyIllegalArgument(fmt, UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_NOW);
1064     VerifyIllegalArgument(fmt, UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_NOW);
1065     VerifyIllegalArgument(fmt, UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_NOW);
1066 }
1067 
TestCustomNumberFormat()1068 void RelativeDateTimeFormatterTest::TestCustomNumberFormat() {
1069     NumberFormat *nf;
1070     UErrorCode status = U_ZERO_ERROR;
1071     {
1072         RelativeDateTimeFormatter fmt("en", status);
1073         if (U_FAILURE(status)) {
1074             dataerrln(
1075                     "Failure creating format object - %s", u_errorName(status));
1076             return;
1077         }
1078         nf = fmt.getNumberFormat().clone();
1079     }
1080     nf->setMinimumFractionDigits(1);
1081     nf->setMaximumFractionDigits(1);
1082     RelativeDateTimeFormatter fmt("en", nf, status);
1083 
1084     // Test copy constructor.
1085     RelativeDateTimeFormatter fmt2(fmt);
1086     RunTest(fmt2, kEnglishDecimal, UPRV_LENGTHOF(kEnglishDecimal), "en decimal digits");
1087 
1088     // Test assignment
1089     fmt = RelativeDateTimeFormatter("es", status);
1090     RunTest(fmt, kSpanishNoQuantity, UPRV_LENGTHOF(kSpanishNoQuantity), "assignment operator");
1091 
1092 }
1093 
TestGetters()1094 void RelativeDateTimeFormatterTest::TestGetters() {
1095     UErrorCode status = U_ZERO_ERROR;
1096     RelativeDateTimeFormatter fmt(
1097             "en",
1098             NULL,
1099             UDAT_STYLE_NARROW,
1100             UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE,
1101             status);
1102     if (U_FAILURE(status)) {
1103         dataerrln("Failed call to RelativeDateTimeFormatter(\"en\", NULL, UDAT_STYLE_NARROW, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, status);) : %s", u_errorName(status));
1104         return;
1105     }
1106     RelativeDateTimeFormatter fmt3(status);
1107 
1108     // copy and assignment.
1109     RelativeDateTimeFormatter fmt2(fmt);
1110     fmt3 = fmt2;
1111     assertEquals("style", (int32_t)UDAT_STYLE_NARROW, fmt3.getFormatStyle());
1112     assertEquals(
1113             "context",
1114             (int32_t)UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE,
1115             fmt3.getCapitalizationContext());
1116     assertSuccess("", status);
1117 }
1118 
TestCombineDateAndTime()1119 void RelativeDateTimeFormatterTest::TestCombineDateAndTime() {
1120     UErrorCode status = U_ZERO_ERROR;
1121     RelativeDateTimeFormatter fmt("en", status);
1122     if (U_FAILURE(status)) {
1123         dataerrln("Failure creating format object - %s", u_errorName(status));
1124         return;
1125     }
1126     UnicodeString actual;
1127     fmt.combineDateAndTime(
1128         UnicodeString("yesterday"),
1129         UnicodeString("3:50"),
1130         actual,
1131         status);
1132     UnicodeString expected("yesterday, 3:50");
1133     if (expected != actual) {
1134         errln("Expected "+expected+", got "+actual);
1135     }
1136 }
1137 
TestBadDisplayContext()1138 void RelativeDateTimeFormatterTest::TestBadDisplayContext() {
1139     UErrorCode status = U_ZERO_ERROR;
1140     RelativeDateTimeFormatter fmt(
1141             "en", NULL, UDAT_STYLE_LONG, UDISPCTX_STANDARD_NAMES, status);
1142     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1143         errln("Expected U_ILLEGAL_ARGUMENT_ERROR, got %s", u_errorName(status));
1144     }
1145 }
1146 
1147 
1148 
RunTest(const Locale & locale,const WithQuantityExpected * expectedResults,int32_t expectedResultLength)1149 void RelativeDateTimeFormatterTest::RunTest(
1150         const Locale& locale,
1151         const WithQuantityExpected* expectedResults,
1152         int32_t expectedResultLength) {
1153     UErrorCode status = U_ZERO_ERROR;
1154     RelativeDateTimeFormatter fmt(locale, status);
1155     if (U_FAILURE(status)) {
1156         dataerrln("Unable to create format object - %s", u_errorName(status));
1157         return;
1158     }
1159     RunTest(fmt, expectedResults, expectedResultLength, locale.getName());
1160 }
1161 
RunTest(const Locale & locale,const WithQuantityExpectedRelativeDateTimeUnit * expectedResults,int32_t expectedResultLength,bool numeric)1162 void RelativeDateTimeFormatterTest::RunTest(
1163         const Locale& locale,
1164         const WithQuantityExpectedRelativeDateTimeUnit* expectedResults,
1165         int32_t expectedResultLength,
1166         bool numeric) {
1167     UErrorCode status = U_ZERO_ERROR;
1168     RelativeDateTimeFormatter fmt(locale, status);
1169     if (U_FAILURE(status)) {
1170         dataerrln("Unable to create format object - %s", u_errorName(status));
1171         return;
1172     }
1173     RunTest(fmt, expectedResults, expectedResultLength, locale.getName(), numeric);
1174 }
1175 
1176 
RunTest(const Locale & locale,UDateRelativeDateTimeFormatterStyle style,const WithQuantityExpected * expectedResults,int32_t expectedResultLength)1177 void RelativeDateTimeFormatterTest::RunTest(
1178         const Locale& locale,
1179         UDateRelativeDateTimeFormatterStyle style,
1180         const WithQuantityExpected* expectedResults,
1181         int32_t expectedResultLength) {
1182     UErrorCode status = U_ZERO_ERROR;
1183     RelativeDateTimeFormatter fmt(
1184             locale, NULL, style, UDISPCTX_CAPITALIZATION_NONE, status);
1185     if (U_FAILURE(status)) {
1186         dataerrln("Unable to create format object - %s", u_errorName(status));
1187         return;
1188     }
1189     RunTest(fmt, expectedResults, expectedResultLength, locale.getName());
1190 }
1191 
RunTest(const Locale & locale,const WithoutQuantityExpected * expectedResults,int32_t expectedResultLength)1192 void RelativeDateTimeFormatterTest::RunTest(
1193         const Locale& locale,
1194         const WithoutQuantityExpected* expectedResults,
1195         int32_t expectedResultLength) {
1196     UErrorCode status = U_ZERO_ERROR;
1197     RelativeDateTimeFormatter fmt(locale, status);
1198     if (U_FAILURE(status)) {
1199         dataerrln("Unable to create format object - %s", u_errorName(status));
1200         return;
1201     }
1202     RunTest(fmt, expectedResults, expectedResultLength, locale.getName());
1203 }
1204 
RunTest(const Locale & locale,UDateRelativeDateTimeFormatterStyle style,const WithoutQuantityExpected * expectedResults,int32_t expectedResultLength)1205 void RelativeDateTimeFormatterTest::RunTest(
1206         const Locale& locale,
1207         UDateRelativeDateTimeFormatterStyle style,
1208         const WithoutQuantityExpected* expectedResults,
1209         int32_t expectedResultLength) {
1210     UErrorCode status = U_ZERO_ERROR;
1211     RelativeDateTimeFormatter fmt(
1212             locale, NULL, style, UDISPCTX_CAPITALIZATION_NONE, status);
1213     if (U_FAILURE(status)) {
1214         dataerrln("Unable to create format object - %s", u_errorName(status));
1215         return;
1216     }
1217     RunTest(fmt, expectedResults, expectedResultLength, locale.getName());
1218 }
1219 
RunTest(const RelativeDateTimeFormatter & fmt,const WithQuantityExpected * expectedResults,int32_t expectedResultLength,const char * description)1220 void RelativeDateTimeFormatterTest::RunTest(
1221         const RelativeDateTimeFormatter& fmt,
1222         const WithQuantityExpected* expectedResults,
1223         int32_t expectedResultLength,
1224         const char *description) {
1225     for (int32_t i = 0; i < expectedResultLength; ++i) {
1226         CheckExpectedResult(fmt, expectedResults[i], description);
1227     }
1228 }
1229 
RunTest(const RelativeDateTimeFormatter & fmt,const WithQuantityExpectedRelativeDateTimeUnit * expectedResults,int32_t expectedResultLength,const char * description,bool numeric)1230 void RelativeDateTimeFormatterTest::RunTest(
1231         const RelativeDateTimeFormatter& fmt,
1232         const WithQuantityExpectedRelativeDateTimeUnit* expectedResults,
1233         int32_t expectedResultLength,
1234         const char *description,
1235         bool numeric) {
1236     for (int32_t i = 0; i < expectedResultLength; ++i) {
1237         CheckExpectedResult(fmt, expectedResults[i], description, numeric);
1238     }
1239 }
1240 
RunTest(const RelativeDateTimeFormatter & fmt,const WithoutQuantityExpected * expectedResults,int32_t expectedResultLength,const char * description)1241 void RelativeDateTimeFormatterTest::RunTest(
1242         const RelativeDateTimeFormatter& fmt,
1243         const WithoutQuantityExpected* expectedResults,
1244         int32_t expectedResultLength,
1245         const char *description) {
1246     for (int32_t i = 0; i < expectedResultLength; ++i) {
1247         CheckExpectedResult(fmt, expectedResults[i], description);
1248     }
1249 }
1250 
CheckExpectedResult(const RelativeDateTimeFormatter & fmt,const WithQuantityExpected & expectedResult,const char * description)1251 void RelativeDateTimeFormatterTest::CheckExpectedResult(
1252         const RelativeDateTimeFormatter& fmt,
1253         const WithQuantityExpected& expectedResult,
1254         const char* description) {
1255     UErrorCode status = U_ZERO_ERROR;
1256     UnicodeString actual;
1257     fmt.format(expectedResult.value, expectedResult.direction, expectedResult.unit, actual, status);
1258     UnicodeString expected(expectedResult.expected, -1, US_INV);
1259     expected = expected.unescape();
1260     char buffer[256];
1261     sprintf(
1262             buffer,
1263             "%s, %f, %s, %s",
1264             description,
1265             expectedResult.value,
1266             DirectionStr(expectedResult.direction),
1267             RelativeUnitStr(expectedResult.unit));
1268     if (actual != expected) {
1269         errln(UnicodeString("Fail: Expected: ") + expected
1270                 + ", Got: " + actual
1271                 + ", For: " + buffer);
1272     }
1273 }
1274 
CheckExpectedResult(const RelativeDateTimeFormatter & fmt,const WithQuantityExpectedRelativeDateTimeUnit & expectedResult,const char * description,bool numeric)1275 void RelativeDateTimeFormatterTest::CheckExpectedResult(
1276         const RelativeDateTimeFormatter& fmt,
1277         const WithQuantityExpectedRelativeDateTimeUnit& expectedResult,
1278         const char* description,
1279         bool numeric) {
1280     UErrorCode status = U_ZERO_ERROR;
1281     UnicodeString actual;
1282     if (numeric) {
1283       fmt.formatNumeric(expectedResult.value, expectedResult.unit, actual, status);
1284     } else {
1285       fmt.format(expectedResult.value, expectedResult.unit, actual, status);
1286     }
1287     UnicodeString expected(expectedResult.expected, -1, US_INV);
1288     expected = expected.unescape();
1289     char buffer[256];
1290     sprintf(
1291             buffer,
1292             "%s, %f, %s",
1293             description,
1294             expectedResult.value,
1295             RelativeDateTimeUnitStr(expectedResult.unit));
1296     if (actual != expected) {
1297         errln(UnicodeString("Fail: Expected: ") + expected
1298                 + ", Got: " + actual
1299                 + ", For: " + buffer);
1300     }
1301 }
1302 
CheckExpectedResult(const RelativeDateTimeFormatter & fmt,const WithoutQuantityExpected & expectedResult,const char * description)1303 void RelativeDateTimeFormatterTest::CheckExpectedResult(
1304         const RelativeDateTimeFormatter& fmt,
1305         const WithoutQuantityExpected& expectedResult,
1306         const char* description) {
1307     UErrorCode status = U_ZERO_ERROR;
1308     UnicodeString actual;
1309     fmt.format(expectedResult.direction, expectedResult.unit, actual, status);
1310     UnicodeString expected(expectedResult.expected, -1, US_INV);
1311     expected = expected.unescape();
1312     char buffer[256];
1313     sprintf(
1314             buffer,
1315             "%s, %s, %s",
1316             description,
1317             DirectionStr(expectedResult.direction),
1318             AbsoluteUnitStr(expectedResult.unit));
1319     if (actual != expected) {
1320         errln(UnicodeString("Fail: Expected: ") + expected
1321                 + ", Got: " + actual
1322                 + ", For: " + buffer);
1323     }
1324 }
1325 
VerifyIllegalArgument(const RelativeDateTimeFormatter & fmt,UDateDirection direction,UDateRelativeUnit unit)1326 void RelativeDateTimeFormatterTest::VerifyIllegalArgument(
1327         const RelativeDateTimeFormatter& fmt,
1328         UDateDirection direction,
1329         UDateRelativeUnit unit) {
1330     UnicodeString appendTo;
1331     UErrorCode status = U_ZERO_ERROR;
1332     fmt.format(1.0, direction, unit, appendTo, status);
1333     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1334         errln("Expected U_ILLEGAL_ARGUMENT_ERROR, got %s", u_errorName(status));
1335     }
1336 }
1337 
VerifyIllegalArgument(const RelativeDateTimeFormatter & fmt,UDateDirection direction,UDateAbsoluteUnit unit)1338 void RelativeDateTimeFormatterTest::VerifyIllegalArgument(
1339         const RelativeDateTimeFormatter& fmt,
1340         UDateDirection direction,
1341         UDateAbsoluteUnit unit) {
1342     UnicodeString appendTo;
1343     UErrorCode status = U_ZERO_ERROR;
1344     fmt.format(direction, unit, appendTo, status);
1345     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1346         errln("Expected U_ILLEGAL_ARGUMENT_ERROR, got %s", u_errorName(status));
1347     }
1348 }
1349 
1350 /* Add tests to check "sideways" data loading. */
TestSidewaysDataLoading(void)1351 void RelativeDateTimeFormatterTest::TestSidewaysDataLoading(void) {
1352     UErrorCode status = U_ZERO_ERROR;
1353     UnicodeString actual;
1354     UnicodeString expected;
1355     Locale enGbLocale("en_GB");
1356 
1357     RelativeDateTimeFormatter fmt(enGbLocale, NULL, UDAT_STYLE_NARROW,
1358                                   UDISPCTX_CAPITALIZATION_NONE, status);
1359     if (U_FAILURE(status)) {
1360         dataerrln("Unable to create RelativeDateTimeFormatter - %s", u_errorName(status));
1361         return;
1362     }
1363 
1364     status = U_ZERO_ERROR;
1365     actual = "";
1366     fmt.format(3.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_MONTHS, actual, status);
1367     expected = "in 3 mo";
1368     assertEquals("narrow in 3 mo", expected, actual);
1369 
1370     fmt.format(3.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, actual.remove(), status);
1371     expected = "3 days ago";
1372     assertEquals("3 days ago (positive 3.0): ", expected, actual);
1373 
1374     expected = "-3 days ago";
1375     fmt.format(-3.0, UDAT_DIRECTION_LAST, UDAT_RELATIVE_DAYS, actual.remove(), status);
1376     assertEquals("3 days ago (negative 3.0): ", expected, actual);
1377 
1378     expected = "next yr";
1379     fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_YEAR, actual.remove(), status);
1380     assertEquals("next year: ", expected, actual);
1381 
1382     // Testing the SHORT style
1383     RelativeDateTimeFormatter fmtshort(enGbLocale, NULL, UDAT_STYLE_SHORT,
1384                                   UDISPCTX_CAPITALIZATION_NONE, status);
1385     expected = "now";
1386     fmtshort.format(0.0, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, actual.remove(), status);
1387 
1388     expected = "next yr";
1389     fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_YEAR, actual.remove(), status);
1390     assertEquals("next year: ", expected, actual);
1391 }
1392 
TestFormatNumeric()1393 void RelativeDateTimeFormatterTest::TestFormatNumeric() {
1394     RunTest("en", kEnglishFormatNumeric, UPRV_LENGTHOF(kEnglishFormatNumeric), true);
1395 }
1396 
TestFormat()1397 void RelativeDateTimeFormatterTest::TestFormat() {
1398     RunTest("en", kEnglishFormat, UPRV_LENGTHOF(kEnglishFormat), false);
1399 }
1400 
TestLocales()1401 void RelativeDateTimeFormatterTest::TestLocales() {
1402     int32_t numLocales = 0;
1403     const Locale *availableLocales = Locale::getAvailableLocales(numLocales);
1404     std::vector<std::unique_ptr<RelativeDateTimeFormatter>> allFormatters;
1405     for (int localeIdx=0; localeIdx<numLocales; localeIdx++) {
1406         const Locale &loc = availableLocales[localeIdx];
1407         UErrorCode status = U_ZERO_ERROR;
1408         std::unique_ptr<RelativeDateTimeFormatter> rdtf(new RelativeDateTimeFormatter(loc, status));
1409         allFormatters.push_back(std::move(rdtf));
1410         assertSuccess(loc.getName(), status);
1411     }
1412 }
1413 
TestFields()1414 void RelativeDateTimeFormatterTest::TestFields() {
1415     IcuTestErrorCode status(*this, "TestFields");
1416 
1417     RelativeDateTimeFormatter fmt("en-US", status);
1418 
1419     {
1420         const char16_t* message = u"automatic absolute unit";
1421         FormattedRelativeDateTime fv = fmt.formatToValue(1, UDAT_REL_UNIT_DAY, status);
1422         const char16_t* expectedString = u"tomorrow";
1423         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1424             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 0, 8}};
1425         checkMixedFormattedValue(
1426             message,
1427             fv,
1428             expectedString,
1429             expectedFieldPositions,
1430             UPRV_LENGTHOF(expectedFieldPositions));
1431     }
1432     {
1433         const char16_t* message = u"automatic numeric unit";
1434         FormattedRelativeDateTime fv = fmt.formatToValue(3, UDAT_REL_UNIT_DAY, status);
1435         const char16_t* expectedString = u"in 3 days";
1436         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1437             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 0, 2},
1438             {UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, 3, 4},
1439             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD, 3, 4},
1440             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 5, 9}};
1441         checkMixedFormattedValue(
1442             message,
1443             fv,
1444             expectedString,
1445             expectedFieldPositions,
1446             UPRV_LENGTHOF(expectedFieldPositions));
1447     }
1448     {
1449         const char16_t* message = u"manual absolute unit";
1450         FormattedRelativeDateTime fv = fmt.formatToValue(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_MONDAY, status);
1451         const char16_t* expectedString = u"next Monday";
1452         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1453             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 0, 11}};
1454         checkMixedFormattedValue(
1455             message,
1456             fv,
1457             expectedString,
1458             expectedFieldPositions,
1459             UPRV_LENGTHOF(expectedFieldPositions));
1460     }
1461     {
1462         const char16_t* message = u"manual numeric unit";
1463         FormattedRelativeDateTime fv = fmt.formatNumericToValue(1.5, UDAT_REL_UNIT_WEEK, status);
1464         const char16_t* expectedString = u"in 1.5 weeks";
1465         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1466             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 0, 2},
1467             {UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, 3, 4},
1468             {UFIELD_CATEGORY_NUMBER, UNUM_DECIMAL_SEPARATOR_FIELD, 4, 5},
1469             {UFIELD_CATEGORY_NUMBER, UNUM_FRACTION_FIELD, 5, 6},
1470             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD, 3, 6},
1471             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 7, 12}};
1472         checkMixedFormattedValue(
1473             message,
1474             fv,
1475             expectedString,
1476             expectedFieldPositions,
1477             UPRV_LENGTHOF(expectedFieldPositions));
1478     }
1479     {
1480         const char16_t* message = u"manual numeric resolved unit";
1481         FormattedRelativeDateTime fv = fmt.formatToValue(12, UDAT_DIRECTION_LAST, UDAT_RELATIVE_HOURS, status);
1482         const char16_t* expectedString = u"12 hours ago";
1483         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1484             {UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, 0, 2},
1485             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD, 0, 2},
1486             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 3, 12}};
1487         checkMixedFormattedValue(
1488             message,
1489             fv,
1490             expectedString,
1491             expectedFieldPositions,
1492             UPRV_LENGTHOF(expectedFieldPositions));
1493     }
1494 
1495     // Test when the number field is at the end
1496     fmt = RelativeDateTimeFormatter("sw", status);
1497     {
1498         const char16_t* message = u"numeric field at end";
1499         FormattedRelativeDateTime fv = fmt.formatToValue(12, UDAT_REL_UNIT_HOUR, status);
1500         const char16_t* expectedString = u"baada ya saa 12";
1501         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1502             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 0, 12},
1503             {UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, 13, 15},
1504             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD, 13, 15}};
1505         checkMixedFormattedValue(
1506             message,
1507             fv,
1508             expectedString,
1509             expectedFieldPositions,
1510             UPRV_LENGTHOF(expectedFieldPositions));
1511     }
1512 }
1513 
TestRBNF()1514 void RelativeDateTimeFormatterTest::TestRBNF() {
1515     IcuTestErrorCode status(*this, "TestRBNF");
1516 
1517     LocalPointer<RuleBasedNumberFormat> rbnf(new RuleBasedNumberFormat(URBNF_SPELLOUT, "en-us", status));
1518     if (status.errIfFailureAndReset()) { return; }
1519     RelativeDateTimeFormatter fmt("en-us", rbnf.orphan(), status);
1520     UnicodeString result;
1521     assertEquals("format (direction)", "in five seconds",
1522         fmt.format(5, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_SECONDS, result, status));
1523     assertEquals("formatNumeric", "one week ago",
1524         fmt.formatNumeric(-1, UDAT_REL_UNIT_WEEK, result.remove(), status));
1525     assertEquals("format (absolute)", "yesterday",
1526         fmt.format(UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_DAY, result.remove(), status));
1527     assertEquals("format (relative)", "in forty-two months",
1528         fmt.format(42, UDAT_REL_UNIT_MONTH, result.remove(), status));
1529 
1530     {
1531         const char16_t* message = u"formatToValue (relative)";
1532         FormattedRelativeDateTime fv = fmt.formatToValue(-100, UDAT_REL_UNIT_YEAR, status);
1533         const char16_t* expectedString = u"one hundred years ago";
1534         static const UFieldPositionWithCategory expectedFieldPositions[] = {
1535             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD, 0, 11},
1536             {UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD, 12, 21}};
1537         checkMixedFormattedValue(
1538             message,
1539             fv,
1540             expectedString,
1541             expectedFieldPositions,
1542             UPRV_LENGTHOF(expectedFieldPositions));
1543     }
1544 }
1545 
1546 static const char *kLast2 = "Last_2";
1547 static const char *kLast = "Last";
1548 static const char *kThis = "This";
1549 static const char *kNext = "Next";
1550 static const char *kNext2 = "Next_2";
1551 static const char *kPlain = "Plain";
1552 
1553 static const char *kSeconds = "Seconds";
1554 static const char *kMinutes = "Minutes";
1555 static const char *kHours = "Hours";
1556 static const char *kDays = "Days";
1557 static const char *kWeeks = "Weeks";
1558 static const char *kMonths = "Months";
1559 static const char *kQuarters = "Quarters";
1560 static const char *kYears = "Years";
1561 static const char *kSundays = "Sundays";
1562 static const char *kMondays = "Mondays";
1563 static const char *kTuesdays = "Tuesdays";
1564 static const char *kWednesdays = "Wednesdays";
1565 static const char *kThursdays = "Thursdays";
1566 static const char *kFridays = "Fridays";
1567 static const char *kSaturdays = "Saturdays";
1568 
1569 static const char *kSunday = "Sunday";
1570 static const char *kMonday = "Monday";
1571 static const char *kTuesday = "Tuesday";
1572 static const char *kWednesday = "Wednesday";
1573 static const char *kThursday = "Thursday";
1574 static const char *kFriday = "Friday";
1575 static const char *kSaturday = "Saturday";
1576 static const char *kDay = "Day";
1577 static const char *kWeek = "Week";
1578 static const char *kMonth = "Month";
1579 static const char *kQuarter = "Quarter";
1580 static const char *kYear = "Year";
1581 static const char *kNow = "Now";
1582 
1583 static const char *kUndefined = "Undefined";
1584 
DirectionStr(UDateDirection direction)1585 static const char *DirectionStr(
1586         UDateDirection direction) {
1587     switch (direction) {
1588         case UDAT_DIRECTION_LAST_2:
1589             return kLast2;
1590         case UDAT_DIRECTION_LAST:
1591             return kLast;
1592         case UDAT_DIRECTION_THIS:
1593             return kThis;
1594         case UDAT_DIRECTION_NEXT:
1595             return kNext;
1596         case UDAT_DIRECTION_NEXT_2:
1597             return kNext2;
1598         case UDAT_DIRECTION_PLAIN:
1599             return kPlain;
1600         default:
1601             return kUndefined;
1602     }
1603     return kUndefined;
1604 }
1605 
RelativeUnitStr(UDateRelativeUnit unit)1606 static const char *RelativeUnitStr(
1607         UDateRelativeUnit unit) {
1608     switch (unit) {
1609         case UDAT_RELATIVE_SECONDS:
1610             return kSeconds;
1611         case UDAT_RELATIVE_MINUTES:
1612             return kMinutes;
1613         case UDAT_RELATIVE_HOURS:
1614             return kHours;
1615         case UDAT_RELATIVE_DAYS:
1616             return kDays;
1617         case UDAT_RELATIVE_WEEKS:
1618             return kWeeks;
1619         case UDAT_RELATIVE_MONTHS:
1620             return kMonths;
1621         case UDAT_RELATIVE_YEARS:
1622             return kYears;
1623         default:
1624             return kUndefined;
1625     }
1626     return kUndefined;
1627 }
1628 
RelativeDateTimeUnitStr(URelativeDateTimeUnit unit)1629 static const char *RelativeDateTimeUnitStr(
1630         URelativeDateTimeUnit  unit) {
1631     switch (unit) {
1632         case UDAT_REL_UNIT_SECOND:
1633             return kSeconds;
1634         case UDAT_REL_UNIT_MINUTE:
1635             return kMinutes;
1636         case UDAT_REL_UNIT_HOUR:
1637             return kHours;
1638         case UDAT_REL_UNIT_DAY:
1639             return kDays;
1640         case UDAT_REL_UNIT_WEEK:
1641             return kWeeks;
1642         case UDAT_REL_UNIT_MONTH:
1643             return kMonths;
1644         case UDAT_REL_UNIT_QUARTER:
1645             return kQuarters;
1646         case UDAT_REL_UNIT_YEAR:
1647             return kYears;
1648         case UDAT_REL_UNIT_SUNDAY:
1649             return kSundays;
1650         case UDAT_REL_UNIT_MONDAY:
1651             return kMondays;
1652         case UDAT_REL_UNIT_TUESDAY:
1653             return kTuesdays;
1654         case UDAT_REL_UNIT_WEDNESDAY:
1655             return kWednesdays;
1656         case UDAT_REL_UNIT_THURSDAY:
1657             return kThursdays;
1658         case UDAT_REL_UNIT_FRIDAY:
1659             return kFridays;
1660         case UDAT_REL_UNIT_SATURDAY:
1661             return kSaturdays;
1662         default:
1663             return kUndefined;
1664     }
1665     return kUndefined;
1666 }
1667 
AbsoluteUnitStr(UDateAbsoluteUnit unit)1668 static const char *AbsoluteUnitStr(
1669         UDateAbsoluteUnit unit) {
1670     switch (unit) {
1671         case UDAT_ABSOLUTE_SUNDAY:
1672             return kSunday;
1673         case UDAT_ABSOLUTE_MONDAY:
1674             return kMonday;
1675         case UDAT_ABSOLUTE_TUESDAY:
1676             return kTuesday;
1677         case UDAT_ABSOLUTE_WEDNESDAY:
1678             return kWednesday;
1679         case UDAT_ABSOLUTE_THURSDAY:
1680             return kThursday;
1681         case UDAT_ABSOLUTE_FRIDAY:
1682             return kFriday;
1683         case UDAT_ABSOLUTE_SATURDAY:
1684             return kSaturday;
1685         case UDAT_ABSOLUTE_DAY:
1686             return kDay;
1687         case UDAT_ABSOLUTE_WEEK:
1688             return kWeek;
1689         case UDAT_ABSOLUTE_MONTH:
1690             return kMonth;
1691         case UDAT_ABSOLUTE_QUARTER:
1692             return kQuarter;
1693         case UDAT_ABSOLUTE_YEAR:
1694             return kYear;
1695         case UDAT_ABSOLUTE_NOW:
1696             return kNow;
1697         default:
1698             return kUndefined;
1699     }
1700     return kUndefined;
1701 }
1702 
createRelativeDateTimeFormatterTest()1703 extern IntlTest *createRelativeDateTimeFormatterTest() {
1704     return new RelativeDateTimeFormatterTest();
1705 }
1706 
1707 #endif
1708