diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sal/qa/rtl/oustring/rtl_OUString2.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sal/qa/rtl/oustring/rtl_OUString2.cxx')
-rw-r--r-- | sal/qa/rtl/oustring/rtl_OUString2.cxx | 1068 |
1 files changed, 1068 insertions, 0 deletions
diff --git a/sal/qa/rtl/oustring/rtl_OUString2.cxx b/sal/qa/rtl/oustring/rtl_OUString2.cxx new file mode 100644 index 000000000..22e731fd1 --- /dev/null +++ b/sal/qa/rtl/oustring/rtl_OUString2.cxx @@ -0,0 +1,1068 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +// autogenerated file with codegen.pl + +#include <memory> +#include <math.h> +#include <stdio.h> + +#include <algorithm> +#include <limits> + +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/plugin/TestPlugIn.h> + +#include <config_options.h> +#include <o3tl/cppunittraitshelper.hxx> +#include <o3tl/safeint.hxx> + +#include <stringhelper.hxx> +#include <valueequal.hxx> + +namespace rtl_OUString +{ + +namespace { + +// Avoid -fsanitize=undefined warning e.g. "runtime error: value 1e+99 is +// outside the range of representable values of type 'float'" with Clang prior to +// <https://github.com/llvm/llvm-project/commit/9e52c43090f8cd980167bbd2719878ae36bcf6b5> "Treat the +// range of representable values of floating-point types as [-inf, +inf] not as [-max, +max]" +// (ENABLE_RUNTIME_OPTIMIZATIONS is an approximation for checking whether building is done without +// -fsanitize=undefined): +float doubleToFloat(double x) { +#if !defined __clang__ || __clang_major__ >= 9 || ENABLE_RUNTIME_OPTIMIZATIONS + return static_cast<float>(x); +#else + return + x < -std::numeric_limits<float>::max() + ? -std::numeric_limits<float>::infinity() + : x > std::numeric_limits<float>::max() + ? std::numeric_limits<float>::infinity() + : static_cast<float>(x); +#endif +} + +} + +class number : public CppUnit::TestFixture +{ + void number_float_test_impl(float _nValue) + { + OUString suValue(OUString::number(_nValue)); + OString sValue; + sValue <<= suValue; + printf("nFloat := %.9f sValue := %s\n", _nValue, sValue.getStr()); + + double nValueATOF = doubleToFloat(atof( sValue.getStr() )); + + bool bEqualResult = is_float_equal(_nValue, nValueATOF); + CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult); + } + + void number_float_test(float _nValue) + { + number_float_test_impl(_nValue); + + // test also the negative part. + float nNegativeValue = -_nValue; + number_float_test_impl(nNegativeValue); + } + +public: + // insert your test code here. + void number_float_test_001() + { + // this is demonstration code + // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1); + float nValue = 3.0f; + number_float_test(nValue); + } + + void number_float_test_002() + { + float nValue = 3.5f; + number_float_test(nValue); + } + + void number_float_test_003() + { + float nValue = 3.0625f; + number_float_test(nValue); + } + + void number_float_test_004() + { + float nValue = 3.502525f; + number_float_test(nValue); + } + + void number_float_test_005() + { + float nValue = 3.141592f; + number_float_test(nValue); + } + + void number_float_test_006() + { + float nValue = 3.5025255f; + number_float_test(nValue); + } + + void number_float_test_007() + { + float nValue = 3.0039062f; + number_float_test(nValue); + } + +private: + + void number_double_test_impl(double _nValue) + { + OUString suValue = OUString::number( _nValue ); + OString sValue; + sValue <<= suValue; + printf("nDouble := %.20f sValue := %s\n", _nValue, sValue.getStr()); + + double nValueATOF = atof( sValue.getStr() ); + + bool bEqualResult = is_double_equal(_nValue, nValueATOF); + CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult); + } + + void number_double_test(double _nValue) + { + number_double_test_impl(_nValue); + + // test also the negative part. + double nNegativeValue = -_nValue; + number_double_test_impl(nNegativeValue); + } +public: + + // number double + void number_double_test_001() + { + double nValue = 3.0; + number_double_test(nValue); + } + void number_double_test_002() + { + double nValue = 3.5; + number_double_test(nValue); + } + void number_double_test_003() + { + double nValue = 3.0625; + number_double_test(nValue); + } + void number_double_test_004() + { + double nValue = 3.1415926535; + number_double_test(nValue); + } + void number_double_test_005() + { + double nValue = 3.141592653589793; + number_double_test(nValue); + } + void number_double_test_006() + { + double nValue = 3.1415926535897932; + number_double_test(nValue); + } + void number_double_test_007() + { + double nValue = 3.14159265358979323; + number_double_test(nValue); + } + void number_double_test_008() + { + double nValue = 3.141592653589793238462643; + number_double_test(nValue); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(number); + CPPUNIT_TEST(number_float_test_001); + CPPUNIT_TEST(number_float_test_002); + CPPUNIT_TEST(number_float_test_003); + CPPUNIT_TEST(number_float_test_004); + CPPUNIT_TEST(number_float_test_005); + CPPUNIT_TEST(number_float_test_006); + CPPUNIT_TEST(number_float_test_007); + + CPPUNIT_TEST(number_double_test_001); + CPPUNIT_TEST(number_double_test_002); + CPPUNIT_TEST(number_double_test_003); + CPPUNIT_TEST(number_double_test_004); + CPPUNIT_TEST(number_double_test_005); + CPPUNIT_TEST(number_double_test_006); + CPPUNIT_TEST(number_double_test_007); + CPPUNIT_TEST(number_double_test_008); + CPPUNIT_TEST_SUITE_END(); +}; // class number + + class toInt: public CppUnit::TestFixture { + public: + void test() { + CPPUNIT_ASSERT_EQUAL( + static_cast< sal_Int32 >(-0x76543210), + (OUString("-76543210"). + toInt32(16))); + // @return 0 if this string represents no number or one of too large magnitude + CPPUNIT_ASSERT_EQUAL( + static_cast< sal_Int32 >(0), + (OUString("+FEDCBA98"). + toInt32(16))); + CPPUNIT_ASSERT_EQUAL( + static_cast< sal_Int64 >(-SAL_CONST_INT64(0x76543210FEDCBA98)), + (OUString( + "-76543210FEDCBA98"). + toInt64(16))); + // @return 0 if this string represents no number or one of too large magnitude + CPPUNIT_ASSERT_EQUAL( + static_cast< sal_Int64 >(SAL_CONST_INT64(0)), + (OUString( + "+FEDCBA9876543210"). + toInt64(16))); + } + + CPPUNIT_TEST_SUITE(toInt); + CPPUNIT_TEST(test); + CPPUNIT_TEST_SUITE_END(); + }; + + // - toDouble (tests) + class toDouble : public CppUnit::TestFixture + { + public: + void toDouble_test_impl(OString const& _sValue) + { + //printf("the original str is %s\n", _sValue.getStr()); + double nValueATOF = atof( _sValue.getStr() ); + //printf("original data is %e\n", nValueATOF); + OUString suValue = OUString::createFromAscii( _sValue.getStr() ); + double nValueToDouble = suValue.toDouble(); + //printf("result data is %e\n", nValueToDouble); + + bool bEqualResult = is_double_equal(nValueToDouble, nValueATOF); + CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult); + } + + void toDouble_test(OString const& _sValue) + { + toDouble_test_impl(_sValue); + + // test also the negative part. + OString sNegativValue("-"); + sNegativValue += _sValue; + toDouble_test_impl(sNegativValue); + } + + // insert your test code here. + void toDouble_selftest() + { + printf("Start selftest:\n"); + CPPUNIT_ASSERT (!is_double_equal(1.0, 1.01)); + CPPUNIT_ASSERT (!is_double_equal(1.0, 1.001)); + CPPUNIT_ASSERT (!is_double_equal(1.0, 1.0001)); + CPPUNIT_ASSERT (!is_double_equal(1.0, 1.00001)); + CPPUNIT_ASSERT (!is_double_equal(1.0, 1.000001)); + CPPUNIT_ASSERT (!is_double_equal(1.0, 1.0000001)); + CPPUNIT_ASSERT (!is_double_equal(1.0, 1.00000001)); + CPPUNIT_ASSERT (!is_double_equal(1.0, 1.000000001)); + CPPUNIT_ASSERT (!is_double_equal(1.0, 1.0000000001)); + CPPUNIT_ASSERT (!is_double_equal(1.0, 1.00000000001)); + CPPUNIT_ASSERT (!is_double_equal(1.0, 1.000000000001)); + CPPUNIT_ASSERT (!is_double_equal(1.0, 1.0000000000001)); + // we check til 15 values after comma + CPPUNIT_ASSERT (is_double_equal(1.0, 1.00000000000001)); + CPPUNIT_ASSERT (is_double_equal(1.0, 1.000000000000001)); + CPPUNIT_ASSERT (is_double_equal(1.0, 1.0000000000000001)); + printf("Selftest done.\n"); + } + + void toDouble_test_3() + { + toDouble_test("3"); + } + void toDouble_test_3_5() + { + toDouble_test("3.5"); + } + void toDouble_test_3_0625() + { + toDouble_test("3.0625"); + } + void toDouble_test_pi() + { + // value from http://www.angio.net/pi/digits/50.txt + toDouble_test("3.141592653589793238462643383279502884197169399375"); + } + + void toDouble_test_1() + { + toDouble_test("1"); + } + void toDouble_test_10() + { + toDouble_test("10"); + } + void toDouble_test_100() + { + toDouble_test("100"); + } + void toDouble_test_1000() + { + toDouble_test("1000"); + } + void toDouble_test_10000() + { + toDouble_test("10000"); + } + void toDouble_test_1e99() + { + toDouble_test("1e99"); + } + void toDouble_test_1e_n99() + { + toDouble_test("1e-99"); + } + void toDouble_test_1e308() + { + toDouble_test("1e308"); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(toDouble); + CPPUNIT_TEST(toDouble_selftest); + + CPPUNIT_TEST(toDouble_test_3); + CPPUNIT_TEST(toDouble_test_3_5); + CPPUNIT_TEST(toDouble_test_3_0625); + CPPUNIT_TEST(toDouble_test_pi); + CPPUNIT_TEST(toDouble_test_1); + CPPUNIT_TEST(toDouble_test_10); + CPPUNIT_TEST(toDouble_test_100); + CPPUNIT_TEST(toDouble_test_1000); + CPPUNIT_TEST(toDouble_test_10000); + CPPUNIT_TEST(toDouble_test_1e99); + CPPUNIT_TEST(toDouble_test_1e_n99); + CPPUNIT_TEST(toDouble_test_1e308); + CPPUNIT_TEST_SUITE_END(); + }; // class toDouble + + // - toFloat (tests) + class toFloat : public CppUnit::TestFixture + { + public: + void toFloat_test_impl(OString const& _sValue) + { + //printf("the original str is %s\n", _sValue.getStr()); + float nValueATOF = doubleToFloat(atof( _sValue.getStr() )); + //printf("the original str is %.10f\n", nValueATOF); + OUString suValue = OUString::createFromAscii( _sValue.getStr() ); + float nValueToFloat = suValue.toFloat(); + //printf("the result str is %.10f\n", nValueToFloat); + + bool bEqualResult = is_float_equal(nValueToFloat, nValueATOF); + CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult); + } + + void toFloat_test(OString const& _sValue) + { + toFloat_test_impl(_sValue); + + // test also the negative part. + OString sNegativValue("-"); + sNegativValue += _sValue; + toFloat_test_impl(sNegativValue); + } + + // insert your test code here. + void toFloat_selftest() + { + printf("Start selftest:\n"); + CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.01f)); + CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.001f)); + CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.0001f)); + CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.00001f)); + CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.000002f)); + CPPUNIT_ASSERT (is_float_equal(1.0f, 1.0000001f)); + CPPUNIT_ASSERT (is_float_equal(1.0f, 1.00000001f)); + CPPUNIT_ASSERT (is_float_equal(1.0f, 1.000000001f)); + + printf("Selftest done.\n"); + } + + void toFloat_test_3() + { + toFloat_test("3"); + } + void toFloat_test_3_5() + { + toFloat_test("3.5"); + } + void toFloat_test_3_0625() + { + toFloat_test("3.0625"); + } + void toFloat_test_3_0625_e() + { + toFloat_test("3.0625e-4"); + } + void toFloat_test_pi() + { + // value from http://www.angio.net/pi/digits/50.txt + toFloat_test("3.141592653589793238462643383279502884197169399375"); + } + + void toFloat_test_1() + { + toFloat_test("1"); + } + void toFloat_test_10() + { + toFloat_test("10"); + } + void toFloat_test_100() + { + toFloat_test("100"); + } + void toFloat_test_1000() + { + toFloat_test("1000"); + } + void toFloat_test_10000() + { + toFloat_test("10000"); + } + void toFloat_test_mix() + { + toFloat_test("456789321455.123456789012"); + } + void toFloat_test_1e99() + { + toFloat_test("1e99"); + } + void toFloat_test_1e_n99() + { + toFloat_test("1e-9"); + } + void toFloat_test_1e308() + { + toFloat_test("1e308"); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(toFloat); + CPPUNIT_TEST(toFloat_selftest); + + CPPUNIT_TEST(toFloat_test_3); + CPPUNIT_TEST(toFloat_test_3_5); + CPPUNIT_TEST(toFloat_test_3_0625); + CPPUNIT_TEST(toFloat_test_3_0625_e); + CPPUNIT_TEST(toFloat_test_pi); + CPPUNIT_TEST(toFloat_test_1); + CPPUNIT_TEST(toFloat_test_10); + CPPUNIT_TEST(toFloat_test_100); + CPPUNIT_TEST(toFloat_test_1000); + CPPUNIT_TEST(toFloat_test_10000); + CPPUNIT_TEST(toFloat_test_mix); + CPPUNIT_TEST(toFloat_test_1e99); + CPPUNIT_TEST(toFloat_test_1e_n99); + CPPUNIT_TEST(toFloat_test_1e308); + CPPUNIT_TEST_SUITE_END(); + }; // class toFloat + +// - lastIndexOf (tests) +class lastIndexOf : public CppUnit::TestFixture +{ + +public: + void lastIndexOf_oustring(OUString const& _suStr, OUString const& _suSearchStr, sal_Int32 _nExpectedResultPos) + { + // Algorithm + // search the string _suSearchStr (OUString) in the string _suStr. + // check if the _nExpectedResultPos occurs. + + sal_Int32 nPos = _suStr.lastIndexOf(_suSearchStr); + CPPUNIT_ASSERT_EQUAL_MESSAGE("expected position is wrong", _nExpectedResultPos, nPos); + } + + void lastIndexOf_salunicode(OUString const& _suStr, sal_Unicode _cuSearchChar, sal_Int32 _nExpectedResultPos) + { + // Algorithm + // search the unicode char _suSearchChar (sal_Unicode) in the string _suStr. + // check if the _nExpectedResultPos occurs. + + sal_Int32 nPos = _suStr.lastIndexOf(_cuSearchChar); + CPPUNIT_ASSERT_EQUAL_MESSAGE("expected position is wrong", _nExpectedResultPos, nPos); + } + + void lastIndexOf_oustring_offset(OUString const& _suStr, OUString const& _suSearchStr, sal_Int32 _nExpectedResultPos, sal_Int32 _nStartOffset) + { + sal_Int32 nPos = _suStr.lastIndexOf(_suSearchStr, _nStartOffset); + CPPUNIT_ASSERT_EQUAL_MESSAGE("expected position is wrong", _nExpectedResultPos, nPos); + } + + void lastIndexOf_salunicode_offset(OUString const& _suStr, sal_Unicode _cuSearchChar, sal_Int32 _nExpectedResultPos, sal_Int32 _nStartOffset) + { + sal_Int32 nPos = _suStr.lastIndexOf(_cuSearchChar, _nStartOffset); + CPPUNIT_ASSERT_EQUAL_MESSAGE("expected position is wrong", _nExpectedResultPos, nPos); + } + + void lastIndexOf_test_oustring_offset_001() + { + // search for sun, start at the end, found (pos==0) + OUString aStr("sun java system"); + lastIndexOf_oustring_offset(aStr, "sun", 0, aStr.getLength()); + } + + void lastIndexOf_test_oustring_offset_002() + { + // search for sun, start at pos = 3, found (pos==0) + lastIndexOf_oustring_offset("sun java system", "sun", 0, 3); + } + + void lastIndexOf_test_oustring_offset_003() + { + // search for sun, start at pos = 2, found (pos==-1) + lastIndexOf_oustring_offset("sun java system", "sun", -1, 2); + } + + void lastIndexOf_test_oustring_offset_004() + { + // search for sun, start at the end, found (pos==0) + lastIndexOf_oustring_offset("sun java system", "sun", -1, 1); + } + + void lastIndexOf_test_oustring_001() + { + // search for sun, found (pos==0) + lastIndexOf_oustring("sun java system", "sun", 0); + } + + void lastIndexOf_test_oustring_002() + { + // search for sun, found (pos==4) + lastIndexOf_oustring("the sun java system", "sun", 4); + } + + void lastIndexOf_test_oustring_003() + { + // search for sun, found (pos==8) + lastIndexOf_oustring("the sun sun java system", "sun", 8); + } + + void lastIndexOf_test_oustring_004() + { + // search for sun, found (pos==8) + lastIndexOf_oustring("the sun sun", "sun", 8); + } + + void lastIndexOf_test_oustring_005() + { + // search for sun, found (pos==4) + lastIndexOf_oustring("the sun su", "sun", 4); + } + + void lastIndexOf_test_oustring_006() + { + // search for sun, found (pos==-1) + lastIndexOf_oustring("the su su", "sun", -1); + } + + void lastIndexOf_test_oustring_007() + { + // search for earth, not found (-1) + lastIndexOf_oustring("the su su", "earth", -1); + } + + void lastIndexOf_test_oustring_008() + { + // search for earth, not found (-1) + lastIndexOf_oustring("", "earth", -1); + } + + void lastIndexOf_test_oustring_009() + { + // search for earth, not found (-1) + lastIndexOf_oustring("", "", -1); + + } + + void lastIndexOf_test_salunicode_001() + { + // search for 's', found (19) + sal_Unicode suChar = L's'; + lastIndexOf_salunicode("the sun sun java system", suChar, 19); + } + + void lastIndexOf_test_salunicode_002() + { + // search for 'x', not found (-1) + sal_Unicode suChar = L'x'; + lastIndexOf_salunicode("the sun sun java system", suChar, -1); + } + + void lastIndexOf_test_salunicode_offset_001() + { + // search for 's', start from pos last char, found (19) + OUString aStr("the sun sun java system"); + sal_Unicode cuChar = L's'; + lastIndexOf_salunicode_offset(aStr, cuChar, 19, aStr.getLength()); + } + void lastIndexOf_test_salunicode_offset_002() + { + // search for 's', start pos is last occur from search behind, found (17) + sal_Unicode cuChar = L's'; + lastIndexOf_salunicode_offset("the sun sun java system", cuChar, 17, 19); + } + void lastIndexOf_test_salunicode_offset_003() + { + // search for 't', start pos is 1, found (0) + sal_Unicode cuChar = L't'; + lastIndexOf_salunicode_offset("the sun sun java system", cuChar, 0, 1); + } + + // Change the following lines only, if you add, remove or rename + // member functions of the current class, + // because these macros are need by auto register mechanism. + + CPPUNIT_TEST_SUITE(lastIndexOf); + CPPUNIT_TEST(lastIndexOf_test_oustring_001); + CPPUNIT_TEST(lastIndexOf_test_oustring_002); + CPPUNIT_TEST(lastIndexOf_test_oustring_003); + CPPUNIT_TEST(lastIndexOf_test_oustring_004); + CPPUNIT_TEST(lastIndexOf_test_oustring_005); + CPPUNIT_TEST(lastIndexOf_test_oustring_006); + CPPUNIT_TEST(lastIndexOf_test_oustring_007); + CPPUNIT_TEST(lastIndexOf_test_oustring_008); + CPPUNIT_TEST(lastIndexOf_test_oustring_009); + + CPPUNIT_TEST(lastIndexOf_test_oustring_offset_001); + CPPUNIT_TEST(lastIndexOf_test_oustring_offset_002); + CPPUNIT_TEST(lastIndexOf_test_oustring_offset_003); + CPPUNIT_TEST(lastIndexOf_test_oustring_offset_004); + + CPPUNIT_TEST(lastIndexOf_test_salunicode_001); + CPPUNIT_TEST(lastIndexOf_test_salunicode_002); + + CPPUNIT_TEST(lastIndexOf_test_salunicode_offset_001); + CPPUNIT_TEST(lastIndexOf_test_salunicode_offset_002); + CPPUNIT_TEST(lastIndexOf_test_salunicode_offset_003); + + CPPUNIT_TEST_SUITE_END(); +}; // class lastIndexOf + +// - getToken (tests) +class getToken : public CppUnit::TestFixture +{ + +public: + void getToken_000() + { + OUString suTokenStr; + + sal_Int32 nIndex = 0; + do + { + suTokenStr.getToken( 0, ';', nIndex ); + } + while ( nIndex >= 0 ); + printf("Index %" SAL_PRIdINT32 "\n", nIndex); + // should not GPF + } + + void getToken_001() + { + OUString suTokenStr("a;b"); + + sal_Int32 nIndex = 0; + + OUString suToken = suTokenStr.getToken( 0, ';', nIndex ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'a'", OUString("a"), suToken); + + /* OUString */ suToken = suTokenStr.getToken( 0, ';', nIndex ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'b'", OUString("b"), suToken); + CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), nIndex); + } + + void getToken_002() + { + OUString suTokenStr("a;b.c"); + + sal_Int32 nIndex = 0; + + OUString suToken = suTokenStr.getToken( 0, ';', nIndex ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'a'", OUString("a"), suToken ); + + /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'b'", OUString("b"), suToken ); + + /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'c'", OUString("c"), suToken ); + CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), nIndex); + } + + void getToken_003() + { + OUString suTokenStr("a;;b"); + + sal_Int32 nIndex = 0; + + OUString suToken = suTokenStr.getToken( 0, ';', nIndex ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'a'", OUString("a"), suToken ); + + /* OUString */ suToken = suTokenStr.getToken( 0, ';', nIndex ); + CPPUNIT_ASSERT_MESSAGE("Token should be empty", suToken.isEmpty()); + + /* OUString */ suToken = suTokenStr.getToken( 0, ';', nIndex ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'b'", OUString("b"), suToken ); + CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), nIndex); + } + + void getToken_004() + { + OUString suTokenStr("longer.then.ever."); + + sal_Int32 nIndex = 0; + + OUString suToken = suTokenStr.getToken( 0, '.', nIndex ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be 'longer'", OUString("longer"), suToken ); + + /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be 'then'", OUString("then"), suToken ); + + /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be 'ever'", OUString("ever"), suToken ); + + /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex ); + CPPUNIT_ASSERT_MESSAGE("Token should be empty", suToken.isEmpty()); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), nIndex); + } + + void getToken_005() { + OUString ab("ab"); + sal_Int32 n = 0; + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "token should be 'ab'", ab, ab.getToken(0, '-', n)); + CPPUNIT_ASSERT_EQUAL_MESSAGE("n should be -1", static_cast<sal_Int32>(-1), n); + CPPUNIT_ASSERT_MESSAGE( + "token should be empty", ab.getToken(0, '-', n).isEmpty()); + } + + void getToken_006() + { + OUString suTokenStr; + auto pTokenStr = suTokenStr.getStr(); + sal_uInt64 n64 = reinterpret_cast<sal_uInt64>(pTokenStr) / sizeof(sal_Unicode); + // Point either to 0x0, or to some random address -4GiB away from this string + sal_Int32 n = n64 > o3tl::make_unsigned(SAL_MAX_INT32) ? -SAL_MAX_INT32 + : -static_cast<sal_Int32>(n64); + suTokenStr.getToken(0, ';', n); + // should not GPF with negative index + } + + CPPUNIT_TEST_SUITE(getToken); + CPPUNIT_TEST(getToken_000); + CPPUNIT_TEST(getToken_001); + CPPUNIT_TEST(getToken_002); + CPPUNIT_TEST(getToken_003); + CPPUNIT_TEST(getToken_004); + CPPUNIT_TEST(getToken_005); + CPPUNIT_TEST(getToken_006); + CPPUNIT_TEST_SUITE_END(); +}; // class getToken + +class convertToString: public CppUnit::TestFixture { +public: + void test(); + + CPPUNIT_TEST_SUITE(convertToString); + CPPUNIT_TEST(test); + CPPUNIT_TEST_SUITE_END(); +}; + +void convertToString::test() { + static constexpr OUStringLiteral utf16 = u"A\u00E4a"; + OString s; + CPPUNIT_ASSERT( + OUString(utf16).convertToString( + &s, RTL_TEXTENCODING_UTF7, + (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | + RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))); + CPPUNIT_ASSERT_EQUAL( + OString(RTL_CONSTASCII_STRINGPARAM("A+AOQ-a")), s); +} + +// - string construction & interning (tests) + +class construction : public CppUnit::TestFixture +{ +public: + void construct() + { +#ifdef RTL_INLINE_STRINGS + OUString aFoo( "foo" ); + CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[0] == 'f'); + CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[1] == 'o'); + CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[2] == 'o'); + CPPUNIT_ASSERT_MESSAGE("string length", aFoo.getLength() == 3); + + 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." ); + CPPUNIT_ASSERT_MESSAGE("string length", aBaa.getLength() == 104); + // Dig at the internals ... FIXME: should we have the bit-flag defines public ? + CPPUNIT_ASSERT_MESSAGE("string static flags", (aBaa.pData->refCount & 1<<30) != 0); +#endif + } + + void intern() + { + // The empty string is 'static' a special case ... + OUString().intern(); + OUString::intern( "",strlen(""),RTL_TEXTENCODING_ASCII_US ); + + OUString aFoo( "foo" ); + OUString aFooIntern = aFoo.intern(); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "string contents", OUString("foo"), aFooIntern); + CPPUNIT_ASSERT_EQUAL_MESSAGE("string length", static_cast<sal_Int32>(3), aFooIntern.getLength()); + // We have to dup due to no atomic 'intern' bit-set operation + CPPUNIT_ASSERT_MESSAGE("intern dups", aFoo.pData != aFooIntern.pData); + + // Test interning lots of things + int i; + static const int nSequence = 4096; + std::unique_ptr<OUString[]> pStrs(new OUString[nSequence]); + for (i = 0; i < nSequence; i++) + { + pStrs[i] = OUString( OUString::number( sqrt( static_cast<double>(i) ) ) ).intern(); + } + for (i = 0; i < nSequence; i++) + { + OUString aNew = OUString( OUString::number( sqrt( static_cast<double>(i) ) ) ).intern(); + CPPUNIT_ASSERT_EQUAL_MESSAGE("double intern failed", + pStrs[i].pData, aNew.pData); + } + } + + CPPUNIT_TEST_SUITE(construction); + CPPUNIT_TEST(construct); + CPPUNIT_TEST(intern); + CPPUNIT_TEST_SUITE_END(); +}; + +class indexOfAscii: public CppUnit::TestFixture { +public: + void test(); + + CPPUNIT_TEST_SUITE(indexOfAscii); + CPPUNIT_TEST(test); + CPPUNIT_TEST_SUITE_END(); +}; + +void indexOfAscii::test() { + CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), OUString().indexOf("")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), OUString().lastIndexOf("")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), OUString("foo").indexOf("foo")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), OUString("foo").lastIndexOf("foo")); + CPPUNIT_ASSERT_EQUAL( + sal_Int32(2), OUString("fofoobar").indexOf("foo")); + CPPUNIT_ASSERT_EQUAL( + sal_Int32(3), OUString("foofoofob").lastIndexOf("foo")); + CPPUNIT_ASSERT_EQUAL( + sal_Int32(3), OUString("foofoobar").indexOf("foo", 1)); +} + +class endsWith: public CppUnit::TestFixture { +public: + void test(); + + CPPUNIT_TEST_SUITE(endsWith); + CPPUNIT_TEST(test); + CPPUNIT_TEST_SUITE_END(); +}; + +void endsWith::test() { + CPPUNIT_ASSERT_EQUAL(true, OUString().endsWith("")); + CPPUNIT_ASSERT_EQUAL(false, OUString().endsWith("foo")); + CPPUNIT_ASSERT_EQUAL(true, OUString("bar").endsWith("bar")); + CPPUNIT_ASSERT_EQUAL(true, OUString("foobar").endsWith("bar")); + CPPUNIT_ASSERT_EQUAL(false, OUString("FOOBAR").endsWith("bar")); +} + +class isEmpty: public CppUnit::TestFixture { +public: + void test(); + + CPPUNIT_TEST_SUITE(isEmpty); + CPPUNIT_TEST(test); + CPPUNIT_TEST_SUITE_END(); +}; + +void isEmpty::test() { + OUString aString; + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Newly constructed string should be empty", true, aString.isEmpty() ); + + aString = "Not empty any more"; + CPPUNIT_ASSERT_EQUAL_MESSAGE( "String should not be empty", false, aString.isEmpty() ); + + aString.clear(); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "aString.clear(), so should now be empty", true, aString.isEmpty() ); +} + + +class createFromCodePoints: public CppUnit::TestFixture { +public: + void test(); + + CPPUNIT_TEST_SUITE(createFromCodePoints); + CPPUNIT_TEST(test); + CPPUNIT_TEST_SUITE_END(); +}; + +void createFromCodePoints::test() { + CPPUNIT_ASSERT_EQUAL( + sal_Int32(0), + OUString(static_cast< sal_uInt32 const * >(nullptr), 0).getLength()); + sal_uInt32 cp[] = { 0, 0xD800, 0xFFFF, 0x10000, 0x10FFFF }; + // non-const, to avoid loplugin:stringliteralvar + OUString s(cp, SAL_N_ELEMENTS(cp)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(7), s.getLength()); + CPPUNIT_ASSERT_EQUAL(u'\0', s[0]); + CPPUNIT_ASSERT_EQUAL(u'\xD800', s[1]); + CPPUNIT_ASSERT_EQUAL(u'\xFFFF', s[2]); + CPPUNIT_ASSERT_EQUAL(u'\xD800', s[3]); + CPPUNIT_ASSERT_EQUAL(u'\xDC00', s[4]); + CPPUNIT_ASSERT_EQUAL(u'\xDBFF', s[5]); + CPPUNIT_ASSERT_EQUAL(u'\xDFFF', s[6]); +} + +class iterateCodePoints: public CppUnit::TestFixture { +public: + void testNotWellFormed(); + + CPPUNIT_TEST_SUITE(iterateCodePoints); + CPPUNIT_TEST(testNotWellFormed); + CPPUNIT_TEST_SUITE_END(); +}; + +void iterateCodePoints::testNotWellFormed() { + static constexpr OUStringLiteral utf16 = + u"\U00010000A\U0010FFFF\xDDEF\xD9AB"; + OUString s(utf16); + sal_Int32 i = 0; + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), s.iterateCodePoints(&i)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), i); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x0041), s.iterateCodePoints(&i)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(3), i); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10FFFF), s.iterateCodePoints(&i)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(5), i); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDDEF), s.iterateCodePoints(&i)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(6), i); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xD9AB), s.iterateCodePoints(&i)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(7), i); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xD9AB), s.iterateCodePoints(&i, -1)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(6), i); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDDEF), s.iterateCodePoints(&i, -1)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(5), i); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10FFFF), s.iterateCodePoints(&i, -1)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(3), i); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x0041), s.iterateCodePoints(&i, -1)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), i); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), s.iterateCodePoints(&i, -1)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i); + i = 1; + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDC00), s.iterateCodePoints(&i, 2)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(3), i); + i = 4; + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), s.iterateCodePoints(&i, -3)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i); +} + +class convertFromString: public CppUnit::TestFixture { +public: + void test(); + + CPPUNIT_TEST_SUITE(convertFromString); + CPPUNIT_TEST(test); + CPPUNIT_TEST_SUITE_END(); +}; + +void convertFromString::test() { + OUString t; + CPPUNIT_ASSERT( + !rtl_convertStringToUString( + &t.pData, RTL_CONSTASCII_STRINGPARAM("\x80"), RTL_TEXTENCODING_UTF8, + (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))); + CPPUNIT_ASSERT( + !rtl_convertStringToUString( + &t.pData, RTL_CONSTASCII_STRINGPARAM("\xC0"), RTL_TEXTENCODING_UTF8, + (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))); + CPPUNIT_ASSERT( + !rtl_convertStringToUString( + &t.pData, RTL_CONSTASCII_STRINGPARAM("\xFF"), RTL_TEXTENCODING_UTF8, + (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))); + CPPUNIT_ASSERT( + rtl_convertStringToUString( + &t.pData, RTL_CONSTASCII_STRINGPARAM("abc"), RTL_TEXTENCODING_UTF8, + (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))); + CPPUNIT_ASSERT_EQUAL( OUString("abc"), t ); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::number); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::toInt); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::toDouble); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::toFloat); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::lastIndexOf); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::getToken); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::convertToString); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::construction); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::indexOfAscii); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::endsWith); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::isEmpty); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::createFromCodePoints); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::iterateCodePoints); +CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::convertFromString); + +} // namespace rtl_OUString + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |