#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "base/files/file_path.h"
#include <stddef.h>
#include <sstream>
#include <string_view>
#include "base/files/safe_base_name.h"
#include "base/strings/utf_ostream_operators.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "build/buildflag.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#if BUILDFLAG(ENABLE_BASE_TRACING)
#include "third_party/perfetto/include/perfetto/test/traced_value_test_support.h"
#endif
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#include "base/test/scoped_locale.h"
#endif
#define TEST_FILE …
#define FPL(x) …
#define FPS(x) …
namespace base {
struct UnaryTestData { … };
struct UnaryBooleanTestData { … };
struct BinaryTestData { … };
struct BinaryBooleanTestData { … };
struct BinaryIntTestData { … };
struct UTF8TestData { … };
FilePathTest;
TEST_F(FilePathTest, DirName) { … }
TEST_F(FilePathTest, BaseName) { … }
TEST_F(FilePathTest, Append) { … }
TEST_F(FilePathTest, StripTrailingSeparators) { … }
TEST_F(FilePathTest, IsAbsoluteOrNetwork) { … }
TEST_F(FilePathTest, PathComponentsTest) { … }
TEST_F(FilePathTest, IsParentTest) { … }
TEST_F(FilePathTest, AppendRelativePathTest) { … }
TEST_F(FilePathTest, EqualityTest) { … }
TEST_F(FilePathTest, MacroExpansion) { … }
TEST_F(FilePathTest, Extension) { … }
TEST_F(FilePathTest, Extension2) { … }
TEST_F(FilePathTest, InsertBeforeExtension) { … }
TEST_F(FilePathTest, RemoveExtension) { … }
TEST_F(FilePathTest, ReplaceExtension) { … }
TEST_F(FilePathTest, AddExtension) { … }
TEST_F(FilePathTest, MatchesExtension) { … }
TEST_F(FilePathTest, MatchesFinalExtension) { … }
TEST_F(FilePathTest, CompareIgnoreCase) { … }
TEST_F(FilePathTest, ReferencesParent) { … }
TEST_F(FilePathTest, FromASCII) { … }
TEST_F(FilePathTest, FromUTF8Unsafe_And_AsUTF8Unsafe) { … }
TEST_F(FilePathTest, ConstructWithNUL) { … }
TEST_F(FilePathTest, AppendWithNUL) { … }
TEST_F(FilePathTest, AppendBaseName) { … }
TEST_F(FilePathTest, ReferencesParentWithNUL) { … }
#if defined(FILE_PATH_USES_WIN_SEPARATORS)
TEST_F(FilePathTest, NormalizePathSeparators) {
const struct UnaryTestData cases[] = {
{ FPL("foo/bar"), FPL("foo\\bar") },
{ FPL("foo/bar\\betz"), FPL("foo\\bar\\betz") },
{ FPL("foo\\bar"), FPL("foo\\bar") },
{ FPL("foo\\bar/betz"), FPL("foo\\bar\\betz") },
{ FPL("foo"), FPL("foo") },
{ FPL("foo\\"), FPL("foo\\") },
{ FPL("foo/"), FPL("foo\\") },
{ FPL("foo/bar\\"), FPL("foo\\bar\\") },
{ FPL("foo\\bar/"), FPL("foo\\bar\\") },
{ FPL("foo/bar/"), FPL("foo\\bar\\") },
{ FPL("foo\\bar\\"), FPL("foo\\bar\\") },
{ FPL("\\foo/bar"), FPL("\\foo\\bar") },
{ FPL("/foo\\bar"), FPL("\\foo\\bar") },
{ FPL("c:/foo/bar/"), FPL("c:\\foo\\bar\\") },
{ FPL("/foo/bar/"), FPL("\\foo\\bar\\") },
{ FPL("\\foo\\bar\\"), FPL("\\foo\\bar\\") },
{ FPL("c:\\foo/bar"), FPL("c:\\foo\\bar") },
{ FPL("//foo\\bar\\"), FPL("\\\\foo\\bar\\") },
{ FPL("\\\\foo\\bar\\"), FPL("\\\\foo\\bar\\") },
{ FPL("//foo\\bar\\"), FPL("\\\\foo\\bar\\") },
{ FPL("foo\\\\bar"), FPL("foo\\\\bar") },
{ FPL("foo//bar"), FPL("foo\\\\bar") },
{ FPL("foo/\\bar"), FPL("foo\\\\bar") },
{ FPL("foo\\/bar"), FPL("foo\\\\bar") },
{ FPL("///foo\\\\bar"), FPL("\\\\\\foo\\\\bar") },
{ FPL("foo//bar///"), FPL("foo\\\\bar\\\\\\") },
{ FPL("foo/\\bar/\\"), FPL("foo\\\\bar\\\\") },
{ FPL("/\\foo\\/bar"), FPL("\\\\foo\\\\bar") },
};
for (size_t i = 0; i < std::size(cases); ++i) {
FilePath input(cases[i].input);
FilePath observed = input.NormalizePathSeparators();
EXPECT_EQ(FilePath::StringType(cases[i].expected), observed.value()) <<
"i: " << i << ", input: " << input.value();
}
}
#endif
TEST_F(FilePathTest, EndsWithSeparator) { … }
TEST_F(FilePathTest, AsEndingWithSeparator) { … }
#if BUILDFLAG(IS_ANDROID)
TEST_F(FilePathTest, ContentUriTest) {
const struct UnaryBooleanTestData cases[] = {
{ FPL("content://foo.bar"), true },
{ FPL("content://foo.bar/"), true },
{ FPL("content://foo/bar"), true },
{ FPL("CoNTenT://foo.bar"), true },
{ FPL("content://"), true },
{ FPL("content:///foo.bar"), true },
{ FPL("content://3foo/bar"), true },
{ FPL("content://_foo/bar"), true },
{ FPL(".. "), false },
{ FPL("foo.bar"), false },
{ FPL("content:foo.bar"), false },
{ FPL("content:/foo.ba"), false },
{ FPL("content:/dir/foo.bar"), false },
{ FPL("content: //foo.bar"), false },
{ FPL("content%2a%2f%2f"), false },
};
for (size_t i = 0; i < std::size(cases); ++i) {
FilePath input(cases[i].input);
bool observed = input.IsContentUri();
EXPECT_EQ(cases[i].expected, observed) <<
"i: " << i << ", input: " << input.value();
}
}
#endif
TEST_F(FilePathTest, PrintToOstream) { … }
#if BUILDFLAG(ENABLE_BASE_TRACING)
TEST_F(FilePathTest, TracedValueSupport) { … }
#endif
#if BUILDFLAG(IS_APPLE)
TEST_F(FilePathTest, GetHFSDecomposedFormWithInvalidInput) {
const FilePath::CharType* cases[] = {
FPL("\xc3\x28"),
FPL("\xe2\x82\x28"),
FPL("\xe2\x28\xa1"),
FPL("\xf0\x28\x8c\xbc"),
FPL("\xf0\x28\x8c\x28"),
};
for (auto* invalid_input : cases) {
FilePath::StringType observed = FilePath::GetHFSDecomposedForm(
invalid_input);
EXPECT_TRUE(observed.empty());
}
}
TEST_F(FilePathTest, CompareIgnoreCaseWithInvalidInput) {
const FilePath::CharType* cases[] = {
FPL("\xc3\x28"), FPL("\xe2\x82\x28"), FPL("\xe2\x28\xa1"),
FPL("\xf0\x28\x8c\xbc"), FPL("\xf0\x28\x8c\x28"),
};
for (auto* invalid_input : cases) {
EXPECT_EQ(FilePath::CompareIgnoreCase(invalid_input, FPL("fixed")), 1);
}
}
#endif
}