You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
4.0 KiB
C++
133 lines
4.0 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// UNSUPPORTED: c++98, c++03
|
|
|
|
// <filesystem>
|
|
|
|
// path proximate(const path& p, error_code &ec)
|
|
// path proximate(const path& p, const path& base = current_path())
|
|
// path proximate(const path& p, const path& base, error_code& ec);
|
|
|
|
#include "filesystem_include.hpp"
|
|
#include <type_traits>
|
|
#include <vector>
|
|
#include <iostream>
|
|
#include <cassert>
|
|
|
|
#include "test_macros.h"
|
|
#include "test_iterators.h"
|
|
#include "count_new.hpp"
|
|
#include "rapid-cxx-test.hpp"
|
|
#include "filesystem_test_helper.hpp"
|
|
|
|
|
|
static int count_path_elems(const fs::path& p) {
|
|
int count = 0;
|
|
for (auto& elem : p) {
|
|
if (elem != "/" && elem != "")
|
|
++count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
TEST_SUITE(filesystem_proximate_path_test_suite)
|
|
|
|
|
|
TEST_CASE(signature_test)
|
|
{
|
|
using fs::path;
|
|
const path p; ((void)p);
|
|
std::error_code ec; ((void)ec);
|
|
ASSERT_NOT_NOEXCEPT(proximate(p));
|
|
ASSERT_NOT_NOEXCEPT(proximate(p, p));
|
|
ASSERT_NOT_NOEXCEPT(proximate(p, ec));
|
|
ASSERT_NOT_NOEXCEPT(proximate(p, p, ec));
|
|
}
|
|
|
|
TEST_CASE(basic_test) {
|
|
using fs::path;
|
|
const path cwd = fs::current_path();
|
|
const path parent_cwd = cwd.parent_path();
|
|
const path curdir = cwd.filename();
|
|
TEST_REQUIRE(!cwd.native().empty());
|
|
int cwd_depth = count_path_elems(cwd);
|
|
path dot_dot_to_root;
|
|
for (int i=0; i < cwd_depth; ++i)
|
|
dot_dot_to_root /= "..";
|
|
path relative_cwd = cwd.native().substr(1);
|
|
// clang-format off
|
|
struct {
|
|
std::string input;
|
|
std::string base;
|
|
std::string expect;
|
|
} TestCases[] = {
|
|
{"", "", "."},
|
|
{cwd, "a", ".."},
|
|
{parent_cwd, "a", "../.."},
|
|
{"a", cwd, "a"},
|
|
{"a", parent_cwd, "fs.op.proximate/a"},
|
|
{"/", "a", dot_dot_to_root / ".."},
|
|
{"/", "a/b", dot_dot_to_root / "../.."},
|
|
{"/", "a/b/", dot_dot_to_root / "../.."},
|
|
{"a", "/", relative_cwd / "a"},
|
|
{"a/b", "/", relative_cwd / "a/b"},
|
|
{"a", "/net", ".." / relative_cwd / "a"},
|
|
{"//foo/", "//foo", "."},
|
|
{"//foo", "//foo/", "."},
|
|
{"//foo", "//foo", "."},
|
|
{"//foo/", "//foo/", "."},
|
|
{"//base", "a", dot_dot_to_root / "../base"},
|
|
{"a", "a", "."},
|
|
{"a/b", "a/b", "."},
|
|
{"a/b/c/", "a/b/c/", "."},
|
|
{"//foo/a/b", "//foo/a/b", "."},
|
|
{"/a/d", "/a/b/c", "../../d"},
|
|
{"/a/b/c", "/a/d", "../b/c"},
|
|
{"a/b/c", "a", "b/c"},
|
|
{"a/b/c", "a/b/c/x/y", "../.."},
|
|
{"a/b/c", "a/b/c", "."},
|
|
{"a/b", "c/d", "../../a/b"}
|
|
};
|
|
// clang-format on
|
|
int ID = 0;
|
|
for (auto& TC : TestCases) {
|
|
++ID;
|
|
std::error_code ec = GetTestEC();
|
|
fs::path p(TC.input);
|
|
const fs::path output = fs::proximate(p, TC.base, ec);
|
|
if (ec) {
|
|
TEST_CHECK(!ec);
|
|
std::cerr << "TEST CASE #" << ID << " FAILED: \n";
|
|
std::cerr << " Input: '" << TC.input << "'\n";
|
|
std::cerr << " Base: '" << TC.base << "'\n";
|
|
std::cerr << " Expected: '" << TC.expect << "'\n";
|
|
|
|
std::cerr << std::endl;
|
|
} else if (!PathEq(output, TC.expect)) {
|
|
TEST_CHECK(PathEq(output, TC.expect));
|
|
|
|
const path canon_input = fs::weakly_canonical(TC.input);
|
|
const path canon_base = fs::weakly_canonical(TC.base);
|
|
const path lexically_p = canon_input.lexically_proximate(canon_base);
|
|
std::cerr << "TEST CASE #" << ID << " FAILED: \n";
|
|
std::cerr << " Input: '" << TC.input << "'\n";
|
|
std::cerr << " Base: '" << TC.base << "'\n";
|
|
std::cerr << " Expected: '" << TC.expect << "'\n";
|
|
std::cerr << " Output: '" << output.native() << "'\n";
|
|
std::cerr << " Lex Prox: '" << lexically_p.native() << "'\n";
|
|
std::cerr << " Canon Input: " << canon_input << "\n";
|
|
std::cerr << " Canon Base: " << canon_base << "\n";
|
|
|
|
std::cerr << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_SUITE_END()
|