diff --git a/source/test/SingleFile.hpp b/source/test/SingleFile.hpp index 59a27f483..2d2613627 100644 --- a/source/test/SingleFile.hpp +++ b/source/test/SingleFile.hpp @@ -15,6 +15,7 @@ #include #include #include +#include "TestConfig.hpp" namespace clang { namespace mrdox { @@ -25,22 +26,29 @@ class SingleFile : public tooling::CompilationDatabase { std::vector cc_; - public: SingleFile( llvm::StringRef dir, - llvm::StringRef file) + llvm::StringRef file, + const TestConfig &tc) { std::vector cmds; cmds.emplace_back("clang"); - cmds.emplace_back("-std=c++20"); + { + char buf[64]; + snprintf(buf, 63, "-std=%s", tc.cxxstd.c_str()); + cmds.emplace_back(buf); + } + for (const auto & fl : tc.compile_flags) + cmds.emplace_back(fl); + cmds.emplace_back(file); cc_.emplace_back( dir, file, std::move(cmds), dir); - cc_.back().Heuristic = "unit test"; + cc_.back().Heuristic = tc.heuristics; } std::vector diff --git a/source/test/TestConfig.cpp b/source/test/TestConfig.cpp new file mode 100644 index 000000000..c27ac5293 --- /dev/null +++ b/source/test/TestConfig.cpp @@ -0,0 +1,72 @@ +`// This is a derivative work. originally part of the LLVM Project. +// Licensed 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 +// +// Copyright (c) 2023 Klemens D. Morgenstern +// + +#include "TestConfig.hpp" +#include +#include +#include +#include +#include + + +template<> +struct llvm::yaml::MappingTraits< + clang::mrdox::TestConfig> +{ + static void mapping(IO &io, + clang::mrdox::TestConfig& f) + { + io.mapOptional("cxxstd", f.cxxstd); + io.mapOptional("compile-flags", f.compile_flags); + io.mapOptional("should-fail", f.should_fail); + io.mapOptional("heuristics", f.heuristics); + } +}; + +namespace clang { +namespace mrdox { + +llvm::Expected> +TestConfig::loadForTest( + llvm::StringRef dir, + llvm::StringRef file) +{ + namespace fs = llvm::sys::fs; + namespace path = llvm::sys::path; + + llvm::SmallString<256> filePath = file; + path::replace_extension(filePath, "yml"); + + if (!fs::exists(filePath)) + { + filePath = dir; + filePath.append("/mrdox-test.yml"); + } + + if (fs::exists(filePath)) + { + auto fileText = llvm::MemoryBuffer::getFile(filePath); + if(! fileText) + return makeError(fileText.getError().message(), " when loading file '", filePath, "' "); + llvm::yaml::Input yin(**fileText); + + std::vector res; + do + { + yin >> res.emplace_back(); + if (auto ec = yin.error()) + return makeError(ec.message(), " when parsing file '", filePath, "' "); + } + while (yin.nextDocument()); + return res; + } + return std::vector{TestConfig{}}; +} + +} +} \ No newline at end of file diff --git a/source/test/TestConfig.hpp b/source/test/TestConfig.hpp new file mode 100644 index 000000000..3cacf3d97 --- /dev/null +++ b/source/test/TestConfig.hpp @@ -0,0 +1,43 @@ +// This is a derivative work. originally part of the LLVM Project. +// Licensed 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 +// +// Copyright (c) 2023 Klemens D. Morgenstern +// + +#ifndef MRDOX_TEST_CONFIG_HPP +#define MRDOX_TEST_CONFIG_HPP + +#include + +#include +#include + +#include +#include + +namespace clang { +namespace mrdox { + +struct TestConfig +{ + std::string cxxstd = "c++20"; + std::vector compile_flags; + bool should_fail = false; + std::string heuristics = "unit test"; + + MRDOX_DECL + static + llvm::Expected> + loadForTest( + llvm::StringRef dir, + llvm::StringRef file); +}; + + +} +} + + +#endif //MRDOX_TEST_CONFIG_HPP diff --git a/source/test/TestMain.cpp b/source/test/TestMain.cpp index 573d4143f..5c456fda0 100644 --- a/source/test/TestMain.cpp +++ b/source/test/TestMain.cpp @@ -10,6 +10,7 @@ #include "Options.hpp" #include "SingleFile.hpp" +#include "TestConfig.hpp" #include #include #include @@ -77,6 +78,8 @@ class Instance Generator const* xmlGen_; Generator const* adocGen_; + TestConfig testConfig_; + void setConfig( std::shared_ptr config); @@ -184,11 +187,24 @@ handleFile( // Build Corpus std::unique_ptr corpus; + + auto tcs = TestConfig::loadForTest(dirPath, filePath); + if (!tcs) + return tcs.takeError(); + + for (const auto & tc : *tcs) { - SingleFile db(dirPath, filePath); + SingleFile db(dirPath, filePath, tc); tooling::StandaloneToolExecutor ex(db, { std::string(filePath) }); auto result = Corpus::build(ex, config_, R_); - if(R_.error(result, "build Corpus for '", filePath, "'")) + + if (tc.should_fail && result) + { + R_.failed("build Corpus for '", filePath, "' should have failed"); + results_.numberOfErrors++; + return llvm::Error::success(); // keep going + } + else if (R_.error(result, "build Corpus for '", filePath, "'")) { results_.numberOfErrors++; return llvm::Error::success(); // keep going diff --git a/test-files/old-tests/attributes_1.yml b/test-files/old-tests/attributes_1.yml new file mode 100644 index 000000000..471caf17a --- /dev/null +++ b/test-files/old-tests/attributes_1.yml @@ -0,0 +1,4 @@ +cxxstd: c++20 +... +--- +cxxstd: c++17 diff --git a/test-files/old-tests/mrdox-test.yml b/test-files/old-tests/mrdox-test.yml new file mode 100644 index 000000000..7174d06da --- /dev/null +++ b/test-files/old-tests/mrdox-test.yml @@ -0,0 +1,4 @@ +cxxstd: c++20 +... +--- +cxxstd: c++17 \ No newline at end of file