Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : : *
5 : : * The contents of this file are subject to the Mozilla Public License Version
6 : : * 1.1 (the "License"); you may not use this file except in compliance with
7 : : * the License or as specified alternatively below. You may obtain a copy of
8 : : * the License at http://www.mozilla.org/MPL/
9 : : *
10 : : * Software distributed under the License is distributed on an "AS IS" basis,
11 : : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : : * for the specific language governing rights and limitations under the
13 : : * License.
14 : : *
15 : : * Major Contributor(s):
16 : : * Copyright (C) 2012 Lubos Lunak <l.lunak@suse.cz> (initial developer)
17 : : *
18 : : * All Rights Reserved.
19 : : *
20 : : * For minor contributions see the git repository.
21 : : *
22 : : * Alternatively, the contents of this file may be used under the terms of
23 : : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
24 : : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
25 : : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
26 : : * instead of those above.
27 : : */
28 : :
29 : : // activate the extra needed ctor
30 : : #define RTL_STRING_UNITTEST
31 : : extern bool rtl_string_unittest_const_literal;
32 : : extern bool rtl_string_unittest_invalid_conversion;
33 : : extern bool rtl_string_unittest_const_literal_function;
34 : : extern bool rtl_string_unittest_non_const_literal_function;
35 : :
36 : : #include <sal/types.h>
37 : : #include <cppunit/TestFixture.h>
38 : : #include <cppunit/extensions/HelperMacros.h>
39 : : #include "rtl/string.h"
40 : : #include "rtl/ustring.hxx"
41 : : #include "rtl/ustrbuf.hxx"
42 : : #include "rtl/oustringostreaminserter.hxx"
43 : :
44 : : namespace test { namespace oustring {
45 : :
46 [ - + ]: 75 : class StringLiterals: public CppUnit::TestFixture
47 : : {
48 : : private:
49 : : void checkCtors();
50 : : void checkUsage();
51 : : void checkExtraIntArgument();
52 : : void checkNonconstChar();
53 : : void checkBuffer();
54 : :
55 : : void testcall( const char str[] );
56 : :
57 [ + - ][ + - ]: 10 : CPPUNIT_TEST_SUITE(StringLiterals);
[ + - ][ + - ]
[ # # ]
58 [ + - ][ + - ]: 5 : CPPUNIT_TEST(checkCtors);
[ + - ][ + - ]
[ + - ][ + - ]
59 [ + - ][ + - ]: 5 : CPPUNIT_TEST(checkUsage);
[ + - ][ + - ]
[ + - ][ + - ]
60 [ + - ][ + - ]: 5 : CPPUNIT_TEST(checkExtraIntArgument);
[ + - ][ + - ]
[ + - ][ + - ]
61 [ + - ][ + - ]: 5 : CPPUNIT_TEST(checkNonconstChar);
[ + - ][ + - ]
[ + - ][ + - ]
62 [ + - ][ + - ]: 5 : CPPUNIT_TEST(checkBuffer);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
63 [ + - ][ + - ]: 10 : CPPUNIT_TEST_SUITE_END();
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
64 : : };
65 : :
66 : : // reset the flag, evaluate the expression and return
67 : : // whether the string literal ctor was used (i.e. whether the conversion was valid)
68 : : #define VALID_CONVERSION( expression ) \
69 : : ( \
70 : : rtl_string_unittest_invalid_conversion = false, \
71 : : ( void ) rtl::OUString( expression ), \
72 : : ( void ) rtl::OUStringBuffer( expression ), \
73 : : !rtl_string_unittest_invalid_conversion )
74 : :
75 : 5 : void test::oustring::StringLiterals::checkCtors()
76 : : {
77 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( VALID_CONVERSION( "test" ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
78 : 5 : const char good1[] = "test";
79 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( VALID_CONVERSION( good1 ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
80 : :
81 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !VALID_CONVERSION( (const char*) "test" ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
82 : 5 : const char* bad1 = good1;
83 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !VALID_CONVERSION( bad1 ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
84 : 5 : char bad2[] = "test";
85 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !VALID_CONVERSION( bad2 ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
86 : 5 : char* bad3 = bad2;
87 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !VALID_CONVERSION( bad3 ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
88 : 5 : const char* bad4[] = { "test1" };
89 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !VALID_CONVERSION( bad4[ 0 ] ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
90 [ + - ]: 5 : testcall( good1 );
91 : :
92 : : // This one is technically broken, since the first element is 6 characters test\0\0,
93 : : // but there does not appear a way to detect this by compile time (runtime will complain).
94 : : // RTL_CONSTASCII_USTRINGPARAM() has the same flaw.
95 : 5 : const char bad5[][ 6 ] = { "test", "test2" };
96 : : // CPPUNIT_ASSERT( VALID_CONVERSION( bad5[ 0 ] ));
97 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( VALID_CONVERSION( bad5[ 1 ] ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
98 : :
99 : : // Check that contents are correct and equal to the case when RTL_CONSTASCII_USTRINGPARAM is used.
100 : : // Also check that embedded \0 is included.
101 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT_EQUAL( rtl::OUString( "" ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "" )));
[ + - ][ + - ]
[ + - ][ + - ]
102 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT_EQUAL( rtl::OUString( "\0" ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\0" )));
[ + - ][ + - ]
[ + - ][ + - ]
103 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT_EQUAL( rtl::OUString( "ab" ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ab" )));
[ + - ][ + - ]
[ + - ][ + - ]
104 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT_EQUAL( rtl::OUString( "a\0b" ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "a\0b" )));
[ + - ][ + - ]
[ + - ][ + - ]
105 : 5 : }
106 : :
107 : 5 : void test::oustring::StringLiterals::testcall( const char str[] )
108 : : {
109 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( str )));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
110 : 5 : }
111 : :
112 : 5 : void test::oustring::StringLiterals::checkUsage()
113 : : {
114 : : // simply check that all string literal based calls work as expected
115 : : // also check that they really use string literal overload and do not convert to OUString
116 : 5 : rtl::OUString foo( "foo" );
117 : 5 : rtl::OUString FoO( "FoO" );
118 : 5 : rtl::OUString foobarfoo( "foobarfoo" );
119 : 5 : rtl::OUString foobar( "foobar" );
120 : 5 : rtl::OUString FooBaRfoo( "FooBaRfoo" );
121 : 5 : rtl::OUString FooBaR( "FooBaR" );
122 : 5 : rtl::OUString bar( "bar" );
123 : 5 : rtl::OUString test( "test" );
124 : :
125 : 5 : rtl_string_unittest_const_literal = false; // start checking for OUString conversions
126 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT_EQUAL( foo, rtl::OUString() = "foo" );
[ + - ][ + - ]
[ + - ]
127 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( FoO.equalsIgnoreAsciiCase( "fOo" ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
128 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( foobarfoo.match( "bar", 3 ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
129 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( foobar.match( "foo" ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
130 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( FooBaRfoo.matchIgnoreAsciiCase( "bAr", 3 ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
131 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( FooBaR.matchIgnoreAsciiCase( "fOo" ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
132 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( foobar.endsWith( "bar" ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
133 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( FooBaR.endsWithIgnoreAsciiCase( "bar" ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
134 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( foo == "foo" );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
135 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( "foo" == foo );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
136 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( foo != "bar" );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
137 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( "foo" != bar );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
138 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( foobarfoo.indexOf( "foo", 1 ) == 6 );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
139 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( foobarfoo.lastIndexOf( "foo" ) == 6 );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
140 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( foobarfoo.replaceFirst( "foo", test ) == "testbarfoo" );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
141 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( foobarfoo.replaceFirst( "foo", "test" ) == "testbarfoo" );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
142 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( foobarfoo.replaceAll( "foo", test ) == "testbartest" );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
143 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( foobarfoo.replaceAll( "foo", "test" ) == "testbartest" );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
144 : : // if this is not true, some of the calls above converted to OUString
145 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal == false );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
146 : 5 : }
147 : :
148 : 5 : void test::oustring::StringLiterals::checkExtraIntArgument()
149 : : {
150 : : // This makes sure that using by mistake RTL_CONSTASCII_STRINGPARAM does not trigger a different
151 : : // overload, i.e. the second argument to match() in this case is the indexFrom argument,
152 : : // but with the macro it would contain the length of the string. Therefore
153 : : // match( RTL_CONSTASCII_STRINGPARAM( "bar" )) would be match( "bar", 3 ), which would be
154 : : // true when called for OUString( "foobar" ). But this should not happen because of the
155 : : // &foo[0] trick in the RTL_CONSTASCII_STRINGPARAM macro.
156 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !rtl::OUString("foobar").match( "bar" ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
157 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !rtl::OUString("foobar").match( RTL_CONSTASCII_STRINGPARAM( "bar" )));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
158 : 5 : }
159 : :
160 : 5 : void test::oustring::StringLiterals::checkNonconstChar()
161 : : { // check that non-const char[] data do not trigger string literal overloads
162 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT_EQUAL( rtl::OUString( "foobar" ), rtl::OUString( "footest" ).replaceAll( "test", "bar" ));
[ + - ][ + - ]
[ + - ]
163 : 5 : char test[] = "test";
164 : 5 : char bar[] = "bar";
165 : 5 : const char consttest[] = "test";
166 : 5 : const char constbar[] = "bar";
167 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( "footest" ).replaceAll( test, bar )));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
168 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( "footest" ).replaceAll( consttest, bar )));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
169 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !VALID_CONVERSION( rtl::OUString( "footest" ).replaceAll( test, constbar )));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
170 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( rtl::OUString( "foobar" ) == rtl::OUString( "footest" ).replaceAll( consttest, constbar ));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
171 : 5 : }
172 : :
173 : 5 : void test::oustring::StringLiterals::checkBuffer()
174 : : {
175 : 5 : rtl::OUStringBuffer buf;
176 [ + - ]: 5 : buf.append( "foo" );
177 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT_EQUAL( rtl::OUString( "foo" ), buf.toString());
[ + - ][ + - ]
[ + - ]
178 [ + - ]: 5 : buf.append( "bar" );
179 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT_EQUAL( rtl::OUString( "foobar" ), buf.toString());
[ + - ][ + - ]
[ + - ]
180 [ + - ]: 5 : buf.insert( 3, "baz" );
181 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT_EQUAL( rtl::OUString( "foobazbar" ), buf.toString());
[ + - ][ + - ]
[ + - ]
182 : 5 : char d[] = "d";
183 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !VALID_CONVERSION( buf.append( d )));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
184 [ + - ][ + - ]: 5 : CPPUNIT_ASSERT( !VALID_CONVERSION( buf.insert( 0, d )));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
185 : 5 : }
186 : :
187 : : }} // namespace
188 : :
189 [ + - ][ + - ]: 15 : CPPUNIT_TEST_SUITE_REGISTRATION(test::oustring::StringLiterals);
190 : :
191 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|