LCOV - code coverage report
Current view: top level - libreoffice/sal/qa/rtl/strings - test_ostring_stringliterals.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 153 153 100.0 %
Date: 2012-12-17 Functions: 13 13 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10