diff --git a/CMakeLists.txt b/CMakeLists.txt
index 09793f7b..8cc1ca31 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,7 @@ if(NOT DEFINED PROJECT_NAME)
set(NOT_SUBPROJECT ON)
endif()
-project(Catch2 LANGUAGES CXX VERSION 2.4.1)
+project(Catch2 LANGUAGES CXX VERSION 2.4.2)
# Provide path for scripts
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
diff --git a/README.md b/README.md
index 73162bbf..e84306c5 100644
--- a/README.md
+++ b/README.md
@@ -5,11 +5,11 @@
[![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
[![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
[![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
-[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/E0msqwbW7U4PVbHn)
+[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/rbkudthN4hBNJznk)
[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
-The latest version of the single header can be downloaded directly using this link
+The latest version of the single header can be downloaded directly using this link
## Catch2 is released!
diff --git a/conanfile.py b/conanfile.py
index 19b2c65e..b99f314d 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -4,7 +4,7 @@ from conans import ConanFile, CMake
class CatchConan(ConanFile):
name = "Catch"
- version = "2.4.1"
+ version = "2.4.2"
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
author = "philsquared"
generators = "cmake"
diff --git a/docs/release-notes.md b/docs/release-notes.md
index f31f0e87..16f9cc5b 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -2,6 +2,7 @@
# Release notes
**Contents**
+[2.4.2](#242)
[2.4.1](#241)
[2.4.0](#240)
[2.3.0](#230)
@@ -17,6 +18,29 @@
[Even Older versions](#even-older-versions)
+## 2.4.2
+
+### Improvements
+* XmlReporter now also outputs the RNG seed that was used in a run (#1404)
+* `Catch::Session::applyCommandLine` now also accepts `wchar_t` arguments.
+ * However, Catch2 still does not support unicode.
+* Added `STATIC_REQUIRE` macro (#1356, #1362)
+* Catch2's singleton's are now cleaned up even if tests are run (#1411)
+ * This is mostly useful as a FP prevention for users who define their own main.
+* Specifying an invalid reporter via `-r` is now reported sooner (#1351, #1422)
+
+
+### Fixes
+* Stringification no longer assumes that `char` is signed (#1399, #1407)
+ * This caused a `Wtautological-compare` warning.
+* SFINAE for `operator<<` no longer sees different overload set than the actual insertion (#1403)
+
+
+### Contrib
+* `catch_discover_tests` correctly adds tests with comma in name (#1327, #1409)
+* Added a new customization point in how the tests are launched to `catch_discover_tests`
+
+
## 2.4.1
### Improvements
diff --git a/include/catch.hpp b/include/catch.hpp
index f6786e8d..84b9f466 100644
--- a/include/catch.hpp
+++ b/include/catch.hpp
@@ -11,7 +11,7 @@
#define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 4
-#define CATCH_VERSION_PATCH 1
+#define CATCH_VERSION_PATCH 2
#ifdef __clang__
# pragma clang system_header
diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp
index a57553c0..690d4f7b 100644
--- a/include/internal/catch_version.cpp
+++ b/include/internal/catch_version.cpp
@@ -37,7 +37,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 4, 1, "", 0 );
+ static Version version( 2, 4, 2, "", 0 );
return version;
}
diff --git a/single_include/catch2/catch.hpp b/single_include/catch2/catch.hpp
index 4191607a..b324e56a 100644
--- a/single_include/catch2/catch.hpp
+++ b/single_include/catch2/catch.hpp
@@ -1,6 +1,6 @@
/*
- * Catch v2.4.1
- * Generated: 2018-09-28 15:50:15.645795
+ * Catch v2.4.2
+ * Generated: 2018-10-26 21:12:29.223927
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.
@@ -15,7 +15,7 @@
#define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 4
-#define CATCH_VERSION_PATCH 1
+#define CATCH_VERSION_PATCH 2
#ifdef __clang__
# pragma clang system_header
@@ -356,6 +356,10 @@ namespace Catch {
#include
#include
+// We need a dummy global operator<< so we can bring it into Catch namespace later
+struct Catch_global_namespace_dummy {};
+std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
+
namespace Catch {
struct CaseSensitive { enum Choice {
@@ -397,6 +401,11 @@ namespace Catch {
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
+ // Bring in operator<< from global namespace into Catch namespace
+ // This is necessary because the overload of operator<< above makes
+ // lookup stop at namespace Catch
+ using ::operator<<;
+
// Use this in variadic streaming macros to allow
// >> +StreamEndStop
// as well as
@@ -850,14 +859,7 @@ inline id performOptionalSelector( id obj, SEL sel ) {
#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
#endif
-// We need a dummy global operator<< so we can bring it into Catch namespace later
-struct Catch_global_namespace_dummy {};
-std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
-
namespace Catch {
- // Bring in operator<< from global namespace into Catch namespace
- using ::operator<<;
-
namespace Detail {
extern const std::string unprintableString;
@@ -5121,6 +5123,7 @@ namespace Catch {
struct LeakDetector {
LeakDetector();
+ ~LeakDetector();
};
}
@@ -5772,7 +5775,7 @@ namespace Catch {
//
// See https://github.com/philsquared/Clara for more details
-// Clara v1.1.4
+// Clara v1.1.5
#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
@@ -5798,8 +5801,8 @@ namespace Catch {
//
// A single-header library for wrapping and laying out basic text, by Phil Nash
//
-// This work is licensed under the BSD 2-Clause license.
-// See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// This project is hosted at https://github.com/philsquared/textflowcpp
@@ -5813,314 +5816,324 @@ namespace Catch {
#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
#endif
-namespace Catch { namespace clara { namespace TextFlow {
+namespace Catch {
+namespace clara {
+namespace TextFlow {
- inline auto isWhitespace( char c ) -> bool {
- static std::string chars = " \t\n\r";
- return chars.find( c ) != std::string::npos;
- }
- inline auto isBreakableBefore( char c ) -> bool {
- static std::string chars = "[({<|";
- return chars.find( c ) != std::string::npos;
- }
- inline auto isBreakableAfter( char c ) -> bool {
- static std::string chars = "])}>.,:;*+-=&/\\";
- return chars.find( c ) != std::string::npos;
- }
+inline auto isWhitespace(char c) -> bool {
+ static std::string chars = " \t\n\r";
+ return chars.find(c) != std::string::npos;
+}
+inline auto isBreakableBefore(char c) -> bool {
+ static std::string chars = "[({<|";
+ return chars.find(c) != std::string::npos;
+}
+inline auto isBreakableAfter(char c) -> bool {
+ static std::string chars = "])}>.,:;*+-=&/\\";
+ return chars.find(c) != std::string::npos;
+}
- class Columns;
+class Columns;
- class Column {
- std::vector m_strings;
- size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
- size_t m_indent = 0;
- size_t m_initialIndent = std::string::npos;
+class Column {
+ std::vector m_strings;
+ size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
+ size_t m_indent = 0;
+ size_t m_initialIndent = std::string::npos;
- public:
- class iterator {
- friend Column;
+public:
+ class iterator {
+ friend Column;
- Column const& m_column;
- size_t m_stringIndex = 0;
- size_t m_pos = 0;
+ Column const& m_column;
+ size_t m_stringIndex = 0;
+ size_t m_pos = 0;
- size_t m_len = 0;
- size_t m_end = 0;
- bool m_suffix = false;
+ size_t m_len = 0;
+ size_t m_end = 0;
+ bool m_suffix = false;
- iterator( Column const& column, size_t stringIndex )
- : m_column( column ),
- m_stringIndex( stringIndex )
- {}
+ iterator(Column const& column, size_t stringIndex)
+ : m_column(column),
+ m_stringIndex(stringIndex) {}
- auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
+ auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
- auto isBoundary( size_t at ) const -> bool {
- assert( at > 0 );
- assert( at <= line().size() );
+ auto isBoundary(size_t at) const -> bool {
+ assert(at > 0);
+ assert(at <= line().size());
- return at == line().size() ||
- ( isWhitespace( line()[at] ) && !isWhitespace( line()[at-1] ) ) ||
- isBreakableBefore( line()[at] ) ||
- isBreakableAfter( line()[at-1] );
- }
+ return at == line().size() ||
+ (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
+ isBreakableBefore(line()[at]) ||
+ isBreakableAfter(line()[at - 1]);
+ }
- void calcLength() {
- assert( m_stringIndex < m_column.m_strings.size() );
+ void calcLength() {
+ assert(m_stringIndex < m_column.m_strings.size());
- m_suffix = false;
- auto width = m_column.m_width-indent();
- m_end = m_pos;
- while( m_end < line().size() && line()[m_end] != '\n' )
- ++m_end;
+ m_suffix = false;
+ auto width = m_column.m_width - indent();
+ m_end = m_pos;
+ while (m_end < line().size() && line()[m_end] != '\n')
+ ++m_end;
- if( m_end < m_pos + width ) {
- m_len = m_end - m_pos;
- }
- else {
- size_t len = width;
- while (len > 0 && !isBoundary(m_pos + len))
- --len;
- while (len > 0 && isWhitespace( line()[m_pos + len - 1] ))
- --len;
+ if (m_end < m_pos + width) {
+ m_len = m_end - m_pos;
+ } else {
+ size_t len = width;
+ while (len > 0 && !isBoundary(m_pos + len))
+ --len;
+ while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
+ --len;
- if (len > 0) {
- m_len = len;
- } else {
- m_suffix = true;
- m_len = width - 1;
- }
- }
- }
+ if (len > 0) {
+ m_len = len;
+ } else {
+ m_suffix = true;
+ m_len = width - 1;
+ }
+ }
+ }
- auto indent() const -> size_t {
- auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
- return initial == std::string::npos ? m_column.m_indent : initial;
- }
+ auto indent() const -> size_t {
+ auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
+ return initial == std::string::npos ? m_column.m_indent : initial;
+ }
- auto addIndentAndSuffix(std::string const &plain) const -> std::string {
- return std::string( indent(), ' ' ) + (m_suffix ? plain + "-" : plain);
- }
+ auto addIndentAndSuffix(std::string const &plain) const -> std::string {
+ return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
+ }
- public:
- explicit iterator( Column const& column ) : m_column( column ) {
- assert( m_column.m_width > m_column.m_indent );
- assert( m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent );
- calcLength();
- if( m_len == 0 )
- m_stringIndex++; // Empty string
- }
+ public:
+ using difference_type = std::ptrdiff_t;
+ using value_type = std::string;
+ using pointer = value_type * ;
+ using reference = value_type & ;
+ using iterator_category = std::forward_iterator_tag;
- auto operator *() const -> std::string {
- assert( m_stringIndex < m_column.m_strings.size() );
- assert( m_pos <= m_end );
- if( m_pos + m_column.m_width < m_end )
- return addIndentAndSuffix(line().substr(m_pos, m_len));
- else
- return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos));
- }
+ explicit iterator(Column const& column) : m_column(column) {
+ assert(m_column.m_width > m_column.m_indent);
+ assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
+ calcLength();
+ if (m_len == 0)
+ m_stringIndex++; // Empty string
+ }
- auto operator ++() -> iterator& {
- m_pos += m_len;
- if( m_pos < line().size() && line()[m_pos] == '\n' )
- m_pos += 1;
- else
- while( m_pos < line().size() && isWhitespace( line()[m_pos] ) )
- ++m_pos;
+ auto operator *() const -> std::string {
+ assert(m_stringIndex < m_column.m_strings.size());
+ assert(m_pos <= m_end);
+ return addIndentAndSuffix(line().substr(m_pos, m_len));
+ }
- if( m_pos == line().size() ) {
- m_pos = 0;
- ++m_stringIndex;
- }
- if( m_stringIndex < m_column.m_strings.size() )
- calcLength();
- return *this;
- }
- auto operator ++(int) -> iterator {
- iterator prev( *this );
- operator++();
- return prev;
- }
+ auto operator ++() -> iterator& {
+ m_pos += m_len;
+ if (m_pos < line().size() && line()[m_pos] == '\n')
+ m_pos += 1;
+ else
+ while (m_pos < line().size() && isWhitespace(line()[m_pos]))
+ ++m_pos;
- auto operator ==( iterator const& other ) const -> bool {
- return
- m_pos == other.m_pos &&
- m_stringIndex == other.m_stringIndex &&
- &m_column == &other.m_column;
- }
- auto operator !=( iterator const& other ) const -> bool {
- return !operator==( other );
- }
- };
- using const_iterator = iterator;
+ if (m_pos == line().size()) {
+ m_pos = 0;
+ ++m_stringIndex;
+ }
+ if (m_stringIndex < m_column.m_strings.size())
+ calcLength();
+ return *this;
+ }
+ auto operator ++(int) -> iterator {
+ iterator prev(*this);
+ operator++();
+ return prev;
+ }
- explicit Column( std::string const& text ) { m_strings.push_back( text ); }
+ auto operator ==(iterator const& other) const -> bool {
+ return
+ m_pos == other.m_pos &&
+ m_stringIndex == other.m_stringIndex &&
+ &m_column == &other.m_column;
+ }
+ auto operator !=(iterator const& other) const -> bool {
+ return !operator==(other);
+ }
+ };
+ using const_iterator = iterator;
- auto width( size_t newWidth ) -> Column& {
- assert( newWidth > 0 );
- m_width = newWidth;
- return *this;
- }
- auto indent( size_t newIndent ) -> Column& {
- m_indent = newIndent;
- return *this;
- }
- auto initialIndent( size_t newIndent ) -> Column& {
- m_initialIndent = newIndent;
- return *this;
- }
+ explicit Column(std::string const& text) { m_strings.push_back(text); }
- auto width() const -> size_t { return m_width; }
- auto begin() const -> iterator { return iterator( *this ); }
- auto end() const -> iterator { return { *this, m_strings.size() }; }
+ auto width(size_t newWidth) -> Column& {
+ assert(newWidth > 0);
+ m_width = newWidth;
+ return *this;
+ }
+ auto indent(size_t newIndent) -> Column& {
+ m_indent = newIndent;
+ return *this;
+ }
+ auto initialIndent(size_t newIndent) -> Column& {
+ m_initialIndent = newIndent;
+ return *this;
+ }
- inline friend std::ostream& operator << ( std::ostream& os, Column const& col ) {
- bool first = true;
- for( auto line : col ) {
- if( first )
- first = false;
- else
- os << "\n";
- os << line;
- }
- return os;
- }
+ auto width() const -> size_t { return m_width; }
+ auto begin() const -> iterator { return iterator(*this); }
+ auto end() const -> iterator { return { *this, m_strings.size() }; }
- auto operator + ( Column const& other ) -> Columns;
+ inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
+ bool first = true;
+ for (auto line : col) {
+ if (first)
+ first = false;
+ else
+ os << "\n";
+ os << line;
+ }
+ return os;
+ }
- auto toString() const -> std::string {
- std::ostringstream oss;
- oss << *this;
- return oss.str();
- }
- };
+ auto operator + (Column const& other)->Columns;
- class Spacer : public Column {
+ auto toString() const -> std::string {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+};
- public:
- explicit Spacer( size_t spaceWidth ) : Column( "" ) {
- width( spaceWidth );
- }
- };
+class Spacer : public Column {
- class Columns {
- std::vector m_columns;
+public:
+ explicit Spacer(size_t spaceWidth) : Column("") {
+ width(spaceWidth);
+ }
+};
- public:
+class Columns {
+ std::vector m_columns;
- class iterator {
- friend Columns;
- struct EndTag {};
+public:
- std::vector const& m_columns;
- std::vector m_iterators;
- size_t m_activeIterators;
+ class iterator {
+ friend Columns;
+ struct EndTag {};
- iterator( Columns const& columns, EndTag )
- : m_columns( columns.m_columns ),
- m_activeIterators( 0 )
- {
- m_iterators.reserve( m_columns.size() );
+ std::vector const& m_columns;
+ std::vector m_iterators;
+ size_t m_activeIterators;
- for( auto const& col : m_columns )
- m_iterators.push_back( col.end() );
- }
+ iterator(Columns const& columns, EndTag)
+ : m_columns(columns.m_columns),
+ m_activeIterators(0) {
+ m_iterators.reserve(m_columns.size());
- public:
- explicit iterator( Columns const& columns )
- : m_columns( columns.m_columns ),
- m_activeIterators( m_columns.size() )
- {
- m_iterators.reserve( m_columns.size() );
+ for (auto const& col : m_columns)
+ m_iterators.push_back(col.end());
+ }
- for( auto const& col : m_columns )
- m_iterators.push_back( col.begin() );
- }
+ public:
+ using difference_type = std::ptrdiff_t;
+ using value_type = std::string;
+ using pointer = value_type * ;
+ using reference = value_type & ;
+ using iterator_category = std::forward_iterator_tag;
- auto operator ==( iterator const& other ) const -> bool {
- return m_iterators == other.m_iterators;
- }
- auto operator !=( iterator const& other ) const -> bool {
- return m_iterators != other.m_iterators;
- }
- auto operator *() const -> std::string {
- std::string row, padding;
+ explicit iterator(Columns const& columns)
+ : m_columns(columns.m_columns),
+ m_activeIterators(m_columns.size()) {
+ m_iterators.reserve(m_columns.size());
- for( size_t i = 0; i < m_columns.size(); ++i ) {
- auto width = m_columns[i].width();
- if( m_iterators[i] != m_columns[i].end() ) {
- std::string col = *m_iterators[i];
- row += padding + col;
- if( col.size() < width )
- padding = std::string( width - col.size(), ' ' );
- else
- padding = "";
- }
- else {
- padding += std::string( width, ' ' );
- }
- }
- return row;
- }
- auto operator ++() -> iterator& {
- for( size_t i = 0; i < m_columns.size(); ++i ) {
- if (m_iterators[i] != m_columns[i].end())
- ++m_iterators[i];
- }
- return *this;
- }
- auto operator ++(int) -> iterator {
- iterator prev( *this );
- operator++();
- return prev;
- }
- };
- using const_iterator = iterator;
+ for (auto const& col : m_columns)
+ m_iterators.push_back(col.begin());
+ }
- auto begin() const -> iterator { return iterator( *this ); }
- auto end() const -> iterator { return { *this, iterator::EndTag() }; }
+ auto operator ==(iterator const& other) const -> bool {
+ return m_iterators == other.m_iterators;
+ }
+ auto operator !=(iterator const& other) const -> bool {
+ return m_iterators != other.m_iterators;
+ }
+ auto operator *() const -> std::string {
+ std::string row, padding;
- auto operator += ( Column const& col ) -> Columns& {
- m_columns.push_back( col );
- return *this;
- }
- auto operator + ( Column const& col ) -> Columns {
- Columns combined = *this;
- combined += col;
- return combined;
- }
+ for (size_t i = 0; i < m_columns.size(); ++i) {
+ auto width = m_columns[i].width();
+ if (m_iterators[i] != m_columns[i].end()) {
+ std::string col = *m_iterators[i];
+ row += padding + col;
+ if (col.size() < width)
+ padding = std::string(width - col.size(), ' ');
+ else
+ padding = "";
+ } else {
+ padding += std::string(width, ' ');
+ }
+ }
+ return row;
+ }
+ auto operator ++() -> iterator& {
+ for (size_t i = 0; i < m_columns.size(); ++i) {
+ if (m_iterators[i] != m_columns[i].end())
+ ++m_iterators[i];
+ }
+ return *this;
+ }
+ auto operator ++(int) -> iterator {
+ iterator prev(*this);
+ operator++();
+ return prev;
+ }
+ };
+ using const_iterator = iterator;
- inline friend std::ostream& operator << ( std::ostream& os, Columns const& cols ) {
+ auto begin() const -> iterator { return iterator(*this); }
+ auto end() const -> iterator { return { *this, iterator::EndTag() }; }
- bool first = true;
- for( auto line : cols ) {
- if( first )
- first = false;
- else
- os << "\n";
- os << line;
- }
- return os;
- }
+ auto operator += (Column const& col) -> Columns& {
+ m_columns.push_back(col);
+ return *this;
+ }
+ auto operator + (Column const& col) -> Columns {
+ Columns combined = *this;
+ combined += col;
+ return combined;
+ }
- auto toString() const -> std::string {
- std::ostringstream oss;
- oss << *this;
- return oss.str();
- }
- };
+ inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
- inline auto Column::operator + ( Column const& other ) -> Columns {
- Columns cols;
- cols += *this;
- cols += other;
- return cols;
- }
-}}} // namespace Catch::clara::TextFlow
+ bool first = true;
+ for (auto line : cols) {
+ if (first)
+ first = false;
+ else
+ os << "\n";
+ os << line;
+ }
+ return os;
+ }
+
+ auto toString() const -> std::string {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+};
+
+inline auto Column::operator + (Column const& other) -> Columns {
+ Columns cols;
+ cols += *this;
+ cols += other;
+ return cols;
+}
+}
+
+}
+}
// ----------- end of #include from clara_textflow.hpp -----------
// ........... back in clara.hpp
+#include
#include
#include
#include
@@ -7119,6 +7132,18 @@ namespace Catch {
return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
return ParserResult::ok( ParseResultType::Matched );
};
+ auto const setReporter = [&]( std::string const& reporter ) {
+ IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
+
+ auto lcReporter = toLower( reporter );
+ auto result = factories.find( lcReporter );
+
+ if( factories.end() != result )
+ config.reporterName = lcReporter;
+ else
+ return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
+ return ParserResult::ok( ParseResultType::Matched );
+ };
auto cli
= ExeName( config.processName )
@@ -7144,7 +7169,7 @@ namespace Catch {
| Opt( config.outputFilename, "filename" )
["-o"]["--out"]
( "output filename" )
- | Opt( config.reporterName, "name" )
+ | Opt( setReporter, "name" )
["-r"]["--reporter"]
( "reporter to use (defaults to console)" )
| Opt( config.name, "name" )
@@ -8292,6 +8317,10 @@ namespace Catch {
Catch::LeakDetector::LeakDetector() {}
#endif
+
+Catch::LeakDetector::~LeakDetector() {
+ Catch::cleanUp();
+}
// end catch_leak_detector.cpp
// start catch_list.cpp
@@ -8315,7 +8344,7 @@ namespace Catch {
std::size_t listTags( Config const& config );
- std::size_t listReporters( Config const& /*config*/ );
+ std::size_t listReporters();
Option list( Config const& config );
@@ -8433,7 +8462,7 @@ namespace Catch {
return tagCounts.size();
}
- std::size_t listReporters( Config const& /*config*/ ) {
+ std::size_t listReporters() {
Catch::cout() << "Available reporters:\n";
IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
std::size_t maxNameLen = 0;
@@ -8464,7 +8493,7 @@ namespace Catch {
if( config.listTags() )
listedCount = listedCount.valueOr(0) + listTags( config );
if( config.listReporters() )
- listedCount = listedCount.valueOr(0) + listReporters( config );
+ listedCount = listedCount.valueOr(0) + listReporters();
return listedCount;
}
@@ -9930,13 +9959,22 @@ namespace Catch {
void libIdentify();
int applyCommandLine( int argc, char const * const * argv );
+ #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
+ int applyCommandLine( int argc, wchar_t const * const * argv );
+ #endif
void useConfigData( ConfigData const& configData );
- int run( int argc, char* argv[] );
- #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
- int run( int argc, wchar_t* const argv[] );
- #endif
+ template
+ int run(int argc, CharT const * const argv[]) {
+ if (m_startupExceptions)
+ return 1;
+ int returnCode = applyCommandLine(argc, argv);
+ if (returnCode == 0)
+ returnCode = run();
+ return returnCode;
+ }
+
int run();
clara::Parser const& cli() const;
@@ -10148,22 +10186,8 @@ namespace Catch {
return 0;
}
- void Session::useConfigData( ConfigData const& configData ) {
- m_configData = configData;
- m_config.reset();
- }
-
- int Session::run( int argc, char* argv[] ) {
- if( m_startupExceptions )
- return 1;
- int returnCode = applyCommandLine( argc, argv );
- if( returnCode == 0 )
- returnCode = run();
- return returnCode;
- }
-
#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
- int Session::run( int argc, wchar_t* const argv[] ) {
+ int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
char **utf8Argv = new char *[ argc ];
@@ -10175,7 +10199,7 @@ namespace Catch {
WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
}
- int returnCode = run( argc, utf8Argv );
+ int returnCode = applyCommandLine( argc, utf8Argv );
for ( int i = 0; i < argc; ++i )
delete [] utf8Argv[ i ];
@@ -10185,6 +10209,12 @@ namespace Catch {
return returnCode;
}
#endif
+
+ void Session::useConfigData( ConfigData const& configData ) {
+ m_configData = configData;
+ m_config.reset();
+ }
+
int Session::run() {
if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
@@ -11686,7 +11716,7 @@ std::string StringMaker::convert(bool b) {
return b ? "true" : "false";
}
-std::string StringMaker::convert(char value) {
+std::string StringMaker::convert(signed char value) {
if (value == '\r') {
return "'\\r'";
} else if (value == '\f') {
@@ -11703,8 +11733,8 @@ std::string StringMaker::convert(char value) {
return chstr;
}
}
-std::string StringMaker::convert(signed char c) {
- return ::Catch::Detail::stringify(static_cast(c));
+std::string StringMaker::convert(char c) {
+ return ::Catch::Detail::stringify(static_cast(c));
}
std::string StringMaker::convert(unsigned char c) {
return ::Catch::Detail::stringify(static_cast(c));
@@ -11836,7 +11866,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 4, 1, "", 0 );
+ static Version version( 2, 4, 2, "", 0 );
return version;
}
@@ -13517,6 +13547,9 @@ namespace Catch {
m_xml.startElement( "Catch" );
if( !m_config->name().empty() )
m_xml.writeAttribute( "name", m_config->name() );
+ if( m_config->rngSeed() != 0 )
+ m_xml.scopedElement( "Randomness" )
+ .writeAttribute( "seed", m_config->rngSeed() );
}
void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
@@ -13792,6 +13825,14 @@ int main (int argc, char * const argv[]) {
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
+#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
+#define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
+#define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
+#else
+#define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
+#define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
+#endif
+
// "BDD-style" convenience wrappers
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
@@ -13851,6 +13892,14 @@ int main (int argc, char * const argv[]) {
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
+#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
+#define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
+#define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
+#else
+#define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
+#define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
+#endif
+
#endif
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
@@ -13931,6 +13980,9 @@ using Catch::Detail::Approx;
#define CATCH_THEN( desc )
#define CATCH_AND_THEN( desc )
+#define CATCH_STATIC_REQUIRE( ... ) (void)(0)
+#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
+
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
#else
@@ -13980,6 +14032,9 @@ using Catch::Detail::Approx;
#define SUCCEED( ... ) (void)(0)
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
+#define STATIC_REQUIRE( ... ) (void)(0)
+#define STATIC_REQUIRE_FALSE( ... ) (void)(0)
+
#endif
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
diff --git a/test_package/conanfile.py b/test_package/conanfile.py
index e8d50f9a..e63b2ce5 100644
--- a/test_package/conanfile.py
+++ b/test_package/conanfile.py
@@ -10,7 +10,7 @@ class CatchConanTest(ConanFile):
settings = "os", "compiler", "arch", "build_type"
username = getenv("CONAN_USERNAME", "philsquared")
channel = getenv("CONAN_CHANNEL", "testing")
- requires = "Catch/2.4.1@%s/%s" % (username, channel)
+ requires = "Catch/2.4.2@%s/%s" % (username, channel)
def build(self):
cmake = CMake(self)