path_test.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 1,251 行 · 第 1/3 页

CPP
1,251
字号
//  path_test program  -------------------------------------------------------////  Copyright Beman Dawes 2002//  Copyright Vladimir Prus 2002//  Use, modification, and distribution is subject to the Boost Software//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at//  http://www.boost.org/LICENSE_1_0.txt)//  See library home page at http://www.boost.org/libs/filesystem//  basic_path's stem(), extension(), and replace_extension() tests are based//  on basename(), extension(), and change_extension() tests from the original//  convenience_test.cpp by Vladimir Prus.//  See deprecated_test for tests of deprecated features#define BOOST_FILESYSTEM_NO_DEPRECATED#include <boost/filesystem/operations.hpp>#include <boost/utility.hpp>#include <iostream>#include <sstream>#include <string>#include <vector>#include <cstring>#include <cassert>namespace fs = boost::filesystem;using boost::filesystem::path;using boost::next;using boost::prior;#include <boost/test/minimal.hpp>#define PATH_CHECK( a, b ) check( a, b, __LINE__ )#define DIR_CHECK( a, b ) check_dir( a, b, __LINE__ )#define CHECK_EQUAL( a,b ) check_equal( a, b, __LINE__ )namespace{  std::string platform( BOOST_PLATFORM );  int errors;  void check( const fs::path & source,              const std::string & expected, int line )  {    if ( source.string()== expected ) return;    ++errors;    std::cout << '(' << line << ") source.string(): \"" << source.string()              << "\" != expected: \"" << expected              << "\"" << std::endl;  }  void check_dir( const fs::path & source,              const std::string & expected, int line )  {    if ( source.directory_string()== expected ) return;    ++errors;    std::cout << '(' << line << ") source.directory_string(): \""              << source.directory_string()              << "\" != expected: \"" << expected              << "\"" << std::endl;  }  void check_equal( const std::string & value,              const std::string & expected, int line )  {    if ( value == expected ) return;    ++errors;    std::cout << '(' << line << ") value: \"" << value              << "\" != expected: \"" << expected              << "\"" << std::endl;  }  void exception_tests()  {    const std::string str_1("string-1");    boost::system::error_code ec( 12345, boost::system::system_category);    try { throw fs::filesystem_error( str_1, ec ); }    catch ( const fs::filesystem_error & ex )    {      //std::cout << ex.what() << "*" << std::endl;      //BOOST_CHECK( std::strcmp( ex.what(),      //  "string-1: Unknown error" ) == 0 );      BOOST_CHECK( ex.code() == ec );    }    try { throw fs::filesystem_error( str_1, "p1", "p2", ec ); }    catch ( const fs::filesystem_error & ex )    {      //std::cout << ex.what() << "*" << std::endl;                          //BOOST_CHECK( std::strcmp( ex.what(),      //  "string-1: Unknown error: \"p1\", \"p2\"" ) == 0 );      BOOST_CHECK( ex.code() == ec );      BOOST_CHECK( ex.path1().string() == "p1" );      BOOST_CHECK( ex.path2().string() == "p2" );    }  }} // unnamed namespaceint test_main( int, char*[] ){  // The choice of platform is make at runtime rather than compile-time  // so that compile errors for all platforms will be detected even though  // only the current platform is runtime tested.  platform = ( platform == "Win32" || platform == "Win64" || platform == "Cygwin" )               ? "Windows"               : "POSIX";  std::cout << "Platform is " << platform << '\n';  path p1( "fe/fi/fo/fum" );  path p2( p1 );  path p3;  BOOST_CHECK( p1.string() != p3.string() );  p3 = p2;  BOOST_CHECK( p1.string() == p3.string() );  path p4( "foobar" );  BOOST_CHECK( p4.string() == "foobar" );  p4 = p4; // self-assignment  BOOST_CHECK( p4.string() == "foobar" );  exception_tests();  // These verify various overloads don't cause compiler errors  fs::exists( p1 );  fs::exists( "foo" );  fs::exists( std::string( "foo" ) );  fs::exists( p1 / path( "foo" ) );  fs::exists( p1 / "foo" );  fs::exists( p1 / std::string( "foo" ) );  fs::exists( "foo" / p1 );  fs::exists( std::string( "foo" ) / p1 );  p4 /= path( "foo" );  p4 /= "foo";  p4 /= std::string( "foo" );  path p5;  std::string s1( "//:somestring" );  // verify deprecated names still available# ifndef BOOST_FILESYSTEM_NO_DEPRECATED  p1.branch_path();  p1.leaf();  path p_remove_leaf;  p_remove_leaf.remove_leaf();# endif# ifndef BOOST_NO_MEMBER_TEMPLATES  // check the path member templates  p5.assign( s1.begin(), s1.end() );  PATH_CHECK( p5, "somestring" );  p5 = s1;  PATH_CHECK( p5, "somestring" );  BOOST_CHECK( p4.string() == path( p4.string().begin(), p4.string().end() ).string() );  char c0 = 'a';  p5.assign( &c0, &c0 );  PATH_CHECK( p5, "" );  p5 /= "";  PATH_CHECK( p5, "" );  p5 /= "foo/bar";  PATH_CHECK( p5, "foo/bar" );  p5.append( &c0, &c0 );  PATH_CHECK( p5, "foo/bar" );  p5 /= "";  PATH_CHECK( p5, "foo/bar" );  char bf[]= "bar/foo";  p5.assign( bf, bf + sizeof(bf) );   PATH_CHECK( p5, bf );  p5.append( bf, bf + sizeof(bf) );   PATH_CHECK( p5, "bar/foo/bar/foo" );  // this code, courtesy of David Whetstone, detected a now fixed bug that  // derefereced the end iterator (assuming debug build with checked itors)  std::vector<char> v1;  p5.assign( v1.begin(), v1.end() );  std::string s2( v1.begin(), v1.end() );  PATH_CHECK( p5, s2 );  p5.assign( s1.begin(), s1.begin() + 1 );  PATH_CHECK( p5, "/" );# endif  BOOST_CHECK( p1 != p4 );  BOOST_CHECK( p1.string() == p2.string() );  BOOST_CHECK( p1.string() == p3.string() );  BOOST_CHECK( path( "foo" ).filename() == "foo" );  BOOST_CHECK( path( "foo" ).parent_path().string() == "" );  BOOST_CHECK( p1.filename() == "fum" );  BOOST_CHECK( p1.parent_path().string() == "fe/fi/fo" );  BOOST_CHECK( path( "" ).empty() == true );  BOOST_CHECK( path( "foo" ).empty() == false );  PATH_CHECK( "", "" );  PATH_CHECK( "foo", "foo" );  PATH_CHECK( "f", "f" );  PATH_CHECK( "foo/", "foo/" );  PATH_CHECK( "f/", "f/" );  PATH_CHECK( "foo/..", "foo/.." );  PATH_CHECK( "foo/../", "foo/../" );  PATH_CHECK( "foo/bar/../..", "foo/bar/../.." );  PATH_CHECK( "foo/bar/../../", "foo/bar/../../" );  PATH_CHECK( path("") / "foo", "foo" );  PATH_CHECK( path("") / "foo/", "foo/" );  PATH_CHECK( path("foo") / "", "foo" );  PATH_CHECK( path( "/" ), "/" );  PATH_CHECK( path( "/" ) / "", "/" );  PATH_CHECK( path( "/f" ), "/f" );  PATH_CHECK( "/foo", "/foo" );  PATH_CHECK( path("") / "/foo", "/foo" );  PATH_CHECK( path("/foo") / "", "/foo" );  if ( platform == "Windows" )  {    PATH_CHECK( path("c:") / "foo", "c:foo" );    PATH_CHECK( path("c:") / "/foo", "c:/foo" );  }  if ( platform == "Windows" )  {    PATH_CHECK( path("c:") / "foo", "c:foo" );    PATH_CHECK( path("c:") / "/foo", "c:/foo" );  }  PATH_CHECK( "foo/bar", "foo/bar" );  PATH_CHECK( path("foo") / path("bar"), "foo/bar" ); // path arg  PATH_CHECK( path("foo") / "bar", "foo/bar" );       // const char * arg  PATH_CHECK( path("foo") / path("woo/bar").filename(), "foo/bar" ); // const std::string & arg  PATH_CHECK( "foo" / path("bar"), "foo/bar" );  PATH_CHECK( "a/b", "a/b" );  // probe for length effects  PATH_CHECK( path("a") / "b", "a/b" );  PATH_CHECK( "..", ".." );  PATH_CHECK( path("..") / "", ".." );  PATH_CHECK( path("") / "..", ".." );  PATH_CHECK( "../..", "../.." );  PATH_CHECK( path("..") / ".." , "../.." );  PATH_CHECK( "/..", "/.." );  PATH_CHECK( path("/") / ".." , "/.." );  PATH_CHECK( "/../..", "/../.." );  PATH_CHECK( path("/..") / ".." , "/../.." );  PATH_CHECK( "../foo", "../foo" );  PATH_CHECK( path("..") / "foo" , "../foo" );  PATH_CHECK( "foo/..", "foo/.." );  PATH_CHECK( path("foo") / ".." , "foo/.." );  PATH_CHECK( path( "foo/..bar"), "foo/..bar" );  PATH_CHECK( "../f", "../f" );  PATH_CHECK( path("..") / "f" , "../f" );  PATH_CHECK( "/../f", "/../f" );  PATH_CHECK( path("/..") / "f" , "/../f" );  PATH_CHECK( "f/..", "f/.." );  PATH_CHECK( path("f") / ".." , "f/.." );  PATH_CHECK( "foo/../..", "foo/../.." );  PATH_CHECK( path("foo") / ".." / ".." , "foo/../.." );  PATH_CHECK( "foo/../../..", "foo/../../.." );  PATH_CHECK( path("foo") / ".." / ".." / ".." , "foo/../../.." );  PATH_CHECK( "foo/../bar", "foo/../bar" );  PATH_CHECK( path("foo") / ".." / "bar" , "foo/../bar" );  PATH_CHECK( "foo/bar/..", "foo/bar/.." );  PATH_CHECK( path("foo") / "bar" / ".." , "foo/bar/.." );  PATH_CHECK( "foo/bar/../..", "foo/bar/../.." );  PATH_CHECK( path("foo") / "bar" / ".." / "..", "foo/bar/../.." );  PATH_CHECK( "foo/bar/../blah", "foo/bar/../blah" );  PATH_CHECK( path("foo") / "bar" / ".." / "blah", "foo/bar/../blah" );  PATH_CHECK( "f/../b", "f/../b" );  PATH_CHECK( path("f") / ".." / "b" , "f/../b" );  PATH_CHECK( "f/b/..", "f/b/.." );  PATH_CHECK( path("f") / "b" / ".." , "f/b/.." );  PATH_CHECK( "f/b/../a", "f/b/../a" );  PATH_CHECK( path("f") / "b" / ".." / "a", "f/b/../a" );  PATH_CHECK( "foo/bar/blah/../..", "foo/bar/blah/../.." );  PATH_CHECK( path("foo") / "bar" / "blah" / ".." / "..", "foo/bar/blah/../.." );  PATH_CHECK( "foo/bar/blah/../../bletch", "foo/bar/blah/../../bletch" );  PATH_CHECK( path("foo") / "bar" / "blah" / ".." / ".." / "bletch", "foo/bar/blah/../../bletch" );  PATH_CHECK( "...", "..." );  PATH_CHECK( "....", "...." );  PATH_CHECK( "foo/...", "foo/..." );  PATH_CHECK( "abc.", "abc." );  PATH_CHECK( "abc..", "abc.." );  PATH_CHECK( "foo/abc.", "foo/abc." );  PATH_CHECK( "foo/abc..", "foo/abc.." );  PATH_CHECK( path(".abc"), ".abc" );  PATH_CHECK( "a.c", "a.c" );  PATH_CHECK( path("..abc"), "..abc" );  PATH_CHECK( "a..c", "a..c" );  PATH_CHECK( path("foo/.abc"), "foo/.abc" );  PATH_CHECK( "foo/a.c", "foo/a.c" );  PATH_CHECK( path("foo/..abc"), "foo/..abc" );  PATH_CHECK( "foo/a..c", "foo/a..c" );  PATH_CHECK( ".", "." );  PATH_CHECK( path("") / ".", "." );  PATH_CHECK( "./foo", "./foo" );  PATH_CHECK( path(".") / "foo", "./foo" );  PATH_CHECK( "./..", "./.." );  PATH_CHECK( path(".") / "..", "./.." );  PATH_CHECK( "./../foo", "./../foo" );  PATH_CHECK( "foo/.", "foo/." );  PATH_CHECK( path("foo") / ".", "foo/." );  PATH_CHECK( "../.", "../." );  PATH_CHECK( path("..") / ".", "../." );  PATH_CHECK( "./.", "./." );  PATH_CHECK( path(".") / ".", "./." );  PATH_CHECK( "././.", "././." );  PATH_CHECK( path(".") / "." / ".", "././." );  PATH_CHECK( "./foo/.", "./foo/." );  PATH_CHECK( path(".") / "foo" / ".", "./foo/." );  PATH_CHECK( "foo/./bar", "foo/./bar" );  PATH_CHECK( path("foo") / "." / "bar", "foo/./bar" );  PATH_CHECK( "foo/./.", "foo/./." );  PATH_CHECK( path("foo") / "." / ".", "foo/./." );  PATH_CHECK( "foo/./..", "foo/./.." );  PATH_CHECK( path("foo") / "." / "..", "foo/./.." );  PATH_CHECK( "foo/./../bar", "foo/./../bar" );  PATH_CHECK( "foo/../.", "foo/../." );  PATH_CHECK( path(".") / "." / "..", "././.." );  PATH_CHECK( "././..", "././.." );  PATH_CHECK( path(".") / "." / "..", "././.." );  PATH_CHECK( "./../.", "./../." );  PATH_CHECK( path(".") / ".." / ".", "./../." );  PATH_CHECK( ".././.", ".././." );  PATH_CHECK( path("..") / "." / ".", ".././." );  // iterator tests  path itr_ck = "";  path::const_iterator itr = itr_ck.begin();  BOOST_CHECK( itr == itr_ck.end() );  itr_ck = "/";  itr = itr_ck.begin();  BOOST_CHECK( *itr == std::string( "/" ) );  BOOST_CHECK( ++itr == itr_ck.end() );  BOOST_CHECK( *--itr == std::string( "/" ) );  itr_ck = "foo";  BOOST_CHECK( *itr_ck.begin() == std::string( "foo" ) );  BOOST_CHECK( next( itr_ck.begin() ) == itr_ck.end() );  BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "foo" ) );  BOOST_CHECK( prior( itr_ck.end() ) == itr_ck.begin() );  itr_ck = path( "/foo" );  BOOST_CHECK( *itr_ck.begin() == std::string( "/" ) );  BOOST_CHECK( *next( itr_ck.begin() ) == std::string( "foo" ) );  BOOST_CHECK( next(next( itr_ck.begin() )) == itr_ck.end() );  BOOST_CHECK( next( itr_ck.begin() ) == prior( itr_ck.end() ) );  BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "foo" ) );  BOOST_CHECK( *prior(prior( itr_ck.end() )) == std::string( "/" ) );  BOOST_CHECK( prior(prior( itr_ck.end() )) == itr_ck.begin() );  itr_ck = "/foo/bar";  itr = itr_ck.begin();  BOOST_CHECK( *itr == std::string( "/" ) );  BOOST_CHECK( *++itr == std::string( "foo" ) );  BOOST_CHECK( *++itr == std::string( "bar" ) );  BOOST_CHECK( ++itr == itr_ck.end() );  CHECK_EQUAL( *--itr, "bar" );  CHECK_EQUAL( *--itr, "foo" );  CHECK_EQUAL( *--itr, "/" );  itr_ck = "../f"; // previously failed due to short name bug  itr = itr_ck.begin();  CHECK_EQUAL( *itr, ".." );  CHECK_EQUAL( *++itr, "f" );  BOOST_CHECK( ++itr == itr_ck.end() );  CHECK_EQUAL( *--itr, "f" );  CHECK_EQUAL( *--itr, ".." );  // POSIX says treat "/foo/bar/" as "/foo/bar/."  itr_ck = "/foo/bar/";

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?