1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// REQUIRES: can-create-symlinks
10// UNSUPPORTED: c++03, c++11, c++14
11// UNSUPPORTED: no-filesystem
12// UNSUPPORTED: availability-filesystem-missing
13
14// <filesystem>
15
16// bool exists(file_status s) noexcept
17// bool exists(path const& p);
18// bool exists(path const& p, std::error_code& ec) noexcept;
19
20#include <filesystem>
21#include <type_traits>
22#include <cassert>
23
24#include "assert_macros.h"
25#include "test_macros.h"
26#include "filesystem_test_helper.h"
27namespace fs = std::filesystem;
28using namespace fs;
29
30static void signature_test()
31{
32 file_status s; ((void)s);
33 const path p; ((void)p);
34 std::error_code ec; ((void)ec);
35 ASSERT_NOEXCEPT(exists(s: s));
36 ASSERT_NOEXCEPT(exists(p: p, ec&: ec));
37 ASSERT_NOT_NOEXCEPT(exists(p: p));
38}
39
40static void exists_status_test()
41{
42 struct TestCase {
43 file_type type;
44 bool expect;
45 };
46 const TestCase testCases[] = {
47 {.type: file_type::none, .expect: false},
48 {.type: file_type::not_found, .expect: false},
49 {.type: file_type::regular, .expect: true},
50 {.type: file_type::directory, .expect: true},
51 {.type: file_type::symlink, .expect: true},
52 {.type: file_type::block, .expect: true},
53 {.type: file_type::character, .expect: true},
54 {.type: file_type::fifo, .expect: true},
55 {.type: file_type::socket, .expect: true},
56 {.type: file_type::unknown, .expect: true}
57 };
58 for (auto& TC : testCases) {
59 file_status s(TC.type);
60 assert(exists(s) == TC.expect);
61 }
62}
63
64static void test_exist_not_found()
65{
66 static_test_env static_env;
67 const path p = static_env.DNE;
68 assert(exists(p) == false);
69
70 assert(exists(static_env.Dir) == true);
71 assert(exists(static_env.Dir / "dne") == false);
72 // Whether <dir>/dne/.. is considered to exist or not is not necessarily
73 // something we need to define, but the platform specific behaviour
74 // does affect a few other tests, so clarify the root cause here.
75#ifdef _WIN32
76 assert(exists(static_env.Dir / "dne" / "..") == true);
77#else
78 assert(exists(static_env.Dir / "dne" / "..") == false);
79#endif
80
81 std::error_code ec = GetTestEC();
82 assert(exists(p, ec) == false);
83 assert(!ec);
84}
85
86static void test_exists_fails()
87{
88#ifdef _WIN32
89 // Windows doesn't support setting perms::none to trigger failures
90 // reading directories; test using a special inaccessible directory
91 // instead.
92 const path p = GetWindowsInaccessibleDir();
93 if (p.empty())
94 return;
95#else
96 scoped_test_env env;
97 const path dir = env.create_dir("dir");
98 const path p = env.create_file("dir/file", 42);
99 permissions(p: dir, prms: perms::none);
100#endif
101
102 std::error_code ec;
103 assert(exists(p, ec) == false);
104 assert(ec);
105
106 TEST_THROWS_TYPE(filesystem_error, exists(p));
107}
108
109#ifndef _WIN32
110// Checking for the existence of an invalid long path name doesn't
111// trigger errors on windows.
112static void test_name_too_long() {
113 std::string long_name(2500, 'a');
114 const path file(long_name);
115
116 std::error_code ec;
117 assert(exists(file, ec) == false);
118 assert(ec);
119}
120#endif // _WIN32
121
122int main(int, char**) {
123 signature_test();
124 exists_status_test();
125 test_exist_not_found();
126 test_exists_fails();
127#ifndef _WIN32
128 test_name_too_long();
129#endif
130
131 return 0;
132}
133

source code of libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp