Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : */
9 :
10 : #include <sal/config.h>
11 :
12 : #include <cppunit/TestFixture.h>
13 : #include <cppunit/TestAssert.h>
14 : #include <cppunit/extensions/HelperMacros.h>
15 : #include <cppunit/plugin/TestPlugIn.h>
16 :
17 : #include <i18nlangtag/mslangid.hxx>
18 : #include <i18nlangtag/languagetag.hxx>
19 :
20 : #include <rtl/ustring.hxx>
21 : #include <rtl/ustrbuf.hxx>
22 : #include <osl/file.hxx>
23 :
24 : #include <com/sun/star/lang/Locale.hpp>
25 :
26 : using namespace com::sun::star;
27 :
28 : // To test the replacement code add '&& 0' and also in
29 : // source/languagetag/languagetag.cxx
30 : #if defined(ENABLE_LIBLANGTAG)
31 : #define USE_LIBLANGTAG 1
32 : #else
33 : #define USE_LIBLANGTAG 0
34 : #endif
35 :
36 : namespace {
37 :
38 : class TestLanguageTag : public CppUnit::TestFixture
39 : {
40 : public:
41 2 : TestLanguageTag() {}
42 4 : virtual ~TestLanguageTag() {}
43 :
44 : void testAllTags();
45 : void testAllIsoLangEntries();
46 :
47 2 : CPPUNIT_TEST_SUITE(TestLanguageTag);
48 1 : CPPUNIT_TEST(testAllTags);
49 1 : CPPUNIT_TEST(testAllIsoLangEntries);
50 2 : CPPUNIT_TEST_SUITE_END();
51 : };
52 :
53 1 : void TestLanguageTag::testAllTags()
54 : {
55 : {
56 1 : OUString s_de_Latn_DE( "de-Latn-DE" );
57 2 : LanguageTag de_DE( s_de_Latn_DE, true );
58 2 : OUString aBcp47 = de_DE.getBcp47();
59 2 : lang::Locale aLocale = de_DE.getLocale();
60 1 : LanguageType nLanguageType = de_DE.getLanguageType();
61 : #if USE_LIBLANGTAG
62 1 : CPPUNIT_ASSERT_MESSAGE("Default script should be stripped after canonicalize.", aBcp47 == "de-DE" );
63 1 : CPPUNIT_ASSERT( aLocale.Language == "de" );
64 1 : CPPUNIT_ASSERT( aLocale.Country == "DE" );
65 1 : CPPUNIT_ASSERT( aLocale.Variant == "" );
66 1 : CPPUNIT_ASSERT( nLanguageType == LANGUAGE_GERMAN );
67 1 : CPPUNIT_ASSERT( de_DE.getLanguage() == "de" );
68 1 : CPPUNIT_ASSERT( de_DE.getCountry() == "DE" );
69 1 : CPPUNIT_ASSERT( de_DE.getScript() == "" );
70 2 : CPPUNIT_ASSERT( de_DE.getLanguageAndScript() == "de" );
71 : #else
72 : // The simple replacement code doesn't do any fancy stuff.
73 : CPPUNIT_ASSERT_MESSAGE("Default script was stripped after canonicalize!?!", aBcp47 == s_de_Latn_DE );
74 : CPPUNIT_ASSERT( aLocale.Language == "qlt" );
75 : CPPUNIT_ASSERT( aLocale.Country == "DE" );
76 : CPPUNIT_ASSERT( aLocale.Variant == "de-Latn-DE" );
77 : CPPUNIT_ASSERT( nLanguageType == LANGUAGE_SYSTEM ); // XXX not resolved!
78 : CPPUNIT_ASSERT( de_DE.getLanguage() == "de" );
79 : CPPUNIT_ASSERT( de_DE.getCountry() == "DE" );
80 : CPPUNIT_ASSERT( de_DE.getScript() == "Latn" );
81 : CPPUNIT_ASSERT( de_DE.getLanguageAndScript() == "de-Latn" );
82 : #endif
83 : }
84 :
85 : {
86 1 : OUString s_klingon( "i-klingon" );
87 2 : LanguageTag klingon( s_klingon, true );
88 2 : lang::Locale aLocale = klingon.getLocale();
89 : #if USE_LIBLANGTAG
90 1 : CPPUNIT_ASSERT( klingon.getBcp47() == "tlh" );
91 1 : CPPUNIT_ASSERT( aLocale.Language == "tlh" );
92 1 : CPPUNIT_ASSERT( aLocale.Country == "" );
93 1 : CPPUNIT_ASSERT( aLocale.Variant == "" );
94 1 : CPPUNIT_ASSERT( klingon.getLanguageType() == LANGUAGE_SYSTEM );
95 1 : CPPUNIT_ASSERT( klingon.isValidBcp47() == true );
96 1 : CPPUNIT_ASSERT( klingon.isIsoLocale() == true );
97 2 : CPPUNIT_ASSERT( klingon.isIsoODF() == true );
98 : #else
99 : CPPUNIT_ASSERT( klingon.getBcp47() == s_klingon );
100 : CPPUNIT_ASSERT( aLocale.Language == "qlt" );
101 : CPPUNIT_ASSERT( aLocale.Country == "" );
102 : CPPUNIT_ASSERT( aLocale.Variant == s_klingon );
103 : CPPUNIT_ASSERT( klingon.getLanguageType() == LANGUAGE_SYSTEM );
104 : CPPUNIT_ASSERT( klingon.isValidBcp47() == true );
105 : CPPUNIT_ASSERT( klingon.isIsoLocale() == false );
106 : CPPUNIT_ASSERT( klingon.isIsoODF() == false );
107 : #endif
108 : }
109 :
110 : {
111 1 : OUString s_sr_RS( "sr-RS" );
112 2 : LanguageTag sr_RS( s_sr_RS, true );
113 2 : lang::Locale aLocale = sr_RS.getLocale();
114 1 : CPPUNIT_ASSERT( sr_RS.getBcp47() == s_sr_RS );
115 1 : CPPUNIT_ASSERT( aLocale.Language == "sr" );
116 1 : CPPUNIT_ASSERT( aLocale.Country == "RS" );
117 1 : CPPUNIT_ASSERT( aLocale.Variant == "" );
118 1 : CPPUNIT_ASSERT( sr_RS.getLanguageType() == LANGUAGE_USER_SERBIAN_CYRILLIC_SERBIA );
119 1 : CPPUNIT_ASSERT( sr_RS.isValidBcp47() == true );
120 1 : CPPUNIT_ASSERT( sr_RS.isIsoLocale() == true );
121 2 : CPPUNIT_ASSERT( sr_RS.isIsoODF() == true );
122 : }
123 :
124 : {
125 1 : OUString s_sr_Latn_RS( "sr-Latn-RS" );
126 2 : LanguageTag sr_RS( s_sr_Latn_RS, true );
127 2 : lang::Locale aLocale = sr_RS.getLocale();
128 1 : CPPUNIT_ASSERT( sr_RS.getBcp47() == s_sr_Latn_RS );
129 1 : CPPUNIT_ASSERT( aLocale.Language == "qlt" );
130 1 : CPPUNIT_ASSERT( aLocale.Country == "RS" );
131 1 : CPPUNIT_ASSERT( aLocale.Variant == s_sr_Latn_RS );
132 : /* TODO: conversion doesn't know this yet, once it does activate test. */
133 : #if 0
134 : CPPUNIT_ASSERT( sr_RS.getLanguageType() == LANGUAGE_USER_SERBIAN_LATIN_SERBIA );
135 : #else
136 1 : CPPUNIT_ASSERT( sr_RS.getLanguageType() == LANGUAGE_SYSTEM );
137 : #endif
138 1 : CPPUNIT_ASSERT( sr_RS.isValidBcp47() == true );
139 1 : CPPUNIT_ASSERT( sr_RS.isIsoLocale() == false );
140 1 : CPPUNIT_ASSERT( sr_RS.isIsoODF() == true );
141 1 : CPPUNIT_ASSERT( sr_RS.getLanguage() == "sr" );
142 1 : CPPUNIT_ASSERT( sr_RS.getCountry() == "RS" );
143 1 : CPPUNIT_ASSERT( sr_RS.getScript() == "Latn" );
144 2 : CPPUNIT_ASSERT( sr_RS.getLanguageAndScript() == "sr-Latn" );
145 : }
146 :
147 : {
148 1 : OUString s_de_DE( "de-DE" );
149 2 : LanguageTag de_DE( s_de_DE, true );
150 2 : lang::Locale aLocale = de_DE.getLocale();
151 1 : CPPUNIT_ASSERT( de_DE.getBcp47() == s_de_DE );
152 1 : CPPUNIT_ASSERT( aLocale.Language == "de" );
153 1 : CPPUNIT_ASSERT( aLocale.Country == "DE" );
154 1 : CPPUNIT_ASSERT( aLocale.Variant == "" );
155 1 : CPPUNIT_ASSERT( de_DE.getLanguageType() == LANGUAGE_GERMAN );
156 1 : CPPUNIT_ASSERT( de_DE.isValidBcp47() == true );
157 1 : CPPUNIT_ASSERT( de_DE.isIsoLocale() == true );
158 1 : CPPUNIT_ASSERT( de_DE.isIsoODF() == true );
159 1 : CPPUNIT_ASSERT( de_DE.getLanguage() == "de" );
160 1 : CPPUNIT_ASSERT( de_DE.getCountry() == "DE" );
161 1 : CPPUNIT_ASSERT( de_DE.getScript() == "" );
162 2 : CPPUNIT_ASSERT( de_DE.getLanguageAndScript() == "de" );
163 : }
164 :
165 : {
166 1 : OUString s_de_DE( "de-DE" );
167 2 : LanguageTag de_DE( lang::Locale( "de", "DE", "" ) );
168 2 : lang::Locale aLocale = de_DE.getLocale();
169 1 : CPPUNIT_ASSERT( de_DE.getBcp47() == s_de_DE );
170 1 : CPPUNIT_ASSERT( aLocale.Language == "de" );
171 1 : CPPUNIT_ASSERT( aLocale.Country == "DE" );
172 1 : CPPUNIT_ASSERT( aLocale.Variant == "" );
173 2 : CPPUNIT_ASSERT( de_DE.getLanguageType() == LANGUAGE_GERMAN );
174 : }
175 :
176 : {
177 1 : OUString s_de_DE( "de-DE" );
178 2 : LanguageTag de_DE( LANGUAGE_GERMAN );
179 2 : lang::Locale aLocale = de_DE.getLocale();
180 1 : CPPUNIT_ASSERT( de_DE.getBcp47() == s_de_DE );
181 1 : CPPUNIT_ASSERT( aLocale.Language == "de" );
182 1 : CPPUNIT_ASSERT( aLocale.Country == "DE" );
183 1 : CPPUNIT_ASSERT( aLocale.Variant == "" );
184 2 : CPPUNIT_ASSERT( de_DE.getLanguageType() == LANGUAGE_GERMAN );
185 : }
186 :
187 : // 'qtz' is a local use known pseudolocale for key ID resource
188 : {
189 1 : OUString s_qtz( "qtz" );
190 2 : LanguageTag qtz( s_qtz );
191 2 : lang::Locale aLocale = qtz.getLocale();
192 1 : CPPUNIT_ASSERT( qtz.getBcp47() == s_qtz );
193 1 : CPPUNIT_ASSERT( aLocale.Language == "qtz" );
194 1 : CPPUNIT_ASSERT( aLocale.Country == "" );
195 1 : CPPUNIT_ASSERT( aLocale.Variant == "" );
196 2 : CPPUNIT_ASSERT( qtz.getLanguageType() == LANGUAGE_USER_KEYID );
197 : }
198 :
199 : // 'qty' is a local use unknown locale
200 : {
201 1 : OUString s_qty( "qty" );
202 2 : LanguageTag qty( s_qty );
203 2 : lang::Locale aLocale = qty.getLocale();
204 1 : CPPUNIT_ASSERT( qty.getBcp47() == s_qty );
205 1 : CPPUNIT_ASSERT( aLocale.Language == "qty" );
206 1 : CPPUNIT_ASSERT( aLocale.Country == "" );
207 1 : CPPUNIT_ASSERT( aLocale.Variant == "" );
208 2 : CPPUNIT_ASSERT( qty.getLanguageType() == LANGUAGE_SYSTEM );
209 : }
210 :
211 : // 'x-comment' is a privateuse known "locale"
212 : {
213 1 : OUString s_xcomment( "x-comment" );
214 2 : LanguageTag xcomment( s_xcomment );
215 2 : lang::Locale aLocale = xcomment.getLocale();
216 1 : CPPUNIT_ASSERT( xcomment.getBcp47() == s_xcomment );
217 1 : CPPUNIT_ASSERT( aLocale.Language == "qlt" );
218 1 : CPPUNIT_ASSERT( aLocale.Country == "" );
219 1 : CPPUNIT_ASSERT( aLocale.Variant == "x-comment" );
220 2 : CPPUNIT_ASSERT( xcomment.getLanguageType() == LANGUAGE_USER_PRIV_COMMENT );
221 : }
222 :
223 : // 'x-foobar' is a privateuse unknown "locale"
224 : {
225 1 : OUString s_xfoobar( "x-foobar" );
226 2 : LanguageTag xfoobar( s_xfoobar );
227 2 : lang::Locale aLocale = xfoobar.getLocale();
228 1 : CPPUNIT_ASSERT( xfoobar.getBcp47() == s_xfoobar );
229 1 : CPPUNIT_ASSERT( aLocale.Language == "qlt" );
230 1 : CPPUNIT_ASSERT( aLocale.Country == "" );
231 1 : CPPUNIT_ASSERT( aLocale.Variant == "x-foobar" );
232 2 : CPPUNIT_ASSERT( xfoobar.getLanguageType() == LANGUAGE_SYSTEM );
233 : }
234 :
235 : // '*' the dreaded jolly joker is a "privateuse" known "locale"
236 : {
237 1 : OUString s_joker( "*" );
238 2 : LanguageTag joker( s_joker );
239 2 : lang::Locale aLocale = joker.getLocale();
240 1 : CPPUNIT_ASSERT( joker.getBcp47() == s_joker );
241 1 : CPPUNIT_ASSERT( aLocale.Language == "qlt" );
242 1 : CPPUNIT_ASSERT( aLocale.Country == "" );
243 1 : CPPUNIT_ASSERT( aLocale.Variant == "*" );
244 1 : CPPUNIT_ASSERT( joker.getLanguageType() == LANGUAGE_USER_PRIV_JOKER );
245 :
246 1 : joker.reset( LANGUAGE_USER_PRIV_JOKER );
247 1 : aLocale = joker.getLocale();
248 1 : CPPUNIT_ASSERT( joker.getBcp47() == s_joker );
249 1 : CPPUNIT_ASSERT( aLocale.Language == "qlt" );
250 1 : CPPUNIT_ASSERT( aLocale.Country == "" );
251 1 : CPPUNIT_ASSERT( aLocale.Variant == "*" );
252 2 : CPPUNIT_ASSERT( joker.getLanguageType() == LANGUAGE_USER_PRIV_JOKER );
253 : }
254 :
255 : // test reset() methods
256 : {
257 1 : LanguageTag aTag( LANGUAGE_DONTKNOW );
258 2 : lang::Locale aLocale;
259 :
260 1 : aTag.reset( LANGUAGE_GERMAN );
261 1 : aLocale = aTag.getLocale();
262 1 : CPPUNIT_ASSERT( aTag.getBcp47() == "de-DE" );
263 1 : CPPUNIT_ASSERT( aLocale.Language == "de" );
264 1 : CPPUNIT_ASSERT( aLocale.Country == "DE" );
265 1 : CPPUNIT_ASSERT( aLocale.Variant == "" );
266 1 : CPPUNIT_ASSERT( aTag.getLanguageType() == LANGUAGE_GERMAN );
267 :
268 1 : aTag.reset( "en-US" );
269 1 : aLocale = aTag.getLocale();
270 1 : CPPUNIT_ASSERT( aTag.getBcp47() == "en-US" );
271 1 : CPPUNIT_ASSERT( aLocale.Language == "en" );
272 1 : CPPUNIT_ASSERT( aLocale.Country == "US" );
273 1 : CPPUNIT_ASSERT( aLocale.Variant == "" );
274 1 : CPPUNIT_ASSERT( aTag.getLanguageType() == LANGUAGE_ENGLISH_US );
275 :
276 1 : aTag.reset( lang::Locale( "de", "DE", "" ) );
277 1 : aLocale = aTag.getLocale();
278 1 : CPPUNIT_ASSERT( aTag.getBcp47() == "de-DE" );
279 1 : CPPUNIT_ASSERT( aLocale.Language == "de" );
280 1 : CPPUNIT_ASSERT( aLocale.Country == "DE" );
281 1 : CPPUNIT_ASSERT( aLocale.Variant == "" );
282 2 : CPPUNIT_ASSERT( aTag.getLanguageType() == LANGUAGE_GERMAN );
283 : }
284 :
285 : {
286 1 : OUString s_uab( "unreg-and-bad" );
287 2 : LanguageTag uab( s_uab, true );
288 2 : lang::Locale aLocale = uab.getLocale();
289 1 : CPPUNIT_ASSERT( uab.getBcp47() == s_uab );
290 1 : CPPUNIT_ASSERT( aLocale.Language == "qlt" );
291 1 : CPPUNIT_ASSERT( aLocale.Country == "" );
292 1 : CPPUNIT_ASSERT( aLocale.Variant == s_uab );
293 1 : CPPUNIT_ASSERT( uab.getLanguageType() == LANGUAGE_SYSTEM );
294 1 : CPPUNIT_ASSERT( uab.isValidBcp47() == false );
295 1 : CPPUNIT_ASSERT( uab.isIsoLocale() == false );
296 2 : CPPUNIT_ASSERT( uab.isIsoODF() == false );
297 : }
298 1 : }
299 :
300 1 : void TestLanguageTag::testAllIsoLangEntries()
301 : {
302 : const MsLangId::IsoLangEntry* pLangEntry;
303 1 : sal_Int32 nIndex = 0;
304 424 : while (((pLangEntry = MsLangId::getIsoLangEntry( nIndex++ )) != NULL) && (pLangEntry->mnLang != LANGUAGE_DONTKNOW))
305 : {
306 422 : LanguageTag aTagString( pLangEntry->getTagString(), true);
307 844 : LanguageTag aTagID( pLangEntry->mnLang);
308 422 : if (pLangEntry->getTagString() != aTagString.getBcp47())
309 : {
310 0 : OString aMessage( OUStringToOString( pLangEntry->getTagString(), RTL_TEXTENCODING_ASCII_US));
311 0 : aMessage += " -> " + OUStringToOString( aTagString.getBcp47(), RTL_TEXTENCODING_ASCII_US);
312 0 : CPPUNIT_ASSERT_MESSAGE( aMessage.getStr(), pLangEntry->getTagString() == aTagString.getBcp47());
313 : }
314 422 : if (pLangEntry->getTagString() != aTagID.getBcp47())
315 : {
316 : // There are multiple mappings, ID must be equal after conversions.
317 14 : LanguageTag aTagBack( aTagID.getBcp47(), true);
318 14 : if (aTagString.getLanguageType() != aTagBack.getLanguageType())
319 : {
320 0 : OString aMessage( OUStringToOString( pLangEntry->getTagString(), RTL_TEXTENCODING_ASCII_US));
321 0 : aMessage += " " + OString::number( aTagString.getLanguageType(), 16) +
322 0 : " -> " + OString::number( aTagBack.getLanguageType(), 16);
323 0 : CPPUNIT_ASSERT_MESSAGE( aMessage.getStr(), aTagString.getLanguageType() == aTagBack.getLanguageType());
324 14 : }
325 : }
326 : #if 0
327 : // This does not hold, there are cases like 'ar'
328 : // LANGUAGE_ARABIC_PRIMARY_ONLY that when mapped back results in
329 : // 'ar-SA' as default locale.
330 : if (pLangEntry->mnLang != aTagString.getLanguageType())
331 : {
332 : // There are multiple mappings, string must be equal after conversions.
333 : LanguageTag aTagBack( aTagString.getLanguageType());
334 : if (aTagID.getBcp47() != aTagBack.getBcp47())
335 : {
336 : OString aMessage( OUStringToOString( pLangEntry->getTagString(), RTL_TEXTENCODING_ASCII_US));
337 : aMessage += " " + OUStringToOString( aTagID.getBcp47(), RTL_TEXTENCODING_ASCII_US) +
338 : " -> " + OUStringToOString( aTagBack.getBcp47(), RTL_TEXTENCODING_ASCII_US);
339 : CPPUNIT_ASSERT_MESSAGE( aMessage.getStr(), aTagID.getBcp47() == aTagBack.getBcp47());
340 : }
341 : }
342 : #endif
343 422 : }
344 :
345 1 : }
346 :
347 1 : CPPUNIT_TEST_SUITE_REGISTRATION( TestLanguageTag );
348 :
349 : }
350 :
351 4 : CPPUNIT_PLUGIN_IMPLEMENT();
352 :
353 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|