// Copyright Catch2 Authors // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE.txt or copy at // https://www.boost.org/LICENSE_1_0.txt) // SPDX-License-Identifier: BSL-1.0 #include #include #include #include #include #include #include #include namespace Catch { void ITestInvoker::prepareTestCase() {} void ITestInvoker::tearDownTestCase() {} ITestInvoker::~ITestInvoker() = default; namespace { static StringRef extractClassName( StringRef classOrMethodName ) { if ( !startsWith( classOrMethodName, '&' ) ) { return classOrMethodName; } // Remove the leading '&' to avoid having to special case it later const auto methodName = classOrMethodName.substr( 1, classOrMethodName.size() ); auto reverseStart = std::make_reverse_iterator( methodName.end() ); auto reverseEnd = std::make_reverse_iterator( methodName.begin() ); // We make a simplifying assumption that ":" is only present // in the input as part of "::" from C++ typenames (this is // relatively safe assumption because the input is generated // as stringification of type through preprocessor). auto lastColons = std::find( reverseStart, reverseEnd, ':' ) + 1; auto secondLastColons = std::find( lastColons + 1, reverseEnd, ':' ); auto const startIdx = reverseEnd - secondLastColons; auto const classNameSize = secondLastColons - lastColons - 1; return methodName.substr( static_cast( startIdx ), static_cast( classNameSize ) ); } class TestInvokerAsFunction final : public ITestInvoker { using TestType = void ( * )(); TestType m_testAsFunction; public: constexpr TestInvokerAsFunction( TestType testAsFunction ) noexcept: m_testAsFunction( testAsFunction ) {} void invoke() const override { m_testAsFunction(); } }; } // namespace Detail::unique_ptr makeTestInvoker( void(*testAsFunction)() ) { return Detail::make_unique( testAsFunction ); } AutoReg::AutoReg( Detail::unique_ptr invoker, SourceLineInfo const& lineInfo, StringRef classOrMethod, NameAndTags const& nameAndTags ) noexcept { CATCH_TRY { getMutableRegistryHub() .registerTest( makeTestCaseInfo( extractClassName( classOrMethod ), nameAndTags, lineInfo), CATCH_MOVE(invoker) ); } CATCH_CATCH_ALL { // Do not throw when constructing global objects, instead register the exception to be processed later getMutableRegistryHub().registerStartupException(); } } }