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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <comphelper/string.hxx>
21 #include <cppuhelper/implbase1.hxx>
22 #include <com/sun/star/i18n/CharType.hpp>
24 #include "cppunit/TestAssert.h"
25 #include "cppunit/TestFixture.h"
26 #include "cppunit/extensions/HelperMacros.h"
27 #include "cppunit/plugin/TestPlugIn.h"
28 #include "rtl/string.hxx"
29 #include "rtl/ustring.hxx"
33 class TestString
: public CppUnit::TestFixture
38 void testStripStart();
42 void testTokenCount();
43 void testDecimalStringToNumber();
44 void testIsdigitAsciiString();
45 void testReverseString();
46 void testEqualsString();
48 CPPUNIT_TEST_SUITE(TestString
);
49 CPPUNIT_TEST(testNatural
);
50 CPPUNIT_TEST(testRemove
);
51 CPPUNIT_TEST(testStripStart
);
52 CPPUNIT_TEST(testStripEnd
);
53 CPPUNIT_TEST(testStrip
);
54 CPPUNIT_TEST(testToken
);
55 CPPUNIT_TEST(testTokenCount
);
56 CPPUNIT_TEST(testDecimalStringToNumber
);
57 CPPUNIT_TEST(testIsdigitAsciiString
);
58 CPPUNIT_TEST(testReverseString
);
59 CPPUNIT_TEST(testEqualsString
);
60 CPPUNIT_TEST_SUITE_END();
63 void TestString::testDecimalStringToNumber()
66 CPPUNIT_ASSERT_EQUAL((sal_uInt32
)1234, comphelper::string::decimalStringToNumber(s1
));
67 s1
+= OUString(static_cast<sal_Unicode
>(0x07C6));
68 CPPUNIT_ASSERT_EQUAL((sal_uInt32
)12346, comphelper::string::decimalStringToNumber(s1
));
69 // Codepoints on 2 16bits words
70 sal_uInt32 utf16String
[] = { 0x1D7FE /* 8 */, 0x1D7F7 /* 1 */};
71 s1
= OUString(utf16String
, 2);
72 CPPUNIT_ASSERT_EQUAL((sal_uInt32
)81, comphelper::string::decimalStringToNumber(s1
));
75 void TestString::testIsdigitAsciiString()
78 CPPUNIT_ASSERT_EQUAL(comphelper::string::isdigitAsciiString(s1
), true);
81 CPPUNIT_ASSERT_EQUAL(comphelper::string::isdigitAsciiString(s2
), false);
84 CPPUNIT_ASSERT_EQUAL(comphelper::string::isdigitAsciiString(s3
), true);
87 using namespace ::com::sun::star
;
89 class testCollator
: public cppu::WeakImplHelper1
< i18n::XCollator
>
92 virtual sal_Int32 SAL_CALL
compareSubstring(
93 const OUString
& str1
, sal_Int32 off1
, sal_Int32 len1
,
94 const OUString
& str2
, sal_Int32 off2
, sal_Int32 len2
) throw(uno::RuntimeException
)
96 return str1
.copy(off1
, len1
).compareTo(str2
.copy(off2
, len2
));
98 virtual sal_Int32 SAL_CALL
compareString(
100 const OUString
& str2
) throw(uno::RuntimeException
)
102 return str1
.compareTo(str2
);
104 virtual sal_Int32 SAL_CALL
loadDefaultCollator(const lang::Locale
&, sal_Int32
)
105 throw(uno::RuntimeException
) {return 0;}
106 virtual sal_Int32 SAL_CALL
loadCollatorAlgorithm(const OUString
&,
107 const lang::Locale
&, sal_Int32
) throw(uno::RuntimeException
) {return 0;}
108 virtual void SAL_CALL
loadCollatorAlgorithmWithEndUserOption(const OUString
&,
109 const lang::Locale
&, const uno::Sequence
< sal_Int32
>&) throw(uno::RuntimeException
) {}
110 virtual uno::Sequence
< OUString
> SAL_CALL
listCollatorAlgorithms(const lang::Locale
&)
111 throw(uno::RuntimeException
)
113 return uno::Sequence
< OUString
>();
115 virtual uno::Sequence
< sal_Int32
> SAL_CALL
listCollatorOptions(const OUString
&)
116 throw(uno::RuntimeException
)
118 return uno::Sequence
< sal_Int32
>();
122 #define IS_DIGIT(CHAR) (((CHAR) >= 48) && ((CHAR <= 57)))
124 class testBreakIterator
: public cppu::WeakImplHelper1
< i18n::XBreakIterator
>
127 virtual sal_Int32 SAL_CALL
nextCharacters( const OUString
&, sal_Int32
,
128 const lang::Locale
&, sal_Int16
, sal_Int32
, sal_Int32
& )
129 throw(uno::RuntimeException
) {return -1;}
130 virtual sal_Int32 SAL_CALL
previousCharacters( const OUString
&, sal_Int32
,
131 const lang::Locale
&, sal_Int16
, sal_Int32
, sal_Int32
& )
132 throw(uno::RuntimeException
) {return -1;}
134 virtual i18n::Boundary SAL_CALL
previousWord( const OUString
&, sal_Int32
,
135 const lang::Locale
&, sal_Int16
) throw(uno::RuntimeException
)
136 { return i18n::Boundary(); }
137 virtual i18n::Boundary SAL_CALL
nextWord( const OUString
&, sal_Int32
,
138 const lang::Locale
&, sal_Int16
) throw(uno::RuntimeException
)
139 { return i18n::Boundary(); }
140 virtual i18n::Boundary SAL_CALL
getWordBoundary( const OUString
&, sal_Int32
,
141 const lang::Locale
&, sal_Int16
, sal_Bool
)
142 throw(uno::RuntimeException
)
143 { return i18n::Boundary(); }
145 virtual sal_Bool SAL_CALL
isBeginWord( const OUString
&, sal_Int32
,
146 const lang::Locale
&, sal_Int16
) throw(uno::RuntimeException
)
148 virtual sal_Bool SAL_CALL
isEndWord( const OUString
&, sal_Int32
,
149 const lang::Locale
& , sal_Int16
) throw(uno::RuntimeException
)
151 virtual sal_Int16 SAL_CALL
getWordType( const OUString
&, sal_Int32
,
152 const lang::Locale
& ) throw(uno::RuntimeException
)
155 virtual sal_Int32 SAL_CALL
beginOfSentence( const OUString
&, sal_Int32
,
156 const lang::Locale
& ) throw(uno::RuntimeException
)
158 virtual sal_Int32 SAL_CALL
endOfSentence( const OUString
& rText
, sal_Int32
,
159 const lang::Locale
& ) throw(uno::RuntimeException
)
160 { return rText
.getLength(); }
162 virtual i18n::LineBreakResults SAL_CALL
getLineBreak( const OUString
&, sal_Int32
,
163 const lang::Locale
&, sal_Int32
,
164 const i18n::LineBreakHyphenationOptions
&,
165 const i18n::LineBreakUserOptions
&)
166 throw(uno::RuntimeException
)
168 return i18n::LineBreakResults();
171 virtual sal_Int16 SAL_CALL
getScriptType( const OUString
&, sal_Int32
)
172 throw(uno::RuntimeException
) { return -1; }
173 virtual sal_Int32 SAL_CALL
beginOfScript( const OUString
&, sal_Int32
,
174 sal_Int16
) throw(uno::RuntimeException
) { return -1; }
175 virtual sal_Int32 SAL_CALL
endOfScript( const OUString
&, sal_Int32
,
176 sal_Int16
) throw(uno::RuntimeException
) { return -1; }
177 virtual sal_Int32 SAL_CALL
previousScript( const OUString
&, sal_Int32
,
178 sal_Int16
) throw(uno::RuntimeException
) { return -1; }
179 virtual sal_Int32 SAL_CALL
nextScript( const OUString
&, sal_Int32
,
180 sal_Int16
) throw(uno::RuntimeException
) { return -1; }
182 virtual sal_Int32 SAL_CALL
beginOfCharBlock( const OUString
&, sal_Int32
,
183 const lang::Locale
&, sal_Int16
) throw(uno::RuntimeException
) { return -1; }
184 virtual sal_Int32 SAL_CALL
endOfCharBlock( const OUString
& rText
, sal_Int32 nStartPos
,
185 const lang::Locale
&, sal_Int16 CharType
) throw(uno::RuntimeException
)
187 const sal_Unicode
*pStr
= rText
.getStr()+nStartPos
;
188 for (sal_Int32 nI
= nStartPos
; nI
< rText
.getLength(); ++nI
)
190 if (CharType
== i18n::CharType::DECIMAL_DIGIT_NUMBER
&& !IS_DIGIT(*pStr
))
192 else if (CharType
!= i18n::CharType::DECIMAL_DIGIT_NUMBER
&& IS_DIGIT(*pStr
))
198 virtual sal_Int32 SAL_CALL
previousCharBlock( const OUString
&, sal_Int32
,
199 const lang::Locale
&, sal_Int16
) throw(uno::RuntimeException
) { return -1; }
200 virtual sal_Int32 SAL_CALL
nextCharBlock( const OUString
& rText
, sal_Int32 nStartPos
,
201 const lang::Locale
&, sal_Int16 CharType
) throw(uno::RuntimeException
)
203 const sal_Unicode
*pStr
= rText
.getStr()+nStartPos
;
204 for (sal_Int32 nI
= nStartPos
; nI
< rText
.getLength(); ++nI
)
206 if (CharType
== i18n::CharType::DECIMAL_DIGIT_NUMBER
&& IS_DIGIT(*pStr
))
208 else if (CharType
!= i18n::CharType::DECIMAL_DIGIT_NUMBER
&& !IS_DIGIT(*pStr
))
216 void TestString::testNatural()
218 using namespace comphelper::string
;
220 uno::Reference
< i18n::XCollator
> xCollator(new testCollator
);
221 uno::Reference
< i18n::XBreakIterator
> xBI(new testBreakIterator
);
223 // --- Some generic tests to ensure we do not alter original behavior
224 // outside what we want
226 compareNatural("ABC", "ABC", xCollator
, xBI
, lang::Locale()) == 0
230 compareNatural("ABC", "abc", xCollator
, xBI
, lang::Locale()) < 0
234 compareNatural("abc", "ABC", xCollator
, xBI
, lang::Locale()) > 0
238 compareNatural("alongstring", "alongerstring", xCollator
, xBI
, lang::Locale()) > 0
242 compareNatural("alongerstring", "alongstring", xCollator
, xBI
, lang::Locale()) < 0
244 // -- Here we go on natural order, each one is followed by classic compare and the reverse comparison
245 // That's why we originally made the patch
247 compareNatural("Heading 9", "Heading 10", xCollator
, xBI
, lang::Locale()) < 0
251 OUString("Heading 9").compareTo("Heading 10") > 0
254 compareNatural("Heading 10", "Heading 9", xCollator
, xBI
, lang::Locale()) > 0
258 compareNatural("July, the 4th", "July, the 10th", xCollator
, xBI
, lang::Locale()) < 0
261 OUString("July, the 4th").compareTo("July, the 10th") > 0
264 compareNatural("July, the 10th", "July, the 4th", xCollator
, xBI
, lang::Locale()) > 0
268 compareNatural("abc08", "abc010", xCollator
, xBI
, lang::Locale()) < 0
271 OUString("abc08").compareTo("abc010") > 0
274 compareNatural("abc010", "abc08", xCollator
, xBI
, lang::Locale()) > 0
277 compareNatural("apple10apple", "apple10apple", xCollator
, xBI
, lang::Locale()) == 0
281 void TestString::testRemove()
286 aOut
= ::comphelper::string::remove(aIn
, 'b');
287 CPPUNIT_ASSERT(aOut
== "ac");
291 aOut
= ::comphelper::string::remove(aIn
, 'a');
292 CPPUNIT_ASSERT(aOut
.isEmpty());
295 void TestString::testStripStart()
300 aOut
= ::comphelper::string::stripStart(aIn
, 'b');
301 CPPUNIT_ASSERT(aOut
== "abc");
303 aOut
= ::comphelper::string::stripStart(aIn
, 'a');
304 CPPUNIT_ASSERT(aOut
== "bc");
307 aOut
= ::comphelper::string::stripStart(aIn
, 'a');
308 CPPUNIT_ASSERT(aOut
.isEmpty());
311 aOut
= ::comphelper::string::stripStart(aIn
, 'a');
312 CPPUNIT_ASSERT(aOut
== "ba");
315 void TestString::testStripEnd()
320 aOut
= ::comphelper::string::stripEnd(aIn
, 'b');
321 CPPUNIT_ASSERT(aOut
== "abc");
323 aOut
= ::comphelper::string::stripEnd(aIn
, 'c');
324 CPPUNIT_ASSERT(aOut
== "ab");
327 aOut
= ::comphelper::string::stripEnd(aIn
, 'a');
328 CPPUNIT_ASSERT(aOut
.isEmpty());
331 aOut
= ::comphelper::string::stripEnd(aIn
, 'a');
332 CPPUNIT_ASSERT(aOut
== "ab");
335 void TestString::testStrip()
340 aOut
= ::comphelper::string::strip(aIn
, 'b');
341 CPPUNIT_ASSERT(aOut
== "abc");
343 aOut
= ::comphelper::string::strip(aIn
, 'c');
344 CPPUNIT_ASSERT(aOut
== "ab");
347 aOut
= ::comphelper::string::strip(aIn
, 'a');
348 CPPUNIT_ASSERT(aOut
.isEmpty());
351 aOut
= ::comphelper::string::strip(aIn
, 'a');
352 CPPUNIT_ASSERT(aOut
== "b");
355 void TestString::testToken()
357 OString
aIn("10.11.12");
360 aOut
= ::comphelper::string::getToken(aIn
, -1, '.');
361 CPPUNIT_ASSERT(aOut
.isEmpty());
363 aOut
= ::comphelper::string::getToken(aIn
, 0, '.');
364 CPPUNIT_ASSERT(aOut
== "10");
366 aOut
= ::comphelper::string::getToken(aIn
, 1, '.');
367 CPPUNIT_ASSERT(aOut
== "11");
369 aOut
= ::comphelper::string::getToken(aIn
, 2, '.');
370 CPPUNIT_ASSERT(aOut
== "12");
372 aOut
= ::comphelper::string::getToken(aIn
, 3, '.');
373 CPPUNIT_ASSERT(aOut
.isEmpty());
376 void TestString::testTokenCount()
378 OString
aIn("10.11.12");
381 nOut
= ::comphelper::string::getTokenCount(aIn
, '.');
382 CPPUNIT_ASSERT(nOut
== 3);
384 nOut
= ::comphelper::string::getTokenCount(aIn
, 'X');
385 CPPUNIT_ASSERT(nOut
== 1);
387 nOut
= ::comphelper::string::getTokenCount(OString(), 'X');
388 CPPUNIT_ASSERT(nOut
== 0);
391 void TestString::testReverseString()
394 OString aOut
= ::comphelper::string::reverseString(aIn
);
396 CPPUNIT_ASSERT(aOut
== "CBA");
399 void TestString::testEqualsString()
402 CPPUNIT_ASSERT(::comphelper::string::equals(aIn
, 'A'));
403 CPPUNIT_ASSERT(!::comphelper::string::equals(aIn
, 'B'));
405 CPPUNIT_ASSERT(!::comphelper::string::equals(aIn
, 'A'));
407 CPPUNIT_ASSERT(!::comphelper::string::equals(aIn
, 'A'));
410 CPPUNIT_TEST_SUITE_REGISTRATION(TestString
);
414 CPPUNIT_PLUGIN_IMPLEMENT();
416 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */