1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// REQUIRES: can-create-symlinks
// UNSUPPORTED: c++03, c++11, c++14
// UNSUPPORTED: no-filesystem
// UNSUPPORTED: availability-filesystem-missing
// <filesystem>
// path canonical(const path& p);
// path canonical(const path& p, error_code& ec);
#include <filesystem>
#include <type_traits>
#include <cassert>
#include "assert_macros.h"
#include "test_macros.h"
#include "filesystem_test_helper.h"
#include "../../class.path/path_helper.h"
namespace fs = std::filesystem;
using namespace fs;
static void signature_test()
{
const path p; ((void)p);
std::error_code ec; ((void)ec);
ASSERT_NOT_NOEXCEPT(canonical(p));
ASSERT_NOT_NOEXCEPT(canonical(p, ec));
}
// There are 4 cases is the proposal for absolute path.
// Each scope tests one of the cases.
static void test_canonical()
{
static_test_env static_env;
CWDGuard guard;
// has_root_name() && has_root_directory()
const path Root = static_env.Root;
const path RootName = Root.filename();
const path DirName = static_env.Dir.filename();
const path SymlinkName = static_env.SymlinkToFile.filename();
struct TestCase {
path p;
path expect;
path base;
TestCase(path p1, path e, path b)
: p(p1), expect(e), base(b) {}
};
const TestCase testCases[] = {
{ ".", Root, Root },
{ DirName / ".." / "." / DirName, static_env.Dir, Root },
{ static_env.Dir2 / "..", static_env.Dir, Root },
{ static_env.Dir3 / "../..", static_env.Dir, Root },
{ static_env.Dir / ".", static_env.Dir, Root },
{ Root / "." / DirName / ".." / DirName, static_env.Dir, Root },
{ path("..") / "." / RootName / DirName / ".." / DirName,
static_env.Dir,
Root },
{ static_env.SymlinkToFile, static_env.File, Root },
{ SymlinkName, static_env.File, Root}
};
for (auto& TC : testCases) {
std::error_code ec = GetTestEC();
fs::current_path(TC.base);
const path ret = canonical(TC.p, ec);
assert(!ec);
const path ret2 = canonical(TC.p);
assert(PathEq(ret, TC.expect));
assert(PathEq(ret, ret2));
assert(ret.is_absolute());
}
}
static void test_dne_path()
{
static_test_env static_env;
std::error_code ec = GetTestEC();
{
const path ret = canonical(static_env.DNE, ec);
assert(ec != GetTestEC());
assert(ec);
assert(ret == path{});
}
{
TEST_THROWS_TYPE(filesystem_error, canonical(static_env.DNE));
}
}
static void test_exception_contains_paths()
{
#ifndef TEST_HAS_NO_EXCEPTIONS
static_test_env static_env;
CWDGuard guard;
const path p = "blabla/dne";
try {
(void)canonical(p);
assert(false);
} catch (filesystem_error const& err) {
assert(err.path1() == p);
// libc++ provides the current path as the second path in the exception
LIBCPP_ASSERT(err.path2() == current_path());
}
fs::current_path(static_env.Dir);
try {
(void)canonical(p);
assert(false);
} catch (filesystem_error const& err) {
assert(err.path1() == p);
LIBCPP_ASSERT(err.path2() == static_env.Dir);
}
#endif
}
int main(int, char**) {
signature_test();
test_canonical();
test_dne_path();
test_exception_contains_paths();
return 0;
}
|