mirror of
https://github.com/catchorg/Catch2.git
synced 2025-01-16 07:08:01 +00:00
Compare commits
3 Commits
8dd25b0410
...
ff349a50bf
Author | SHA1 | Date | |
---|---|---|---|
|
ff349a50bf | ||
|
aca2472d40 | ||
|
765ac08f08 |
@ -14,7 +14,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
endif()
|
||||
|
||||
|
||||
project(Catch2 LANGUAGES CXX VERSION 2.13.2)
|
||||
project(Catch2 LANGUAGES CXX VERSION 2.13.3)
|
||||
|
||||
# Provide path for scripts
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
||||
|
@ -9,7 +9,7 @@
|
||||
[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
|
||||
|
||||
|
||||
<a href="https://github.com/catchorg/Catch2/releases/download/v2.13.2/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
|
||||
<a href="https://github.com/catchorg/Catch2/releases/download/v2.13.3/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
|
||||
|
||||
## Catch2 is released!
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
# Release notes
|
||||
**Contents**<br>
|
||||
[2.13.3](#2133)<br>
|
||||
[2.13.2](#2132)<br>
|
||||
[2.13.1](#2131)<br>
|
||||
[2.13.0](#2130)<br>
|
||||
@ -43,6 +44,17 @@
|
||||
[Even Older versions](#even-older-versions)<br>
|
||||
|
||||
|
||||
## 2.13.3
|
||||
|
||||
### Fixes
|
||||
* Fixed possible infinite loop when combining generators with section filter (`-c` option) (#2025)
|
||||
|
||||
### Miscellaneous
|
||||
* Fixed `ParseAndAddCatchTests` not finding `TEST_CASE`s without tags (#2055, #2056)
|
||||
* `ParseAndAddCatchTests` supports `CMP0110` policy for changing behaviour of `add_test` (#2057)
|
||||
* This was the shortlived change in CMake 3.18.0 that temporarily broke `ParseAndAddCatchTests`
|
||||
|
||||
|
||||
## 2.13.2
|
||||
|
||||
### Improvements
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#define CATCH_VERSION_MAJOR 2
|
||||
#define CATCH_VERSION_MINOR 13
|
||||
#define CATCH_VERSION_PATCH 2
|
||||
#define CATCH_VERSION_PATCH 3
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang system_header
|
||||
|
@ -71,13 +71,53 @@ namespace Catch {
|
||||
// `SECTION`s.
|
||||
// **The check for m_children.empty cannot be removed**.
|
||||
// doing so would break `GENERATE` _not_ followed by `SECTION`s.
|
||||
const bool should_wait_for_child =
|
||||
!m_children.empty() &&
|
||||
std::find_if( m_children.begin(),
|
||||
m_children.end(),
|
||||
[]( TestCaseTracking::ITrackerPtr tracker ) {
|
||||
return tracker->hasStarted();
|
||||
} ) == m_children.end();
|
||||
const bool should_wait_for_child = [&]() {
|
||||
// No children -> nobody to wait for
|
||||
if ( m_children.empty() ) {
|
||||
return false;
|
||||
}
|
||||
// If at least one child started executing, don't wait
|
||||
if ( std::find_if(
|
||||
m_children.begin(),
|
||||
m_children.end(),
|
||||
[]( TestCaseTracking::ITrackerPtr tracker ) {
|
||||
return tracker->hasStarted();
|
||||
} ) != m_children.end() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No children have started. We need to check if they _can_
|
||||
// start, and thus we should wait for them, or they cannot
|
||||
// start (due to filters), and we shouldn't wait for them
|
||||
auto* parent = m_parent;
|
||||
// This is safe: there is always at least one section
|
||||
// tracker in a test case tracking tree
|
||||
while ( !parent->isSectionTracker() ) {
|
||||
parent = &( parent->parent() );
|
||||
}
|
||||
assert( parent &&
|
||||
"Missing root (test case) level section" );
|
||||
|
||||
auto const& parentSection =
|
||||
static_cast<SectionTracker&>( *parent );
|
||||
auto const& filters = parentSection.getFilters();
|
||||
// No filters -> no restrictions on running sections
|
||||
if ( filters.empty() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for ( auto const& child : m_children ) {
|
||||
if ( child->isSectionTracker() &&
|
||||
std::find( filters.begin(),
|
||||
filters.end(),
|
||||
static_cast<SectionTracker&>( *child )
|
||||
.trimmedName() ) !=
|
||||
filters.end() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
|
||||
// This check is a bit tricky, because m_generator->next()
|
||||
// has a side-effect, where it consumes generator's current
|
||||
|
@ -233,6 +233,14 @@ namespace TestCaseTracking {
|
||||
m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
|
||||
}
|
||||
|
||||
std::vector<std::string> const& SectionTracker::getFilters() const {
|
||||
return m_filters;
|
||||
}
|
||||
|
||||
std::string const& SectionTracker::trimmedName() const {
|
||||
return m_trimmed_name;
|
||||
}
|
||||
|
||||
} // namespace TestCaseTracking
|
||||
|
||||
using TestCaseTracking::ITracker;
|
||||
|
@ -163,6 +163,10 @@ namespace TestCaseTracking {
|
||||
|
||||
void addInitialFilters( std::vector<std::string> const& filters );
|
||||
void addNextFilters( std::vector<std::string> const& filters );
|
||||
//! Returns filters active in this tracker
|
||||
std::vector<std::string> const& getFilters() const;
|
||||
//! Returns whitespace-trimmed name of the tracked section
|
||||
std::string const& trimmedName() const;
|
||||
};
|
||||
|
||||
} // namespace TestCaseTracking
|
||||
|
@ -37,7 +37,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 2, 13, 2, "", 0 );
|
||||
static Version version( 2, 13, 3, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
|
@ -419,6 +419,33 @@ set_tests_properties(FilteredSection-1 PROPERTIES FAIL_REGULAR_EXPRESSION "No te
|
||||
add_test(NAME FilteredSection-2 COMMAND $<TARGET_FILE:SelfTest> \#1394\ nested -c NestedRunSection -c s1)
|
||||
set_tests_properties(FilteredSection-2 PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran")
|
||||
|
||||
add_test(
|
||||
NAME
|
||||
FilteredSection::GeneratorsDontCauseInfiniteLoop-1
|
||||
COMMAND
|
||||
$<TARGET_FILE:SelfTest> "#2025: original repro" -c "fov_0"
|
||||
)
|
||||
set_tests_properties(FilteredSection::GeneratorsDontCauseInfiniteLoop-1
|
||||
PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION "inside with fov: 0" # This should happen
|
||||
FAIL_REGULAR_EXPRESSION "inside with fov: 1" # This would mean there was no filtering
|
||||
)
|
||||
|
||||
# GENERATE between filtered sections (both are selected)
|
||||
add_test(
|
||||
NAME
|
||||
FilteredSection::GeneratorsDontCauseInfiniteLoop-2
|
||||
COMMAND
|
||||
$<TARGET_FILE:SelfTest> "#2025: same-level sections"
|
||||
-c "A"
|
||||
-c "B"
|
||||
)
|
||||
set_tests_properties(FilteredSection::GeneratorsDontCauseInfiniteLoop-2
|
||||
PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION "All tests passed \\(4 assertions in 1 test case\\)"
|
||||
)
|
||||
|
||||
|
||||
# AppVeyor has a Python 2.7 in path, but doesn't have .py files as autorunnable
|
||||
add_test(NAME ApprovalTests COMMAND ${PYTHON_EXECUTABLE} ${CATCH_DIR}/scripts/approvalTests.py $<TARGET_FILE:SelfTest>)
|
||||
set_tests_properties(ApprovalTests PROPERTIES FAIL_REGULAR_EXPRESSION "Results differed")
|
||||
|
@ -402,3 +402,28 @@ TEST_CASE("#1514: stderr/stdout is not captured in tests aborted by an exception
|
||||
// FAIL aborts the test by throwing a Catch exception
|
||||
FAIL("1514");
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE( "#2025: -c shouldn't cause infinite loop", "[sections][generators][regression][.approvals]" ) {
|
||||
SECTION( "Check cursor from buffer offset" ) {
|
||||
auto bufPos = GENERATE_REF( range( 0, 44 ) );
|
||||
WHEN( "Buffer position is " << bufPos ) { REQUIRE( 1 == 1 ); }
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("#2025: original repro", "[sections][generators][regression][.approvals]") {
|
||||
auto fov = GENERATE(true, false);
|
||||
DYNAMIC_SECTION("fov_" << fov) {
|
||||
std::cout << "inside with fov: " << fov << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("#2025: same-level sections", "[sections][generators][regression][.approvals]") {
|
||||
SECTION("A") {
|
||||
SUCCEED();
|
||||
}
|
||||
auto i = GENERATE(1, 2, 3);
|
||||
SECTION("B") {
|
||||
REQUIRE(i < 4);
|
||||
}
|
||||
}
|
||||
|
@ -79,13 +79,15 @@ class Version:
|
||||
f.write( line + "\n" )
|
||||
|
||||
def updateReadmeFile(version):
|
||||
import updateWandbox
|
||||
|
||||
# Wandbox no longer accepts the single-header upload, skip
|
||||
# import updateWandbox
|
||||
|
||||
downloadParser = re.compile( r'<a href=\"https://github.com/catchorg/Catch2/releases/download/v\d+\.\d+\.\d+/catch.hpp\">' )
|
||||
success, wandboxLink = updateWandbox.uploadFiles()
|
||||
if not success:
|
||||
print('Error when uploading to wandbox: {}'.format(wandboxLink))
|
||||
exit(1)
|
||||
# success, wandboxLink = updateWandbox.uploadFiles()
|
||||
# if not success:
|
||||
# print('Error when uploading to wandbox: {}'.format(wandboxLink))
|
||||
# exit(1)
|
||||
f = open( readmePath, 'r' )
|
||||
lines = []
|
||||
for line in f:
|
||||
@ -94,8 +96,8 @@ def updateReadmeFile(version):
|
||||
f = open( readmePath, 'w' )
|
||||
for line in lines:
|
||||
line = downloadParser.sub( r'<a href="https://github.com/catchorg/Catch2/releases/download/v{0}/catch.hpp">'.format(version.getVersionString()) , line)
|
||||
if '[![Try online](https://img.shields.io/badge/try-online-blue.svg)]' in line:
|
||||
line = '[![Try online](https://img.shields.io/badge/try-online-blue.svg)]({0})'.format(wandboxLink)
|
||||
# if '[![Try online](https://img.shields.io/badge/try-online-blue.svg)]' in line:
|
||||
# line = '[![Try online](https://img.shields.io/badge/try-online-blue.svg)]({0})'.format(wandboxLink)
|
||||
f.write( line + "\n" )
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Catch v2.13.2
|
||||
* Generated: 2020-10-07 11:32:53.302017
|
||||
* Catch v2.13.3
|
||||
* Generated: 2020-10-31 18:20:31.045274
|
||||
* ----------------------------------------------------------
|
||||
* This file has been merged from multiple headers. Please don't edit it directly
|
||||
* Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved.
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
#define CATCH_VERSION_MAJOR 2
|
||||
#define CATCH_VERSION_MINOR 13
|
||||
#define CATCH_VERSION_PATCH 2
|
||||
#define CATCH_VERSION_PATCH 3
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang system_header
|
||||
@ -7602,6 +7602,10 @@ namespace TestCaseTracking {
|
||||
|
||||
void addInitialFilters( std::vector<std::string> const& filters );
|
||||
void addNextFilters( std::vector<std::string> const& filters );
|
||||
//! Returns filters active in this tracker
|
||||
std::vector<std::string> const& getFilters() const;
|
||||
//! Returns whitespace-trimmed name of the tracked section
|
||||
std::string const& trimmedName() const;
|
||||
};
|
||||
|
||||
} // namespace TestCaseTracking
|
||||
@ -12571,13 +12575,53 @@ namespace Catch {
|
||||
// `SECTION`s.
|
||||
// **The check for m_children.empty cannot be removed**.
|
||||
// doing so would break `GENERATE` _not_ followed by `SECTION`s.
|
||||
const bool should_wait_for_child =
|
||||
!m_children.empty() &&
|
||||
std::find_if( m_children.begin(),
|
||||
m_children.end(),
|
||||
[]( TestCaseTracking::ITrackerPtr tracker ) {
|
||||
return tracker->hasStarted();
|
||||
} ) == m_children.end();
|
||||
const bool should_wait_for_child = [&]() {
|
||||
// No children -> nobody to wait for
|
||||
if ( m_children.empty() ) {
|
||||
return false;
|
||||
}
|
||||
// If at least one child started executing, don't wait
|
||||
if ( std::find_if(
|
||||
m_children.begin(),
|
||||
m_children.end(),
|
||||
[]( TestCaseTracking::ITrackerPtr tracker ) {
|
||||
return tracker->hasStarted();
|
||||
} ) != m_children.end() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No children have started. We need to check if they _can_
|
||||
// start, and thus we should wait for them, or they cannot
|
||||
// start (due to filters), and we shouldn't wait for them
|
||||
auto* parent = m_parent;
|
||||
// This is safe: there is always at least one section
|
||||
// tracker in a test case tracking tree
|
||||
while ( !parent->isSectionTracker() ) {
|
||||
parent = &( parent->parent() );
|
||||
}
|
||||
assert( parent &&
|
||||
"Missing root (test case) level section" );
|
||||
|
||||
auto const& parentSection =
|
||||
static_cast<SectionTracker&>( *parent );
|
||||
auto const& filters = parentSection.getFilters();
|
||||
// No filters -> no restrictions on running sections
|
||||
if ( filters.empty() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for ( auto const& child : m_children ) {
|
||||
if ( child->isSectionTracker() &&
|
||||
std::find( filters.begin(),
|
||||
filters.end(),
|
||||
static_cast<SectionTracker&>( *child )
|
||||
.trimmedName() ) !=
|
||||
filters.end() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
|
||||
// This check is a bit tricky, because m_generator->next()
|
||||
// has a side-effect, where it consumes generator's current
|
||||
@ -14449,6 +14493,14 @@ namespace TestCaseTracking {
|
||||
m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
|
||||
}
|
||||
|
||||
std::vector<std::string> const& SectionTracker::getFilters() const {
|
||||
return m_filters;
|
||||
}
|
||||
|
||||
std::string const& SectionTracker::trimmedName() const {
|
||||
return m_trimmed_name;
|
||||
}
|
||||
|
||||
} // namespace TestCaseTracking
|
||||
|
||||
using TestCaseTracking::ITracker;
|
||||
@ -15264,7 +15316,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 2, 13, 2, "", 0 );
|
||||
static Version version( 2, 13, 3, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user