/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #include #include "Base/Logger.hpp" #include "IO/FsUtils.hpp" #include "IO/AppFolders.hpp" #include #include using namespace OpenVulkano; namespace { void touch(const std::filesystem::path& file) { std::ofstream foo(file); foo.close(); } } TEST_CASE("DeleteEmptyDirs", "[FsUtils]") { Logger::SetupLogger("", "tests.log"); auto baseDir = AppFolders::GetAppTempDir() / "testEmptyDirs"; std::filesystem::create_directories(baseDir / "emptyDir"); std::filesystem::create_directories(baseDir / "nonEmptyDir"); std::ofstream(baseDir / "nonEmptyDir/file.txt").put('x'); REQUIRE(FsUtils::DeleteEmptyDirs(baseDir)); REQUIRE(!std::filesystem::exists(baseDir / "emptyDir")); REQUIRE(std::filesystem::exists(baseDir / "nonEmptyDir")); std::filesystem::create_directories(baseDir / "emptyDir"); REQUIRE(FsUtils::DeleteEmptyDirs(baseDir, false)); REQUIRE(!std::filesystem::exists(baseDir / "emptyDir")); std::filesystem::remove_all(baseDir); } TEST_CASE("DeleteEmptySubTrees", "[FsUtils]") { Logger::SetupLogger("", "tests.log"); auto baseDir = AppFolders::GetAppTempDir() / "testEmptySubtrees"; std::filesystem::create_directories(baseDir / "emptyTree" / "subDir1"); std::filesystem::create_directories(baseDir / "emptyTree" / "subDir2"); REQUIRE(FsUtils::DeleteEmptySubTrees(baseDir)); REQUIRE(!std::filesystem::exists(baseDir / "emptyTree")); std::filesystem::create_directories(baseDir / "partialTree" / "subDir1"); std::filesystem::create_directories(baseDir / "partialTree" / "subDir2"); std::ofstream(baseDir / "partialTree" / "subDir2/file.txt").put('x'); REQUIRE(FsUtils::DeleteEmptySubTrees(baseDir / "partialTree")); REQUIRE(!std::filesystem::exists(baseDir / "partialTree" / "subDir1")); REQUIRE(std::filesystem::exists(baseDir / "partialTree" / "subDir2")); REQUIRE(std::filesystem::exists(baseDir / "partialTree" / "subDir2/file.txt")); std::filesystem::remove(baseDir / "partialTree" / "subDir2/file.txt"); REQUIRE(!std::filesystem::exists(baseDir / "partialTree" / "subDir1")); REQUIRE(std::filesystem::exists(baseDir / "partialTree" / "subDir2")); REQUIRE(!std::filesystem::exists(baseDir / "partialTree" / "subDir2/file.txt")); REQUIRE(FsUtils::DeleteEmptySubTrees(baseDir / "partialTree")); REQUIRE(!std::filesystem::exists(baseDir / "partialTree" / "subDir1")); REQUIRE(!std::filesystem::exists(baseDir / "partialTree" / "subDir2")); std::filesystem::remove_all(baseDir); } TEST_CASE("IsTreeEmpty", "[FsUtils]") { Logger::SetupLogger("", "tests.log"); auto baseDir = AppFolders::GetAppTempDir() / "testTreeEmpty"; std::filesystem::create_directories(baseDir / "emptyDir"); std::filesystem::create_directories(baseDir / "nonEmptyDir"); std::ofstream(baseDir / "nonEmptyDir/file.txt").put('x'); REQUIRE(FsUtils::IsTreeEmpty(baseDir / "emptyDir")); REQUIRE(!FsUtils::IsTreeEmpty(baseDir / "nonEmptyDir")); std::filesystem::remove_all(baseDir); } TEST_CASE("GetDirSize", "[FsUtils]") { Logger::SetupLogger("", "tests.log"); auto baseDir = AppFolders::GetAppTempDir() / "testDirSize"; std::filesystem::create_directories(baseDir / "dir"); std::ofstream(baseDir / "dir/file1.txt").put('x'); std::ofstream(baseDir / "dir/file2.txt").put('y'); REQUIRE(FsUtils::GetDirSize(baseDir / "dir") == 2); std::filesystem::remove_all(baseDir); } TEST_CASE("ToValidFileName", "[FsUtils]") { Logger::SetupLogger("", "tests.log"); REQUIRE(FsUtils::ToValidFileName("file") == "file<name>"); REQUIRE(FsUtils::ToValidFileName("file:name") == "file꞉name"); REQUIRE(FsUtils::ToValidFileName("file\"name\"") == "file"name""); REQUIRE(FsUtils::ToValidFileName("file/name\\") == "file⁄name⧹"); REQUIRE(FsUtils::ToValidFileName("file|name") == "file|name"); REQUIRE(FsUtils::ToValidFileName("file?name*") == "file?name∗"); REQUIRE(FsUtils::ToValidFileName("file~name") == "filename"); REQUIRE(FsUtils::ToValidFileName("file`name") == "filename"); REQUIRE(FsUtils::ToValidFileName("file!@#$%^&name") == "filename"); REQUIRE(FsUtils::ToValidFileName("file(name{name}") == "filenamename"); REQUIRE(FsUtils::ToValidFileName("file=name") == "filename"); REQUIRE(FsUtils::ToValidFileName("file+name,name") == "filenamename"); REQUIRE(FsUtils::ToValidFileName(" file name ") == "file name"); REQUIRE(FsUtils::ToValidFileName("..file name..") == "file name"); REQUIRE(FsUtils::ToValidFileName(".file.") == "file"); REQUIRE(FsUtils::ToValidFileName("file name") == "file name"); REQUIRE(FsUtils::ToValidFileName("file name") == "file name"); REQUIRE(FsUtils::ToValidFileName("") == "unnamed_file"); REQUIRE(FsUtils::ToValidFileName(" ") == "unnamed_file"); REQUIRE(FsUtils::ToValidFileName("...") == "unnamed_file"); std::string long_name(300, 'a'); REQUIRE(FsUtils::ToValidFileName(long_name).length() == 255); std::string utf8_name = "name_" + std::string(250, 'a') + "∗"; REQUIRE(FsUtils::ToValidFileName(utf8_name).back() == 'a'); REQUIRE(FsUtils::ToValidFileName("<>:/\\|?*") == "<>꞉⁄⧹|?∗"); REQUIRE(FsUtils::ToValidFileName("~~~~") == "unnamed_file"); REQUIRE(FsUtils::ToValidFileName("..") == "unnamed_file"); REQUIRE(FsUtils::ToValidFileName("file:name<>") == "file꞉name<>"); REQUIRE(FsUtils::ToValidFileName(" file?") == "file<name>?"); } TEST_CASE("DeleteEmptyFilesAndDirs", "[FsUtils]") { Logger::SetupLogger("", "tests.log"); const auto testDir = AppFolders::GetAppTempDir() / "testDirectory"; { std::filesystem::create_directories(testDir); auto emptyFile = testDir / "empty_file.txt"; auto emptyDir = testDir / "empty_dir"; auto nonEmptyFile = testDir / "non_empty_file.txt"; std::filesystem::create_directory(emptyDir); std::ofstream(nonEmptyFile) << "non-empty content"; touch(emptyFile); REQUIRE(std::filesystem::exists(emptyFile)); REQUIRE(std::filesystem::exists(emptyDir)); REQUIRE(std::filesystem::exists(nonEmptyFile)); bool result = FsUtils::DeleteEmptyFilesAndDirs(testDir, false); REQUIRE(result == true); REQUIRE(!std::filesystem::exists(emptyFile)); REQUIRE(!std::filesystem::exists(emptyDir)); REQUIRE(std::filesystem::exists(nonEmptyFile)); std::filesystem::remove_all(testDir); } { std::filesystem::create_directories(testDir); auto nestedDir = testDir / "nested"; auto nestedEmptyFile = nestedDir / "empty_file_nested.txt"; auto nonEmptyFile = nestedDir / "non_empty_file_nested.txt"; std::filesystem::create_directories(nestedDir); touch(nestedEmptyFile); std::ofstream(nonEmptyFile) << "data"; REQUIRE(std::filesystem::exists(nestedDir)); REQUIRE(std::filesystem::exists(nestedEmptyFile)); REQUIRE(std::filesystem::exists(nonEmptyFile)); bool result = FsUtils::DeleteEmptyFilesAndDirs(testDir, true); REQUIRE(result == true); REQUIRE(!std::filesystem::exists(nestedEmptyFile)); REQUIRE(std::filesystem::exists(nonEmptyFile)); REQUIRE(std::filesystem::exists(nestedDir)); std::filesystem::remove_all(testDir); } { std::filesystem::create_directories(testDir); auto nonEmptyDir = testDir / "non_empty_dir"; auto nonEmptyFile = nonEmptyDir / "non_empty_file.txt"; std::filesystem::create_directory(nonEmptyDir); std::ofstream(nonEmptyFile) << "data"; bool result = FsUtils::DeleteEmptyFilesAndDirs(testDir, false); REQUIRE(result == false); REQUIRE(std::filesystem::exists(nonEmptyFile)); REQUIRE(std::filesystem::exists(nonEmptyDir)); std::filesystem::remove_all(testDir); } { std::filesystem::create_directories(testDir); auto emptyDir = testDir / "empty_dir"; std::filesystem::create_directory(emptyDir); REQUIRE(std::filesystem::exists(emptyDir)); bool result = FsUtils::DeleteEmptyFilesAndDirs(emptyDir, false); REQUIRE(result == false); REQUIRE(std::filesystem::exists(emptyDir)); std::filesystem::remove_all(testDir); } } TEST_CASE("GetDirFileAndDirCount", "[FsUtils]") { Logger::SetupLogger("", "tests.log"); const auto testDir = AppFolders::GetAppTempDir() / "count_test_directory"; { std::filesystem::create_directories(testDir); auto file1 = testDir / "file1.txt"; auto file2 = testDir / "file2.txt"; auto dir1 = testDir / "dir1"; auto dir2 = testDir / "dir2"; std::filesystem::create_directories(dir1); std::filesystem::create_directories(dir2); touch(file1); touch(file2); REQUIRE(std::filesystem::exists(file1)); REQUIRE(std::filesystem::exists(file2)); REQUIRE(std::filesystem::exists(dir1)); REQUIRE(std::filesystem::exists(dir2)); FsCount count = FsUtils::GetDirFileAndDirCount(testDir); REQUIRE(count.fileCount == 2); REQUIRE(count.dirCount == 2); std::filesystem::remove_all(testDir); } { std::filesystem::create_directories(testDir); auto emptyDir = testDir / "empty_dir"; std::filesystem::create_directory(emptyDir); REQUIRE(std::filesystem::exists(emptyDir)); FsCount count = FsUtils::GetDirFileAndDirCount(testDir); REQUIRE(count.fileCount == 0); REQUIRE(count.dirCount == 1); std::filesystem::remove_all(testDir); } }