/* * Cppcheck - A tool for static C/C++ code analysis * Copyright (C) 2007-2025 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "filelister.h" #include "filesettings.h" #include "fixture.h" #include "path.h" #include "pathmatch.h" #include "standards.h" #include #include #include #include class TestFileLister : public TestFixture { public: TestFileLister() : TestFixture("TestFileLister") {} private: void run() override { TEST_CASE(recursiveAddFiles); TEST_CASE(recursiveAddFilesEmptyPath); TEST_CASE(excludeFile1); TEST_CASE(excludeFile2); TEST_CASE(excludeDir); TEST_CASE(addFiles); } // TODO: generate file list instead static std::string findBaseDir() { std::string basedir; while (!Path::isDirectory(Path::join(basedir, ".github"))) { const std::string abspath = Path::getAbsoluteFilePath(basedir); basedir += "../"; // no more going up if (Path::getAbsoluteFilePath(basedir) == abspath) throw std::runtime_error("could not find repository root directory"); } return basedir; } void recursiveAddFiles() const { const std::string adddir = findBaseDir() + "."; // Recursively add add files.. std::list files; std::string err = FileLister::recursiveAddFiles(files, adddir, {}, PathMatch()); ASSERT_EQUALS("", err); ASSERT(!files.empty()); #ifdef _WIN32 std::string dirprefix; if (adddir != ".") dirprefix = adddir + "/"; #else const std::string dirprefix = adddir + "/"; #endif const auto find_file = [&](const std::string& name) { return std::find_if(files.cbegin(), files.cend(), [&name](const FileWithDetails& entry) { return entry.path() == name; }); }; // Make sure source files are added.. auto it = find_file(dirprefix + "cli/main.cpp"); ASSERT(it != files.end()); ASSERT_EQUALS_ENUM(Standards::Language::CPP, it->lang()); it = find_file(dirprefix + "lib/token.cpp"); ASSERT(it != files.end()); ASSERT_EQUALS_ENUM(Standards::Language::CPP, it->lang()); it = find_file(dirprefix + "lib/tokenize.cpp"); ASSERT(it != files.end()); ASSERT_EQUALS_ENUM(Standards::Language::CPP, it->lang()); it = find_file(dirprefix + "gui/main.cpp"); ASSERT(it != files.end()); ASSERT_EQUALS_ENUM(Standards::Language::CPP, it->lang()); it = find_file(dirprefix + "test/testfilelister.cpp"); ASSERT(it != files.end()); ASSERT_EQUALS_ENUM(Standards::Language::CPP, it->lang()); // Make sure headers are not added.. ASSERT(find_file(dirprefix + "lib/tokenize.h") == files.end()); } void recursiveAddFilesEmptyPath() const { std::list files; const std::string err = FileLister::recursiveAddFiles(files, "", {}, PathMatch()); ASSERT_EQUALS("no path specified", err); } void excludeFile1() const { const std::string basedir = findBaseDir(); std::list files; PathMatch matcher({"lib/token.cpp"}); std::string err = FileLister::recursiveAddFiles(files, basedir + "lib/token.cpp", {}, matcher); ASSERT_EQUALS("", err); ASSERT(files.empty()); } void excludeFile2() const { const std::string basedir = findBaseDir(); std::list files; std::string err = FileLister::recursiveAddFiles(files, basedir + "lib/token.cpp", {}, PathMatch()); ASSERT_EQUALS("", err); ASSERT_EQUALS(1, files.size()); ASSERT_EQUALS(basedir + "lib/token.cpp", files.begin()->path()); } void excludeDir() const { const std::string basedir = findBaseDir() + "."; std::list files; PathMatch matcher({"lib/"}); std::string err = FileLister::recursiveAddFiles(files, basedir, {}, matcher); ASSERT_EQUALS("", err); ASSERT(!files.empty()); const auto it = std::find_if(files.cbegin(), files.cend(), [](const FileWithDetails& f){ return f.spath().find("/lib/") != std::string::npos; }); ASSERT(it == files.cend()); } void addFiles() const { const std::string adddir = findBaseDir() + "."; // TODO: on Windows the prefix is different from when a recursive a folder (see recursiveAddFiles test) const std::string dirprefix = adddir + "/"; #ifdef _WIN32 const std::string dirprefix_nat = Path::toNativeSeparators(dirprefix); #endif std::list files; { const std::string addfile = Path::join(Path::join(adddir, "cli"), "main.cpp"); const std::string err = FileLister::addFiles(files, addfile, {}, true,PathMatch()); ASSERT_EQUALS("", err); } { const std::string addfile = Path::join(Path::join(adddir, "lib"), "token.cpp"); const std::string err = FileLister::addFiles(files, addfile, {}, true,PathMatch()); ASSERT_EQUALS("", err); } { const std::string addfile = Path::join(Path::join(adddir, "cli"), "token.cpp"); // does not exist const std::string err = FileLister::addFiles(files, addfile, {}, true,PathMatch()); ASSERT_EQUALS("", err); } { const std::string addfile = Path::join(Path::join(adddir, "lib2"), "token.cpp"); // does not exist const std::string err = FileLister::addFiles(files, addfile, {}, true,PathMatch()); ASSERT_EQUALS("", err); } { const std::string addfile = Path::join(Path::join(adddir, "lib"), "matchcompiler.h"); const std::string err = FileLister::addFiles(files, addfile, {}, true,PathMatch()); ASSERT_EQUALS("", err); } ASSERT_EQUALS(3, files.size()); auto it = files.cbegin(); ASSERT_EQUALS(dirprefix + "cli/main.cpp", it->path()); ASSERT_EQUALS(Path::simplifyPath(dirprefix + "cli/main.cpp"), it->spath()); ASSERT_EQUALS_ENUM(Standards::Language::None, it->lang()); it++; ASSERT_EQUALS(dirprefix + "lib/token.cpp", it->path()); ASSERT_EQUALS(Path::simplifyPath(dirprefix + "lib/token.cpp"), it->spath()); ASSERT_EQUALS_ENUM(Standards::Language::None, it->lang()); it++; ASSERT_EQUALS(dirprefix + "lib/matchcompiler.h", it->path()); ASSERT_EQUALS(Path::simplifyPath(dirprefix + "lib/matchcompiler.h"), it->spath()); ASSERT_EQUALS_ENUM(Standards::Language::None, it->lang()); } // TODO: test errors // TODO: test wildcards }; REGISTER_TEST(TestFileLister)