android: Update app-specific/MIME type icons
[LibreOffice.git] / sal / qa / rtl / oustring / rtl_OUString2.cxx
blob1340b262642bbebed28a044e02fc5cc17c3631b2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 // autogenerated file with codegen.pl
22 #include <memory>
23 #include <math.h>
24 #include <stdio.h>
26 #include <algorithm>
27 #include <limits>
29 #include <cppunit/TestFixture.h>
30 #include <cppunit/extensions/HelperMacros.h>
31 #include <cppunit/plugin/TestPlugIn.h>
33 #include <config_options.h>
34 #include <o3tl/cppunittraitshelper.hxx>
35 #include <o3tl/safeint.hxx>
37 #include <stringhelper.hxx>
38 #include <valueequal.hxx>
40 namespace rtl_OUString
43 namespace {
45 // Avoid -fsanitize=undefined warning e.g. "runtime error: value 1e+99 is
46 // outside the range of representable values of type 'float'" with Clang prior to
47 // <https://github.com/llvm/llvm-project/commit/9e52c43090f8cd980167bbd2719878ae36bcf6b5> "Treat the
48 // range of representable values of floating-point types as [-inf, +inf] not as [-max, +max]"
49 // (ENABLE_RUNTIME_OPTIMIZATIONS is an approximation for checking whether building is done without
50 // -fsanitize=undefined):
51 float doubleToFloat(double x) {
52 #if !defined __clang__ || __clang_major__ >= 9 || ENABLE_RUNTIME_OPTIMIZATIONS
53 return static_cast<float>(x);
54 #else
55 return
56 x < -std::numeric_limits<float>::max()
57 ? -std::numeric_limits<float>::infinity()
58 : x > std::numeric_limits<float>::max()
59 ? std::numeric_limits<float>::infinity()
60 : static_cast<float>(x);
61 #endif
66 class number : public CppUnit::TestFixture
68 void number_float_test_impl(float _nValue)
70 OUString suValue(OUString::number(_nValue));
71 OString sValue;
72 sValue <<= suValue;
73 printf("nFloat := %.9f sValue := %s\n", _nValue, sValue.getStr());
75 double nValueATOF = doubleToFloat(atof( sValue.getStr() ));
77 bool bEqualResult = is_float_equal(_nValue, nValueATOF);
78 CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult);
81 void number_float_test(float _nValue)
83 number_float_test_impl(_nValue);
85 // test also the negative part.
86 float nNegativeValue = -_nValue;
87 number_float_test_impl(nNegativeValue);
90 public:
91 // insert your test code here.
92 void number_float_test_001()
94 // this is demonstration code
95 // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1);
96 float nValue = 3.0f;
97 number_float_test(nValue);
100 void number_float_test_002()
102 float nValue = 3.5f;
103 number_float_test(nValue);
106 void number_float_test_003()
108 float nValue = 3.0625f;
109 number_float_test(nValue);
112 void number_float_test_004()
114 float nValue = 3.502525f;
115 number_float_test(nValue);
118 void number_float_test_005()
120 float nValue = 3.141592f;
121 number_float_test(nValue);
124 void number_float_test_006()
126 float nValue = 3.5025255f;
127 number_float_test(nValue);
130 void number_float_test_007()
132 float nValue = 3.0039062f;
133 number_float_test(nValue);
136 private:
138 void number_double_test_impl(double _nValue)
140 OUString suValue = OUString::number( _nValue );
141 OString sValue;
142 sValue <<= suValue;
143 printf("nDouble := %.20f sValue := %s\n", _nValue, sValue.getStr());
145 double nValueATOF = atof( sValue.getStr() );
147 bool bEqualResult = is_double_equal(_nValue, nValueATOF);
148 CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult);
151 void number_double_test(double _nValue)
153 number_double_test_impl(_nValue);
155 // test also the negative part.
156 double nNegativeValue = -_nValue;
157 number_double_test_impl(nNegativeValue);
159 public:
161 // number double
162 void number_double_test_001()
164 double nValue = 3.0;
165 number_double_test(nValue);
167 void number_double_test_002()
169 double nValue = 3.5;
170 number_double_test(nValue);
172 void number_double_test_003()
174 double nValue = 3.0625;
175 number_double_test(nValue);
177 void number_double_test_004()
179 double nValue = 3.1415926535;
180 number_double_test(nValue);
182 void number_double_test_005()
184 double nValue = 3.141592653589793;
185 number_double_test(nValue);
187 void number_double_test_006()
189 double nValue = 3.1415926535897932;
190 number_double_test(nValue);
192 void number_double_test_007()
194 double nValue = 3.14159265358979323;
195 number_double_test(nValue);
197 void number_double_test_008()
199 double nValue = 3.141592653589793238462643;
200 number_double_test(nValue);
203 // Change the following lines only, if you add, remove or rename
204 // member functions of the current class,
205 // because these macros are need by auto register mechanism.
207 CPPUNIT_TEST_SUITE(number);
208 CPPUNIT_TEST(number_float_test_001);
209 CPPUNIT_TEST(number_float_test_002);
210 CPPUNIT_TEST(number_float_test_003);
211 CPPUNIT_TEST(number_float_test_004);
212 CPPUNIT_TEST(number_float_test_005);
213 CPPUNIT_TEST(number_float_test_006);
214 CPPUNIT_TEST(number_float_test_007);
216 CPPUNIT_TEST(number_double_test_001);
217 CPPUNIT_TEST(number_double_test_002);
218 CPPUNIT_TEST(number_double_test_003);
219 CPPUNIT_TEST(number_double_test_004);
220 CPPUNIT_TEST(number_double_test_005);
221 CPPUNIT_TEST(number_double_test_006);
222 CPPUNIT_TEST(number_double_test_007);
223 CPPUNIT_TEST(number_double_test_008);
224 CPPUNIT_TEST_SUITE_END();
225 }; // class number
227 class toInt: public CppUnit::TestFixture {
228 public:
229 void test() {
230 CPPUNIT_ASSERT_EQUAL(
231 static_cast< sal_Int32 >(-0x76543210),
232 (OUString("-76543210").
233 toInt32(16)));
234 // @return 0 if this string represents no number or one of too large magnitude
235 CPPUNIT_ASSERT_EQUAL(
236 static_cast< sal_Int32 >(0),
237 (OUString("+FEDCBA98").
238 toInt32(16)));
239 CPPUNIT_ASSERT_EQUAL(
240 static_cast< sal_Int64 >(-SAL_CONST_INT64(0x76543210FEDCBA98)),
241 (OUString(
242 "-76543210FEDCBA98").
243 toInt64(16)));
244 // @return 0 if this string represents no number or one of too large magnitude
245 CPPUNIT_ASSERT_EQUAL(
246 static_cast< sal_Int64 >(SAL_CONST_INT64(0)),
247 (OUString(
248 "+FEDCBA9876543210").
249 toInt64(16)));
252 CPPUNIT_TEST_SUITE(toInt);
253 CPPUNIT_TEST(test);
254 CPPUNIT_TEST_SUITE_END();
257 // - toDouble (tests)
258 class toDouble : public CppUnit::TestFixture
260 public:
261 void toDouble_test_impl(OString const& _sValue)
263 //printf("the original str is %s\n", _sValue.getStr());
264 double nValueATOF = atof( _sValue.getStr() );
265 //printf("original data is %e\n", nValueATOF);
266 OUString suValue = OUString::createFromAscii( _sValue.getStr() );
267 double nValueToDouble = suValue.toDouble();
268 //printf("result data is %e\n", nValueToDouble);
270 bool bEqualResult = is_double_equal(nValueToDouble, nValueATOF);
271 CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult);
274 void toDouble_test(OString const& _sValue)
276 toDouble_test_impl(_sValue);
278 // test also the negative part.
279 OString sNegativValue("-");
280 sNegativValue += _sValue;
281 toDouble_test_impl(sNegativValue);
284 // insert your test code here.
285 void toDouble_selftest()
287 printf("Start selftest:\n");
288 CPPUNIT_ASSERT (!is_double_equal(1.0, 1.01));
289 CPPUNIT_ASSERT (!is_double_equal(1.0, 1.001));
290 CPPUNIT_ASSERT (!is_double_equal(1.0, 1.0001));
291 CPPUNIT_ASSERT (!is_double_equal(1.0, 1.00001));
292 CPPUNIT_ASSERT (!is_double_equal(1.0, 1.000001));
293 CPPUNIT_ASSERT (!is_double_equal(1.0, 1.0000001));
294 CPPUNIT_ASSERT (!is_double_equal(1.0, 1.00000001));
295 CPPUNIT_ASSERT (!is_double_equal(1.0, 1.000000001));
296 CPPUNIT_ASSERT (!is_double_equal(1.0, 1.0000000001));
297 CPPUNIT_ASSERT (!is_double_equal(1.0, 1.00000000001));
298 CPPUNIT_ASSERT (!is_double_equal(1.0, 1.000000000001));
299 CPPUNIT_ASSERT (!is_double_equal(1.0, 1.0000000000001));
300 // we check til 15 values after comma
301 CPPUNIT_ASSERT (is_double_equal(1.0, 1.00000000000001));
302 CPPUNIT_ASSERT (is_double_equal(1.0, 1.000000000000001));
303 CPPUNIT_ASSERT (is_double_equal(1.0, 1.0000000000000001));
304 printf("Selftest done.\n");
307 void toDouble_test_3()
309 toDouble_test("3");
311 void toDouble_test_3_5()
313 toDouble_test("3.5");
315 void toDouble_test_3_0625()
317 toDouble_test("3.0625");
319 void toDouble_test_pi()
321 // value from http://www.angio.net/pi/digits/50.txt
322 toDouble_test("3.141592653589793238462643383279502884197169399375");
325 void toDouble_test_1()
327 toDouble_test("1");
329 void toDouble_test_10()
331 toDouble_test("10");
333 void toDouble_test_100()
335 toDouble_test("100");
337 void toDouble_test_1000()
339 toDouble_test("1000");
341 void toDouble_test_10000()
343 toDouble_test("10000");
345 void toDouble_test_1e99()
347 toDouble_test("1e99");
349 void toDouble_test_1e_n99()
351 toDouble_test("1e-99");
353 void toDouble_test_1e308()
355 toDouble_test("1e308");
358 // Change the following lines only, if you add, remove or rename
359 // member functions of the current class,
360 // because these macros are need by auto register mechanism.
362 CPPUNIT_TEST_SUITE(toDouble);
363 CPPUNIT_TEST(toDouble_selftest);
365 CPPUNIT_TEST(toDouble_test_3);
366 CPPUNIT_TEST(toDouble_test_3_5);
367 CPPUNIT_TEST(toDouble_test_3_0625);
368 CPPUNIT_TEST(toDouble_test_pi);
369 CPPUNIT_TEST(toDouble_test_1);
370 CPPUNIT_TEST(toDouble_test_10);
371 CPPUNIT_TEST(toDouble_test_100);
372 CPPUNIT_TEST(toDouble_test_1000);
373 CPPUNIT_TEST(toDouble_test_10000);
374 CPPUNIT_TEST(toDouble_test_1e99);
375 CPPUNIT_TEST(toDouble_test_1e_n99);
376 CPPUNIT_TEST(toDouble_test_1e308);
377 CPPUNIT_TEST_SUITE_END();
378 }; // class toDouble
380 // - toFloat (tests)
381 class toFloat : public CppUnit::TestFixture
383 public:
384 void toFloat_test_impl(OString const& _sValue)
386 //printf("the original str is %s\n", _sValue.getStr());
387 float nValueATOF = doubleToFloat(atof( _sValue.getStr() ));
388 //printf("the original str is %.10f\n", nValueATOF);
389 OUString suValue = OUString::createFromAscii( _sValue.getStr() );
390 float nValueToFloat = suValue.toFloat();
391 //printf("the result str is %.10f\n", nValueToFloat);
393 bool bEqualResult = is_float_equal(nValueToFloat, nValueATOF);
394 CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult);
397 void toFloat_test(OString const& _sValue)
399 toFloat_test_impl(_sValue);
401 // test also the negative part.
402 OString sNegativValue("-");
403 sNegativValue += _sValue;
404 toFloat_test_impl(sNegativValue);
407 // insert your test code here.
408 void toFloat_selftest()
410 printf("Start selftest:\n");
411 CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.01f));
412 CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.001f));
413 CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.0001f));
414 CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.00001f));
415 CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.000002f));
416 CPPUNIT_ASSERT (is_float_equal(1.0f, 1.0000001f));
417 CPPUNIT_ASSERT (is_float_equal(1.0f, 1.00000001f));
418 CPPUNIT_ASSERT (is_float_equal(1.0f, 1.000000001f));
420 printf("Selftest done.\n");
423 void toFloat_test_3()
425 toFloat_test("3");
427 void toFloat_test_3_5()
429 toFloat_test("3.5");
431 void toFloat_test_3_0625()
433 toFloat_test("3.0625");
435 void toFloat_test_3_0625_e()
437 toFloat_test("3.0625e-4");
439 void toFloat_test_pi()
441 // value from http://www.angio.net/pi/digits/50.txt
442 toFloat_test("3.141592653589793238462643383279502884197169399375");
445 void toFloat_test_1()
447 toFloat_test("1");
449 void toFloat_test_10()
451 toFloat_test("10");
453 void toFloat_test_100()
455 toFloat_test("100");
457 void toFloat_test_1000()
459 toFloat_test("1000");
461 void toFloat_test_10000()
463 toFloat_test("10000");
465 void toFloat_test_mix()
467 toFloat_test("456789321455.123456789012");
469 void toFloat_test_1e99()
471 toFloat_test("1e99");
473 void toFloat_test_1e_n99()
475 toFloat_test("1e-9");
477 void toFloat_test_1e308()
479 toFloat_test("1e308");
482 // Change the following lines only, if you add, remove or rename
483 // member functions of the current class,
484 // because these macros are need by auto register mechanism.
486 CPPUNIT_TEST_SUITE(toFloat);
487 CPPUNIT_TEST(toFloat_selftest);
489 CPPUNIT_TEST(toFloat_test_3);
490 CPPUNIT_TEST(toFloat_test_3_5);
491 CPPUNIT_TEST(toFloat_test_3_0625);
492 CPPUNIT_TEST(toFloat_test_3_0625_e);
493 CPPUNIT_TEST(toFloat_test_pi);
494 CPPUNIT_TEST(toFloat_test_1);
495 CPPUNIT_TEST(toFloat_test_10);
496 CPPUNIT_TEST(toFloat_test_100);
497 CPPUNIT_TEST(toFloat_test_1000);
498 CPPUNIT_TEST(toFloat_test_10000);
499 CPPUNIT_TEST(toFloat_test_mix);
500 CPPUNIT_TEST(toFloat_test_1e99);
501 CPPUNIT_TEST(toFloat_test_1e_n99);
502 CPPUNIT_TEST(toFloat_test_1e308);
503 CPPUNIT_TEST_SUITE_END();
504 }; // class toFloat
506 // - lastIndexOf (tests)
507 class lastIndexOf : public CppUnit::TestFixture
510 public:
511 void lastIndexOf_oustring(OUString const& _suStr, OUString const& _suSearchStr, sal_Int32 _nExpectedResultPos)
513 // Algorithm
514 // search the string _suSearchStr (OUString) in the string _suStr.
515 // check if the _nExpectedResultPos occurs.
517 sal_Int32 nPos = _suStr.lastIndexOf(_suSearchStr);
518 CPPUNIT_ASSERT_EQUAL_MESSAGE("expected position is wrong", _nExpectedResultPos, nPos);
521 void lastIndexOf_salunicode(OUString const& _suStr, sal_Unicode _cuSearchChar, sal_Int32 _nExpectedResultPos)
523 // Algorithm
524 // search the unicode char _suSearchChar (sal_Unicode) in the string _suStr.
525 // check if the _nExpectedResultPos occurs.
527 sal_Int32 nPos = _suStr.lastIndexOf(_cuSearchChar);
528 CPPUNIT_ASSERT_EQUAL_MESSAGE("expected position is wrong", _nExpectedResultPos, nPos);
531 void lastIndexOf_oustring_offset(OUString const& _suStr, OUString const& _suSearchStr, sal_Int32 _nExpectedResultPos, sal_Int32 _nStartOffset)
533 sal_Int32 nPos = _suStr.lastIndexOf(_suSearchStr, _nStartOffset);
534 CPPUNIT_ASSERT_EQUAL_MESSAGE("expected position is wrong", _nExpectedResultPos, nPos);
537 void lastIndexOf_salunicode_offset(OUString const& _suStr, sal_Unicode _cuSearchChar, sal_Int32 _nExpectedResultPos, sal_Int32 _nStartOffset)
539 sal_Int32 nPos = _suStr.lastIndexOf(_cuSearchChar, _nStartOffset);
540 CPPUNIT_ASSERT_EQUAL_MESSAGE("expected position is wrong", _nExpectedResultPos, nPos);
543 void lastIndexOf_test_oustring_offset_001()
545 // search for sun, start at the end, found (pos==0)
546 OUString aStr("sun java system");
547 lastIndexOf_oustring_offset(aStr, "sun", 0, aStr.getLength());
550 void lastIndexOf_test_oustring_offset_002()
552 // search for sun, start at pos = 3, found (pos==0)
553 lastIndexOf_oustring_offset("sun java system", "sun", 0, 3);
556 void lastIndexOf_test_oustring_offset_003()
558 // search for sun, start at pos = 2, found (pos==-1)
559 lastIndexOf_oustring_offset("sun java system", "sun", -1, 2);
562 void lastIndexOf_test_oustring_offset_004()
564 // search for sun, start at the end, found (pos==0)
565 lastIndexOf_oustring_offset("sun java system", "sun", -1, 1);
568 void lastIndexOf_test_oustring_001()
570 // search for sun, found (pos==0)
571 lastIndexOf_oustring("sun java system", "sun", 0);
574 void lastIndexOf_test_oustring_002()
576 // search for sun, found (pos==4)
577 lastIndexOf_oustring("the sun java system", "sun", 4);
580 void lastIndexOf_test_oustring_003()
582 // search for sun, found (pos==8)
583 lastIndexOf_oustring("the sun sun java system", "sun", 8);
586 void lastIndexOf_test_oustring_004()
588 // search for sun, found (pos==8)
589 lastIndexOf_oustring("the sun sun", "sun", 8);
592 void lastIndexOf_test_oustring_005()
594 // search for sun, found (pos==4)
595 lastIndexOf_oustring("the sun su", "sun", 4);
598 void lastIndexOf_test_oustring_006()
600 // search for sun, found (pos==-1)
601 lastIndexOf_oustring("the su su", "sun", -1);
604 void lastIndexOf_test_oustring_007()
606 // search for earth, not found (-1)
607 lastIndexOf_oustring("the su su", "earth", -1);
610 void lastIndexOf_test_oustring_008()
612 // search for earth, not found (-1)
613 lastIndexOf_oustring("", "earth", -1);
616 void lastIndexOf_test_oustring_009()
618 // search for earth, not found (-1)
619 lastIndexOf_oustring("", "", -1);
623 void lastIndexOf_test_salunicode_001()
625 // search for 's', found (19)
626 sal_Unicode suChar = L's';
627 lastIndexOf_salunicode("the sun sun java system", suChar, 19);
630 void lastIndexOf_test_salunicode_002()
632 // search for 'x', not found (-1)
633 sal_Unicode suChar = L'x';
634 lastIndexOf_salunicode("the sun sun java system", suChar, -1);
637 void lastIndexOf_test_salunicode_offset_001()
639 // search for 's', start from pos last char, found (19)
640 OUString aStr("the sun sun java system");
641 sal_Unicode cuChar = L's';
642 lastIndexOf_salunicode_offset(aStr, cuChar, 19, aStr.getLength());
644 void lastIndexOf_test_salunicode_offset_002()
646 // search for 's', start pos is last occur from search behind, found (17)
647 sal_Unicode cuChar = L's';
648 lastIndexOf_salunicode_offset("the sun sun java system", cuChar, 17, 19);
650 void lastIndexOf_test_salunicode_offset_003()
652 // search for 't', start pos is 1, found (0)
653 sal_Unicode cuChar = L't';
654 lastIndexOf_salunicode_offset("the sun sun java system", cuChar, 0, 1);
657 // Change the following lines only, if you add, remove or rename
658 // member functions of the current class,
659 // because these macros are need by auto register mechanism.
661 CPPUNIT_TEST_SUITE(lastIndexOf);
662 CPPUNIT_TEST(lastIndexOf_test_oustring_001);
663 CPPUNIT_TEST(lastIndexOf_test_oustring_002);
664 CPPUNIT_TEST(lastIndexOf_test_oustring_003);
665 CPPUNIT_TEST(lastIndexOf_test_oustring_004);
666 CPPUNIT_TEST(lastIndexOf_test_oustring_005);
667 CPPUNIT_TEST(lastIndexOf_test_oustring_006);
668 CPPUNIT_TEST(lastIndexOf_test_oustring_007);
669 CPPUNIT_TEST(lastIndexOf_test_oustring_008);
670 CPPUNIT_TEST(lastIndexOf_test_oustring_009);
672 CPPUNIT_TEST(lastIndexOf_test_oustring_offset_001);
673 CPPUNIT_TEST(lastIndexOf_test_oustring_offset_002);
674 CPPUNIT_TEST(lastIndexOf_test_oustring_offset_003);
675 CPPUNIT_TEST(lastIndexOf_test_oustring_offset_004);
677 CPPUNIT_TEST(lastIndexOf_test_salunicode_001);
678 CPPUNIT_TEST(lastIndexOf_test_salunicode_002);
680 CPPUNIT_TEST(lastIndexOf_test_salunicode_offset_001);
681 CPPUNIT_TEST(lastIndexOf_test_salunicode_offset_002);
682 CPPUNIT_TEST(lastIndexOf_test_salunicode_offset_003);
684 CPPUNIT_TEST_SUITE_END();
685 }; // class lastIndexOf
687 // - getToken (tests)
688 class getToken : public CppUnit::TestFixture
691 public:
692 void getToken_000()
694 OUString suTokenStr;
696 sal_Int32 nIndex = 0;
699 suTokenStr.getToken( 0, ';', nIndex );
701 while ( nIndex >= 0 );
702 printf("Index %" SAL_PRIdINT32 "\n", nIndex);
703 // should not GPF
706 void getToken_001()
708 OUString suTokenStr("a;b");
710 sal_Int32 nIndex = 0;
712 OUString suToken = suTokenStr.getToken( 0, ';', nIndex );
713 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'a'", OUString("a"), suToken);
715 /* OUString */ suToken = suTokenStr.getToken( 0, ';', nIndex );
716 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'b'", OUString("b"), suToken);
717 CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), nIndex);
720 void getToken_002()
722 OUString suTokenStr("a;b.c");
724 sal_Int32 nIndex = 0;
726 OUString suToken = suTokenStr.getToken( 0, ';', nIndex );
727 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'a'", OUString("a"), suToken );
729 /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
730 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'b'", OUString("b"), suToken );
732 /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
733 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'c'", OUString("c"), suToken );
734 CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), nIndex);
737 void getToken_003()
739 OUString suTokenStr("a;;b");
741 sal_Int32 nIndex = 0;
743 OUString suToken = suTokenStr.getToken( 0, ';', nIndex );
744 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'a'", OUString("a"), suToken );
746 /* OUString */ suToken = suTokenStr.getToken( 0, ';', nIndex );
747 CPPUNIT_ASSERT_MESSAGE("Token should be empty", suToken.isEmpty());
749 /* OUString */ suToken = suTokenStr.getToken( 0, ';', nIndex );
750 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'b'", OUString("b"), suToken );
751 CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), nIndex);
754 void getToken_004()
756 OUString suTokenStr("longer.then.ever.");
758 sal_Int32 nIndex = 0;
760 OUString suToken = suTokenStr.getToken( 0, '.', nIndex );
761 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be 'longer'", OUString("longer"), suToken );
763 /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
764 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be 'then'", OUString("then"), suToken );
766 /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
767 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be 'ever'", OUString("ever"), suToken );
769 /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
770 CPPUNIT_ASSERT_MESSAGE("Token should be empty", suToken.isEmpty());
772 CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), nIndex);
775 void getToken_005() {
776 OUString ab("ab");
777 sal_Int32 n = 0;
778 CPPUNIT_ASSERT_EQUAL_MESSAGE(
779 "token should be 'ab'", ab, ab.getToken(0, '-', n));
780 CPPUNIT_ASSERT_EQUAL_MESSAGE("n should be -1", static_cast<sal_Int32>(-1), n);
781 CPPUNIT_ASSERT_MESSAGE(
782 "token should be empty", ab.getToken(0, '-', n).isEmpty());
785 void getToken_006()
787 OUString suTokenStr;
788 auto pTokenStr = suTokenStr.getStr();
789 sal_uInt64 n64 = reinterpret_cast<sal_uInt64>(pTokenStr) / sizeof(sal_Unicode);
790 // Point either to 0x0, or to some random address -4GiB away from this string
791 sal_Int32 n = n64 > o3tl::make_unsigned(SAL_MAX_INT32) ? -SAL_MAX_INT32
792 : -static_cast<sal_Int32>(n64);
793 suTokenStr.getToken(0, ';', n);
794 // should not GPF with negative index
797 CPPUNIT_TEST_SUITE(getToken);
798 CPPUNIT_TEST(getToken_000);
799 CPPUNIT_TEST(getToken_001);
800 CPPUNIT_TEST(getToken_002);
801 CPPUNIT_TEST(getToken_003);
802 CPPUNIT_TEST(getToken_004);
803 CPPUNIT_TEST(getToken_005);
804 CPPUNIT_TEST(getToken_006);
805 CPPUNIT_TEST_SUITE_END();
806 }; // class getToken
808 class convertToString: public CppUnit::TestFixture {
809 public:
810 void test();
812 CPPUNIT_TEST_SUITE(convertToString);
813 CPPUNIT_TEST(test);
814 CPPUNIT_TEST_SUITE_END();
817 void convertToString::test() {
818 static constexpr OUStringLiteral utf16 = u"A\u00E4a";
819 OString s;
820 CPPUNIT_ASSERT(
821 OUString(utf16).convertToString(
822 &s, RTL_TEXTENCODING_UTF7,
823 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
824 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)));
825 CPPUNIT_ASSERT_EQUAL(
826 OString(RTL_CONSTASCII_STRINGPARAM("A+AOQ-a")), s);
829 // - string construction & interning (tests)
831 class construction : public CppUnit::TestFixture
833 public:
834 void construct()
836 #ifdef RTL_INLINE_STRINGS
837 OUString aFoo( "foo" );
838 CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[0] == 'f');
839 CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[1] == 'o');
840 CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[2] == 'o');
841 CPPUNIT_ASSERT_MESSAGE("string length", aFoo.getLength() == 3);
843 OUString aBaa( "this is a very long string with a lot of long things inside it and it goes on and on and on forever etc." );
844 CPPUNIT_ASSERT_MESSAGE("string length", aBaa.getLength() == 104);
845 // Dig at the internals ... FIXME: should we have the bit-flag defines public ?
846 CPPUNIT_ASSERT_MESSAGE("string static flags", (aBaa.pData->refCount & 1<<30) != 0);
847 #endif
850 void intern()
852 // The empty string is 'static' a special case ...
853 OUString().intern();
854 OUString::intern( "",strlen(""),RTL_TEXTENCODING_ASCII_US );
856 OUString aFoo( "foo" );
857 OUString aFooIntern = aFoo.intern();
858 CPPUNIT_ASSERT_EQUAL_MESSAGE( "string contents", OUString("foo"), aFooIntern);
859 CPPUNIT_ASSERT_EQUAL_MESSAGE("string length", static_cast<sal_Int32>(3), aFooIntern.getLength());
860 // We have to dup due to no atomic 'intern' bit-set operation
861 CPPUNIT_ASSERT_MESSAGE("intern dups", aFoo.pData != aFooIntern.pData);
863 // Test interning lots of things
864 int i;
865 static const int nSequence = 4096;
866 std::unique_ptr<OUString[]> pStrs(new OUString[nSequence]);
867 for (i = 0; i < nSequence; i++)
869 pStrs[i] = OUString::number( sqrt( static_cast<double>(i) ) ).intern();
871 for (i = 0; i < nSequence; i++)
873 OUString aNew = OUString::number( sqrt( static_cast<double>(i) ) ).intern();
874 CPPUNIT_ASSERT_EQUAL_MESSAGE("double intern failed",
875 pStrs[i].pData, aNew.pData);
879 CPPUNIT_TEST_SUITE(construction);
880 CPPUNIT_TEST(construct);
881 CPPUNIT_TEST(intern);
882 CPPUNIT_TEST_SUITE_END();
885 class indexOfAscii: public CppUnit::TestFixture {
886 public:
887 void test();
889 CPPUNIT_TEST_SUITE(indexOfAscii);
890 CPPUNIT_TEST(test);
891 CPPUNIT_TEST_SUITE_END();
894 void indexOfAscii::test() {
895 CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), OUString().indexOf(""));
896 CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), OUString().lastIndexOf(""));
897 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), OUString("foo").indexOf("foo"));
898 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), OUString("foo").lastIndexOf("foo"));
899 CPPUNIT_ASSERT_EQUAL(
900 sal_Int32(2), OUString("fofoobar").indexOf("foo"));
901 CPPUNIT_ASSERT_EQUAL(
902 sal_Int32(3), OUString("foofoofob").lastIndexOf("foo"));
903 CPPUNIT_ASSERT_EQUAL(
904 sal_Int32(3), OUString("foofoobar").indexOf("foo", 1));
907 class endsWith: public CppUnit::TestFixture {
908 public:
909 void test();
911 CPPUNIT_TEST_SUITE(endsWith);
912 CPPUNIT_TEST(test);
913 CPPUNIT_TEST_SUITE_END();
916 void endsWith::test() {
917 CPPUNIT_ASSERT_EQUAL(true, OUString().endsWith(""));
918 CPPUNIT_ASSERT_EQUAL(false, OUString().endsWith("foo"));
919 CPPUNIT_ASSERT_EQUAL(true, OUString("bar").endsWith("bar"));
920 CPPUNIT_ASSERT_EQUAL(true, OUString("foobar").endsWith("bar"));
921 CPPUNIT_ASSERT_EQUAL(false, OUString("FOOBAR").endsWith("bar"));
924 class isEmpty: public CppUnit::TestFixture {
925 public:
926 void test();
928 CPPUNIT_TEST_SUITE(isEmpty);
929 CPPUNIT_TEST(test);
930 CPPUNIT_TEST_SUITE_END();
933 void isEmpty::test() {
934 OUString aString;
935 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Newly constructed string should be empty", true, aString.isEmpty() );
937 aString = "Not empty any more";
938 CPPUNIT_ASSERT_EQUAL_MESSAGE( "String should not be empty", false, aString.isEmpty() );
940 aString.clear();
941 CPPUNIT_ASSERT_EQUAL_MESSAGE( "aString.clear(), so should now be empty", true, aString.isEmpty() );
945 class createFromCodePoints: public CppUnit::TestFixture {
946 public:
947 void test();
949 CPPUNIT_TEST_SUITE(createFromCodePoints);
950 CPPUNIT_TEST(test);
951 CPPUNIT_TEST_SUITE_END();
954 void createFromCodePoints::test() {
955 CPPUNIT_ASSERT_EQUAL(
956 sal_Int32(0),
957 OUString(static_cast< sal_uInt32 const * >(nullptr), 0).getLength());
958 sal_uInt32 cp[] = { 0, 0xD800, 0xFFFF, 0x10000, 0x10FFFF };
959 // non-const, to avoid loplugin:stringliteralvar
960 OUString s(cp, SAL_N_ELEMENTS(cp));
961 CPPUNIT_ASSERT_EQUAL(sal_Int32(7), s.getLength());
962 CPPUNIT_ASSERT_EQUAL(u'\0', s[0]);
963 CPPUNIT_ASSERT_EQUAL(u'\xD800', s[1]);
964 CPPUNIT_ASSERT_EQUAL(u'\xFFFF', s[2]);
965 CPPUNIT_ASSERT_EQUAL(u'\xD800', s[3]);
966 CPPUNIT_ASSERT_EQUAL(u'\xDC00', s[4]);
967 CPPUNIT_ASSERT_EQUAL(u'\xDBFF', s[5]);
968 CPPUNIT_ASSERT_EQUAL(u'\xDFFF', s[6]);
971 class iterateCodePoints: public CppUnit::TestFixture {
972 public:
973 void testNotWellFormed();
975 CPPUNIT_TEST_SUITE(iterateCodePoints);
976 CPPUNIT_TEST(testNotWellFormed);
977 CPPUNIT_TEST_SUITE_END();
980 void iterateCodePoints::testNotWellFormed() {
981 static constexpr OUStringLiteral utf16 =
982 u"\U00010000A\U0010FFFF\xDDEF\xD9AB";
983 OUString s(utf16);
984 sal_Int32 i = 0;
985 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), s.iterateCodePoints(&i));
986 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), i);
987 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x0041), s.iterateCodePoints(&i));
988 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), i);
989 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10FFFF), s.iterateCodePoints(&i));
990 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), i);
991 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDDEF), s.iterateCodePoints(&i));
992 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), i);
993 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xD9AB), s.iterateCodePoints(&i));
994 CPPUNIT_ASSERT_EQUAL(sal_Int32(7), i);
995 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xD9AB), s.iterateCodePoints(&i, -1));
996 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), i);
997 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDDEF), s.iterateCodePoints(&i, -1));
998 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), i);
999 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10FFFF), s.iterateCodePoints(&i, -1));
1000 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), i);
1001 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x0041), s.iterateCodePoints(&i, -1));
1002 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), i);
1003 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), s.iterateCodePoints(&i, -1));
1004 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
1005 i = 1;
1006 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDC00), s.iterateCodePoints(&i, 2));
1007 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), i);
1008 i = 4;
1009 CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), s.iterateCodePoints(&i, -3));
1010 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
1013 class convertFromString: public CppUnit::TestFixture {
1014 public:
1015 void test();
1017 CPPUNIT_TEST_SUITE(convertFromString);
1018 CPPUNIT_TEST(test);
1019 CPPUNIT_TEST_SUITE_END();
1022 void convertFromString::test() {
1023 OUString t;
1024 CPPUNIT_ASSERT(
1025 !rtl_convertStringToUString(
1026 &t.pData, RTL_CONSTASCII_STRINGPARAM("\x80"), RTL_TEXTENCODING_UTF8,
1027 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
1028 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
1029 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
1030 CPPUNIT_ASSERT(
1031 !rtl_convertStringToUString(
1032 &t.pData, RTL_CONSTASCII_STRINGPARAM("\xC0"), RTL_TEXTENCODING_UTF8,
1033 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
1034 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
1035 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
1036 CPPUNIT_ASSERT(
1037 !rtl_convertStringToUString(
1038 &t.pData, RTL_CONSTASCII_STRINGPARAM("\xFF"), RTL_TEXTENCODING_UTF8,
1039 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
1040 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
1041 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
1042 CPPUNIT_ASSERT(
1043 rtl_convertStringToUString(
1044 &t.pData, RTL_CONSTASCII_STRINGPARAM("abc"), RTL_TEXTENCODING_UTF8,
1045 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
1046 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
1047 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
1048 CPPUNIT_ASSERT_EQUAL( OUString("abc"), t );
1051 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::number);
1052 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::toInt);
1053 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::toDouble);
1054 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::toFloat);
1055 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::lastIndexOf);
1056 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::getToken);
1057 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::convertToString);
1058 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::construction);
1059 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::indexOfAscii);
1060 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::endsWith);
1061 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::isEmpty);
1062 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::createFromCodePoints);
1063 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::iterateCodePoints);
1064 CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::convertFromString);
1066 } // namespace rtl_OUString
1068 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */