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 : // activate the extra needed ctor
11 : #define RTL_STRING_UNITTEST
12 : bool rtl_string_unittest_const_literal;
13 : bool rtl_string_unittest_invalid_conversion;
14 : bool rtl_string_unittest_const_literal_function;
15 : bool rtl_string_unittest_non_const_literal_function;
16 :
17 : #include <sal/types.h>
18 : #include <cppunit/TestFixture.h>
19 : #include <cppunit/extensions/HelperMacros.h>
20 : #include "rtl/string.h"
21 : #include "rtl/string.hxx"
22 : #include "rtl/strbuf.hxx"
23 :
24 : namespace test { namespace ostring {
25 :
26 12 : class StringLiterals: public CppUnit::TestFixture
27 : {
28 : private:
29 : void checkCtors();
30 : void checkUsage();
31 : void checkNonConstUsage();
32 : void checkBuffer();
33 :
34 : void testcall( const char str[] );
35 :
36 : static const char bad5[];
37 : static char bad6[];
38 :
39 2 : CPPUNIT_TEST_SUITE(StringLiterals);
40 1 : CPPUNIT_TEST(checkCtors);
41 1 : CPPUNIT_TEST(checkUsage);
42 1 : CPPUNIT_TEST(checkNonConstUsage);
43 1 : CPPUNIT_TEST(checkBuffer);
44 5 : CPPUNIT_TEST_SUITE_END();
45 : };
46 :
47 : // reset the flag, call OString ctor with the given argument and return
48 : // whether the string literal ctor was used
49 : #define CONST_CTOR_USED( argument ) \
50 : ( \
51 : rtl_string_unittest_const_literal = false, \
52 : ( void ) rtl::OString( argument ), \
53 : result_tmp = rtl_string_unittest_const_literal, \
54 : rtl_string_unittest_const_literal = false, \
55 : ( void ) rtl::OStringBuffer( argument ), \
56 : rtl_string_unittest_const_literal && result_tmp )
57 :
58 1 : void test::ostring::StringLiterals::checkCtors()
59 : {
60 : bool result_tmp;
61 1 : CPPUNIT_ASSERT( CONST_CTOR_USED( "test" ));
62 1 : const char good1[] = "test";
63 1 : CPPUNIT_ASSERT( CONST_CTOR_USED( good1 ));
64 :
65 1 : CPPUNIT_ASSERT( !CONST_CTOR_USED( static_cast<const char*>("test") ));
66 1 : const char* bad1 = good1;
67 1 : CPPUNIT_ASSERT( !CONST_CTOR_USED( bad1 ));
68 1 : char bad2[] = "test";
69 1 : CPPUNIT_ASSERT( !CONST_CTOR_USED( bad2 ));
70 1 : char* bad3 = bad2;
71 1 : CPPUNIT_ASSERT( !CONST_CTOR_USED( bad3 ));
72 1 : const char* bad4[] = { "test1" };
73 1 : CPPUNIT_ASSERT( !CONST_CTOR_USED( bad4[ 0 ] ));
74 1 : testcall( good1 );
75 : #ifndef _MSC_VER
76 : // this is actually not supposed to work (see discussion in stringutils.hxx),
77 : // but gcc and clang somehow manage, so keep it used, just in case some other problem
78 : // shows up somewhen in the future
79 1 : CPPUNIT_ASSERT( !CONST_CTOR_USED( bad5 )); // size is not known here
80 1 : CPPUNIT_ASSERT( !CONST_CTOR_USED( bad6 ));
81 : #endif
82 :
83 : // This one is technically broken, since the first element is 6 characters test\0\0,
84 : // but there does not appear a way to detect this by compile time (runtime will assert()).
85 : // RTL_CONSTASCII_USTRINGPARAM() has the same flaw.
86 1 : const char bad7[][ 6 ] = { "test", "test2" };
87 : // CPPUNIT_ASSERT( CONST_CTOR_USED( bad7[ 0 ] ));
88 1 : CPPUNIT_ASSERT( CONST_CTOR_USED( bad7[ 1 ] ));
89 :
90 : // Check that contents are correct and equal to the case when const char* ctor is used.
91 1 : CPPUNIT_ASSERT( rtl::OString( static_cast<const char*>("") ) == rtl::OString( "" ));
92 1 : CPPUNIT_ASSERT( rtl::OString( static_cast<const char*>("ab") ) == rtl::OString( "ab" ));
93 :
94 : // Check that contents are correct and equal to the case when RTL_CONSTASCII_STRINGPARAM is used.
95 1 : CPPUNIT_ASSERT( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "" )) == rtl::OString( "" ));
96 1 : CPPUNIT_ASSERT( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "ab" )) == rtl::OString( "ab" ));
97 1 : }
98 :
99 : const char test::ostring::StringLiterals::bad5[] = "test";
100 : char test::ostring::StringLiterals::bad6[] = "test";
101 :
102 1 : void test::ostring::StringLiterals::testcall( const char str[] )
103 : {
104 : #ifndef _MSC_VER
105 : bool result_tmp;
106 1 : CPPUNIT_ASSERT( !CONST_CTOR_USED( str ));
107 : #else
108 : // MSVC just errors out on this for some reason, which is fine as well
109 : (void)str;
110 : #endif
111 1 : }
112 :
113 1 : void test::ostring::StringLiterals::checkUsage()
114 : {
115 : // simply check that all string literal based calls work as expected
116 : // also check that they really use string literal overload and do not convert to OString
117 1 : rtl::OString foo( "foo" );
118 2 : rtl::OString FoO( "FoO" );
119 2 : rtl::OString foobarfoo( "foobarfoo" );
120 2 : rtl::OString foobar( "foobar" );
121 2 : rtl::OString FooBaRfoo( "FooBaRfoo" );
122 2 : rtl::OString FooBaR( "FooBaR" );
123 2 : rtl::OString bar( "bar" );
124 :
125 1 : rtl_string_unittest_const_literal = false; // start checking for OString conversions
126 1 : rtl_string_unittest_non_const_literal_function = false; // and check for non-const variants
127 1 : rtl_string_unittest_const_literal_function = false;
128 1 : CPPUNIT_ASSERT_EQUAL( foo, rtl::OString() = "foo" );
129 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
130 1 : rtl_string_unittest_const_literal_function = false;
131 1 : CPPUNIT_ASSERT( FoO.equalsIgnoreAsciiCase( "fOo" ));
132 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
133 1 : rtl_string_unittest_const_literal_function = false;
134 1 : CPPUNIT_ASSERT( foobarfoo.match( "bar", 3 ));
135 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
136 1 : rtl_string_unittest_const_literal_function = false;
137 1 : CPPUNIT_ASSERT( foobar.match( "foo" ));
138 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
139 1 : rtl_string_unittest_const_literal_function = false;
140 1 : CPPUNIT_ASSERT( FooBaRfoo.matchIgnoreAsciiCase( "bAr", 3 ));
141 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
142 1 : rtl_string_unittest_const_literal_function = false;
143 1 : CPPUNIT_ASSERT( FooBaR.matchIgnoreAsciiCase( "fOo" ));
144 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
145 1 : rtl_string_unittest_const_literal_function = false;
146 1 : CPPUNIT_ASSERT( foobar.startsWith( "foo" ));
147 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
148 1 : rtl_string_unittest_const_literal_function = false;
149 1 : CPPUNIT_ASSERT( foobar.endsWith( "bar" ));
150 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
151 : // rtl_string_unittest_const_literal_function = false;
152 : // CPPUNIT_ASSERT( FooBaR.endsWithIgnoreAsciiCase( "bar" ));
153 : // CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function == true );
154 1 : rtl_string_unittest_const_literal_function = false;
155 1 : CPPUNIT_ASSERT( foo == "foo" );
156 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
157 1 : rtl_string_unittest_const_literal_function = false;
158 1 : CPPUNIT_ASSERT( "foo" == foo );
159 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
160 1 : rtl_string_unittest_const_literal_function = false;
161 1 : CPPUNIT_ASSERT( foo != "bar" );
162 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
163 1 : rtl_string_unittest_const_literal_function = false;
164 1 : CPPUNIT_ASSERT( "foo" != bar );
165 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
166 1 : rtl_string_unittest_const_literal_function = false;
167 1 : CPPUNIT_ASSERT( foobarfoo.indexOf( "foo", 1 ) == 6 );
168 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
169 : // rtl_string_unittest_const_literal_function = false;
170 : // CPPUNIT_ASSERT( foobarfoo.lastIndexOf( "foo" ) == 6 );
171 : // CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function == true );
172 : // if this is not true, some of the calls above converted to OString
173 1 : CPPUNIT_ASSERT( !rtl_string_unittest_const_literal );
174 : // if this is not true, some of the calls above used non-const variants
175 2 : CPPUNIT_ASSERT( !rtl_string_unittest_non_const_literal_function );
176 1 : }
177 :
178 1 : void test::ostring::StringLiterals::checkNonConstUsage()
179 : {
180 : // check that (non-const) char[] overloads work and do not use const char[] overloads
181 1 : rtl::OString foo( "foo" );
182 2 : rtl::OString FoO( "FoO" );
183 2 : rtl::OString foobarfoo( "foobarfoo" );
184 2 : rtl::OString foobar( "foobar" );
185 2 : rtl::OString FooBaRfoo( "FooBaRfoo" );
186 2 : rtl::OString FooBaR( "FooBaR" );
187 2 : rtl::OString bar( "bar" );
188 1 : char foo_c[] = "foo";
189 1 : char bar_c[] = "bar";
190 1 : char fOo_c[] = "fOo";
191 1 : char bAr_c[] = "bAr";
192 :
193 1 : rtl_string_unittest_const_literal = false; // start checking for OString conversions
194 1 : rtl_string_unittest_const_literal_function = false; // and check for const variants
195 1 : CPPUNIT_ASSERT_EQUAL( foo, rtl::OString() = static_cast<const char*>(foo_c) );
196 1 : CPPUNIT_ASSERT_EQUAL( foo, rtl::OString() = foo_c );
197 1 : CPPUNIT_ASSERT( FoO.equalsIgnoreAsciiCase( static_cast<const char*>(fOo_c) ));
198 1 : CPPUNIT_ASSERT( FoO.equalsIgnoreAsciiCase( fOo_c ));
199 1 : CPPUNIT_ASSERT( foobarfoo.match( static_cast<const char*>(bar_c), 3 ));
200 1 : CPPUNIT_ASSERT( foobarfoo.match( bar_c, 3 ));
201 1 : CPPUNIT_ASSERT( foobar.match( static_cast<const char*>(foo_c) ));
202 1 : CPPUNIT_ASSERT( foobar.match( foo_c ));
203 1 : CPPUNIT_ASSERT( FooBaRfoo.matchIgnoreAsciiCase( static_cast<const char*>(bAr_c), 3 ));
204 1 : CPPUNIT_ASSERT( FooBaRfoo.matchIgnoreAsciiCase( bAr_c, 3 ));
205 1 : CPPUNIT_ASSERT( FooBaR.matchIgnoreAsciiCase( static_cast<const char*>(fOo_c) ));
206 1 : CPPUNIT_ASSERT( FooBaR.matchIgnoreAsciiCase( fOo_c ));
207 1 : CPPUNIT_ASSERT( foobar.startsWith( static_cast<const char*>(foo_c) ));
208 1 : CPPUNIT_ASSERT( foobar.startsWith( foo_c ));
209 1 : CPPUNIT_ASSERT( foobar.endsWith( static_cast<const char*>(bar_c) ));
210 1 : CPPUNIT_ASSERT( foobar.endsWith( bar_c ));
211 : // CPPUNIT_ASSERT( FooBaR.endsWithIgnoreAsciiCase( (const char*)bar_c ));
212 : // CPPUNIT_ASSERT( FooBaR.endsWithIgnoreAsciiCase( bar_c ));
213 1 : CPPUNIT_ASSERT( foo == static_cast<const char*>(foo_c) );
214 1 : CPPUNIT_ASSERT( foo == foo_c );
215 1 : CPPUNIT_ASSERT( static_cast<const char*>(foo_c) == foo );
216 1 : CPPUNIT_ASSERT( foo_c == foo );
217 1 : CPPUNIT_ASSERT( foo != static_cast<const char*>(bar_c) );
218 1 : CPPUNIT_ASSERT( foo != bar_c );
219 1 : CPPUNIT_ASSERT( static_cast<const char*>(foo_c) != bar );
220 1 : CPPUNIT_ASSERT( foo_c != bar );
221 1 : CPPUNIT_ASSERT( foobarfoo.indexOf( static_cast<const char*>(foo_c), 1 ) == 6 );
222 1 : CPPUNIT_ASSERT( foobarfoo.indexOf( foo_c, 1 ) == 6 );
223 : // CPPUNIT_ASSERT( foobarfoo.lastIndexOf( (const char*)foo_c ) == 6 );
224 : // CPPUNIT_ASSERT( foobarfoo.lastIndexOf( foo_c ) == 6 );
225 : // if this is not true, some of the calls above used const variants
226 1 : CPPUNIT_ASSERT( !rtl_string_unittest_const_literal );
227 2 : CPPUNIT_ASSERT( !rtl_string_unittest_const_literal_function );
228 1 : }
229 :
230 1 : void test::ostring::StringLiterals::checkBuffer()
231 : {
232 1 : rtl::OStringBuffer buf;
233 1 : rtl_string_unittest_const_literal_function = false;
234 1 : buf.append( "foo" );
235 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
236 1 : CPPUNIT_ASSERT_EQUAL( rtl::OString( "foo" ), buf.toString());
237 1 : rtl_string_unittest_const_literal_function = false;
238 1 : buf.append( "bar" );
239 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
240 1 : CPPUNIT_ASSERT_EQUAL( rtl::OString( "foobar" ), buf.toString());
241 1 : rtl_string_unittest_const_literal_function = false;
242 1 : buf.insert( 3, "baz" );
243 1 : CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
244 1 : CPPUNIT_ASSERT_EQUAL( rtl::OString( "foobazbar" ), buf.toString());
245 :
246 2 : rtl::OString foobazbard( "foobazbard" );
247 2 : rtl::OString foodbazbard( "foodbazbard" );
248 1 : rtl_string_unittest_const_literal = false; // start checking for OString conversions
249 1 : rtl_string_unittest_const_literal_function = false; // and check for const variants
250 1 : char d[] = "d";
251 1 : CPPUNIT_ASSERT_EQUAL( foobazbard, buf.append( d ).toString());
252 1 : CPPUNIT_ASSERT_EQUAL( foodbazbard, buf.insert( 3, d ).toString() );
253 1 : CPPUNIT_ASSERT( !rtl_string_unittest_const_literal );
254 2 : CPPUNIT_ASSERT( !rtl_string_unittest_const_literal_function );
255 1 : }
256 :
257 : #undef CONST_CTOR_USED
258 :
259 : }} // namespace
260 :
261 3 : CPPUNIT_TEST_SUITE_REGISTRATION(test::ostring::StringLiterals);
262 :
263 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|