mirror of
https://github.com/catchorg/Catch2.git
synced 2024-12-22 11:23:29 +01:00
Provide round-tripping serialization for TestSpec
This commit is contained in:
parent
c6dfeb5e7d
commit
e19ed221bd
@ -6,12 +6,14 @@
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
#include <catch2/catch_test_spec.hpp>
|
||||
#include <catch2/internal/catch_reusable_string_stream.hpp>
|
||||
#include <catch2/internal/catch_string_manip.hpp>
|
||||
#include <catch2/catch_test_case_info.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@ -35,6 +37,10 @@ namespace Catch {
|
||||
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 )
|
||||
@ -47,6 +53,10 @@ namespace Catch {
|
||||
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) {
|
||||
@ -63,18 +73,31 @@ namespace Catch {
|
||||
return should_use;
|
||||
}
|
||||
|
||||
std::string TestSpec::Filter::name() const {
|
||||
std::string name;
|
||||
for (auto const& p : m_required) {
|
||||
name += p->name();
|
||||
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& p : m_forbidden) {
|
||||
name += p->name();
|
||||
for ( auto const& pattern : m_forbidden ) {
|
||||
if ( !first ) {
|
||||
out << ' ';
|
||||
}
|
||||
out << *pattern;
|
||||
first = false;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
std::string TestSpec::extractFilterName( Filter const& filter ) {
|
||||
Catch::ReusableStringStream sstr;
|
||||
sstr << filter;
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
bool TestSpec::hasFilters() const {
|
||||
return !m_filters.empty();
|
||||
}
|
||||
@ -91,7 +114,7 @@ namespace Catch {
|
||||
for( auto const& test : testCases )
|
||||
if( isThrowSafe( test, config ) && filter.matches( test.getTestCaseInfo() ) )
|
||||
currentMatches.emplace_back( &test );
|
||||
return FilterMatch{ filter.name(), currentMatches };
|
||||
return FilterMatch{ extractFilterName(filter), currentMatches };
|
||||
} );
|
||||
return matches;
|
||||
}
|
||||
@ -100,4 +123,15 @@ namespace Catch {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <catch2/internal/catch_unique_ptr.hpp>
|
||||
#include <catch2/internal/catch_wildcard_pattern.hpp>
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -34,6 +35,14 @@ namespace Catch {
|
||||
virtual bool matches( TestCaseInfo const& testCase ) const = 0;
|
||||
std::string const& name() const;
|
||||
private:
|
||||
virtual void serializeTo( std::ostream& out ) const = 0;
|
||||
// Writes string that would be reparsed into the pattern
|
||||
friend std::ostream& operator<<(std::ostream& out,
|
||||
Pattern const& pattern) {
|
||||
pattern.serializeTo( out );
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string const m_name;
|
||||
};
|
||||
|
||||
@ -42,6 +51,8 @@ namespace Catch {
|
||||
explicit NamePattern( std::string const& name, std::string const& filterString );
|
||||
bool matches( TestCaseInfo const& testCase ) const override;
|
||||
private:
|
||||
void serializeTo( std::ostream& out ) const override;
|
||||
|
||||
WildcardPattern m_wildcardPattern;
|
||||
};
|
||||
|
||||
@ -50,6 +61,8 @@ namespace Catch {
|
||||
explicit TagPattern( std::string const& tag, std::string const& filterString );
|
||||
bool matches( TestCaseInfo const& testCase ) const override;
|
||||
private:
|
||||
void serializeTo( std::ostream& out ) const override;
|
||||
|
||||
std::string m_tag;
|
||||
};
|
||||
|
||||
@ -57,10 +70,19 @@ namespace Catch {
|
||||
std::vector<Detail::unique_ptr<Pattern>> m_required;
|
||||
std::vector<Detail::unique_ptr<Pattern>> m_forbidden;
|
||||
|
||||
//! Serializes this filter into a string that would be parsed into
|
||||
//! an equivalent filter
|
||||
void serializeTo( std::ostream& out ) const;
|
||||
friend std::ostream& operator<<(std::ostream& out, Filter const& f) {
|
||||
f.serializeTo( out );
|
||||
return out;
|
||||
}
|
||||
|
||||
bool matches( TestCaseInfo const& testCase ) const;
|
||||
std::string name() const;
|
||||
};
|
||||
|
||||
static std::string extractFilterName( Filter const& filter );
|
||||
|
||||
public:
|
||||
struct FilterMatch {
|
||||
std::string name;
|
||||
@ -77,7 +99,16 @@ namespace Catch {
|
||||
private:
|
||||
std::vector<Filter> m_filters;
|
||||
std::vector<std::string> m_invalidSpecs;
|
||||
|
||||
friend class TestSpecParser;
|
||||
//! Serializes this test spec into a string that would be parsed into
|
||||
//! equivalent test spec
|
||||
void serializeTo( std::ostream& out ) const;
|
||||
friend std::ostream& operator<<(std::ostream& out,
|
||||
TestSpec const& spec) {
|
||||
spec.serializeTo( out );
|
||||
return out;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,7 @@ add_test(NAME TestSpecs::CombiningMatchingAndNonMatchingIsOk-1 COMMAND $<TARGET_
|
||||
|
||||
add_test(NAME TestSpecs::CombiningMatchingAndNonMatchingIsOk-2 COMMAND $<TARGET_FILE:SelfTest> Tracker, "___nonexistent_test___")
|
||||
set_tests_properties(TestSpecs::CombiningMatchingAndNonMatchingIsOk-2 PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION "No test cases matched '___nonexistent_test___'"
|
||||
PASS_REGULAR_EXPRESSION "No test cases matched '\"___nonexistent_test___\"'"
|
||||
FAIL_REGULAR_EXPRESSION "No tests ran"
|
||||
)
|
||||
|
||||
|
@ -325,3 +325,40 @@ TEST_CASE("#1912 -- test spec parser handles escaping", "[command-line][test-spe
|
||||
REQUIRE(spec.matches(*fakeTestCase(R"(spec \ char)")));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Test spec serialization is round-trippable", "[test-spec][serialization][approvals]") {
|
||||
using Catch::parseTestSpec;
|
||||
using Catch::TestSpec;
|
||||
|
||||
auto serializedTestSpec = []( std::string const& spec ) {
|
||||
Catch::ReusableStringStream sstr;
|
||||
sstr << parseTestSpec( spec );
|
||||
return sstr.str();
|
||||
};
|
||||
|
||||
SECTION("Spaces are normalized") {
|
||||
CHECK( serializedTestSpec( "[abc][def]" ) == "[abc] [def]" );
|
||||
CHECK( serializedTestSpec( "[def] [abc]" ) == "[def] [abc]" );
|
||||
CHECK( serializedTestSpec( "[def] [abc]" ) == "[def] [abc]" );
|
||||
}
|
||||
SECTION("Output is order dependent") {
|
||||
CHECK( serializedTestSpec( "[abc][def]" ) == "[abc] [def]" );
|
||||
CHECK( serializedTestSpec( "[def][abc]" ) == "[def] [abc]" );
|
||||
}
|
||||
SECTION("Multiple disjunct filters") {
|
||||
CHECK( serializedTestSpec( "[abc],[def]" ) == "[abc],[def]" );
|
||||
CHECK( serializedTestSpec( "[def],[abc],[idkfa]" ) == "[def],[abc],[idkfa]" );
|
||||
}
|
||||
SECTION("Test names are enclosed in string") {
|
||||
CHECK( serializedTestSpec( "Some test" ) == "\"Some test\"" );
|
||||
CHECK( serializedTestSpec( "*Some test" ) == "\"*Some test\"" );
|
||||
CHECK( serializedTestSpec( "* Some test" ) == "\"* Some test\"" );
|
||||
CHECK( serializedTestSpec( "* Some test *" ) == "\"* Some test *\"" );
|
||||
}
|
||||
SECTION( "Mixing test names and tags" ) {
|
||||
CHECK( serializedTestSpec( "some test[abcd]" ) ==
|
||||
"\"some test\" [abcd]" );
|
||||
CHECK( serializedTestSpec( "[ab]some test[cd]" ) ==
|
||||
"[ab] \"some test\" [cd]" );
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user