1 // (C) Copyright Gennadiy Rozental 2001-2008.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
6 // See http://www.boost.org/libs/test for the library home page.
10 // Version : $Revision$
12 // Description : basic_cstring unit test
13 // *****************************************************************************
16 #pragma warning(disable: 4996)
17 #pragma warning(disable: 4267)
21 #include <boost/test/unit_test.hpp>
22 #include <boost/test/test_case_template.hpp>
24 #include <boost/test/utils/basic_cstring/basic_cstring.hpp>
25 #include <boost/test/utils/basic_cstring/compare.hpp>
26 #include <boost/test/utils/basic_cstring/io.hpp>
27 #include <boost/test/output_test_stream.hpp>
28 namespace utf = boost::unit_test;
29 namespace tt = boost::test_tools;
30 using utf::const_string;
33 #include <boost/mpl/list.hpp>
34 #include <boost/mpl/joint_view.hpp>
35 #include <boost/mpl/transform.hpp>
36 #include <boost/type_traits/add_const.hpp>
45 namespace mpl = boost::mpl;
47 #if defined(BOOST_NO_STD_WSTRING)
48 typedef mpl::list1<char const> base_const_char_types;
49 typedef mpl::list2<char,unsigned char> mutable_char_types;
51 typedef mpl::list2<char const,wchar_t const> base_const_char_types;
52 typedef mpl::list3<char,unsigned char,wchar_t> mutable_char_types;
54 typedef mpl::transform<mutable_char_types,boost::add_const<mpl::_1> >::type const_char_types;
55 typedef mpl::joint_view<const_char_types,mutable_char_types> char_types;
56 typedef mpl::list2<char,const char> io_test_types;
58 //____________________________________________________________________________//
60 template<typename CharT>
63 typedef typename boost::remove_const<CharT>::type mutable_char;
65 string_literal( char const* orig, std::size_t orig_size )
67 std::copy( orig, orig + orig_size, buff );
72 mutable_char buff[100];
75 #define LITERAL( s ) (CharT*)string_literal<CharT>( s, sizeof( s ) ).buff
76 #define LOCAL_DEF( name, s ) \
77 string_literal<CharT> BOOST_JOIN( sl, __LINE__)(s, sizeof( s )); \
78 utf::basic_cstring<CharT> name( (CharT*)(BOOST_JOIN( sl, __LINE__).buff) ) \
81 #define TEST_STRING test_string<CharT>( (CharT*)0 )
83 template<typename CharT>
85 test_string( CharT* = 0 )
87 static string_literal<CharT> l( "test_string", 11 );
92 //____________________________________________________________________________//
94 BOOST_TEST_CASE_TEMPLATE_FUNCTION( constructors_test, CharT )
97 utf::basic_cstring<CharT> bcs;
98 BOOST_CHECK_EQUAL( bcs.size(), (unsigned)0 );
99 BOOST_CHECK( bcs.is_empty() );
103 utf::basic_cstring<CharT> bcs( utf::basic_cstring<CharT>::null_str() );
104 BOOST_CHECK_EQUAL( bcs.size(), (unsigned)0 );
105 BOOST_CHECK( bcs.is_empty() );
109 utf::basic_cstring<CharT> bcs( 0 );
110 BOOST_CHECK_EQUAL( bcs.size(), (unsigned)0 );
111 BOOST_CHECK( bcs.is_empty() );
115 typedef typename utf::basic_cstring<CharT>::traits_type traits;
117 utf::basic_cstring<CharT> bcs( TEST_STRING );
118 BOOST_CHECK_EQUAL( traits::compare( bcs.begin(), TEST_STRING, bcs.size() ), 0 );
119 BOOST_CHECK_EQUAL( bcs.size(), traits::length( TEST_STRING ) );
121 utf::basic_cstring<CharT> bcs1( bcs );
122 BOOST_CHECK_EQUAL( traits::compare( bcs1.begin(), TEST_STRING, bcs1.size() ), 0 );
126 typedef typename utf::basic_cstring<CharT>::traits_type traits;
128 utf::basic_cstring<CharT> bcs( TEST_STRING, 4 );
129 BOOST_CHECK_EQUAL( traits::compare( bcs.begin(), LITERAL( "test" ), bcs.size() ), 0 );
133 typedef typename utf::basic_cstring<CharT>::traits_type traits;
135 utf::basic_cstring<CharT> bcs( TEST_STRING, TEST_STRING + 6 );
136 BOOST_CHECK_EQUAL( traits::compare( bcs.begin(), LITERAL( "test_s" ), bcs.size() ), 0 );
140 //____________________________________________________________________________//
142 BOOST_TEST_CASE_TEMPLATE_FUNCTION( constructors_std_string_test, CharT )
144 typedef typename utf::basic_cstring<CharT>::traits_type traits;
147 typename utf::basic_cstring<CharT>::std_string l( TEST_STRING );
149 utf::basic_cstring<CharT> bcs( l );
150 BOOST_CHECK_EQUAL( traits::compare( bcs.begin(), TEST_STRING, bcs.size() ), 0 );
155 //____________________________________________________________________________//
157 void array_construction_test()
159 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x600))
160 const_string bcs_array[] = { "str1", "str2" };
162 BOOST_CHECK_EQUAL( const_string::traits_type::compare( bcs_array[0].begin(), "str1", bcs_array[0].size() ), 0 );
163 BOOST_CHECK_EQUAL( const_string::traits_type::compare( bcs_array[1].begin(), "str2", bcs_array[1].size() ), 0 );
165 const_string bcs( "abc" );
166 BOOST_CHECK_EQUAL( const_string::traits_type::compare( bcs.begin(), "abc", bcs.size() ), 0 );
170 //____________________________________________________________________________//
172 BOOST_TEST_CASE_TEMPLATE_FUNCTION( data_access_test, CharT )
174 typedef typename utf::basic_cstring<CharT>::traits_type traits_type;
176 utf::basic_cstring<CharT> bcs1( TEST_STRING );
177 BOOST_CHECK_EQUAL( traits_type::compare( bcs1.begin(), TEST_STRING, bcs1.size() ), 0 );
178 BOOST_CHECK_EQUAL( traits_type::compare( bcs1.begin(), bcs1.begin(), bcs1.size() ), 0 );
180 BOOST_CHECK_EQUAL( bcs1[0], 't' );
181 BOOST_CHECK_EQUAL( bcs1[4], '_' );
182 BOOST_CHECK_EQUAL( bcs1[bcs1.size()-1], 'g' );
184 BOOST_CHECK_EQUAL( bcs1[0], bcs1.at( 0 ) );
185 BOOST_CHECK_EQUAL( bcs1[2], bcs1.at( 5 ) );
186 BOOST_CHECK_EQUAL( bcs1.at( bcs1.size() - 1 ), 'g' );
187 BOOST_CHECK_EQUAL( bcs1.at( bcs1.size() ), 0 );
188 BOOST_CHECK_EQUAL( bcs1.at( bcs1.size()+1 ), 0 );
190 BOOST_CHECK_EQUAL( utf::first_char( bcs1 ), 't' );
191 BOOST_CHECK_EQUAL( utf::last_char( bcs1 ) , 'g' );
193 BOOST_CHECK_EQUAL( utf::first_char( utf::basic_cstring<CharT>() ), 0 );
194 BOOST_CHECK_EQUAL( utf::last_char( utf::basic_cstring<CharT>() ), 0 );
197 //____________________________________________________________________________//
199 BOOST_TEST_CASE_TEMPLATE_FUNCTION( size_test, CharT )
201 utf::basic_cstring<CharT> bcs1;
203 BOOST_CHECK_EQUAL( bcs1.size(), (unsigned)0 );
204 BOOST_CHECK( bcs1.is_empty() );
207 BOOST_CHECK_EQUAL( bcs1.size(), (unsigned)11 );
210 BOOST_CHECK_EQUAL( bcs1.size(), (unsigned)0 );
211 BOOST_CHECK( bcs1.is_empty() );
213 bcs1 = utf::basic_cstring<CharT>( TEST_STRING, 4 );
214 BOOST_CHECK_EQUAL( bcs1.size(), (unsigned)4 );
217 BOOST_CHECK_EQUAL( bcs1.size(), (unsigned)4 );
220 BOOST_CHECK_EQUAL( bcs1.size(), (unsigned)3 );
223 //____________________________________________________________________________//
225 BOOST_TEST_CASE_TEMPLATE_FUNCTION( asignment_test, CharT )
227 typedef typename utf::basic_cstring<CharT>::traits_type traits_type;
229 utf::basic_cstring<CharT> bcs1;
230 string_literal<CharT> l( "test", 4 );
233 BOOST_CHECK_EQUAL( traits_type::compare( bcs1.begin(), LITERAL( "test" ), bcs1.size() ), 0 );
235 utf::basic_cstring<CharT> bcs2( TEST_STRING );
237 BOOST_CHECK_EQUAL( traits_type::compare( bcs1.begin(), TEST_STRING, bcs1.size() ), 0 );
239 bcs1.assign( l.buff );
240 BOOST_CHECK_EQUAL( traits_type::compare( bcs1.begin(), LITERAL( "test" ), bcs1.size() ), 0 );
242 bcs1.assign( l.buff+1, l.buff+3 );
243 BOOST_CHECK_EQUAL( traits_type::compare( bcs1.begin(), LITERAL( "est" ), bcs1.size() ), 0 );
245 bcs1.assign( bcs2, 4, 3 );
246 BOOST_CHECK_EQUAL( traits_type::compare( bcs1.begin(), LITERAL( "_st" ), bcs1.size() ), 0 );
249 BOOST_CHECK_EQUAL( traits_type::compare( bcs1.begin(), TEST_STRING, bcs1.size() ), 0 );
250 BOOST_CHECK_EQUAL( traits_type::compare( bcs2.begin(), LITERAL( "_st" ), bcs2.size() ), 0 );
253 //____________________________________________________________________________//
255 BOOST_TEST_CASE_TEMPLATE_FUNCTION( asignment_std_string_test, CharT )
257 typedef typename utf::basic_cstring<CharT>::traits_type traits_type;
259 utf::basic_cstring<CharT> bcs1;
260 typename utf::basic_cstring<CharT>::std_string l( TEST_STRING );
263 BOOST_CHECK_EQUAL( traits_type::compare( bcs1.begin(), TEST_STRING, bcs1.size() ), 0 );
266 BOOST_CHECK_EQUAL( traits_type::compare( bcs1.begin(), TEST_STRING, bcs1.size() ), 0 );
268 bcs1.assign( l, 1, 2 );
269 BOOST_CHECK_EQUAL( traits_type::compare( bcs1.begin(), LITERAL( "es" ), bcs1.size() ), 0 );
272 //____________________________________________________________________________//
274 BOOST_TEST_CASE_TEMPLATE_FUNCTION( comparison_test, CharT )
276 utf::basic_cstring<CharT> bcs1( TEST_STRING );
277 utf::basic_cstring<CharT> bcs2( TEST_STRING );
279 BOOST_CHECK_EQUAL( bcs1, TEST_STRING );
280 BOOST_CHECK_EQUAL( TEST_STRING, bcs1 );
281 BOOST_CHECK_EQUAL( bcs1, bcs2 );
285 BOOST_CHECK_EQUAL( bcs1, LITERAL( "test" ) );
287 BOOST_CHECK( bcs1 != TEST_STRING );
288 BOOST_CHECK( TEST_STRING != bcs1 );
289 BOOST_CHECK( bcs1 != bcs2 );
291 LOCAL_DEF( bcs3, "TeSt" );
292 BOOST_CHECK( utf::case_ins_eq( bcs1, bcs3 ) );
295 //____________________________________________________________________________//
297 BOOST_TEST_CASE_TEMPLATE_FUNCTION( comparison_std_string_test, CharT )
299 utf::basic_cstring<CharT> bcs1( TEST_STRING );
300 typename utf::basic_cstring<CharT>::std_string l( TEST_STRING );
302 BOOST_CHECK( bcs1 == l );
303 #if BOOST_WORKAROUND(BOOST_MSVC, > 1300)
304 BOOST_CHECK( l == bcs1 );
309 BOOST_CHECK( bcs1 != l );
310 #if BOOST_WORKAROUND(BOOST_MSVC, > 1300)
311 BOOST_CHECK( l != bcs1 );
315 //____________________________________________________________________________//
317 BOOST_TEST_CASE_TEMPLATE_FUNCTION( ordering_test, CharT )
319 LOCAL_DEF( bcs1, "aBcd" );
320 LOCAL_DEF( bcs2, "aBbdd" );
321 LOCAL_DEF( bcs3, "aBbde" );
322 LOCAL_DEF( bcs4, "abab" );
324 BOOST_CHECK( bcs1 < bcs2 );
325 BOOST_CHECK( bcs2 < bcs3 );
326 BOOST_CHECK( bcs1 < bcs3 );
327 BOOST_CHECK( bcs1 < bcs4 );
329 utf::case_ins_less<CharT> cil;
330 BOOST_CHECK( cil( bcs4, bcs1 ) );
333 //____________________________________________________________________________//
335 BOOST_TEST_CASE_TEMPLATE_FUNCTION( trim_test, CharT )
337 LOCAL_DEF( bcs0, "tes" );
339 bcs0.trim_right( 1 );
340 BOOST_CHECK_EQUAL( bcs0.size(), (unsigned)2 );
341 BOOST_CHECK_EQUAL( bcs0[0], 't' );
344 BOOST_CHECK_EQUAL( bcs0.size(), (unsigned)1 );
345 BOOST_CHECK_EQUAL( bcs0[0], 'e' );
348 BOOST_CHECK( bcs0.is_empty() );
351 bcs0.trim_left( 11 );
352 BOOST_CHECK( bcs0.is_empty() );
355 bcs0.trim_right( 11 );
356 BOOST_CHECK( bcs0.is_empty() );
359 bcs0.trim_right( bcs0.size() - bcs0.find( LITERAL( "t_s" ) ) - 3 );
360 BOOST_CHECK_EQUAL( bcs0, LITERAL( "test_s" ) );
362 bcs0.trim_left( bcs0.find( LITERAL( "t_s" ) ) );
363 BOOST_CHECK_EQUAL( bcs0, LITERAL( "t_s" ) );
365 LOCAL_DEF( bcs1, "abcd " );
366 LOCAL_DEF( bcs2, " abcd" );
367 LOCAL_DEF( bcs3, " abcd " );
370 BOOST_CHECK_EQUAL( bcs1, LITERAL( "abcd" ) );
373 BOOST_CHECK_EQUAL( bcs2, LITERAL( "abcd" ) );
375 bcs3.trim( LITERAL( "\"" ) );
376 BOOST_CHECK_EQUAL( bcs3, LITERAL( " abcd " ) );
379 BOOST_CHECK_EQUAL( bcs3, LITERAL( "abcd" ) );
382 BOOST_CHECK_EQUAL( bcs3, LITERAL( "abcd" ) );
385 //____________________________________________________________________________//
387 BOOST_TEST_CASE_TEMPLATE_FUNCTION( io_test, CharT )
389 utf::basic_cstring<CharT> bcs1( TEST_STRING );
390 bcs1.trim_right( 7 );
392 tt::output_test_stream ostr;
394 ostr << std::setw( 6 ) << bcs1;
395 BOOST_CHECK( ostr.is_equal( " test" ) );
397 ostr << std::setw( 3 ) << bcs1;
398 BOOST_CHECK( ostr.is_equal( "test" ) );
400 ostr << std::setw( 5 ) << std::setiosflags( std::ios::left ) << bcs1;
401 BOOST_CHECK( ostr.is_equal( "test " ) );
404 //____________________________________________________________________________//
406 BOOST_TEST_CASE_TEMPLATE_FUNCTION( find_test, CharT )
408 typedef typename utf::basic_cstring<CharT>::size_type size;
409 utf::basic_cstring<CharT> bcs1( TEST_STRING );
411 size not_found = (size)utf::basic_cstring<CharT>::npos;
413 BOOST_CHECK_EQUAL( bcs1.find( utf::basic_cstring<CharT>() ), not_found );
414 BOOST_CHECK_EQUAL( bcs1.find( LITERAL( "test" ) ), (size)0 );
415 BOOST_CHECK_EQUAL( bcs1.find( TEST_STRING ), (size)0 );
416 BOOST_CHECK_EQUAL( bcs1.find( LITERAL( "test_string " ) ), not_found );
417 BOOST_CHECK_EQUAL( bcs1.find( LITERAL( " test_string" ) ), not_found );
418 BOOST_CHECK_EQUAL( bcs1.find( LITERAL( "est" ) ), (size)1 );
419 BOOST_CHECK_EQUAL( bcs1.find( LITERAL( "t_st" ) ), (size)3 );
420 BOOST_CHECK_EQUAL( bcs1.find( LITERAL( "ing" ) ), (size)8 );
421 BOOST_CHECK_EQUAL( bcs1.find( LITERAL( "tst" ) ), not_found );
423 BOOST_CHECK_EQUAL( bcs1.rfind( utf::basic_cstring<CharT>() ), not_found );
424 BOOST_CHECK_EQUAL( bcs1.rfind( LITERAL( "test" ) ), (size)0 );
425 BOOST_CHECK_EQUAL( bcs1.rfind( TEST_STRING ), (size)0 );
426 BOOST_CHECK_EQUAL( bcs1.rfind( LITERAL( "test_string " ) ), not_found );
427 BOOST_CHECK_EQUAL( bcs1.rfind( LITERAL( " test_string" ) ), not_found );
428 BOOST_CHECK_EQUAL( bcs1.rfind( LITERAL( "est" ) ), (size)1 );
429 BOOST_CHECK_EQUAL( bcs1.rfind( LITERAL( "t_st" ) ), (size)3 );
430 BOOST_CHECK_EQUAL( bcs1.rfind( LITERAL( "ing" ) ), (size)8 );
431 BOOST_CHECK_EQUAL( bcs1.rfind( LITERAL( "tst" ) ), not_found );
434 //____________________________________________________________________________//
436 void const_conversion()
438 char arr[] = { "ABC" };
440 utf::basic_cstring<char> str1( arr );
441 utf::basic_cstring<char const> str2;
445 BOOST_CHECK_EQUAL( str1, "ABC" );
446 BOOST_CHECK_EQUAL( str2, "ABC" );
449 //____________________________________________________________________________//
452 init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
454 utf::test_suite* test= BOOST_TEST_SUITE("basic_cstring test");
456 test->add( BOOST_TEST_CASE_TEMPLATE( constructors_test, char_types ) );
457 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
458 test->add( BOOST_TEST_CASE_TEMPLATE( constructors_std_string_test, base_const_char_types ) );
459 test->add( BOOST_TEST_CASE_TEMPLATE( asignment_std_string_test, base_const_char_types ) );
460 test->add( BOOST_TEST_CASE_TEMPLATE( comparison_std_string_test, base_const_char_types ) );
462 test->add( BOOST_TEST_CASE( array_construction_test ) );
463 test->add( BOOST_TEST_CASE_TEMPLATE( data_access_test, char_types ) );
464 test->add( BOOST_TEST_CASE_TEMPLATE( size_test, char_types ) );
465 test->add( BOOST_TEST_CASE_TEMPLATE( asignment_test, char_types ) );
466 test->add( BOOST_TEST_CASE_TEMPLATE( comparison_test, char_types ) );
467 test->add( BOOST_TEST_CASE_TEMPLATE( ordering_test, char_types ) );
468 test->add( BOOST_TEST_CASE_TEMPLATE( trim_test, char_types ) );
469 test->add( BOOST_TEST_CASE_TEMPLATE( io_test, io_test_types ) );
470 test->add( BOOST_TEST_CASE_TEMPLATE( find_test, char_types ) );
471 test->add( BOOST_TEST_CASE( &const_conversion ) );