Update the tests. Unstable.

This commit is contained in:
Beman 2014-07-09 08:57:45 -04:00
parent 46ac999b2c
commit e59aecbcbe
8 changed files with 527 additions and 108 deletions

View File

@ -8,6 +8,7 @@ project
: requirements
<library>/boost/filesystem//boost_filesystem
<library>/boost/system//boost_system
<library>/boost/chrono//boost_chrono
<library>/boost/test//boost_prg_exec_monitor
<toolset>msvc:<asynch-exceptions>on
;

View File

@ -125,19 +125,21 @@ int cpp_main(int, char*[])
it = fs::recursive_directory_iterator(unique_dir);
BOOST_TEST(it->path() == unique_yy);
BOOST_TEST(it.level() == 0);
BOOST_TEST(it.depth() == 0);
++it;
BOOST_TEST(it->path() == unique_yy_zz);
BOOST_TEST(it.level() == 1);
BOOST_TEST(it.depth() == 1);
it.pop();
BOOST_TEST(it->path() == unique_yya);
BOOST_TEST(it.level() == 0);
BOOST_TEST(it.depth() == 0);
it++;
BOOST_TEST(it == fs::recursive_directory_iterator());
it = fs::recursive_directory_iterator(unique_dir);
BOOST_TEST(it->path() == unique_yy);
it.no_push();
BOOST_TEST(it.recursion_pending());
it.disable_recursion_pending();
BOOST_TEST(!it.recursion_pending());
++it;
BOOST_TEST(it->path() == unique_yya);
++it;
@ -151,16 +153,16 @@ int cpp_main(int, char*[])
it = fs::recursive_directory_iterator(unique_dir);
BOOST_TEST(it->path() == unique_yy);
BOOST_TEST(it.level() == 0);
BOOST_TEST(it.depth() == 0);
++it;
BOOST_TEST(it->path() == unique_yy_zz);
BOOST_TEST(it.level() == 1);
BOOST_TEST(it.depth() == 1);
it++;
BOOST_TEST(it == fs::recursive_directory_iterator());
it = fs::recursive_directory_iterator(unique_dir);
BOOST_TEST(it->path() == unique_yy);
it.no_push();
it.disable_recursion_pending();
++it;
BOOST_TEST(it == fs::recursive_directory_iterator());

View File

@ -164,6 +164,8 @@ namespace
fs::initial_path<fs::path>();
fs::initial_path<fs::wpath>();
p = fs::initial_path();
p.file_string();
p.directory_string();
}
@ -250,5 +252,24 @@ int cpp_main(int /*argc*/, char* /*argv*/[])
// see the rationale in html docs for explanation why this works
BOOST_TEST(fs::change_extension("", ".png").string() == ".png");
// recursive_directory_iterator tests --------------------------------------//
fs::recursive_directory_iterator iter(".");
BOOST_TEST(iter.no_push_request() != iter.recursion_pending());
BOOST_TEST(iter.no_push_pending() != iter.recursion_pending());
iter.no_push();
// symlink_option
BOOST_TEST(fs::directory_options::none == fs::symlink_option::none);
BOOST_TEST(fs::directory_options::follow_directory_symlink
== fs::symlink_option::recurse);
// copy_option
BOOST_TEST(fs::copy_options::none == fs::copy_option::none);
BOOST_TEST(fs::copy_options::overwrite_if_exists
== fs::copy_option::overwrite_if_exists);
return ::boost::report_errors();
}

View File

@ -7,8 +7,14 @@
#include <locale>
#include <iostream>
#include <exception>
#include <stdexcept>
#include <cstdlib>
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_CODECVT
# include <codecvt>
#endif
using namespace std;
#ifdef _MSC_VER
@ -20,11 +26,30 @@ namespace
{
void facet_info(const locale& loc, const char* msg)
{
cout << "has_facet<std::codecvt<char, char, std::mbstate_t> >("
<< msg << ") is "
<< (has_facet<std::codecvt<char, char, std::mbstate_t> >(loc)
? "true\n"
: "false\n");
cout << "has_facet<std::codecvt<wchar_t, char, std::mbstate_t> >("
<< msg << ") is "
<< (has_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(loc)
? "true\n"
: "false\n");
#ifndef BOOST_NO_CXX11_HDR_CODECVT
cout << "has_facet<std::codecvt<char16_t, char, std::mbstate_t> >("
<< msg << ") is "
<< (has_facet<std::codecvt<char16_t, char, std::mbstate_t> >(loc)
? "true\n"
: "false\n");
#endif
#ifndef BOOST_NO_CXX11_HDR_CODECVT
cout << "has_facet<std::codecvt<char32_t, char, std::mbstate_t> >("
<< msg << ") is "
<< (has_facet<std::codecvt<char32_t, char, std::mbstate_t> >(loc)
? "true\n"
: "false\n");
#endif
}
void default_info()
@ -32,7 +57,7 @@ namespace
try
{
locale loc;
cout << "\nlocale default construction OK" << endl;
cout << "\nlocale default construction OK, name is " << loc.name() << endl;
facet_info(loc, "locale()");
}
catch (const exception& ex)
@ -46,7 +71,7 @@ namespace
try
{
locale loc("");
cout << "\nlocale(\"\") construction OK" << endl;
cout << "\nlocale(\"\") construction OK, name is " << loc.name() << endl;
facet_info(loc, "locale(\"\")");
}
catch (const exception& ex)
@ -60,7 +85,7 @@ namespace
try
{
locale loc(locale::classic());
cout << "\nlocale(locale::classic()) copy construction OK" << endl;
cout << "\nlocale(locale::classic()) copy construction OK, name is " << loc.name() << endl;
facet_info(loc, "locale::classic()");
}
catch (const exception& ex)
@ -68,6 +93,52 @@ namespace
cout << "\nlocale(locale::clasic()) copy construction threw: " << ex.what() << endl;
}
}
void codecvt_info(const locale& loc)
{
cout << "\ncodecvt conversion for locale " << loc.name() << endl;
char s[128];
wchar_t ws[128];
for (int i = 0; i < 128; ++i)
{
s[i] = char(128 + i);
ws[i] = L'\0';
}
mbstate_t state = mbstate_t(); // VC++ needs initialization
const char* from_next;
wchar_t* to_next;
codecvt<wchar_t, char, mbstate_t>::result result;
try
{
result = use_facet<codecvt<wchar_t, char, mbstate_t> >(loc).in(state, s, s+128, from_next, ws, ws+128, to_next);
}
catch (const runtime_error& x)
{
cout << "exception: " << x.what() << endl;
return;
}
if (result != codecvt<wchar_t, char, mbstate_t>::ok)
{
cout << "Oops! conversion returned " << result << endl;
return;
}
cout << hex;
for (int i = 0; i < 128; ++i)
{
cout << s[i] << ':' << (unsigned short)(ws[i]);
if (i % 8)
cout << ',';
else
cout << endl;
}
cout << endl;
}
}
int main()
@ -76,10 +147,31 @@ int main()
cout << "\nLANG environmental variable is "
<< (lang ? lang : "not present") << endl;
#ifndef BOOST_NO_CXX11_HDR_CODECVT
cout << "BOOST_NO_CXX11_HDR_CODECVT is not defined" << endl;
#else
cout << "BOOST_NO_CXX11_HDR_CODECVT is defined" << endl;
#endif
#ifndef BOOST_NO_CXX11_CHAR16_T
cout << "BOOST_NO_CXX11_CHAR16_T is not defined" << endl;
#else
cout << "BOOST_NO_CXX11_CHAR16_T is defined" << endl;
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
cout << "BOOST_NO_CXX11_CHAR32_T is not defined" << endl;
#else
cout << "BOOST_NO_CXX11_CHAR32_T is defined" << endl;
#endif
default_info();
null_string_info();
classic_info();
codecvt_info(locale());
codecvt_info(locale(""));
return 0;
}

View File

@ -17,6 +17,7 @@
# define BOOST_SYSTEM_NO_DEPRECATED
#endif
#define BOOST_CHRONO_HEADER_ONLY
#include <boost/filesystem/operations.hpp>
#include <boost/config.hpp>
@ -95,6 +96,7 @@ inline int unsetenv(const char* name)
namespace
{
fs::path initial_path = fs::current_path();
typedef int errno_t;
std::string platform(BOOST_PLATFORM);
bool report_throws = false;
@ -117,6 +119,20 @@ namespace
const fs::path temp_dir(fs::unique_path("operations-test-%%%%-%%%%-%%%%-%%%%"));
std::time_t to_time_t(fs::file_time_type ft)
# ifdef BOOST_FILESYSTEM_USE_TIME_T
{return ft;}
# else
{return boost::chrono::system_clock::to_time_t(ft);}
# endif
fs::file_time_type from_time_t(std::time_t ft)
# ifdef BOOST_FILESYSTEM_USE_TIME_T
{return ft;}
# else
{return boost::chrono::system_clock::from_time_t(ft);}
# endif
void create_file(const fs::path & ph, const std::string & contents = std::string())
{
std::ofstream f(ph.BOOST_FILESYSTEM_C_STR);
@ -165,6 +181,14 @@ namespace
return false;
}
void delay(std::time_t amt)
{
std::time_t start = std::time(0);
cout << " start delay" << endl;
while (start + amt >= std::time(0)) {}
cout << " end delay" << endl;
}
boost::system::error_category* poison_category_aux() { return 0; }
boost::system::error_category& poison_category() { return *poison_category_aux(); }
@ -231,17 +255,17 @@ namespace
std::ostream& operator<<(std::ostream& os, const fs::file_status& s)
{
if (s.type() == fs::status_error) { os << "status_error"; }
else if (s.type() == fs::file_not_found) { os << "file_not_found"; }
else if (s.type() == fs::regular_file) { os << "regular_file"; }
else if (s.type() == fs::directory_file) { os << "directory_file"; }
else if (s.type() == fs::symlink_file) { os << "symlink_file"; }
else if (s.type() == fs::block_file) { os << "block_file"; }
else if (s.type() == fs::character_file) { os << "character_file"; }
else if (s.type() == fs::fifo_file) { os << "fifo_file"; }
else if (s.type() == fs::socket_file) { os << "socket_file"; }
else if (s.type() == fs::reparse_file) { os << "reparse_file"; }
else if (s.type() == fs::type_unknown) { os << "type_unknown"; }
if (s.type() == fs::file_type::none) { os << "file_type::none"; }
else if (s.type() == fs::file_type::not_found) { os << "file_type::not_found"; }
else if (s.type() == fs::file_type::regular) { os << "file_type::regular"; }
else if (s.type() == fs::file_type::directory) { os << "file_type::directory"; }
else if (s.type() == fs::file_type::symlink) { os << "file_type::symlink"; }
else if (s.type() == fs::file_type::block) { os << "file_type::block"; }
else if (s.type() == fs::file_type::character) { os << "file_type::character"; }
else if (s.type() == fs::file_type::fifo) { os << "file_type::fifo"; }
else if (s.type() == fs::file_type::socket) { os << "file_type::socket"; }
else if (s.type() == fs::file_type::reparse_point) { os << "file_type::reparse_point"; }
else if (s.type() == fs::file_type::unknown) { os << "file_type::unknown"; }
else { os << "_detail_directory_symlink"; }
return os;
}
@ -249,11 +273,11 @@ namespace
void dump_tree(const fs::path & root)
{
cout << "dumping tree rooted at " << root << endl;
for (fs::recursive_directory_iterator it (root, fs::symlink_option::recurse);
for (fs::recursive_directory_iterator it (root, fs::directory_options::follow_directory_symlink);
it != fs::recursive_directory_iterator();
++it)
{
for (int i = 0; i <= it.level(); ++i)
for (int i = 0; i <= it.depth(); ++i)
cout << " ";
cout << it->path();
@ -600,11 +624,16 @@ namespace
int walk_tree(bool recursive)
{
int d1f1_count = 0;
// for (fs::recursive_directory_iterator it (dir, fs::directory_options::none);
for (fs::recursive_directory_iterator it (dir,
recursive ? fs::symlink_option::recurse : fs::symlink_option::no_recurse);
recursive ? fs::directory_options::follow_directory_symlink
: fs::directory_options::none);
it != fs::recursive_directory_iterator();
++it)
{
BOOST_TEST(it.options() ==
(recursive ? fs::directory_options::follow_directory_symlink
: fs::directory_options::none));
if (it->path().filename() == "d1f1")
++d1f1_count;
}
@ -621,7 +650,7 @@ namespace
// test iterator increment with error_code argument
boost::system::error_code ec;
int d1f1_count = 0;
for (fs::recursive_directory_iterator it (dir, fs::symlink_option::no_recurse);
for (fs::recursive_directory_iterator it (dir);
it != fs::recursive_directory_iterator();
it.increment(ec))
{
@ -680,7 +709,7 @@ namespace
}
else if (it->path().filename() == "dangling_symlink")
{
BOOST_TEST(it->status().type() == fs::file_not_found);
BOOST_TEST(it->status().type() == fs::file_type::not_found);
BOOST_TEST(fs::is_symlink(it->symlink_status()));
}
else if (it->path().filename() == "d1_symlink")
@ -690,7 +719,7 @@ namespace
}
else if (it->path().filename() == "dangling_directory_symlink")
{
BOOST_TEST(it->status().type() == fs::file_not_found);
BOOST_TEST(it->status().type() == fs::file_type::not_found);
BOOST_TEST(fs::is_symlink(it->symlink_status()));
}
//else
@ -1146,7 +1175,7 @@ namespace
fs::file_status s = fs::status(p);
BOOST_TEST(!fs::exists(s));
BOOST_TEST_EQ(s.type(), fs::file_not_found);
BOOST_TEST(s.type() == fs::file_type::not_found);
BOOST_TEST(fs::type_present(s));
BOOST_TEST(!fs::is_regular_file(s));
BOOST_TEST(!fs::is_directory(s));
@ -1180,7 +1209,7 @@ namespace
BOOST_TEST(ec.category() == system_category());
BOOST_TEST(!fs::exists(s));
BOOST_TEST_EQ(s.type(), fs::file_not_found);
BOOST_TEST(s.type() == fs::file_type::not_found);
BOOST_TEST(fs::type_present(s));
BOOST_TEST(!fs::is_regular_file(s));
BOOST_TEST(!fs::is_directory(s));
@ -1446,32 +1475,125 @@ namespace
fs::remove(d1 / "f2"); // remove possible residue from prior testing
BOOST_TEST(fs::exists(d1));
BOOST_TEST(!fs::exists(d1 / "f2"));
cout << " copy " << f1 << " to " << d1 / "f2" << endl;
fs::copy_file(f1, d1 / "f2");
cout << " copy complete" << endl;
// cout << " copy_file " << f1 << " to " << d1 / "f2" << endl;
BOOST_TEST(fs::copy_file(f1, d1 / "f2"));
// cout << " copy_file complete" << endl;
BOOST_TEST(fs::exists(f1));
BOOST_TEST(fs::exists(d1 / "f2"));
BOOST_TEST_EQ(fs::file_size(d1 / "f2"), 7U);
BOOST_TEST(!fs::is_directory(d1 / "f2"));
verify_file(d1 / "f2", "file-f1");
// default copy_options::none
bool copy_ex_ok = false;
try { fs::copy_file(f1, d1 / "f2"); }
try
{
BOOST_TEST(!fs::copy_file(f1, d1 / "f2"));
}
catch (const fs::filesystem_error&) { copy_ex_ok = true; }
BOOST_TEST(copy_ex_ok);
// copy_options::none
copy_ex_ok = false;
try { fs::copy_file(f1, d1 / "f2", fs::copy_option::fail_if_exists); }
try
{
BOOST_TEST(!fs::copy_file(f1, d1 / "f2", fs::copy_options::none));
}
catch (const fs::filesystem_error&) { copy_ex_ok = true; }
BOOST_TEST(copy_ex_ok);
create_file(d1 / "f2", "1234567890");
BOOST_TEST_EQ(fs::file_size(d1 / "f2"), 10U);
// copy_options::skip_existing and exists(to)
BOOST_TEST(!fs::copy_file(f1, d1 / "f2", fs::copy_options::skip_existing));
BOOST_TEST_EQ(fs::file_size(d1 / "f2"), 10U);
// copy_options::skip_existing and !exists(to)
BOOST_TEST(!fs::exists(d1 / "f3"));
BOOST_TEST(fs::copy_file(f1, d1 / "f3", fs::copy_options::skip_existing));
BOOST_TEST(fs::exists(d1 / "f3"));
BOOST_TEST_EQ(fs::file_size(d1 / "f3"), 7U);
// copy_options::overwrite_existing and exists(to)
copy_ex_ok = true;
try { fs::copy_file(f1, d1 / "f2", fs::copy_option::overwrite_if_exists); }
try
{
BOOST_TEST(fs::copy_file(f1, d1 / "f2", fs::copy_options::overwrite_existing));
}
catch (const fs::filesystem_error&) { copy_ex_ok = false; }
BOOST_TEST(copy_ex_ok);
BOOST_TEST_EQ(fs::file_size(d1 / "f2"), 7U);
verify_file(d1 / "f2", "file-f1");
// copy_options::overwrite_existing and !exists(to)
BOOST_TEST(!fs::exists(d1 / "f4"));
BOOST_TEST(fs::copy_file(f1, d1 / "f4", fs::copy_options::overwrite_existing));
BOOST_TEST(fs::exists(d1 / "f4"));
BOOST_TEST_EQ(fs::file_size(d1 / "f4"), 7U);
// copy_options::update_existing and !exists(to)
BOOST_TEST(!fs::exists(d1 / "f5"));
BOOST_TEST(fs::copy_file(f1, d1 / "f5", fs::copy_options::update_existing));
BOOST_TEST(fs::exists(d1 / "f5"));
BOOST_TEST_EQ(fs::file_size(d1 / "f5"), 7U);
// copy_options::update_existing and exists(to) and from is older
BOOST_TEST(!fs::copy_file(f1, d1 / "f5", fs::copy_options::update_existing));
BOOST_TEST_EQ(fs::file_size(d1 / "f5"), 7U);
// copy_options::update_existing and exists(to) and from is newer
delay(1);
create_file(d1 / "f5a", "12345");
BOOST_TEST(fs::copy_file(d1 / "f5a", d1 / "f5", fs::copy_options::update_existing));
BOOST_TEST_EQ(fs::file_size(d1 / "f5"), 5U);
}
// copy_tests ------------------------------------------------------------------//
void copy_tests()
{
cout << "copy_tests..." << endl;
//int regular_file_count = 0;
//int directory_count = 0;
//int logic_error_count = 0;
//for (fs::recursive_directory_iterator it (dir);
// it != fs::recursive_directory_iterator();
// ++it)
//{
// if (fs::is_regular_file(it->status()))
// ++regular_file_count;
// else if (fs::is_directory(it->status()))
// ++directory_count;
// else
// ++logic_error_count;
//}
//cout << regular_file_count << " regular_file_count \n";
//cout << directory_count << " directory_count \n";
//cout << logic_error_count << " logic_error_count \n";
fs::create_directories(dir/"dir1/dir2");
create_file(dir/"dir1/file1", "file1");
create_file(dir/"dir1/file2", "file2");
create_file(dir/"dir1/dir2/file3", "file3");
BOOST_TEST(exists(dir/"dir1/file1"));
BOOST_TEST(exists(dir/"dir1/file2"));
BOOST_TEST(exists(dir/"dir1/dir2/file3"));
fs::copy(dir/"dir1", dir/"dir3");
BOOST_TEST(exists(dir/"dir3/file1"));
BOOST_TEST(exists(dir/"dir3/file2"));
BOOST_TEST(!exists(dir/"dir3/dir2"));
BOOST_TEST(!exists(dir/"dir3/dir2/file3"));
fs::copy(dir/"dir1", dir/"dir3",
fs::copy_options::recursive | fs::copy_options::skip_existing);
BOOST_TEST(exists(dir/"dir3/file1"));
BOOST_TEST(exists(dir/"dir3/file2"));
BOOST_TEST(exists(dir/"dir3/dir2"));
BOOST_TEST(exists(dir/"dir3/dir2/file3"));
}
// symlink_status_tests -------------------------------------------------------------//
@ -1496,23 +1618,23 @@ namespace
fs::create_symlink(sym_f1, symsym_f1);
// verify all cases detected as symlinks
BOOST_TEST_EQ(fs::symlink_status(dangling_sym, ec).type(), fs::symlink_file);
BOOST_TEST_EQ(fs::symlink_status(dangling_directory_sym, ec).type(), fs::symlink_file);
BOOST_TEST_EQ(fs::symlink_status(sym_d1, ec).type(), fs::symlink_file);
BOOST_TEST_EQ(fs::symlink_status(symsym_d1, ec).type(), fs::symlink_file);
BOOST_TEST_EQ(fs::symlink_status(sym_f1, ec).type(), fs::symlink_file);
BOOST_TEST_EQ(fs::symlink_status(symsym_f1, ec).type(), fs::symlink_file);
BOOST_TEST(fs::symlink_status(dangling_sym, ec).type() == fs::file_type::symlink);
BOOST_TEST(fs::symlink_status(dangling_directory_sym, ec).type() == fs::file_type::symlink);
BOOST_TEST(fs::symlink_status(sym_d1, ec).type() == fs::file_type::symlink);
BOOST_TEST(fs::symlink_status(symsym_d1, ec).type() == fs::file_type::symlink);
BOOST_TEST(fs::symlink_status(sym_f1, ec).type() == fs::file_type::symlink);
BOOST_TEST(fs::symlink_status(symsym_f1, ec).type() == fs::file_type::symlink);
// verify all cases resolve to the (possibly recursive) symlink target
BOOST_TEST_EQ(fs::status(dangling_sym, ec).type(), fs::file_not_found);
BOOST_TEST_EQ(fs::status(dangling_directory_sym, ec).type(), fs::file_not_found);
BOOST_TEST(fs::status(dangling_sym, ec).type() == fs::file_type::not_found);
BOOST_TEST(fs::status(dangling_directory_sym, ec).type() == fs::file_type::not_found);
BOOST_TEST_EQ(fs::status(sym_d1, ec).type(), fs::directory_file);
BOOST_TEST_EQ(fs::status(sym_d1 / "d1f1", ec).type(), fs::regular_file);
BOOST_TEST_EQ(fs::status(symsym_d1, ec).type(), fs::directory_file);
BOOST_TEST_EQ(fs::status(symsym_d1 / "d1f1", ec).type(), fs::regular_file);
BOOST_TEST_EQ(fs::status(sym_f1, ec).type(), fs::regular_file);
BOOST_TEST_EQ(fs::status(symsym_f1, ec).type(), fs::regular_file);
BOOST_TEST(fs::status(sym_d1, ec).type() == fs::file_type::directory);
BOOST_TEST(fs::status(sym_d1 / "d1f1", ec).type() == fs::file_type::regular);
BOOST_TEST(fs::status(symsym_d1, ec).type() == fs::file_type::directory);
BOOST_TEST(fs::status(symsym_d1 / "d1f1", ec).type() == fs::file_type::regular);
BOOST_TEST(fs::status(sym_f1, ec).type() == fs::file_type::regular);
BOOST_TEST(fs::status(symsym_f1, ec).type() == fs::file_type::regular);
#ifdef BOOST_WINDOWS_API
@ -1587,7 +1709,7 @@ namespace
// others (NTFS) report it as UTC. The C standard does not specify
// if time_t is local or UTC.
std::time_t ft = fs::last_write_time(f1);
std::time_t ft = to_time_t(fs::last_write_time(f1));
cout << "\n UTC last_write_time() for a file just created is "
<< std::asctime(std::gmtime(&ft)) << endl;
@ -1595,15 +1717,15 @@ namespace
cout << "\n Year is " << tmp->tm_year << endl;
--tmp->tm_year;
cout << " Change year to " << tmp->tm_year << endl;
fs::last_write_time(f1, std::mktime(tmp));
std::time_t ft2 = fs::last_write_time(f1);
fs::last_write_time(f1, from_time_t(std::mktime(tmp)));
std::time_t ft2 = to_time_t(fs::last_write_time(f1));
cout << " last_write_time() for the file is now "
<< std::asctime(std::gmtime(&ft2)) << endl;
BOOST_TEST(ft != fs::last_write_time(f1));
BOOST_TEST(ft != to_time_t(fs::last_write_time(f1)));
cout << "\n Reset to current time" << endl;
fs::last_write_time(f1, ft);
double time_diff = std::difftime(ft, fs::last_write_time(f1));
fs::last_write_time(f1, from_time_t(ft));
double time_diff = std::difftime(ft, to_time_t(fs::last_write_time(f1)));
cout
<< " original last_write_time() - current last_write_time() is "
<< time_diff << " seconds" << endl;
@ -1634,20 +1756,20 @@ namespace
&& dir.string()[1] == ':'); // verify path includes drive
BOOST_TEST(fs::system_complete("").empty());
BOOST_TEST(fs::system_complete("/") == fs::initial_path().root_path());
BOOST_TEST(fs::system_complete("/") == initial_path.root_path());
BOOST_TEST(fs::system_complete("foo")
== fs::initial_path() / "foo");
== initial_path / "foo");
fs::path p1(fs::system_complete("/foo"));
BOOST_TEST_EQ(p1.string().size(), 6U); // this failed during v3 development due to bug
std::string s1(p1.string() );
std::string s2(fs::initial_path().root_path().string()+"foo");
std::string s2(initial_path.root_path().string()+"foo");
BOOST_TEST_EQ(s1, s2);
BOOST_TEST(fs::system_complete(fs::path(fs::initial_path().root_name()))
== fs::initial_path());
BOOST_TEST(fs::system_complete(fs::path(fs::initial_path().root_name().string()
+ "foo")).string() == fs::initial_path() / "foo");
BOOST_TEST(fs::system_complete(fs::path(initial_path.root_name()))
== initial_path);
BOOST_TEST(fs::system_complete(fs::path(initial_path.root_name().string()
+ "foo")).string() == initial_path / "foo");
BOOST_TEST(fs::system_complete(fs::path("c:/")).generic_string()
== "c:/");
BOOST_TEST(fs::system_complete(fs::path("c:/foo")).generic_string()
@ -1660,12 +1782,12 @@ namespace
{
cout << "POSIX specific tests..." << endl;
BOOST_TEST(fs::system_complete("").empty());
BOOST_TEST(fs::initial_path().root_path().string() == "/");
BOOST_TEST(initial_path.root_path().string() == "/");
BOOST_TEST(fs::system_complete("/").string() == "/");
BOOST_TEST(fs::system_complete("foo").string()
== fs::initial_path().string()+"/foo");
== initial_path.string()+"/foo");
BOOST_TEST(fs::system_complete("/foo").string()
== fs::initial_path().root_path().string()+"foo");
== initial_path.root_path().string()+"foo");
} // POSIX
}
@ -1676,12 +1798,12 @@ namespace
cout << "initial_tests..." << endl;
cout << " current_path().string() is\n \""
<< fs::initial_path().string()
<< fs::current_path().string()
<< "\"\n\n";
BOOST_TEST(fs::initial_path() == fs::current_path());
BOOST_TEST(fs::initial_path().is_absolute());
BOOST_TEST(initial_path == fs::current_path());
BOOST_TEST(initial_path.is_absolute());
BOOST_TEST(fs::current_path().is_absolute());
BOOST_TEST(fs::initial_path().string()
BOOST_TEST(initial_path.string()
== fs::current_path().string());
}
@ -1789,7 +1911,7 @@ namespace
BOOST_TEST(!exists(ph));
}
fs::path test_temp_dir = fs::initial_path();
fs::path test_temp_dir = initial_path;
#if defined BOOST_POSIX_API
{
@ -1942,7 +2064,7 @@ int cpp_main(int argc, char* argv[])
# endif
cout << "API is " << platform << endl;
dir = fs::initial_path() / temp_dir;
dir = initial_path / temp_dir;
if (fs::exists(dir))
{
@ -2001,6 +2123,7 @@ int cpp_main(int argc, char* argv[])
copy_symlink_tests(f1, d1);
canonical_symlink_tests();
}
copy_tests();
iterator_status_tests(); // lots of cases by now, so a good time to test
// dump_tree(dir);
recursive_directory_iterator_tests();
@ -2021,12 +2144,18 @@ int cpp_main(int argc, char* argv[])
if (cleanup)
{
cout << "post-test removal of " << dir << endl;
BOOST_TEST(fs::remove_all(dir) != 0);
boost::uintmax_t removed = fs::remove_all(dir);
cout << " removed " << removed << " files, including directories" << endl;
BOOST_TEST(removed != 0);
// above was added just to simplify testing, but it ended up detecting
// a bug (failure to close an internal search handle).
cout << "post-test removal complete" << endl;
// The following is failing itermittently with a permissions error. The error
// goes away if recursive_directory_iterator_tests() is not run, but directory
// search handles seem to be closed properly. Very perplexing. 8/8/2012.
BOOST_TEST(!fs::exists(dir));
BOOST_TEST(fs::remove_all(dir) == 0);
cout << "post-test removal complete" << endl;
}
cout << "returning from main()" << endl;

View File

@ -24,6 +24,7 @@
# define BOOST_SYSTEM_NO_DEPRECATED
#endif
#define BOOST_CHRONO_HEADER_ONLY
#include <boost/filesystem.hpp> // make sure filesystem.hpp works
#include <boost/config.hpp>
@ -93,7 +94,7 @@ namespace
CHECK(file_size("no-such-file", ec) == static_cast<boost::uintmax_t>(-1));
CHECK(ec == errc::no_such_file_or_directory);
CHECK(status("no-such-file") == file_status(file_not_found, no_perms));
CHECK(status("no-such-file") == file_status(file_type::not_found, no_perms));
CHECK(exists("/"));
CHECK(is_directory("/"));
@ -112,6 +113,10 @@ namespace
CHECK(!is_regular_file("/"));
CHECK(!boost::filesystem::is_empty("/"));
CHECK(!is_other("/"));
CHECK(!is_block_file("/"));
CHECK(!is_character_file("/"));
CHECK(!is_fifo("/"));
CHECK(!is_socket("/"));
}
// directory_iterator_test -----------------------------------------------//
@ -256,8 +261,8 @@ namespace
CHECK(equivalent("/", "/"));
CHECK(!equivalent("/", "."));
std::time_t ft = last_write_time(".");
ft = -1;
file_time_type ft = last_write_time(".");
// ft = -1;
last_write_time(".", ft, ec);
}
@ -268,11 +273,11 @@ namespace
cout << "directory_entry test..." << endl;
directory_entry de("foo.bar",
file_status(regular_file, owner_all), file_status(directory_file, group_all));
file_status(file_type::regular, owner_all), file_status(file_type::directory, group_all));
CHECK(de.path() == "foo.bar");
CHECK(de.status() == file_status(regular_file, owner_all));
CHECK(de.symlink_status() == file_status(directory_file, group_all));
CHECK(de.status() == file_status(file_type::regular, owner_all));
CHECK(de.symlink_status() == file_status(file_type::directory, group_all));
CHECK(de < directory_entry("goo.bar"));
CHECK(de == directory_entry("foo.bar"));
CHECK(de != directory_entry("goo.bar"));

View File

@ -597,10 +597,47 @@ namespace
BOOST_TEST(!(as < acs));
BOOST_TEST(!(acs < as));
// verify compare is actually lexicographical
// character set reality check before lexicographical tests
BOOST_TEST(std::string("a.b") < std::string("a/b"));
// verify compare is actually lexicographical
BOOST_TEST(path("a/b") < path("a.b"));
path lex_lo("a/b"), lex_hi("a.b");
const char* plex_lo = "a/b";
const char* plex_hi = "a.b";
const std::string slex_lo("a/b"), slex_hi("a.b");
BOOST_TEST(lex_lo < lex_hi);
BOOST_TEST(lex_lo < "a.b");
BOOST_TEST(lex_lo < plex_hi);
BOOST_TEST(lex_lo < slex_hi);
BOOST_TEST("a/b" < lex_hi);
BOOST_TEST(plex_lo < lex_hi);
BOOST_TEST(slex_lo < lex_hi);
BOOST_TEST(!(lex_lo == lex_hi));
BOOST_TEST(!(lex_lo == "a.b"));
BOOST_TEST(!(lex_lo == plex_hi));
BOOST_TEST(!(lex_lo == slex_hi));
BOOST_TEST(!("a/b" == lex_hi));
BOOST_TEST(!(plex_lo == lex_hi));
BOOST_TEST(!(slex_lo == lex_hi));
// verify path overloads aren't knocking out string overloads
BOOST_TEST(!(slex_lo < slex_hi));
BOOST_TEST(!(slex_lo < "a.b"));
BOOST_TEST(!(slex_lo < plex_hi));
BOOST_TEST(!("a/b" < slex_hi));
BOOST_TEST(!(plex_lo < slex_hi));
BOOST_TEST(!(slex_lo == slex_hi));
BOOST_TEST(!(slex_lo == "a.b"));
BOOST_TEST(!(slex_lo == plex_hi));
BOOST_TEST(!("a/b" == slex_hi));
BOOST_TEST(!(plex_lo == slex_hi));
// misc test cases
BOOST_TEST(path("a/b") == path("a///b"));
BOOST_TEST(path("a/b/") == path("a/b/."));
BOOST_TEST(path("a/b") != path("a/b/"));
@ -1729,6 +1766,27 @@ namespace
BOOST_TEST(!fs::portable_file_name(std::string("foo.")));
}
// replace_filename_tests ---------------------------------------------------------//
void replace_filename_tests()
{
std::cout << "replace_filename_tests..." << std::endl;
BOOST_TEST(path().replace_filename("").empty());
BOOST_TEST(path().replace_filename("a") == "a");
BOOST_TEST(path().replace_filename("a.txt") == "a.txt");
BOOST_TEST(path("foo").replace_filename("bar") == "bar");
BOOST_TEST_EQ(path("/").replace_filename("bar"), path("bar"));
BOOST_TEST_EQ(path(".").replace_filename("bar"), path("bar"));
BOOST_TEST_EQ(path("..").replace_filename("bar"), path("bar"));
BOOST_TEST(path("/foo").replace_filename("bar") == "/bar");
BOOST_TEST(path("my/foo").replace_filename("bar") == "my/bar");
BOOST_TEST(path("my//foo").replace_filename("bar") == "my/bar");
BOOST_TEST(path("./foo").replace_filename("bar") == "./bar");
BOOST_TEST(path("../foo").replace_filename("bar") == "../bar");
}
// replace_extension_tests ---------------------------------------------------------//
void replace_extension_tests()
@ -1820,6 +1878,7 @@ int cpp_main(int, char*[])
non_member_tests();
exception_tests();
name_function_tests();
replace_filename_tests();
replace_extension_tests();
make_preferred_tests();

View File

@ -60,6 +60,15 @@ using std::cout;
using std::endl;
using std::string;
using std::wstring;
using boost::char16;
using boost::char32;
using boost::u16string;
using boost::u32string;
using boost::interop::make_string;
using boost::interop::narrow;
using boost::interop::wide;
using boost::interop::utf16;
using boost::interop::utf32;
#define CHECK(x) check(x, __FILE__, __LINE__)
#define PATH_IS(a, b) check_path(a, b, __FILE__, __LINE__)
@ -143,8 +152,26 @@ namespace
string s("string");
wstring ws(L"wstring");
// Test with cases that require UTF-16 surrogate pairs
// U+1F60A SMILING FACE WITH SMILING EYES
// U+1F60E SMILING FACE WITH SUNGLASSES
// build test strings character by character so they work with C++03 compilers
const char32 u32c[] = {0x1F60A, 0x1F60E, 0};
const char16 u16c[] = {0xD83D, 0xDE0A, 0xD83D, 0xDE0E, 0};
const u32string u32s(u32c);
const u16string u16s(u16c);
const string u8s("\xF0\x9F\x98\x8A\xF0\x9F\x98\x8E");
const string chars("\xF0\x9F\x98\x8A\xF0\x9F\x98\x8E");
const wstring wchars(L"\xF0\x9F\x98\x8A\xF0\x9F\x98\x8E");
std::list<char> l; // see main() for initialization to s, t, r, i, n, g
std::list<wchar_t> wl; // see main() for initialization to w, s, t, r, i, n, g
std::list<char16> u16l; // see main() for initialization to u, 1, 6, s, t, r, i, n, g
std::list<char32> u32l; // see main() for initialization to u, 3, 2, s, t, r, i, n, g
std::vector<char> v; // see main() for initialization to f, u, z
std::vector<wchar_t> wv; // see main() for initialization to w, f, u, z
@ -170,10 +197,27 @@ namespace
PATH_IS(x2, L"string");
BOOST_TEST_EQ(x2.native().size(), 6U);
# ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
std::cout << " with rvalue references..." << std::endl;
path x2source("source------------------------32");
path x2m(std::move(x2source)); // move constructor
BOOST_TEST(x2m == "source------------------------32");
BOOST_TEST(x2source.empty());
std::cout << " with rvalue references complete" << std::endl;
# endif
path x3(wl.begin(), wl.end()); // iterator range wchar_t
PATH_IS(x3, L"wstring");
BOOST_TEST_EQ(x3.native().size(), 7U);
path x3_16(u16l.begin(), u16l.end()); // iterator range char16
PATH_IS(x3_16, L"u16string");
BOOST_TEST_EQ(x3_16.native().size(), 9U);
path x3_32(u32l.begin(), u32l.end()); // iterator range char32
PATH_IS(x3_32, L"u32string");
BOOST_TEST_EQ(x3_32.native().size(), 9U);
// contiguous containers
path x4(string("std::string")); // std::string
PATH_IS(x4, L"std::string");
@ -183,6 +227,14 @@ namespace
PATH_IS(x5, L"std::wstring");
BOOST_TEST_EQ(x5.native().size(), 12U);
path x4_16(make_string<utf16, narrow, u16string>("u16string")); // u16string
PATH_IS(x4_16, L"u16string");
BOOST_TEST_EQ(x4_16.native().size(), 9U);
path x4_32(make_string<utf32, narrow, u32string>("u32string")); // u32string
PATH_IS(x4_32, L"u32string");
BOOST_TEST_EQ(x4_32.native().size(), 9U);
path x4v(v); // std::vector<char>
PATH_IS(x4v, L"fuz");
BOOST_TEST_EQ(x4v.native().size(), 3U);
@ -219,6 +271,14 @@ namespace
PATH_IS(x9, L"wstring");
BOOST_TEST_EQ(x9.native().size(), 7U);
path x9_16(make_string<utf16, narrow, u16string>("cvt-u16string").c_str()); // const char16* null terminated
PATH_IS(x9_16, L"cvt-u16string");
BOOST_TEST_EQ(x9_16.native().size(), 13U);
path x9_32(make_string<utf32, narrow, u32string>("cvt-u32string").c_str()); // const char32* null terminated
PATH_IS(x9_32, L"cvt-u32string");
BOOST_TEST_EQ(x9_32.native().size(), 13U);
// non-contiguous containers
path x10(l); // std::list<char>
PATH_IS(x10, L"string");
@ -245,10 +305,19 @@ namespace
{
std::cout << "testing assignments..." << std::endl;
x = path("yet another path"); // another path
x = path("yet another path"); // copy assignment
PATH_IS(x, L"yet another path");
BOOST_TEST_EQ(x.native().size(), 16U);
# ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
std::cout << " with rvalue references" << std::endl;
path x2source("source------------------------32");
path x2;
x2 = std::move(x2source); // move assignment
BOOST_TEST(x2 == "source------------------------32");
BOOST_TEST(x2source.empty());
# endif
x = x; // self-assignment
PATH_IS(x, L"yet another path");
BOOST_TEST_EQ(x.native().size(), 16U);
@ -423,6 +492,15 @@ namespace
CHECK(p0.string().size() == 3);
CHECK(p0.wstring() == L"abc");
CHECK(p0.wstring().size() == 3);
CHECK(p0.u16string() == (make_string<utf16, narrow, u16string>("abc")));
CHECK(p0.u16string().size() == 3);
CHECK(p0.u32string() == (make_string<utf32, narrow, u32string>("abc")));
CHECK(p0.u32string().size() == 3);
CHECK(p0.string() == p0.string<string>());
CHECK(p0.string() == (p0.basic_string<char,
std::char_traits<char>, std::allocator<char> >()));
# ifdef BOOST_WINDOWS_API
@ -435,6 +513,8 @@ namespace
CHECK(p.generic_string() == "abc/def/ghi");
CHECK(p.generic_wstring() == L"abc/def/ghi");
CHECK(p.generic_u16string() == (make_string<utf16, narrow, u16string>("abc/def/ghi")));
CHECK(p.generic_u32string() == (make_string<utf32, narrow, u32string>("abc/def/ghi")));
CHECK(p.generic_string<string>() == "abc/def/ghi");
CHECK(p.generic_string<wstring>() == L"abc/def/ghi");
@ -451,6 +531,8 @@ namespace
CHECK(p.generic_string() == "abc\\def/ghi");
CHECK(p.generic_wstring() == L"abc\\def/ghi");
CHECK(p.generic_u16string() == (make_string<utf16, narrow, u16string>("abc\\def/ghi")));
CHECK(p.generic_u32string() == (make_string<utf32, narrow, u32string>("abc\\def/ghi")));
CHECK(p.generic_string<string>() == "abc\\def/ghi");
CHECK(p.generic_string<wstring>() == L"abc\\def/ghi");
@ -473,32 +555,35 @@ namespace
CHECK(hash(path("c:\\abc")) == hash(path("c:/abc")));
# endif
const path p("bar");
const path p2("baz");
const path p("a/b");
const path p2("a.b");
// verify "a.c" < "a/c", so tests will detect failure to do lexicographic compare
CHECK(string("a.b") < string("a/b"));
CHECK(!(p < p));
CHECK(p < p2);
CHECK(!(p2 < p));
CHECK(p < "baz");
CHECK(p < string("baz"));
CHECK(p < L"baz");
CHECK(p < wstring(L"baz"));
CHECK(!("baz" < p));
CHECK(!(string("baz") < p));
CHECK(!(L"baz" < p));
CHECK(!(wstring(L"baz") < p));
CHECK(p < "a.b");
CHECK(p < string("a.b"));
CHECK(p < L"a.b");
CHECK(p < wstring(L"a.b"));
CHECK(!("a.b" < p));
CHECK(!(string("a.b") < p));
CHECK(!(L"a.b" < p));
CHECK(!(wstring(L"a.b") < p));
CHECK(p == p);
CHECK(!(p == p2));
CHECK(!(p2 == p));
CHECK(p2 == "baz");
CHECK(p2 == string("baz"));
CHECK(p2 == L"baz");
CHECK(p2 == wstring(L"baz"));
CHECK("baz" == p2);
CHECK(string("baz") == p2);
CHECK(L"baz" == p2);
CHECK(wstring(L"baz") == p2);
CHECK(p2 == "a.b");
CHECK(p2 == string("a.b"));
CHECK(p2 == L"a.b");
CHECK(p2 == wstring(L"a.b"));
CHECK("a.b" == p2);
CHECK(string("a.b") == p2);
CHECK(L"a.b" == p2);
CHECK(wstring(L"a.b") == p2);
CHECK(hash(p) == hash(p));
CHECK(hash(p) != hash(p2)); // Not strictly required, but desirable
@ -620,6 +705,11 @@ namespace
{
std::cout << "testing modifiers..." << std::endl;
path p("foo/bar");
std::cout << p << std::endl; // outputs: "foo/bar"
p.make_preferred();
std::cout << p << std::endl; // outputs: "foo\bar" on Windows, otherwise "foo/bar"
}
// test_decompositions -------------------------------------------------------------//
@ -1063,6 +1153,26 @@ int cpp_main(int, char*[])
wl.push_back(L'n');
wl.push_back(L'g');
u16l.push_back('u');
u16l.push_back('1');
u16l.push_back('6');
u16l.push_back('s');
u16l.push_back('t');
u16l.push_back('r');
u16l.push_back('i');
u16l.push_back('n');
u16l.push_back('g');
u32l.push_back('u');
u32l.push_back('3');
u32l.push_back('2');
u32l.push_back('s');
u32l.push_back('t');
u32l.push_back('r');
u32l.push_back('i');
u32l.push_back('n');
u32l.push_back('g');
v.push_back('f');
v.push_back('u');
v.push_back('z');