1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <sal/config.h>
12 #include <cppunit/TestFixture.h>
13 #include <cppunit/TestAssert.h>
14 #include <cppunit/extensions/HelperMacros.h>
15 #include <cppunit/plugin/TestPlugIn.h>
17 #include <i18nlangtag/mslangid.hxx>
18 #include <i18nlangtag/languagetag.hxx>
19 #include <i18nlangtag/languagetagicu.hxx>
21 #include <rtl/ustring.hxx>
23 #include <com/sun/star/lang/Locale.hpp>
24 #include <com/sun/star/i18n/ScriptType.hpp>
26 using namespace com::sun::star
;
30 class TestLanguageTag
: public CppUnit::TestFixture
36 void testAllIsoLangEntries();
37 void testDisplayNames();
38 void testLanguagesWithoutHyphenation();
40 CPPUNIT_TEST_SUITE(TestLanguageTag
);
41 CPPUNIT_TEST(testAllTags
);
42 CPPUNIT_TEST(testAllIsoLangEntries
);
43 CPPUNIT_TEST(testDisplayNames
);
44 CPPUNIT_TEST(testLanguagesWithoutHyphenation
);
45 CPPUNIT_TEST_SUITE_END();
48 void TestLanguageTag::testAllTags()
51 LanguageTag
de_DE( u
"de-Latn-DE"_ustr
, true );
52 OUString aBcp47
= de_DE
.getBcp47();
53 lang::Locale aLocale
= de_DE
.getLocale();
54 LanguageType nLanguageType
= de_DE
.getLanguageType();
55 CPPUNIT_ASSERT_EQUAL_MESSAGE("Default script should be stripped after canonicalize.", u
"de-DE"_ustr
, aBcp47
);
56 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, aLocale
.Language
);
57 CPPUNIT_ASSERT_EQUAL( u
"DE"_ustr
, aLocale
.Country
);
58 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
59 CPPUNIT_ASSERT_EQUAL( LANGUAGE_GERMAN
, nLanguageType
);
60 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, de_DE
.getLanguage() );
61 CPPUNIT_ASSERT_EQUAL( u
"DE"_ustr
, de_DE
.getCountry() );
62 CPPUNIT_ASSERT( de_DE
.getScript().isEmpty() );
63 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, de_DE
.getLanguageAndScript() );
64 CPPUNIT_ASSERT_EQUAL( u
"de-DE"_ustr
, de_DE
.makeFallback().getBcp47() );
68 LanguageTag
klingon( u
"i-klingon"_ustr
, true );
69 lang::Locale aLocale
= klingon
.getLocale();
70 CPPUNIT_ASSERT_EQUAL( u
"tlh"_ustr
, klingon
.getBcp47() );
71 CPPUNIT_ASSERT_EQUAL( u
"tlh"_ustr
, aLocale
.Language
);
72 CPPUNIT_ASSERT( aLocale
.Country
.isEmpty() );
73 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
74 CPPUNIT_ASSERT( klingon
.isValidBcp47() );
75 CPPUNIT_ASSERT( klingon
.isIsoLocale() );
76 CPPUNIT_ASSERT( klingon
.isIsoODF() );
77 LanguageType nLang
= klingon
.getLanguageType();
78 LanguageTag
klingon_id( nLang
);
79 CPPUNIT_ASSERT_EQUAL( u
"tlh"_ustr
, klingon_id
.getBcp47() );
83 OUString
s_sr_RS( u
"sr-RS"_ustr
);
84 LanguageTag
sr_RS( s_sr_RS
, true );
85 lang::Locale aLocale
= sr_RS
.getLocale();
86 CPPUNIT_ASSERT_EQUAL( s_sr_RS
, sr_RS
.getBcp47() );
87 CPPUNIT_ASSERT_EQUAL( u
"sr"_ustr
, aLocale
.Language
);
88 CPPUNIT_ASSERT_EQUAL( u
"RS"_ustr
, aLocale
.Country
);
89 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
90 CPPUNIT_ASSERT_EQUAL( LANGUAGE_USER_SERBIAN_CYRILLIC_SERBIA
, sr_RS
.getLanguageType() );
91 CPPUNIT_ASSERT( sr_RS
.isValidBcp47() );
92 CPPUNIT_ASSERT( sr_RS
.isIsoLocale() );
93 CPPUNIT_ASSERT( sr_RS
.isIsoODF() );
97 OUString
s_sr_Latn_RS( u
"sr-Latn-RS"_ustr
);
98 LanguageTag
sr_RS( s_sr_Latn_RS
, true );
99 lang::Locale aLocale
= sr_RS
.getLocale();
100 CPPUNIT_ASSERT_EQUAL( s_sr_Latn_RS
, sr_RS
.getBcp47() );
101 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
102 CPPUNIT_ASSERT_EQUAL( u
"RS"_ustr
, aLocale
.Country
);
103 CPPUNIT_ASSERT_EQUAL( s_sr_Latn_RS
, aLocale
.Variant
);
104 CPPUNIT_ASSERT_EQUAL( LANGUAGE_USER_SERBIAN_LATIN_SERBIA
, sr_RS
.getLanguageType() );
105 CPPUNIT_ASSERT( sr_RS
.isValidBcp47() );
106 CPPUNIT_ASSERT( !sr_RS
.isIsoLocale() );
107 CPPUNIT_ASSERT( sr_RS
.isIsoODF() );
108 CPPUNIT_ASSERT_EQUAL( u
"sr"_ustr
, sr_RS
.getLanguage() );
109 CPPUNIT_ASSERT_EQUAL( u
"RS"_ustr
, sr_RS
.getCountry() );
110 CPPUNIT_ASSERT_EQUAL( u
"Latn"_ustr
, sr_RS
.getScript() );
111 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn"_ustr
, sr_RS
.getLanguageAndScript() );
115 OUString
s_sr_Latn_CS( u
"sr-Latn-CS"_ustr
);
116 LanguageTag
sr_Latn_CS( s_sr_Latn_CS
, true );
117 lang::Locale aLocale
= sr_Latn_CS
.getLocale();
118 CPPUNIT_ASSERT_EQUAL( s_sr_Latn_CS
, sr_Latn_CS
.getBcp47() );
119 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
120 CPPUNIT_ASSERT_EQUAL( u
"CS"_ustr
, aLocale
.Country
);
121 CPPUNIT_ASSERT_EQUAL( s_sr_Latn_CS
, aLocale
.Variant
);
122 CPPUNIT_ASSERT_EQUAL( LANGUAGE_SERBIAN_LATIN_SAM
, sr_Latn_CS
.getLanguageType() );
123 CPPUNIT_ASSERT( sr_Latn_CS
.isValidBcp47() );
124 CPPUNIT_ASSERT( !sr_Latn_CS
.isIsoLocale() );
125 CPPUNIT_ASSERT( sr_Latn_CS
.isIsoODF() );
126 CPPUNIT_ASSERT_EQUAL( u
"sr"_ustr
, sr_Latn_CS
.getLanguage() );
127 CPPUNIT_ASSERT_EQUAL( u
"CS"_ustr
, sr_Latn_CS
.getCountry() );
128 CPPUNIT_ASSERT_EQUAL( u
"Latn"_ustr
, sr_Latn_CS
.getScript() );
129 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn"_ustr
, sr_Latn_CS
.getLanguageAndScript() );
130 ::std::vector
< OUString
> sr_Latn_CS_Fallbacks( sr_Latn_CS
.getFallbackStrings( true));
131 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(9), sr_Latn_CS_Fallbacks
.size());
132 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn-CS"_ustr
, sr_Latn_CS_Fallbacks
[0]);
133 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn-YU"_ustr
, sr_Latn_CS_Fallbacks
[1]);
134 CPPUNIT_ASSERT_EQUAL( u
"sh-CS"_ustr
, sr_Latn_CS_Fallbacks
[2]);
135 CPPUNIT_ASSERT_EQUAL( u
"sh-YU"_ustr
, sr_Latn_CS_Fallbacks
[3]);
136 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn"_ustr
, sr_Latn_CS_Fallbacks
[4]);
137 CPPUNIT_ASSERT_EQUAL( u
"sh"_ustr
, sr_Latn_CS_Fallbacks
[5]);
138 CPPUNIT_ASSERT_EQUAL( u
"sr-CS"_ustr
, sr_Latn_CS_Fallbacks
[6]);
139 CPPUNIT_ASSERT_EQUAL( u
"sr-YU"_ustr
, sr_Latn_CS_Fallbacks
[7]);
140 CPPUNIT_ASSERT_EQUAL( u
"sr"_ustr
, sr_Latn_CS_Fallbacks
[8]);
141 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn-CS"_ustr
, sr_Latn_CS
.makeFallback().getBcp47());
144 // 'sh-RS' has an internal override to 'sr-Latn-RS'
146 LanguageTag
sh_RS( u
"sh-RS"_ustr
, true );
147 lang::Locale aLocale
= sh_RS
.getLocale();
148 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn-RS"_ustr
, sh_RS
.getBcp47() );
149 CPPUNIT_ASSERT_EQUAL( I18NLANGTAG_QLT
, aLocale
.Language
);
150 CPPUNIT_ASSERT_EQUAL( u
"RS"_ustr
, aLocale
.Country
);
151 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn-RS"_ustr
, aLocale
.Variant
);
152 CPPUNIT_ASSERT_EQUAL( LANGUAGE_USER_SERBIAN_LATIN_SERBIA
, sh_RS
.getLanguageType() );
153 CPPUNIT_ASSERT( sh_RS
.isValidBcp47() );
154 CPPUNIT_ASSERT( !sh_RS
.isIsoLocale() );
155 CPPUNIT_ASSERT( sh_RS
.isIsoODF() );
156 CPPUNIT_ASSERT_EQUAL( u
"sr"_ustr
, sh_RS
.getLanguage() );
157 CPPUNIT_ASSERT_EQUAL( u
"RS"_ustr
, sh_RS
.getCountry() );
158 CPPUNIT_ASSERT_EQUAL( u
"Latn"_ustr
, sh_RS
.getScript() );
159 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn"_ustr
, sh_RS
.getLanguageAndScript() );
160 ::std::vector
< OUString
> sh_RS_Fallbacks( sh_RS
.getFallbackStrings( true));
161 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(6), sh_RS_Fallbacks
.size());
162 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn-RS"_ustr
, sh_RS_Fallbacks
[0]);
163 CPPUNIT_ASSERT_EQUAL( u
"sh-RS"_ustr
, sh_RS_Fallbacks
[1]);
164 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn"_ustr
, sh_RS_Fallbacks
[2]);
165 CPPUNIT_ASSERT_EQUAL( u
"sh"_ustr
, sh_RS_Fallbacks
[3]);
166 CPPUNIT_ASSERT_EQUAL( u
"sr-RS"_ustr
, sh_RS_Fallbacks
[4]);
167 CPPUNIT_ASSERT_EQUAL( u
"sr"_ustr
, sh_RS_Fallbacks
[5]);
168 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn-RS"_ustr
, sh_RS
.makeFallback().getBcp47());
169 CPPUNIT_ASSERT_EQUAL( u
"sr-Latn-RS"_ustr
, sh_RS
.getBcp47());
170 CPPUNIT_ASSERT_EQUAL( LANGUAGE_USER_SERBIAN_LATIN_SERBIA
, sh_RS
.getLanguageType() );
173 // 'bs-Latn-BA' with 'Latn' suppress-script, we map that ourselves for a
174 // known LangID with an override and canonicalization should work the same
175 // without liblangtag.
177 LanguageTag
bs_Latn_BA( u
"bs-Latn-BA"_ustr
, true );
178 lang::Locale aLocale
= bs_Latn_BA
.getLocale();
179 CPPUNIT_ASSERT_EQUAL( u
"bs-BA"_ustr
, bs_Latn_BA
.getBcp47() );
180 CPPUNIT_ASSERT_EQUAL( u
"bs"_ustr
, aLocale
.Language
);
181 CPPUNIT_ASSERT_EQUAL( u
"BA"_ustr
, aLocale
.Country
);
182 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
183 CPPUNIT_ASSERT_EQUAL( LANGUAGE_BOSNIAN_LATIN_BOSNIA_HERZEGOVINA
, bs_Latn_BA
.getLanguageType() );
184 CPPUNIT_ASSERT( bs_Latn_BA
.isValidBcp47() );
185 CPPUNIT_ASSERT( bs_Latn_BA
.isIsoLocale() );
186 CPPUNIT_ASSERT( bs_Latn_BA
.isIsoODF() );
187 CPPUNIT_ASSERT_EQUAL( u
"bs"_ustr
, bs_Latn_BA
.getLanguage() );
188 CPPUNIT_ASSERT_EQUAL( u
"BA"_ustr
, bs_Latn_BA
.getCountry() );
189 CPPUNIT_ASSERT( bs_Latn_BA
.getScript().isEmpty() );
190 CPPUNIT_ASSERT_EQUAL( u
"bs"_ustr
, bs_Latn_BA
.getLanguageAndScript() );
191 ::std::vector
< OUString
> bs_Latn_BA_Fallbacks( bs_Latn_BA
.getFallbackStrings( true));
192 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(2), bs_Latn_BA_Fallbacks
.size());
193 CPPUNIT_ASSERT_EQUAL( u
"bs-BA"_ustr
, bs_Latn_BA_Fallbacks
[0]);
194 CPPUNIT_ASSERT_EQUAL( u
"bs"_ustr
, bs_Latn_BA_Fallbacks
[1]);
195 CPPUNIT_ASSERT_EQUAL( u
"bs-BA"_ustr
, bs_Latn_BA
.makeFallback().getBcp47());
196 CPPUNIT_ASSERT_EQUAL( u
"bs-BA"_ustr
, bs_Latn_BA
.getBcp47());
197 CPPUNIT_ASSERT_EQUAL( LANGUAGE_BOSNIAN_LATIN_BOSNIA_HERZEGOVINA
, bs_Latn_BA
.getLanguageType() );
201 OUString
s_ca_ES_valencia( u
"ca-ES-valencia"_ustr
);
202 LanguageTag
ca_ES_valencia( s_ca_ES_valencia
, true );
203 lang::Locale aLocale
= ca_ES_valencia
.getLocale();
204 CPPUNIT_ASSERT_EQUAL( s_ca_ES_valencia
, ca_ES_valencia
.getBcp47() );
205 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
206 CPPUNIT_ASSERT_EQUAL( u
"ES"_ustr
, aLocale
.Country
);
207 CPPUNIT_ASSERT_EQUAL( s_ca_ES_valencia
, aLocale
.Variant
);
208 CPPUNIT_ASSERT_EQUAL( LANGUAGE_CATALAN_VALENCIAN
, ca_ES_valencia
.getLanguageType() );
209 CPPUNIT_ASSERT( ca_ES_valencia
.isValidBcp47() );
210 CPPUNIT_ASSERT( !ca_ES_valencia
.isIsoLocale() );
211 CPPUNIT_ASSERT( !ca_ES_valencia
.isIsoODF() );
212 CPPUNIT_ASSERT_EQUAL( u
"ca"_ustr
, ca_ES_valencia
.getLanguage() );
213 CPPUNIT_ASSERT_EQUAL( u
"ES"_ustr
, ca_ES_valencia
.getCountry() );
214 CPPUNIT_ASSERT( ca_ES_valencia
.getScript().isEmpty() );
215 CPPUNIT_ASSERT_EQUAL( u
"ca"_ustr
, ca_ES_valencia
.getLanguageAndScript() );
216 ::std::vector
< OUString
> ca_ES_valencia_Fallbacks( ca_ES_valencia
.getFallbackStrings( true));
217 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(5), ca_ES_valencia_Fallbacks
.size());
218 CPPUNIT_ASSERT_EQUAL( u
"ca-ES-valencia"_ustr
, ca_ES_valencia_Fallbacks
[0]);
219 CPPUNIT_ASSERT_EQUAL( u
"ca-XV"_ustr
, ca_ES_valencia_Fallbacks
[1]);
220 CPPUNIT_ASSERT_EQUAL( u
"ca-valencia"_ustr
, ca_ES_valencia_Fallbacks
[2]);
221 CPPUNIT_ASSERT_EQUAL( u
"ca-ES"_ustr
, ca_ES_valencia_Fallbacks
[3]);
222 CPPUNIT_ASSERT_EQUAL( u
"ca"_ustr
, ca_ES_valencia_Fallbacks
[4]);
223 CPPUNIT_ASSERT_EQUAL( u
"ca-ES-valencia"_ustr
, ca_ES_valencia
.makeFallback().getBcp47());
227 OUString
s_ca_valencia( u
"ca-valencia"_ustr
);
228 LanguageTag
ca_valencia( s_ca_valencia
, true );
229 lang::Locale aLocale
= ca_valencia
.getLocale();
230 CPPUNIT_ASSERT_EQUAL( s_ca_valencia
, ca_valencia
.getBcp47() );
231 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
232 CPPUNIT_ASSERT( aLocale
.Country
.isEmpty() );
233 CPPUNIT_ASSERT_EQUAL( s_ca_valencia
, aLocale
.Variant
);
234 CPPUNIT_ASSERT( LanguageTag::isOnTheFlyID( ca_valencia
.getLanguageType()) );
235 CPPUNIT_ASSERT( ca_valencia
.isValidBcp47() );
236 CPPUNIT_ASSERT( !ca_valencia
.isIsoLocale() );
237 CPPUNIT_ASSERT( !ca_valencia
.isIsoODF() );
238 CPPUNIT_ASSERT_EQUAL( u
"ca"_ustr
, ca_valencia
.getLanguage() );
239 CPPUNIT_ASSERT( ca_valencia
.getCountry().isEmpty() );
240 CPPUNIT_ASSERT( ca_valencia
.getScript().isEmpty() );
241 CPPUNIT_ASSERT_EQUAL( u
"ca"_ustr
, ca_valencia
.getLanguageAndScript() );
242 ::std::vector
< OUString
> ca_valencia_Fallbacks( ca_valencia
.getFallbackStrings( true));
243 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(2), ca_valencia_Fallbacks
.size());
244 CPPUNIT_ASSERT_EQUAL( u
"ca-valencia"_ustr
, ca_valencia_Fallbacks
[0]);
245 CPPUNIT_ASSERT_EQUAL( u
"ca"_ustr
, ca_valencia_Fallbacks
[1]);
246 CPPUNIT_ASSERT_EQUAL( u
"ca-ES-valencia"_ustr
, ca_valencia
.makeFallback().getBcp47());
249 // 'ca-XV' has an internal override to 'ca-ES-valencia'
251 OUString
s_ca_ES_valencia( u
"ca-ES-valencia"_ustr
);
252 LanguageTag
ca_XV( u
"ca-XV"_ustr
, true );
253 lang::Locale aLocale
= ca_XV
.getLocale();
254 CPPUNIT_ASSERT_EQUAL( s_ca_ES_valencia
, ca_XV
.getBcp47() );
255 CPPUNIT_ASSERT_EQUAL( I18NLANGTAG_QLT
, aLocale
.Language
);
256 CPPUNIT_ASSERT_EQUAL( u
"ES"_ustr
, aLocale
.Country
);
257 CPPUNIT_ASSERT_EQUAL( s_ca_ES_valencia
, aLocale
.Variant
);
258 CPPUNIT_ASSERT_EQUAL( LANGUAGE_CATALAN_VALENCIAN
, ca_XV
.getLanguageType() );
259 CPPUNIT_ASSERT( ca_XV
.isValidBcp47() );
260 CPPUNIT_ASSERT( !ca_XV
.isIsoLocale() );
261 CPPUNIT_ASSERT( !ca_XV
.isIsoODF() );
262 CPPUNIT_ASSERT_EQUAL( u
"ca"_ustr
, ca_XV
.getLanguage() );
263 CPPUNIT_ASSERT_EQUAL( u
"ES"_ustr
, ca_XV
.getCountry() );
264 CPPUNIT_ASSERT( ca_XV
.getScript().isEmpty() );
265 CPPUNIT_ASSERT_EQUAL( u
"ca"_ustr
, ca_XV
.getLanguageAndScript() );
266 ::std::vector
< OUString
> ca_XV_Fallbacks( ca_XV
.getFallbackStrings( true));
267 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(5), ca_XV_Fallbacks
.size());
268 CPPUNIT_ASSERT_EQUAL( u
"ca-ES-valencia"_ustr
, ca_XV_Fallbacks
[0]);
269 CPPUNIT_ASSERT_EQUAL( u
"ca-XV"_ustr
, ca_XV_Fallbacks
[1]);
270 CPPUNIT_ASSERT_EQUAL( u
"ca-valencia"_ustr
, ca_XV_Fallbacks
[2]);
271 CPPUNIT_ASSERT_EQUAL( u
"ca-ES"_ustr
, ca_XV_Fallbacks
[3]);
272 CPPUNIT_ASSERT_EQUAL( u
"ca"_ustr
, ca_XV_Fallbacks
[4]);
273 CPPUNIT_ASSERT_EQUAL( u
"ca-ES-valencia"_ustr
, ca_XV
.makeFallback().getBcp47());
277 OUString
s_de_DE( u
"de-DE"_ustr
);
278 LanguageTag
de_DE( s_de_DE
, true );
279 lang::Locale aLocale
= de_DE
.getLocale();
280 CPPUNIT_ASSERT_EQUAL( s_de_DE
, de_DE
.getBcp47() );
281 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, aLocale
.Language
);
282 CPPUNIT_ASSERT_EQUAL( u
"DE"_ustr
, aLocale
.Country
);
283 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
284 CPPUNIT_ASSERT_EQUAL( LANGUAGE_GERMAN
, de_DE
.getLanguageType() );
285 CPPUNIT_ASSERT( de_DE
.isValidBcp47() );
286 CPPUNIT_ASSERT( de_DE
.isIsoLocale() );
287 CPPUNIT_ASSERT( de_DE
.isIsoODF() );
288 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, de_DE
.getLanguage() );
289 CPPUNIT_ASSERT_EQUAL( u
"DE"_ustr
, de_DE
.getCountry() );
290 CPPUNIT_ASSERT( de_DE
.getScript().isEmpty() );
291 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, de_DE
.getLanguageAndScript() );
292 ::std::vector
< OUString
> de_DE_Fallbacks( de_DE
.getFallbackStrings( true));
293 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(2), de_DE_Fallbacks
.size());
294 CPPUNIT_ASSERT_EQUAL( u
"de-DE"_ustr
, de_DE_Fallbacks
[0]);
295 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, de_DE_Fallbacks
[1]);
296 CPPUNIT_ASSERT_EQUAL( u
"de-DE"_ustr
, de_DE
.makeFallback().getBcp47());
300 LanguageTag
de_DE( lang::Locale( u
"de"_ustr
, u
"DE"_ustr
, u
""_ustr
) );
301 lang::Locale aLocale
= de_DE
.getLocale();
302 CPPUNIT_ASSERT_EQUAL( u
"de-DE"_ustr
, de_DE
.getBcp47() );
303 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, aLocale
.Language
);
304 CPPUNIT_ASSERT_EQUAL( u
"DE"_ustr
, aLocale
.Country
);
305 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
306 CPPUNIT_ASSERT_EQUAL( LANGUAGE_GERMAN
, de_DE
.getLanguageType() );
310 LanguageTag
de_DE( LANGUAGE_GERMAN
);
311 lang::Locale aLocale
= de_DE
.getLocale();
312 CPPUNIT_ASSERT_EQUAL( u
"de-DE"_ustr
, de_DE
.getBcp47() );
313 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, aLocale
.Language
);
314 CPPUNIT_ASSERT_EQUAL( u
"DE"_ustr
, aLocale
.Country
);
315 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
316 CPPUNIT_ASSERT_EQUAL( LANGUAGE_GERMAN
, de_DE
.getLanguageType() );
319 // Unmapped but known language-only.
321 OUString
s_de( u
"de"_ustr
);
322 LanguageTag
de( s_de
, true );
323 lang::Locale aLocale
= de
.getLocale();
324 CPPUNIT_ASSERT_EQUAL( s_de
, de
.getBcp47() );
325 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, aLocale
.Language
);
326 CPPUNIT_ASSERT( aLocale
.Country
.isEmpty() );
327 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
328 LanguageType de_LangID
= de
.getLanguageType();
329 CPPUNIT_ASSERT( de_LangID
!= LANGUAGE_GERMAN
);
330 CPPUNIT_ASSERT_EQUAL( MsLangId::getPrimaryLanguage( LANGUAGE_GERMAN
) , de_LangID
);
331 CPPUNIT_ASSERT_EQUAL( u
"de-DE"_ustr
, de
.makeFallback().getBcp47());
332 // Check registered mapping.
333 LanguageTag
de_l( de_LangID
);
334 CPPUNIT_ASSERT_EQUAL( s_de
, de_l
.getBcp47() );
337 // "bo" and "dz" share the same primary language ID, only one gets it
338 // assigned, "dz" language-only has a special mapping.
340 LanguageTag
bo( u
"bo"_ustr
, true );
341 CPPUNIT_ASSERT_EQUAL( MsLangId::getPrimaryLanguage( LANGUAGE_TIBETAN
), bo
.getLanguageType() );
342 LanguageTag
dz( u
"dz"_ustr
, true );
343 CPPUNIT_ASSERT_EQUAL( LANGUAGE_USER_DZONGKHA_MAP_LONLY
, dz
.getLanguageType() );
346 // "no", "nb" and "nn" share the same primary language ID, which even is
347 // assigned to "no-NO" for legacy so none gets it assigned, all on-the-fly
348 // except if there is a defined MS-LCID for LanguageScriptOnly (LSO).
350 LanguageTag
no( u
"no"_ustr
, true );
351 CPPUNIT_ASSERT( LanguageTag::isOnTheFlyID( no
.getLanguageType()) );
352 LanguageTag
nb( u
"nb"_ustr
, true );
353 CPPUNIT_ASSERT_EQUAL( LANGUAGE_NORWEGIAN_BOKMAL_LSO
, nb
.getLanguageType() );
354 LanguageTag
nn( u
"nn"_ustr
, true );
355 CPPUNIT_ASSERT_EQUAL( LANGUAGE_NORWEGIAN_NYNORSK_LSO
, nn
.getLanguageType() );
356 LanguageTag
no_NO( u
"no-NO"_ustr
, true );
357 CPPUNIT_ASSERT_EQUAL( LANGUAGE_NORWEGIAN
, no_NO
.getLanguageType() );
360 // 'de-1901' derived from 'de-DE-1901' grandfathered to check that it is
361 // accepted as (DIGIT 3ALNUM) variant
363 OUString
s_de_1901( u
"de-1901"_ustr
);
364 LanguageTag
de_1901( s_de_1901
);
365 lang::Locale aLocale
= de_1901
.getLocale();
366 CPPUNIT_ASSERT_EQUAL( s_de_1901
, de_1901
.getBcp47() );
367 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
368 CPPUNIT_ASSERT( aLocale
.Country
.isEmpty() );
369 CPPUNIT_ASSERT_EQUAL( s_de_1901
, aLocale
.Variant
);
370 CPPUNIT_ASSERT( LanguageTag::isOnTheFlyID( de_1901
.getLanguageType()) );
371 CPPUNIT_ASSERT( de_1901
.isValidBcp47() );
372 CPPUNIT_ASSERT( !de_1901
.isIsoLocale() );
373 CPPUNIT_ASSERT( !de_1901
.isIsoODF() );
374 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, de_1901
.getLanguageAndScript() );
375 CPPUNIT_ASSERT_EQUAL( u
"1901"_ustr
, de_1901
.getVariants() );
376 ::std::vector
< OUString
> de_1901_Fallbacks( de_1901
.getFallbackStrings( true));
377 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(2), de_1901_Fallbacks
.size());
378 CPPUNIT_ASSERT_EQUAL( u
"de-1901"_ustr
, de_1901_Fallbacks
[0]);
379 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, de_1901_Fallbacks
[1]);
382 // 'en-GB-oed' is known grandfathered for English, Oxford English
383 // Dictionary spelling.
384 // Deprecated as of 2015-04-17, prefer en-GB-oxendict instead.
385 // As of 2017-03-14 we also alias to en-GB-oxendict.
387 OUString
s_en_GB_oxendict( u
"en-GB-oxendict"_ustr
);
388 LanguageTag
en_GB_oed( u
"en-GB-oed"_ustr
);
389 lang::Locale aLocale
= en_GB_oed
.getLocale();
390 CPPUNIT_ASSERT_EQUAL( s_en_GB_oxendict
, en_GB_oed
.getBcp47() );
391 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
392 CPPUNIT_ASSERT_EQUAL( u
"GB"_ustr
, aLocale
.Country
);
393 CPPUNIT_ASSERT_EQUAL( s_en_GB_oxendict
, aLocale
.Variant
);
394 CPPUNIT_ASSERT_EQUAL( LANGUAGE_USER_ENGLISH_UK_OXENDICT
, en_GB_oed
.getLanguageType() );
395 CPPUNIT_ASSERT( en_GB_oed
.isValidBcp47() );
396 CPPUNIT_ASSERT( !en_GB_oed
.isIsoLocale() );
397 CPPUNIT_ASSERT( !en_GB_oed
.isIsoODF() );
398 CPPUNIT_ASSERT_EQUAL( u
"en"_ustr
, en_GB_oed
.getLanguageAndScript() );
399 CPPUNIT_ASSERT_EQUAL( u
"oxendict"_ustr
, en_GB_oed
.getVariants() );
400 ::std::vector
< OUString
> en_GB_oed_Fallbacks( en_GB_oed
.getFallbackStrings( true));
401 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(5), en_GB_oed_Fallbacks
.size() );
402 CPPUNIT_ASSERT_EQUAL( u
"en-GB-oxendict"_ustr
, en_GB_oed_Fallbacks
[0]);
403 CPPUNIT_ASSERT_EQUAL( u
"en-GB-oed"_ustr
, en_GB_oed_Fallbacks
[1]);
404 CPPUNIT_ASSERT_EQUAL( u
"en-oxendict"_ustr
, en_GB_oed_Fallbacks
[2]);
405 CPPUNIT_ASSERT_EQUAL( u
"en-GB"_ustr
, en_GB_oed_Fallbacks
[3]);
406 CPPUNIT_ASSERT_EQUAL( u
"en"_ustr
, en_GB_oed_Fallbacks
[4]);
407 // 'en-oed' is not a valid fallback!
410 // 'en-GB-oxendict' as preferred over 'en-GB-oed'.
412 OUString
s_en_GB_oxendict( u
"en-GB-oxendict"_ustr
);
413 LanguageTag
en_GB_oxendict( s_en_GB_oxendict
);
414 lang::Locale aLocale
= en_GB_oxendict
.getLocale();
415 CPPUNIT_ASSERT_EQUAL( s_en_GB_oxendict
, en_GB_oxendict
.getBcp47() );
416 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
417 CPPUNIT_ASSERT_EQUAL( u
"GB"_ustr
, aLocale
.Country
);
418 CPPUNIT_ASSERT_EQUAL( s_en_GB_oxendict
, aLocale
.Variant
);
419 CPPUNIT_ASSERT_EQUAL( LANGUAGE_USER_ENGLISH_UK_OXENDICT
, en_GB_oxendict
.getLanguageType() );
420 CPPUNIT_ASSERT( en_GB_oxendict
.isValidBcp47() );
421 CPPUNIT_ASSERT( !en_GB_oxendict
.isIsoLocale() );
422 CPPUNIT_ASSERT( !en_GB_oxendict
.isIsoODF() );
423 CPPUNIT_ASSERT_EQUAL( u
"en"_ustr
, en_GB_oxendict
.getLanguageAndScript() );
424 CPPUNIT_ASSERT_EQUAL( u
"oxendict"_ustr
, en_GB_oxendict
.getVariants() );
425 ::std::vector
< OUString
> en_GB_oxendict_Fallbacks( en_GB_oxendict
.getFallbackStrings( true));
426 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(5), en_GB_oxendict_Fallbacks
.size() );
427 CPPUNIT_ASSERT_EQUAL( u
"en-GB-oxendict"_ustr
, en_GB_oxendict_Fallbacks
[0]);
428 CPPUNIT_ASSERT_EQUAL( u
"en-GB-oed"_ustr
, en_GB_oxendict_Fallbacks
[1]);
429 CPPUNIT_ASSERT_EQUAL( u
"en-oxendict"_ustr
, en_GB_oxendict_Fallbacks
[2]);
430 CPPUNIT_ASSERT_EQUAL( u
"en-GB"_ustr
, en_GB_oxendict_Fallbacks
[3]);
431 CPPUNIT_ASSERT_EQUAL( u
"en"_ustr
, en_GB_oxendict_Fallbacks
[4]);
434 // 'es-ES-u-co-trad' is a valid (and known) Extension U tag
436 OUString
s_es_ES_u_co_trad( u
"es-ES-u-co-trad"_ustr
);
437 LanguageTag
es_ES_u_co_trad( s_es_ES_u_co_trad
);
438 lang::Locale aLocale
= es_ES_u_co_trad
.getLocale();
439 CPPUNIT_ASSERT_EQUAL( s_es_ES_u_co_trad
, es_ES_u_co_trad
.getBcp47() );
440 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
441 CPPUNIT_ASSERT_EQUAL( u
"ES"_ustr
, aLocale
.Country
);
442 CPPUNIT_ASSERT_EQUAL( s_es_ES_u_co_trad
, aLocale
.Variant
);
443 CPPUNIT_ASSERT_EQUAL( LANGUAGE_SPANISH_DATED
, es_ES_u_co_trad
.getLanguageType() );
444 CPPUNIT_ASSERT( es_ES_u_co_trad
.isValidBcp47() );
445 CPPUNIT_ASSERT( !es_ES_u_co_trad
.isIsoLocale() );
446 CPPUNIT_ASSERT( !es_ES_u_co_trad
.isIsoODF() );
447 CPPUNIT_ASSERT_EQUAL( u
"es"_ustr
, es_ES_u_co_trad
.getLanguageAndScript() );
448 CPPUNIT_ASSERT_EQUAL( u
"u-co-trad"_ustr
, es_ES_u_co_trad
.getVariants() );
449 ::std::vector
< OUString
> es_ES_u_co_trad_Fallbacks( es_ES_u_co_trad
.getFallbackStrings( true));
450 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(4), es_ES_u_co_trad_Fallbacks
.size() );
451 CPPUNIT_ASSERT_EQUAL( u
"es-ES-u-co-trad"_ustr
, es_ES_u_co_trad_Fallbacks
[0]);
452 CPPUNIT_ASSERT_EQUAL( u
"es-u-co-trad"_ustr
, es_ES_u_co_trad_Fallbacks
[1]);
453 CPPUNIT_ASSERT_EQUAL( u
"es-ES"_ustr
, es_ES_u_co_trad_Fallbacks
[2]);
454 CPPUNIT_ASSERT_EQUAL( u
"es"_ustr
, es_ES_u_co_trad_Fallbacks
[3]);
456 CPPUNIT_ASSERT_EQUAL( u
"es-ES_tradnl"_ustr
, es_ES_u_co_trad
.getBcp47MS() );
459 // 'es-ES_tradnl' (broken MS) maps to 'es-ES-u-co-trad'
461 OUString
s_es_ES_u_co_trad( u
"es-ES-u-co-trad"_ustr
);
462 OUString
s_es_ES_tradnl( u
"es-ES_tradnl"_ustr
);
463 LanguageTag
es_ES_tradnl( s_es_ES_tradnl
);
464 lang::Locale aLocale
= es_ES_tradnl
.getLocale();
465 CPPUNIT_ASSERT_EQUAL( s_es_ES_u_co_trad
, es_ES_tradnl
.getBcp47() );
466 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
467 CPPUNIT_ASSERT_EQUAL( u
"ES"_ustr
, aLocale
.Country
);
468 CPPUNIT_ASSERT_EQUAL( s_es_ES_u_co_trad
, aLocale
.Variant
);
469 CPPUNIT_ASSERT_EQUAL( LANGUAGE_SPANISH_DATED
, es_ES_tradnl
.getLanguageType() );
470 CPPUNIT_ASSERT( es_ES_tradnl
.isValidBcp47() );
471 CPPUNIT_ASSERT( !es_ES_tradnl
.isIsoLocale() );
472 CPPUNIT_ASSERT( !es_ES_tradnl
.isIsoODF() );
473 CPPUNIT_ASSERT_EQUAL( u
"es"_ustr
, es_ES_tradnl
.getLanguageAndScript() );
474 CPPUNIT_ASSERT_EQUAL( u
"u-co-trad"_ustr
, es_ES_tradnl
.getVariants() );
475 ::std::vector
< OUString
> es_ES_tradnl_Fallbacks( es_ES_tradnl
.getFallbackStrings( true));
476 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(4), es_ES_tradnl_Fallbacks
.size() );
477 CPPUNIT_ASSERT_EQUAL( u
"es-ES-u-co-trad"_ustr
, es_ES_tradnl_Fallbacks
[0]);
478 CPPUNIT_ASSERT_EQUAL( u
"es-u-co-trad"_ustr
, es_ES_tradnl_Fallbacks
[1]);
479 CPPUNIT_ASSERT_EQUAL( u
"es-ES"_ustr
, es_ES_tradnl_Fallbacks
[2]);
480 CPPUNIT_ASSERT_EQUAL( u
"es"_ustr
, es_ES_tradnl_Fallbacks
[3]);
481 // Map back to broken MS.
482 CPPUNIT_ASSERT_EQUAL( s_es_ES_tradnl
, es_ES_tradnl
.getBcp47MS() );
485 // 'zh-Hans-CN' maps to 'zh-CN' and fallbacks
487 LanguageTag
zh_Hans_CN( u
"zh-Hans-CN"_ustr
, true );
488 lang::Locale aLocale
= zh_Hans_CN
.getLocale();
489 CPPUNIT_ASSERT_EQUAL( u
"zh-CN"_ustr
, zh_Hans_CN
.getBcp47() );
490 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, aLocale
.Language
);
491 CPPUNIT_ASSERT_EQUAL( u
"CN"_ustr
, aLocale
.Country
);
492 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
493 CPPUNIT_ASSERT_EQUAL( LANGUAGE_CHINESE_SIMPLIFIED
, zh_Hans_CN
.getLanguageType() );
494 CPPUNIT_ASSERT( zh_Hans_CN
.isValidBcp47() );
495 CPPUNIT_ASSERT( zh_Hans_CN
.isIsoLocale() );
496 CPPUNIT_ASSERT( zh_Hans_CN
.isIsoODF() );
497 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, zh_Hans_CN
.getLanguage() );
498 CPPUNIT_ASSERT_EQUAL( u
"CN"_ustr
, zh_Hans_CN
.getCountry() );
499 CPPUNIT_ASSERT( zh_Hans_CN
.getScript().isEmpty() );
500 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, zh_Hans_CN
.getLanguageAndScript() );
501 ::std::vector
< OUString
> zh_Hans_CN_Fallbacks( zh_Hans_CN
.getFallbackStrings( true));
502 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(2), zh_Hans_CN_Fallbacks
.size());
503 CPPUNIT_ASSERT_EQUAL( u
"zh-CN"_ustr
, zh_Hans_CN_Fallbacks
[0]);
504 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, zh_Hans_CN_Fallbacks
[1]);
505 CPPUNIT_ASSERT_EQUAL( u
"zh-CN"_ustr
, zh_Hans_CN
.makeFallback().getBcp47());
508 // 'zh-Hant-TW' maps to 'zh-TW' and fallbacks
510 LanguageTag
zh_Hant_TW( u
"zh-Hant-TW"_ustr
, true );
511 lang::Locale aLocale
= zh_Hant_TW
.getLocale();
512 CPPUNIT_ASSERT_EQUAL( u
"zh-TW"_ustr
, zh_Hant_TW
.getBcp47() );
513 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, aLocale
.Language
);
514 CPPUNIT_ASSERT_EQUAL( u
"TW"_ustr
, aLocale
.Country
);
515 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
516 CPPUNIT_ASSERT_EQUAL( LANGUAGE_CHINESE_TRADITIONAL
, zh_Hant_TW
.getLanguageType() );
517 CPPUNIT_ASSERT( zh_Hant_TW
.isValidBcp47() );
518 CPPUNIT_ASSERT( zh_Hant_TW
.isIsoLocale() );
519 CPPUNIT_ASSERT( zh_Hant_TW
.isIsoODF() );
520 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, zh_Hant_TW
.getLanguage() );
521 CPPUNIT_ASSERT_EQUAL( u
"TW"_ustr
, zh_Hant_TW
.getCountry() );
522 CPPUNIT_ASSERT( zh_Hant_TW
.getScript().isEmpty() );
523 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, zh_Hant_TW
.getLanguageAndScript() );
524 ::std::vector
< OUString
> zh_Hant_TW_Fallbacks( zh_Hant_TW
.getFallbackStrings( true));
525 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(3), zh_Hant_TW_Fallbacks
.size());
526 CPPUNIT_ASSERT_EQUAL( u
"zh-TW"_ustr
, zh_Hant_TW_Fallbacks
[0]);
527 CPPUNIT_ASSERT_EQUAL( u
"zh-CN"_ustr
, zh_Hant_TW_Fallbacks
[1]);
528 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, zh_Hant_TW_Fallbacks
[2]);
529 CPPUNIT_ASSERT_EQUAL( u
"zh-TW"_ustr
, zh_Hant_TW
.makeFallback().getBcp47());
532 // 'zh-SG' and fallbacks
534 OUString
s_zh_SG( u
"zh-SG"_ustr
);
535 LanguageTag
zh_SG( s_zh_SG
, true );
536 lang::Locale aLocale
= zh_SG
.getLocale();
537 CPPUNIT_ASSERT_EQUAL( s_zh_SG
, zh_SG
.getBcp47() );
538 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, aLocale
.Language
);
539 CPPUNIT_ASSERT_EQUAL( u
"SG"_ustr
, aLocale
.Country
);
540 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
541 CPPUNIT_ASSERT_EQUAL( LANGUAGE_CHINESE_SINGAPORE
, zh_SG
.getLanguageType() );
542 CPPUNIT_ASSERT( zh_SG
.isValidBcp47() );
543 CPPUNIT_ASSERT( zh_SG
.isIsoLocale() );
544 CPPUNIT_ASSERT( zh_SG
.isIsoODF() );
545 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, zh_SG
.getLanguage() );
546 CPPUNIT_ASSERT_EQUAL( u
"SG"_ustr
, zh_SG
.getCountry() );
547 CPPUNIT_ASSERT( zh_SG
.getScript().isEmpty() );
548 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, zh_SG
.getLanguageAndScript() );
549 ::std::vector
< OUString
> zh_SG_Fallbacks( zh_SG
.getFallbackStrings( true));
550 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(3), zh_SG_Fallbacks
.size());
551 CPPUNIT_ASSERT_EQUAL( u
"zh-SG"_ustr
, zh_SG_Fallbacks
[0]);
552 CPPUNIT_ASSERT_EQUAL( u
"zh-CN"_ustr
, zh_SG_Fallbacks
[1]);
553 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, zh_SG_Fallbacks
[2]);
554 CPPUNIT_ASSERT_EQUAL( u
"zh-SG"_ustr
, zh_SG
.makeFallback().getBcp47());
557 // 'zh-HK' and fallbacks
559 OUString
s_zh_HK( u
"zh-HK"_ustr
);
560 LanguageTag
zh_HK( s_zh_HK
, true );
561 lang::Locale aLocale
= zh_HK
.getLocale();
562 CPPUNIT_ASSERT_EQUAL( s_zh_HK
, zh_HK
.getBcp47() );
563 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, aLocale
.Language
);
564 CPPUNIT_ASSERT_EQUAL( u
"HK"_ustr
, aLocale
.Country
);
565 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
566 CPPUNIT_ASSERT_EQUAL( LANGUAGE_CHINESE_HONGKONG
, zh_HK
.getLanguageType() );
567 CPPUNIT_ASSERT( zh_HK
.isValidBcp47() );
568 CPPUNIT_ASSERT( zh_HK
.isIsoLocale() );
569 CPPUNIT_ASSERT( zh_HK
.isIsoODF() );
570 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, zh_HK
.getLanguage() );
571 CPPUNIT_ASSERT_EQUAL( u
"HK"_ustr
, zh_HK
.getCountry() );
572 CPPUNIT_ASSERT( zh_HK
.getScript().isEmpty() );
573 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, zh_HK
.getLanguageAndScript() );
574 ::std::vector
< OUString
> zh_HK_Fallbacks( zh_HK
.getFallbackStrings( true));
575 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(3), zh_HK_Fallbacks
.size());
576 CPPUNIT_ASSERT_EQUAL( u
"zh-HK"_ustr
, zh_HK_Fallbacks
[0]);
577 CPPUNIT_ASSERT_EQUAL( u
"zh-TW"_ustr
, zh_HK_Fallbacks
[1]);
578 CPPUNIT_ASSERT_EQUAL( u
"zh"_ustr
, zh_HK_Fallbacks
[2]);
579 CPPUNIT_ASSERT_EQUAL( u
"zh-HK"_ustr
, zh_HK
.makeFallback().getBcp47());
582 // 'zh-yue-HK' uses redundant 'zh-yue' and should be preferred 'yue-HK'
584 /* XXX Disabled because liblangtag in lt_tag_canonicalize() after replacing
585 * 'zh-yue' with the preferred 'yue' does:
586 * "If the language tag starts with a primary language subtag that is also
587 * an extlang subtag, then the language tag is prepended with the extlang's
589 * Primary language 'yue' is also extlang 'yue' for which the prefix
590 * happens to be 'zh' ... so the result is 'zh-yue-HK' again. */
592 OUString
s_zh_yue_HK( "zh-yue-HK" );
593 LanguageTag
zh_yue_HK( s_zh_yue_HK
);
594 lang::Locale aLocale
= zh_yue_HK
.getLocale();
595 CPPUNIT_ASSERT( zh_yue_HK
.getBcp47() == "yue-HK" );
596 CPPUNIT_ASSERT( aLocale
.Language
== "yue" );
597 CPPUNIT_ASSERT( aLocale
.Country
== "HK" );
598 CPPUNIT_ASSERT( aLocale
.Variant
== "" );
599 CPPUNIT_ASSERT( zh_yue_HK
.getLanguageType() == LANGUAGE_YUE_CHINESE_HONGKONG
);
600 CPPUNIT_ASSERT( zh_yue_HK
.isValidBcp47() == true );
601 CPPUNIT_ASSERT( zh_yue_HK
.isIsoLocale() == true );
602 CPPUNIT_ASSERT( zh_yue_HK
.isIsoODF() == true );
603 CPPUNIT_ASSERT( zh_yue_HK
.getLanguageAndScript() == "yue" );
604 CPPUNIT_ASSERT( zh_yue_HK
.getVariants() == "" );
605 ::std::vector
< OUString
> zh_yue_HK_Fallbacks( zh_yue_HK
.getFallbackStrings( true));
606 CPPUNIT_ASSERT( zh_yue_HK_Fallbacks
.size() == 2);
607 CPPUNIT_ASSERT( zh_yue_HK_Fallbacks
[0] == "yue-HK");
608 CPPUNIT_ASSERT( zh_yue_HK_Fallbacks
[1] == "yue");
612 // 'es-419' fallbacks
614 OUString
s_es_419( u
"es-419"_ustr
);
615 LanguageTag
es_419( s_es_419
);
616 lang::Locale aLocale
= es_419
.getLocale();
617 CPPUNIT_ASSERT_EQUAL( s_es_419
, es_419
.getBcp47() );
618 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
619 CPPUNIT_ASSERT( aLocale
.Country
.isEmpty() );
620 CPPUNIT_ASSERT_EQUAL( u
"es-419"_ustr
, aLocale
.Variant
);
621 CPPUNIT_ASSERT_EQUAL( LANGUAGE_SPANISH_LATIN_AMERICA
, es_419
.getLanguageType() );
622 ::std::vector
< OUString
> es_419_Fallbacks( es_419
.getFallbackStrings( true));
623 CPPUNIT_ASSERT_EQUAL( static_cast<size_t>(2), es_419_Fallbacks
.size());
624 CPPUNIT_ASSERT_EQUAL( u
"es-419"_ustr
, es_419_Fallbacks
[0]);
625 CPPUNIT_ASSERT_EQUAL( u
"es"_ustr
, es_419_Fallbacks
[1]);
628 // 'qtz' is a local use known pseudolocale for key ID resource
630 OUString
s_qtz( u
"qtz"_ustr
);
631 LanguageTag
qtz( s_qtz
);
632 lang::Locale aLocale
= qtz
.getLocale();
633 CPPUNIT_ASSERT_EQUAL( s_qtz
, qtz
.getBcp47() );
634 CPPUNIT_ASSERT_EQUAL( u
"qtz"_ustr
, aLocale
.Language
);
635 CPPUNIT_ASSERT( aLocale
.Country
.isEmpty() );
636 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
637 CPPUNIT_ASSERT_EQUAL( LANGUAGE_USER_KEYID
, qtz
.getLanguageType() );
640 // 'qty' is a local use unknown locale
642 OUString
s_qty( u
"qty"_ustr
);
643 LanguageTag
qty( s_qty
);
644 lang::Locale aLocale
= qty
.getLocale();
645 CPPUNIT_ASSERT_EQUAL( s_qty
, qty
.getBcp47() );
646 CPPUNIT_ASSERT_EQUAL( u
"qty"_ustr
, aLocale
.Language
);
647 CPPUNIT_ASSERT( aLocale
.Country
.isEmpty() );
648 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
649 CPPUNIT_ASSERT( LanguageTag::isOnTheFlyID( qty
.getLanguageType()) );
652 // 'qtx' is an unknown new mslangid
654 LanguageTag
qtx( u
"qtx"_ustr
);
655 qtx
.setScriptType( LanguageTag::ScriptType::RTL
);
656 LanguageType n_qtx
= qtx
.getLanguageType();
657 CPPUNIT_ASSERT_EQUAL( css::i18n::ScriptType::COMPLEX
, MsLangId::getScriptType(n_qtx
) );
658 CPPUNIT_ASSERT( MsLangId::isRightToLeft(n_qtx
) );
659 CPPUNIT_ASSERT( !MsLangId::isCJK(n_qtx
) );
662 // 'x-comment' is a privateuse known "locale"
664 OUString
s_xcomment( u
"x-comment"_ustr
);
665 LanguageTag
xcomment( s_xcomment
);
666 lang::Locale aLocale
= xcomment
.getLocale();
667 CPPUNIT_ASSERT_EQUAL( s_xcomment
, xcomment
.getBcp47() );
668 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
669 CPPUNIT_ASSERT( aLocale
.Country
.isEmpty() );
670 CPPUNIT_ASSERT_EQUAL( u
"x-comment"_ustr
, aLocale
.Variant
);
671 CPPUNIT_ASSERT_EQUAL( LANGUAGE_USER_PRIV_COMMENT
, xcomment
.getLanguageType() );
674 // 'x-foobar' is a privateuse unknown "locale"
676 OUString
s_xfoobar( u
"x-foobar"_ustr
);
677 LanguageTag
xfoobar( s_xfoobar
);
678 lang::Locale aLocale
= xfoobar
.getLocale();
679 CPPUNIT_ASSERT_EQUAL( s_xfoobar
, xfoobar
.getBcp47() );
680 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
681 CPPUNIT_ASSERT( aLocale
.Country
.isEmpty() );
682 CPPUNIT_ASSERT_EQUAL( u
"x-foobar"_ustr
, aLocale
.Variant
);
683 CPPUNIT_ASSERT( LanguageTag::isOnTheFlyID( xfoobar
.getLanguageType()) );
686 // '*' the dreaded jolly joker is a "privateuse" known "locale"
688 OUString
s_joker( u
"*"_ustr
);
689 LanguageTag
joker( s_joker
);
690 lang::Locale aLocale
= joker
.getLocale();
691 CPPUNIT_ASSERT_EQUAL( s_joker
, joker
.getBcp47() );
692 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
693 CPPUNIT_ASSERT( aLocale
.Country
.isEmpty() );
694 CPPUNIT_ASSERT_EQUAL( u
"*"_ustr
, aLocale
.Variant
);
695 CPPUNIT_ASSERT_EQUAL( LANGUAGE_USER_PRIV_JOKER
, joker
.getLanguageType() );
697 joker
.reset( LANGUAGE_USER_PRIV_JOKER
);
698 aLocale
= joker
.getLocale();
699 CPPUNIT_ASSERT_EQUAL( s_joker
, joker
.getBcp47() );
700 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
701 CPPUNIT_ASSERT( aLocale
.Country
.isEmpty() );
702 CPPUNIT_ASSERT_EQUAL( u
"*"_ustr
, aLocale
.Variant
);
703 CPPUNIT_ASSERT_EQUAL( LANGUAGE_USER_PRIV_JOKER
, joker
.getLanguageType() );
706 // 'C' locale shall map to 'en-US'
708 LanguageTag
aTag( u
"C"_ustr
);
709 CPPUNIT_ASSERT_EQUAL( u
"en"_ustr
, aTag
.getLanguage() );
710 CPPUNIT_ASSERT_EQUAL( u
"US"_ustr
, aTag
.getCountry() );
711 lang::Locale aLocale
= aTag
.getLocale();
712 CPPUNIT_ASSERT_EQUAL( u
"en-US"_ustr
, aTag
.getBcp47() );
713 CPPUNIT_ASSERT_EQUAL( u
"en"_ustr
, aLocale
.Language
);
714 CPPUNIT_ASSERT_EQUAL( u
"US"_ustr
, aLocale
.Country
);
715 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
716 CPPUNIT_ASSERT_EQUAL( LANGUAGE_ENGLISH_US
, aTag
.getLanguageType() );
719 LanguageTag
aTag( lang::Locale(u
"C"_ustr
,u
""_ustr
,u
""_ustr
) );
720 CPPUNIT_ASSERT_EQUAL( u
"en"_ustr
, aTag
.getLanguage() );
721 CPPUNIT_ASSERT_EQUAL( u
"US"_ustr
, aTag
.getCountry() );
722 lang::Locale aLocale
= aTag
.getLocale();
723 CPPUNIT_ASSERT_EQUAL( u
"en-US"_ustr
, aTag
.getBcp47() );
724 CPPUNIT_ASSERT_EQUAL( u
"en"_ustr
, aLocale
.Language
);
725 CPPUNIT_ASSERT_EQUAL( u
"US"_ustr
, aLocale
.Country
);
726 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
727 CPPUNIT_ASSERT_EQUAL( LANGUAGE_ENGLISH_US
, aTag
.getLanguageType() );
730 // test reset() methods
732 LanguageTag
aTag( LANGUAGE_DONTKNOW
);
733 lang::Locale aLocale
;
735 aTag
.reset( LANGUAGE_GERMAN
);
736 aLocale
= aTag
.getLocale();
737 CPPUNIT_ASSERT_EQUAL( u
"de-DE"_ustr
, aTag
.getBcp47() );
738 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, aLocale
.Language
);
739 CPPUNIT_ASSERT_EQUAL( u
"DE"_ustr
, aLocale
.Country
);
740 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
741 CPPUNIT_ASSERT_EQUAL( LANGUAGE_GERMAN
, aTag
.getLanguageType() );
743 aTag
.reset( u
"en-US"_ustr
);
744 aLocale
= aTag
.getLocale();
745 CPPUNIT_ASSERT_EQUAL( u
"en-US"_ustr
, aTag
.getBcp47() );
746 CPPUNIT_ASSERT_EQUAL( u
"en"_ustr
, aLocale
.Language
);
747 CPPUNIT_ASSERT_EQUAL( u
"US"_ustr
, aLocale
.Country
);
748 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
749 CPPUNIT_ASSERT_EQUAL( LANGUAGE_ENGLISH_US
, aTag
.getLanguageType() );
751 aTag
.reset( lang::Locale( u
"de"_ustr
, u
"DE"_ustr
, u
""_ustr
) );
752 aLocale
= aTag
.getLocale();
753 CPPUNIT_ASSERT_EQUAL( u
"de-DE"_ustr
, aTag
.getBcp47() );
754 CPPUNIT_ASSERT_EQUAL( u
"de"_ustr
, aLocale
.Language
);
755 CPPUNIT_ASSERT_EQUAL( u
"DE"_ustr
, aLocale
.Country
);
756 CPPUNIT_ASSERT( aLocale
.Variant
.isEmpty() );
757 CPPUNIT_ASSERT_EQUAL( LANGUAGE_GERMAN
, aTag
.getLanguageType() );
761 OUString
s_uab( u
"unreg-and-bad"_ustr
);
762 LanguageTag
uab( s_uab
, true );
763 lang::Locale aLocale
= uab
.getLocale();
764 CPPUNIT_ASSERT_EQUAL( s_uab
, uab
.getBcp47() );
765 CPPUNIT_ASSERT_EQUAL( u
"qlt"_ustr
, aLocale
.Language
);
766 CPPUNIT_ASSERT( aLocale
.Country
.isEmpty() );
767 CPPUNIT_ASSERT_EQUAL( s_uab
, aLocale
.Variant
);
768 CPPUNIT_ASSERT_EQUAL( LANGUAGE_DONTKNOW
, uab
.getLanguageType() );
769 CPPUNIT_ASSERT( !uab
.isValidBcp47() );
770 CPPUNIT_ASSERT( !uab
.isIsoLocale() );
771 CPPUNIT_ASSERT( !uab
.isIsoODF() );
774 // test static isValidBcp47() method
776 OUString aCanonicalized
;
777 CPPUNIT_ASSERT( LanguageTag::isValidBcp47( u
"en-US"_ustr
, &aCanonicalized
) );
778 CPPUNIT_ASSERT_EQUAL( u
"en-US"_ustr
, aCanonicalized
);
779 CPPUNIT_ASSERT( LanguageTag::isValidBcp47( u
"x-foobar"_ustr
, &aCanonicalized
) );
780 CPPUNIT_ASSERT_EQUAL( u
"x-foobar"_ustr
, aCanonicalized
);
781 CPPUNIT_ASSERT( LanguageTag::isValidBcp47( u
"qaa"_ustr
, &aCanonicalized
) );
782 CPPUNIT_ASSERT_EQUAL( u
"qaa"_ustr
, aCanonicalized
);
783 CPPUNIT_ASSERT( !LanguageTag::isValidBcp47( u
"unreg-and-bad"_ustr
, &aCanonicalized
) );
784 CPPUNIT_ASSERT( LanguageTag::isValidBcp47( u
"en-US"_ustr
, &aCanonicalized
, LanguageTag::PrivateUse::DISALLOW
) );
785 CPPUNIT_ASSERT_EQUAL( u
"en-US"_ustr
, aCanonicalized
);
786 CPPUNIT_ASSERT( !LanguageTag::isValidBcp47( u
"x-foobar"_ustr
, &aCanonicalized
, LanguageTag::PrivateUse::DISALLOW
) );
787 CPPUNIT_ASSERT_EQUAL( u
"x-foobar"_ustr
, aCanonicalized
);
788 CPPUNIT_ASSERT( LanguageTag::isValidBcp47( u
"qaa"_ustr
, &aCanonicalized
, LanguageTag::PrivateUse::DISALLOW
) );
789 CPPUNIT_ASSERT_EQUAL( u
"qaa"_ustr
, aCanonicalized
);
790 CPPUNIT_ASSERT( LanguageTag::isValidBcp47( u
"de-Latn-DE"_ustr
, &aCanonicalized
) );
791 CPPUNIT_ASSERT_EQUAL( u
"de-DE"_ustr
, aCanonicalized
);
792 /* TODO: at least some (those we know) grandfathered tags should be
793 * recognized by the replacement code. */
794 CPPUNIT_ASSERT( LanguageTag::isValidBcp47( u
"en-GB-oed"_ustr
, &aCanonicalized
) );
795 // en-GB-oed has become deprecated in updated language-subtag-registry database
796 // (liblangtag 0.5.7)
797 CPPUNIT_ASSERT( ( aCanonicalized
== "en-GB-oxendict" ) || ( aCanonicalized
== "en-GB-oed" ) );
801 bool checkMapping( std::u16string_view rStr1
, std::u16string_view rStr2
)
803 if (rStr1
== u
"la" ) return rStr2
== u
"la-VA";
804 if (rStr1
== u
"la-Latn" ) return rStr2
== u
"la-VA";
805 if (rStr1
== u
"tzm-Latn-DZ" ) return rStr2
== u
"kab-DZ";
806 if (rStr1
== u
"bs-Latn-BA" ) return rStr2
== u
"bs-BA";
807 if (rStr1
== u
"bs-Latn" ) return rStr2
== u
"bs";
808 if (rStr1
== u
"cz" ) return rStr2
== u
"cs-CZ";
809 if (rStr1
== u
"iw-IL" ) return rStr2
== u
"he-IL";
810 if (rStr1
== u
"in-ID" ) return rStr2
== u
"id-ID";
811 if (rStr1
== u
"sr-YU" ) return rStr2
== u
"sr-CS";
812 if (rStr1
== u
"sh-RS" ) return rStr2
== u
"sr-Latn-RS";
813 if (rStr1
== u
"sh-YU" ) return rStr2
== u
"sr-Latn-CS";
814 if (rStr1
== u
"sh-CS" ) return rStr2
== u
"sr-Latn-CS";
815 if (rStr1
== u
"sh-ME" ) return rStr2
== u
"sr-Latn-ME";
816 if (rStr1
== u
"sh-BA" ) return rStr2
== u
"sr-Latn-BA";
817 if (rStr1
== u
"sh" ) return rStr2
== u
"sr-Latn";
818 if (rStr1
== u
"lah-PK" ) return rStr2
== u
"pnb-Arab-PK";
819 if (rStr1
== u
"pa-PK" ) return rStr2
== u
"pnb-Arab-PK";
820 if (rStr1
== u
"ca-XV" ) return rStr2
== u
"ca-ES-valencia";
821 if (rStr1
== u
"qcv-ES" ) return rStr2
== u
"ca-ES-valencia";
822 if (rStr1
== u
"ns-ZA" ) return rStr2
== u
"nso-ZA";
823 if (rStr1
== u
"ven-ZA" ) return rStr2
== u
"ve-ZA";
824 if (rStr1
== u
"qu-EC" ) return rStr2
== u
"quz-EC";
825 if (rStr1
== u
"qu-PE" ) return rStr2
== u
"quz-PE";
826 if (rStr1
== u
"ff-Latn-NG" ) return rStr2
== u
"ff-NG";
827 if (rStr1
== u
"fuv-NG" ) return rStr2
== u
"ff-NG";
828 if (rStr1
== u
"ji-IL" ) return rStr2
== u
"yi-IL";
829 if (rStr1
== u
"iu-CA" ) return rStr2
== u
"iu-Latn-CA";
830 if (rStr1
== u
"iu" ) return rStr2
== u
"iu-Latn";
831 if (rStr1
== u
"gbz-AF" ) return rStr2
== u
"prs-AF";
832 if (rStr1
== u
"ber-DZ" ) return rStr2
== u
"kab-DZ";
833 if (rStr1
== u
"tmz-MA" ) return rStr2
== u
"tzm-Tfng-MA";
834 if (rStr1
== u
"ber-MA" ) return rStr2
== u
"tzm-Tfng-MA";
835 if (rStr1
== u
"mg-MG" ) return rStr2
== u
"plt-MG";
836 if (rStr1
== u
"pli" ) return rStr2
== u
"pi-Latn";
837 if (rStr1
== u
"ks" ) return rStr2
== u
"ks-Arab";
838 if (rStr1
== u
"ks-IN" ) return rStr2
== u
"ks-Deva-IN";
839 if (rStr1
== u
"chr-US" ) return rStr2
== u
"chr-Cher-US";
840 if (rStr1
== u
"sd-PK" ) return rStr2
== u
"sd-Arab-PK";
841 if (rStr1
== u
"sr-Cyrl-RS" ) return rStr2
== u
"sr-RS";
842 if (rStr1
== u
"sr-Cyrl-ME" ) return rStr2
== u
"sr-ME";
843 if (rStr1
== u
"sr-Cyrl-BA" ) return rStr2
== u
"sr-BA";
844 if (rStr1
== u
"sr-Cyrl-CS" ) return rStr2
== u
"sr-CS";
845 if (rStr1
== u
"sr-Cyrl" ) return rStr2
== u
"sr";
846 if (rStr1
== u
"yi-Hebr-US" ) return rStr2
== u
"yi-US";
847 if (rStr1
== u
"yi-Hebr-IL" ) return rStr2
== u
"yi-IL";
848 if (rStr1
== u
"ha-NG" ) return rStr2
== u
"ha-Latn-NG";
849 if (rStr1
== u
"ha-GH" ) return rStr2
== u
"ha-Latn-GH";
850 if (rStr1
== u
"ku-Arab-IQ" ) return rStr2
== u
"ckb-IQ";
851 if (rStr1
== u
"ku-Arab" ) return rStr2
== u
"ckb";
852 if (rStr1
== u
"kmr-TR" ) return rStr2
== u
"kmr-Latn-TR";
853 if (rStr1
== u
"ku-TR" ) return rStr2
== u
"kmr-Latn-TR";
854 if (rStr1
== u
"kmr-SY" ) return rStr2
== u
"kmr-Latn-SY";
855 if (rStr1
== u
"ku-SY" ) return rStr2
== u
"kmr-Latn-SY";
856 if (rStr1
== u
"ku-IQ" ) return rStr2
== u
"ckb-IQ";
857 if (rStr1
== u
"ku-IR" ) return rStr2
== u
"ckb-IR";
858 if (rStr1
== u
"eu" ) return rStr2
== u
"eu-ES";
859 if (rStr1
== u
"crk-Latn-CN" ) return rStr2
== u
"crk-Latn-CA";
860 if (rStr1
== u
"crk-Cans-CN" ) return rStr2
== u
"crk-Cans-CA";
861 if (rStr1
== u
"en-GB-oed" ) return rStr2
== u
"en-GB-oxendict";
862 if (rStr1
== u
"es-ES_tradnl") return rStr2
== u
"es-ES-u-co-trad";
863 if (rStr1
== u
"sd-IN" ) return rStr2
== u
"sd-Deva-IN";
864 if (rStr1
== u
"cmn-CN" ) return rStr2
== u
"zh-CN";
865 if (rStr1
== u
"cmn-TW" ) return rStr2
== u
"zh-TW";
866 if (rStr1
== u
"kw-UK" ) return rStr2
== u
"kw-GB";
867 if (rStr1
== u
"oc-FR" ) return rStr2
== u
"oc-FR-lengadoc";
868 if (rStr1
== u
"oc-ES" ) return rStr2
== u
"oc-ES-aranes";
869 if (rStr1
== u
"zh-Hans-CN" ) return rStr2
== u
"zh-CN";
870 if (rStr1
== u
"zh-Hant-TW" ) return rStr2
== u
"zh-TW";
871 if (rStr1
== u
"zh-Hans-SG" ) return rStr2
== u
"zh-SG";
872 if (rStr1
== u
"zh-Hant-HK" ) return rStr2
== u
"zh-HK";
873 if (rStr1
== u
"zh-Hant-MO" ) return rStr2
== u
"zh-MO";
874 return rStr1
== rStr2
;
877 void TestLanguageTag::testAllIsoLangEntries()
879 const ::std::vector
< MsLangId::LanguagetagMapping
> aList( MsLangId::getDefinedLanguagetags());
880 for (auto const& elem
: aList
)
883 if (elem
.maBcp47
== "la-VA")
887 LanguageTag
aTagString( elem
.maBcp47
, true);
888 LanguageTag
aTagID( elem
.mnLang
);
889 if (!checkMapping( elem
.maBcp47
, aTagString
.getBcp47()))
891 CPPUNIT_ASSERT_EQUAL_MESSAGE( "defined elem to tag", elem
.maBcp47
, aTagString
.getBcp47() );
893 if (elem
.maBcp47
!= aTagID
.getBcp47())
895 // There are multiple mappings, ID must be equal after conversions.
896 LanguageTag
aTagBack( aTagID
.getBcp47(), true);
897 if (aTagString
.getLanguageType() != aTagBack
.getLanguageType())
899 OString
aMessage( OUStringToOString( elem
.maBcp47
, RTL_TEXTENCODING_ASCII_US
));
900 aMessage
+= " " + OUStringToOString( aTagString
.getBcp47(), RTL_TEXTENCODING_ASCII_US
) + ": " +
901 OUStringToOString( aTagString
.getBcp47(), RTL_TEXTENCODING_ASCII_US
) + " " +
902 OString::number( static_cast<sal_uInt16
>(aTagString
.getLanguageType()), 16) +
903 " -> " + OUStringToOString( aTagBack
.getBcp47(), RTL_TEXTENCODING_ASCII_US
) + " " +
904 OString::number( static_cast<sal_uInt16
>(aTagBack
.getLanguageType()), 16);
905 CPPUNIT_ASSERT_EQUAL_MESSAGE( aMessage
.getStr(), aTagBack
.getLanguageType(), aTagString
.getLanguageType());
909 // This does not hold, there are cases like 'ar'
910 // LANGUAGE_ARABIC_PRIMARY_ONLY that when mapped back results in
911 // 'ar-SA' as default locale.
912 if (elem
.mnLang
!= aTagString
.getLanguageType())
914 // There are multiple mappings, string must be equal after conversions.
915 LanguageTag
aTagBack( aTagString
.getLanguageType());
916 if (aTagID
.getBcp47() != aTagBack
.getBcp47())
918 OString
aMessage( OUStringToOString( elem
.maBcp47
, RTL_TEXTENCODING_ASCII_US
));
919 aMessage
+= " " + OUStringToOString( aTagID
.getBcp47(), RTL_TEXTENCODING_ASCII_US
) +
920 " -> " + OUStringToOString( aTagBack
.getBcp47(), RTL_TEXTENCODING_ASCII_US
);
921 CPPUNIT_ASSERT_MESSAGE( aMessage
.getStr(), aTagID
.getBcp47() == aTagBack
.getBcp47());
927 // Uncommenting this makes the test break and output SAL_WARN/INFO
928 //CPPUNIT_ASSERT( true == false );
931 void TestLanguageTag::testDisplayNames()
934 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"en-US"_ustr
), LanguageTag(u
"en-US"_ustr
));
935 CPPUNIT_ASSERT_EQUAL( u
"English (United States)"_ustr
, aStr
);
936 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"en-US"_ustr
), LanguageTag(u
"en"_ustr
));
937 CPPUNIT_ASSERT_EQUAL( u
"English (United States)"_ustr
, aStr
);
938 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"en"_ustr
), LanguageTag(u
"en"_ustr
));
939 CPPUNIT_ASSERT_EQUAL( u
"English"_ustr
, aStr
);
941 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"en-US"_ustr
), LanguageTag(u
"de-DE"_ustr
));
942 CPPUNIT_ASSERT_EQUAL( u
"Englisch (Vereinigte Staaten)"_ustr
, aStr
);
943 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"en-US"_ustr
), LanguageTag(u
"de"_ustr
));
944 CPPUNIT_ASSERT_EQUAL( u
"Englisch (Vereinigte Staaten)"_ustr
, aStr
);
945 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"en"_ustr
), LanguageTag(u
"de"_ustr
));
946 CPPUNIT_ASSERT_EQUAL( u
"Englisch"_ustr
, aStr
);
948 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"de-DE"_ustr
), LanguageTag(u
"en"_ustr
));
949 CPPUNIT_ASSERT_EQUAL( u
"German (Germany)"_ustr
, aStr
);
950 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"de"_ustr
), LanguageTag(u
"en"_ustr
));
951 CPPUNIT_ASSERT_EQUAL( u
"German"_ustr
, aStr
);
952 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"de-DE-1901"_ustr
), LanguageTag(u
"en"_ustr
));
953 CPPUNIT_ASSERT_EQUAL( u
"German (Germany, Traditional German orthography)"_ustr
, aStr
);
954 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"de-DE-1901"_ustr
), LanguageTag(u
"de-DE"_ustr
));
955 CPPUNIT_ASSERT_EQUAL( u
"Deutsch (Deutschland, Alte deutsche Rechtschreibung)"_ustr
, aStr
);
957 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"en-GB"_ustr
), LanguageTag(u
"en"_ustr
));
958 CPPUNIT_ASSERT_EQUAL( u
"English (United Kingdom)"_ustr
, aStr
);
959 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"en-GB-oxendict"_ustr
), LanguageTag(u
"en"_ustr
));
960 CPPUNIT_ASSERT_EQUAL( u
"English (United Kingdom, Oxford English Dictionary spelling)"_ustr
, aStr
);
962 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"ca-ES-valencia"_ustr
), LanguageTag(u
"en"_ustr
));
963 CPPUNIT_ASSERT_EQUAL( u
"Catalan (Spain, Valencian)"_ustr
, aStr
);
965 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"sr-Cyrl-RS"_ustr
), LanguageTag(u
"en"_ustr
));
966 CPPUNIT_ASSERT_EQUAL( u
"Serbian (Serbia)"_ustr
, aStr
);
967 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"sr-Latn-RS"_ustr
), LanguageTag(u
"en"_ustr
));
968 CPPUNIT_ASSERT_EQUAL( u
"Serbian (Latin, Serbia)"_ustr
, aStr
);
970 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"tlh"_ustr
), LanguageTag(u
"en"_ustr
));
971 CPPUNIT_ASSERT_EQUAL( u
"Klingon"_ustr
, aStr
);
973 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"und"_ustr
), LanguageTag(u
"en"_ustr
));
974 CPPUNIT_ASSERT_EQUAL( u
"Unknown language"_ustr
, aStr
);
976 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"zxx"_ustr
), LanguageTag(u
"en"_ustr
));
977 CPPUNIT_ASSERT_EQUAL( u
"No linguistic content"_ustr
, aStr
);
979 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"x-lala"_ustr
), LanguageTag(u
"en"_ustr
));
980 CPPUNIT_ASSERT_EQUAL( u
"Unknown language (Private-Use=lala)"_ustr
, aStr
);
981 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"x-lala"_ustr
), LanguageTag(u
"de"_ustr
));
982 CPPUNIT_ASSERT_EQUAL( u
"Unbekannte Sprache (Privatnutzung=lala)"_ustr
, aStr
);
983 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"en-GB"_ustr
), LanguageTag(u
"x-lala"_ustr
));
984 CPPUNIT_ASSERT_EQUAL( u
"en (GB)"_ustr
, aStr
);
985 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"en-GB-oxendict"_ustr
), LanguageTag(u
"x-lala"_ustr
));
986 CPPUNIT_ASSERT_EQUAL( u
"en (GB, OXENDICT)"_ustr
, aStr
);
988 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"unreg-and-bad"_ustr
), LanguageTag(u
"en"_ustr
));
989 CPPUNIT_ASSERT_EQUAL( u
"unreg (Andorra, BAD)"_ustr
, aStr
); // a tad of a surprise..
991 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"en-029"_ustr
), LanguageTag(u
"en"_ustr
));
992 CPPUNIT_ASSERT_EQUAL( u
"English (Caribbean)"_ustr
, aStr
);
993 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"fr-015"_ustr
), LanguageTag(u
"en"_ustr
));
994 CPPUNIT_ASSERT_EQUAL( u
"French (Northern Africa)"_ustr
, aStr
);
996 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"qtz"_ustr
), LanguageTag(u
"en"_ustr
));
997 CPPUNIT_ASSERT_EQUAL( u
"qtz"_ustr
, aStr
);
999 aStr
= LanguageTagIcu::getDisplayName( LanguageTag(u
"*"_ustr
), LanguageTag(u
"en"_ustr
));
1000 CPPUNIT_ASSERT_EQUAL( u
"*"_ustr
, aStr
);
1003 void TestLanguageTag::testLanguagesWithoutHyphenation()
1006 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_PRIMARY_ONLY
));
1007 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_ALGERIA
));
1008 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_BAHRAIN
));
1009 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_EGYPT
));
1010 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_IRAQ
));
1011 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_JORDAN
));
1012 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_KUWAIT
));
1013 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_LEBANON
));
1014 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_LIBYA
));
1015 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_MOROCCO
));
1016 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_OMAN
));
1017 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_QATAR
));
1018 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_SAUDI_ARABIA
));
1019 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_SYRIA
));
1020 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_TUNISIA
));
1021 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_UAE
));
1022 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_ARABIC_YEMEN
));
1025 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_PASHTO
));
1028 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_FARSI
));
1031 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_KASHMIRI
));
1032 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_KASHMIRI_INDIA
));
1034 // Central Kurdish (Sorani), uses Arabic script, does not have hyphenation
1035 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_KURDISH_ARABIC_IRAQ
));
1036 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_KURDISH_ARABIC_LSO
));
1038 // Northern Kurdish (Kurmanji) -> uses Latin script, has hyphenation
1039 CPPUNIT_ASSERT(MsLangId::usesHyphenation(LANGUAGE_USER_KURDISH_SYRIA
));
1040 CPPUNIT_ASSERT(MsLangId::usesHyphenation(LANGUAGE_USER_KURDISH_TURKEY
));
1042 // Southern Kurdish -> uses Arabic script, does not have hyphenation
1043 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_USER_KURDISH_SOUTHERN_IRAN
));
1044 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_USER_KURDISH_SOUTHERN_IRAQ
));
1047 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_PUNJABI
));
1048 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_PUNJABI_ARABIC_LSO
));
1049 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_PUNJABI_PAKISTAN
));
1052 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_SINDHI
));
1053 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_SINDHI_ARABIC_LSO
));
1054 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_SINDHI_PAKISTAN
));
1057 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_MALAY_BRUNEI_DARUSSALAM
));
1058 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_MALAY_MALAYSIA
));
1059 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_USER_MALAY_ARABIC_BRUNEI
));
1060 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_USER_MALAY_ARABIC_MALAYSIA
));
1063 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_SOMALI
));
1066 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_SWAHILI
));
1067 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_USER_SWAHILI_TANZANIA
));
1070 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_URDU_INDIA
));
1071 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_URDU_PAKISTAN
));
1075 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_CHINESE
));
1076 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_CHINESE_HONGKONG
));
1077 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_CHINESE_LSO
));
1078 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_CHINESE_MACAU
));
1079 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_CHINESE_SIMPLIFIED
));
1080 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_CHINESE_SIMPLIFIED_LEGACY
));
1081 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_CHINESE_SINGAPORE
));
1082 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_CHINESE_TRADITIONAL
));
1083 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_CHINESE_TRADITIONAL_LSO
));
1084 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_YUE_CHINESE_HONGKONG
));
1086 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_JAPANESE
));
1088 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_KOREAN
));
1089 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_KOREAN_JOHAB
));
1090 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_USER_KOREAN_NORTH
));
1093 CPPUNIT_ASSERT(!MsLangId::usesHyphenation(LANGUAGE_VIETNAMESE
));
1096 CPPUNIT_TEST_SUITE_REGISTRATION( TestLanguageTag
);
1100 CPPUNIT_PLUGIN_IMPLEMENT();
1102 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */