diff --git a/.travis.yml b/.travis.yml index 1da1c0fc..ed8a956f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,145 +17,140 @@ matrix: addons: apt: sources: *all_sources - packages: ['valgrind', 'lcov', 'clang-3.5'] - env: COMPILER='clang++-3.5' VALGRIND=1 + packages: ['clang-3.5'] + env: COMPILER='clang++-3.5' - os: linux compiler: clang addons: apt: sources: *all_sources - packages: ['valgrind', 'lcov', 'clang-3.6'] - env: COMPILER='clang++-3.6' VALGRIND=1 + packages: ['clang-3.6'] + env: COMPILER='clang++-3.6' -# Travis's containers do not seem to have Clang 3.7 in apt, no matter what sources I add. -# - os: linux -# compiler: clang -# addons: -# apt: -# sources: *all_sources -# packages: ['valgrind', 'clang-3.7'] -# env: COMPILER='clang++-3.7' VALGRIND=1 + # Clang 3.7 is intentionally skipped as we cannot get it easily on + # TravisCI container - os: linux compiler: clang addons: apt: sources: *all_sources - packages: ['valgrind', 'lcov', 'clang-3.8'] - env: COMPILER='clang++-3.8' VALGRIND=1 + packages: ['lcov', 'clang-3.8'] + env: COMPILER='clang++-3.8' - os: linux compiler: clang addons: apt: sources: *all_sources - packages: ['clang-3.9', 'valgrind', 'lcov'] - env: COMPILER='clang++-3.9' VALGRIND=1 + packages: ['clang-3.9'] + env: COMPILER='clang++-3.9' - os: linux compiler: clang addons: apt: sources: *all_sources - packages: ['clang-4.0', 'valgrind', 'lcov'] - env: COMPILER='clang++-4.0' VALGRIND=1 + packages: ['clang-4.0'] + env: COMPILER='clang++-4.0' - os: linux compiler: clang addons: apt: sources: *all_sources - packages: ['clang-5.0', 'valgrind', 'lcov'] - env: COMPILER='clang++-5.0' VALGRIND=1 + packages: ['clang-5.0'] + env: COMPILER='clang++-5.0' # 2/ Linux GCC Builds - os: linux compiler: gcc addons: apt: - sources: ['ubuntu-toolchain-r-test'] - packages: ['valgrind', 'lcov', 'g++-4.8'] - env: COMPILER='g++-4.8' VALGRIND=1 + sources: *all_sources + packages: ['g++-4.8'] + env: COMPILER='g++-4.8' - os: linux compiler: gcc addons: apt: sources: *all_sources - packages: ['valgrind', 'lcov', 'g++-4.9'] - env: COMPILER='g++-4.9' VALGRIND=1 + packages: ['g++-4.9'] + env: COMPILER='g++-4.9' - os: linux compiler: gcc addons: apt: sources: *all_sources - packages: ['valgrind', 'lcov', 'g++-5'] - env: COMPILER='g++-5' VALGRIND=1 + packages: ['g++-5'] + env: COMPILER='g++-5' - os: linux compiler: gcc addons: &gcc6 apt: sources: *all_sources - packages: ['valgrind', 'lcov', 'g++-6'] - env: COMPILER='g++-6' VALGRIND=1 + packages: ['g++-6'] + env: COMPILER='g++-6' - os: linux compiler: gcc addons: &gcc7 apt: sources: *all_sources - packages: ['valgrind', 'lcov', 'g++-7'] - env: COMPILER='g++-7' VALGRIND=1 + packages: ['g++-7'] + env: COMPILER='g++-7' # 3b/ Linux C++14 Clang builds + # Note that we need newer libstdc++ for C++14 support - os: linux compiler: clang addons: apt: - packages: ['clang-3.8', 'valgrind', 'lcov', 'libstdc++-6-dev'] + packages: ['clang-3.8', 'libstdc++-6-dev'] sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty - env: COMPILER='clang++-3.8' CPP14=1 VALGRIND=1 + env: COMPILER='clang++-3.8' CPP14=1 - os: linux compiler: clang addons: apt: sources: *all_sources - packages: ['clang-3.9', 'valgrind', 'lcov', 'libstdc++-6-dev'] - env: COMPILER='clang++-3.9' CPP14=1 VALGRIND=1 + packages: ['clang-3.9', 'libstdc++-6-dev'] + env: COMPILER='clang++-3.9' CPP14=1 - os: linux compiler: clang addons: apt: sources: *all_sources - packages: ['clang-4.0', 'valgrind', 'lcov', 'libstdc++-6-dev'] - env: COMPILER='clang++-4.0' CPP14=1 VALGRIND=1 + packages: ['clang-4.0', 'libstdc++-6-dev'] + env: COMPILER='clang++-4.0' CPP14=1 - os: linux compiler: clang addons: apt: sources: *all_sources - packages: ['clang-5.0', 'valgrind', 'lcov', 'libstdc++-6-dev'] - env: COMPILER='clang++-5.0' CPP14=1 VALGRIND=1 + packages: ['clang-5.0', 'libstdc++-6-dev'] + env: COMPILER='clang++-5.0' CPP14=1 # 4a/ Linux C++14 GCC builds - os: linux compiler: gcc addons: *gcc6 - env: COMPILER='g++-6' CPP14=1 VALGRIND=1 + env: COMPILER='g++-6' CPP14=1 - os: linux compiler: gcc addons: *gcc7 - env: COMPILER='g++-7' CPP14=1 VALGRIND=1 + env: COMPILER='g++-7' CPP14=1 # 5/ OSX Clang Builds - os: osx @@ -181,8 +176,39 @@ matrix: - os: osx osx_image: xcode9.1 compiler: clang - env: COMPILER='clang++' USE_CPP14=1 + env: COMPILER='clang++' CPP14=1 + # 6/ Special builds -- examples, coverage, valgrind, etc. + - os: linux + compiler: gcc + addons: + apt: + sources: *all_sources + packages: ['lcov', 'g++-7'] + env: COMPILER='g++-7' CPP14=1 EXAMPLES=1 COVERAGE=1 + + - os: linux + compiler: clang + addons: + apt: + packages: ['clang-3.8', 'lcov'] + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty + env: COMPILER='clang++-3.8' EXAMPLES=1 COVERAGE=1 + + - os: linux + compiler: gcc + addons: + apt: + sources: *all_sources + packages: ['valgrind', 'lcov', 'g++-7'] + env: COMPILER='g++-7' CPP14=1 VALGRIND=1 + + - os: osx + osx_image: xcode9.1 + compiler: clang + env: COMPILER='clang++' CPP14=1 EXAMPLES=1 COVERAGE=1 install: - DEPS_DIR="${TRAVIS_BUILD_DIR}/deps" @@ -204,7 +230,7 @@ before_script: - | # Use Debug builds for running Valgrind and building examples - cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DUSE_CPP14=${CPP14} -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=ON -DCATCH_ENABLE_COVERAGE=ON + cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DUSE_CPP14=${CPP14} -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=${EXAMPLES} -DCATCH_ENABLE_COVERAGE=${COVERAGE} # Don't bother with release build for coverage build cmake -H. -BBuild-Release -DCMAKE_BUILD_TYPE=Release -Wdev -DUSE_CPP14=${CPP14} @@ -215,7 +241,9 @@ script: make -j 2 CTEST_OUTPUT_ON_FAILURE=1 ctest -j 2 # Coverage collection does not work for OS X atm - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then + echo "${TRAVIS_OS_NAME}"; + echo "${COVERAGE}"; + if [[ "${TRAVIS_OS_NAME}" == "linux" ]] && [[ "${COVERAGE}" == "1" ]]; then make gcov make lcov bash <(curl -s https://codecov.io/bash) -X gcov || echo "Codecov did not collect coverage reports" diff --git a/CMakeLists.txt b/CMakeLists.txt index cf7e5965..4bb365ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -445,9 +445,10 @@ install(EXPORT Catch2Config # install Catch2ConfigVersion.cmake file to handle versions in find_package include(CMakePackageConfigHelpers) -write_basic_package_version_file(Catch2ConfigVersion.cmake +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake" COMPATIBILITY SameMajorVersion) install(FILES - "${CMAKE_BINARY_DIR}/Catch2ConfigVersion.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake" DESTINATION ${CATCH_CMAKE_CONFIG_DESTINATION}) diff --git a/appveyor.yml b/appveyor.yml index 2d681726..847d3f62 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,18 +19,51 @@ environment: - additional_flags: "/D_UNICODE /DUNICODE" wmain: 1 + coverage: 0 + + # Have a coverage dimension + - additional_flags: "" + wmain: 0 + coverage: 1 + + # Have an examples dimension + - additional_flags: "" + wmain: 0 + examples: 1 + matrix: exclude: - os: Visual Studio 2015 additional_flags: "/permissive- /std:c++latest" -init: - - git config --global core.autocrlf input + - os: Visual Studio 2015 + additional_flags: "/D_UNICODE /DUNICODE" + + # Exclude unwanted coverage configurations + - coverage: 1 + platform: Win32 + + - coverage: 1 + os: Visual Studio 2015 + + - coverage: 1 + configuration: Release + + # Exclude unwanted examples configurations + - examples: 1 + platform: Win32 + + - examples: 1 + os: Visual Studio 2015 + + - examples: 1 + configuration: Release + install: - - ps: if (($env:CONFIGURATION) -eq "Debug" ) { python -m pip install codecov } - - ps: if (($env:CONFIGURATION) -eq "Debug" ) { .\misc\installOpenCppCoverage.ps1 } + - ps: if (($env:CONFIGURATION) -eq "Debug" -And ($env:coverage) -eq "1" ) { python -m pip install codecov } + - ps: if (($env:CONFIGURATION) -eq "Debug" -And ($env:coverage) -eq "1" ) { .\misc\installOpenCppCoverage.ps1 } # Win32 and x64 are CMake-compatible solution platform names. # This allows us to pass %PLATFORM% to CMake -A. diff --git a/docs/assertions.md b/docs/assertions.md index ece4e106..509abf8a 100644 --- a/docs/assertions.md +++ b/docs/assertions.md @@ -9,7 +9,7 @@ Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc). -Catch is different. Because it decomposes natural C-style conditional expressions most of these forms are reduced to one or two that you will use all the time. That said there are a rich set of auxilliary macros as well. We'll describe all of these here. +Catch is different. Because it decomposes natural C-style conditional expressions most of these forms are reduced to one or two that you will use all the time. That said there are a rich set of auxiliary macros as well. We'll describe all of these here. Most of these macros come in two forms: diff --git a/docs/command-line.md b/docs/command-line.md index 0c24c3b1..78d83625 100644 --- a/docs/command-line.md +++ b/docs/command-line.md @@ -78,7 +78,7 @@ Wildcards consist of the `*` character at the beginning and/or end of test case Test specs are case insensitive. -If a spec is prefixed with `exclude:` or the `~` character then the pattern matches an exclusion. This means that tests matching the pattern are excluded from the set - even if a prior inclusion spec included them. Subsequent inclusion specs will take precendence, however. +If a spec is prefixed with `exclude:` or the `~` character then the pattern matches an exclusion. This means that tests matching the pattern are excluded from the set - even if a prior inclusion spec included them. Subsequent inclusion specs will take precedence, however. Inclusions and exclusions are evaluated in left-to-right order. Test case examples: @@ -94,7 +94,7 @@ a* ~ab* abc Matches all tests that start with 'a', except those that Names within square brackets are interpreted as tags. -A series of tags form an AND expression wheras a comma-separated sequence forms an OR expression. e.g.: +A series of tags form an AND expression whereas a comma-separated sequence forms an OR expression. e.g.:
[one][two],[three]
This matches all tests tagged `[one]` and `[two]`, as well as all tests tagged `[three]` @@ -269,7 +269,7 @@ either before running any tests, after running all tests - or both, depending on When running benchmarks the clock resolution is estimated. Benchmarks are then run for exponentially increasing numbers of iterations until some multiple of the estimated resolution is exceed. By default that multiple is 100, but -it can be overriden here. +it can be overridden here. ## Usage diff --git a/docs/configuration.md b/docs/configuration.md index 3f963eec..dd81dde4 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -26,7 +26,7 @@ Although Catch is header only it still, internally, maintains a distinction betw # Reporter / Listener interfaces - CATCH_CONFIG_EXTERNAL_INTERFACES // Brings in neccessary headers for Reporter/Listener implementation + CATCH_CONFIG_EXTERNAL_INTERFACES // Brings in necessary headers for Reporter/Listener implementation Brings in various parts of Catch that are required for user defined Reporters and Listeners. This means that new Reporters and Listeners can be defined in this file as well as in the main file. @@ -79,7 +79,7 @@ This can be useful on certain platforms that do not provide the standard iostrea By default Catch's stringification machinery falls back to a "{?}". To let projects reuse their own existing stringification machinery, this -fallback can be overriden by defining `CATCH_CONFIG_FALLBACK_STRINGIFIER` +fallback can be overridden by defining `CATCH_CONFIG_FALLBACK_STRINGIFIER` to a name of a function that should perform the stringification instead. The provided function must return std::string and must accept any type diff --git a/docs/event-listeners.md b/docs/event-listeners.md index 1ddef0f8..c6625a2e 100644 --- a/docs/event-listeners.md +++ b/docs/event-listeners.md @@ -44,7 +44,7 @@ _Note that you should not use any assertion macros within a Listener!_ ## Events that can be hooked -The following are the methods that can be overriden in the Listener: +The following are the methods that can be overridden in the Listener: ```c++ // The whole test run, starting and ending diff --git a/docs/opensource-users.md b/docs/opensource-users.md index fb46875a..374cb1d2 100644 --- a/docs/opensource-users.md +++ b/docs/opensource-users.md @@ -21,7 +21,7 @@ Listing a project here does not imply endorsement and the plan is to keep these Boost Asio style bindings for ZeroMQ ### [ChakraCore](https://github.com/Microsoft/ChakraCore) -The core part of the Chakra Javascript engine that powers Microsoft Edge +The core part of the Chakra JavaScript engine that powers Microsoft Edge ### [ChaiScript](https://github.com/ChaiScript/ChaiScript) A, header-only, embedded scripting language designed from the ground up to directly target C++ and take advantage of modern C++ development techniques diff --git a/docs/own-main.md b/docs/own-main.md index 18d1b7d3..c74f9f14 100644 --- a/docs/own-main.md +++ b/docs/own-main.md @@ -30,7 +30,7 @@ int main( int argc, char* argv[] ) { ## Amending the config -If you still want Catch to process the command line, but you want to programatically tweak the config, you can do so in one of two ways: +If you still want Catch to process the command line, but you want to programmatically tweak the config, you can do so in one of two ways: ```c++ #define CATCH_CONFIG_RUNNER diff --git a/docs/release-notes.md b/docs/release-notes.md index 76d88be7..dc9f435c 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -379,8 +379,8 @@ Cygwin issue with `gettimeofday` - `#define` was not early enough * Cygwin compatibility fixes * Signal handling is no longer compiled by default. * Usage of `gettimeofday` inside Catch should no longer cause compilation errors. -* Improved `-Wparentheses` supression for gcc (#674) - * When compiled with gcc 4.8 or newer, the supression is localized to assertions only +* Improved `-Wparentheses` suppression for gcc (#674) + * When compiled with gcc 4.8 or newer, the suppression is localized to assertions only * Otherwise it is supressed for the whole TU * Fixed test spec parser issue (with escapes in multiple names) @@ -399,7 +399,7 @@ Xml: * C-escape control characters instead of XML encoding them (which requires XML 1.1) * Revert XML output to XML 1.0 * Can provide stylesheet references by extending the XML reporter -* Added description and tags attribites to XML Reporter +* Added description and tags attributes to XML Reporter * Tags are closed and the stream flushed more eagerly to avoid stdout interpolation diff --git a/docs/release-process.md b/docs/release-process.md index 433777b1..9990bab2 100644 --- a/docs/release-process.md +++ b/docs/release-process.md @@ -1,11 +1,11 @@ # How to release -When enough changes have accumulated, it is time to release new version of Catch. This document describes the proces in doing so, that no steps are forgotten. Note that all referenced scripts can be found in the `scripts/` directory. +When enough changes have accumulated, it is time to release new version of Catch. This document describes the process in doing so, that no steps are forgotten. Note that all referenced scripts can be found in the `scripts/` directory. -## Neccessary steps +## Necessary steps -These steps are neccessary and have to be performed before each new release. They serve to make sure that the new release is correct and linked-to from the standard places. +These steps are necessary and have to be performed before each new release. They serve to make sure that the new release is correct and linked-to from the standard places. ### Approval testing @@ -54,7 +54,7 @@ The following steps are optional, and do not have to be performed when releasing ### vcpkg update -Catch is maintaining its own port in Microsoft's package manager [vcpkg](https://github.com/Microsoft/vcpkg). This means that when new version of Catch is released, it should be posted there as well. `updateVcpkgPackage.py` can do a lot of neccessary work for you, it creates a branch and commits neccessary changes. You should review these changes, push and open a PR against vcpkg's upstream. +Catch is maintaining its own port in Microsoft's package manager [vcpkg](https://github.com/Microsoft/vcpkg). This means that when new version of Catch is released, it should be posted there as well. `updateVcpkgPackage.py` can do a lot of necessary work for you, it creates a branch and commits necessary changes. You should review these changes, push and open a PR against vcpkg's upstream. Note that the script assumes you have your fork of vcpkg checked out in a directory next to the directory where you have checked out Catch, like so: ``` diff --git a/include/external/clara.hpp b/include/external/clara.hpp index 9c03c8e3..1762651f 100644 --- a/include/external/clara.hpp +++ b/include/external/clara.hpp @@ -5,7 +5,7 @@ // // See https://github.com/philsquared/Clara for more details -// Clara v1.1.2 +// Clara v1.1.3 #ifndef CATCH_CLARA_HPP_INCLUDED #define CATCH_CLARA_HPP_INCLUDED @@ -18,6 +18,15 @@ #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH #endif +#ifndef CLARA_CONFIG_OPTIONAL_TYPE +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define CLARA_CONFIG_OPTIONAL_TYPE std::optional +#endif +#endif +#endif + + // ----------- #included from clara_textflow.hpp ----------- // TextFlowCpp @@ -389,11 +398,9 @@ namespace detail { std::vector m_args; public: - Args( int argc, char *argv[] ) { - m_exeName = argv[0]; - for( int i = 1; i < argc; ++i ) - m_args.push_back( argv[i] ); - } + Args( int argc, char const* const* argv ) + : m_exeName(argv[0]), + m_args(argv + 1, argv + argc) {} Args( std::initializer_list args ) : m_exeName( *args.begin() ), @@ -580,15 +587,13 @@ namespace detail { protected: void enforceOk() const override { - // !TBD: If no exceptions, std::terminate here or something - switch( m_type ) { - case ResultBase::LogicError: - throw std::logic_error( m_errorMessage ); - case ResultBase::RuntimeError: - throw std::runtime_error( m_errorMessage ); - case ResultBase::Ok: - break; - } + + // Errors shouldn't reach this point, but if they do + // the actual error message will be in m_errorMessage + assert( m_type != ResultBase::LogicError ); + assert( m_type != ResultBase::RuntimeError ); + if( m_type != ResultBase::Ok ) + std::abort(); } std::string m_errorMessage; // Only populated if resultType is an error @@ -658,6 +663,16 @@ namespace detail { return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" ); return ParserResult::ok( ParseResultType::Matched ); } +#ifdef CLARA_CONFIG_OPTIONAL_TYPE + template + inline auto convertInto( std::string const &source, std::optional& target ) -> ParserResult { + T temp; + auto result = convertInto( source, temp ); + if( result ) + target = temp; + return result; + } +#endif // CLARA_CONFIG_OPTIONAL_TYPE struct NonCopyable { NonCopyable() = default; diff --git a/include/internal/catch_capture_matchers.cpp b/include/internal/catch_capture_matchers.cpp index 7ef1597d..a67cc797 100644 --- a/include/internal/catch_capture_matchers.cpp +++ b/include/internal/catch_capture_matchers.cpp @@ -13,7 +13,7 @@ namespace Catch { using StringMatcher = Matchers::Impl::MatcherBase; // This is the general overload that takes a any string matcher - // There is another overload, in catch_assertinhandler.h/.cpp, that only takes a string and infers + // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers // the Equals matcher (so the header does not mention matchers) void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString ) { std::string exceptionMessage = Catch::translateActiveException(); diff --git a/include/internal/catch_compiler_capabilities.h b/include/internal/catch_compiler_capabilities.h index 2bbba4f0..0eb266c4 100644 --- a/include/internal/catch_compiler_capabilities.h +++ b/include/internal/catch_compiler_capabilities.h @@ -68,11 +68,7 @@ //////////////////////////////////////////////////////////////////////////////// // We know some environments not to support full POSIX signals #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) - -# if !defined(CATCH_CONFIG_POSIX_SIGNALS) -# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -# endif - + #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS #endif #ifdef __OS400__ diff --git a/include/internal/catch_run_context.cpp b/include/internal/catch_run_context.cpp index ca78bfb4..99c77058 100644 --- a/include/internal/catch_run_context.cpp +++ b/include/internal/catch_run_context.cpp @@ -57,7 +57,7 @@ namespace Catch { m_context(getCurrentMutableContext()), m_config(_config), m_reporter(std::move(reporter)), - m_lastAssertionInfo{ "", SourceLineInfo("",0), "", ResultDisposition::Normal }, + m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal }, m_includeSuccessfulResults( m_config->includeSuccessfulResults() ) { m_context.setRunner(this); @@ -84,7 +84,7 @@ namespace Catch { std::string redirectedCout; std::string redirectedCerr; - TestCaseInfo testInfo = testCase.getTestCaseInfo(); + auto const& testInfo = testCase.getTestCaseInfo(); m_reporter->testCaseStarting(testInfo); @@ -292,7 +292,7 @@ namespace Catch { Counts prevAssertions = m_totals.assertions; double duration = 0; m_shouldReportUnexpected = true; - m_lastAssertionInfo = { "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal }; + m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal }; seedRng(*m_config); diff --git a/include/internal/catch_session.cpp b/include/internal/catch_session.cpp index 0039fcb5..0581ac88 100644 --- a/include/internal/catch_session.cpp +++ b/include/internal/catch_session.cpp @@ -133,7 +133,7 @@ namespace Catch { if ( !exceptions.empty() ) { m_startupExceptions = true; Colour colourGuard( Colour::Red ); - Catch::cerr() << "Errors occured during startup!" << '\n'; + Catch::cerr() << "Errors occurred during startup!" << '\n'; // iterate over all exceptions and notify user for ( const auto& ex_ptr : exceptions ) { try { @@ -165,7 +165,7 @@ namespace Catch { << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl; } - int Session::applyCommandLine( int argc, char* argv[] ) { + int Session::applyCommandLine( int argc, char const * const * argv ) { if( m_startupExceptions ) return 1; diff --git a/include/internal/catch_session.h b/include/internal/catch_session.h index 39f7a0dd..eb8013cd 100644 --- a/include/internal/catch_session.h +++ b/include/internal/catch_session.h @@ -25,7 +25,7 @@ namespace Catch { void showHelp() const; void libIdentify(); - int applyCommandLine( int argc, char* argv[] ); + int applyCommandLine( int argc, char const * const * argv ); void useConfigData( ConfigData const& configData ); diff --git a/include/internal/catch_test_case_info.cpp b/include/internal/catch_test_case_info.cpp index 4ab97755..9bf68912 100644 --- a/include/internal/catch_test_case_info.cpp +++ b/include/internal/catch_test_case_info.cpp @@ -48,8 +48,7 @@ namespace Catch { TestCase makeTestCase( ITestInvoker* _testCase, std::string const& _className, - std::string const& _name, - std::string const& _descOrTags, + NameAndTags const& nameAndTags, SourceLineInfo const& _lineInfo ) { bool isHidden = false; @@ -58,6 +57,7 @@ namespace Catch { std::vector tags; std::string desc, tag; bool inTag = false; + std::string _descOrTags = nameAndTags.tags; for (char c : _descOrTags) { if( !inTag ) { if( c == '[' ) @@ -85,8 +85,8 @@ namespace Catch { tags.push_back( "." ); } - TestCaseInfo info( _name, _className, desc, tags, _lineInfo ); - return TestCase( _testCase, info ); + TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo ); + return TestCase( _testCase, std::move(info) ); } void setTags( TestCaseInfo& testCaseInfo, std::vector tags ) { @@ -147,7 +147,7 @@ namespace Catch { } - TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} + TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {} TestCase TestCase::withName( std::string const& _newName ) const { diff --git a/include/internal/catch_test_case_info.h b/include/internal/catch_test_case_info.h index 2a911b06..809c974f 100644 --- a/include/internal/catch_test_case_info.h +++ b/include/internal/catch_test_case_info.h @@ -9,6 +9,7 @@ #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED #include "catch_common.h" +#include "catch_test_registry.h" #include #include @@ -61,7 +62,7 @@ namespace Catch { class TestCase : public TestCaseInfo { public: - TestCase( ITestInvoker* testCase, TestCaseInfo const& info ); + TestCase( ITestInvoker* testCase, TestCaseInfo&& info ); TestCase withName( std::string const& _newName ) const; @@ -78,8 +79,7 @@ namespace Catch { TestCase makeTestCase( ITestInvoker* testCase, std::string const& className, - std::string const& name, - std::string const& description, + NameAndTags const& nameAndTags, SourceLineInfo const& lineInfo ); } diff --git a/include/internal/catch_test_case_registry_impl.cpp b/include/internal/catch_test_case_registry_impl.cpp index 89c72392..b30b112a 100644 --- a/include/internal/catch_test_case_registry_impl.cpp +++ b/include/internal/catch_test_case_registry_impl.cpp @@ -96,7 +96,7 @@ namespace Catch { m_testAsFunction(); } - std::string extractClassName( std::string const& classOrQualifiedMethodName ) { + std::string extractClassName( StringRef const& classOrQualifiedMethodName ) { std::string className = classOrQualifiedMethodName; if( startsWith( className, '&' ) ) { diff --git a/include/internal/catch_test_case_registry_impl.h b/include/internal/catch_test_case_registry_impl.h index ad45e5a0..8dc5b0fe 100644 --- a/include/internal/catch_test_case_registry_impl.h +++ b/include/internal/catch_test_case_registry_impl.h @@ -22,7 +22,7 @@ namespace Catch { class TestCase; struct IConfig; - std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ); + std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ); bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); void enforceNoDuplicateTestCases( std::vector const& functions ); @@ -58,7 +58,7 @@ namespace Catch { }; - std::string extractClassName( std::string const& classOrQualifiedMethodName ); + std::string extractClassName( StringRef const& classOrQualifiedMethodName ); /////////////////////////////////////////////////////////////////////////// diff --git a/include/internal/catch_test_registry.cpp b/include/internal/catch_test_registry.cpp index ec50e92c..ac83f333 100644 --- a/include/internal/catch_test_registry.cpp +++ b/include/internal/catch_test_registry.cpp @@ -15,23 +15,22 @@ namespace Catch { return new(std::nothrow) TestInvokerAsFunction( testAsFunction ); } - NameAndTags::NameAndTags( StringRef name_ , StringRef tags_ ) noexcept : name( name_ ), tags( tags_ ) {} + NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {} - AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef classOrMethod, NameAndTags const& nameAndTags ) noexcept { + AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept { try { getMutableRegistryHub() .registerTest( makeTestCase( invoker, extractClassName( classOrMethod ), - nameAndTags.name, - nameAndTags.tags, + nameAndTags, lineInfo)); } catch (...) { // Do not throw when constructing global objects, instead register the exception to be processed later getMutableRegistryHub().registerStartupException(); } } - + AutoReg::~AutoReg() = default; } diff --git a/include/internal/catch_test_registry.h b/include/internal/catch_test_registry.h index 84001018..a192a531 100644 --- a/include/internal/catch_test_registry.h +++ b/include/internal/catch_test_registry.h @@ -35,13 +35,13 @@ auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* { } struct NameAndTags { - NameAndTags( StringRef name_ = StringRef(), StringRef tags_ = StringRef() ) noexcept; + NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept; StringRef name; StringRef tags; }; struct AutoReg : NonCopyable { - AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef classOrMethod, NameAndTags const& nameAndTags ) noexcept; + AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept; ~AutoReg(); }; diff --git a/include/reporters/catch_reporter_tap.hpp b/include/reporters/catch_reporter_tap.hpp index edb75b5a..19e54ed1 100644 --- a/include/reporters/catch_reporter_tap.hpp +++ b/include/reporters/catch_reporter_tap.hpp @@ -26,7 +26,7 @@ namespace Catch { ~TAPReporter() override; static std::string getDescription() { - return "Reports test results in TAP format, suitable for test harneses"; + return "Reports test results in TAP format, suitable for test harnesses"; } ReporterPreferences getPreferences() const override { diff --git a/misc/appveyorBuildConfigurationScript.bat b/misc/appveyorBuildConfigurationScript.bat index 27efcd10..1e91a588 100644 --- a/misc/appveyorBuildConfigurationScript.bat +++ b/misc/appveyorBuildConfigurationScript.bat @@ -1,12 +1,26 @@ -@REM # In debug build, we want to -@REM # 1) Prebuild memcheck redirecter -@REM # 2) Regenerate single header include for examples -@REM # 3) Enable building examples + +@REM # Possibilities: +@REM # Debug build + coverage +@REM # Debug build + examples +@REM # Debug build + --- +@REM # Release build if "%CONFIGURATION%"=="Debug" ( - python scripts\generateSingleHeader.py - cmake -Hmisc -Bbuild-misc -A%PLATFORM% - cmake --build build-misc - cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DCATCH_BUILD_EXAMPLES=ON -DMEMORYCHECK_COMMAND=build-misc\Debug\CoverageHelper.exe -DMEMORYCHECK_COMMAND_OPTIONS=--sep-- -DMEMORYCHECK_TYPE=Valgrind + if "%coverage%"=="1" ( + @REM # coverage needs to build the special helper as well as the main + cmake -Hmisc -Bbuild-misc -A%PLATFORM% + cmake --build build-misc + cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DMEMORYCHECK_COMMAND=build-misc\Debug\CoverageHelper.exe -DMEMORYCHECK_COMMAND_OPTIONS=--sep-- -DMEMORYCHECK_TYPE=Valgrind + ) else ( + @REM # We know that coverage is 0 + if "%examples%"=="1" ( + @REM # Examples live off the single header, so it needs to be regenerated + python scripts\generateSingleHeader.py + cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DCATCH_BUILD_EXAMPLES=ON + ) else ( + @REM # This is just a plain debug build + cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% + ) + ) ) if "%CONFIGURATION%"=="Release" ( cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% diff --git a/misc/appveyorTestRunScript.bat b/misc/appveyorTestRunScript.bat index fdcc2ce0..19a364be 100644 --- a/misc/appveyorTestRunScript.bat +++ b/misc/appveyorTestRunScript.bat @@ -1,8 +1,12 @@ cd Build if "%CONFIGURATION%"=="Debug" ( - ctest -j 2 -C %CONFIGURATION% -D ExperimentalMemCheck - python ..\misc\appveyorMergeCoverageScript.py - codecov --root .. --no-color --disable gcov -f cobertura.xml -t %CODECOV_TOKEN% + if "%coverage%"=="1" ( + ctest -j 2 -C %CONFIGURATION% -D ExperimentalMemCheck + python ..\misc\appveyorMergeCoverageScript.py + codecov --root .. --no-color --disable gcov -f cobertura.xml -t %CODECOV_TOKEN% + ) else ( + ctest -j 2 -C %CONFIGURATION% + ) ) if "%CONFIGURATION%"=="Release" ( ctest -j 2 -C %CONFIGURATION% diff --git a/misc/installOpenCppCoverage.ps1 b/misc/installOpenCppCoverage.ps1 index 9dbffca7..d277a55d 100644 --- a/misc/installOpenCppCoverage.ps1 +++ b/misc/installOpenCppCoverage.ps1 @@ -1,5 +1,5 @@ -# Downloads are done from the oficial github release page links -$downloadUrl = "https://github.com/OpenCppCoverage/OpenCppCoverage/releases/download/release-0.9.6.1/OpenCppCoverageSetup-x64-0.9.6.1.exe" +# Downloads are done from the official github release page links +$downloadUrl = "https://github.com/OpenCppCoverage/OpenCppCoverage/releases/download/release-0.9.7.0/OpenCppCoverageSetup-x64-0.9.7.0.exe" $installerPath = [System.IO.Path]::Combine($Env:USERPROFILE, "Downloads", "OpenCppCoverageSetup.exe") if(-Not (Test-Path $installerPath)) { diff --git a/projects/SelfTest/Baselines/automake.std.approved.txt b/projects/SelfTest/Baselines/automake.std.approved.txt index 85299f70..057be069 100644 --- a/projects/SelfTest/Baselines/automake.std.approved.txt +++ b/projects/SelfTest/Baselines/automake.std.approved.txt @@ -53,7 +53,7 @@ :test-result: PASS Inequality checks that should succeed :test-result: PASS Less-than inequalities with different epsilons :test-result: PASS Long strings can be wrapped -:test-result: PASS Long text is truncted +:test-result: PASS Long text is truncated :test-result: PASS ManuallyRegistered :test-result: PASS Matchers can be (AllOf) composed with the && operator :test-result: PASS Matchers can be (AnyOf) composed with the || operator diff --git a/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp b/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp index 075e7d34..7bc4a367 100644 --- a/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp +++ b/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp @@ -15,7 +15,7 @@ # pragma clang diagnostic ignored "-Wc++98-compat" #endif -inline Catch::TestCase fakeTestCase( const char* name, const char* desc = "" ){ return Catch::makeTestCase( nullptr, "", name, desc, CATCH_INTERNAL_LINEINFO ); } +inline Catch::TestCase fakeTestCase(const char* name, const char* desc = "") { return Catch::makeTestCase(nullptr, "", { name, desc }, CATCH_INTERNAL_LINEINFO); } TEST_CASE( "Parse test names and tags" ) { diff --git a/projects/SelfTest/UsageTests/Exception.tests.cpp b/projects/SelfTest/UsageTests/Exception.tests.cpp index 3cc44d98..f9c73ed5 100644 --- a/projects/SelfTest/UsageTests/Exception.tests.cpp +++ b/projects/SelfTest/UsageTests/Exception.tests.cpp @@ -12,7 +12,7 @@ #include #ifdef _MSC_VER -#pragma warning(disable:4702) // Unreachable code -- uncoditional throws and so on +#pragma warning(disable:4702) // Unreachable code -- unconditional throws and so on #endif #ifdef __clang__ #pragma clang diagnostic push diff --git a/projects/SelfTest/UsageTests/ToStringVector.tests.cpp b/projects/SelfTest/UsageTests/ToStringVector.tests.cpp index 18e56c08..63b49e50 100644 --- a/projects/SelfTest/UsageTests/ToStringVector.tests.cpp +++ b/projects/SelfTest/UsageTests/ToStringVector.tests.cpp @@ -2,7 +2,7 @@ #include #include -// vedctor +// vector TEST_CASE( "vector -> toString", "[toString][vector]" ) { std::vector vv; diff --git a/projects/XCode/OCTest/OCTest/OCTest.1 b/projects/XCode/OCTest/OCTest/OCTest.1 index 38afeb5f..1cd333e2 100644 --- a/projects/XCode/OCTest/OCTest/OCTest.1 +++ b/projects/XCode/OCTest/OCTest/OCTest.1 @@ -61,9 +61,9 @@ FILE_2 description .\" .Sh DIAGNOSTICS \" May not be needed .\" .Bl -diag .\" .It Diagnostic Tag -.\" Diagnostic informtion here. +.\" Diagnostic information here. .\" .It Diagnostic Tag -.\" Diagnostic informtion here. +.\" Diagnostic information here. .\" .El .Sh SEE ALSO .\" List links in ascending order by section, alphabetically within a section. diff --git a/scripts/updateDocumentToC.py b/scripts/updateDocumentToC.py index 948e5e1d..e706c5c3 100644 --- a/scripts/updateDocumentToC.py +++ b/scripts/updateDocumentToC.py @@ -127,7 +127,7 @@ def tagAndCollect(lines, id_tag=True, back_links=False, exclude_h=None): A list of 3-value sublists, where the first value represents the heading, the second value the string that was inserted assigned to the IDs in the anchor tags, - and the third value is an integer that reprents the headline level. + and the third value is an integer that represents the headline level. E.g., [['some header lvl3', 'some-header-lvl3', 3], ...] @@ -282,7 +282,7 @@ def markdownToclify( input_file: str Path to the markdown input file. - output_file: str (defaul: None) + output_file: str (default: None) Path to the markdown output file. min_toc_len: int (default: 2) @@ -420,7 +420,7 @@ def updateDocumentToCMain(): default=minTocEntries, type=int, metavar='N', - help='the minimum number of entries to create a table of contents for [{deflt}]'.format(deflt=minTocEntries)) + help='the minimum number of entries to create a table of contents for [{default}]'.format(default=minTocEntries)) parser.add_argument( '--remove-toc', diff --git a/scripts/updateVcpkgPackage.py b/scripts/updateVcpkgPackage.py index 43321e15..fd7b759a 100644 --- a/scripts/updateVcpkgPackage.py +++ b/scripts/updateVcpkgPackage.py @@ -89,7 +89,7 @@ def git_push(path_to_repo): # Make sure we branch off master subprocess.call('git checkout master', shell=True) - # Update repo to current master, so we don't work off old version of the portsfile + # Update repo to current master, so we don't work off old version of the portfile subprocess.call('git pull Microsoft master', shell=True) subprocess.call('git push', shell=True) diff --git a/third_party/clara.hpp b/third_party/clara.hpp index 9a60c174..257ba10f 100644 --- a/third_party/clara.hpp +++ b/third_party/clara.hpp @@ -5,7 +5,7 @@ // // See https://github.com/philsquared/Clara for more details -// Clara v1.1.2 +// Clara v1.1.3 #ifndef CLARA_HPP_INCLUDED #define CLARA_HPP_INCLUDED @@ -18,6 +18,15 @@ #define CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH #endif +#ifndef CLARA_CONFIG_OPTIONAL_TYPE +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define CLARA_CONFIG_OPTIONAL_TYPE std::optional +#endif +#endif +#endif + + // ----------- #included from clara_textflow.hpp ----------- // TextFlowCpp @@ -389,11 +398,9 @@ namespace detail { std::vector m_args; public: - Args( int argc, char *argv[] ) { - m_exeName = argv[0]; - for( int i = 1; i < argc; ++i ) - m_args.push_back( argv[i] ); - } + Args( int argc, char const* const* argv ) + : m_exeName(argv[0]), + m_args(argv + 1, argv + argc) {} Args( std::initializer_list args ) : m_exeName( *args.begin() ), @@ -580,15 +587,13 @@ namespace detail { protected: void enforceOk() const override { - // !TBD: If no exceptions, std::terminate here or something - switch( m_type ) { - case ResultBase::LogicError: - throw std::logic_error( m_errorMessage ); - case ResultBase::RuntimeError: - throw std::runtime_error( m_errorMessage ); - case ResultBase::Ok: - break; - } + + // Errors shouldn't reach this point, but if they do + // the actual error message will be in m_errorMessage + assert( m_type != ResultBase::LogicError ); + assert( m_type != ResultBase::RuntimeError ); + if( m_type != ResultBase::Ok ) + std::abort(); } std::string m_errorMessage; // Only populated if resultType is an error @@ -658,6 +663,16 @@ namespace detail { return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" ); return ParserResult::ok( ParseResultType::Matched ); } +#ifdef CLARA_CONFIG_OPTIONAL_TYPE + template + inline auto convertInto( std::string const &source, std::optional& target ) -> ParserResult { + T temp; + auto result = convertInto( source, temp ); + if( result ) + target = temp; + return result; + } +#endif // CLARA_CONFIG_OPTIONAL_TYPE struct NonCopyable { NonCopyable() = default;