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 + -
显示快捷键?