diff options
| author | Leitwolf11 | 2026-10-25 02:37:35 +0300 |
|---|---|---|
| committer | Leitwolf11 | 2026-10-25 02:37:35 +0300 |
| commit | 126dc333564cb72b5115d9a9242d66694694b6d0 (patch) | |
| tree | 0bce4462b2e190c39b3e1c5f697e3e4abd1a5e2a /src/Progmasoft/Catch3/TestSpec.cpp | |
| parent | 13f81a480a93807c14dddb5abdb97355ced4d4c5 (diff) | |
| download | catch3-126dc333564cb72b5115d9a9242d66694694b6d0.tar.gz | |
Give Catch3 its own build names and headers
Catch2 compatibility means the API tests are written in: the macros, such
as TEST_CASE and REQUIRE, and the Catch:: namespace. It does not mean
Catch2's build names or header paths. find_package(Catch2) found Catch3,
and a project using both frameworks met two packages, two sets of targets,
two Catch.cmake modules and two catch2/ header trees with the same names.
Build names:
- CMake: project and package Catch3, targets Catch3::Catch3 and
Catch3::Catch3WithMain, libraries Catch3 and Catch3Main, options
CATCH3_*, lib/cmake/Catch3 with Catch3Config, and pkg-config catch3 and
catch3-with-main. The version is Catch3's, 0.3.0, compatible within a
minor version.
- The CMake scripts are Catch3.cmake (catch3_discover_tests),
Catch3AddTests.cmake and Catch3ShardTests.cmake
(catch3_add_sharded_tests); the helpers they define at ctest time have a
catch3_ prefix. ParseAndAddCatchTests.cmake, deprecated upstream, is gone.
- Bazel //:catch3 and //:catch3_main, Meson catch3 and catch3-with-main
(with override_dependency), Xmake catch3 and catch3_main, Premake Catch3
and Catch3WithMain. Visual Studio projects get GUIDs of their own.
- The Progmasoft::Catch3 target and package are gone: property testing
and snapshots are part of Catch3::Catch3. Their sources now build with
the library's warning flags, so property failures are built field by
field (no missing initializers) and the default property name is a
thread-local pointer to the name its scope owns (no global destructor).
Headers: the engine moved from src/catch2 to src/Progmasoft/Catch3 with
Progmasoft names, so <catch2/catch_test_macros.hpp> is
<Progmasoft/Catch3/TestMacros.hpp>, <catch2/matchers/catch_matchers_string.hpp>
is <Progmasoft/Catch3/Matchers/String.hpp>, and interface headers are named
after their interface, such as Interfaces/IConfig.hpp. Include guards
became #pragma once. The installed headers go to include/Progmasoft.
src/Progmasoft/Context.cpp is StrategyContext.cpp, so no two sources share
a file name.
tools/scripts/upstreamFiles.txt lists the files that come from Catch2.
The license check expects BSL-1.0 on them and Progmasoft's header on the
rest of src/Progmasoft; the convenience-header check, the amalgamation
script and the surrogate tests take the engine's headers from it. The
amalgamated files are regenerated. The header-guard workflow checks for
#pragma once instead of checkguard.
Documents, the README and the release notes describe the new names.
Diffstat (limited to 'src/Progmasoft/Catch3/TestSpec.cpp')
| -rw-r--r-- | src/Progmasoft/Catch3/TestSpec.cpp | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/Progmasoft/Catch3/TestSpec.cpp b/src/Progmasoft/Catch3/TestSpec.cpp new file mode 100644 index 00000000..5b789e66 --- /dev/null +++ b/src/Progmasoft/Catch3/TestSpec.cpp @@ -0,0 +1,143 @@ + +// 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 <Progmasoft/Catch3/TestSpec.hpp> +#include <Progmasoft/Catch3/Interfaces/ITestCaseRegistry.hpp> +#include <Progmasoft/Catch3/Internal/TestCaseRegistryImpl.hpp> +#include <Progmasoft/Catch3/Internal/ReusableStringStream.hpp> +#include <Progmasoft/Catch3/Internal/StringManip.hpp> +#include <Progmasoft/Catch3/TestCaseInfo.hpp> + +#include <algorithm> +#include <string> +#include <vector> +#include <ostream> + +namespace Catch { + + TestSpec::Pattern::Pattern( std::string const& name ) + : m_name( name ) + {} + + TestSpec::Pattern::~Pattern() = default; + + std::string const& TestSpec::Pattern::name() const { + return m_name; + } + + + TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString ) + : Pattern( filterString ) + , m_wildcardPattern( name, CaseSensitive::No ) + {} + + bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const { + return m_wildcardPattern.matches( testCase.name ); + } + + void TestSpec::NamePattern::serializeTo( std::ostream& out ) const { + out << '"' << name() << '"'; + } + + + TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString ) + : Pattern( filterString ) + , m_tag( tag ) + {} + + bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const { + return std::find( begin( testCase.tags ), + end( testCase.tags ), + Tag( m_tag ) ) != end( testCase.tags ); + } + + void TestSpec::TagPattern::serializeTo( std::ostream& out ) const { + out << name(); + } + + bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const { + bool should_use = !testCase.isHidden(); + for (auto const& pattern : m_required) { + should_use = true; + if (!pattern->matches(testCase)) { + return false; + } + } + for (auto const& pattern : m_forbidden) { + if (pattern->matches(testCase)) { + return false; + } + } + return should_use; + } + + void TestSpec::Filter::serializeTo( std::ostream& out ) const { + bool first = true; + for ( auto const& pattern : m_required ) { + if ( !first ) { + out << ' '; + } + out << *pattern; + first = false; + } + for ( auto const& pattern : m_forbidden ) { + if ( !first ) { + out << ' '; + } + out << *pattern; + first = false; + } + } + + + std::string TestSpec::extractFilterName( Filter const& filter ) { + Catch::ReusableStringStream sstr; + sstr << filter; + return sstr.str(); + } + + bool TestSpec::hasFilters() const { + return !m_filters.empty(); + } + + bool TestSpec::matches( TestCaseInfo const& testCase ) const { + return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } ); + } + + TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCaseHandle> const& testCases, IConfig const& config ) const { + Matches matches; + matches.reserve( m_filters.size() ); + for ( auto const& filter : m_filters ) { + std::vector<TestCaseHandle const*> currentMatches; + for ( auto const& test : testCases ) { + if ( isThrowSafe( test, config ) && + filter.matches( test.getTestCaseInfo() ) ) { + currentMatches.emplace_back( &test ); + } + } + matches.push_back( FilterMatch{ extractFilterName( filter ), + CATCH_MOVE( currentMatches ) } ); + } + return matches; + } + + const TestSpec::vectorStrings& TestSpec::getInvalidSpecs() const { + return m_invalidSpecs; + } + + void TestSpec::serializeTo( std::ostream& out ) const { + bool first = true; + for ( auto const& filter : m_filters ) { + if ( !first ) { + out << ','; + } + out << filter; + first = false; + } + } + +} |